Skip to content

Commit

Permalink
Merge pull request CleverRaven#73550 from osuphobia/Display-RAS-weapo…
Browse files Browse the repository at this point in the history
…n-reload-time-in-aim-ui

Display RAS weapon reload time in aim ui
  • Loading branch information
kevingranade authored May 25, 2024
2 parents 22d851b + d909186 commit 388ca6c
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 87 deletions.
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 @@ -3132,7 +3132,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
Loading

0 comments on commit 388ca6c

Please sign in to comment.