Skip to content

Commit

Permalink
Mutators for EOCs (CleverRaven#65539)
Browse files Browse the repository at this point in the history
* Mutator EOCs

* Update data/mods/TEST_DATA/EOC.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
bombasticSlacks and github-actions[bot] authored May 8, 2023
1 parent e3ecc4e commit ea17d8e
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 2 deletions.
15 changes: 15 additions & 0 deletions data/mods/TEST_DATA/EOC.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@
"condition": { "expects_vars": [ "npctalk_var_key1", "npctalk_var_key2", "npctalk_var_key3" ] },
"effect": [ { "math": [ "key1", "=", "_key1" ] }, { "math": [ "key2", "=", "_key2" ] }, { "math": [ "key3", "=", "_key3" ] } ]
},
{
"type": "effect_on_condition",
"id": "EOC_mutator_test",
"effect": [
{ "set_string_var": "mon_zombie", "target_var": { "context_val": "temp" } },
{
"set_string_var": { "mutator": "mon_faction", "mtype_id": "mon_zombie" },
"target_var": { "global_val": "key1" }
},
{
"set_string_var": { "mutator": "mon_faction", "mtype_id": { "context_val": "temp" } },
"target_var": { "global_val": "key2" }
}
]
},
{
"type": "effect_on_condition",
"id": "EOC_math_test_context",
Expand Down
12 changes: 12 additions & 0 deletions doc/NPCs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,18 @@ Example:
]
```

### Mutators
`mutators`: take in an ammount of data and provide you with a relevant string. This can be used to get information about items, monsters, etc. from the id, or other data. Mutators can be used anywhere that a string [variable object](#variable-object) can be used. Mutators take the form:
```json
{ "mutator": "MUTATOR_NAME", "REQUIRED_KEY1": "REQUIRED_VALUE1", ..., "REQUIRED_KEYn": "REQUIRED_VALUEn" }
```

#### List Of Mutators
Mutator Name | Required Keys | Description
--- | --- | ---
`"mon_faction"` | `mtype_id`: String or [variable object](#variable-object). | Returns the faction of the monster with mtype_id.


### Compare Numbers and Arithmetics
*`arithmetic` and `compare_num` are deprecated in the long term. See [Math](#math) for the replacement.*

Expand Down
26 changes: 24 additions & 2 deletions src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,14 @@ str_or_var get_str_or_var( const JsonValue &jv, const std::string &member, bool
if( jv.test_string() ) {
ret_val.str_val = jv.get_string();
} else if( jv.test_object() ) {
ret_val.var_val = read_var_info( jv.get_object() );
ret_val.default_val = default_val;
const JsonObject &jo = jv.get_object();
if( jo.has_member( "mutator" ) ) {
// if we have a mutator then process that here.
ret_val.function = conditional_t::get_get_string( jo );
} else {
ret_val.var_val = read_var_info( jo );
ret_val.default_val = default_val;
}
} else if( required ) {
jv.throw_error( "No valid value for " + member );
} else {
Expand Down Expand Up @@ -1410,6 +1416,22 @@ void conditional_t::set_math( const JsonObject &jo, const std::string_view membe
};
}

template<class J>
std::function<std::string( const dialogue & )> conditional_t::get_get_string( J const &jo )
{
if( jo.get_string( "mutator" ) == "mon_faction" ) {
str_or_var mtypeid = get_str_or_var( jo.get_member( "mtype_id" ), "mtype_id" );
return [mtypeid]( const dialogue & d ) {
return static_cast<mtype_id>( mtypeid.evaluate( d ) )->default_faction.str();
};
}

jo.throw_error( "unrecognized string mutator in " + jo.str() );
return []( const dialogue & ) {
return "INVALID";
};
}

template<class J>
// NOLINTNEXTLINE(readability-function-cognitive-complexity): not my problem!!
std::function<double( dialogue & )> conditional_t::get_get_dbl( J const &jo )
Expand Down
2 changes: 2 additions & 0 deletions src/condition.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ struct conditional_t {
void set_compare_num( const JsonObject &jo, std::string_view member );
void set_math( const JsonObject &jo, std::string_view member );
template<class J>
static std::function<std::string( const dialogue & )> get_get_string( J const &jo );
template<class J>
static std::function<double( dialogue & )> get_get_dbl( J const &jo );
static std::function<double( dialogue & )> get_get_dbl( const std::string &value,
const JsonObject &jo );
Expand Down
3 changes: 3 additions & 0 deletions src/dialogue_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ std::string read_var_value( const var_info &info, const dialogue &d )

std::string str_or_var::evaluate( dialogue const &d ) const
{
if( function.has_value() ) {
return function.value()( d );
}
if( str_val.has_value() ) {
return str_val.value();
}
Expand Down
1 change: 1 addition & 0 deletions src/dialogue_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ struct str_or_var {
std::optional<std::string> str_val;
std::optional<var_info> var_val;
std::optional<std::string> default_val;
std::optional<std::function<std::string( const dialogue & )>> function;
std::string evaluate( dialogue const &d ) const;
};

Expand Down
17 changes: 17 additions & 0 deletions tests/eoc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static const effect_on_condition_id
effect_on_condition_EOC_math_var( "EOC_math_var" );
static const effect_on_condition_id
effect_on_condition_EOC_math_weighted_list( "EOC_math_weighted_list" );
static const effect_on_condition_id effect_on_condition_EOC_mutator_test( "EOC_mutator_test" );
static const effect_on_condition_id effect_on_condition_EOC_run_with_test( "EOC_run_with_test" );
static const effect_on_condition_id
effect_on_condition_EOC_run_with_test_expects_fail( "EOC_run_with_test_expects_fail" );
Expand Down Expand Up @@ -232,6 +233,22 @@ TEST_CASE( "EOC_context_test", "[eoc][math_parser]" )
CHECK( d.get_value( "npctalk_var_simple" ).empty() );
}

TEST_CASE( "EOC_mutator_test", "[eoc][math_parser]" )
{
clear_avatar();
clear_map();

dialogue d( get_talker_for( get_avatar() ), std::make_unique<talker>() );
global_variables &globvars = get_globals();
globvars.clear_global_values();

REQUIRE( globvars.get_global_value( "npctalk_var_key1" ).empty() );
REQUIRE( globvars.get_global_value( "npctalk_var_key2" ).empty() );
CHECK( effect_on_condition_EOC_mutator_test->activate( d ) );
CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "zombie" );
CHECK( globvars.get_global_value( "npctalk_var_key2" ) == "zombie" );
}

TEST_CASE( "EOC_activity_ongoing", "[eoc][timed_event]" )
{
clear_avatar();
Expand Down

0 comments on commit ea17d8e

Please sign in to comment.