Skip to content

Commit

Permalink
Allow to return softwares for missions (#45434)
Browse files Browse the repository at this point in the history
* Check Software container in count_items
* Also count softwares in players pockets
* count_softwares
* find softwares hidden in pocketses
* Consume software container upon returning software for a quest
  • Loading branch information
Fris0uman authored Dec 3, 2020
1 parent c0ceab3 commit 7bf7d14
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
15 changes: 15 additions & 0 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2683,6 +2683,21 @@ int Character::amount_worn( const itype_id &id ) const
return amount;
}

int Character::count_softwares( const itype_id &id )
{
int count = 0;
for( const item_location &it_loc : all_items_loc() ) {
if( it_loc->is_software_storage() ) {
for( const item *soft : it_loc->softwares() ) {
if( soft->typeId() == id ) {
count++;
}
}
}
}
return count;
}

std::vector<item_location> Character::nearby( const
std::function<bool( const item *, const item * )> &func, int radius ) const
{
Expand Down
4 changes: 4 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,9 @@ class Character : public Creature, public visitable<Character>
/** Returns the amount of item `type' that is currently worn */
int amount_worn( const itype_id &id ) const;

/** Returns the amount of software `type' that are in the inventory */
int count_softwares( const itype_id &id );

/** Returns nearby items which match the provided predicate */
std::vector<item_location> nearby( const std::function<bool( const item *, const item * )> &func,
int radius = 1 ) const;
Expand Down Expand Up @@ -2530,6 +2533,7 @@ class Character : public Creature, public visitable<Character>
const tripoint &origin = tripoint_zero, int radius = PICKUP_RANGE );
std::list<item> consume_items( const std::vector<item_comp> &components, int batch = 1,
const std::function<bool( const item & )> &filter = return_true<item> );
bool consume_software_container( const itype_id &software_id );
comp_selection<tool_comp>
select_tool_component( const std::vector<tool_comp> &tools, int batch, inventory &map_inv,
bool can_cancel = false, bool player_inv = true,
Expand Down
24 changes: 23 additions & 1 deletion src/crafting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,11 @@ comp_selection<item_comp> Character::select_item_component( const std::vector<it
// Can't use pseudo items as components
if( player_inv ) {
bool found = false;
if( has_amount( type, count, false, filter ) ) {
const item item_sought( type );
if( item_sought.is_software() && count_softwares( type ) > 0 ) {
player_has.push_back( component );
found = true;
} else if( has_amount( type, count, false, filter ) ) {
player_has.push_back( component );
found = true;
}
Expand Down Expand Up @@ -1732,6 +1736,24 @@ std::list<item> Character::consume_items( const std::vector<item_comp> &componen
filter );
}

bool Character::consume_software_container( const itype_id &software_id )
{
for( item_location it : all_items_loc() ) {
if( !it.get_item() ) {
continue;
}
if( it.get_item()->is_software_storage() ) {
for( const item *soft : it.get_item()->softwares() ) {
if( soft->typeId() == software_id ) {
it.remove_item();
return true;
}
}
}
}
return false;
}

comp_selection<tool_comp>
Character::select_tool_component( const std::vector<tool_comp> &tools, int batch,
inventory &map_inv, bool can_cancel, bool player_inv,
Expand Down
31 changes: 28 additions & 3 deletions src/mission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ void mission::wrap_up()
status = mission_status::success;
player_character.on_mission_finished( *this );
std::vector<item_comp> comps;
const item item_sought( type->item_id );
switch( type->goal ) {
case MGOAL_FIND_ITEM_GROUP: {
inventory tmp_inv = player_character.crafting_inventory();
Expand Down Expand Up @@ -334,8 +335,20 @@ void mission::wrap_up()
break;

case MGOAL_FIND_ITEM:
comps.push_back( item_comp( type->item_id, item_count ) );
player_character.consume_items( comps );
if( item_sought.is_software() ) {
int consumed = 0;
while( consumed < item_count ) {
if( player_character.consume_software_container( type->item_id ) ) {
consumed++;
} else {
debugmsg( "Tried to consume more software %s than available", type->item_id.c_str() );
break;
}
}
} else {
comps.push_back( item_comp( type->item_id, item_count ) );
player_character.consume_items( comps );
}
break;
case MGOAL_FIND_ANY_ITEM:
player_character.remove_mission_items( uid );
Expand Down Expand Up @@ -399,11 +412,20 @@ bool mission::is_complete( const character_id &_npc_id ) const
map &here = get_map();
int found_quantity = 0;
bool charges = item_sought.count_by_charges();
auto count_items = [this, &found_quantity, &player_character, charges]( item_stack && items ) {
bool software = item_sought.is_software();
auto count_items = [this, &found_quantity, &player_character, charges, software]( item_stack &&
items ) {
for( const item &i : items ) {
if( !i.is_owned_by( player_character, true ) ) {
continue;
}
if( software ) {
for( const item *soft : i.softwares() ) {
if( soft->typeId() == type->item_id ) {
found_quantity ++;
}
}
}
if( charges ) {
found_quantity += i.charges_of( type->item_id, item_count - found_quantity );
} else {
Expand All @@ -425,6 +447,9 @@ bool mission::is_complete( const character_id &_npc_id ) const
}
}
}
if( software ) {
found_quantity += player_character.count_softwares( type->item_id );
}
if( charges ) {
return player_character.charges_of( type->item_id ) + found_quantity >= item_count;
} else {
Expand Down

0 comments on commit 7bf7d14

Please sign in to comment.