Skip to content

Commit

Permalink
Better worn container display (#48109)
Browse files Browse the repository at this point in the history
* wip: first test

* wip: first working conditions

* feat: add unit_to_string wrapper to handle most units display, add the ability to use compact param to remove whitespaces for to_string functions, add remove_trailing_zeroes to to_string functions to have the ability to remove trailing zeros, add round function to be able to round a double specifying decimal places

* feat: add bool is_restricted method

* feat: add divers utility get method to obtain capacity and weight capacity of contents, add unrestricted_pockets_only argument in some of get capacity related methods to limit the total of capacities to contained unrestricted pockets only

* feat: add some utility get methods to obtain capacity related data and pocket restriction, add unrestricted_pockets_only argument to some of capacity related get methods to be able to only calculate capacity based upon unrestricted pockets only

* feat: add container_data struct to handle item container data, add display to inventory_ui to display `(remains $REMAINING_UNRESTRICTED_VOLUME, $REMAINING_UNRESTRICTED_WEIGHT), max length $MAX_UNRESTRICTED_ITEM_LENGTH` after item name and item filling, if : the item is worn, the item is a container, the item has at least 1 unrestricted pocket

* rm: duplicated debugmsg

* fix : int to size_t comparison through static_cast

* fix: custom_category attribute previously moved to public for testing purposes, put back to private members as it should

* astyle: update

* fix?: private public shenanigans

* fix: quick fix for unwanted behaviour extension to all inventory panes

* fix: wrongly associating item if within worn items menu `;` but not worn - due to item_category handling

* astyle: update

* fix: trying to fix clang-tidy errors

* astyle: update

* fix?: clang it up

* fix: clang it up

* fix: lgtm

* fix: omitted declaration rename

* fit: default decimal places with a variable

* fix: wrong behaviour on restricted pockets

* fix: string format error for vol_to_string when remove_trailing_zeroes == false

* fix: inverted condition for max_containable_length with unrestricted_pockets_only

* fix: formatting error for weight_to_string when remove_trailing_zeroes is false

* fix: clang-tidy

* chore - astyle: update

* fix: } supression while resolving conflicts

* fix: string_id to static

* fix: duplicated addition made during conflict resolve

Co-authored-by: Kevin Granade <kevin.granade@gmail.com>
  • Loading branch information
Moltenhead and kevingranade authored Dec 16, 2021
1 parent 4ac5f71 commit cfc00fa
Show file tree
Hide file tree
Showing 10 changed files with 305 additions and 47 deletions.
47 changes: 46 additions & 1 deletion src/inventory_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,27 @@ struct inventory_input {
inventory_entry *entry;
};

struct container_data {
units::volume actual_capacity;
units::volume total_capacity;
units::mass actual_capacity_weight;
units::mass total_capacity_weight;
units::length max_containable_length;

std::string to_formatted_string( const bool compact = true ) {
std::string string_to_format;
if( compact ) {
string_to_format = "%s/%s : %s/%s : max %s";
} else {
string_to_format = "(remains %s, %s) max length %s";
}
return string_format( string_to_format,
unit_to_string( total_capacity - actual_capacity, true, true ),
unit_to_string( total_capacity_weight - actual_capacity_weight, true, true ),
unit_to_string( max_containable_length, true ) );
}
};

static int contained_offset( const item_location &loc )
{
if( loc.where() != item_location::type::container ) {
Expand Down Expand Up @@ -388,7 +409,31 @@ std::string inventory_selector_preset::get_cell_text( const inventory_entry &ent
if( !entry ) {
return std::string();
} else if( entry.is_item() ) {
return cells[cell_index].get_text( entry );
std::string text = cells[cell_index].get_text( entry );
const item &actual_item = *entry.locations.front();
if( cell_index == 0 && !text.empty() &&
entry.get_category_ptr()->get_id() == item_category_ITEMS_WORN &&
actual_item.is_worn_by_player() &&
actual_item.is_container() && actual_item.has_unrestricted_pockets() ) {
const units::volume total_capacity = actual_item.get_total_capacity( true );
const units::mass total_capacity_weight = actual_item.get_total_weight_capacity( true );
const units::length max_containable_length = actual_item.max_containable_length( true );

const units::volume actual_capacity = actual_item.get_total_contained_volume( true );
const units::mass actual_capacity_weight = actual_item.get_total_contained_weight( true );

container_data container_data = {
actual_capacity,
total_capacity,
actual_capacity_weight,
total_capacity_weight,
max_containable_length
};
std::string formatted_string = container_data.to_formatted_string( false );

text = text + string_format( " %s", formatted_string );
}
return text;
} else if( cell_index != 0 ) {
return replace_colors( cells[cell_index].title );
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/inventory_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "optional.h"
#include "pimpl.h"
#include "translations.h"
#include "units.h"
#include "units_fwd.h"

class Character;
Expand All @@ -51,6 +52,7 @@ enum class toggle_mode : int {
};

struct inventory_input;
struct container_data;
struct navigation_mode_data;

using drop_location = std::pair<item_location, int>;
Expand Down
52 changes: 46 additions & 6 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,10 @@ bool item::is_worn_only_with( const item &it ) const
{
return is_power_armor() && it.is_power_armor() && it.covers( bodypart_id( "torso" ) );
}
bool item::is_worn_by_player() const
{
return get_player_character().is_worn( *this );
}

item item::in_its_container( int qty ) const
{
Expand Down Expand Up @@ -8104,6 +8108,18 @@ bool item::is_container() const
return contents.has_pocket_type( item_pocket::pocket_type::CONTAINER );
}

bool item::is_container_with_restriction() const
{
if( !is_container() ) {
return false;
}
return contents.is_restricted_container();
}

bool item::is_single_container_with_restriction() const
{
return contents.is_single_restricted_container();
}

bool item::has_pocket_type( item_pocket::pocket_type pk_type ) const
{
Expand Down Expand Up @@ -8417,9 +8433,9 @@ double item::calculate_by_enchantment_wield( double modify, enchant_vals::mod va
return modify;
}

units::length item::max_containable_length() const
units::length item::max_containable_length( const bool unrestricted_pockets_only ) const
{
return contents.max_containable_length();
return contents.max_containable_length( unrestricted_pockets_only );
}

units::length item::min_containable_length() const
Expand Down Expand Up @@ -9922,14 +9938,33 @@ int item::getlight_emit() const
return lumint;
}

units::volume item::get_total_capacity() const
units::volume item::get_total_capacity( const bool unrestricted_pockets_only ) const
{
return contents.total_container_capacity();
return contents.total_container_capacity( unrestricted_pockets_only );
}

units::mass item::get_total_weight_capacity() const
units::mass item::get_total_weight_capacity( const bool unrestricted_pockets_only ) const
{
return contents.total_container_weight_capacity();
return contents.total_container_weight_capacity( unrestricted_pockets_only );
}

units::volume item::get_remaining_capacity( const bool unrestricted_pockets_only ) const
{
return contents.remaining_container_capacity( unrestricted_pockets_only );
}
units::mass item::get_remaining_weight_capacity( const bool unrestricted_pockets_only ) const
{
return contents.remaining_container_capacity_weight( unrestricted_pockets_only );
}


units::volume item::get_total_contained_volume( const bool unrestricted_pockets_only ) const
{
return contents.total_contained_volume( unrestricted_pockets_only );
}
units::mass item::get_total_contained_weight( const bool unrestricted_pockets_only ) const
{
return contents.total_contained_weight( unrestricted_pockets_only );
}

int item::get_remaining_capacity_for_liquid( const item &liquid, bool allow_bucket,
Expand Down Expand Up @@ -12040,6 +12075,11 @@ units::volume item::get_selected_stack_volume( const std::map<const item *, int>
return 0_ml;
}

bool item::has_unrestricted_pockets() const
{
return contents.has_unrestricted_pockets();
}

units::volume item::get_contents_volume_with_tweaks( const std::map<const item *, int> &without )
const
{
Expand Down
26 changes: 23 additions & 3 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,10 @@ class item : public visitable
/** Whether this is container. Note that container does not necessarily means it's
* suitable for liquids. */
bool is_container() const;
/** Whether it is a container, and if it is has some restrictions */
bool is_container_with_restriction() const;
/** Whether it is a container with only one pocket, and if it is has some restrictions */
bool is_single_container_with_restriction() const;
// whether the contents has a pocket with the associated type
bool has_pocket_type( item_pocket::pocket_type pk_type ) const;
bool has_any_with( const std::function<bool( const item & )> &filter,
Expand Down Expand Up @@ -829,12 +833,24 @@ class item : public visitable
* It returns the maximum volume of any contents, including liquids,
* ammo, magazines, weapons, etc.
*/
units::volume get_total_capacity() const;
units::mass get_total_weight_capacity() const;
units::volume get_total_capacity( bool unrestricted_pockets_only = false ) const;
units::mass get_total_weight_capacity( bool unrestricted_pockets_only = false ) const;

units::volume get_remaining_capacity( bool unrestricted_pockets_only = false ) const;
units::mass get_remaining_weight_capacity( bool unrestricted_pockets_only = false ) const;

units::volume get_total_contained_volume( bool unrestricted_pockets_only = false ) const;
units::mass get_total_contained_weight( bool unrestricted_pockets_only = false ) const;

// recursive function that checks pockets for remaining free space
units::volume check_for_free_space() const;
units::volume get_selected_stack_volume( const std::map<const item *, int> &without ) const;
// checks if the item can have things placed in it
bool has_pockets() const {
// what has it gots in them, precious
return contents.has_pocket_type( item_pocket::pocket_type::CONTAINER );
}
bool has_unrestricted_pockets() const;
units::volume get_contents_volume_with_tweaks( const std::map<const item *, int> &without ) const;
units::volume get_nested_content_volume_recursive( const std::map<const item *, int> &without )
const;
Expand Down Expand Up @@ -1380,7 +1396,7 @@ class item : public visitable
std::pair<item_location, item_pocket *> best_pocket( const item &it, item_location &parent,
const item *avoid = nullptr, bool allow_sealed = false, bool ignore_settings = false );

units::length max_containable_length() const;
units::length max_containable_length( bool unrestricted_pockets_only = false ) const;
units::length min_containable_length() const;
units::volume max_containable_volume() const;

Expand Down Expand Up @@ -1877,6 +1893,10 @@ class item : public visitable
* Returns true whether this item can be worn only when @param it is worn.
*/
bool is_worn_only_with( const item &it ) const;
/**
* Returns true wether this item is worn or not
*/
bool is_worn_by_player() const;

/**
* @name Pet armor related functions.
Expand Down
Loading

0 comments on commit cfc00fa

Please sign in to comment.