Pass player_info to which_bomb

Previously, rendering the preferred bomb type could also change it if
the active type was exhausted.  This is undesirable, since it depends on
the user to have a HUD mode which causes the bomb type to render.
Switch to only change the active type if the user tries to drop a bomb
while the active type is unavailable.  Some call sites already switch
bomb types automatically on depletion.  Those sites will still do so.
This commit is contained in:
Kp 2021-01-17 22:23:22 +00:00
parent c7680621a8
commit baa2823953
4 changed files with 25 additions and 12 deletions

View file

@ -276,8 +276,7 @@ public:
namespace dsx {
//return which bomb will be dropped next time the bomb key is pressed
#if defined(DXX_BUILD_DESCENT_I)
static constexpr int which_bomb()
static constexpr secondary_weapon_index_t which_bomb(const player_info &)
{
return PROXIMITY_INDEX;
}
@ -298,7 +297,8 @@ static constexpr unsigned vulcan_ammo_scale(const unsigned v)
return (v * 0xcc180u) >> 16;
}
#elif defined(DXX_BUILD_DESCENT_II)
int which_bomb(void);
secondary_weapon_index_t which_bomb(player_info &player_info);
secondary_weapon_index_t which_bomb(const player_info &player_info);
static constexpr int weapon_index_uses_vulcan_ammo(const unsigned id)
{

View file

@ -249,34 +249,47 @@ static void update_vcr_state(void)
namespace dsx {
#if defined(DXX_BUILD_DESCENT_II)
namespace {
//returns which bomb will be dropped next time the bomb key is pressed
int which_bomb()
template <typename T>
secondary_weapon_index_t read_update_which_proximity_mine_to_use(T &player_info)
{
auto &Objects = LevelUniqueObjectState.Objects;
auto &vmobjptr = Objects.vmptr;
//use the last one selected, unless there aren't any, in which case use
//the other if there are any
auto &player_info = get_local_plrobj().ctype.player_info;
auto &Secondary_last_was_super = player_info.Secondary_last_was_super;
const auto mask = 1 << PROXIMITY_INDEX;
const auto bomb = (Secondary_last_was_super & mask) ? SMART_MINE_INDEX : PROXIMITY_INDEX;
auto &secondary_ammo = player_info.secondary_ammo;
if (secondary_ammo[bomb])
/* Player has the requested bomb type available. Use it. */
return bomb;
const auto alt_bomb = SMART_MINE_INDEX + PROXIMITY_INDEX - bomb;
const auto alt_bomb = static_cast<secondary_weapon_index_t>(SMART_MINE_INDEX + PROXIMITY_INDEX - bomb);
if (secondary_ammo[alt_bomb])
{
/* Player has the alternate bomb type, but not the requested
* bomb type. Switch.
*/
Secondary_last_was_super ^= mask;
if constexpr (!std::is_const<T>::value)
Secondary_last_was_super ^= mask;
return alt_bomb;
}
/* Player has no bombs of either type. */
return bomb;
}
}
secondary_weapon_index_t which_bomb(const player_info &player_info)
{
return read_update_which_proximity_mine_to_use(player_info);
}
secondary_weapon_index_t which_bomb(player_info &player_info)
{
return read_update_which_proximity_mine_to_use(player_info);
}
#endif
namespace {

View file

@ -1295,7 +1295,7 @@ static void show_bomb_count(grs_canvas &canvas, const player_info &player_info,
return;
#endif
const auto bomb = which_bomb();
const auto bomb = which_bomb(player_info);
int count = player_info.secondary_ammo[bomb];
count = min(count,99); //only have room for 2 digits - cheating give 200

View file

@ -2315,8 +2315,8 @@ void do_missile_firing(int drop_bomb)
fix fire_frame_overhead = 0;
auto &plrobj = get_local_plrobj();
const auto bomb = which_bomb();
auto &player_info = plrobj.ctype.player_info;
const auto bomb = which_bomb(player_info);
const auto weapon = drop_bomb ? bomb : player_info.Secondary_weapon;
assert(weapon < MAX_SECONDARY_WEAPONS);
auto &Next_missile_fire_time = player_info.Next_missile_fire_time;