Skip to content

Commit

Permalink
refactor game::inv_for_filter
Browse files Browse the repository at this point in the history
- rescope to game_menus::inv::
- rename function to titled_filter_menu
- remove superfluous functions in favor of generic filter function
- fix function calls
- return item_location instead of int pos
- add avatar parameter
  • Loading branch information
KorGgenT committed Dec 14, 2019
1 parent 302d020 commit 7985946
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 87 deletions.
11 changes: 8 additions & 3 deletions src/computer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "creature.h"
#include "enums.h"
#include "game_constants.h"
#include "game_inventory.h"
#include "int_id.h"
#include "item.h"
#include "omdata.h"
Expand Down Expand Up @@ -366,9 +367,13 @@ void computer::load_data( const std::string &data )

static item *pick_usb()
{
const int pos = g->inv_for_id( itype_id( "usb_drive" ), _( "Choose drive:" ) );
if( pos != INT_MIN ) {
return &g->u.i_at( pos );
auto filter = []( const item & it ) {
return it.typeId() == "usb_drive";
};

item_location loc = game_menus::inv::titled_filter_menu( filter, g->u, _( "Choose drive:" ) );
if( loc ) {
return &*loc;
}
return nullptr;
}
Expand Down
12 changes: 7 additions & 5 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5334,13 +5334,13 @@ bool game::npc_menu( npc &who )
actor->head_power >= 0 &&
actor->torso_power >= 0;
};
const int pos = inv_for_filter( _( "Use which item?" ), will_accept );
item_location loc = game_menus::inv::titled_filter_menu( will_accept, u, _( "Use which item?" ) );

if( pos == INT_MIN ) {
if( !loc ) {
add_msg( _( "Never mind" ) );
return false;
}
item &used = u.i_at( pos );
item &used = *loc;
bool did_use = u.invoke_item( &used, heal_string, who.pos() );
if( did_use ) {
// Note: exiting a body part selection menu counts as use here
Expand Down Expand Up @@ -8339,9 +8339,11 @@ void game::butcher()
void game::change_side( int pos )
{
if( pos == INT_MIN ) {
pos = inv_for_filter( _( "Change side for item" ), [&]( const item & it ) {
auto filter = [&]( const item & it ) {
return u.is_worn( it ) && it.is_sided();
}, _( "You don't have sided items worn." ) );
};
pos = u.get_item_position( game_menus::inv::titled_filter_menu( filter, u,
_( "Change side for item" ), _( "You don't have sided items worn." ) ).get_item() );
}
if( pos == INT_MIN ) {
add_msg( _( "Never mind." ) );
Expand Down
6 changes: 0 additions & 6 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,12 +562,6 @@ class game

void draw_trail_to_square( const tripoint &t, bool bDrawX );

// TODO: Move these functions to game_menus::inv and isolate them.
int inv_for_filter( const std::string &title, item_filter filter,
const std::string &none_message = "" );
int inv_for_flag( const std::string &flag, const std::string &title );
int inv_for_id( const itype_id &id, const std::string &title );

enum inventory_item_menu_positon {
RIGHT_TERMINAL_EDGE,
LEFT_OF_INFO,
Expand Down
21 changes: 4 additions & 17 deletions src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,11 @@ void game_menus::inv::common( avatar &you )
} while( loop_options.count( res ) != 0 );
}

int game::inv_for_filter( const std::string &title, item_filter filter,
const std::string &none_message )
item_location game_menus::inv::titled_filter_menu( item_filter filter, avatar &you,
const std::string &title, const std::string &none_message )
{
return u.get_item_position( inv_map_splice( filter, title, -1, none_message ).get_item() );
return inv_internal( you, inventory_filter_preset( convert_filter( filter ) ),
title, -1, none_message );
}

item_location game_menus::inv::titled_menu( avatar &you, const std::string &title,
Expand All @@ -220,20 +221,6 @@ item_location game_menus::inv::titled_menu( avatar &you, const std::string &titl
return inv_internal( you, inventory_selector_preset(), title, -1, msg );
}

int game::inv_for_flag( const std::string &flag, const std::string &title )
{
return inv_for_filter( title, [ &flag ]( const item & it ) {
return it.has_flag( flag );
} );
}

int game::inv_for_id( const itype_id &id, const std::string &title )
{
return inv_for_filter( title, [ &id ]( const item & it ) {
return it.typeId() == id;
}, string_format( _( "You don't have a %s." ), item::nname( id ) ) );
}

class armor_inventory_preset: public inventory_selector_preset
{
public:
Expand Down
4 changes: 4 additions & 0 deletions src/game_inventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class player;
class salvage_actor;
class repair_item_actor;

using item_filter = std::function<bool( const item & )>;
using item_location_filter = std::function<bool ( const item_location & )>;

class inventory_filter_preset : public inventory_selector_preset
Expand All @@ -42,6 +43,9 @@ namespace inv
// item selector for all items in @you's inventory.
item_location titled_menu( avatar &you, const std::string &title,
const std::string &none_message = "" );
// item selector for items in @you's inventory with a filter
item_location titled_filter_menu( item_filter filter, avatar &you,
const std::string &title, const std::string &none_message = "" );

/**
* @name Customized inventory menus
Expand Down
145 changes: 102 additions & 43 deletions src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1589,15 +1589,19 @@ int iuse::radio_mod( player *p, item *, bool, const tripoint & )
return 0;
}

int inventory_index = g->inv_for_filter( _( "Modify what?" ), []( const item & itm ) {
auto filter = []( const item & itm ) {
return itm.has_flag( "RADIO_MODABLE" );
} );
item &modded = p->i_at( inventory_index );
};

// note: if !p->is_npc() then p is avatar
item_location loc = game_menus::inv::titled_filter_menu(
filter, *p->as_avatar(), _( "Modify what?" ) );

if( modded.is_null() ) {
if( !loc ) {
p->add_msg_if_player( _( "You do not have that item!" ) );
return 0;
}
item &modded = *loc;

int choice = uilist( _( "Which signal should activate the item?" ), {
_( "\"Red\"" ), _( "\"Blue\"" ), _( "\"Green\"" )
Expand Down Expand Up @@ -4621,12 +4625,20 @@ int iuse::mind_splicer( player *p, item *it, bool, const tripoint & )
if( map_it.typeId() == "rmi2_corpse" &&
query_yn( _( "Use the mind splicer kit on the %s?" ), colorize( map_it.tname(),
map_it.color_in_inventory() ) ) ) {
int pos = g->inv_for_id( itype_id( "data_card" ), _( "Select storage media" ) );
item &data_card = p->i_at( pos );
if( data_card.is_null() ) {

auto filter = []( const item & it ) {
return it.typeId() == "data_card";
};
avatar *you = p->as_avatar();
item_location loc;
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu( filter, *you, _( "Select storage media" ) );
}
if( !loc ) {
add_msg( m_info, _( "Nevermind." ) );
return 0;
}
item &data_card = *loc;
///\EFFECT_DEX makes using the mind splicer faster
///\EFFECT_FIRSTAID makes using the mind splicer faster
const time_duration time = std::max( 150_minutes - 20_minutes * ( p->get_skill_level(
Expand Down Expand Up @@ -4674,15 +4686,20 @@ int iuse::lumber( player *p, item *it, bool t, const tripoint & )
}

// If the player is not standing on a log, check inventory
int pos = g->inv_for_id( itype_id( "log" ), _( "Cut up what?" ) );

item &cut = p->i_at( pos );
avatar *you = p->as_avatar();
item_location loc;
auto filter = []( const item & it ) {
return it.typeId() == "log";
};
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu( filter, *you, _( "Cut up what?" ) );
}

if( cut.is_null() ) {
if( !loc ) {
p->add_msg_if_player( m_info, _( "You do not have that item!" ) );
return 0;
}
p->i_rem( &cut );
p->i_rem( &*loc );
cut_log_into_planks( *p );
return it->type->charges_to_use();
}
Expand Down Expand Up @@ -6009,21 +6026,31 @@ int iuse::misc_repair( player *p, item *it, bool, const tripoint & )
p->add_msg_if_player( m_info, _( "You need a fabrication skill of 1 to use this repair kit." ) );
return 0;
}
static const std::set<material_id> repairable {
static const std::set<material_id> repairable{
material_id( "wood" ),
material_id( "paper" ),
material_id( "bone" ),
material_id( "chitin" ),
material_id( "acidchitin" )
};
int inventory_index = g->inv_for_filter( _( "Select the item to repair" ), []( const item & itm ) {

auto filter = []( const item & itm ) {
return !itm.is_firearm() && itm.made_of_any( repairable ) && !itm.count_by_charges();
} );
item &fix = p->i_at( inventory_index );
if( fix.is_null() ) {
};

item_location loc;
avatar *you = p->as_avatar();
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu(
filter, *you, _( "Select the item to repair" ) );
}

if( !loc ) {
p->add_msg_if_player( m_info, _( "You do not have that item!" ) );
return 0;
}
item &fix = *loc;

if( fix.damage() <= fix.min_damage() ) {
p->add_msg_if_player( m_info, _( "You cannot improve your %s any more this way." ),
fix.tname() );
Expand Down Expand Up @@ -6686,17 +6713,26 @@ int iuse::einktabletpc( player *p, item *it, bool t, const tripoint &pos )
return it->type->charges_to_use();
}

avatar *you = p->as_avatar();
item_location loc;
auto filter = []( const item & it ) {
return it.has_flag( "MC_MOBILE" );
};
const std::string title = _( "Insert memory card" );

if( ei_download == choice ) {

p->moves -= to_moves<int>( 2_seconds );

const int inventory_index = g->inv_for_flag( "MC_MOBILE", _( "Insert memory card" ) );
item &mc = p->i_at( inventory_index );

if( mc.is_null() ) {
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu( filter, *you, title );
}
if( !loc ) {
p->add_msg_if_player( m_info, _( "You do not have that item!" ) );
return it->type->charges_to_use();
}
item &mc = *loc;

if( !mc.has_flag( "MC_MOBILE" ) ) {
p->add_msg_if_player( m_info, _( "This is not a compatible memory card." ) );
return it->type->charges_to_use();
Expand All @@ -6720,13 +6756,15 @@ int iuse::einktabletpc( player *p, item *it, bool t, const tripoint &pos )

if( ei_decrypt == choice ) {
p->moves -= to_moves<int>( 2_seconds );
const int inventory_index = g->inv_for_flag( "MC_MOBILE", _( "Insert memory card" ) );
item &mc = p->i_at( inventory_index );

if( mc.is_null() ) {
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu( filter, *you, title );
}
if( !loc ) {
p->add_msg_if_player( m_info, _( "You do not have that item!" ) );
return it->type->charges_to_use();
}
item &mc = *loc;

if( !mc.has_flag( "MC_MOBILE" ) ) {
p->add_msg_if_player( m_info, _( "This is not a compatible memory card." ) );
return it->type->charges_to_use();
Expand Down Expand Up @@ -7796,13 +7834,19 @@ int iuse::camera( player *p, item *it, bool, const tripoint & )

p->moves -= to_moves<int>( 2_seconds );

const int inventory_index = g->inv_for_flag( "MC_MOBILE", _( "Insert memory card" ) );
item &mc = p->i_at( inventory_index );

if( mc.is_null() ) {
avatar *you = p->as_avatar();
item_location loc;
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu( []( const item & it ) {
return it.has_flag( "MC_MOBILE" );
}, *you, _( "Insert memory card" ) );
}
if( !loc ) {
p->add_msg_if_player( m_info, _( "You do not have that item!" ) );
return it->type->charges_to_use();
}
item &mc = *loc;

if( !mc.has_flag( "MC_MOBILE" ) ) {
p->add_msg_if_player( m_info, _( "This is not a compatible memory card." ) );
return it->type->charges_to_use();
Expand Down Expand Up @@ -7989,19 +8033,26 @@ int iuse::radiocar( player *p, item *it, bool, const tripoint & )
if( choice == 1 ) {

if( bomb_it == it->contents.end() ) { //arming car with bomb
int inventory_index = g->inv_for_flag( "RADIOCARITEM", _( "Arm what?" ) );
item &put = p->i_at( inventory_index );
if( put.is_null() ) {

avatar *you = p->as_avatar();
item_location loc;
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu( []( const item & it ) {
return it.has_flag( "RADIOCARITEM" );
}, *you, _( "Arm what?" ) );
}
if( !loc ) {
p->add_msg_if_player( m_info, _( "You do not have that item!" ) );
return 0;
}
item &put = *loc;

if( put.has_flag( "RADIOCARITEM" ) && ( put.volume() <= 1250_ml ||
( put.weight() <= 2_kilogram ) ) ) {
p->moves -= to_moves<int>( 3_seconds );
p->add_msg_if_player( _( "You armed your RC car with %s." ),
put.tname() );
it->put_in( p->i_rem( inventory_index ) );
it->put_in( p->i_rem( &put ) );
} else if( !put.has_flag( "RADIOCARITEM" ) ) {
p->add_msg_if_player( _( "RC car with %s? How?" ),
put.tname() );
Expand Down Expand Up @@ -8826,6 +8877,16 @@ int iuse::cable_attach( player *p, item *it, bool, const tripoint & )
const bool wearing_solar_pack = has_solar_pack || has_solar_pack_on;
const bool has_ups = p->has_charges( "UPS_off", 1 ) || p->has_charges( "adv_UPS_off", 1 );

item_location loc;
avatar *you = p->as_avatar();

auto filter = [&]( const item & itm ) {
return itm.has_flag( "IS_UPS" );
};

const std::string choose_ups = _( "Choose UPS:" );
const std::string dont_have_ups = _( "You don't have any UPS." );

const auto set_cable_active = []( player * p, item * it, const std::string & state ) {
it->set_var( "state", state );
it->active = true;
Expand Down Expand Up @@ -8858,14 +8919,14 @@ int iuse::cable_attach( player *p, item *it, bool, const tripoint & )
p->add_msg_if_player( m_info, _( "You attach the cable to the solar pack." ) );
return 0;
} else if( choice == 3 ) {
int pos = g->inv_for_filter( _( "Choose UPS:" ), [&]( const item & itm ) {
return itm.has_flag( "IS_UPS" );
}, _( "You don't have any UPS." ) );
if( pos == INT_MIN ) {
if( you != nullptr ) {
loc = game_menus::inv::titled_filter_menu( filter, *you, choose_ups, dont_have_ups );
}
if( !loc ) {
add_msg( _( "Never mind" ) );
return 0;
}
item &chosen = p->i_at( pos );
item &chosen = *loc;
chosen.set_var( "cable", "plugged_in" );
chosen.activate();
set_cable_active( p, it, "UPS" );
Expand Down Expand Up @@ -8963,15 +9024,13 @@ int iuse::cable_attach( player *p, item *it, bool, const tripoint & )
p->add_msg_if_player( m_good, _( "You are now plugged to the solar backpack." ) );
return 0;
} else if( choice == 4 ) {
loc = game_menus::inv::titled_filter_menu( filter, *you, choose_ups, dont_have_ups );
// connecting self to UPS
int pos = g->inv_for_filter( _( "Choose UPS:" ), [&]( const item & itm ) {
return itm.has_flag( "IS_UPS" );
}, _( "You don't have any UPS." ) );
if( pos == INT_MIN ) {
if( !loc ) {
add_msg( _( "Never mind" ) );
return 0;
}
item &chosen = p->i_at( pos );
item &chosen = *loc;
chosen.set_var( "cable", "plugged_in" );
chosen.activate();
set_cable_active( p, it, "UPS_link" );
Expand Down
Loading

0 comments on commit 7985946

Please sign in to comment.