Skip to content

Commit

Permalink
refactor player::invlet_to_position() to Character::invlet_to_item()
Browse files Browse the repository at this point in the history
  • Loading branch information
KorGgenT authored and kevingranade committed Apr 10, 2020
1 parent 1de418f commit d1c43aa
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 41 deletions.
2 changes: 1 addition & 1 deletion src/armor_layers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ void player::sort_armor()
item &w = *witer;
if( invlet == w.invlet ) {
++witer;
} else if( invlet_to_position( invlet ) != INT_MIN ) {
} else if( invlet_to_item( invlet ) != nullptr ) {
++iiter;
} else {
inv.reassign_item( w, invlet );
Expand Down
25 changes: 25 additions & 0 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2181,6 +2181,31 @@ std::list<item> Character::remove_worn_items_with( std::function<bool( item & )>
return result;
}

item *Character::invlet_to_item( const int linvlet )
{
// Invlets may come from curses, which may also return any kind of key codes, those being
// of type int and they can become valid, but different characters when casted to char.
// Example: KEY_NPAGE (returned when the player presses the page-down key) is 0x152,
// casted to char would yield 0x52, which happens to be 'R', a valid invlet.
if( linvlet > std::numeric_limits<char>::max() || linvlet < std::numeric_limits<char>::min() ) {
return nullptr;
}
const char invlet = static_cast<char>( linvlet );
if( is_npc() ) {
DebugLog( D_WARNING, D_GAME ) << "Why do you need to call Character::invlet_to_position on npc " <<
name;
}
item *invlet_item = nullptr;
visit_items( [&invlet, &invlet_item]( item * it ) {
if( it->invlet == invlet ) {
invlet_item = it;
return VisitResponse::ABORT;
}
return VisitResponse::NEXT;
} );
return invlet_item;
}

// Negative positions indicate weapon/clothing, 0 & positive indicate inventory
const item &Character::i_at( int position ) const
{
Expand Down
5 changes: 5 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,11 @@ class Character : public Creature, public visitable<Character>
*/
std::list<item> remove_worn_items_with( std::function<bool( item & )> filter );

/** Return the item pointer of the item with given invlet, return nullptr if
* the player does not have such an item with that invlet. Don't use this on npcs.
* Only use the invlet in the user interface, otherwise always use the item position. */
item *invlet_to_item( int invlet );

// Returns the item with a given inventory position.
item &i_at( int position );
const item &i_at( int position ) const;
Expand Down
2 changes: 1 addition & 1 deletion src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1533,7 +1533,7 @@ void game_menus::inv::swap_letters( player &p )
[ &p ]( const std::string::value_type & elem ) {
if( p.inv.assigned_invlet.count( elem ) ) {
return c_yellow;
} else if( p.invlet_to_position( elem ) != INT_MIN ) {
} else if( p.invlet_to_item( elem ) != nullptr ) {
return c_white;
} else {
return c_dark_gray;
Expand Down
9 changes: 5 additions & 4 deletions src/inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ char inventory::find_usable_cached_invlet( const std::string &item_type )
continue;
}
// Check if anything is using this invlet.
if( g->u.invlet_to_position( invlet ) != INT_MIN ) {
if( g->u.invlet_to_item( invlet ) != nullptr ) {
continue;
}
return invlet;
Expand Down Expand Up @@ -338,8 +338,9 @@ void inventory::restack( player &p )
std::list<item> &stack = *iter;
item &topmost = stack.front();

const int ipos = p.invlet_to_position( topmost.invlet );
if( !inv_chars.valid( topmost.invlet ) || ( ipos != INT_MIN && ipos != idx ) ) {
const item *invlet_item = p.invlet_to_item( topmost.invlet );
if( !inv_chars.valid( topmost.invlet ) || ( invlet_item != nullptr &&
position_by_item( invlet_item ) != idx ) ) {
assign_empty_invlet( topmost, p );
for( auto &stack_iter : stack ) {
stack_iter.invlet = topmost.invlet;
Expand Down Expand Up @@ -1093,7 +1094,7 @@ void inventory::update_invlet( item &newit, bool assign_invlet )
if( newit.invlet ) {
char tmp_invlet = newit.invlet;
newit.invlet = '\0';
if( g->u.invlet_to_position( tmp_invlet ) == INT_MIN ) {
if( g->u.invlet_to_item( tmp_invlet ) == nullptr ) {
newit.invlet = tmp_invlet;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/pickup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer
}
}
if( newit.invlet != '\0' &&
u.invlet_to_position( newit.invlet ) != INT_MIN ) {
u.invlet_to_item( newit.invlet ) != nullptr ) {
// Existing invlet is not re-usable, remove it and let the code in player.cpp/inventory.cpp
// add a new invlet, otherwise keep the (usable) invlet.
newit.invlet = '\0';
Expand Down
34 changes: 4 additions & 30 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2383,32 +2383,6 @@ item player::reduce_charges( item *it, int quantity )
return result;
}

int player::invlet_to_position( const int linvlet ) const
{
// Invlets may come from curses, which may also return any kind of key codes, those being
// of type int and they can become valid, but different characters when casted to char.
// Example: KEY_NPAGE (returned when the player presses the page-down key) is 0x152,
// casted to char would yield 0x52, which happens to be 'R', a valid invlet.
if( linvlet > std::numeric_limits<char>::max() || linvlet < std::numeric_limits<char>::min() ) {
return INT_MIN;
}
const char invlet = static_cast<char>( linvlet );
if( is_npc() ) {
DebugLog( D_WARNING, D_GAME ) << "Why do you need to call player::invlet_to_position on npc " <<
name;
}
if( weapon.invlet == invlet ) {
return -1;
}
auto iter = worn.begin();
for( size_t i = 0; i < worn.size(); i++, iter++ ) {
if( iter->invlet == invlet ) {
return worn_position_to_index( i );
}
}
return inv.invlet_to_position( invlet );
}

bool player::can_interface_armor() const
{
bool okay = std::any_of( my_bionics->begin(), my_bionics->end(),
Expand Down Expand Up @@ -3855,10 +3829,10 @@ void player::reassign_item( item &it, int invlet )
{
bool remove_old = true;
if( invlet ) {
item &prev = i_at( invlet_to_position( invlet ) );
if( !prev.is_null() ) {
remove_old = it.typeId() != prev.typeId();
inv.reassign_item( prev, it.invlet, remove_old );
item *prev = invlet_to_item( invlet );
if( prev != nullptr ) {
remove_old = it.typeId() != prev->typeId();
inv.reassign_item( *prev, it.invlet, remove_old );
}
}

Expand Down
4 changes: 0 additions & 4 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,10 +687,6 @@ class player : public Character
* @param quantity How many charges to remove
*/
item reduce_charges( item *it, int quantity );
/** Return the item position of the item with given invlet, return INT_MIN if
* the player does not have such an item with that invlet. Don't use this on npcs.
* Only use the invlet in the user interface, otherwise always use the item position. */
int invlet_to_position( int invlet ) const;

/**
* Check whether player has a bionic power armor interface.
Expand Down

0 comments on commit d1c43aa

Please sign in to comment.