diff --git a/doc/JSON/NPCs.md b/doc/JSON/NPCs.md index 5811802202b42..5ff06401b5fde 100644 --- a/doc/JSON/NPCs.md +++ b/doc/JSON/NPCs.md @@ -1391,6 +1391,7 @@ _some functions support array arguments or kwargs, denoted with square brackets | climate_control_str_chill() | ✅ | ❌ | u, n | return amount of chill climate control that character currently has (character feels better in cold places with it), in warmth points; default 0, affected by CLIMATE_CONTROL_HEAT enchantment.

Example:
`"condition": { "math": [ "n_climate_control_str_chill() < 0" ] }`| | calories() | ✅ | ✅ | u, n | Return amount of calories character has. If used on item, return amount of calories this item gives when consumed (not affected by enchantments or mutations). Optional kwargs:
`format`: `s`/`v` - return the value in specific format. Can be `percent` (return percent to the healthy amount of calories, `100` being the target, bmi 25, or 110000 kcal) or `raw`. If now used, `raw` is used by default.
`dont_affect_weariness`: `true`/`false` (default false) When assigning value, whether the gained/spent calories should be tracked by weariness.

Example:
`"condition": { "math": [ "u_calories() < 0" ] }`
`"condition": { "math": [ "u_calories('format': 'percent') > 0" ] }`
`"condition": { "math": [ "u_calories() = 110000" ] }`| | get_calories_daily() | ✅ | ❌ | g | Return amount of calories character consumed before, up to 30 days, in kcal. Calorie diary is something only character has, so it can't be used with NPCs. Optional kwargs:
`day`: `d/v` - picks the date the value would be pulled from, from 0 to 30. Default 0, meaning amount of calories you consumed today.
`type`: `s/v` - picks the data that would be pulled. Possible values are: `spent` - how much calories character spent in different activities throughout the day; `gained` - how much calories character ate that day; `ingested` - how much calories character processed that day; `total` - `gained` minus `spent`. Default is `total`;

Example:
`"condition": { "math": [ "get_calories_daily() > 1000" ] }`
`{ "math": [ "foo = get_calories_daily('type':'gained', 'day':'1')" ] }`| +| quality( `s` / `v` ) | ✅ | ❌ | u, n | Return the level of a specified item tool quality. Only usable on item talkers.
Argument is the quality ID. Returns the lowest integer value if the item lacks the specified quality.
Optional kwargs:
`strict`: `true` / `false` (default false) When true the item must be empty to have the boiling quality.

Example
`"condition: { "math": [ " u_quality('HACK') > 0 " ] }`
`{ "math": [ "_cut_quality = u_quality('CUT') " ] }`
`condition: { "math": [ " u_quality('BOIL', 'strict': true ) > 0" ] }` #### List of Character and item aspects These can be read or written to with `val()`. diff --git a/src/item_location.cpp b/src/item_location.cpp index 09f2d209a550b..30de607475680 100644 --- a/src/item_location.cpp +++ b/src/item_location.cpp @@ -1182,3 +1182,10 @@ bool item_location::can_reload_with( const item_location &ammo, bool now ) const } return reloadable->can_reload_with( *ammo, now ); } + +int item_location::get_quality( const std::string &quality, bool strict ) const +{ + const item_location tool = *this; + quality_id qualityid( quality ); + return tool->get_quality_nonrecursive( qualityid, strict ); +} diff --git a/src/item_location.h b/src/item_location.h index 3b443303bc4d2..61492ce3cd777 100644 --- a/src/item_location.h +++ b/src/item_location.h @@ -163,6 +163,13 @@ class item_location */ bool can_reload_with( const item_location &ammo, bool now ) const; + /** + * returns the item's level of the specified quality. + * @param quality the name of quality to check the level of + * @param boiling true if the item is required to be empty to have the boiling quality + */ + int get_quality( const std::string &quality, bool strict ) const; + private: class impl; diff --git a/src/math_parser_diag.cpp b/src/math_parser_diag.cpp index 0518fd05ecd65..2b155dd15e408 100644 --- a/src/math_parser_diag.cpp +++ b/src/math_parser_diag.cpp @@ -1689,6 +1689,20 @@ diag_eval_dbl_f weight_eval( char scope, std::vector const & /* para }; } +diag_eval_dbl_f quality_eval( char scope, std::vector const ¶ms /* params */, + diag_kwargs const &kwargs /* kwargs */ ) +{ + diag_value strict_val = kwargs.kwarg_or( "strict" ); + + return[quality_param = params[0], strict_val, + beta = is_beta( scope )]( const_dialogue const & d ) { + std::string quality = quality_param.str( d ); + bool strict = is_true( strict_val.dbl( d ) ); + + return d.const_actor( beta )->get_quality( quality, strict ); + }; +} + diag_eval_dbl_f volume_eval( char scope, std::vector const & /* params */, diag_kwargs const & /* kwargs */ ) { @@ -1872,6 +1886,7 @@ std::map const dialogue_funcs{ { "school_level_adjustment", { "un", 1, school_level_adjustment_eval, school_level_adjustment_ass } }, { "spellcasting_adjustment", { "u", 1, nullptr, spellcasting_adjustment_ass } }, { "get_calories_daily", { "g", 0, get_daily_calories } }, + { "quality", { "un", 1, quality_eval } }, { "skill", { "un", 1, skill_eval, skill_ass } }, { "skill_exp", { "un", 1, skill_exp_eval, skill_exp_ass } }, { "spell_count", { "un", 0, spell_count_eval}}, diff --git a/src/talker.h b/src/talker.h index 23a8ef6db1152..293a3c1a309c2 100644 --- a/src/talker.h +++ b/src/talker.h @@ -646,6 +646,9 @@ class const_talker virtual int climate_control_str_chill() const { return 0; } + virtual int get_quality( const std::string &, bool ) const { + return 0; + } }; class talker: virtual public const_talker diff --git a/src/talker_item.cpp b/src/talker_item.cpp index 0044ec6277aa3..f71e7a5848473 100644 --- a/src/talker_item.cpp +++ b/src/talker_item.cpp @@ -126,6 +126,11 @@ int talker_item_const::get_weight() const return units::to_milligram( me_it_const->get_item()->weight() ); } +int talker_item_const::get_quality( const std::string &quality, bool strict ) const +{ + return me_it_const->get_quality( quality, strict ); +} + void talker_item::set_value( const std::string &var_name, const std::string &value ) { me_it->get_item()->set_var( var_name, value ); diff --git a/src/talker_item.h b/src/talker_item.h index 66ac3ae7929e8..edc04dc5201c8 100644 --- a/src/talker_item.h +++ b/src/talker_item.h @@ -59,6 +59,7 @@ class talker_item_const: public const_talker_cloner int encumbrance_at( bodypart_id & ) const override; int get_volume() const override; int get_weight() const override; + int get_quality( const std::string &, bool strict ) const override; private: const item_location *me_it_const{};