From 067f6ad06d6a8b6b86ae80f84a7a25ce45b679bd Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Fri, 15 Dec 2023 16:38:21 -0500 Subject: [PATCH] Allow excluding items lacking flags (#70171) * First * Test fix --- data/mods/TEST_DATA/EOC.json | 16 ++++++++++++++++ doc/EFFECT_ON_CONDITION.md | 2 +- src/npctalk.cpp | 9 +++++++++ tests/eoc_test.cpp | 10 ++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/data/mods/TEST_DATA/EOC.json b/data/mods/TEST_DATA/EOC.json index 3fa87d2835e3e..5f525e00bc992 100644 --- a/data/mods/TEST_DATA/EOC.json +++ b/data/mods/TEST_DATA/EOC.json @@ -81,6 +81,22 @@ "id": "EOC_run_inv_test4_nested", "effect": [ { "npc_add_var": "key4", "type": "general", "context": "run_inv_test", "value": "yes" } ] }, + { + "type": "effect_on_condition", + "id": "EOC_run_inv_test5_nested", + "effect": [ { "npc_add_var": "key5", "type": "general", "context": "run_inv_test", "value": "yes" } ] + }, + { + "type": "effect_on_condition", + "id": "EOC_run_inv_test5", + "effect": [ + { + "u_run_inv_eocs": "all", + "true_eocs": [ "EOC_run_inv_test5_nested" ], + "search_data": [ { "excluded_flags": [ "BELT_CLIP" ] } ] + } + ] + }, { "type": "effect_on_condition", "id": "EOC_item_math_test", diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md index e7e4f2b7f05b3..9622559f0a7f2 100644 --- a/doc/EFFECT_ON_CONDITION.md +++ b/doc/EFFECT_ON_CONDITION.md @@ -1901,7 +1901,7 @@ Run EOCs on items in your or NPC's inventory | Syntax | Optionality | Value | Info | | --- | --- | --- | --- | | "u_run_inv_eocs" / "npc_run_inv_eocs" | **mandatory** | string or [variable object](#variable-object) | way the item would be picked;
values can be:
`all` - all items that match the conditions are picked;
`random` - from all items that match the conditions, one picked;
`manual` - menu is open with all items that can be picked, and you can choose one;
`manual_mult` - same as `manual`, but multiple items can be picked | -| "search_data" | optional | `search_data` | sets the condition for the target item; lack of search_data means any item can be picked; conditions can be:
`id` - id of a specific item;
`category` - category of an item (case sensitive, should always be in lower case);
`flags`- flag or flags the item has
`material` - material of an item;
`worn_only` - if true, return only items, that are worn;
`wielded_only` - if true, return only wielded items | +| "search_data" | optional | `search_data` | sets the condition for the target item; lack of search_data means any item can be picked; conditions can be:
`id` - id of a specific item;
`category` - category of an item (case sensitive, should always be in lower case);
`flags`- flag or flags the item has
`excluded_flags`- flag or flags the item doesn't have
`material` - material of an item;
`worn_only` - if true, return only items, that are worn;
`wielded_only` - if true, return only wielded items | | "title" | optional | string or [variable object](#variable-object) | name of the menu, that would be shown, if `manual` or `manual_mult` is used | | "true_eocs" / "false_eocs" | optional | string, [variable object](##variable-object), inline EoC, or range of all of them | if item was picked successfully, all EoCs from `true_eocs` are run, otherwise all EoCs from `false_eocs` are run; picked item is returned as npc; for example, `n_hp()` return hp of an item | diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 18ccb930ab882..81fd4789325b9 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -162,6 +162,7 @@ struct item_search_data { item_category_id category; material_id material; std::vector flags; + std::vector excluded_flags; bool worn_only; bool wielded_only; @@ -172,6 +173,9 @@ struct item_search_data { for( std::string flag : jo.get_string_array( "flags" ) ) { flags.emplace_back( flag ); } + for( std::string flag : jo.get_string_array( "excluded_flags" ) ) { + excluded_flags.emplace_back( flag ); + } worn_only = jo.get_bool( "worn_only", false ); wielded_only = jo.get_bool( "wielded_only", false ); } @@ -191,6 +195,11 @@ struct item_search_data { return false; } } + for( flag_id flag : excluded_flags ) { + if( loc->has_flag( flag ) ) { + return false; + } + } if( worn_only && !guy->is_worn( *loc ) ) { return false; } diff --git a/tests/eoc_test.cpp b/tests/eoc_test.cpp index 4d1fbce5bf30a..c1a9fbf8fae44 100644 --- a/tests/eoc_test.cpp +++ b/tests/eoc_test.cpp @@ -92,6 +92,7 @@ static const effect_on_condition_id effect_on_condition_EOC_run_inv_test1( "EOC_ static const effect_on_condition_id effect_on_condition_EOC_run_inv_test2( "EOC_run_inv_test2" ); static const effect_on_condition_id effect_on_condition_EOC_run_inv_test3( "EOC_run_inv_test3" ); static const effect_on_condition_id effect_on_condition_EOC_run_inv_test4( "EOC_run_inv_test4" ); +static const effect_on_condition_id effect_on_condition_EOC_run_inv_test5( "EOC_run_inv_test5" ); static const effect_on_condition_id effect_on_condition_EOC_run_until_test( "EOC_run_until_test" ); static const effect_on_condition_id effect_on_condition_EOC_run_with_test( "EOC_run_with_test" ); static const effect_on_condition_id @@ -972,6 +973,15 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) CHECK( items_after.size() == 1 ); + // Test search_data: excluded flags + CHECK( effect_on_condition_EOC_run_inv_test5->activate( d ) ); + + items_after = get_avatar().items_with( []( const item & it ) { + return it.get_var( "npctalk_var_general_run_inv_test_key5" ) == "yes"; + } ); + + CHECK( items_after.size() == 3 ); + // Flag test for item CHECK( effect_on_condition_EOC_item_flag_test->activate( d ) );