Skip to content

Commit

Permalink
Preserve ammo linkage on zone unload
Browse files Browse the repository at this point in the history
  • Loading branch information
robob27 committed Dec 4, 2022
1 parent 1894579 commit 6a71a8d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6430,8 +6430,18 @@ void unload_loot_activity_actor::do_turn( player_activity &act, Character &you )
for( item *contained : it->first->all_items_top( item_pocket::pocket_type::MAGAZINE ) ) {
// no liquids don't want to spill stuff
if( !contained->made_of( phase_id::LIQUID ) && !contained->made_of( phase_id::GAS ) ) {
if( it->first->is_ammo_belt() ) {
if( it->first->type->magazine->linkage ) {
item link( *it->first->type->magazine->linkage, calendar::turn, contained->count() );
here.add_item_or_charges( src_loc, link );
}
}
move_item( you, *contained, contained->count(), src_loc, src_loc, this_veh, this_part );
it->first->remove_item( *contained );

if( it->first->has_flag( flag_MAG_DESTROY ) && it->first->ammo_remaining() == 0 ) {
here.i_rem( src_loc, it->first );
}
}
if( you.moves <= 0 ) {
return;
Expand Down
10 changes: 10 additions & 0 deletions src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2276,8 +2276,18 @@ void activity_on_turn_move_loot( player_activity &act, Character &you )
for( item *contained : it->first->all_items_top( item_pocket::pocket_type::MAGAZINE ) ) {
// no liquids don't want to spill stuff
if( !contained->made_of( phase_id::LIQUID ) && !contained->made_of( phase_id::GAS ) ) {
if( it->first->is_ammo_belt() ) {
if( it->first->type->magazine->linkage ) {
item link( *it->first->type->magazine->linkage, calendar::turn, contained->count() );
here.add_item_or_charges( src_loc, link );
}
}
move_item( you, *contained, contained->count(), src_loc, src_loc, this_veh, this_part );
it->first->remove_item( *contained );

if( it->first->has_flag( flag_MAG_DESTROY ) && it->first->ammo_remaining() == 0 ) {
here.i_rem( src_loc, it->first );
}
}
}
for( item *contained : it->first->all_items_top( item_pocket::pocket_type::MAGAZINE_WELL ) ) {
Expand Down
52 changes: 52 additions & 0 deletions tests/clzones_test.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,81 @@
#include <iosfwd>
#include <vector>

#include "activity_actor_definitions.h"
#include "cata_catch.h"
#include "clzones.h"
#include "item.h"
#include "item_category.h"
#include "item_pocket.h"
#include "map_helpers.h"
#include "player_helpers.h"
#include "point.h"
#include "ret_val.h"
#include "type_id.h"

static const faction_id faction_your_followers( "your_followers" );

static const itype_id itype_556( "556" );
static const itype_id itype_ammolink223( "ammolink223" );
static const itype_id itype_belt223( "belt223" );

static const zone_type_id zone_type_LOOT_DRINK( "LOOT_DRINK" );
static const zone_type_id zone_type_LOOT_FOOD( "LOOT_FOOD" );
static const zone_type_id zone_type_LOOT_PDRINK( "LOOT_PDRINK" );
static const zone_type_id zone_type_LOOT_PFOOD( "LOOT_PFOOD" );
static const zone_type_id zone_type_zone_unload_all( "zone_unload_all" );

static int count_items_or_charges( const tripoint src, const itype_id &id )
{
int n = 0;
map_stack items = get_map().i_at( src );
for( const item &it : items ) {
if( it.typeId() == id ) {
n += it.count();
}
}
return n;
}

static void create_tile_zone( const std::string &name, const zone_type_id &zone_type, tripoint pos )
{
zone_manager &zm = zone_manager::get_manager();
zm.add( name, zone_type, faction_your_followers, false, true, pos, pos );
}

TEST_CASE( "zone unloading ammo belts", "[zones][items][ammo_belt][activities][unload]" )
{
avatar &dummy = get_avatar();
map &here = get_map();

clear_avatar();
clear_map();

tripoint_abs_ms const start = here.getglobal( tripoint_east );
dummy.set_location( start );
create_tile_zone( "Unload All", zone_type_zone_unload_all, start.raw() );

item ammo_belt = item( itype_belt223, calendar::turn );
ammo_belt.ammo_set( ammo_belt.ammo_default() );
int belt_ammo_count_before_unload = ammo_belt.ammo_remaining();

REQUIRE( belt_ammo_count_before_unload > 0 );

WHEN( "unloading ammo belts using zone_unload_all " ) {
here.add_item_or_charges( tripoint_east, ammo_belt );
dummy.assign_activity(
player_activity( unload_loot_activity_actor() ) );
process_activity( dummy );

THEN( "check that the ammo and linkages are both unloaded and the ammo belt is removed" ) {
CHECK( count_items_or_charges( tripoint_east, itype_belt223 ) == 0 );
CHECK( count_items_or_charges( tripoint_east,
itype_ammolink223 ) == belt_ammo_count_before_unload );
CHECK( count_items_or_charges( tripoint_east, itype_556 ) == belt_ammo_count_before_unload );
}
}
}

// Comestibles sorting is a bit awkward. Unlike other loot, they're almost
// always inside of a container, and their sort zone changes based on their
// shelf life and whether the container prevents rotting.
Expand Down

0 comments on commit 6a71a8d

Please sign in to comment.