From 3509761cd676133ce44396d7d9246a2ca5032379 Mon Sep 17 00:00:00 2001 From: GuardianDll Date: Sat, 12 Oct 2024 16:03:07 +0200 Subject: [PATCH 1/2] add f_map_run_eocs effect --- doc/EFFECT_ON_CONDITION.md | 60 ++++++++++++++++++++++++++++++++++++++ src/npctalk.cpp | 45 ++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md index 13ff7e2d38832..4636cedc3a733 100644 --- a/doc/EFFECT_ON_CONDITION.md +++ b/doc/EFFECT_ON_CONDITION.md @@ -2267,6 +2267,66 @@ Pick all items with `RECHARGE` _or_ `ELECTRONIC` flags, and run `EOC_PRINT_ITEM_ } ``` +#### `u_map_run_eocs`, `npc_map_run_eocs` +Picks all tiles around you, npc or target_var, stores it's coordinates in `store_coordinates_in`, and then checks EoC conditions for each tile picked +Used if you need to check if specific furniture or terrain is around + +| Syntax | Optionality | Value | Info | +| --- | --- | --- | --- | +| "u_map_run_eocs", "npc_map_run_eocs" | **mandatory** | string, [variable object](#variable-object) or array | EoC or EoCs that would be run | +| "store_coordinates_in" | optional | [variable object](#variable-object) | variable, where testet coordinate is stored | +| "condition" | optional | condition | condition that would be checked if eoc need to be run or not. Can (and intended to) use variable from `store_coordinates_in`. Default true (run always) | +| "target_var" | optional | [variable object](#variable-object) | location variable, around which the game should scan; if omitted, sticks to `u_` or `npc_` position | +| "range" | optional | int or [variable object](#variable-object) | how big the search radius should be; default 1 ( 3x3 square with character in the middle ) | +| stop_at_first | optional | bool | If true, stops execution after the first `condition` is met; if false, runs EoC on all tiles that met condition. Default false | + +##### Examples + +Picks range of 6 tiles around the player, and check is there any terrain with `TREE` flag +```json +{ + "type": "effect_on_condition", + "id": "SOME_TEST_EOC", + "effect": [ + { + "u_map_run_eocs": [ "SOME_ANOTHER_TEST_EOC" ], + "range": 6, + "store_coordinates_in": { "context_val": "loc" }, + "condition": { "map_terrain_with_flag": "TREE", "loc": { "context_val": "loc" } } + } + ] +}, +{ + "type": "effect_on_condition", + "id": "SOME_ANOTHER_TEST_EOC", + "effect": [ { "u_message": "tripoint contains TREE" } ] +} +``` + +Picks all TREEs in 50 tiles range, and burn it +```json + { + "type": "effect_on_condition", + "id": "QWERTY", + "effect": [ + { + "u_map_run_eocs": [ "QWERTYYUIOP" ], + "range": 50, + "store_coordinates_in": { "context_val": "loc" }, + "stop_at_first": false, + "condition": { "map_terrain_with_flag": "TREE", "loc": { "context_val": "loc" } } + } + ] + }, + { + "type": "effect_on_condition", + "id": "QWERTYYUIOP", + "effect": [ + { "u_set_field": "fd_fire", "radius": 0, "intensity": 10, "target_var": { "context_val": "loc" } } + ] + } +``` + #### `u_map_run_item_eocs`, `npc_map_run_item_eocs` Search items around you on the map, and run EoC on them diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 7b931023b4e75..f481322171576 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -5885,6 +5885,50 @@ talk_effect_fun_t::func f_map_run_item_eocs( const JsonObject &jo, std::string_v }; } +talk_effect_fun_t::func f_map_run_eocs( const JsonObject &jo, std::string_view member, + const std::string_view src, bool is_npc ) +{ + std::vector eocs = load_eoc_vector( jo, member, src ); + std::optional target_var; + if( jo.has_member( "target_var" ) ) { + target_var = read_var_info( jo.get_object( "target_var" ) ); + } + std::function cond; + read_condition( jo, "condition", cond, true ); + dbl_or_var range = get_dbl_or_var( jo, "range", false, 1 ); + + var_info store_coordinates_in; + if( jo.has_member( "store_coordinates_in" ) ) { + store_coordinates_in = read_var_info( jo.get_member( "store_coordinates_in" ) ); + } + bool stop_at_first = jo.get_bool( "stop_at_first", true ); + + return [is_npc, eocs, target_var, cond, range, store_coordinates_in, + stop_at_first]( dialogue & d ) { + + tripoint_abs_ms pos; + if( target_var.has_value() ) { + pos = get_tripoint_from_var( target_var, d, is_npc ); + } else { + pos = d.actor( is_npc )->global_pos(); + } + + std::vector adjacent = closest_points_first( pos, range.evaluate( d ) ); + + for( tripoint_abs_ms point : adjacent ) { + write_var_value( store_coordinates_in.type, store_coordinates_in.name, &d, point.to_string() ); + for( effect_on_condition_id eoc_id : eocs ) { + if( cond( d ) ) { + eoc_id->activate( d ); + if( stop_at_first ) { + return; + } + } + } + } + }; +} + talk_effect_fun_t::func f_set_talker( const JsonObject &jo, std::string_view member, const std::string_view, bool is_npc ) { @@ -6924,6 +6968,7 @@ parsers = { { "u_bulk_trade_accept", "npc_bulk_trade_accept", jarg::member, &talk_effect_fun::f_bulk_trade_accept }, { "u_bulk_donate", "npc_bulk_donate", jarg::member, &talk_effect_fun::f_bulk_trade_accept }, { "u_cast_spell", "npc_cast_spell", jarg::member, &talk_effect_fun::f_cast_spell }, + { "u_map_run_eocs", "npc_map_run_eocs", jarg::member, &talk_effect_fun::f_map_run_eocs }, { "u_map_run_item_eocs", "npc_map_run_item_eocs", jarg::member, &talk_effect_fun::f_map_run_item_eocs }, { "companion_mission", jarg::string, &talk_effect_fun::f_companion_mission }, { "reveal_map", jarg::object, &talk_effect_fun::f_reveal_map }, From 28502f206d69695818d78318032f9bb74cb2ee41 Mon Sep 17 00:00:00 2001 From: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> Date: Sat, 12 Oct 2024 20:19:16 +0200 Subject: [PATCH 2/2] Update doc/EFFECT_ON_CONDITION.md Co-authored-by: Steve Brand --- doc/EFFECT_ON_CONDITION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md index 4636cedc3a733..fdcc4b88d7d2e 100644 --- a/doc/EFFECT_ON_CONDITION.md +++ b/doc/EFFECT_ON_CONDITION.md @@ -2274,7 +2274,7 @@ Used if you need to check if specific furniture or terrain is around | Syntax | Optionality | Value | Info | | --- | --- | --- | --- | | "u_map_run_eocs", "npc_map_run_eocs" | **mandatory** | string, [variable object](#variable-object) or array | EoC or EoCs that would be run | -| "store_coordinates_in" | optional | [variable object](#variable-object) | variable, where testet coordinate is stored | +| "store_coordinates_in" | optional | [variable object](#variable-object) | variable, where tested coordinate is stored | | "condition" | optional | condition | condition that would be checked if eoc need to be run or not. Can (and intended to) use variable from `store_coordinates_in`. Default true (run always) | | "target_var" | optional | [variable object](#variable-object) | location variable, around which the game should scan; if omitted, sticks to `u_` or `npc_` position | | "range" | optional | int or [variable object](#variable-object) | how big the search radius should be; default 1 ( 3x3 square with character in the middle ) |