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

mics eoc changes #77941

Merged
merged 3 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 1 addition & 7 deletions data/json/effects_on_condition/computer_eocs.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,7 @@
"type": "effect_on_condition",
"id": "EOC_CHECK_MAP_CACHE",
"//": "todo: make it not reveal fungal towers and such? would require edits in reveal_map code, to accept blacklist of locations?",
"condition": {
"or": [
{ "compare_string": [ "has", { "npc_val": "map_cache" } ] },
{ "compare_string": [ "lack", { "npc_val": "map_cache" } ] },
{ "compare_string": [ "read", { "npc_val": "map_cache" } ] }
]
},
"condition": { "or": [ { "compare_string": [ { "npc_val": "map_cache" }, "has", "lack", "read" ] } ] },
"false_effect": [ { "npc_add_var": "map_cache", "possible_values": [ "has", "lack" ] }, { "run_eocs": "EOC_CHECK_MAP_CACHE" } ],
"effect": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1335,18 +1335,23 @@
{ "u_has_items": { "item": "nre_recorder", "charges": 1 } },
{
"or": [
{ "compare_string": [ "mon_hound_tindalos", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_darkman", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_zombie_phase_shrike", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_swarm_structure", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_better_half", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_hallucinator", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_archunk_strong", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_void_spider", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_XEDRA_officer", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_eigenspectre_3", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_eigenspectre_4", { "context_val": "victim_type" } ] },
{ "compare_string": [ "mon_living_vector", { "context_val": "victim_type" } ] }
{
"compare_string": [
{ "context_val": "victim_type" },
"mon_hound_tindalos",
"mon_darkman",
"mon_zombie_phase_shrike",
"mon_swarm_structure",
"mon_better_half",
"mon_hallucinator",
"mon_archunk_strong",
"mon_void_spider",
"mon_XEDRA_officer",
"mon_eigenspectre_3",
"mon_eigenspectre_4",
"mon_living_vector"
]
}
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@
},
{
"type": "effect_on_condition",
"id": "EOC_vitrified_farm_entry",
"id": "EOC_vitrified_farm_entry_event",
"eoc_type": "EVENT",
"required_event": "avatar_enters_omt",
"effect": [ { "run_eocs": "EOC_vitrified_farm_entry" } ]
},
{
"type": "effect_on_condition",
"id": "EOC_vitrified_farm_entry",
"condition": {
"and": [
{ "or": [ { "u_at_om_location": "unvitrified_farm_0" }, { "u_at_om_location": "unvitrified_orchard" } ] },
Expand All @@ -41,6 +46,12 @@
}
]
},
"false_effect": [
{
"if": { "not": { "u_has_trait": "NOT_GLASS" } },
"then": { "run_eocs": [ "EOC_vitrified_farm_entry" ], "time_in_future": "1 seconds" }
}
],
"effect": [
{
"place_override": { "global_val": "place_name", "default_str": "Quiet Farmhouse" },
Expand Down
25 changes: 14 additions & 11 deletions data/json/effects_on_condition/npc_eocs/generic_npc_eocs.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,20 +386,23 @@
"eoc_type": "EVENT",
"required_event": "avatar_moves",
"condition": "u_is_underwater",
"//": "I would assume that Mycus spores are a bit sticky to keep them from coming off, so this has a chance to be removed instead of a guarantee.",
"effect": [
{
"run_eocs": {
"id": "EOC_REMOVE_HARD_THINGS_CHECK",
"global": false,
"eoc_type": "EVENT",
"required_event": "avatar_moves",
"condition": { "x_in_y_chance": { "x": 1, "y": 10 } },
"//": "I would assume that Mycus spores are a bit sticky to keep them from coming off, so this has a chance to be removed instead of a garuntee.",
"effect": [ { "u_lose_effect": "spores" } ]
}
"if": { "and": [ { "u_has_effect": "spores" }, { "x_in_y_chance": { "x": 1, "y": 10 } } ] },
"then": [
{ "u_message": "You scrub your body extensively, and spores are finally gone.", "type": "good" },
{ "u_lose_effect": "spores" }
]
},
{
"if": { "u_has_effect": "boomered" },
"then": [ { "u_message": "You wash the bile from your face.", "type": "good" }, { "u_lose_effect": "boomered" } ]
},
{ "u_lose_effect": "boomered" },
{ "u_lose_effect": "corroding" }
{
"if": { "u_has_effect": "corroding" },
"then": [ { "u_message": "You wash the acid from your body.", "type": "good" }, { "u_lose_effect": "corroding" } ]
}
]
},
{
Expand Down
43 changes: 43 additions & 0 deletions data/mods/TEST_DATA/effect_on_condition.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,48 @@
{ "set_string_var": "mixin fail alpha", "target_var": { "global_val": "alpha_name" } },
{ "set_string_var": "mixin fail beta", "target_var": { "global_val": "beta_name" } }
]
},
{
"type": "effect_on_condition",
"id": "EOC_compare_string_test",
"effect": [
{ "if": { "compare_string": [ "yes", "yes" ] }, "then": { "math": [ "eoc_compare_string_test_1", "++" ] } },
{ "if": { "compare_string": [ "yes", "no" ] }, "else": { "math": [ "eoc_compare_string_test_2", "++" ] } },
{
"if": { "compare_string": [ "yes", "yes", "yes" ] },
"then": { "math": [ "eoc_compare_string_test_3", "++" ] }
},
{
"if": { "compare_string": [ "yes", "yes", "no" ] },
"then": { "math": [ "eoc_compare_string_test_4", "++" ] }
},
{ "if": { "compare_string": [ "yes", "no", "eh" ] }, "else": { "math": [ "eoc_compare_string_test_5", "++" ] } }
]
},
{
"type": "effect_on_condition",
"id": "EOC_compare_string_match_all_test",
"effect": [
{
"if": { "compare_string_match_all": [ "yes", "yes" ] },
"then": { "math": [ "eoc_compare_string_match_all_test_1", "++" ] }
},
{
"if": { "compare_string_match_all": [ "yes", "no" ] },
"else": { "math": [ "eoc_compare_string_match_all_test_2", "++" ] }
},
{
"if": { "compare_string_match_all": [ "yes", "yes", "yes" ] },
"then": { "math": [ "eoc_compare_string_match_all_test_3", "++" ] }
},
{
"if": { "compare_string_match_all": [ "yes", "yes", "no" ] },
"else": { "math": [ "eoc_compare_string_match_all_test_4", "++" ] }
},
{
"if": { "compare_string_match_all": [ "yes", "no", "eh" ] },
"else": { "math": [ "eoc_compare_string_match_all_test_5", "++" ] }
}
]
}
]
42 changes: 39 additions & 3 deletions doc/EFFECT_ON_CONDITION.md
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,8 @@ checks this var exists
```

### `compare_string`
- type: pair of strings or [variable objects](#variable-object)
- Compare two strings, and return true if strings are equal
- type: array of strings or [variable objects](#variable-object)
- Compare all strings, and return true if at least two of them match

#### Examples
checks if `victim_type` is `mon_zombie_phase_shrike`
Expand All @@ -569,6 +569,42 @@ checks is `victim_type` has `zombie` faction
{ "compare_string": [ "zombie", { "mutator": "mon_faction", "mtype_id": { "context_val": "victim_type" } } ] }
```

Check if victim_type is any in the list
```json
"compare_string": [
{ "context_val": "victim_type" },
"mon_hound_tindalos",
"mon_darkman",
"mon_zombie_phase_shrike",
"mon_swarm_structure",
"mon_better_half",
"mon_hallucinator",
"mon_archunk_strong",
"mon_void_spider",
"mon_XEDRA_officer",
"mon_eigenspectre_3",
"mon_eigenspectre_4",
"mon_living_vector"
]
```

Check if `map_cache` contain value `has`, `lack` or `read`
```json
{ "compare_string": [ { "npc_val": "map_cache" }, "has", "lack", "read" ] }
```

### `compare_string_match_all`
- type: array of strings or [variable objects](#variable-object)
- Compare all strings, and return true if all of them match
- For two strings the check is same as compare_string

#### Examples

Check if two variables are `yes`
```json
"compare_string": [ "yes", { "context_val": "some_context_should_be_yes" }, { "context_val": "some_another_context_also_should_be_yes" } ]
```

### `u_profession`
- type: string or [variable object](#variable-object)
- Return true if player character has the given profession id or its "hobby" subtype
Expand Down Expand Up @@ -1358,7 +1394,7 @@ Every event EOC passes context vars with each of their key value pairs that the
| activates_mininuke | Triggers when any character arms a mininuke | { "character", `character_id` } | character / NONE |
| administers_mutagen | | { "character", `character_id` },<br/> { "technique", `mutagen_technique` }, | character / NONE |
| angers_amigara_horrors | Triggers when amigara horrors are spawned as part of a mine finale | NONE | avatar / NONE |
| avatar_enters_omt | | { "pos", `tripoint` },<br/> { "oter_id", `oter_id` }, | avatar / NONE |
| avatar_enters_omt | Triggers when player crosses the overmap boundary, including when player spawns | { "pos", `tripoint` },<br/> { "oter_id", `oter_id` }, | avatar / NONE |
| avatar_moves | | { "mount", `mtype_id` },<br/> { "terrain", `ter_id` },<br/> { "movement_mode", `move_mode_id` },<br/> { "underwater", `bool` },<br/> { "z", `int` }, | avatar / NONE |
| avatar_dies | | NONE | avatar / NONE |
| awakes_dark_wyrms | Triggers when `pedestal_wyrm` examine action is used | NONE | avatar / NONE |
Expand Down
49 changes: 33 additions & 16 deletions src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1829,26 +1829,42 @@ conditional_t::func f_has_faction_trust( const JsonObject &jo, std::string_view

conditional_t::func f_compare_string( const JsonObject &jo, std::string_view member )
{
str_or_var first;
str_or_var second;
JsonArray objects = jo.get_array( member );
if( objects.size() != 2 ) {
jo.throw_error( "incorrect number of values. Expected 2 in " + jo.str() );
}
// return true if at least two strings match, OR

if( objects.has_object( 0 ) ) {
first = get_str_or_var( objects.next_value(), member, true );
} else {
first.str_val = objects.next_string();
std::vector<str_or_var> values;
for( JsonValue jv : jo.get_array( member ) ) {
values.emplace_back( get_str_or_var( jv, member ) );
}
if( objects.has_object( 1 ) ) {
second = get_str_or_var( objects.next_value(), member, true );
} else {
second.str_val = objects.next_string();

return [values]( const_dialogue const & d ) {
std::unordered_set<std::string> seen_values;
for( const str_or_var &val : values ) {
std::string evaluated_value = val.evaluate( d );
if( seen_values.count( evaluated_value ) > 0 ) {
return true;
}
seen_values.insert( evaluated_value );
}
return false;
};
}

conditional_t::func f_compare_string_match_all( const JsonObject &jo, std::string_view member )
{
// return true if all strings match, AND
std::vector<str_or_var> values;
for( JsonValue jv : jo.get_array( member ) ) {
values.emplace_back( get_str_or_var( jv, member ) );
}

return [first, second]( const_dialogue const & d ) {
return first.evaluate( d ) == second.evaluate( d );
return [values]( const_dialogue const & d ) {
std::string first_value = values[0].evaluate( d );
for( size_t i = 1; i < values.size(); ++i ) {
if( values[i].evaluate( d ) != first_value ) {
return false;
}
}
return true;
};
}

Expand Down Expand Up @@ -2628,6 +2644,7 @@ parsers = {
{"u_has_faction_trust", jarg::member | jarg::array, &conditional_fun::f_has_faction_trust },
{"math", jarg::member, &conditional_fun::f_math },
{"compare_string", jarg::member, &conditional_fun::f_compare_string },
{"compare_string_match_all", jarg::member, &conditional_fun::f_compare_string_match_all },
{"get_condition", jarg::member, &conditional_fun::f_get_condition },
{"test_eoc", jarg::member, &conditional_fun::f_test_eoc },
};
Expand Down
47 changes: 47 additions & 0 deletions tests/eoc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ static const effect_on_condition_id effect_on_condition_EOC_attack_test( "EOC_at
static const effect_on_condition_id
effect_on_condition_EOC_combat_mutator_test( "EOC_combat_mutator_test" );
static const effect_on_condition_id
effect_on_condition_EOC_compare_string_match_all_test( "EOC_compare_string_match_all_test" );
static const effect_on_condition_id
effect_on_condition_EOC_compare_string_test( "EOC_compare_string_test" );
static const effect_on_condition_id
effect_on_condition_EOC_increment_var_var( "EOC_increment_var_var" );
static const effect_on_condition_id
effect_on_condition_EOC_item_activate_test( "EOC_item_activate_test" );
Expand Down Expand Up @@ -1414,6 +1418,49 @@ TEST_CASE( "EOC_string_test", "[eoc]" )
CHECK( get_avatar().get_value( "key3" ) == "nest4" );
}

TEST_CASE( "EOC_compare_string_test", "[eoc]" )
{
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( "eoc_compare_string_test_1" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_test_2" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_test_3" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_test_4" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_test_5" ).empty() );

CHECK( effect_on_condition_EOC_compare_string_test->activate( d ) );

CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_test_1" ) ) == Approx( 1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_test_2" ) ) == Approx( 1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_test_3" ) ) == Approx( 1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_test_4" ) ) == Approx( 1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_test_5" ) ) == Approx( 1 ) );

REQUIRE( globvars.get_global_value( "eoc_compare_string_match_all_test_1" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_match_all_test_2" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_match_all_test_3" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_match_all_test_4" ).empty() );
REQUIRE( globvars.get_global_value( "eoc_compare_string_match_all_test_5" ).empty() );

CHECK( effect_on_condition_EOC_compare_string_match_all_test->activate( d ) );

CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_match_all_test_1" ) ) == Approx(
1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_match_all_test_2" ) ) == Approx(
1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_match_all_test_3" ) ) == Approx(
1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_match_all_test_4" ) ) == Approx(
1 ) );
CHECK( std::stod( globvars.get_global_value( "eoc_compare_string_match_all_test_5" ) ) == Approx(
1 ) );
}

TEST_CASE( "EOC_run_eocs", "[eoc]" )
{
clear_avatar();
Expand Down
Loading