Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encapsulate item::contents #38026

Merged
merged 1 commit into from
Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 20 additions & 17 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,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 @@ -1290,16 +1289,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 @@ -2898,7 +2898,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 @@ -2933,7 +2933,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 @@ -4304,15 +4304,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 @@ -4923,6 +4926,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 @@ -1693,7 +1693,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 @@ -1083,7 +1083,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 @@ -41,7 +41,7 @@ static const std::string flag_LIQUID( "LIQUID" );
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 @@ -55,9 +55,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 @@ -71,9 +73,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 @@ -2231,11 +2231,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 @@ -8059,7 +8057,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 @@ -1160,7 +1160,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 @@ -701,7 +701,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 @@ -739,7 +739,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 @@ -390,7 +390,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 @@ -1570,11 +1570,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 @@ -2331,14 +2331,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 @@ -68,7 +68,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 @@ -213,14 +213,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 @@ -3873,7 +3873,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 @@ -1106,7 +1106,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 @@ -788,9 +788,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