From 9a132977b973d85a822abc28cc79ac8837592fce Mon Sep 17 00:00:00 2001 From: Kp Date: Thu, 12 Nov 2015 02:57:45 +0000 Subject: [PATCH] Fix drop_player_eggs smart mine logic The count of mines was not decremented, so a player who entered the loop could continue to drop until (d_rand() < rthresh) became false. Halving rthresh on each pass guaranteed that it would stop, but with the right string of random numbers, the player could drop more mines than he had. Remove the ==1 qualifier, so that mines can spawn whenever one will be lost to rounding. --- similar/main/collide.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/similar/main/collide.cpp b/similar/main/collide.cpp index a59c9e6f1..22a269628 100644 --- a/similar/main/collide.cpp +++ b/similar/main/collide.cpp @@ -1889,33 +1889,27 @@ void drop_player_eggs(const vobjptridx_t playerobj) auto &secondary_ammo = playerobj->ctype.player_info.secondary_ammo; #if defined(DXX_BUILD_DESCENT_II) // If the player had smart mines, maybe arm one of them. - int rthresh; - rthresh = 30000; - while (secondary_ammo[SMART_MINE_INDEX] % 4 == 1 && d_rand() < rthresh) + const auto drop_armed_bomb = [&](uint8_t mines, weapon_type_t id) { + mines %= 4; + for (int rthresh = 30000; mines && d_rand() < rthresh; rthresh /= 2) { const auto randvec = make_random_vector(); - rthresh /= 2; const auto tvec = vm_vec_add(playerobj->pos, randvec); auto newseg = find_point_seg(tvec, playerobj->segnum); if (newseg != segment_none) - Laser_create_new(randvec, tvec, newseg, playerobj, SUPERPROX_ID, 0); - } + { + -- mines; + Laser_create_new(randvec, tvec, newseg, playerobj, id, 0); + } + } + }; + drop_armed_bomb(secondary_ammo[SMART_MINE_INDEX], SUPERPROX_ID); // If the player had proximity bombs, maybe arm one of them. if ((Game_mode & GM_MULTI) && !game_mode_hoard()) { - rthresh = 30000; - while (secondary_ammo[PROXIMITY_INDEX] % 4 == 1 && d_rand() < rthresh) - { - const auto randvec = make_random_vector(); - rthresh /= 2; - const auto tvec = vm_vec_add(playerobj->pos, randvec); - auto newseg = find_point_seg(tvec, playerobj->segnum); - if (newseg != segment_none) - Laser_create_new(randvec, tvec, newseg, playerobj, PROXIMITY_ID, 0); - - } + drop_armed_bomb(secondary_ammo[PROXIMITY_INDEX], PROXIMITY_ID); } #endif