Skip to content

Commit

Permalink
Jsonize Weight capacity modifier for armor and CBM (#33394)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fris0uman authored and ZhilkinSerg committed Aug 22, 2019
1 parent 28cd247 commit e888867
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 27 deletions.
1 change: 1 addition & 0 deletions data/json/bionics.json
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@
"name": "Titanium Skeletal Bracing",
"description": "Titanium bracing has been installed onto your elbows, knees, and spine, making them far better at handling strain. Your carrying capacity is increased by 20 kilograms, or about 44 pounds.",
"occupied_bodyparts": [ [ "TORSO", 8 ], [ "ARM_L", 3 ], [ "ARM_R", 3 ], [ "LEG_L", 3 ], [ "LEG_R", 3 ] ],
"weight_capacity_bonus": "20 kg",
"flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ]
},
{
Expand Down
44 changes: 24 additions & 20 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,26 +161,28 @@ Currently, only some JSON values support this syntax (see [here](https://github.
### Bionics
| Identifier | Description
|--- |---
| id | Unique ID. Must be one continuous word, use underscores if necessary.
| name | In-game name displayed.
| active | Whether the bionic is active or passive. (default: `passive`)
| power_source | Whether the bionic provides power. (default: `false`)
| faulty | Whether it is a faulty type. (default: `false`)
| cost | How many PUs it costs to use the bionic. (default: `0`)
| time | How long, when activated, between drawing cost/converting fuel to power. If 0, it draws power once and never produce any in the case of a fueled bionic. (default: `0`)
| description | In-game description.
| encumbrance | (_optional_) A list of body parts and how much this bionic encumber them.
| canceled_mutations | (_optional_) A list of mutations/traits that are removed when this bionic is installed (e.g. because it replaces the fault biological part).
| included_bionics | (_optional_) Additional bionics that are installed automatically when this bionic is installed. This can be used to install several bionics from one CBM item, which is useful as each of those can be activated independently.
| included | (_optional_) Whether this bionic is included with another. If true this bionic does not require a CBM item to be defined. (default: `false`)
| env_protec | (_optional_) How much environmental protection does this bionic provide on the specified body parts.
| occupied_bodyparts | (_optional_) A list of body parts occupied by this bionic, and the number of bionic slots it take on those parts.
| capacity | (_optional_) Amount of power storage added by this bionic.
| fuel_options | (_optional_) A list of fuel that this bionic can use to produce bionic power.
| fuel_capacity | (_optional_) Volume of fuel this bionic can store.
| fuel_efficiency | (_optional_) Fraction of fuel energy converted into power. (default: `0`)
| Identifier | Description
|--- |---
| id | Unique ID. Must be one continuous word, use underscores if necessary.
| name | In-game name displayed.
| active | Whether the bionic is active or passive. (default: `passive`)
| power_source | Whether the bionic provides power. (default: `false`)
| faulty | Whether it is a faulty type. (default: `false`)
| cost | How many PUs it costs to use the bionic. (default: `0`)
| time | How long, when activated, between drawing cost. If 0, it draws power once. (default: `0`)
| description | In-game description.
| encumbrance | (_optional_) A list of body parts and how much this bionic encumber them.
| weight_capacity_bonus | (_optional_) Bonus to weight carrying capacity in grams, can be negative. Strings must be used - "5000 g" or "5 kg" (default: `0`)
| weight_capacity_modifier | (_optional_) Factor modifying base weight carrying capacity. (default: `1`)
| canceled_mutations | (_optional_) A list of mutations/traits that are removed when this bionic is installed (e.g. because it replaces the fault biological part).
| included_bionics | (_optional_) Additional bionics that are installed automatically when this bionic is installed. This can be used to install several bionics from one CBM item, which is useful as each of those can be activated independently.
| included | (_optional_) Whether this bionic is included with another. If true this bionic does not require a CBM item to be defined. (default: `false`)
| env_protec | (_optional_) How much environmental protection does this bionic provide on the specified body parts.
| occupied_bodyparts | (_optional_) A list of body parts occupied by this bionic, and the number of bionic slots it take on those parts.
| capacity | (_optional_) Amount of power storage added by this bionic.
| fuel_options | (_optional_) A list of fuel that this bionic can use to produce bionic power.
| fuel_capacity | (_optional_) Volume of fuel this bionic can store.
| fuel_efficiency | (_optional_) Fraction of fuel energy converted into power. (default: `0`)
```C++
{
Expand Down Expand Up @@ -916,6 +918,8 @@ Armor can be defined like this:
"warmth" : 10, // (Optional, default = 0) How much warmth clothing provides
"environmental_protection" : 0, // (Optional, default = 0) How much environmental protection it affords
"encumbrance" : 0, // Base encumbrance (unfitted value)
"weight_capacity_bonus": "20 kg", // (Optional, default = 0) Bonus to weight carrying capacity, can be negative. Strings must be used - "5000 g" or "5 kg"
"weight_capacity_modifier": 1.5, // (Optional, default = 1) Factor modifying base weight carrying capacity.
"coverage" : 80, // What percentage of body part
"material_thickness" : 1, // Thickness of material, in millimeter units (approximately). Generally ranges between 1 - 5, more unusual armor types go up to 10 or more
"power_armor" : false, // If this is a power armor item (those are special).
Expand Down
9 changes: 9 additions & 0 deletions src/bionics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2015,6 +2015,7 @@ static bool get_bool_or_flag( JsonObject &jsobj, const std::string &name, const

void load_bionic( JsonObject &jsobj )
{

bionic_data new_bionic;

const bionic_id id( jsobj.get_string( "id" ) );
Expand Down Expand Up @@ -2052,6 +2053,14 @@ void load_bionic( JsonObject &jsobj )

new_bionic.fake_item = jsobj.get_string( "fake_item", "" );

new_bionic.weight_capacity_modifier = jsobj.get_float( "weight_capacity_modifier", 1.0 );

if( jsobj.has_string( "weight_capacity_bonus" ) ) {
new_bionic.weight_capacity_bonus = read_from_json_string<units::mass>
( *jsobj.get_raw( "weight_capacity_bonus" ), units::mass_units );
}


jsobj.read( "canceled_mutations", new_bionic.canceled_mutations );
jsobj.read( "included_bionics", new_bionic.included_bionics );
jsobj.read( "included", new_bionic.included );
Expand Down
5 changes: 5 additions & 0 deletions src/bionics.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "calendar.h"
#include "string_id.h"
#include "type_id.h"
#include "units.h"

class player;
class JsonObject;
Expand Down Expand Up @@ -74,6 +75,10 @@ struct bionic_data {
* If true, this bionic is included with another.
*/
bool included = false;
/**Factor modifiying weight capacity*/
float weight_capacity_modifier;
/**Bonus to weight capacity*/
units::mass weight_capacity_bonus;
/**Fuel types that can be used by this bionic*/
std::vector<itype_id> fuel_opts;
/**How much fuel this bionic can hold*/
Expand Down
18 changes: 15 additions & 3 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1441,12 +1441,24 @@ units::mass Character::weight_capacity() const
ret += get_str() * 4_kilogram;
ret *= mutation_value( "weight_capacity_modifier" );

units::mass worn_weight_bonus = 0_gram;
for( const item &it : worn ) {
ret *= it.get_weight_capacity_modifier();
worn_weight_bonus += it.get_weight_capacity_bonus();
}

units::mass bio_weight_bonus = 0_gram;
for( const bionic &bio : *my_bionics ) {
ret *= bio.info().weight_capacity_modifier;
bio_weight_bonus += bio.info().weight_capacity_bonus;
}

ret += bio_weight_bonus + worn_weight_bonus ;

if( has_artifact_with( AEP_CARRY_MORE ) ) {
ret += 22500_gram;
}
if( has_bionic( bionic_id( "bio_weight" ) ) ) {
ret += 20_kilogram;
}

if( ret < 0_gram ) {
ret = 0_gram;
}
Expand Down
99 changes: 95 additions & 4 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2037,6 +2037,29 @@ std::string item::info( std::vector<iteminfo> &info, const iteminfo_query *parts
"item</info>." ) ) );
}
}
const units::mass weight_bonus = get_weight_capacity_bonus();
const float weight_modif = get_weight_capacity_modifier();
if( weight_modif != 1 ) {
std::string modifier;
if( weight_modif < 1 ) {
modifier = "<num><bad>x</bad>";
} else {
modifier = "<num><color_light_green>x</color>";
}
info.push_back( iteminfo( "ARMOR",
_( "<bold>Weight capacity modifier</bold>: " ), modifier,
iteminfo::no_newline | iteminfo::is_decimal, weight_modif ) );
}
if( weight_bonus != 0_gram ) {
std::string bonus;
if( weight_bonus < 0_gram ) {
bonus = string_format( "<num> <bad>%s</bad>", weight_units() );
} else {
bonus = string_format( "<num> <color_light_green> %s</color>", weight_units() );
}
info.push_back( iteminfo( "ARMOR", _( "<bold>Weight capacity bonus</bold>: " ), bonus,
iteminfo::no_newline | iteminfo::is_decimal, convert_weight( weight_bonus ) ) );
}

}
if( is_book() ) {
Expand Down Expand Up @@ -2643,10 +2666,60 @@ std::string item::info( std::vector<iteminfo> &info, const iteminfo_query *parts
}

// TODO: Unhide when enforcing limits
if( is_bionic() && get_option < bool >( "CBM_SLOTS_ENABLED" )
&& parts->test( iteminfo_parts::DESCRIPTION_CBM_SLOTS ) ) {
info.push_back( iteminfo( "DESCRIPTION", list_occupied_bps( type->bionic->id,
_( "This bionic is installed in the following body part(s):" ) ) ) );
if( is_bionic() ) {
if( get_option < bool >( "CBM_SLOTS_ENABLED" )
&& parts->test( iteminfo_parts::DESCRIPTION_CBM_SLOTS ) ) {
info.push_back( iteminfo( "DESCRIPTION", list_occupied_bps( type->bionic->id,
_( "This bionic is installed in the following body part(s):" ) ) ) );
}
insert_separation_line();

const bionic_id bid = type->bionic->id;

if( !bid->encumbrance.empty() ) {
info.push_back( iteminfo( "DESCRIPTION", _( "<bold>Encumbrance:</bold> " ),
iteminfo::no_newline ) );
for( const auto &element : bid->encumbrance ) {
info.push_back( iteminfo( "CBM", body_part_name_as_heading( element.first, 1 ), " <num> ",
iteminfo::no_newline, element.second ) );
}

}

if( !bid->env_protec.empty() ) {
info.push_back( iteminfo( "DESCRIPTION", _( "<bold>Environmental Protection:</bold> " ),
iteminfo::no_newline ) );
for( const auto &element : bid->env_protec ) {
info.push_back( iteminfo( "CBM", body_part_name_as_heading( element.first, 1 ), " <num> ",
iteminfo::no_newline, element.second ) );
}

}

const units::mass weight_bonus = bid->weight_capacity_bonus;
const float weight_modif = bid->weight_capacity_modifier;
if( weight_modif != 1 ) {
std::string modifier;
if( weight_modif < 1 ) {
modifier = "<num><bad>x</bad>";
} else {
modifier = "<num><color_light_green>x</color>";
}
info.push_back( iteminfo( "CBM",
_( "<bold>Weight capacity modifier</bold>: " ), modifier,
iteminfo::no_newline | iteminfo::is_decimal, weight_modif ) );
}
if( weight_bonus != 0_gram ) {
std::string bonus;
if( weight_bonus < 0_gram ) {
bonus = string_format( "<num> <bad>%s</bad>", weight_units() );
} else {
bonus = string_format( "<num> <color_light_green>%s</color>", weight_units() );
}
info.push_back( iteminfo( "CBM", _( "<bold>Weight capacity bonus</bold>: " ), bonus,
iteminfo::no_newline | iteminfo::is_decimal, convert_weight( weight_bonus ) ) );
}

}

if( is_gun() && has_flag( "FIRE_TWOHAND" ) &&
Expand Down Expand Up @@ -4319,6 +4392,24 @@ units::volume item::get_storage() const
return storage;
}

float item::get_weight_capacity_modifier() const
{
const islot_armor *t = find_armor_data();
if( t == nullptr ) {
return 1;
}
return t->weight_capacity_modifier;
}

units::mass item::get_weight_capacity_bonus() const
{
const islot_armor *t = find_armor_data();
if( t == nullptr ) {
return 0_gram;
}
return t->weight_capacity_bonus;
}

int item::get_env_resist( int override_base_resist ) const
{
const islot_armor *t = find_armor_data();
Expand Down
10 changes: 10 additions & 0 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,16 @@ class item : public visitable<item>
* character that wears the item.
*/
units::volume get_storage() const;
/**
* Returns the weight capacity modifier (@ref islot_armor::weight_capacity_modifier) that this item provides when worn.
* For non-armor it returns 1. The modifier is multiplied with the weight capacity of the character that wears the item.
*/
float get_weight_capacity_modifier() const;
/**
* Returns the weight capacity bonus (@ref islot_armor::weight_capacity_modifier) that this item provides when worn.
* For non-armor it returns 0. The bonus is added to the total weight capacity of the character that wears the item.
*/
units::mass get_weight_capacity_bonus() const;
/**
* Returns the resistance to environmental effects (@ref islot_armor::env_resist) that this
* item provides when worn. See @ref player::get_env_resist. Higher values are better.
Expand Down
7 changes: 7 additions & 0 deletions src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1509,9 +1509,16 @@ void Item_factory::load( islot_armor &slot, JsonObject &jo, const std::string &s
assign( jo, "environmental_protection_with_filter", slot.env_resist_w_filter, strict, 0 );
assign( jo, "warmth", slot.warmth, strict, 0 );
assign( jo, "storage", slot.storage, strict, 0_ml );
assign( jo, "weight_capacity_modifier", slot.weight_capacity_modifier );
assign( jo, "power_armor", slot.power_armor, strict );

assign_coverage_from_json( jo, "covers", slot.covers, slot.sided );

if( jo.has_string( "weight_capacity_bonus" ) ) {
slot.weight_capacity_bonus = read_from_json_string<units::mass>
( *jo.get_raw( "weight_capacity_bonus" ), units::mass_units );
}

}

void Item_factory::load( islot_pet_armor &slot, JsonObject &jo, const std::string &src )
Expand Down
8 changes: 8 additions & 0 deletions src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,14 @@ struct islot_armor {
* How much storage this items provides when worn.
*/
units::volume storage = 0_ml;
/**
* Factor modifiying weight capacity
*/
float weight_capacity_modifier = 1.0;
/**
* Bonus to weight capacity
*/
units::mass weight_capacity_bonus = 0_gram;
/**
* Whether this is a power armor item.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/units.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,11 @@ static const std::vector<std::pair<std::string, energy>> energy_units = { {
{ "kJ", 1_kJ },
}
};
static const std::vector<std::pair<std::string, mass>> mass_units = { {
{ "g", 1_gram },
{ "kg", 1_kilogram },
}
};
} // namespace units

template<typename T>
Expand Down

0 comments on commit e888867

Please sign in to comment.