diff --git a/src/armor_layers.cpp b/src/armor_layers.cpp index 689825f99ed5e..a53f2fd05b648 100644 --- a/src/armor_layers.cpp +++ b/src/armor_layers.cpp @@ -774,7 +774,7 @@ void player::sort_armor() if( loc ) { // wear the item cata::optional::iterator> new_equip_it = - wear( this->i_at( loc.obtain( *this ) ) ); + wear( *loc.obtain( *this ) ); if( new_equip_it ) { body_part bp = static_cast( tabindex ); if( tabindex == num_bp || ( **new_equip_it ).covers( bp ) ) { @@ -802,7 +802,7 @@ void player::sort_armor() if( loc ) { // wear the item if( cata::optional::iterator> new_equip_it = - wear( this->i_at( loc.obtain( *this ) ) ) ) { + wear( *loc.obtain( *this ) ) ) { // save iterator to cursor's position std::list::iterator cursor_it = tmp_worn[leftListIndex]; // reorder `worn` vector to place new item at cursor diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 1a7149c6bd20c..121e370c8f707 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -1252,12 +1252,11 @@ void avatar_action::use_item( avatar &you, item_location &loc ) use_in_place = true; } else { const int obtain_cost = loc.obtain_cost( you ); - item &target = you.i_at( loc.obtain( you ) ); - if( target.is_null() ) { + loc = loc.obtain( you ); + if( !loc ) { debugmsg( "Failed to obtain target item" ); return; } - loc = item_location( you, &target ); // TODO: the following comment is inaccurate and this mechanic needs to be rexamined // This method only handles items in the inventory, so refund the obtain cost. @@ -1295,7 +1294,7 @@ void avatar_action::unload( avatar &you ) item *it = loc.get_item(); if( loc.where() != item_location::type::character ) { - it = &you.i_at( loc.obtain( you ) ); + it = loc.obtain( you ).get_item(); } if( you.unload( *it ) ) { if( it->has_flag( "MAG_DESTROY" ) && it->ammo_remaining() == 0 ) { diff --git a/src/game.cpp b/src/game.cpp index 174e3fe90296d..dc07a184d5d75 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -8379,7 +8379,7 @@ void game::reload( item_location &loc, bool prompt, bool empty ) bool use_loc = true; if( !it->has_flag( "ALLOWS_REMOTE_USE" ) ) { - it = &u.i_at( loc.obtain( u ) ); + it = loc.obtain( u ).get_item(); use_loc = false; } diff --git a/src/handle_action.cpp b/src/handle_action.cpp index b119ce230595a..f46dac1d7b2bc 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -1206,7 +1206,7 @@ static void wear() item_location loc = game_menus::inv::wear( u ); if( loc ) { - u.wear( u.i_at( loc.obtain( u ) ) ); + u.wear( *loc.obtain( u ) ); } else { add_msg( _( "Never mind." ) ); } @@ -1218,7 +1218,7 @@ static void takeoff() item_location loc = game_menus::inv::take_off( u ); if( loc ) { - u.takeoff( u.i_at( loc.obtain( u ) ) ); + u.takeoff( *loc.obtain( u ) ); } else { add_msg( _( "Never mind." ) ); } @@ -1235,9 +1235,7 @@ static void read() item spell_book = *loc.get_item(); spell_book.get_use( "learn_spell" )->call( u, spell_book, spell_book.active, u.pos() ); } else { - // calling obtain() invalidates the item pointer - // TODO: find a way to do this without an int index - u.read( u.i_at( loc.obtain( u ) ) ); + u.read( *loc.obtain( u ) ); } } else { add_msg( _( "Never mind." ) ); diff --git a/src/item_location.cpp b/src/item_location.cpp index 903cd46cdf293..e8d1c4f7e8a35 100644 --- a/src/item_location.cpp +++ b/src/item_location.cpp @@ -74,7 +74,7 @@ class item_location::impl virtual type where() const = 0; virtual tripoint position() const = 0; virtual std::string describe( const Character * ) const = 0; - virtual int obtain( Character &, int ) = 0; + virtual item_location obtain( Character &, int ) = 0; virtual int obtain_cost( const Character &, int ) const = 0; virtual void remove_item() = 0; virtual void serialize( JsonOut &js ) const = 0; @@ -127,9 +127,9 @@ class item_location::impl::nowhere : public item_location::impl return ""; } - int obtain( Character &, int ) override { + item_location obtain( Character &, int ) override { debugmsg( "invalid use of nowhere item_location" ); - return INT_MIN; + return item_location(); } int obtain_cost( const Character &, int ) const override { @@ -189,16 +189,16 @@ class item_location::impl::item_on_map : public item_location::impl return res; } - int obtain( Character &ch, int qty ) override { + item_location obtain( Character &ch, int qty ) override { ch.moves -= obtain_cost( ch, qty ); item obj = target()->split( qty ); if( !obj.is_null() ) { - return ch.get_item_position( &ch.i_add( obj, should_stack ) ); + return item_location( ch, &ch.i_add( obj, should_stack ) ); } else { - int inv = ch.get_item_position( &ch.i_add( *target(), should_stack ) ); + item *inv = &ch.i_add( *target(), should_stack ); remove_item(); - return inv; + return item_location( ch, inv ); } } @@ -307,21 +307,21 @@ class item_location::impl::item_on_person : public item_location::impl } } - int obtain( Character &ch, int qty ) override { + item_location obtain( Character &ch, int qty ) override { ch.mod_moves( -obtain_cost( ch, qty ) ); if( &ch.i_at( ch.get_item_position( target() ) ) == target() ) { // item already in target characters inventory at base of stack - return ch.get_item_position( target() ); + return item_location( ch, target() ); } item obj = target()->split( qty ); if( !obj.is_null() ) { - return ch.get_item_position( &ch.i_add( obj, should_stack ) ); + return item_location( ch, &ch.i_add( obj, should_stack ) ); } else { - int inv = ch.get_item_position( &ch.i_add( *target(), should_stack ) ); + item *inv = &ch.i_add( *target(), should_stack ); remove_item(); // This also takes off the item from whoever wears it. - return inv; + return item_location( ch, inv ); } } @@ -434,16 +434,16 @@ class item_location::impl::item_on_vehicle : public item_location::impl return res; } - int obtain( Character &ch, int qty ) override { + item_location obtain( Character &ch, int qty ) override { ch.moves -= obtain_cost( ch, qty ); item obj = target()->split( qty ); if( !obj.is_null() ) { - return ch.get_item_position( &ch.i_add( obj, should_stack ) ); + return item_location( ch, &ch.i_add( obj, should_stack ) ); } else { - int inv = ch.get_item_position( &ch.i_add( *target(), should_stack ) ); + item *inv = &ch.i_add( *target(), should_stack ); remove_item(); - return inv; + return item_location( ch, inv ); } } @@ -581,11 +581,11 @@ std::string item_location::describe( const Character *ch ) const return ptr->describe( ch ); } -int item_location::obtain( Character &ch, int qty ) +item_location item_location::obtain( Character &ch, int qty ) { if( !ptr->valid() ) { debugmsg( "item location does not point to valid item" ); - return INT_MIN; + return item_location(); } return ptr->obtain( ch, qty ); } diff --git a/src/item_location.h b/src/item_location.h index f5f04cc698268..3dee2a76aee53 100644 --- a/src/item_location.h +++ b/src/item_location.h @@ -68,8 +68,8 @@ class item_location * @warning caller should restack inventory if item is to remain in it * @warning all further operations using this class are invalid * @warning it is unsafe to call this within unsequenced operations (see #15542) - * @return inventory position for the item */ - int obtain( Character &ch, int qty = -1 ); + * @return item_location for the item */ + item_location obtain( Character &ch, int qty = -1 ); /** Calculate (but do not deduct) number of moves required to obtain an item * @see item_location::obtain */ diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index a5b121bf98cc5..9d54ef90a529f 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -2716,7 +2716,7 @@ int holster_actor::use( player &p, item &it, bool, const tripoint & ) const return 0; } - store( p, it, p.i_at( loc.obtain( p ) ) ); + store( p, it, *loc.obtain( p ) ); } return 0; @@ -4186,7 +4186,7 @@ int saw_barrel_actor::use( player &p, item &it, bool t, const tripoint & ) const return 0; } - item &obj = p.i_at( loc.obtain( p ) ); + item &obj = *loc.obtain( p ); p.add_msg_if_player( _( "You saw down the barrel of your %s." ), obj.tname() ); obj.contents.emplace_back( "barrel_small", calendar::turn ); diff --git a/src/npc.cpp b/src/npc.cpp index bdad2311d7af6..5e5fa6879ff67 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -1009,7 +1009,7 @@ void npc::do_npc_read() if( !ch ) { return; } - item &chosen = i_at( loc.obtain( *ch ) ); + item &chosen = *loc.obtain( *ch ); if( can_read( chosen, fail_reasons ) ) { if( g->u.sees( pos() ) ) { add_msg( m_info, _( "%s starts reading." ), disp_name() );