From 7df905c1db682338318b1e9bdcc4b43df4cb4fe2 Mon Sep 17 00:00:00 2001 From: Kp Date: Thu, 12 Nov 2015 02:57:45 +0000 Subject: [PATCH] Fix weapon selection after respawn Commit 7da64d3 added the ability to select a weapon when firing stops. However, it did not take into account that select_primary_weapon/select_secondary_weapon do not check whether the selected weapon is available. The caller must perform that check. The draft version proposed by Mako88 in the original feature request mostly avoided the problem by clearing the delayed auto-select when it was first applied. That version would only manifest the problem if the player had a delayed auto-select and lost the weapon before resolving it, whether due to death, a thief bot, or, in the case of mines, direct-dropping the last mine by the "Drop Bomb" key. The version that went in switched to using delayed==active to indicate that no change was required. Under that design, the incorrect auto-select appears if the player loses the active weapon even if no delayed selection was pending. Add a check that the player has the weapon before switching to it and reset delayed=current if the delayed weapon is not available. This fixes all known cases under which a spurious delayed selection could activate a missing weapon and prevents repeated checks for weapon availability. Reported-by: Mako88 Fixes: 7da64d37825e1d32b4672eea86390ef941bdaad5 ("Add new autoselect-while-firing mode: "when firing stops"") --- similar/main/weapon.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/similar/main/weapon.cpp b/similar/main/weapon.cpp index 9aa776567..74ca46b1e 100644 --- a/similar/main/weapon.cpp +++ b/similar/main/weapon.cpp @@ -645,10 +645,30 @@ void auto_select_secondary_weapon() void delayed_autoselect() { - if (!Controls.state.fire_primary && Delayed_primary != Primary_weapon) - select_primary_weapon(nullptr, Delayed_primary, 1); - if (!Controls.state.fire_secondary && Delayed_secondary != Secondary_weapon) - select_secondary_weapon(nullptr, Delayed_secondary, 1); + if (!Controls.state.fire_primary) + { + const auto primary_weapon = Primary_weapon; + const auto delayed_primary = Delayed_primary; + if (delayed_primary != primary_weapon) + { + if (player_has_primary_weapon(delayed_primary).has_all()) + select_primary_weapon(nullptr, delayed_primary, 1); + else + Delayed_primary = primary_weapon; + } + } + if (!Controls.state.fire_secondary) + { + const auto secondary_weapon = Secondary_weapon; + const auto delayed_secondary = Delayed_secondary; + if (delayed_secondary != secondary_weapon) + { + if (player_has_secondary_weapon(delayed_secondary).has_all()) + select_secondary_weapon(nullptr, delayed_secondary, 1); + else + Delayed_secondary = secondary_weapon; + } + } } static void maybe_autoselect_primary_weapon(int weapon_index)