Skip to content

Commit

Permalink
Migrate ACT_PICKUP to the activity actor system
Browse files Browse the repository at this point in the history
  • Loading branch information
ifreund authored and kevingranade committed Apr 25, 2020
1 parent d834d7a commit de16cb5
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 151 deletions.
66 changes: 66 additions & 0 deletions src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <utility>

#include "activity_handlers.h" // put_into_vehicle_or_drop and drop_on_map
#include "advanced_inv.h"
#include "avatar.h"
#include "character.h"
#include "computer_session.h"
Expand Down Expand Up @@ -281,6 +282,70 @@ std::unique_ptr<activity_actor> move_items_activity_actor::deserialize( JsonIn &
return actor.clone();
}

void pickup_activity_actor::do_turn( player_activity &, Character &who )
{
// If we don't have target items bail out
if( target_items.empty() ) {
who.cancel_activity();
return;
}

// If the player moves while picking up (i.e.: in a moving vehicle) cancel
// the activity, only populate starting_pos when grabbing from the ground
if( starting_pos && *starting_pos != who.pos() ) {
who.cancel_activity();
who.add_msg_if_player( _( "Moving canceled auto-pickup." ) );
return;
}

// Auto_resume implies autopickup.
const bool autopickup = who.activity.auto_resume;

// False indicates that the player canceled pickup when met with some prompt
const bool keep_going = Pickup::do_pickup( target_items, quantities, autopickup );

// If there are items left we ran out of moves, so continue the activity
// Otherwise, we are done.
if( !keep_going || target_items.empty() ) {
who.cancel_activity();

if( who.get_value( "THIEF_MODE_KEEP" ) != "YES" ) {
who.set_value( "THIEF_MODE", "THIF_ASK" );
}

if( !keep_going ) {
// The user canceled the activity, so we're done
// AIM might have more pickup activities pending, also cancel them.
// TODO: Move this to advanced inventory instead of hacking it in here
cancel_aim_processing();
}
}
}

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

jsout.member( "target_items", target_items );
jsout.member( "quantities", quantities );
jsout.member( "starting_pos", starting_pos );

jsout.end_object();
}

std::unique_ptr<activity_actor> pickup_activity_actor::deserialize( JsonIn &jsin )
{
pickup_activity_actor actor( {}, {}, cata::nullopt );

JsonObject data = jsin.get_object();

data.read( "target_items", actor.target_items );
data.read( "quantities", actor.quantities );
data.read( "starting_pos", actor.starting_pos );

return actor.clone();
}

void migration_cancel_activity_actor::do_turn( player_activity &act, Character &who )
{
// Stop the activity
Expand Down Expand Up @@ -318,6 +383,7 @@ deserialize_functions = {
{ activity_id( "ACT_HACKING" ), &hacking_activity_actor::deserialize },
{ activity_id( "ACT_MIGRATION_CANCEL" ), &migration_cancel_activity_actor::deserialize },
{ activity_id( "ACT_MOVE_ITEMS" ), &move_items_activity_actor::deserialize },
{ activity_id( "ACT_PICKUP" ), &pickup_activity_actor::deserialize },
};
} // namespace activity_actors

Expand Down
37 changes: 37 additions & 0 deletions src/activity_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,43 @@ class move_items_activity_actor : public activity_actor
static std::unique_ptr<activity_actor> deserialize( JsonIn &jsin );
};

class pickup_activity_actor : public activity_actor
{
private:
/** Target items and the quantities thereof */
std::vector<item_location> target_items;
std::vector<int> quantities;

/**
* Position of the character when the activity is started. This is
* stored so that we can cancel the activity if the player moves
* (e.g. if the player is in a moving vehicle). This should be null
* if not grabbing from the ground.
*/
cata::optional<tripoint> starting_pos;

public:
pickup_activity_actor( const std::vector<item_location> &target_items,
const std::vector<int> &quantities,
const cata::optional<tripoint> &starting_pos ) : target_items( target_items ),
quantities( quantities ), starting_pos( starting_pos ) {}

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

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

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

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

class migration_cancel_activity_actor : public activity_actor
{
public:
Expand Down
7 changes: 0 additions & 7 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ static const activity_id ACT_OPEN_GATE( "ACT_OPEN_GATE" );
static const activity_id ACT_OPERATION( "ACT_OPERATION" );
static const activity_id ACT_OXYTORCH( "ACT_OXYTORCH" );
static const activity_id ACT_PICKAXE( "ACT_PICKAXE" );
static const activity_id ACT_PICKUP( "ACT_PICKUP" );
static const activity_id ACT_PLANT_SEED( "ACT_PLANT_SEED" );
static const activity_id ACT_PLAY_WITH_PET( "ACT_PLAY_WITH_PET" );
static const activity_id ACT_PRY_NAILS( "ACT_PRY_NAILS" );
Expand Down Expand Up @@ -299,7 +298,6 @@ activity_handlers::do_turn_functions = {
{ ACT_HAND_CRANK, hand_crank_do_turn },
{ ACT_OXYTORCH, oxytorch_do_turn },
{ ACT_AIM, aim_do_turn },
{ ACT_PICKUP, pickup_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 @@ -3059,11 +3057,6 @@ void activity_handlers::aim_do_turn( player_activity *act, player * )
}
}

void activity_handlers::pickup_do_turn( player_activity *, player * )
{
activity_on_turn_pickup();
}

void activity_handlers::wear_do_turn( player_activity *act, player *p )
{
activity_on_turn_wear( *act, *p );
Expand Down
2 changes: 0 additions & 2 deletions src/activity_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ void activity_on_turn_move_loot( player_activity &act, player &p );
//return true if there is an activity that can be done potentially, return false if no work can be found.
bool generic_multi_activity_handler( player_activity &act, player &p, bool check_only = false );
void activity_on_turn_fetch( player_activity &, player *p );
void activity_on_turn_pickup();
void activity_on_turn_wear( player_activity &act, player &p );
bool find_auto_consume( player &p, bool food );
void try_fuel_fire( player_activity &act, player &p, bool starting_fire = false );
Expand Down Expand Up @@ -140,7 +139,6 @@ 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 pickup_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
51 changes: 0 additions & 51 deletions src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,57 +741,6 @@ void activity_handlers::stash_do_turn( player_activity *act, player *p )
}
}

void activity_on_turn_pickup()
{
// ACT_PICKUP has item_locations of target items and quantities of the same.

// If we don't have target items bail out
if( g->u.activity.targets.empty() ) {
g->u.cancel_activity();
return;
}

// If the player moves while picking up (i.e.: in a moving vehicle) cancel the activity, only populate coords when grabbing from the ground
if( !g->u.activity.coords.empty() && g->u.activity.coords.at( 0 ) != g->u.pos() ) {
g->u.cancel_activity();
if( g->u.is_player() ) {
g->u.add_msg_if_player( _( "Moving canceled auto-pickup." ) );
}
return;
}

// Auto_resume implies autopickup.
const bool autopickup = g->u.activity.auto_resume;

// False indicates that the player canceled pickup when met with some prompt
const bool keep_going = Pickup::do_pickup( g->u.activity.targets, g->u.activity.values,
autopickup );

// If there are items left we ran out of moves, so continue the activity
// Otherwise, we are done.
if( !keep_going || g->u.activity.targets.empty() ) {
g->u.cancel_activity();
if( g->u.get_value( "THIEF_MODE_KEEP" ) != "YES" ) {
g->u.set_value( "THIEF_MODE", "THIEF_ASK" );
}
}

// TODO: Move this to advanced inventory instead of hacking it in here

if( !keep_going ) {
// The user canceled the activity, so we're done
g->u.cancel_activity();
// AIM might have more pickup activities pending, also cancel them.
// TODO: Move this to advanced inventory instead of hacking it in here
cancel_aim_processing();
} else if( g->u.activity.targets.empty() ) {
// The user did not cancel, but there's no item left
g->u.cancel_activity();
// But do not cancel AIM processing as it might have more pickup activities
// pending for other locations.
}
}

static double get_capacity_fraction( int capacity, int volume )
{
// fraction of capacity the item would occupy
Expand Down
102 changes: 36 additions & 66 deletions src/advanced_inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@

static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" );
static const activity_id ACT_DROP( "ACT_DROP" );
static const activity_id ACT_PICKUP( "ACT_PICKUP" );
static const activity_id ACT_WEAR( "ACT_WEAR" );

static const trait_id trait_DEBUG_STORAGE( "DEBUG_STORAGE" );
Expand Down Expand Up @@ -919,48 +918,9 @@ bool advanced_inventory::move_all_items( bool nested_call )

g->u.drop( dropped, g->u.pos() + darea.off );
} else {
if( dpane.get_area() == AIM_INVENTORY || dpane.get_area() == AIM_WORN ) {
g->u.assign_activity( ACT_PICKUP );
g->u.activity.coords.push_back( g->u.pos() );

item_stack::iterator stack_begin, stack_end;
if( panes[src].in_vehicle() ) {
vehicle_stack targets = sarea.veh->get_items( sarea.vstor );
stack_begin = targets.begin();
stack_end = targets.end();
} else {
map_stack targets = g->m.i_at( sarea.pos );
stack_begin = targets.begin();
stack_end = targets.end();
}

// If moving to inventory or worn, silently filter buckets
// Moving them would cause tons of annoying prompts or spills
const bool filter_buckets = dpane.get_area() == AIM_INVENTORY ||
dpane.get_area() == AIM_WORN;
bool filtered_any_bucket = false;
// Push item_locations and item counts for all items at placement
for( item_stack::iterator it = stack_begin; it != stack_end; ++it ) {
if( spane.is_filtered( *it ) ) {
continue;
}
if( filter_buckets && it->is_bucket_nonempty() ) {
filtered_any_bucket = true;
continue;
}
if( spane.in_vehicle() ) {
g->u.activity.targets.emplace_back( vehicle_cursor( *sarea.veh, sarea.vstor ), &*it );
} else {
g->u.activity.targets.emplace_back( map_cursor( sarea.pos ), &*it );
}
// quantity of 0 means move all
g->u.activity.values.push_back( 0 );
}

if( filtered_any_bucket ) {
add_msg( m_info, _( "Skipping filled buckets to avoid spilling their contents." ) );
}

if( dpane.get_area() == AIM_WORN ) {
// TODO: Start ACT_WEAR in this case
debugmsg( "Wearing clothes using move all is not yet implemented" );
} else {
// Vehicle and map destinations are handled the same.
// Check first if the destination area still have enough room for moving all.
Expand Down Expand Up @@ -1013,12 +973,20 @@ bool advanced_inventory::move_all_items( bool nested_call )
add_msg( m_info, _( "Skipping filled buckets to avoid spilling their contents." ) );
}

g->u.assign_activity( player_activity( move_items_activity_actor(
target_items,
quantities,
dpane.in_vehicle(),
relative_destination
) ) );
if( dpane.get_area() == AIM_INVENTORY ) {
g->u.assign_activity( player_activity( pickup_activity_actor(
target_items,
quantities,
panes[src].in_vehicle() ? cata::nullopt : cata::optional<tripoint>( g->u.pos() )
) ) );
} else {
g->u.assign_activity( player_activity( move_items_activity_actor(
target_items,
quantities,
dpane.in_vehicle(),
relative_destination
) ) );
}
}

}
Expand Down Expand Up @@ -1187,13 +1155,8 @@ void advanced_inventory::start_activity( const aim_location destarea, const aim_

const bool by_charges = sitem->items.front()->count_by_charges();

if( destarea == AIM_INVENTORY || destarea == AIM_WORN ) {
if( destarea == AIM_INVENTORY ) {
g->u.assign_activity( ACT_PICKUP );
g->u.activity.coords.push_back( g->u.pos() );
} else {
g->u.assign_activity( ACT_WEAR );
}
if( destarea == AIM_WORN ) {
g->u.assign_activity( ACT_WEAR );

if( by_charges ) {
if( from_vehicle ) {
Expand All @@ -1217,10 +1180,6 @@ void advanced_inventory::start_activity( const aim_location destarea, const aim_
}
}
} else {
// Vehicle and map destinations are handled similarly.
// Stash the destination
const tripoint relative_destination = squares[destarea].off;

// Find target items and quantities thereof for the new activity
std::vector<item_location> target_items;
std::vector<int> quantities;
Expand All @@ -1246,12 +1205,23 @@ void advanced_inventory::start_activity( const aim_location destarea, const aim_
}
}

g->u.assign_activity( player_activity( move_items_activity_actor(
target_items,
quantities,
to_vehicle,
relative_destination
) ) );
if( destarea == AIM_INVENTORY ) {
g->u.assign_activity( player_activity( pickup_activity_actor(
target_items,
quantities,
from_vehicle ? cata::nullopt : cata::optional<tripoint>( g->u.pos() )
) ) );
} else {
// Stash the destination
const tripoint relative_destination = squares[destarea].off;

g->u.assign_activity( player_activity( move_items_activity_actor(
target_items,
quantities,
to_vehicle,
relative_destination
) ) );
}
}
}

Expand Down
Loading

0 comments on commit de16cb5

Please sign in to comment.