Skip to content

Commit

Permalink
encapsulate item::contents into a new class
Browse files Browse the repository at this point in the history
  • Loading branch information
KorGgenT committed Feb 17, 2020
1 parent 6f746e2 commit 1e4e3ad
Show file tree
Hide file tree
Showing 48 changed files with 728 additions and 607 deletions.
37 changes: 20 additions & 17 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,6 @@ void activity_handlers::butcher_finish( player_activity *act, player *p )
}

item &corpse_item = *target;
std::list<item> contents = corpse_item.contents;
const mtype *corpse = corpse_item.get_mtype();
const field_type_id type_blood = corpse->bloodType();
const field_type_id type_gib = corpse->gibType();
Expand Down Expand Up @@ -1113,16 +1112,17 @@ void activity_handlers::butcher_finish( player_activity *act, player *p )
// therefore operations on this activities targets and values may be invalidated.
// reveal hidden items / hidden content
if( action != F_DRESS && action != SKIN ) {
for( auto &content : contents ) {
corpse_item.visit_items( [&]( item * content ) {
if( ( roll_butchery() + 10 ) * 5 > rng( 0, 100 ) ) {
//~ %1$s - item name, %2$s - monster name
p->add_msg_if_player( m_good, _( "You discover a %1$s in the %2$s!" ), content.tname(),
p->add_msg_if_player( m_good, _( "You discover a %1$s in the %2$s!" ), content->tname(),
corpse->nname() );
g->m.add_item_or_charges( p->pos(), content );
} else if( content.is_bionic() ) {
g->m.add_item_or_charges( p->pos(), *content );
} else if( content->is_bionic() ) {
g->m.spawn_item( p->pos(), "burnt_out_bionic", 1, 0, calendar::turn );
}
}
return VisitResponse::NEXT;
} );
}

//end messages and effects
Expand Down Expand Up @@ -2656,7 +2656,7 @@ void activity_handlers::gunmod_add_finish( player_activity *act, player *p )
if( rng( 0, 100 ) <= roll ) {
add_msg( m_good, _( "You successfully attached the %1$s to your %2$s." ), mod.tname(),
gun.tname() );
gun.contents.push_back( p->i_rem( &mod ) );
gun.put_in( p->i_rem( &mod ) );

} else if( rng( 0, 100 ) <= risk ) {
if( gun.inc_damage() ) {
Expand Down Expand Up @@ -2691,7 +2691,7 @@ void activity_handlers::toolmod_add_finish( player_activity *act, player *p )
p->add_msg_if_player( m_good, _( "You successfully attached the %1$s to your %2$s." ),
mod.tname(), tool.tname() );
mod.item_tags.insert( "IRREMOVABLE" );
tool.contents.push_back( mod );
tool.put_in( mod );
act->targets[1].remove_item();
}

Expand Down Expand Up @@ -3966,15 +3966,18 @@ void activity_handlers::unload_mag_finish( player_activity *act, player *p )
int qty = 0;
item &it = *act->targets[ 0 ];

// remove the ammo leads in the belt
it.contents.erase( std::remove_if( it.contents.begin(),
it.contents.end(), [&]( item & e ) {
if( !p->add_or_drop_with_msg( e, true ) ) {
return false;
std::vector<item *> remove_contained;
it.visit_items( [&]( item * contained ) {
if( p->add_or_drop_with_msg( *contained, true ) ) {
qty += contained->charges;
remove_contained.push_back( contained );
}
qty += e.charges;
return true;
} ), it.contents.end() );
return VisitResponse::NEXT;
} );
// remove the ammo leads in the belt
for( item *remove : remove_contained ) {
it.remove_item( *remove );
}

// remove the belt linkage
if( it.is_ammo_belt() ) {
Expand Down Expand Up @@ -4584,6 +4587,6 @@ void activity_handlers::mind_splicer_finish( player_activity *act, player *p )
item &data_card = *act->targets[0];
p->add_msg_if_player( m_info, _( "…you finally find the memory banks." ) );
p->add_msg_if_player( m_info, _( "The kit makes a copy of the data inside the bionic." ) );
data_card.contents.clear();
data_card.contents.clear_items();
data_card.put_in( item( "mind_scan_robofac" ) );
}
2 changes: 1 addition & 1 deletion src/advanced_inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1632,7 +1632,7 @@ bool advanced_inventory::move_content( item &src_container, item &dest_container

uistate.adv_inv_container_content_type = dest_container.contents.front().typeId();
if( src_contents.charges <= 0 ) {
src_container.contents.clear();
src_container.contents.clear_items();
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion src/avatar_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ void avatar_action::eat( avatar &you, item_location loc )

} else if( you.consume_item( *it ) ) {
if( it->is_food_container() || !you.can_consume_as_is( *it ) ) {
it->contents.erase( it->contents.begin() );
it->remove_item( it->contents.front() );
add_msg( _( "You leave the empty %s." ), it->tname() );
} else {
loc.remove_item();
Expand Down
15 changes: 8 additions & 7 deletions src/ballistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
static void drop_or_embed_projectile( const dealt_projectile_attack &attack )
{
const auto &proj = attack.proj;
const auto &drop_item = proj.get_drop();
const item &drop_item = proj.get_drop();
const auto &effects = proj.proj_effects;
if( drop_item.is_null() ) {
return;
Expand All @@ -52,9 +52,11 @@ static void drop_or_embed_projectile( const dealt_projectile_attack &attack )
add_msg( _( "The %s shatters!" ), drop_item.tname() );
}

for( const item &i : drop_item.contents ) {
g->m.add_item_or_charges( pt, i );
}
drop_item.visit_items( [&pt]( const item * it ) {
g->m.add_item_or_charges( pt, *it );
return VisitResponse::NEXT;
} );

// TODO: Non-glass breaking
// TODO: Wine glass breaking vs. entire sheet of glass breaking
sounds::sound( pt, 16, sounds::sound_t::combat, _( "glass breaking!" ), false, "bullet_hit",
Expand All @@ -68,9 +70,8 @@ static void drop_or_embed_projectile( const dealt_projectile_attack &attack )
add_msg( _( "The %s bursts!" ), drop_item.tname() );
}

for( const item &i : drop_item.contents ) {
g->m.add_item_or_charges( pt, i );
}
// copies the drop item to spill the contents
item( drop_item ).spill_contents( pt );

// TODO: Sound
return;
Expand Down
10 changes: 5 additions & 5 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1660,11 +1660,9 @@ item Character::i_rem( const item *it )
return tmp.front();
}

void Character::i_rem_keep_contents( const int pos )
void Character::i_rem_keep_contents( const int idx )
{
for( auto &content : i_rem( pos ).contents ) {
i_add_or_drop( content );
}
i_rem( idx ).spill_contents( pos() );
}

bool Character::i_add_or_drop( item &it, int qty )
Expand Down Expand Up @@ -7365,7 +7363,9 @@ void Character::absorb_hit( body_part bp, damage_instance &dam )
destroyed_armor_msg( *this, pre_damage_name );
armor_destroyed = true;
armor.on_takeoff( *this );
worn_remains.insert( worn_remains.end(), armor.contents.begin(), armor.contents.end() );
for( const item *it : armor.contents.all_items_top() ) {
worn_remains.push_back( *it );
}
// decltype is the type name of the iterator, note that reverse_iterator::base returns the
// iterator to the next element, not the one the revers_iterator points to.
// http://stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-iterator
Expand Down
2 changes: 1 addition & 1 deletion src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ class Character : public Creature, public visitable<Character>
* @return A copy of the removed item.
*/
item i_rem( const item *it );
void i_rem_keep_contents( int pos );
void i_rem_keep_contents( int idx );
/** Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded.
* An optional qty can be provided (and will perform better than separate calls). */
bool i_add_or_drop( item &it, int qty = 1 );
Expand Down
4 changes: 2 additions & 2 deletions src/computer_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ void computer_session::action_download_software()
g->u.moves -= 30;
item software( miss->get_item_id(), 0 );
software.mission_id = comp.mission_id;
usb->contents.clear();
usb->contents.clear_items();
usb->put_in( software );
print_line( _( "Software downloaded." ) );
} else {
Expand Down Expand Up @@ -728,7 +728,7 @@ void computer_session::action_blood_anal()
if( query_bool( _( "Download data?" ) ) ) {
if( item *const usb = pick_usb() ) {
item software( "software_blood_data", 0 );
usb->contents.clear();
usb->contents.clear_items();
usb->put_in( software );
print_line( _( "Software downloaded." ) );
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ std::pair<nutrients, nutrients> Character::compute_nutrient_range(
nutrients this_max;

item result_it = rec->create_result();
if( result_it.contents.size() == 1 ) {
if( result_it.contents.num_item_stacks() == 1 ) {
const item alt_result = result_it.contents.front();
if( alt_result.typeId() == comest_it.typeId() ) {
result_it = alt_result;
Expand Down
19 changes: 9 additions & 10 deletions src/crafting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,11 +1540,11 @@ static void empty_buckets( player &p )
return it.is_bucket_nonempty() && &it != &p.weapon;
}, INT_MAX );
for( auto &it : buckets ) {
for( const item &in : it.contents ) {
drop_or_handle( in, p );
for( const item *in : it.contents.all_items_top() ) {
drop_or_handle( *in, p );
}

it.contents.clear();
it.contents.clear_items();
drop_or_handle( it, p );
}
}
Expand Down Expand Up @@ -2302,14 +2302,13 @@ void drop_or_handle( const item &newit, player &p )

void remove_ammo( item &dis_item, player &p )
{
for( auto iter = dis_item.contents.begin(); iter != dis_item.contents.end(); ) {
if( iter->is_irremovable() ) {
iter++;
continue;
dis_item.remove_items_with( [&p]( const item & it ) {
if( it.is_irremovable() ) {
return false;
}
drop_or_handle( *iter, p );
iter = dis_item.contents.erase( iter );
}
drop_or_handle( it, p );
return true;
} );

if( dis_item.has_flag( flag_NO_UNLOAD ) ) {
return;
Expand Down
6 changes: 3 additions & 3 deletions src/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ bool game::dump_stats( const std::string &what, dump_mode mode,
test_items[ "G2" ] = item( "hk_mp5" ).ammo_set( "9mm" );
test_items[ "G3" ] = item( "ar15" ).ammo_set( "223" );
test_items[ "G4" ] = item( "remington_700" ).ammo_set( "270" );
test_items[ "G4" ].emplace_back( "rifle_scope" );
test_items[ "G4" ].put_in( item( "rifle_scope" ) );

if( what == "AMMO" ) {
header = {
Expand Down Expand Up @@ -212,14 +212,14 @@ bool game::dump_stats( const std::string &what, dump_mode mode,
if( e->gun ) {
item gun( e );
if( !gun.magazine_integral() ) {
gun.emplace_back( gun.magazine_default() );
gun.put_in( item( gun.magazine_default() ) );
}
gun.ammo_set( gun.ammo_default( false ), gun.ammo_capacity() );

dump( test_npcs[ "S1" ], gun );

if( gun.type->gun->barrel_length > 0_ml ) {
gun.emplace_back( "barrel_small" );
gun.put_in( item( "barrel_small" ) );
dump( test_npcs[ "S1" ], gun );
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/faction_camp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3700,7 +3700,7 @@ bool basecamp::distribute_food()
for( item &i : initial_items ) {
if( i.is_container() && i.get_contained().is_food() ) {
auto comest = i.get_contained();
i.contents.clear();
i.contents.clear_items();
//NPCs are lazy bastards who leave empties all around the camp fire
tripoint litter_spread = p_litter;
litter_spread.x += rng( -3, 3 );
Expand Down
2 changes: 1 addition & 1 deletion src/gamemode_defense.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ void defense_game::caravan()
// Guns bought from the caravan should always come with an empty
// magazine.
if( tmp.is_gun() && !tmp.magazine_integral() ) {
tmp.emplace_back( tmp.magazine_default() );
tmp.put_in( item( tmp.magazine_default() ) );
}

for( int j = 0; j < item_count[0][i]; j++ ) {
Expand Down
4 changes: 1 addition & 3 deletions src/handle_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,9 +712,7 @@ static void smash()
if( u.weapon.made_of( material_id( "glass" ) ) &&
rng( 0, vol + 3 ) < vol ) {
add_msg( m_bad, _( "Your %s shatters!" ), u.weapon.tname() );
for( auto &elem : u.weapon.contents ) {
m.add_item_or_charges( u.pos(), elem );
}
u.weapon.spill_contents( u.pos() );
sounds::sound( u.pos(), 24, sounds::sound_t::combat, "CRACK!", true, "smash", "glass" );
u.deal_damage( nullptr, bp_hand_r, damage_instance( DT_CUT, rng( 0, vol ) ) );
if( vol > 20 ) {
Expand Down
21 changes: 14 additions & 7 deletions src/handle_liquid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ bool handle_liquid_from_ground( map_stack::iterator on_ground,
return true;
}

bool handle_liquid_from_container( std::list<item>::iterator in_container,
bool handle_liquid_from_container( item *in_container,
item &container, int radius )
{
// TODO: not all code paths on handle_liquid consume move points, fix that.
Expand All @@ -131,16 +131,23 @@ bool handle_liquid_from_container( std::list<item>::iterator in_container,
container.on_contents_changed();
}

if( in_container->charges > 0 ) {
return false;
}
container.contents.erase( in_container );
return true;
return in_container->charges <= 0;
}

bool handle_liquid_from_container( item &container, int radius )
{
return handle_liquid_from_container( container.contents.begin(), container, radius );
std::vector<item *> remove;
bool handled = false;
for( item *contained : container.contents.all_items_top() ) {
if( handle_liquid_from_container( contained, container, radius ) ) {
remove.push_back( contained );
handled = true;
}
}
for( item *contained : remove ) {
container.remove_item( *contained );
}
return handled;
}

static bool get_liquid_target( item &liquid, item *const source, const int radius,
Expand Down
2 changes: 1 addition & 1 deletion src/handle_liquid.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ bool handle_liquid_from_ground( map_stack::iterator on_ground, const tripoint &p
* The iterator is invalidated in that case. Otherwise the item remains but may have
* fewer charges.
*/
bool handle_liquid_from_container( std::list<item>::iterator in_container, item &container,
bool handle_liquid_from_container( item *in_container, item &container,
int radius = 0 );
/**
* Shortcut to the above: handles the first item in the container.
Expand Down
Loading

0 comments on commit 1e4e3ad

Please sign in to comment.