Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow EOCs to read item tool qualities #79511

Merged
merged 5 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/JSON/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.<br/><br/>Example:<br/>`"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:<br/>`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.<br/>`dont_affect_weariness`: `true`/`false` (default false) When assigning value, whether the gained/spent calories should be tracked by weariness.<br/><br/>Example:<br/>`"condition": { "math": [ "u_calories() < 0" ] }`<br/>`"condition": { "math": [ "u_calories('format': 'percent') > 0" ] }`<br/>`"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:<br/>`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.<br/>`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`;<br/><br/>Example:<br/>`"condition": { "math": [ "get_calories_daily() > 1000" ] }`<br/> `{ "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.<br/>Argument is the quality ID. Returns the lowest integer value if the item lacks the specified quality.<br/>Optional kwargs:<br/>`boiling`: `true` / `false` (default false) When true the item must be empty to have the boiling quality.<br/><br/>Example<br/>`"condition: { "math": [ " u_quality('HACK') > 0 " ] }`<br/>`{ "math": [ "_cut_quality = u_quality('CUT') " ] }`<br/>`condition: { "math": [ " u_quality('BOIL', 'boiling': true ) > 0" ] }`

#### List of Character and item aspects
These can be read or written to with `val()`.
Expand Down
7 changes: 7 additions & 0 deletions src/item_location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 boiling ) const
{
const item_location tool = *this;
quality_id qualityid( quality );
return tool->get_quality_nonrecursive( qualityid, boiling );
}
7 changes: 7 additions & 0 deletions src/item_location.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 boiling ) const;

private:
class impl;

Expand Down
19 changes: 19 additions & 0 deletions src/math_parser_diag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,24 @@ diag_eval_dbl_f weight_eval( char scope, std::vector<diag_value> const & /* para
};
}

diag_eval_dbl_f quality_eval( char scope, std::vector<diag_value> const &params /* params */,
diag_kwargs const &kwargs /* kwargs */ )
{
diag_value boiling_val = kwargs.kwarg_or( "boiling" );
QuillInkwell marked this conversation as resolved.
Show resolved Hide resolved

return[quality_param = params[0], boiling_val,
beta = is_beta( scope )]( const_dialogue const & d ) {
item_location const *it = d.const_actor( beta )->get_const_item();
if( it && *it ) {
std::string quality = quality_param.str( d );
bool boiling = is_true( boiling_val.dbl( d ) );

return d.const_actor( beta )->get_quality( quality, boiling );
}
QuillInkwell marked this conversation as resolved.
Show resolved Hide resolved
throw math::runtime_error( "For quality(), talker is not an item" );
};
}

diag_eval_dbl_f volume_eval( char scope, std::vector<diag_value> const & /* params */,
diag_kwargs const & /* kwargs */ )
{
Expand Down Expand Up @@ -1872,6 +1890,7 @@ std::map<std::string_view, dialogue_func> 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}},
Expand Down
3 changes: 3 additions & 0 deletions src/talker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/talker_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 boiling ) const
{
return me_it_const->get_quality( quality, boiling );
}

void talker_item::set_value( const std::string &var_name, const std::string &value )
{
me_it->get_item()->set_var( var_name, value );
Expand Down
1 change: 1 addition & 0 deletions src/talker_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class talker_item_const: public const_talker_cloner<talker_item_const>
int encumbrance_at( bodypart_id & ) const override;
int get_volume() const override;
int get_weight() const override;
int get_quality( const std::string &, bool boiling ) const override;

private:
const item_location *me_it_const{};
Expand Down
Loading