Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display RAS weapon reload time in aim ui #73550

63 changes: 15 additions & 48 deletions src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,12 @@ void aim_activity_actor::do_turn( player_activity &act, Character &who )
gun_mode gun = weapon->gun_current_mode();
// We need to make sure RAS weapon is loaded/reloaded in case the aim activity was temp. suspended
// therefore the order of evaluation matters here
if( gun->has_flag( flag_RELOAD_AND_SHOOT ) && !gun->ammo_remaining() && !load_RAS_weapon() &&
first_turn ) {
aborted = true;
act.moves_left = 0;
return;
if( gun->has_flag( flag_RELOAD_AND_SHOOT ) && !gun->ammo_remaining() && !reload_loc ) {
if( !load_RAS_weapon() ) {
aborted = true;
act.moves_left = 0;
return;
}
}

if( gun->has_flag( json_flag_ALWAYS_AIMED ) ) {
Expand All @@ -355,10 +356,6 @@ void aim_activity_actor::do_turn( player_activity &act, Character &who )
fin_trajectory = trajectory;
act.moves_left = 0;
}
// If aborting on the first turn, keep 'first_turn' as 'true'.
// This allows refunding moves spent on unloading RELOAD_AND_SHOOT weapons
// to simulate avatar not loading them in the first place
first_turn = false;

// Allow interrupting activity only during 'aim and fire'.
// Prevents '.' key for 'aim for 10 turns' from conflicting with '.' key for 'interrupt activity'
Expand Down Expand Up @@ -388,14 +385,7 @@ void aim_activity_actor::finish( player_activity &act, Character &who )
}

gun_mode gun = weapon->gun_current_mode();
who.fire_gun( fin_trajectory.back(), gun.qty, *gun );

if( weapon && weapon->gun_current_mode()->has_flag( flag_RELOAD_AND_SHOOT ) ) {
// RAS weapons are currently bugged, this is a workaround so bug impact
// isn't amplified, once #54997 and #50571 are fixed this can be removed.
restore_view();
return;
}
who.fire_gun( fin_trajectory.back(), gun.qty, *gun, reload_loc );

if( !get_option<bool>( "AIM_AFTER_FIRING" ) ) {
restore_view();
Expand All @@ -418,8 +408,8 @@ void aim_activity_actor::finish( player_activity &act, Character &who )

void aim_activity_actor::canceled( player_activity &/*act*/, Character &/*who*/ )
{
restore_view();
unload_RAS_weapon();
restore_view();
}

void aim_activity_actor::serialize( JsonOut &jsout ) const
Expand All @@ -428,12 +418,11 @@ void aim_activity_actor::serialize( JsonOut &jsout ) const

jsout.member( "fake_weapon", fake_weapon );
jsout.member( "fin_trajectory", fin_trajectory );
jsout.member( "first_turn", first_turn );
jsout.member( "action", action );
jsout.member( "aif_duration", aif_duration );
jsout.member( "aiming_at_critter", aiming_at_critter );
jsout.member( "snap_to_target", snap_to_target );
jsout.member( "loaded_RAS_weapon", loaded_RAS_weapon );
jsout.member( "reload_loc", reload_loc );
jsout.member( "shifting_view", shifting_view );
jsout.member( "initial_view_offset", initial_view_offset );
jsout.member( "aborted", aborted );
Expand All @@ -451,12 +440,11 @@ std::unique_ptr<activity_actor> aim_activity_actor::deserialize( JsonValue &jsin

data.read( "fake_weapon", actor.fake_weapon );
data.read( "fin_trajectory", actor.fin_trajectory );
data.read( "first_turn", actor.first_turn );
data.read( "action", actor.action );
data.read( "aif_duration", actor.aif_duration );
data.read( "aiming_at_critter", actor.aiming_at_critter );
data.read( "snap_to_target", actor.snap_to_target );
data.read( "loaded_RAS_weapon", actor.loaded_RAS_weapon );
data.read( "reload_loc", actor.reload_loc );
data.read( "shifting_view", actor.shifting_view );
data.read( "initial_view_offset", actor.initial_view_offset );
data.read( "aborted", actor.aborted );
Expand Down Expand Up @@ -519,48 +507,27 @@ bool aim_activity_actor::load_RAS_weapon()
// Menu canceled
return false;
}
int reload_time = 0;
reload_time += opt.moves();
if( !gun->reload( you, std::move( opt.ammo ), 1 ) ) {
// Reload not allowed
return false;
}

// Burn 0.6% max base stamina without cardio/BMI factored in x the strength required to fire.
you.burn_energy_arms( gun->get_min_str() * static_cast<int>( 0.006f *
get_option<int>( "PLAYER_MAX_STAMINA_BASE" ) ) );
// At low stamina levels, firing starts getting slow.
int sta_percent = ( 100 * you.get_stamina() ) / you.get_stamina_max();
reload_time += ( sta_percent < 25 ) ? ( ( 25 - sta_percent ) * 2 ) : 0;

you.mod_moves( -reload_time );
loaded_RAS_weapon = true;
reload_loc = opt.ammo;
return true;
}

void aim_activity_actor::unload_RAS_weapon()
{
// Unload reload-and-shoot weapons to avoid leaving bows pre-loaded with arrows
avatar &you = get_avatar();
item_location weapon = get_weapon();
if( !weapon || !loaded_RAS_weapon ) {
if( !weapon ) {
return;
}

gun_mode gun = weapon->gun_current_mode();
if( gun->has_flag( flag_RELOAD_AND_SHOOT ) ) {
int moves_before_unload = you.get_moves();

// Note: this code works only for avatar
item_location loc = item_location( you, gun.target );
you.unload( loc, true );

// Give back time for unloading as essentially nothing has been done.
if( first_turn ) {
you.set_moves( moves_before_unload );
if( gun->ammo_remaining() ) {
item_location loc = item_location( you, gun.target );
you.unload( loc, true );
}
}
loaded_RAS_weapon = false;
}

void autodrive_activity_actor::update_player_vehicle( Character &who )
Expand Down
5 changes: 2 additions & 3 deletions src/activity_actor_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,12 @@ class aim_activity_actor : public activity_actor
std::vector<tripoint> fin_trajectory;

public:
bool first_turn = true;
std::string action;
int aif_duration = 0; // Counts aim-and-fire duration
bool aiming_at_critter = false; // Whether aiming at critter or a tile
bool snap_to_target = false;
/** Not to try to unload RELOAD_AND_SHOOT weapon if it is not loaded */
bool loaded_RAS_weapon = false;
/* Item location for RAS weapon reload */
item_location reload_loc = item_location();
bool shifting_view = false;
tripoint initial_view_offset;
/** Target UI requested to abort aiming */
Expand Down
2 changes: 1 addition & 1 deletion src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -3131,7 +3131,7 @@ class Character : public Creature, public visitable
* @param gun item to fire (which does not necessary have to be in the players possession)
* @return number of shots actually fired
*/
int fire_gun( const tripoint &target, int shots, item &gun );
int fire_gun( const tripoint &target, int shots, item &gun, item_location ammo = item_location() );
/** Execute a throw */
dealt_projectile_attack throw_item( const tripoint &target, const item &to_throw,
const std::optional<tripoint> &blind_throw_from_pos = std::nullopt );
Expand Down