diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index e5ac8df0c0d83..2da1913ce02a4 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -14,8 +14,10 @@ #include "avatar.h" #include "creature.h" #include "game.h" +#include "game_inventory.h" #include "input.h" #include "item.h" +#include "item_location.h" #include "itype.h" #include "line.h" #include "map.h" @@ -954,3 +956,72 @@ void avatar_action::plthrow( avatar &you, int pos, you.throw_item( trajectory.back(), thrown, blind_throw_from_pos ); g->reenter_fullscreen(); } + +static void make_active( item_location loc ) +{ + switch( loc.where() ) { + case item_location::type::map: + g->m.make_active( loc ); + break; + case item_location::type::vehicle: + g->m.veh_at( loc.position() )->vehicle().make_active( loc ); + break; + default: + break; + } +} + +static void update_lum( item_location loc, bool add ) +{ + switch( loc.where() ) { + case item_location::type::map: + g->m.update_lum( loc, add ); + break; + default: + break; + } +} + +void avatar_action::use_item( avatar &you ) +{ + item_location loc; + avatar_action::use_item( you, loc ); +} + +void avatar_action::use_item( avatar &you, item_location &loc ) +{ + bool use_loc = false; + + if( !loc ) { + loc = game_menus::inv::use( you ); + + if( !loc ) { + add_msg( _( "Never mind." ) ); + return; + } + + const item &it = *loc.get_item(); + if( it.has_flag( "ALLOWS_REMOTE_USE" ) ) { + use_loc = true; + } else { + int obtain_cost = loc.obtain_cost( you ); + loc.obtain( you ); + // This method only handles items in te inventory, so refund the obtain cost. + you.mod_moves( obtain_cost ); + } + } + + g->refresh_all(); + + if( use_loc ) { + update_lum( loc, false ); + you.use( loc ); + update_lum( loc, true ); + + make_active( loc ); + } else { + you.use( loc ); + } + + you.invalidate_crafting_inventory(); +} diff --git a/src/avatar_action.h b/src/avatar_action.h index a7331177b4cbe..41253335b7361 100644 --- a/src/avatar_action.h +++ b/src/avatar_action.h @@ -9,6 +9,7 @@ class avatar; class item; +class item_location; class map; struct targeting_data; @@ -58,6 +59,9 @@ bool fire( avatar &you, map &m, item &weapon, int bp_cost = 0 ); // Throw an item 't' void plthrow( avatar &you, int pos = INT_MIN, const cata::optional &blind_throw_from_pos = cata::nullopt ); + +void use_item( avatar &you, item_location &loc ); // Use item; also tries E,R,W 'a' +void use_item( avatar &you ); } // namespace avatar_action #endif // !AVATAR_MOVE_H diff --git a/src/game.cpp b/src/game.cpp index 18c4d7cab864f..95b509173d373 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1965,6 +1965,7 @@ int game::inventory_item_menu( int pos, int iStartX, int iWidth, int cMenu = static_cast( '+' ); item &oThisItem = u.i_at( pos ); + item_location locThisItem( u, &oThisItem ); if( u.has_item( oThisItem ) ) { #if defined(__ANDROID__) if( get_option( "ANDROID_INVENTORY_AUTOADD" ) ) { @@ -2085,13 +2086,13 @@ int game::inventory_item_menu( int pos, int iStartX, int iWidth, switch( cMenu ) { case 'a': - use_item( pos ); + avatar_action::use_item( u, locThisItem ); break; case 'E': eat( pos ); break; case 'W': - u.wear( u.i_at( pos ) ); + u.wear( oThisItem ); break; case 'w': wield( pos ); @@ -2103,7 +2104,7 @@ int game::inventory_item_menu( int pos, int iStartX, int iWidth, change_side( pos ); break; case 'T': - u.takeoff( u.i_at( pos ) ); + u.takeoff( oThisItem ); break; case 'd': u.drop( pos, u.pos() ); @@ -2124,13 +2125,13 @@ int game::inventory_item_menu( int pos, int iStartX, int iWidth, u.read( pos ); break; case 'D': - u.disassemble( item_location( u, &u.i_at( pos ) ), false ); + u.disassemble( locThisItem, false ); break; case 'f': oThisItem.is_favorite = !oThisItem.is_favorite; break; case '=': - game_menus::inv::reassign_letter( u, u.i_at( pos ) ); + game_menus::inv::reassign_letter( u, oThisItem ); break; case KEY_PPAGE: iScrollPos--; @@ -5010,69 +5011,6 @@ void game::save_cyborg( item *cyborg, const tripoint &couch_pos, player &install } } -static void make_active( item_location loc ) -{ - switch( loc.where() ) { - case item_location::type::map: - g->m.make_active( loc ); - break; - case item_location::type::vehicle: - g->m.veh_at( loc.position() )->vehicle().make_active( loc ); - break; - default: - break; - } -} - -static void update_lum( item_location loc, bool add ) -{ - switch( loc.where() ) { - case item_location::type::map: - g->m.update_lum( loc, add ); - break; - default: - break; - } -} - -void game::use_item( int pos ) -{ - bool use_loc = false; - item_location loc; - - if( pos == INT_MIN ) { - loc = game_menus::inv::use( u ); - - if( !loc ) { - add_msg( _( "Never mind." ) ); - return; - } - - const item &it = *loc.get_item(); - if( it.has_flag( "ALLOWS_REMOTE_USE" ) ) { - use_loc = true; - } else { - int obtain_cost = loc.obtain_cost( u ); - pos = loc.obtain( u ); - // This method only handles items in te inventory, so refund the obtain cost. - u.moves += obtain_cost; - } - } - - refresh_all(); - - if( use_loc ) { - update_lum( loc, false ); - u.use( loc ); - update_lum( loc, true ); - - make_active( loc ); - } else { - u.use( pos ); - } - - u.invalidate_crafting_inventory(); -} void game::exam_vehicle( vehicle &veh, const point &c ) { diff --git a/src/game.h b/src/game.h index 78128a7be54ba..f73d10eea7f59 100644 --- a/src/game.h +++ b/src/game.h @@ -766,7 +766,6 @@ class game void drop_in_direction(); // Drop w/ direction 'D' void butcher(); // Butcher a corpse 'B' - void use_item( int pos = INT_MIN ); // Use item; also tries E,R,W 'a' void change_side( int pos = INT_MIN ); // Change the side on which an item is worn 'c' void reload( int pos, bool prompt = false ); diff --git a/src/handle_action.cpp b/src/handle_action.cpp index 062cc3c4a5c51..1a74c10256051 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -1868,7 +1868,7 @@ bool game::handle_action() case ACTION_USE: // Shell-users are presumed to be able to mess with their inventories, etc // while in the shell. Eating, gear-changing, and item use are OK. - use_item(); + avatar_action::use_item( u ); break; case ACTION_USE_WIELDED: