Skip to content

Commit

Permalink
Implement activity_actor for ACT_AIM; don't restart activity on each …
Browse files Browse the repository at this point in the history
…turn.
  • Loading branch information
olanti-p committed May 18, 2020
1 parent ae6b7ac commit 4f94f5f
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 91 deletions.
60 changes: 60 additions & 0 deletions src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,65 @@ static const mtype_id mon_zombie_rot( "mon_zombie_rot" );
static const mtype_id mon_skeleton( "mon_skeleton" );
static const mtype_id mon_zombie_crawler( "mon_zombie_crawler" );

void aim_activity_actor::start( player_activity &act, Character &/*who*/ )
{
// Time spent on aiming is determined on the go by the player
act.moves_total = 1;
act.moves_left = 1;
}

void aim_activity_actor::do_turn( player_activity &act, Character &who )
{
if( avatar *you = dynamic_cast<avatar *>( &who ) ) {
avatar_action::aim_do_turn( *you, g->m, *this );
} else {
debugmsg( "ACT_AIM not implemented for NPCs" );
aborted = true;
}
first_turn = false;
if( aborted || finished ) {
act.moves_left = 0;
}
}

void aim_activity_actor::finish( player_activity &act, Character &who )
{
act.set_to_null();
if( reload_requested ) {
// Reload the gun / select different arrows
// May assign ACT_RELOAD
g->reload_wielded( true );
}
}

void aim_activity_actor::serialize( JsonOut &jsout ) const
{
jsout.start_object();

jsout.member( "first_turn", first_turn );
jsout.member( "action", action );
jsout.member( "snap_to_target", snap_to_target );
jsout.member( "shifting_view", shifting_view );
jsout.member( "view_offset", view_offset );

jsout.end_object();
}

std::unique_ptr<activity_actor> aim_activity_actor::deserialize( JsonIn &jsin )
{
aim_activity_actor actor = aim_activity_actor();

JsonObject data = jsin.get_object();

data.read( "first_turn", actor.first_turn );
data.read( "action", actor.action );
data.read( "snap_to_target", actor.snap_to_target );
data.read( "shifting_view", actor.shifting_view );
data.read( "view_offset", actor.view_offset );

return actor.clone();
}

void dig_activity_actor::start( player_activity &act, Character & )
{
act.moves_total = moves_total;
Expand Down Expand Up @@ -646,6 +705,7 @@ namespace activity_actors
// Please keep this alphabetically sorted
const std::unordered_map<activity_id, std::unique_ptr<activity_actor>( * )( JsonIn & )>
deserialize_functions = {
{ activity_id( "ACT_AIM" ), &aim_activity_actor::deserialize },
{ activity_id( "ACT_CONSUME" ), &consume_activity_actor::deserialize },
{ activity_id( "ACT_DIG" ), &dig_activity_actor::deserialize },
{ activity_id( "ACT_DIG_CHANNEL" ), &dig_channel_activity_actor::deserialize },
Expand Down
39 changes: 39 additions & 0 deletions src/activity_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,45 @@ class activity_actor
virtual void serialize( JsonOut &jsout ) const = 0;
};

class aim_activity_actor : public activity_actor
{
public:
bool first_turn = true;
std::string action = "";
bool snap_to_target = false;
bool shifting_view = false;
tripoint view_offset = tripoint_zero;

/** Target UI requested to abort aiming */
bool aborted = false;

/** Target UI requested to fire */
bool finished = false;

/**
* Target UI requested to abort aiming and reload weapon
* Implies aborted = true
*/
bool reload_requested = false;

aim_activity_actor() = default;

activity_id get_type() const override {
return activity_id( "ACT_AIM" );
}

void start( player_activity &act, Character &who ) override;
void do_turn( player_activity &act, Character &who ) override;
void finish( player_activity &act, Character &who ) override;

std::unique_ptr<activity_actor> clone() const override {
return std::make_unique<aim_activity_actor>( *this );
}

void serialize( JsonOut &jsout ) const override;
static std::unique_ptr<activity_actor> deserialize( JsonIn &jsin );
};

class dig_activity_actor : public activity_actor
{
private:
Expand Down
18 changes: 0 additions & 18 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ static const efftype_id effect_sheared( "sheared" );
#define dbg(x) DebugLog((x),D_GAME) << __FILE__ << ":" << __LINE__ << ": "

static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" );
static const activity_id ACT_AIM( "ACT_AIM" );
static const activity_id ACT_ARMOR_LAYERS( "ACT_ARMOR_LAYERS" );
static const activity_id ACT_ATM( "ACT_ATM" );
static const activity_id ACT_AUTODRIVE( "ACT_AUTODRIVE" );
Expand Down Expand Up @@ -290,7 +289,6 @@ activity_handlers::do_turn_functions = {
{ ACT_VIBE, vibe_do_turn },
{ ACT_HAND_CRANK, hand_crank_do_turn },
{ ACT_OXYTORCH, oxytorch_do_turn },
{ ACT_AIM, aim_do_turn },
{ ACT_WEAR, wear_do_turn },
{ ACT_MULTIPLE_FISH, multiple_fish_do_turn },
{ ACT_MULTIPLE_CONSTRUCTION, multiple_construction_do_turn },
Expand Down Expand Up @@ -388,7 +386,6 @@ activity_handlers::finish_functions = {
{ ACT_DISASSEMBLE, disassemble_finish },
{ ACT_VIBE, vibe_finish },
{ ACT_ATM, atm_finish },
{ ACT_AIM, aim_finish },
{ ACT_EAT_MENU, eat_menu_finish },
{ ACT_CONSUME_FOOD_MENU, eat_menu_finish },
{ ACT_CONSUME_DRINK_MENU, eat_menu_finish },
Expand Down Expand Up @@ -2962,15 +2959,6 @@ void activity_handlers::meditate_finish( player_activity *act, player *p )
act->set_to_null();
}

void activity_handlers::aim_do_turn( player_activity *act, player * )
{
if( act->index == 0 ) {
g->m.invalidate_map_cache( g->get_levz() );
g->m.build_map_cache( g->get_levz() );
avatar_action::aim_do_turn( g->u, g->m );
}
}

void activity_handlers::wear_do_turn( player_activity *act, player *p )
{
activity_on_turn_wear( *act, *p );
Expand Down Expand Up @@ -3848,12 +3836,6 @@ void activity_handlers::atm_finish( player_activity *act, player * )
}
}

void activity_handlers::aim_finish( player_activity *, player * )
{
// Aim bails itself by resetting itself every turn,
// you only re-enter if it gets set again.
return;
}
void activity_handlers::eat_menu_finish( player_activity *, player * )
{
// Only exists to keep the eat activity alive between turns
Expand Down
1 change: 0 additions & 1 deletion src/activity_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ void vibe_do_turn( player_activity *act, player *p );
void hand_crank_do_turn( player_activity *act, player *p );
void multiple_chop_planks_do_turn( player_activity *act, player *p );
void oxytorch_do_turn( player_activity *act, player *p );
void aim_do_turn( player_activity *act, player *p );
void wear_do_turn( player_activity *act, player *p );
void eat_menu_do_turn( player_activity *act, player *p );
void consume_food_menu_do_turn( player_activity *act, player *p );
Expand Down
53 changes: 27 additions & 26 deletions src/avatar_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ static bool can_fire_turret( avatar &you, const map &m, const turret_data &turre
return false;
}

void avatar_action::aim_do_turn( avatar &you, map &m )
void avatar_action::aim_do_turn( avatar &you, map &m, aim_activity_actor &activity )
{
targeting_data &args = you.get_targeting_data();

Expand Down Expand Up @@ -853,14 +853,10 @@ void avatar_action::aim_do_turn( avatar &you, map &m )
you.cancel_activity();
return;
}

int reload_time = 0;
gun_mode gun = weapon->gun_current_mode();

// TODO: use MODERATE_EXERCISE if firing a bow
you.increase_activity_level( LIGHT_EXERCISE );

// TODO: move handling "RELOAD_AND_SHOOT" flagged guns to a separate function.
int moves_before_reload = you.moves;
if( gun->has_flag( flag_RELOAD_AND_SHOOT ) ) {
if( !gun->ammo_remaining() ) {
const auto ammo_location_is_valid = [&]() -> bool {
Expand All @@ -884,6 +880,7 @@ void avatar_action::aim_do_turn( avatar &you, map &m )
// Menu canceled
return;
}
int reload_time = 0;
reload_time += opt.moves();
if( !gun->reload( you, std::move( opt.ammo ), 1 ) ) {
// Reload not allowed
Expand All @@ -897,43 +894,47 @@ void avatar_action::aim_do_turn( avatar &you, map &m )
int sta_percent = ( 100 * you.get_stamina() ) / you.get_stamina_max();
reload_time += ( sta_percent < 25 ) ? ( ( 25 - sta_percent ) * 2 ) : 0;

you.moves -= reload_time;
g->refresh_all();
}
}
int moves_before_ui = you.moves;

g->temp_exit_fullscreen();
m.draw( g->w_terrain, you.pos() );
bool reload_requested;
target_handler::trajectory trajectory = target_handler::mode_fire( you, *weapon, reload_requested );
target_handler::trajectory trajectory = target_handler::mode_fire( you, *weapon, activity );

//may be changed in target_ui
gun = weapon->gun_current_mode();
if( activity.aborted ) {
if( gun->has_flag( flag_RELOAD_AND_SHOOT ) ) {
bool refund = activity.first_turn && you.moves == moves_before_ui;
int moves_before_unload = you.moves;

if( trajectory.empty() ) {
bool not_aiming = you.activity.id() != ACT_AIM;
if( not_aiming && gun->has_flag( flag_RELOAD_AND_SHOOT ) ) {
const auto previous_moves = you.moves;
item_location loc = item_location( you, gun.target );
g->unload( loc );

// Give back time for unloading as essentially nothing has been done.
// Note that reload_time has not been applied either.
you.moves = previous_moves;
if( refund ) {
you.moves = moves_before_unload;
}
}
g->reenter_fullscreen();

if( reload_requested ) {
// Reload the gun / select different arrows
g->reload_wielded( true );
}
return;
}
if( trajectory.empty() ) {
// Still aiming
return;
}
activity.finished = true;

// TODO: move everything below to aim_activity_actor::finish()

// Recenter our view
g->draw_ter();
wrefresh( g->w_terrain );
g->draw_panels();

you.moves -= reload_time;

// Update gun mode since target UI may change it
gun = weapon->gun_current_mode();
int shots_fired = you.fire_gun( trajectory.back(), gun.qty, *gun );

// TODO: bionic power cost of firing should be derived from a value of the relevant weapon.
Expand Down Expand Up @@ -961,22 +962,22 @@ void avatar_action::fire_wielded_weapon( avatar &you, map &m )

targeting_data args = targeting_data::use_wielded();
you.set_targeting_data( args );
avatar_action::aim_do_turn( you, m );
you.assign_activity( aim_activity_actor(), false );
}

void avatar_action::fire_ranged_mutation( avatar &you, map &m, const item &fake_gun )
{
targeting_data args = targeting_data::use_mutation( fake_gun );
you.set_targeting_data( args );
avatar_action::aim_do_turn( you, m );
you.assign_activity( aim_activity_actor(), false );
}

void avatar_action::fire_ranged_bionic( avatar &you, map &m, const item &fake_gun,
units::energy cost_per_shot )
{
targeting_data args = targeting_data::use_bionic( fake_gun, cost_per_shot );
you.set_targeting_data( args );
avatar_action::aim_do_turn( you, m );
you.assign_activity( aim_activity_actor(), false );
}

void avatar_action::fire_turret_manual( avatar &you, map &m, turret_data &turret )
Expand Down
3 changes: 2 additions & 1 deletion src/avatar_action.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class item;
class item_location;
class map;
class turret_data;
class aim_activity_actor;

namespace avatar_action
{
Expand Down Expand Up @@ -44,7 +45,7 @@ void mend( avatar &you, item_location loc );
* Validates avatar's targeting_data, then handles interactive parts of gun firing
* (target selection, aiming, etc.)
*/
void aim_do_turn( avatar &you, map &m );
void aim_do_turn( avatar &you, map &m, aim_activity_actor &activity );

/** Checks if the wielded weapon is a gun and can be fired then starts interactive aiming */
void fire_wielded_weapon( avatar &you, map &m );
Expand Down
Loading

0 comments on commit 4f94f5f

Please sign in to comment.