Skip to content

Commit

Permalink
[EoC]More armor information(coverage, encumbrance) (CleverRaven#69025)
Browse files Browse the repository at this point in the history
* eoc_armor_info

* document

* fix

* fix

* fix test

* fix

* test fix
  • Loading branch information
lispcoc authored Nov 6, 2023
1 parent 35f9284 commit c496e93
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 9 deletions.
37 changes: 36 additions & 1 deletion data/json/effects_on_condition/example_eocs.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@
{
"foreach": "ids",
"var": { "context_val": "id" },
"target": "flags",
"target": "flag",
"effect": [ { "u_message": "<context_val:id>" } ]
},
{ "u_message": "[foreach_test]item group" },
Expand All @@ -286,6 +286,41 @@
}
]
},
{
"type": "effect_on_condition",
"id": "EOC_armor_info_test",
"effect": [
{
"foreach": "ids",
"var": { "context_val": "id" },
"target": "bodypart",
"effect": [
{ "u_message": "[<context_val:id>]" },
{
"u_run_inv_eocs": "all",
"search_data": [ { "worn_only": true } ],
"true_eocs": [
{
"id": "EOC_armor_info_test_nested",
"effect": [
{ "math": [ "_coverage", "=", "n_coverage(_id)" ] },
{ "math": [ "_encumbrance", "=", "n_encumbrance(_id)" ] },
{
"if": { "math": [ "_coverage", ">", "0" ] },
"then": [
{ "u_message": " <npc_name>" },
{ "u_message": " coverage:<context_val:coverage>" },
{ "u_message": " encumbrance:<context_val:encumbrance>" }
]
}
]
}
]
}
]
}
]
},
{
"type": "effect_on_condition",
"id": "EOC_query_tile_test_anywhere",
Expand Down
19 changes: 19 additions & 0 deletions data/mods/TEST_DATA/EOC.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,25 @@
"id": "EOC_item_activate_test_nested",
"effect": [ { "u_activate": "deploy_furn", "target_var": { "u_val": "activate_pos" } } ]
},
{
"type": "effect_on_condition",
"id": "EOC_armor_math_test",
"effect": [
{ "u_spawn_item": "backpack", "force_equip": true },
{
"u_run_inv_eocs": "all",
"search_data": [ { "id": "backpack", "worn_only": true } ],
"true_eocs": [ "EOC_armor_math_test_nested" ]
},
{ "math": [ "u_key1", "=", "u_coverage('torso')" ] },
{ "math": [ "u_key2", "=", "u_encumbrance('torso')" ] }
]
},
{
"type": "effect_on_condition",
"id": "EOC_armor_math_test_nested",
"effect": [ { "math": [ "n_key1", "=", "n_coverage('torso')" ] }, { "math": [ "n_key2", "=", "n_encumbrance('torso')" ] } ]
},
{
"type": "effect_on_condition",
"id": "EOC_run_until_test",
Expand Down
14 changes: 7 additions & 7 deletions doc/EFFECT_ON_CONDITION.md
Original file line number Diff line number Diff line change
Expand Up @@ -1672,25 +1672,25 @@ Checks the level of `some_spell` spell, and, related to this, cast a spell of pi
Executes the effect repeatedly while storing the values ​​of a specific list one by one in the variable.

| Syntax | Optionality | Value | Info |
| --- | --- | --- | --- |
| "foreach" | **mandatory** | string | Type of list. `"ids"`, `"item_group"`, `"monstergroup"`, `"array"` are available. |
| "var" | **mandatory** | [variable objects](#variable-object) | Variable to store value in the list. |
| --- | --- | --- | --- |
| "foreach" | **mandatory** | string | Type of list. `"ids"`, `"item_group"`, `"monstergroup"`, `"array"` are available. |
| "var" | **mandatory** | [variable objects](#variable-object) | Variable to store value in the list. |
| "effect" | **mandatory** | effect | Effect(s) executed. |
| "target" | **mandatory** | See below | Changes depending on the value of "foreach". See below. |
| "target" | **mandatory** | See below | Changes depending on the value of "foreach". See below. |

The correspondence between "foreach" and "target" is as follows.

| "foreach" | Value | Info |
| --- | --- | ---
| "ids" | string | List the IDs of objects that appear in the game. `"flag"`, `"trait"`, `"vitamin"` are available. |
| --- | --- | --- |
| "ids" | string | List the IDs of objects that appear in the game. `"bodypart"`, `"flag"`, `"trait"`, `"vitamin"` are available. |
| "item_group" | string | List the IDs of items in the item group. |
| "monstergroup" | string | List the IDs of monsters in the monster group. |
| "array" | array of strings or [variable objects](#variable-object) | List simple strings. |

##### Valid talkers:

| Avatar | Character | NPC | Monster | Furniture | Item |
| ------ | --------- | --------- | ---- | ------- | --- |
| ------ | --------- | --------- | ---- | ------- | --- |
| ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |

##### Examples
Expand Down
2 changes: 2 additions & 0 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,9 @@ _function arguments are `d`oubles (or sub-expressions), `s`trings, or `v`[ariabl
|----------|------|--------|-------|-------------|
| armor(`s`/`v`,`s`/`v`) ||| u, n | Return the numerical value for a characters armor on a body part, for a damage type.<br/> Variables are damagetype ID, bodypart ID.<br/> Example:<br/>`"condition": { "math": [ "u_armor('bash', 'torso')", ">=", "5"] }`|
| attack_speed() ||| u, n | Return the characters current adjusted attack speed with their current weapon.<br/> Example:<br/>`"condition": { "math": [ "u_attack_speed()", ">=", "10"] }`|
| coverage(`s`/`v`) ||| u, n | Return the characters total coverage of a body part.<br/> Variable is bodypart ID. <br/> For items, returns typical coverage of the item. <br/><br/> Example:<br/>`"condition": { "math": [ "u_coverage('torso')", ">", "0"] }`|
| effect_intensity(`s`/`v`,...) ||| u, n | Return the characters intensity of effect.<br/> Variable is effect ID.<br/><br/> Optional kwargs:<br/>`bodypart`: `s`/`v` - Specify the bodypart to get/set intensity of effect.<br/><br/> Example:<br/>`"condition": { "math": [ "u_effect_intensity('bite', 'bodypart': 'torso')", ">", "1"] }`|
| encumbrance(`s`/`v`) ||| u, n | Return the characters total encumbrance of a body part.<br/> Variable is bodypart ID. <br/> For items, returns typical encumbrance of the item. <br/><br/> Example:<br/>`"condition": { "math": [ "u_encumbrance('torso')", ">", "0"] }`|
| hp(`s`/`v`) ||| u, n | Return or set the characters hp.<br/> Variable is bodypart ID. If omitted, get sum of all bodypart or set all bodypart.<br/> For items, returns current amount of damage required to destroy item. Variable is not required.<br/><br/> Example:<br/>`"condition": { "math": [ "hp('torso')", ">", "100"] }`|
| hp_max(`s`/`v`) ||| u, n | Return the characters max amount of hp on a body part.<br/> Variable is bodypart ID.<br/> For items, returns max amount of damage required to destroy item. Variable is not required. <br/> Example:<br/>`"condition": { "math": [ "u_hp_max('torso')", ">=", "100"] }`|
| game_option(`s`/`v`) ||| N/A<br/>(global) | Return the numerical value of a game option<br/> Example:<br/>`"condition": { "math": [ "game_option('NPC_SPAWNTIME')", ">=", "5"] }`|
Expand Down
18 changes: 18 additions & 0 deletions src/math_parser_diag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ std::function<double( dialogue & )> armor_eval( char scope,
};
}

std::function<double( dialogue & )> coverage_eval( char scope,
std::vector<diag_value> const &params, diag_kwargs const &/* kwargs */ )
{
return[bpid = params[0], beta = is_beta( scope )]( dialogue const & d ) {
bodypart_id bp( bpid.str( d ) );
return d.actor( beta )->coverage_at( bp );
};
}

std::function<double( dialogue & )> effect_intensity_eval( char scope,
std::vector<diag_value> const &params, diag_kwargs const &kwargs )
{
Expand All @@ -208,6 +217,15 @@ std::function<double( dialogue & )> effect_intensity_eval( char scope,
};
}

std::function<double( dialogue & )> encumbrance_eval( char scope,
std::vector<diag_value> const &params, diag_kwargs const &/* kwargs */ )
{
return[bpid = params[0], beta = is_beta( scope )]( dialogue const & d ) {
bodypart_id bp( bpid.str( d ) );
return d.actor( beta )->encumbrance_at( bp );
};
}

std::function<double( dialogue & )> hp_eval( char scope,
std::vector<diag_value> const &params, diag_kwargs const &/* kwargs */ )
{
Expand Down
4 changes: 4 additions & 0 deletions src/math_parser_diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ using decl_diag_ass = std::function<void( dialogue &, double )> ( char scope,
decl_diag_eval armor_eval;
decl_diag_eval attack_speed_eval;
decl_diag_eval dodge_eval;
decl_diag_eval coverage_eval;
decl_diag_eval effect_intensity_eval;
decl_diag_eval encumbrance_eval;
decl_diag_eval hp_eval;
decl_diag_ass hp_ass;
decl_diag_eval hp_max_eval;
Expand Down Expand Up @@ -129,7 +131,9 @@ inline std::map<std::string_view, dialogue_func_eval> const dialogue_eval_f{
{ "_test_diag_", { "g", -1, test_diag } },
{ "armor", { "un", 2, armor_eval } },
{ "attack_speed", { "un", 0, attack_speed_eval } },
{ "coverage", { "un", 1, coverage_eval } },
{ "effect_intensity", { "un", 1, effect_intensity_eval } },
{ "encumbrance", { "un", 1, encumbrance_eval } },
{ "game_option", { "g", 1, option_eval } },
{ "hp", { "un", -1, hp_eval } },
{ "hp_max", { "un", 1, hp_max_eval } },
Expand Down
6 changes: 5 additions & 1 deletion src/npctalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5161,7 +5161,11 @@ void talk_effect_fun_t::set_foreach( const JsonObject &jo, std::string_view memb
std::vector<std::string> list;

if( type == "ids" ) {
if( target == "flag" ) {
if( target == "bodypart" ) {
for( const body_part_type &bp : body_part_type::get_all() ) {
list.push_back( bp.id.str() );
}
} else if( target == "flag" ) {
for( const json_flag &f : json_flag::get_all() ) {
list.push_back( f.id.str() );
}
Expand Down
6 changes: 6 additions & 0 deletions src/talker.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,12 @@ class talker
virtual double armor_at( damage_type_id &, bodypart_id & ) const {
return 0;
}
virtual int coverage_at( bodypart_id & ) const {
return 0;
}
virtual int encumbrance_at( bodypart_id & ) const {
return 0;
}
virtual bool worn_with_flag( const flag_id &, const bodypart_id & ) const {
return false;
}
Expand Down
10 changes: 10 additions & 0 deletions src/talker_character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,16 @@ double talker_character_const::armor_at( damage_type_id &dt, bodypart_id &bp ) c
return me_chr_const->worn.damage_resist( dt, bp );
}

int talker_character_const::coverage_at( bodypart_id &id ) const
{
return me_chr_const->worn.get_coverage( id );
}

int talker_character_const::encumbrance_at( bodypart_id &id ) const
{
return me_chr_const->encumb( id );
}

void talker_character::mod_pain( int amount )
{
me_chr->mod_pain( amount );
Expand Down
2 changes: 2 additions & 0 deletions src/talker_character.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class talker_character_const: public talker_cloner<talker_character_const>
int attack_speed() const override;
int pain_cur() const override;
double armor_at( damage_type_id &dt, bodypart_id &bp ) const override;
int coverage_at( bodypart_id & ) const override;
int encumbrance_at( bodypart_id & ) const override;
int get_str_max() const override;
int get_dex_max() const override;
int get_int_max() const override;
Expand Down
10 changes: 10 additions & 0 deletions src/talker_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ int talker_item_const::get_hp_max( const bodypart_id & ) const
return me_it_const->get_item()->max_damage();
}

int talker_item_const::coverage_at( bodypart_id &id ) const
{
return me_it_const->get_item()->get_coverage( id );
}

int talker_item_const::encumbrance_at( bodypart_id &id ) const
{
return me_it_const->get_item()->get_encumber( get_player_character(), id );
}

int talker_item_const::get_volume() const
{

Expand Down
2 changes: 2 additions & 0 deletions src/talker_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class talker_item_const: public talker_cloner<talker_item_const>
int get_cur_hp( const bodypart_id & ) const override;
int get_hp_max( const bodypart_id & ) const override;

int coverage_at( bodypart_id & ) const override;
int encumbrance_at( bodypart_id & ) const override;
int get_volume() const override;
int get_weight() const override;
protected:
Expand Down
13 changes: 13 additions & 0 deletions tests/eoc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ effect_on_condition_EOC_TEST_TRANSFORM_RADIUS( "EOC_TEST_TRANSFORM_RADIUS" );
static const effect_on_condition_id
effect_on_condition_EOC_activate_mutation_to_start_test( "EOC_activate_mutation_to_start_test" );
static const effect_on_condition_id effect_on_condition_EOC_alive_test( "EOC_alive_test" );
static const effect_on_condition_id
effect_on_condition_EOC_armor_math_test( "EOC_armor_math_test" );
static const effect_on_condition_id effect_on_condition_EOC_attack_test( "EOC_attack_test" );
static const effect_on_condition_id
effect_on_condition_EOC_combat_mutator_test( "EOC_combat_mutator_test" );
Expand Down Expand Up @@ -810,6 +812,17 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" )
// Teleport test for item
CHECK( effect_on_condition_EOC_item_teleport_test->activate( d ) );
CHECK( get_map().i_at( get_map().getlocal( pos_after ) ).size() == 3 );

// Math function test for armor
CHECK( effect_on_condition_EOC_armor_math_test->activate( d ) );

const item &check_item = get_avatar().worn.i_at( 0 );

REQUIRE( check_item.typeId() == itype_backpack );
CHECK( std::stod( get_avatar().get_value( "npctalk_var_key1" ) ) == Approx( 27 ) );
CHECK( std::stod( get_avatar().get_value( "npctalk_var_key2" ) ) == Approx( 2 ) );
CHECK( std::stod( check_item.get_var( "npctalk_var_key1" ) ) == Approx( 27 ) );
CHECK( std::stod( check_item.get_var( "npctalk_var_key2" ) ) == Approx( 2 ) );
}

TEST_CASE( "EOC_event_test", "[eoc]" )
Expand Down

0 comments on commit c496e93

Please sign in to comment.