From 3df6f20292b1e8a4057ffab165be9c9adb6c6771 Mon Sep 17 00:00:00 2001 From: Valiant Date: Wed, 6 Nov 2024 12:25:06 +0400 Subject: [PATCH 01/19] Fleeing NPCs will now attack player that got too close --- src/npcmove.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 3b8fbf2f4e9a2..cb8feeacc33af 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1368,7 +1368,11 @@ void npc::move() action = method_of_fleeing(); } else if( ( target == &player_character && attitude == NPCATT_FLEE_TEMP ) || has_effect( effect_npc_run_away ) ) { - action = method_of_fleeing(); + if( rl_dist( pos(), player_character.pos() ) <= 1 ) { + action = method_of_attack(); + } else { + action = method_of_fleeing(); + } } else if( has_effect( effect_asthma ) && ( has_charges( itype_inhaler, 1 ) || has_charges( itype_oxygen_tank, 1 ) || has_charges( itype_smoxygen_tank, 1 ) ) ) { From a8701290ccb03f6a1c70570b771045cd75b1b88b Mon Sep 17 00:00:00 2001 From: Anton Burmistrov Date: Wed, 6 Nov 2024 16:28:19 +0400 Subject: [PATCH 02/19] Update src/npcmove.cpp Co-authored-by: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> --- src/npcmove.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index cb8feeacc33af..addc350205e16 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1368,7 +1368,7 @@ void npc::move() action = method_of_fleeing(); } else if( ( target == &player_character && attitude == NPCATT_FLEE_TEMP ) || has_effect( effect_npc_run_away ) ) { - if( rl_dist( pos(), player_character.pos() ) <= 1 ) { + if( target && rl_dist( pos(), target.pos() ) <= 1 ) { action = method_of_attack(); } else { action = method_of_fleeing(); From e4c825dffe1575568e70bfb821d8adeb80325681 Mon Sep 17 00:00:00 2001 From: Valiant Date: Wed, 6 Nov 2024 19:22:33 +0400 Subject: [PATCH 03/19] Update npcmove.cpp --- src/npcmove.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index addc350205e16..bb1b7fad5c549 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1368,7 +1368,7 @@ void npc::move() action = method_of_fleeing(); } else if( ( target == &player_character && attitude == NPCATT_FLEE_TEMP ) || has_effect( effect_npc_run_away ) ) { - if( target && rl_dist( pos(), target.pos() ) <= 1 ) { + if( target && rl_dist( pos(), target->pos() ) <= 1 ) { action = method_of_attack(); } else { action = method_of_fleeing(); From d44d34d5ce46b1b64b618e6714ea86dfe9bde6a8 Mon Sep 17 00:00:00 2001 From: Valiant Date: Thu, 7 Nov 2024 09:54:25 +0400 Subject: [PATCH 04/19] NPC will fight back when fleeing only when they have more than 30% health Also NPCs will change their attitude to `NPCATT_FLEE_TEMP ` when they decide to flee during danger assessment --- src/npcmove.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index bb1b7fad5c549..b781234b6f513 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1144,6 +1144,7 @@ void npc::act_on_danger_assessment() add_msg_debug( debugmode::DF_NPC_COMBATAI, "%s upgrades reposition to flat out retreat.", name ); mem_combat.repositioning = false; // we're not just moving, we're running. warn_about( "run_away", run_away_for ); + set_attitude( NPCATT_FLEE_TEMP ); if( mem_combat.panic > 5 && is_player_ally() && sees( player_character.pos_bub() ) ) { // consider warning player about panic int panic_alert = rl_dist( pos(), player_character.pos() ) - player_character.get_per(); @@ -1368,7 +1369,7 @@ void npc::move() action = method_of_fleeing(); } else if( ( target == &player_character && attitude == NPCATT_FLEE_TEMP ) || has_effect( effect_npc_run_away ) ) { - if( target && rl_dist( pos(), target->pos() ) <= 1 ) { + if( hp_percentage() > 30 && target && rl_dist( pos(), target->pos() ) <= 1 ) { action = method_of_attack(); } else { action = method_of_fleeing(); From 6c6ed40f8c37b569fcde0ed7abe79ab8a67de33a Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:41:10 +0000 Subject: [PATCH 05/19] Fix #77877 --- .../npcs/refugee_center/surface_refugees/NPC_Pablo_Nunez.json | 2 +- data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json | 2 +- data/json/obsoletion_and_migration_0.I/obsolete_eoc.json | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/data/json/npcs/refugee_center/surface_refugees/NPC_Pablo_Nunez.json b/data/json/npcs/refugee_center/surface_refugees/NPC_Pablo_Nunez.json index 9610134b839de..d3b677df092fe 100644 --- a/data/json/npcs/refugee_center/surface_refugees/NPC_Pablo_Nunez.json +++ b/data/json/npcs/refugee_center/surface_refugees/NPC_Pablo_Nunez.json @@ -244,7 +244,7 @@ { "npc_location_variable": { "context_val": "refcenter_nunez_departure" } }, { "math": [ "_travel_time", "=", "time_since('cataclysm', 'unit': 'days') + 2" ] }, { - "run_eocs": [ "EOC_Nunez_Travel" ], + "run_eocs": [ "EOC_Nunez_Travel_To_Tacoma" ], "time_in_future": { "context_val": "travel_time" }, "variables": { "refcenter_nunez_departure": { "context_val": "refcenter_nunez_departure" }, diff --git a/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json b/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json index 2556fcd19b610..b4fbf2ef6ba6d 100644 --- a/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json +++ b/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json @@ -1,6 +1,6 @@ [ { - "id": "EOC_Nunez_Travel", + "id": "EOC_Nunez_Travel_To_Tacoma", "type": "effect_on_condition", "effect": [ { "math": [ "u_counter_refugee_center_refugee_happiness", "++" ] }, diff --git a/data/json/obsoletion_and_migration_0.I/obsolete_eoc.json b/data/json/obsoletion_and_migration_0.I/obsolete_eoc.json index d485c374d40b5..aa75891a68cd0 100644 --- a/data/json/obsoletion_and_migration_0.I/obsolete_eoc.json +++ b/data/json/obsoletion_and_migration_0.I/obsolete_eoc.json @@ -30,5 +30,9 @@ { "type": "effect_on_condition", "id": "eoc_conjunctivitis_itch" + }, + { + "id": "EOC_Nunez_Travel", + "type": "effect_on_condition" } ] From fab5c03fde347e69ca9a90fc861a53b0246a1274 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Fri, 15 Nov 2024 11:29:29 +0000 Subject: [PATCH 06/19] Add roof, fix rotation, fix spawning in fence --- .../special_use/bullet_trailer.json | 7 ++++ .../npcs/tacoma_ranch/Nunez/Arrival_code.json | 39 ++++++++++++++----- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/data/json/furniture_and_terrain/special_use/bullet_trailer.json b/data/json/furniture_and_terrain/special_use/bullet_trailer.json index d3e993b2a6a39..2d825fe9db819 100644 --- a/data/json/furniture_and_terrain/special_use/bullet_trailer.json +++ b/data/json/furniture_and_terrain/special_use/bullet_trailer.json @@ -10,6 +10,13 @@ "color": "brown", "copy-from": "t_linoleum_gray" }, + { + "type": "terrain", + "id": "t_bullettrailer_roof", + "name": "bullet trailer roof", + "description": "A smooth roof of gleaming chrome, slightly dusty from the road.", + "copy-from": "t_metal_flat_roof" + }, { "type": "terrain", "id": "t_bullettrailer_nwall_westcorner", diff --git a/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json b/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json index b4fbf2ef6ba6d..ec07e9e4ef03f 100644 --- a/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json +++ b/data/json/npcs/tacoma_ranch/Nunez/Arrival_code.json @@ -30,14 +30,7 @@ "update_mapgen_id": "tacoma_nunez_trailer_arrive", "method": "json", "//": "In addition to basic mapgen, adds some point variables in the hopes that I can add some passive movement animations for pablo and dana.", - "object": { - "place_nested": [ { "chunks": [ "nunez_trailer" ], "x": 0, "y": 17 } ], - "place_npcs": [ { "class": "tacoma_DanaNunez", "x": 4, "y": 19 }, { "class": "tacoma_PabloNunez", "x": 4, "y": 20 } ], - "set": [ - { "point": "variable", "id": "Pablo_relax", "x": 4, "y": 20 }, - { "point": "variable", "id": "Dana_baking", "x": 4, "y": 19 } - ] - } + "object": { "flags": [ "NO_UNDERLYING_ROTATE" ], "place_nested": [ { "chunks": [ "nunez_trailer" ], "x": 5, "y": 15 } ] } }, { "type": "mapgen", @@ -45,8 +38,9 @@ "nested_mapgen_id": "nunez_trailer", "//": "Nunez bakery inside a silver bullet trailer.", "object": { - "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN", "NO_UNDERLYING_ROTATE" ], + "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], "mapgensize": [ 6, 6 ], + "rotation": [ 0 ], "rows": [ "ABCDE ", "123456", @@ -99,7 +93,32 @@ "c": "f_bullettrailer_bed_head", "d": "f_bullettrailer_toilet", "i": "f_bullettrailer_sign_danabakery" - } + }, + "place_npcs": [ { "class": "tacoma_DanaNunez", "x": 4, "y": 2 }, { "class": "tacoma_PabloNunez", "x": 4, "y": 3 } ], + "set": [ + { "point": "variable", "id": "Pablo_relax", "x": 4, "y": 3 }, + { "point": "variable", "id": "Dana_baking", "x": 4, "y": 2 } + ], + "place_nested": [ { "chunks": [ "nunez_trailer_roof" ], "x": 0, "y": 0, "z": 1 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "nunez_trailer_roof", + "object": { + "flags": [ "ERASE_ALL_BEFORE_PLACING_TERRAIN" ], + "mapgensize": [ 6, 6 ], + "rotation": [ 0 ], + "rows": [ + " ", + "......", + "......", + "......", + "......", + " " + ], + "terrain": { ".": "t_bullettrailer_roof" } } } ] From afa36ef4750dcc92e310b487c761676177c92771 Mon Sep 17 00:00:00 2001 From: NetSysFire <59517351+NetSysFire@users.noreply.github.com> Date: Sat, 16 Nov 2024 17:58:01 +0100 Subject: [PATCH 07/19] remove buckwheat from foraging, add to seed group --- .../itemgroups/Agriculture_Forage_Excavation/agriculture.json | 1 + data/json/itemgroups/Agriculture_Forage_Excavation/forage.json | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json b/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json index 13eaa977af0de..7bb739d606b28 100644 --- a/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json +++ b/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json @@ -9,6 +9,7 @@ [ "seed_cranberries", 60 ], [ "seed_raspberries", 60 ], [ "seed_wheat", 60 ], + [ "seed_buckwheat", 10 ], [ "seed_barley", 60 ], [ "seed_sugar_beet", 60 ], [ "seed_lettuce", 60 ], diff --git a/data/json/itemgroups/Agriculture_Forage_Excavation/forage.json b/data/json/itemgroups/Agriculture_Forage_Excavation/forage.json index d8c7d099551f6..24b699394f93c 100644 --- a/data/json/itemgroups/Agriculture_Forage_Excavation/forage.json +++ b/data/json/itemgroups/Agriculture_Forage_Excavation/forage.json @@ -36,7 +36,6 @@ { "group": "egg_reptile_forest", "prob": 5, "count": [ 2, 5 ] }, { "item": "snail_garden", "prob": 10, "count": [ 1, 3 ] }, { "item": "wild_herbs", "prob": 20, "count": 20 }, - { "item": "buckwheat", "prob": 5, "count": [ 2, 8 ] }, { "item": "thyme", "prob": 5, "count": [ 1, 3 ] }, { "item": "garlic", "prob": 1 }, { "item": "seed_garlic", "prob": 4, "count": [ 1, 6 ] }, @@ -57,7 +56,6 @@ { "item": "groundnut", "prob": 2, "count": [ 1, 9 ] }, { "group": "forage_mushroom", "prob": 50 }, { "item": "wild_herbs", "prob": 10, "count": 20 }, - { "item": "buckwheat", "prob": 15, "count": [ 4, 8 ] }, { "item": "thyme", "prob": 5, "count": [ 1, 3 ] }, { "item": "garlic", "prob": 1 }, { "item": "snail_garden", "prob": 10, "count": [ 1, 3 ] }, From b3869062ffcaa44800b310041b90e424716f18a2 Mon Sep 17 00:00:00 2001 From: GuardianDll Date: Sat, 16 Nov 2024 20:09:00 +0100 Subject: [PATCH 08/19] obsolete OM_MOVE --- .../npc_eocs/isherwood_barry_rescue_eocs.json | 3 ++- doc/EFFECT_ON_CONDITION.md | 3 +-- src/effect_on_condition.cpp | 12 ------------ src/effect_on_condition.h | 3 --- src/game.cpp | 1 - 5 files changed, 3 insertions(+), 19 deletions(-) diff --git a/data/json/effects_on_condition/npc_eocs/isherwood_barry_rescue_eocs.json b/data/json/effects_on_condition/npc_eocs/isherwood_barry_rescue_eocs.json index 63dd374a69c87..01be976467685 100644 --- a/data/json/effects_on_condition/npc_eocs/isherwood_barry_rescue_eocs.json +++ b/data/json/effects_on_condition/npc_eocs/isherwood_barry_rescue_eocs.json @@ -475,7 +475,8 @@ }, { "type": "effect_on_condition", - "eoc_type": "OM_MOVE", + "eoc_type": "EVENT", + "required_event": "avatar_enters_omt", "id": "EOC_HAVE_U_BEEN_TO_MIGOS", "condition": { "or": [ diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md index effe943855299..9aebac18582fa 100644 --- a/doc/EFFECT_ON_CONDITION.md +++ b/doc/EFFECT_ON_CONDITION.md @@ -38,7 +38,7 @@ An effect_on_condition is an object allowing the combination of dialog condition | `false_effect` | effect | The effect(s) caused if `condition` returns false upon activation. See the "Dialogue Effects" section of [NPCs](NPCs.md) for the full syntax. | `global` | bool | If this is true, this recurring eoc will be run on the player and every npc from a global queue. Deactivate conditions will work based on the avatar. If it is false the avatar and every character will have their own copy and their own deactivated list. Defaults to false. | `run_for_npcs` | bool | Can only be true if global is true. If false the EOC will only be run against the avatar. If true the eoc will be run against the avatar and all npcs. Defaults to false. -| `EOC_TYPE` | string | Can be one of `ACTIVATION`, `RECURRING`, `SCENARIO_SPECIFIC`, `AVATAR_DEATH`, `NPC_DEATH`, `OM_MOVE`, `PREVENT_DEATH`, `EVENT` (see details below). It defaults to `ACTIVATION` unless `recurrence` is provided in which case it defaults to `RECURRING`. +| `EOC_TYPE` | string | Can be one of `ACTIVATION`, `RECURRING`, `SCENARIO_SPECIFIC`, `AVATAR_DEATH`, `NPC_DEATH`, `PREVENT_DEATH`, `EVENT` (see details below). It defaults to `ACTIVATION` unless `recurrence` is provided in which case it defaults to `RECURRING`. ### EOC types @@ -49,7 +49,6 @@ An effect_on_condition is an object allowing the combination of dialog condition * `SCENARIO_SPECIFIC` - automatically invoked once on scenario start. * `AVATAR_DEATH` - automatically invoked whenever the current avatar dies (it will be run with the avatar as `u`), if after it the player is no longer dead they will not die, if there are multiple EOCs they all be run until the player is not dead. * `NPC_DEATH` - EOCs can only be assigned to run on the death of an npc, in which case u will be the dying npc and npc will be the killer. If after it npc is no longer dead they will not die, if there are multiple they all be run until npc is not dead. -* `OM_MOVE` - EOCs trigger when the player moves overmap tiles * `PREVENT_DEATH` - whenever the current avatar dies it will be run with the avatar as `u`, if after it the player is no longer dead they will not die, if there are multiple they all be run until the player is not dead. * `EVENT` - EOCs trigger when a specific event given by "required_event" takes place. diff --git a/src/effect_on_condition.cpp b/src/effect_on_condition.cpp index 0084c75df6171..e0b13687b9bd2 100644 --- a/src/effect_on_condition.cpp +++ b/src/effect_on_condition.cpp @@ -42,7 +42,6 @@ namespace io case eoc_type::SCENARIO_SPECIFIC: return "SCENARIO_SPECIFIC"; case eoc_type::AVATAR_DEATH: return "AVATAR_DEATH"; case eoc_type::NPC_DEATH: return "NPC_DEATH"; - case eoc_type::OM_MOVE: return "OM_MOVE"; case eoc_type::PREVENT_DEATH: return "PREVENT_DEATH"; case eoc_type::EVENT: return "EVENT"; case eoc_type::NUM_EOC_TYPES: break; @@ -467,17 +466,6 @@ void effect_on_conditions::avatar_death() } } -void effect_on_conditions::om_move() -{ - avatar &player_character = get_avatar(); - dialogue d( get_talker_for( player_character ), nullptr ); - for( const effect_on_condition &eoc : effect_on_conditions::get_all() ) { - if( eoc.type == eoc_type::OM_MOVE ) { - eoc.activate( d ); - } - } -} - void effect_on_condition::finalize() { } diff --git a/src/effect_on_condition.h b/src/effect_on_condition.h index 0ac5b68bc268f..c3b974928e45f 100644 --- a/src/effect_on_condition.h +++ b/src/effect_on_condition.h @@ -32,7 +32,6 @@ enum eoc_type { SCENARIO_SPECIFIC, AVATAR_DEATH, NPC_DEATH, - OM_MOVE, PREVENT_DEATH, EVENT, NUM_EOC_TYPES @@ -114,8 +113,6 @@ void write_global_eocs_to_file(); void prevent_death(); /** Run all avatar death eocs */ void avatar_death(); -/** Run all OM_MOVE eocs */ -void om_move(); } // namespace effect_on_conditions template<> diff --git a/src/game.cpp b/src/game.cpp index 281f50c59a667..813cfcf0ddba0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -13927,7 +13927,6 @@ void avatar_moves( const tripoint &old_abs_pos, const avatar &u, const map &m ) const oter_id &past_ter = overmap_buffer.ter( old_abs_omt ); get_event_bus().send( new_abs_omt.raw(), cur_ter ); // if the player has moved omt then might trigger an EOC for that OMT - effect_on_conditions::om_move(); if( !past_ter->get_exit_EOC().is_null() ) { dialogue d( get_talker_for( get_avatar() ), nullptr ); effect_on_condition_id eoc = cur_ter->get_exit_EOC(); From 4bf86416a5c3e1b4880d3dc4f1ec3d02d944b907 Mon Sep 17 00:00:00 2001 From: TheMurderUnicorn Date: Sat, 16 Nov 2024 18:42:25 -0500 Subject: [PATCH 09/19] Adjust breaks_into for appliance car battery --- data/json/furniture_and_terrain/appliances.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/data/json/furniture_and_terrain/appliances.json b/data/json/furniture_and_terrain/appliances.json index 8a06c528ad5e6..f8d2bf3674ebb 100644 --- a/data/json/furniture_and_terrain/appliances.json +++ b/data/json/furniture_and_terrain/appliances.json @@ -818,9 +818,11 @@ "description": "A car battery wired into a static power grid.", "item": "battery_car", "breaks_into": [ - { "item": "steel_lump", "count": [ 6, 9 ] }, - { "item": "steel_chunk", "count": [ 6, 9 ] }, - { "item": "scrap", "count": [ 6, 9 ] } + { "item": "lead", "charges": [ 1680, 2380 ] }, + { "item": "chem_sulphuric_acid", "count": [ 5, 8 ], "container-item": "null" }, + { "item": "plastic_chunk", "count": [ 14, 20 ] }, + { "item": "scrap", "charges": [ 2, 3 ] }, + { "item": "shredded_rubber", "charges": [ 10, 14 ] } ], "durability": 120, "requirements": { "removal": { "time": "6 m" } }, From 2a80ab553b97e9e6358f9ce44a08ea96df0ae7c5 Mon Sep 17 00:00:00 2001 From: TheMurderUnicorn Date: Sat, 16 Nov 2024 18:44:07 -0500 Subject: [PATCH 10/19] Audit Lead Acid Battery Vehicle Part breaks_into --- data/json/vehicleparts/battery.json | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/data/json/vehicleparts/battery.json b/data/json/vehicleparts/battery.json index 6e11ae137aa02..366baf6b9dc73 100644 --- a/data/json/vehicleparts/battery.json +++ b/data/json/vehicleparts/battery.json @@ -12,9 +12,11 @@ "description": "A battery for storing electrical power, and discharging it to power electrical devices built into the vehicle.", "folded_volume": "10 L", "breaks_into": [ - { "item": "steel_lump", "count": [ 6, 9 ] }, - { "item": "steel_chunk", "count": [ 6, 9 ] }, - { "item": "scrap", "count": [ 6, 9 ] } + { "item": "lead", "charges": [ 1680, 2380 ] }, + { "item": "chem_sulphuric_acid", "count": [ 5, 8 ], "container-item": "null" }, + { "item": "plastic_chunk", "count": [ 14, 20 ] }, + { "item": "scrap", "charges": [ 2, 3 ] }, + { "item": "shredded_rubber", "charges": [ 10, 14 ] } ], "requirements": { "install": { "skills": [ [ "mechanics", 0 ] ], "time": "50 s", "qualities": [ { "id": "WRENCH", "level": 1 } ] }, @@ -34,9 +36,11 @@ "durability": 100, "folded_volume": "1500 ml", "breaks_into": [ - { "item": "steel_lump", "count": [ 4, 7 ] }, - { "item": "steel_chunk", "count": [ 4, 7 ] }, - { "item": "scrap", "count": [ 4, 7 ] } + { "item": "lead", "charges": [ 252, 357 ] }, + { "item": "chem_sulphuric_acid", "count": [ 0, 1 ], "container-item": "null" }, + { "item": "plastic_chunk", "count": [ 2, 3 ] }, + { "item": "scrap", "charges": [ 0, 1 ] }, + { "item": "shredded_rubber", "charges": [ 1, 2 ] } ] }, { @@ -48,9 +52,11 @@ "durability": 30, "folded_volume": "750 ml", "breaks_into": [ - { "item": "steel_lump", "count": [ 4, 7 ] }, - { "item": "steel_chunk", "count": [ 4, 7 ] }, - { "item": "scrap", "count": [ 4, 7 ] } + { "item": "lead", "charges": [ 126, 178 ] }, + { "item": "chem_sulphuric_acid", "count": [ 0, 1 ], "container-item": "null" }, + { "item": "plastic_chunk" }, + { "item": "scrap", "charges": [ 0, 1 ] }, + { "item": "shredded_rubber", "charges": [ 0, 1 ] } ] }, { From e527d811f297da43ab6d5655dbfaadd7b5e0a6a9 Mon Sep 17 00:00:00 2001 From: ShnitzelX2 <65314588+ShnitzelX2@users.noreply.github.com> Date: Sat, 16 Nov 2024 18:54:48 -0500 Subject: [PATCH 11/19] remove debug message causing basic build failure unintended magiclysm conflicts cause it to trigger rarely --- src/newcharacter.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index 9a6d0b54601ee..b7096b249cdb9 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -668,22 +668,21 @@ void Character::add_profession_items() //storage items may not be added first, so a second attempt is needed attempt_add_items( prof_items, try_adding_again ); - prof_items.clear(); - attempt_add_items( try_adding_again, prof_items ); - //if there's one item left that still can't be added, attempt to wield it - if( prof_items.size() == 1 ) { - item last_item = prof_items.front(); - if( !has_wield_conflicts( last_item ) ) { - bool success_wield = wield( last_item ); - if( success_wield ) { - prof_items.pop_front(); + if( !try_adding_again.empty() ) { + prof_items.clear(); + attempt_add_items( try_adding_again, prof_items ); + //if there's one item left that still can't be added, attempt to wield it + if( prof_items.size() == 1 ) { + item last_item = prof_items.front(); + if( !has_wield_conflicts( last_item ) ) { + bool success_wield = wield( last_item ); + if( success_wield ) { + prof_items.pop_front(); + } } } } - if( !prof_items.empty() ) { - debugmsg( "Failed to place %d items in inventory for profession %s", prof_items.size(), - prof->gender_appropriate_name( male ) ); - } + recalc_sight_limits(); calc_encumbrance(); } From 3eca45dfcaba6c402f8e672fc4c5aef6e6570782 Mon Sep 17 00:00:00 2001 From: John-Candlebury Date: Sat, 16 Nov 2024 19:44:14 -0600 Subject: [PATCH 12/19] Disable portal storms in exoplanet --- data/mods/aftershock_exoplanet/game_balance.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/data/mods/aftershock_exoplanet/game_balance.json b/data/mods/aftershock_exoplanet/game_balance.json index f36efb1980153..5e8f109bcfe17 100644 --- a/data/mods/aftershock_exoplanet/game_balance.json +++ b/data/mods/aftershock_exoplanet/game_balance.json @@ -1,4 +1,11 @@ [ + { + "type": "effect_on_condition", + "id": "EOC_PORTAL_STORM_WARN_OR_CAUSE_RECURRING", + "recurrence": [ "10 days", "11 days" ], + "global": true, + "effect": [ ] + }, { "type": "EXTERNAL_OPTION", "name": "GENERIC_PROFESSION_ID", From b42412f631cb53ae0a99dbf1c80d37c77c3a9c67 Mon Sep 17 00:00:00 2001 From: Alex Mooney Date: Sat, 16 Nov 2024 17:21:41 -0800 Subject: [PATCH 13/19] Allow safecracking prof to identify safe mechanisms With the proficiency you know which way to turn the dial, but you're still hopelessly outclassed by someone with safe cracking gear. --- src/iexamine.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index bad7956ffb291..36406d5eea4ce 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -221,6 +221,7 @@ static const npc_class_id NC_ROBOFAC_INTERCOM( "NC_ROBOFAC_INTERCOM" ); static const proficiency_id proficiency_prof_disarming( "prof_disarming" ); static const proficiency_id proficiency_prof_parkour( "prof_parkour" ); +static const proficiency_id proficiency_prof_safecracking( "prof_safecracking" ); static const proficiency_id proficiency_prof_traps( "prof_traps" ); static const proficiency_id proficiency_prof_trapsetting( "prof_trapsetting" ); @@ -1805,15 +1806,28 @@ void iexamine::safe( Character &you, const tripoint_bub_ms &examp ) // The dialing procedures for safes vary, I'm estimating 5 procedures. // See https://hoogerhydesafe.com/resources/combination-lock-dialing-procedures/ // At the end of the day, that means a 1 / 80,000 chance per attempt. - // If someone is interested, they can feel free to add a proficiency for - // "safe recognition" to mitigate or eliminate this 2x and 5x factor. - if( one_in( 80000 ) ) { - you.add_msg_if_player( m_good, _( "You mess with the dial for a little bit… and it opens!" ) ); - get_map().furn_set( examp, furn_f_safe_o ); - return; + // If the player has the safecracking proficiency, they know the procedure. + + // With the proficiency, there's a 50% chance to open after 15.4 hours of attempts. + // Without the proficiency, there's a 50% chance to open after 154 hours of attempts. + if( you.has_proficiency( proficiency_prof_safecracking ) ) { + if( one_in( 8000 ) ) { + you.add_msg_if_player( m_good, _( "You carefully dial a combination… and it opens!" ) ); + get_map().furn_set( examp, furn_f_safe_o ); + return; + } else { + you.add_msg_if_player( m_info, _( "You carefully dial a combination." ) ); + return; + } } else { - you.add_msg_if_player( m_info, _( "You mess with the dial for a little bit." ) ); - return; + if( one_in( 80000 ) ) { + you.add_msg_if_player( m_good, _( "You mess with the dial for a little bit… and it opens!" ) ); + get_map().furn_set( examp, furn_f_safe_o ); + return; + } else { + you.add_msg_if_player( m_info, _( "You mess with the dial for a little bit." ) ); + return; + } } } From d9ded524bdf7c72112e01bc42d89e81035e16d22 Mon Sep 17 00:00:00 2001 From: SariusSkelrets Date: Sat, 16 Nov 2024 21:49:50 -0500 Subject: [PATCH 14/19] Fix demonic possession causing starvation penalties --- .../Spells/attunements/Blood_Mage.json | 77 ++++++++++++++++++- .../traits/temporary_demon_traits.json | 27 +++++++ 2 files changed, 100 insertions(+), 4 deletions(-) diff --git a/data/mods/Magiclysm/Spells/attunements/Blood_Mage.json b/data/mods/Magiclysm/Spells/attunements/Blood_Mage.json index 496a219dcfaac..5e5a92130b405 100644 --- a/data/mods/Magiclysm/Spells/attunements/Blood_Mage.json +++ b/data/mods/Magiclysm/Spells/attunements/Blood_Mage.json @@ -46,7 +46,7 @@ "DEMON_CLAWS", "DEMON_SKIN", "DEMON_TAIL", - "HUGE_OK", + "DEMON_HUGE", "NOPAIN", "FACIAL_HAIR_GOATEE" ] @@ -59,12 +59,12 @@ "type": "SPELL", "name": "Demonic Possession", "description": "You allow a demon to possess your body for a short time, giving you great combat abilities. You still retain control, though lose your spellcasting abilities temporarily.", - "valid_targets": [ "none" ], + "valid_targets": [ "self" ], "flags": [ "CONJURATION_SPELL", "SOMATIC", "NO_LEGS", "MUST_HAVE_CLASS_TO_LEARN" ], "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], - "effect": "spawn_item", + "effect": "effect_on_condition", "shape": "blast", - "effect_str": "demon_possession_aura", + "effect_str": "EOC_DEMON_POSSESSION", "min_damage": 1, "max_damage": 1, "min_duration": 360000, @@ -76,5 +76,74 @@ "base_casting_time": 800, "base_energy_cost": 5, "energy_source": "HP" + }, + { + "type": "effect_on_condition", + "id": "EOC_DEMON_POSSESSION", + "condition": { "and": [ { "not": { "u_has_trait": "HUGE" } }, { "not": { "u_has_trait": "HUGE_OK" } } ] }, + "effect": [ + { "u_message": "Your body swells and warps as your size increases!", "type": "good" }, + { "math": [ "u_preshift_size", "=", "u_val('size')" ] }, + { + "switch": { "math": [ "u_preshift_size" ] }, + "cases": [ + { "case": 1, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "*=", "12" ] } ] }, + { "case": 2, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "*=", "6" ] } ] }, + { "case": 3, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "*=", "2" ] } ] }, + { "case": 4, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "*=", "1.5" ] } ] }, + { "case": 5, "effect": [ ] } + ] + }, + { "u_cast_spell": { "id": "demonic_possession_real" } }, + { + "run_eocs": "EOC_DEMON_POSSESSION_REMOVE", + "time_in_future": { "math": [ "(u_spell_level('demonic_possession') * 309) + 3600" ] } + } + ], + "false_effect": [ + { "u_message": "Your body fills with demonic power!", "type": "good" }, + { "u_cast_spell": { "id": "demonic_possession_real" } }, + { + "run_eocs": "EOC_DEMON_POSSESSION_REMOVE", + "time_in_future": { "math": [ "(u_spell_level('demonic_possession') * 309) + 3600" ] } + } + ] + }, + { + "type": "effect_on_condition", + "id": "EOC_DEMON_POSSESSION_REMOVE", + "effect": [ + { "u_message": "Your body shrinks and warps as your size decreases!", "type": "bad" }, + { + "switch": { "math": [ "u_preshift_size" ] }, + "cases": [ + { "case": 1, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "/=", "12" ] } ] }, + { "case": 2, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "/=", "6" ] } ] }, + { "case": 3, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "/=", "2" ] } ] }, + { "case": 4, "effect": [ { "math": [ "u_calories('dont_affect_weariness': true)", "/=", "1.5" ] } ] }, + { "case": 5, "effect": [ ] } + ] + } + ] + }, + { + "id": "demonic_possession_real", + "type": "SPELL", + "name": "Demonic Possession Real", + "description": "Grants the aura that gives the demon traits. You're not supposed to see this.", + "valid_targets": [ "self" ], + "flags": [ "CONJURATION_SPELL", "SOMATIC", "NO_LEGS", "MUST_HAVE_CLASS_TO_LEARN", "SILENT", "NO_EXPLOSION_SFX" ], + "extra_effects": [ { "id": "eoc_summon_setup", "hit_self": true } ], + "effect": "spawn_item", + "shape": "blast", + "effect_str": "demon_possession_aura", + "min_damage": 1, + "max_damage": 1, + "min_duration": { "math": [ "(u_spell_level('demonic_possession') * 30900) + 360000" ] }, + "max_duration": { "math": [ "(u_spell_level('demonic_possession') * 30900) + 360000" ] }, + "spell_class": "BLOOD_MAGE", + "difficulty": 5, + "max_level": 35, + "base_casting_time": 0 } ] diff --git a/data/mods/Magiclysm/traits/temporary_demon_traits.json b/data/mods/Magiclysm/traits/temporary_demon_traits.json index 16561b3d3f73f..1734a4af29f2f 100644 --- a/data/mods/Magiclysm/traits/temporary_demon_traits.json +++ b/data/mods/Magiclysm/traits/temporary_demon_traits.json @@ -62,6 +62,33 @@ ], "flags": [ "NO_SPELLCASTING" ] }, + { + "type": "mutation", + "id": "DEMON_HUGE", + "//": "Identical to HUGE_OK but uses the flag for temporary sizeshifting.", + "//2": "I am not using the biomancer version, as it has more bonuses than HUGE_OK and I want to keep the spell's balance identical while fixing the bug.", + "flags": [ "TEMPORARY_SHAPESHIFT", "SHAPESHIFT_SIZE_HUGE" ], + "name": { "str": "Huge" }, + "points": 2, + "visibility": 4, + "ugliness": 3, + "valid": false, + "starting_trait": false, + "mixed_effect": true, + "description": "Your cardiovascular system has caught up with your muscular physique, so who needs pathetic human cars? Strength +4.", + "types": [ "SIZE" ], + "enchantments": [ + { + "values": [ + { "value": "STRENGTH", "add": 4 }, + { "value": "STOMACH_SIZE_MULTIPLIER", "multiply": 1 }, + { "value": "CARRY_WEIGHT", "multiply": 0.1 } + ] + } + ], + "restricts_gear": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r" ], + "destroys_gear": true + }, { "type": "mutation", "id": "DEMON_CLAWS", From eb8aae467cbff111de10e0b16a074c45575eac36 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sun, 17 Nov 2024 04:57:32 +0000 Subject: [PATCH 15/19] u_/npc_forget_recipe can use categories and subcategories in place of individual ids (#77705) * Allow f_forget_recipe to work with recipe categories/subcategories * u_/npc_forget_recipe can use categories and subcategories in place of individual ids * Documentation * Sort by category and remove weapons * Update give_a_class_eoc.json * Update npctalk.cpp --- .../Xedra_Evolved/eocs/give_a_class_eoc.json | 132 +++--------------- doc/EFFECT_ON_CONDITION.md | 14 +- src/crafting_gui.cpp | 6 +- src/crafting_gui.h | 3 + src/npctalk.cpp | 30 +++- 5 files changed, 60 insertions(+), 125 deletions(-) diff --git a/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json b/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json index f6f6b0e5ee7a7..f56897b1065a1 100644 --- a/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json +++ b/data/mods/Xedra_Evolved/eocs/give_a_class_eoc.json @@ -192,71 +192,34 @@ { "u_lose_trait": "EATER" }, { "u_lose_trait": "INVENTOR" }, { "u_mutate_towards": "DREAMLESS", "category": "ANY", "use_vitamins": false }, - { "u_forget_recipe": "inventor_leg_weight" }, - { "u_forget_recipe": "inventor_jump_boots" }, - { "u_forget_recipe": "inventor_sniper" }, - { "u_forget_recipe": "inventor_shotgun" }, - { "u_forget_recipe": "inventor_pistol" }, - { "u_forget_recipe": "megachette" }, - { "u_forget_recipe": "software_math_inventor" }, - { "u_forget_recipe": "software_electronics_reference_inventor" }, - { "u_forget_recipe": "combatsaw_spear_off" }, + { "u_forget_recipe": "CC_XEDRA", "subcategory": "CSC_XEDRA_ARMOR" }, + { "u_forget_recipe": "inventor_research_energy_1", "//": "CSC_XEDRA_RESEARCH start" }, + { "u_forget_recipe": "inventor_research_energy_2" }, + { "u_forget_recipe": "inventor_research_energy_3" }, { "u_forget_recipe": "inventor_research_base_2" }, - { "u_forget_recipe": "helmet_inventor" }, - { "u_forget_recipe": "inventor_fists" }, - { "u_forget_recipe": "wolf_mask" }, - { "u_forget_recipe": "magnetic_holster" }, - { "u_forget_recipe": "binary_sword" }, - { "u_forget_recipe": "bio_launcher" }, - { "u_forget_recipe": "bio_warhead" }, - { "u_forget_recipe": "trinket_damage" }, + { "u_forget_recipe": "inventor_research_base_3" }, + { "u_forget_recipe": "inventor_research_ai_1" }, + { "u_forget_recipe": "inventor_research_dimension_1" }, + { "u_forget_recipe": "dreamsmith_research" }, + { "u_forget_recipe": "CC_XEDRA", "subcategory": "CSC_XEDRA_ROBOTS" }, + { "u_forget_recipe": "CC_XEDRA", "subcategory": "CSC_XEDRA_TOOLS" }, + { "u_forget_recipe": "CC_XEDRA", "subcategory": "CSC_XEDRA_WEAPONS" }, + { "u_forget_recipe": "trinket_damage", "//": "CSC_XEDRA_MISC start" }, { "u_forget_recipe": "trinket_range" }, { "u_forget_recipe": "trinket_sound" }, { "u_forget_recipe": "choke_wideshot" }, { "u_forget_recipe": "mod_inv_pistol_booster" }, - { "u_forget_recipe": "inventor_research_base_3" }, - { "u_forget_recipe": "inventor_research_energy_1" }, - { "u_forget_recipe": "software_AI" }, { "u_forget_recipe": "stunning_qr_trap" }, - { "u_forget_recipe": "inventor_backpack" }, - { "u_forget_recipe": "vision_halo" }, - { "u_forget_recipe": "sonic_gun" }, - { "u_forget_recipe": "mace_magic" }, { "u_forget_recipe": "stunning_arg_trap" }, - { "u_forget_recipe": "inventor_fists_plus" }, - { "u_forget_recipe": "inventor_plasma_axe_off" }, - { "u_forget_recipe": "inventor_research_energy_1" }, - { "u_forget_recipe": "battery_gun" }, - { "u_forget_recipe": "ray_gun" }, { "u_forget_recipe": "inventor_light_minus_cell" }, { "u_forget_recipe": "inventor_light_cell" }, { "u_forget_recipe": "inventor_medium_cell" }, { "u_forget_recipe": "inventor_heavy_cell" }, - { "u_forget_recipe": "inventor_welder" }, - { "u_forget_recipe": "heater_tool" }, - { "u_forget_recipe": "inventor_electric_fist" }, - { "u_forget_recipe": "inventor_research_energy_2" }, - { "u_forget_recipe": "inventor_glauncher" }, - { "u_forget_recipe": "inventor_glauncher_fire" }, - { "u_forget_recipe": "inventor_glauncher_elec" }, - { "u_forget_recipe": "inventor_glauncher_direct" }, - { "u_forget_recipe": "death_ray" }, { "u_forget_recipe": "inventor_lasmod_mega_capasitor" }, { "u_forget_recipe": "inventor_lasmod_adv_adv_cooler" }, { "u_forget_recipe": "inventor_lasmod_recuperator" }, { "u_forget_recipe": "inventor_lasmod_mega_everything" }, { "u_forget_recipe": "inventor_lasmod_more_capacitors" }, - { "u_forget_recipe": "inventor_research_ai_1" }, - { "u_forget_recipe": "inventor_research_dimension_1" }, - { "u_forget_recipe": "nre_recorder_inventor" }, - { "u_forget_recipe": "aura_force" }, - { "u_forget_recipe": "ray_rifle" }, - { "u_forget_recipe": "ion_gun" }, - { "u_forget_recipe": "accelerator_gun" }, - { "u_forget_recipe": "inventor_grenade_noise_expl" }, - { "u_forget_recipe": "inventor_grenade_noise_emp" }, - { "u_forget_recipe": "inventor_grenade_noise_fire" }, - { "u_forget_recipe": "heater_gun" }, { "u_forget_recipe": "inventor_lasmod_close_range" }, { "u_forget_recipe": "inventor_lasmod_long_range" }, { "u_forget_recipe": "inventor_lasmod_capasitor" }, @@ -265,76 +228,13 @@ { "u_forget_recipe": "inventor_lasmod_radiator" }, { "u_forget_recipe": "inventor_lasmod_chonky_radiator" }, { "u_forget_recipe": "inventor_lasmod_spooky_heat_sink" }, - { "u_forget_recipe": "inventor_research_energy_3" }, - { "u_forget_recipe": "bot_sniperbot" }, - { "u_forget_recipe": "bot_shotgunbot" }, - { "u_forget_recipe": "bot_meleebot" }, - { "u_forget_recipe": "rip_ticket" }, - { "u_forget_recipe": "inventor_warp_grenade" }, - { "u_forget_recipe": "inventor_portal_closer" }, - { "u_forget_recipe": "teleporter_inventor" }, - { "u_forget_recipe": "dreamdross_bo" }, - { "u_forget_recipe": "dreamdross_knife" }, - { "u_forget_recipe": "dreamdross_club" }, - { "u_forget_recipe": "dreamsmith_research" }, { "u_forget_recipe": "dreamdross_lump" }, { "u_forget_recipe": "forged_dreamstuff_ingot" }, - { "u_forget_recipe": "dreamforged_ballistic_plate" }, - { "u_forget_recipe": "dreamforged_ballistic_plate_small" }, - { "u_forget_recipe": "dreamforged_q_staff_ench" }, - { "u_forget_recipe": "dreamforged_longsword_ench" }, - { "u_forget_recipe": "dreamforged_warhammer_ench" }, - { "u_forget_recipe": "dreamforged_spear_ench" }, - { "u_forget_recipe": "dreamforged_halberd_ench" }, - { "u_forget_recipe": "dreamforged_glaive_ench" }, - { "u_forget_recipe": "dreamforged_naginata_ench" }, - { "u_forget_recipe": "dreamforged_mace_ench" }, - { "u_forget_recipe": "dreamforged_morningstar_ench" }, - { "u_forget_recipe": "dreamforged_estoc_ench" }, - { "u_forget_recipe": "dreamforged_arming_sword_ench" }, - { "u_forget_recipe": "dreamforged_broadsword_ench" }, - { "u_forget_recipe": "dreamforged_battleaxe_ench" }, - { "u_forget_recipe": "dreamforged_katana_ench" }, - { "u_forget_recipe": "dreamforged_knife_combat_ench" }, - { "u_forget_recipe": "dreamforged_kris_ench" }, - { "u_forget_recipe": "dreamforged_kukri_ench" }, - { "u_forget_recipe": "dreamforged_nodachi_ench" }, - { "u_forget_recipe": "dreamforged_rapier_ench" }, - { "u_forget_recipe": "dreamforged_tanto_ench" }, - { "u_forget_recipe": "dreamforged_wakizashi_ench" }, - { "u_forget_recipe": "dreamforged_zweihander_ench" }, - { "u_forget_recipe": "dreamforged_khopesh_ench" }, - { "u_forget_recipe": "dreamforged_lucerne_ench" }, - { "u_forget_recipe": "dreamforged_knuckle_ench" }, - { "u_forget_recipe": "dreamforged_fullhelmet_ench" }, - { "u_forget_recipe": "dreamforged_helmet_ench" }, - { "u_forget_recipe": "dreamforged_plate_armor_ench" }, - { "u_forget_recipe": "dreamforged_armguard_plate_ench" }, - { "u_forget_recipe": "dreamforged_boots_ench" }, - { "u_forget_recipe": "dreamforged_longbow" }, - { "u_forget_recipe": "arrow_dreamforged" }, - { "u_forget_recipe": "dreamforged_crossbow" }, - { "u_forget_recipe": "bolt_dreamforged" }, - { "u_forget_recipe": "dreamforged_hacksaw" }, - { "u_forget_recipe": "dreamforged_hammer" }, - { "u_forget_recipe": "dreamforged_halligan" }, - { "u_forget_recipe": "dreamforged_pliers_locking" }, - { "u_forget_recipe": "dreamforged_pickaxe" }, - { "u_forget_recipe": "dreamforged_picklocks" }, - { "u_forget_recipe": "dreamforged_scalpel" }, - { "u_forget_recipe": "dreamforged_e_tool" }, - { "u_forget_recipe": "dreamforged_ax" }, { "u_forget_recipe": "dreamforged_nail" }, - { "u_forget_recipe": "dreamforged_knuckle_berserk" }, - { "u_forget_recipe": "dreamforged_helmet_berserker" }, - { "u_forget_recipe": "dreamforged_armguard_plate_berserk" }, - { "u_forget_recipe": "dreamforged_boots_berserk" }, - { "u_forget_recipe": "dreamforged_fullhelmet_arcane" }, - { "u_forget_recipe": "dreamforged_glaive_healing" }, - { "u_forget_recipe": "dreamforged_tsurugi_speed" }, - { "u_forget_recipe": "dreamforged_q_staff_exp" }, - { "u_forget_recipe": "dreamforged_armguard_plate_gunslinger" }, - { "u_forget_recipe": "dreamforged_bed_of_restful_repose" } + { "u_forget_recipe": "software_math_inventor", "//": "Are these even recipes?" }, + { "u_forget_recipe": "software_electronics_reference_inventor" }, + { "u_forget_recipe": "nre_recorder_inventor" }, + { "u_forget_recipe": "teleporter_inventor" } ] } ] diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md index effe943855299..a2f84a4308afb 100644 --- a/doc/EFFECT_ON_CONDITION.md +++ b/doc/EFFECT_ON_CONDITION.md @@ -3455,7 +3455,9 @@ Your character or the npc will forget the recipe | Syntax | Optionality | Value | Info | | --- | --- | --- | --- | -| "u_forget_recipe" / "npc_forget_recipe" | **mandatory** | string or [variable object](#variable-object) | recipe, that would be forgotten | +| "u_forget_recipe" / "npc_forget_recipe" | **mandatory** | string or [variable object](#variable-object) | recipe/recipe category to be forgotten | +| "category" | optional, defaults to false unless subcategory is specified | bool | whether the above field should be interpreted as a category instead of a singular recipe | +| "subcategory" | optional | string or [variable object](#variable-object) | recipe subcategory of the specified category to be forgotten | ##### Valid talkers: @@ -3469,6 +3471,16 @@ You forget the recipe `inventor_research_base_1` { "u_forget_recipe": "inventor_research_base_1" } ``` +You forget all recipes in the `CC_XEDRA` category +```json +{ "u_forget_recipe": "CC_XEDRA", "category": true } +``` + +You forget all recipes in the `CC_XEDRA_MISC` subcategory of `CC_XEDRA` +```json +{ "u_forget_recipe": "CC_XEDRA", "subcategory": "CC_XEDRA_MISC" } +``` + You forget a recipe, that was passes by `recipe_id` context value ```json { "u_forget_recipe": { "context_val": "recipe_id" } } diff --git a/src/crafting_gui.cpp b/src/crafting_gui.cpp index cb6da5041bb1a..9f275a0fa5e7b 100644 --- a/src/crafting_gui.cpp +++ b/src/crafting_gui.cpp @@ -49,7 +49,6 @@ #include "point.h" #include "popup.h" #include "recipe.h" -#include "recipe_dictionary.h" #include "requirements.h" #include "skill.h" #include "string_formatter.h" @@ -885,9 +884,8 @@ void recipe_result_info_cache::insert_iteminfo_block_separator( std::vector, bool> -recipes_from_cat( const recipe_subset &available_recipes, const crafting_category_id &cat, - const std::string &subcat ) +std::pair, bool> recipes_from_cat( const recipe_subset + &available_recipes, const crafting_category_id &cat, const std::string &subcat ) { if( subcat == "CSC_*_FAVORITE" ) { return std::make_pair( available_recipes.favorite(), false ); diff --git a/src/crafting_gui.h b/src/crafting_gui.h index 88fbb1411e504..104f9f6e2e36c 100644 --- a/src/crafting_gui.h +++ b/src/crafting_gui.h @@ -6,6 +6,7 @@ #include #include +#include "recipe_dictionary.h" #include "type_id.h" class Character; @@ -24,6 +25,8 @@ class recipe; std::pair select_crafter_and_crafting_recipe( int &batch_size_out, const recipe_id &goto_recipe, Character *crafter, std::string filterstring = "", bool camp_crafting = false, inventory *inventory_override = nullptr ); +std::pair, bool> recipes_from_cat( const recipe_subset + &available_recipes, const crafting_category_id &cat, const std::string &subcat ); void load_recipe_category( const JsonObject &jsobj, const std::string &src ); void reset_recipe_categories(); diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 941f8128677b6..d2d4601190bc9 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -29,6 +29,7 @@ #include "computer.h" #include "condition.h" #include "coordinates.h" +#include "crafting_gui.h" #include "creature_tracker.h" #include "debug.h" #include "dialogue_helpers.h" @@ -4753,10 +4754,31 @@ talk_effect_fun_t::func f_learn_recipe( const JsonObject &jo, std::string_view m talk_effect_fun_t::func f_forget_recipe( const JsonObject &jo, std::string_view member, const std::string_view, bool is_npc ) { - str_or_var forgotten_recipe_id = get_str_or_var( jo.get_member( member ), member, true ); - return [forgotten_recipe_id, is_npc]( dialogue const & d ) { - const recipe_id &r = recipe_id( forgotten_recipe_id.evaluate( d ) ); - d.actor( is_npc )->forget_recipe( r ); + const bool use_subcategory = jo.has_member( "subcategory" ); + const bool forgotten_recipe_is_category = jo.get_bool( "category", false ) || use_subcategory; + str_or_var forgotten_recipe = get_str_or_var( jo.get_member( member ), member, true ); + std::optional forgotten_recipe_subcategory = std::nullopt; + if( use_subcategory ) { + forgotten_recipe_subcategory = get_str_or_var( jo.get_member( "subcategory" ), "subcategory", + true ); + } + + return [forgotten_recipe, forgotten_recipe_is_category, forgotten_recipe_subcategory, + is_npc]( dialogue const & d ) { + if( forgotten_recipe_is_category ) { + const recipe_subset &known_recipes = d.actor( is_npc )->get_character()->get_learned_recipes(); + const crafting_category_id category_to_use( forgotten_recipe.evaluate( d ) ); + const std::string subcategory_to_forget = !forgotten_recipe_subcategory ? "" : + forgotten_recipe_subcategory.value().evaluate( d ); + const std::vector recipes_to_forget = + recipes_from_cat( known_recipes, category_to_use, subcategory_to_forget ).first; + for( const recipe *recipe_to_forget : recipes_to_forget ) { + d.actor( is_npc )->forget_recipe( recipe_to_forget->ident() ); + } + } else { + const recipe_id &r = recipe_id( forgotten_recipe.evaluate( d ) ); + d.actor( is_npc )->forget_recipe( r ); + } }; } From cf579ac306b48feee8ae9fad2cd6b394d34c4aec Mon Sep 17 00:00:00 2001 From: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> Date: Sun, 17 Nov 2024 05:58:03 +0100 Subject: [PATCH 16/19] get rid of npctalk_var_ prefix for eoc variables (#77515) * get rid of npctalk_var_ prefix for eoc variables * cleanup after #77055 * deprecate more of type and context * migrate item vars, make migration happen only once * doc updates * migrate u/npc/monster variables * fix context var migration * remove `substr( 12 )` in math parser * move migration to a single function where possible * no auto * please clang * Please clang more * fix submap load test * clean up after #77656 * cleanups after #77520 --- data/json/items/tool/science.json | 23 +- .../isolated_road_jay_convert.json | 4 +- doc/JSON_INFO.md | 4 +- src/bionics.cpp | 2 +- src/character.cpp | 6 +- src/condition.cpp | 13 +- src/damage.cpp | 6 +- src/debug_menu.cpp | 10 +- src/dialogue_helpers.cpp | 14 +- src/effect_on_condition.cpp | 2 +- src/faction_camp.cpp | 4 +- src/game.cpp | 23 + src/game.h | 3 + src/iexamine_actors.cpp | 4 +- src/item.cpp | 10 +- src/iuse_actor.cpp | 2 +- src/magic_spell_effect.cpp | 2 +- src/mapgen.cpp | 2 +- src/math_parser.cpp | 4 +- src/math_parser_jmath.cpp | 2 +- src/mattack_actors.cpp | 2 +- src/mission_companion.cpp | 8 +- src/mutation.cpp | 4 +- src/npctalk.cpp | 25 +- src/projectile.cpp | 4 +- src/savegame.cpp | 5 +- src/savegame_json.cpp | 24 + src/suffer.cpp | 2 +- src/weather_gen.cpp | 2 +- src/widget.cpp | 2 +- tests/eoc_test.cpp | 590 +++++++++--------- tests/faction_price_rules_test.cpp | 4 +- tests/math_parser_test.cpp | 18 +- tests/melee_test.cpp | 30 +- tests/npc_blacklist_test.cpp | 2 +- tests/npc_shop_cons_rates_test.cpp | 2 +- tests/npc_shopkeeper_item_groups_test.cpp | 6 +- tests/npc_talk_test.cpp | 16 +- tests/ranged_balance_test.cpp | 4 +- tests/submap_load_test.cpp | 2 +- 40 files changed, 454 insertions(+), 438 deletions(-) diff --git a/data/json/items/tool/science.json b/data/json/items/tool/science.json index 7958465f0a7ea..7c4ed25576bea 100644 --- a/data/json/items/tool/science.json +++ b/data/json/items/tool/science.json @@ -1317,25 +1317,10 @@ ], "name": { "str_sp": "Mi-go Biotech" }, "conditional_names": [ - { "type": "VAR", "condition": "npctalk_var_mbt_f_function", "value": "morale", "name": { "str_sp": "%s (happy)" } }, - { - "type": "VAR", - "condition": "npctalk_var_mbt_f_function", - "value": "focus", - "name": { "str_sp": "%s (focus)" } - }, - { - "type": "VAR", - "condition": "npctalk_var_mbt_f_function", - "value": "pain", - "name": { "str_sp": "%s (pain relief)" } - }, - { - "type": "VAR", - "condition": "npctalk_var_mbt_f_function", - "value": "sleepiness", - "name": { "str_sp": "%s (wake up)" } - } + { "type": "VAR", "condition": "mbt_f_function", "value": "morale", "name": { "str_sp": "%s (happy)" } }, + { "type": "VAR", "condition": "mbt_f_function", "value": "focus", "name": { "str_sp": "%s (focus)" } }, + { "type": "VAR", "condition": "mbt_f_function", "value": "pain", "name": { "str_sp": "%s (pain relief)" } }, + { "type": "VAR", "condition": "mbt_f_function", "value": "sleepiness", "name": { "str_sp": "%s (wake up)" } } ], "description": "A piece of mi-go biotechnology.", "material": [ "alien_resin" ], diff --git a/data/json/npcs/isolated_road/isolated_road_jay_convert.json b/data/json/npcs/isolated_road/isolated_road_jay_convert.json index cdb2133865138..a3116f2916646 100644 --- a/data/json/npcs/isolated_road/isolated_road_jay_convert.json +++ b/data/json/npcs/isolated_road/isolated_road_jay_convert.json @@ -307,8 +307,8 @@ }, { "type": "var_migration", - "from": "npctalk_var_number_artisans_gunsmith_ammo_ammount", - "to": "npctalk_var_number_artisans_gunsmith_ammo_amount" + "from": "number_artisans_gunsmith_ammo_ammount", + "to": "number_artisans_gunsmith_ammo_amount" }, { "id": "TALK_GUNSMITH_BULLET_PICKUP", diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 5cbac8af44dbe..ff3c58ced9f00 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3973,7 +3973,7 @@ The `conditional_names` field allows defining alternate names for items that wil }, { "type": "VAR", - "condition": "npctalk_var_DISPLAY_NAME_MORALE", + "condition": "DISPLAY_NAME_MORALE", "name": { "str_sp": "%s (morale)" }, "value" : "true" }, @@ -3992,7 +3992,7 @@ You can list as many conditional names for a given item as you want. Each condit - `COMPONENT_ID` Similar to `COMPONENT_ID_SUBSTRING`, but search the exact component match - `FLAG` which checks if an item has the specified flag (exact match). - `VITAMIN` which checks if an item has the specified vitamin (exact match). - - `VAR` which checks if an item has a variable with the given name (exact match) and value = `value`. Variables set with effect_on_conditions will have `npctalk_var_` in front of their name. So a variable created with: `"npc_add_var": "MORALE", "value": "Felt Great" }` would be named: `npctalk_var_MORALE`. + - `VAR` which checks if an item has a variable with the given name (exact match) and value = `value`. - `SNIPPET_ID`which checks if an item has a snippet id variable set by an effect_on_condition with the given name (exact match) and snippets id = `value`. 2. The condition you want to look for. 3. The name to use if a match is found. Follows all the rules of a standard `name` field, with valid keys being `str`, `str_pl`, and `ctxt`. You may use %s here, which will be replaced by the name of the item. Conditional names defined prior to this one are taken into account. diff --git a/src/bionics.cpp b/src/bionics.cpp index 48b680bf8ef27..cb66c7d45e9b8 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -783,7 +783,7 @@ bool Character::activate_bionic( bionic &bio, bool eff_only, bool *close_bionics for( const effect_on_condition_id &eoc : bio.id->activated_eocs ) { dialogue d( get_talker_for( *this ), nullptr ); - write_var_value( var_type::context, "npctalk_var_act_cost", &d, + write_var_value( var_type::context, "act_cost", &d, units::to_millijoule( bio.info().power_activate ) ); if( eoc->type == eoc_type::ACTIVATION ) { eoc->activate( d ); diff --git a/src/character.cpp b/src/character.cpp index d3def233ed518..c3101d18c32dd 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -516,8 +516,8 @@ void Character::queue_effect( const std::string &name, const time_duration &dela const time_duration &effect_duration ) { std::unordered_map ctx = { - { "npctalk_var_effect", name }, - { "npctalk_var_duration", std::to_string( to_turns( effect_duration ) ) } + { "effect", name }, + { "duration", std::to_string( to_turns( effect_duration ) ) } }; effect_on_conditions::queue_effect_on_condition( delay, effect_on_condition_add_effect, *this, @@ -529,7 +529,7 @@ int Character::count_queued_effects( const std::string &effect ) const return std::count_if( queued_effect_on_conditions.list.begin(), queued_effect_on_conditions.list.end(), [&effect]( const queued_eoc & eoc ) { return eoc.eoc == effect_on_condition_add_effect && - eoc.context.at( "npctalk_var_effect" ) == effect; + eoc.context.at( "effect" ) == effect; } ); } diff --git a/src/condition.cpp b/src/condition.cpp index d40e43d8fdb6a..e629dee38a9db 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -172,11 +172,8 @@ std::string get_talk_varname( const JsonObject &jo, std::string_view member, jo.throw_error( "invalid " + std::string( member ) + " condition in " + jo.str() ); } const std::string &var_basename = jo.get_string( std::string( member ) ); - const std::string &type_var = jo.get_string( "type", "" ); - const std::string &var_context = jo.get_string( "context", "" ); default_val = get_dbl_or_var( jo, "default", false ); - return "npctalk_var" + ( type_var.empty() ? "" : "_" + type_var ) + ( var_context.empty() ? "" : "_" - + var_context ) + "_" + var_basename; + return var_basename; } std::string get_talk_var_basename( const JsonObject &jo, std::string_view member, @@ -432,11 +429,7 @@ static abstract_var_info abstract_read_var_info( const JsonObject &jo ) } if( jo.has_string( "var_name" ) ) { - const std::string &type_var = jo.get_string( "type", "" ); - const std::string &var_context = jo.get_string( "context", "" ); - name = "npctalk_var_" + type_var + ( type_var.empty() ? "" : "_" ) + var_context + - ( var_context.empty() ? "" : "_" ) - + jo.get_string( "var_name" ); + name = jo.get_string( "var_name" ); } if( jo.has_member( "u_val" ) ) { type = var_type::u; @@ -1165,7 +1158,7 @@ conditional_t::func f_expects_vars( const JsonObject &jo, std::string_view membe return [to_check]( const_dialogue const & d ) { std::string missing_variables; for( const str_or_var &val : to_check ) { - if( d.get_context().find( "npctalk_var_" + val.evaluate( d ) ) == d.get_context().end() ) { + if( d.get_context().find( val.evaluate( d ) ) == d.get_context().end() ) { missing_variables += val.evaluate( d ) + ", "; } } diff --git a/src/damage.cpp b/src/damage.cpp index 6fda13eb70975..84cfcc1bb1886 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -437,9 +437,9 @@ void damage_type::ondamage_effects( Creature *source, Creature *target, bodypart dialogue d( source == nullptr ? nullptr : get_talker_for( source ), target == nullptr ? nullptr : get_talker_for( target ) ); - d.set_value( "npctalk_var_damage_taken", std::to_string( damage_taken ) ); - d.set_value( "npctalk_var_total_damage", std::to_string( total_damage ) ); - d.set_value( "npctalk_var_bp", bp.str() ); + d.set_value( "damage_taken", std::to_string( damage_taken ) ); + d.set_value( "total_damage", std::to_string( total_damage ) ); + d.set_value( "bp", bp.str() ); if( eoc->type == eoc_type::ACTIVATION ) { eoc->activate( d ); diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index fb78686cfdc49..2526ff1cb2343 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -614,11 +614,10 @@ static void edit_global_npctalk_vars() std::string key; string_input_popup popup_key; popup_key - //~This is the title for an input window, where strings like npctalk_var_my_variable are concatenated. The trailing "npctalk_var_" is intended to show that their entry is automatically prepended with that. e.g. if they type "cigar" the resulting var's string is "npctalk_var_cigar" - .title( _( "Key\n npctalk_var_" ) ) + .title( _( "Key\n" ) ) .width( 85 ) .edit( key ); - globvars.set_global_value( "npctalk_var_" + key, query_npctalkvar_new_value() ); + globvars.set_global_value( key, query_npctalkvar_new_value() ); } else if( selected_globvar > 0 && selected_globvar <= static_cast( keymap_index.size() ) ) { globvars.set_global_value( keymap_index[selected_globvar], query_npctalkvar_new_value() ); } @@ -655,11 +654,10 @@ static void edit_character_npctalk_vars( Character &you ) std::string key; string_input_popup popup_key; popup_key - //~This is the title for an input window, where strings like npctalk_var_my_variable are concatenated. The trailing "npctalk_var_" is intended to show that their entry is automatically prepended with that. e.g. if they type "cigar" the resulting var's string is "npctalk_var_cigar" - .title( _( "Key\n npctalk_var_" ) ) + .title( _( "Key\n" ) ) .width( 85 ) .edit( key ); - you.set_value( "npctalk_var_" + key, query_npctalkvar_new_value() ); + you.set_value( key, query_npctalkvar_new_value() ); } else if( selected_globvar > 0 && selected_globvar <= static_cast( keymap_index.size() ) ) { you.set_value( keymap_index[selected_globvar], query_npctalkvar_new_value() ); } diff --git a/src/dialogue_helpers.cpp b/src/dialogue_helpers.cpp index 27e449fc7e724..95d04ed724c02 100644 --- a/src/dialogue_helpers.cpp +++ b/src/dialogue_helpers.cpp @@ -88,7 +88,7 @@ var_info process_variable( const std::string &type ) ret_str = type.substr( 1, type.size() - 1 ); } - return var_info( vt, "npctalk_var_" + ret_str ); + return var_info( vt, ret_str ); } template<> @@ -109,9 +109,6 @@ std::string str_or_var::evaluate( const_dialogue const &d ) const return default_val.value(); } std::string var_name = var_val.value().name; - if( var_name.find( "npctalk_var" ) != std::string::npos ) { - var_name = var_name.substr( 12 ); - } debugmsg( "No default value provided for str_or_var_part while encountering unused " "variable %s. Add a \"default_str\" member to prevent this. %s", var_name, d.get_callstack() ); @@ -139,9 +136,6 @@ std::string translation_or_var::evaluate( const_dialogue const &d ) const return default_val.value().translated(); } std::string var_name = var_val.value().name; - if( var_name.find( "npctalk_var" ) != std::string::npos ) { - var_name = var_name.substr( 12 ); - } debugmsg( "No default value provided for str_or_var_part while encountering unused " "variable %s. Add a \"default_str\" member to prevent this. %s", var_name, d.get_callstack() ); @@ -172,9 +166,6 @@ double dbl_or_var_part::evaluate( const_dialogue const &d ) const return default_val.value(); } std::string var_name = var_val.value().name; - if( var_name.find( "npctalk_var" ) != std::string::npos ) { - var_name = var_name.substr( 12 ); - } debugmsg( "No default value provided for dbl_or_var_part while encountering unused " "variable %s. Add a \"default\" member to prevent this. %s", var_name, d.get_callstack() ); @@ -212,9 +203,6 @@ time_duration duration_or_var_part::evaluate( const_dialogue const &d ) const return default_val.value(); } std::string var_name = var_val.value().name; - if( var_name.find( "npctalk_var" ) != std::string::npos ) { - var_name = var_name.substr( 12 ); - } debugmsg( "No default value provided for duration_or_var_part while encountering unused " "variable %s. Add a \"default\" member to prevent this. %s", var_name, d.get_callstack() ); diff --git a/src/effect_on_condition.cpp b/src/effect_on_condition.cpp index 0084c75df6171..eece9d0b28178 100644 --- a/src/effect_on_condition.cpp +++ b/src/effect_on_condition.cpp @@ -568,7 +568,7 @@ void eoc_events::notify( const cata::event &e, std::unique_ptr alpha, dialogue d; std::unordered_map context; for( const auto &val : e.data() ) { - context["npctalk_var_" + val.first] = val.second.get_string(); + context[val.first] = val.second.get_string(); } // if we have an NPC to trigger this event for, do so, diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 60f03342bbe54..10a04ee913645 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -203,10 +203,10 @@ static const std::string camp_om_fortifications_spiked_trench_parameter = faction_wall_level_n_1_string; static const std::string var_time_between_succession = - "npctalk_var_time_between_succession"; + "time_between_succession"; static const std::string var_timer_time_of_last_succession = - "npctalk_var_timer_time_of_last_succession"; + "timer_time_of_last_succession"; // These strings are matched against recipe group 'building_type'. Definite candidates for JSON definitions of // the various UI strings corresponding to these groups. diff --git a/src/game.cpp b/src/game.cpp index 281f50c59a667..5fb585a7c72e7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -870,6 +870,29 @@ void game::load_map( const tripoint_abs_sm &pos_sm, m.load( pos_sm, true, pump_events ); } +void game::legacy_migrate_npctalk_var_prefix( std::unordered_map + map_of_vars ) +{ + // migrate existing variables with npctalk_var prefix to no prefix (npctalk_var_foo to just foo) + // remove after 0.J + + if( savegame_loading_version >= 35 ) { + return; + } + + const std::string prefix = "npctalk_var_"; + for( auto i = map_of_vars.begin(); i != map_of_vars.end(); ) { + if( i->first.rfind( prefix, 0 ) == 0 ) { + auto extracted = map_of_vars.extract( i++ ); + std::string new_key = extracted.key().substr( prefix.size() ); + extracted.key() = new_key; + map_of_vars.insert( std::move( extracted ) ); + } else { + ++i; + } + } +} + // Set up all default values for a new game bool game::start_game() { diff --git a/src/game.h b/src/game.h index ddd7078c9a681..fb2dc6ceb337e 100644 --- a/src/game.h +++ b/src/game.h @@ -735,6 +735,9 @@ class game * disabled). */ void load_map( const tripoint_abs_sm &pos_sm, bool pump_events = false ); + // Removes legacy npctalk_var_ prefix from older versions of the game. Should be removed after 0.J + static void legacy_migrate_npctalk_var_prefix( std::unordered_map + map_of_vars ); /** * The overmap which contains the center submap of the reality bubble. */ diff --git a/src/iexamine_actors.cpp b/src/iexamine_actors.cpp index 85a4bbd272496..00d8270538f75 100644 --- a/src/iexamine_actors.cpp +++ b/src/iexamine_actors.cpp @@ -256,8 +256,8 @@ std::unique_ptr cardreader_examine_actor::clone() const void eoc_examine_actor::call( Character &you, const tripoint_bub_ms &examp ) const { dialogue d( get_talker_for( you ), nullptr ); - d.set_value( "npctalk_var_this", get_map().furn( examp ).id().str() ); - d.set_value( "npctalk_var_pos", get_map().getglobal( examp ).to_string() ); + d.set_value( "this", get_map().furn( examp ).id().str() ); + d.set_value( "pos", get_map().getglobal( examp ).to_string() ); for( const effect_on_condition_id &eoc : eocs ) { eoc->activate( d ); } diff --git a/src/item.cpp b/src/item.cpp index fcb500a96a153..f3c921fa82bfc 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -339,8 +339,8 @@ item::item( const itype *type, time_point turn, int qty ) : type( type ), bday( if( has_flag( flag_ENERGY_SHIELD ) ) { const islot_armor *sh = find_armor_data(); - set_var( "npctalk_var_MAX_ENERGY_SHIELD_HP", sh->max_energy_shield_hp ); - set_var( "npctalk_var_ENERGY_SHIELD_HP", sh->max_energy_shield_hp ); + set_var( "MAX_ENERGY_SHIELD_HP", sh->max_energy_shield_hp ); + set_var( "ENERGY_SHIELD_HP", sh->max_energy_shield_hp ); } if( has_flag( flag_COLLAPSE_CONTENTS ) ) { @@ -9042,10 +9042,10 @@ item::armor_status item::damage_armor_durability( damage_unit &du, damage_unit & { //Energy shields aren't damaged by attacks but do get their health variable reduced. They are also only //damaged by the damage types they actually protect against. - if( has_var( "npctalk_var_ENERGY_SHIELD_HP" ) && resist( du.type, false, bp ) > 0.0f ) { - double shield_hp = get_var( "npctalk_var_ENERGY_SHIELD_HP", 0.0 ); + if( has_var( "ENERGY_SHIELD_HP" ) && resist( du.type, false, bp ) > 0.0f ) { + double shield_hp = get_var( "ENERGY_SHIELD_HP", 0.0 ); shield_hp -= premitigated.amount; - set_var( "npctalk_var_ENERGY_SHIELD_HP", shield_hp ); + set_var( "ENERGY_SHIELD_HP", shield_hp ); if( shield_hp > 0 ) { return armor_status::UNDAMAGED; } else { diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 8b8ff6beaf657..1d9156a35e62e 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -5636,7 +5636,7 @@ std::optional effect_on_conditons_actor::use( Character *p, item &it, } dialogue d( ( char_ptr == nullptr ? nullptr : get_talker_for( char_ptr ) ), get_talker_for( loc ) ); - write_var_value( var_type::context, "npctalk_var_id", &d, it.typeId().str() ); + write_var_value( var_type::context, "id", &d, it.typeId().str() ); for( const effect_on_condition_id &eoc : eocs ) { if( eoc->type == eoc_type::ACTIVATION ) { eoc->activate( d ); diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 32b49676a3aab..a642f07c1e1c0 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -1893,7 +1893,7 @@ void spell_effect::effect_on_condition( const spell &sp, Creature &caster, Creature *victim = creatures.creature_at( potential_target ); dialogue d( victim ? get_talker_for( victim ) : nullptr, get_talker_for( caster ) ); const tripoint_abs_ms target_abs = get_map().getglobal( potential_target ); - write_var_value( var_type::context, "npctalk_var_spell_location", &d, + write_var_value( var_type::context, "spell_location", &d, target_abs.to_string() ); d.amend_callstack( string_format( "Spell: %s Caster: %s", sp.id().c_str(), caster.disp_name() ) ); effect_on_condition_id eoc = effect_on_condition_id( sp.effect_data() ); diff --git a/src/mapgen.cpp b/src/mapgen.cpp index d0e813b8922eb..63d1f53114041 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -8130,7 +8130,7 @@ void set_queued_points() { global_variables &globvars = get_globals(); for( std::pair &queued_point : queued_points ) { - globvars.set_global_value( "npctalk_var_" + queued_point.first, queued_point.second.to_string() ); + globvars.set_global_value( queued_point.first, queued_point.second.to_string() ); } queued_points.clear(); } diff --git a/src/math_parser.cpp b/src/math_parser.cpp index 509cb14abb737..25da45a20f18c 100644 --- a/src/math_parser.cpp +++ b/src/math_parser.cpp @@ -797,7 +797,7 @@ void math_exp::math_exp_impl::new_var( std::string_view str ) scoped = scoped.substr( 1 ); } validate_string( scoped, "variable", " \'" ); - output.emplace( std::in_place_type_t(), type, "npctalk_var_" + std::string{ scoped } ); + output.emplace( std::in_place_type_t(), type, std::string{ scoped } ); } std::string math_exp::math_exp_impl::error( std::string_view str, std::string_view what ) @@ -815,7 +815,7 @@ std::string math_exp::math_exp_impl::error( std::string_view str, std::string_vi std::holds_alternative( output.top().data ) ) { // NOLINTNEXTLINE(cata-translate-string-literal): debug message mess = string_format( "%s (or unknown function %s)", mess, - std::get( output.top().data ).varinfo.name.substr( 12 ) ); + std::get( output.top().data ).varinfo.name ); } offset = std::max( 0, offset - 1 ); diff --git a/src/math_parser_jmath.cpp b/src/math_parser_jmath.cpp index d641487fee0cb..f082b8aff6d74 100644 --- a/src/math_parser_jmath.cpp +++ b/src/math_parser_jmath.cpp @@ -78,7 +78,7 @@ double jmath_func::eval( const_dialogue const &d, std::vector const &par { const_dialogue d_next( d ); for( std::vector::size_type i = 0; i < params.size(); i++ ) { - d_next.set_value( "npctalk_var_" + std::to_string( i ), string_format( "%g", params[i] ) ); + d_next.set_value( std::to_string( i ), string_format( "%g", params[i] ) ); } return eval( d_next ); diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index da1e05e3933b7..fa9450841390c 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -919,7 +919,7 @@ bool melee_actor::call( monster &z ) const //run EoCs for( const effect_on_condition_id &eoc : eoc ) { dialogue d( get_talker_for( z ), get_talker_for( target ) ); - write_var_value( var_type::context, "npctalk_var_damage", &d, damage_total ); + write_var_value( var_type::context, "damage", &d, damage_total ); eoc->activate( d ); } diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index e6cb7105b5ad0..cc6669e4638b1 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -142,13 +142,13 @@ static const trait_id trait_NPC_CONSTRUCTION_LEV_2( "NPC_CONSTRUCTION_LEV_2" ); static const trait_id trait_NPC_MISSION_LEV_1( "NPC_MISSION_LEV_1" ); static const std::string var_DOCTOR_ANESTHETIC_SCAVENGERS_HELPED = - "npctalk_var_mission_tacoma_ranch_doctor_anesthetic_scavengers_helped"; + "mission_tacoma_ranch_doctor_anesthetic_scavengers_helped"; static const std::string var_PURCHASED_FIELD_1_FENCE = - "npctalk_var_dialogue_tacoma_ranch_purchased_field_1_fence"; + "dialogue_tacoma_ranch_purchased_field_1_fence"; static const std::string var_SCAVENGER_HOSPITAL_RAID = - "npctalk_var_mission_tacoma_ranch_scavenger_hospital_raid"; + "mission_tacoma_ranch_scavenger_hospital_raid"; static const std::string var_SCAVENGER_HOSPITAL_RAID_STARTED = - "npctalk_var_mission_tacoma_ranch_scavenger_hospital_raid_started"; + "mission_tacoma_ranch_scavenger_hospital_raid_started"; static const std::string role_id_faction_camp = "FACTION_CAMP"; diff --git a/src/mutation.cpp b/src/mutation.cpp index e99d54d7cccd3..a6fef23a36699 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -856,7 +856,7 @@ void Character::activate_mutation( const trait_id &mut ) if( !mut->activated_eocs.empty() ) { for( const effect_on_condition_id &eoc : mut->activated_eocs ) { dialogue d( get_talker_for( *this ), nullptr ); - d.set_value( "npctalk_var_this", mut.str() ); + d.set_value( "this", mut.str() ); if( eoc->type == eoc_type::ACTIVATION ) { eoc->activate( d ); } else { @@ -1013,7 +1013,7 @@ void Character::deactivate_mutation( const trait_id &mut ) for( const effect_on_condition_id &eoc : mut->deactivated_eocs ) { dialogue d( get_talker_for( *this ), nullptr ); - d.set_value( "npctalk_var_this", mut.str() ); + d.set_value( "this", mut.str() ); if( eoc->type == eoc_type::ACTIVATION ) { eoc->activate( d ); } else { diff --git a/src/npctalk.cpp b/src/npctalk.cpp index d2d4601190bc9..f83561a1e28b0 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -2372,7 +2372,7 @@ void parse_tags( std::string &phrase, const_talker const &u, const_talker const var.pop_back(); // resolve nest parse_tags( var, u, me, d, item_type ); - phrase.replace( fa, l, u.get_value( "npctalk_var_" + var ) ); + phrase.replace( fa, l, u.get_value( var ) ); } else if( tag.find( "get_unique_id() ); + cur_var.name.insert( 0, guy->get_unique_id() ); } tripoint_abs_ms target_location = get_tripoint_from_var( cur_var, d, is_npc ); guy->set_guard_pos( target_location ); @@ -5723,7 +5722,7 @@ talk_effect_fun_t::func f_run_eocs( const JsonObject &jo, std::string_view membe if( jo.has_object( "variables" ) ) { const JsonObject &variables = jo.get_object( "variables" ); for( const JsonMember &jv : variables ) { - context["npctalk_var_" + jv.name()] = get_str_translation_or_var( jv, jv.name(), true ); + context[jv.name()] = get_str_translation_or_var( jv, jv.name(), true ); } } @@ -5826,7 +5825,7 @@ talk_effect_fun_t::func f_run_eoc_selector( const JsonObject &jo, std::string_vi const JsonObject &variables = member.get_object(); std::unordered_map temp_context; for( const JsonMember &jv : variables ) { - temp_context["npctalk_var_" + jv.name()] = get_str_translation_or_var( jv, jv.name(), true ); + temp_context[jv.name()] = get_str_translation_or_var( jv, jv.name(), true ); } context.emplace_back( temp_context ); } @@ -6998,8 +6997,8 @@ talk_effect_fun_t::func f_closest_city( const JsonObject &jo, std::string_view m if( city ) { tripoint_abs_omt city_center_omt = project_to( city.abs_sm_pos ); write_var_value( type, var_name, &d, city_center_omt.to_string() ); - write_var_value( var_type::context, "npctalk_var_city_name", &d, city.city->name ); - write_var_value( var_type::context, "npctalk_var_city_size", &d, city.city->size ); + write_var_value( var_type::context, "city_name", &d, city.city->name ); + write_var_value( var_type::context, "city_size", &d, city.city->size ); } else { return; } @@ -7008,8 +7007,8 @@ talk_effect_fun_t::func f_closest_city( const JsonObject &jo, std::string_view m if( city ) { tripoint_abs_omt city_center_omt = project_to( city.abs_sm_pos ); write_var_value( type, var_name, &d, city_center_omt.to_string() ); - write_var_value( var_type::context, "npctalk_var_city_name", &d, city.city->name ); - write_var_value( var_type::context, "npctalk_var_city_size", &d, city.city->size ); + write_var_value( var_type::context, "city_name", &d, city.city->name ); + write_var_value( var_type::context, "city_size", &d, city.city->size ); } } }; @@ -7906,7 +7905,7 @@ json_dynamic_line_effect::json_dynamic_line_effect( const JsonObject &jo, // set the sentinel if( jo.has_string( "sentinel" ) ) { const std::string sentinel = jo.get_string( "sentinel" ); - const std::string varname = "npctalk_var_sentinel_" + id + "_" + sentinel; + const std::string varname = "sentinel_" + id + "_" + sentinel; condition = [varname, tmp_condition]( dialogue & d ) { return d.actor( false )->get_value( varname ) != "yes" && tmp_condition( d ); }; diff --git a/src/projectile.cpp b/src/projectile.cpp index fef70423babab..e19d5477609e8 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -197,8 +197,8 @@ void apply_ammo_effects( Creature *source, const tripoint_bub_ms &p, dialogue d( get_talker_for( *source ), critter == nullptr ? nullptr : get_talker_for( critter ) ); // `p` is tripoint relative to the upper left corner of currently loaded overmap // not very useful for player's purposes methinks, but much appreciated - // write_var_value( var_type::context, "npctalk_var_proj_target_tripoint", &d, p.abs().to_string()); - write_var_value( var_type::context, "npctalk_var_proj_damage", &d, dealt_damage ); + // write_var_value( var_type::context, "proj_target_tripoint", &d, p.abs().to_string()); + write_var_value( var_type::context, "proj_damage", &d, dealt_damage ); eoc->activate( d ); } //cast ammo effect spells diff --git a/src/savegame.cpp b/src/savegame.cpp index 014ca9bdbc81a..263fce9bc6ef7 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -69,7 +69,7 @@ extern std::map> quick_shortcuts_map; * Changes that break backwards compatibility should bump this number, so the game can * load a legacy format loader. */ -const int savegame_version = 34; +const int savegame_version = 35; /* * This is a global set by detected version header in .sav, maps.txt, or overmap. @@ -1550,6 +1550,7 @@ void weather_manager::unserialize_all( const JsonObject &w ) void global_variables::unserialize( JsonObject &jo ) { + // global variables jo.read( "global_vals", global_values ); // potentially migrate some variable names for( std::pair migration : migrations ) { @@ -1559,6 +1560,8 @@ void global_variables::unserialize( JsonObject &jo ) global_values.insert( std::move( extracted ) ); } } + + game::legacy_migrate_npctalk_var_prefix( global_values ); } void timed_event_manager::unserialize_all( const JsonArray &ja ) diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index a2c11e559729f..f04b3073728d9 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1265,9 +1265,12 @@ void Character::load( const JsonObject &data ) temp.time = time_point( elem.get_int( "time" ) ); temp.eoc = effect_on_condition_id( elem.get_string( "eoc" ) ); std::unordered_map context; + // context variables for( const JsonMember &jm : elem.get_object( "context" ) ) { context[jm.name()] = jm.get_string(); } + game::legacy_migrate_npctalk_var_prefix( context ); + temp.context = context; queued_effect_on_conditions.push( temp ); } @@ -2808,7 +2811,25 @@ void item::io( Archive &archive ) archive.io( "bday", bday, calendar::start_of_cataclysm ); archive.io( "mission_id", mission_id, -1 ); archive.io( "player_id", player_id, -1 ); + // item variables archive.io( "item_vars", item_vars, io::empty_default_tag() ); + + // game::legacy_migrate_npctalk_var_prefix( item_vars ); + // doesn't work here, because item_vars is cata::heap>, not std::unordered_map<> + // remove after 0.J + if( savegame_loading_version < 35 ) { + const std::string prefix = "npctalk_var_"; + for( auto i = item_vars.begin(); i != item_vars.end(); ) { + if( i->first.rfind( prefix, 0 ) == 0 ) { + std::map::node_type extracted = ( *item_vars ).extract( i++ ); + std::string new_key = extracted.key().substr( prefix.size() ); + extracted.key() = new_key; + item_vars.insert( std::move( extracted ) ); + } else { + ++i; + } + } + } // TODO: change default to empty string archive.io( "name", corpse_name, std::string() ); archive.io( "owner", owner, faction_id::NULL_ID() ); @@ -3762,6 +3783,7 @@ void Creature::load( const JsonObject &jsin ) jsin.read( "effects", *effects ); } + // u/npc variables jsin.read( "values", values ); // potentially migrate some values for( std::pair migration : get_globals().migrations ) { @@ -3772,6 +3794,8 @@ void Creature::load( const JsonObject &jsin ) } } + game::legacy_migrate_npctalk_var_prefix( values ); + jsin.read( "damage_over_time_map", damage_over_time_map ); jsin.read( "blocks_left", num_blocks ); diff --git a/src/suffer.cpp b/src/suffer.cpp index dd43ba37b7b17..696d873ab9e39 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -298,7 +298,7 @@ void suffer::mutation_power( Character &you, const trait_id &mut_id ) // if you haven't deactivated then run the EOC for( const effect_on_condition_id &eoc : mut_id->processed_eocs ) { dialogue d( get_talker_for( you ), nullptr ); - d.set_value( "npctalk_var_this", mut_id.str() ); + d.set_value( "this", mut_id.str() ); if( eoc->type == eoc_type::ACTIVATION ) { eoc->activate( d ); } else { diff --git a/src/weather_gen.cpp b/src/weather_gen.cpp index f5e22ba3ca37d..d59037230c359 100644 --- a/src/weather_gen.cpp +++ b/src/weather_gen.cpp @@ -193,7 +193,7 @@ weather_type_id weather_generator::get_weather_conditions( const w_point &w ) co w_point original_weather_precise = *game_weather.weather_precise; *game_weather.weather_precise = w; std::unordered_map context; - context["npctalk_var_weather_location"] = w.location.to_string(); + context["weather_location"] = w.location.to_string(); weather_type_id current_conditions = WEATHER_CLEAR; dialogue d( get_talker_for( get_avatar() ), nullptr, {}, context ); for( const weather_type_id &type : sorted_weather ) { diff --git a/src/widget.cpp b/src/widget.cpp index d81d908d6256e..263c049fea0d0 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -309,7 +309,7 @@ bool widget_clause::meets_condition( const std::string &opt_var ) const { dialogue d( get_talker_for( get_avatar() ), nullptr ); d.reason = opt_var; // TODO: remove since it's replaced by context var - write_var_value( var_type::context, "npctalk_var_widget", &d, opt_var ); + write_var_value( var_type::context, "widget", &d, opt_var ); return !has_condition || condition( d ); } diff --git a/tests/eoc_test.cpp b/tests/eoc_test.cpp index ffb53f93a60f6..3c2918c1c7a86 100644 --- a/tests/eoc_test.cpp +++ b/tests/eoc_test.cpp @@ -232,15 +232,15 @@ TEST_CASE( "EOC_math_integration", "[eoc][math_parser]" ) dialogue d( get_talker_for( get_avatar() ), std::make_unique() ); global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_math_test" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_math_test_result" ).empty() ); + REQUIRE( globvars.get_global_value( "math_test" ).empty() ); + REQUIRE( globvars.get_global_value( "math_test_result" ).empty() ); calendar::turn = calendar::start_of_cataclysm; CHECK_FALSE( effect_on_condition_EOC_math_test_greater_increment->test_condition( d ) ); effect_on_condition_EOC_math_test_greater_increment->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_math_test" ) ) == Approx( -1 ) ); + CHECK( std::stod( globvars.get_global_value( "math_test" ) ) == Approx( -1 ) ); effect_on_condition_EOC_math_switch_math->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_math_test_result" ) ) == Approx( 1 ) ); + CHECK( std::stod( globvars.get_global_value( "math_test_result" ) ) == Approx( 1 ) ); CHECK( effect_on_condition_EOC_math_duration->recurrence.evaluate( d ) == 1_turns ); calendar::turn += 1_days; @@ -250,16 +250,16 @@ TEST_CASE( "EOC_math_integration", "[eoc][math_parser]" ) CHECK( effect_on_condition_EOC_math_test_equals_assign->test_condition( d ) ); CHECK( effect_on_condition_EOC_math_test_inline_condition->test_condition( d ) ); effect_on_condition_EOC_math_test_equals_assign->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_math_test" ) ) == Approx( 9 ) ); + CHECK( std::stod( globvars.get_global_value( "math_test" ) ) == Approx( 9 ) ); effect_on_condition_EOC_math_switch_math->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_math_test_result" ) ) == Approx( 2 ) ); + CHECK( std::stod( globvars.get_global_value( "math_test_result" ) ) == Approx( 2 ) ); CHECK( effect_on_condition_EOC_math_duration->recurrence.evaluate( d ) == 2_turns ); CHECK( effect_on_condition_EOC_math_test_greater_increment->test_condition( d ) ); effect_on_condition_EOC_math_test_greater_increment->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_math_test" ) ) == Approx( 10 ) ); + CHECK( std::stod( globvars.get_global_value( "math_test" ) ) == Approx( 10 ) ); effect_on_condition_EOC_math_switch_math->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_math_test_result" ) ) == Approx( 3 ) ); + CHECK( std::stod( globvars.get_global_value( "math_test_result" ) ) == Approx( 3 ) ); CHECK( effect_on_condition_EOC_math_duration->recurrence.evaluate( d ) == 3_turns ); int const stam_pre = get_avatar().get_stamina(); @@ -269,34 +269,34 @@ TEST_CASE( "EOC_math_integration", "[eoc][math_parser]" ) get_avatar().set_pain( 0 ); get_avatar().set_stamina( 9000 ); effect_on_condition_EOC_math_weighted_list->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_weighted_var" ) ) == Approx( -999 ) ); + CHECK( std::stod( globvars.get_global_value( "weighted_var" ) ) == Approx( -999 ) ); get_avatar().set_pain( 9000 ); get_avatar().set_stamina( 0 ); effect_on_condition_EOC_math_weighted_list->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_weighted_var" ) ) == Approx( 1 ) ); + CHECK( std::stod( globvars.get_global_value( "weighted_var" ) ) == Approx( 1 ) ); } TEST_CASE( "EOC_jmath", "[eoc][math_parser]" ) { global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_blorgy" ).empty() ); + REQUIRE( globvars.get_global_value( "blorgy" ).empty() ); dialogue d( get_talker_for( get_avatar() ), std::make_unique() ); effect_on_condition_EOC_jmath_test->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_blorgy" ) ) == Approx( 7 ) ); + CHECK( std::stod( globvars.get_global_value( "blorgy" ) ) == Approx( 7 ) ); } TEST_CASE( "EOC_diag_with_vars", "[eoc][math_parser]" ) { global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_myskill_math" ).empty() ); + REQUIRE( globvars.get_global_value( "myskill_math" ).empty() ); dialogue d( get_talker_for( get_avatar() ), std::make_unique() ); effect_on_condition_EOC_math_diag_w_vars->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_myskill_math" ) ) == Approx( 0 ) ); + CHECK( std::stod( globvars.get_global_value( "myskill_math" ) ) == Approx( 0 ) ); get_avatar().set_skill_level( skill_survival, 3 ); effect_on_condition_EOC_math_diag_w_vars->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_myskill_math" ) ) == Approx( 3 ) ); + CHECK( std::stod( globvars.get_global_value( "myskill_math" ) ) == Approx( 3 ) ); } TEST_CASE( "EOC_transform_radius", "[eoc][timed_event]" ) @@ -350,7 +350,7 @@ TEST_CASE( "EOC_activity_finish", "[eoc][timed_event]" ) complete_activity( get_avatar() ); - CHECK( stoi( get_avatar().get_value( "npctalk_var_activitiy_incrementer" ) ) == 1 ); + CHECK( stoi( get_avatar().get_value( "activitiy_incrementer" ) ) == 1 ); } TEST_CASE( "EOC_combat_mutator_test", "[eoc]" ) @@ -365,13 +365,13 @@ TEST_CASE( "EOC_combat_mutator_test", "[eoc]" ) 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() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); CHECK( effect_on_condition_EOC_combat_mutator_test->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "RAPID_TEST" ); - CHECK( globvars.get_global_value( "npctalk_var_key2" ) == "Rapid Strike Test" ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ) == "50% moves, 66% damage" ); + CHECK( globvars.get_global_value( "key1" ) == "RAPID_TEST" ); + CHECK( globvars.get_global_value( "key2" ) == "Rapid Strike Test" ); + CHECK( globvars.get_global_value( "key3" ) == "50% moves, 66% damage" ); } TEST_CASE( "EOC_alive_test", "[eoc]" ) @@ -383,9 +383,9 @@ TEST_CASE( "EOC_alive_test", "[eoc]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); CHECK( effect_on_condition_EOC_alive_test->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "alive" ); + CHECK( globvars.get_global_value( "key1" ) == "alive" ); } TEST_CASE( "EOC_attack_test", "[eoc]" ) @@ -407,19 +407,19 @@ TEST_CASE( "EOC_context_test", "[eoc][math_parser]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_simple_global" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_nested_simple_global" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_non_nested_simple_global" ).empty() ); + REQUIRE( globvars.get_global_value( "simple_global" ).empty() ); + REQUIRE( globvars.get_global_value( "nested_simple_global" ).empty() ); + REQUIRE( globvars.get_global_value( "non_nested_simple_global" ).empty() ); CHECK( effect_on_condition_EOC_math_test_context->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_simple_global" ) ) == Approx( 12 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_nested_simple_global" ) ) == Approx( + CHECK( std::stod( globvars.get_global_value( "simple_global" ) ) == Approx( 12 ) ); + CHECK( std::stod( globvars.get_global_value( "nested_simple_global" ) ) == Approx( 7 ) ); // shouldn't be passed back up - CHECK( std::stod( globvars.get_global_value( "npctalk_var_non_nested_simple_global" ) ) == Approx( + CHECK( std::stod( globvars.get_global_value( "non_nested_simple_global" ) ) == Approx( 0 ) ); // value shouldn't exist in the original dialogue - CHECK( d.get_value( "npctalk_var_simple" ).empty() ); + CHECK( d.get_value( "simple" ).empty() ); } TEST_CASE( "EOC_option_test", "[eoc][math_parser]" ) @@ -432,13 +432,13 @@ TEST_CASE( "EOC_option_test", "[eoc][math_parser]" ) globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key1" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key2" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); CHECK( effect_on_condition_EOC_options_tests->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "ALWAYS" ); - CHECK( globvars.get_global_value( "npctalk_var_key2" ) == "4" ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ) == "1" ); + CHECK( globvars.get_global_value( "key1" ) == "ALWAYS" ); + CHECK( globvars.get_global_value( "key2" ) == "4" ); + CHECK( globvars.get_global_value( "key3" ) == "1" ); } TEST_CASE( "EOC_mutator_test", "[eoc][math_parser]" ) @@ -450,11 +450,11 @@ TEST_CASE( "EOC_mutator_test", "[eoc][math_parser]" ) 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() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "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" ); + CHECK( globvars.get_global_value( "key1" ) == "zombie" ); + CHECK( globvars.get_global_value( "key2" ) == "zombie" ); } TEST_CASE( "EOC_math_addiction", "[eoc][math_parser]" ) @@ -466,16 +466,16 @@ TEST_CASE( "EOC_math_addiction", "[eoc][math_parser]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key_add_intensity" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_add_turn" ).empty() ); + REQUIRE( globvars.get_global_value( "key_add_intensity" ).empty() ); + REQUIRE( globvars.get_global_value( "key_add_turn" ).empty() ); CHECK( effect_on_condition_EOC_math_addiction_setup->activate( d ) ); // Finish drinking complete_activity( get_avatar() ); CHECK( effect_on_condition_EOC_math_addiction_check->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_add_intensity" ) == "1" ); - CHECK( globvars.get_global_value( "npctalk_var_key_add_turn" ) == "3600" ); + CHECK( globvars.get_global_value( "key_add_intensity" ) == "1" ); + CHECK( globvars.get_global_value( "key_add_turn" ) == "3600" ); } TEST_CASE( "EOC_math_armor", "[eoc][math_parser]" ) @@ -489,13 +489,13 @@ TEST_CASE( "EOC_math_armor", "[eoc][math_parser]" ) 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() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); CHECK( effect_on_condition_EOC_math_armor->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 4 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key2" ) ) == Approx( 9 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key3" ) ) == Approx( 0 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 4 ) ); + CHECK( std::stod( globvars.get_global_value( "key2" ) ) == Approx( 9 ) ); + CHECK( std::stod( globvars.get_global_value( "key3" ) ) == Approx( 0 ) ); } TEST_CASE( "EOC_math_field", "[eoc][math_parser]" ) @@ -510,11 +510,11 @@ TEST_CASE( "EOC_math_field", "[eoc][math_parser]" ) get_map().add_field( get_avatar().pos_bub(), fd_blood, 3 ); get_map().add_field( get_avatar().pos_bub() + point_south, fd_blood_insect, 3 ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_field_strength" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_field_strength_north" ).empty() ); + REQUIRE( globvars.get_global_value( "key_field_strength" ).empty() ); + REQUIRE( globvars.get_global_value( "key_field_strength_north" ).empty() ); CHECK( effect_on_condition_EOC_math_field->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_field_strength" ) == "3" ); - CHECK( globvars.get_global_value( "npctalk_var_key_field_strength_north" ) == "3" ); + CHECK( globvars.get_global_value( "key_field_strength" ) == "3" ); + CHECK( globvars.get_global_value( "key_field_strength_north" ) == "3" ); } TEST_CASE( "EOC_math_item", "[eoc][math_parser]" ) @@ -526,11 +526,11 @@ TEST_CASE( "EOC_math_item", "[eoc][math_parser]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key_item_count" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_charge_count" ).empty() ); + REQUIRE( globvars.get_global_value( "key_item_count" ).empty() ); + REQUIRE( globvars.get_global_value( "key_charge_count" ).empty() ); CHECK( effect_on_condition_EOC_math_item_count->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_item_count" ) == "2" ); - CHECK( globvars.get_global_value( "npctalk_var_key_charge_count" ) == "32" ); + CHECK( globvars.get_global_value( "key_item_count" ) == "2" ); + CHECK( globvars.get_global_value( "key_charge_count" ) == "32" ); } TEST_CASE( "EOC_math_proficiency", "[eoc][math_parser]" ) @@ -542,23 +542,23 @@ TEST_CASE( "EOC_math_proficiency", "[eoc][math_parser]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key_total_time_required" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_time_spent_50" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_percent_50" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_percent_50_turn" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_permille_50" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_permille_50_turn" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_time_left_50" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_time_left_50_turn" ).empty() ); + REQUIRE( globvars.get_global_value( "key_total_time_required" ).empty() ); + REQUIRE( globvars.get_global_value( "key_time_spent_50" ).empty() ); + REQUIRE( globvars.get_global_value( "key_percent_50" ).empty() ); + REQUIRE( globvars.get_global_value( "key_percent_50_turn" ).empty() ); + REQUIRE( globvars.get_global_value( "key_permille_50" ).empty() ); + REQUIRE( globvars.get_global_value( "key_permille_50_turn" ).empty() ); + REQUIRE( globvars.get_global_value( "key_time_left_50" ).empty() ); + REQUIRE( globvars.get_global_value( "key_time_left_50_turn" ).empty() ); CHECK( effect_on_condition_EOC_math_proficiency->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_total_time_required" ) == "86400" ); - CHECK( globvars.get_global_value( "npctalk_var_key_time_spent_50" ) == "50" ); - CHECK( globvars.get_global_value( "npctalk_var_key_percent_50" ) == "50" ); - CHECK( globvars.get_global_value( "npctalk_var_key_percent_50_turn" ) == "43200" ); - CHECK( globvars.get_global_value( "npctalk_var_key_permille_50" ) == "50" ); - CHECK( globvars.get_global_value( "npctalk_var_key_permille_50_turn" ) == "4320" ); - CHECK( globvars.get_global_value( "npctalk_var_key_time_left_50" ) == "50" ); - CHECK( globvars.get_global_value( "npctalk_var_key_time_left_50_turn" ) == "86350" ); + CHECK( globvars.get_global_value( "key_total_time_required" ) == "86400" ); + CHECK( globvars.get_global_value( "key_time_spent_50" ) == "50" ); + CHECK( globvars.get_global_value( "key_percent_50" ) == "50" ); + CHECK( globvars.get_global_value( "key_percent_50_turn" ) == "43200" ); + CHECK( globvars.get_global_value( "key_permille_50" ) == "50" ); + CHECK( globvars.get_global_value( "key_permille_50_turn" ) == "4320" ); + CHECK( globvars.get_global_value( "key_time_left_50" ) == "50" ); + CHECK( globvars.get_global_value( "key_time_left_50_turn" ) == "86350" ); } TEST_CASE( "EOC_math_spell", "[eoc][math_parser]" ) @@ -570,17 +570,17 @@ TEST_CASE( "EOC_math_spell", "[eoc][math_parser]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key_spell_level" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_highest_spell_level" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_school_level_test_trait" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_spell_count" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key_spell_count_test_trait" ).empty() ); + REQUIRE( globvars.get_global_value( "key_spell_level" ).empty() ); + REQUIRE( globvars.get_global_value( "key_highest_spell_level" ).empty() ); + REQUIRE( globvars.get_global_value( "key_school_level_test_trait" ).empty() ); + REQUIRE( globvars.get_global_value( "key_spell_count" ).empty() ); + REQUIRE( globvars.get_global_value( "key_spell_count_test_trait" ).empty() ); CHECK( effect_on_condition_EOC_math_spell->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_spell_level" ) == "1" ); - CHECK( globvars.get_global_value( "npctalk_var_key_highest_spell_level" ) == "10" ); - CHECK( globvars.get_global_value( "npctalk_var_key_school_level_test_trait" ) == "1" ); - CHECK( globvars.get_global_value( "npctalk_var_key_spell_count" ) == "2" ); - CHECK( globvars.get_global_value( "npctalk_var_key_spell_count_test_trait" ) == "1" ); + CHECK( globvars.get_global_value( "key_spell_level" ) == "1" ); + CHECK( globvars.get_global_value( "key_highest_spell_level" ) == "10" ); + CHECK( globvars.get_global_value( "key_school_level_test_trait" ) == "1" ); + CHECK( globvars.get_global_value( "key_spell_count" ) == "2" ); + CHECK( globvars.get_global_value( "key_spell_count_test_trait" ) == "1" ); get_avatar().magic->evaluate_opens_spellbook_data(); @@ -601,31 +601,31 @@ TEST_CASE( "EOC_mutation_test", "[eoc][mutations]" ) globvars.clear_global_values(); me.toggle_trait( trait_process_mutation_two ); me.activate_mutation( trait_process_mutation_two ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_test_val" ) ) == Approx( + CHECK( std::stod( globvars.get_global_value( "test_val" ) ) == Approx( 1 ) ); - CHECK( globvars.get_global_value( "npctalk_var_context_test" ) == "process_mutation_two" ); + CHECK( globvars.get_global_value( "context_test" ) == "process_mutation_two" ); // test process globvars.clear_global_values(); me.suffer(); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_test_val" ) ) == Approx( + CHECK( std::stod( globvars.get_global_value( "test_val" ) ) == Approx( 1 ) ); - CHECK( globvars.get_global_value( "npctalk_var_context_test" ) == "process_mutation_two" ); + CHECK( globvars.get_global_value( "context_test" ) == "process_mutation_two" ); // test deactivate globvars.clear_global_values(); me.deactivate_mutation( trait_process_mutation_two ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_test_val" ) ) == Approx( + CHECK( std::stod( globvars.get_global_value( "test_val" ) ) == Approx( 1 ) ); - CHECK( globvars.get_global_value( "npctalk_var_context_test" ) == "process_mutation_two" ); + CHECK( globvars.get_global_value( "context_test" ) == "process_mutation_two" ); // more complex test globvars.clear_global_values(); me.toggle_trait( trait_process_mutation ); effect_on_condition_EOC_activate_mutation_to_start_test->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_test_val" ) ) == Approx( + CHECK( std::stod( globvars.get_global_value( "test_val" ) ) == Approx( 1 ) ); - CHECK( globvars.get_global_value( "npctalk_var_context_test" ) == "process_mutation" ); + CHECK( globvars.get_global_value( "context_test" ) == "process_mutation" ); } TEST_CASE( "EOC_purifiability", "[eoc][mutations]" ) @@ -672,25 +672,25 @@ TEST_CASE( "EOC_monsters_nearby", "[eoc][math_parser]" ) g->place_critter_at( mon_zombie_smoker, a.pos() + tripoint{ 10, 0, 0 } ); g->place_critter_at( mon_zombie_smoker, a.pos() + tripoint{ 11, 0, 0 } ); - REQUIRE( globvars.get_global_value( "npctalk_var_mons" ).empty() ); + REQUIRE( globvars.get_global_value( "mons" ).empty() ); dialogue d( get_talker_for( get_avatar() ), std::make_unique() ); REQUIRE( effect_on_condition_EOC_mon_nearby_test->activate( d ) ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_mons" ) ) == 8 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_triffs" ) ) == 1 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_group" ) ) == 4 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zombs" ) ) == 2 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zombs_friends" ) ) == 0 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zombs_both" ) ) == 2 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zplust" ) ) == 5 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zplust_adj" ) ) == 2 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_smoks" ) ) == 1 ); + CHECK( std::stoi( globvars.get_global_value( "mons" ) ) == 8 ); + CHECK( std::stoi( globvars.get_global_value( "triffs" ) ) == 1 ); + CHECK( std::stoi( globvars.get_global_value( "group" ) ) == 4 ); + CHECK( std::stoi( globvars.get_global_value( "zombs" ) ) == 2 ); + CHECK( std::stoi( globvars.get_global_value( "zombs_friends" ) ) == 0 ); + CHECK( std::stoi( globvars.get_global_value( "zombs_both" ) ) == 2 ); + CHECK( std::stoi( globvars.get_global_value( "zplust" ) ) == 5 ); + CHECK( std::stoi( globvars.get_global_value( "zplust_adj" ) ) == 2 ); + CHECK( std::stoi( globvars.get_global_value( "smoks" ) ) == 1 ); friendo->make_friendly(); REQUIRE( effect_on_condition_EOC_mon_nearby_test->activate( d ) ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zombs" ) ) == 1 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zombs_friends" ) ) == 1 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_zombs_both" ) ) == 2 ); + CHECK( std::stoi( globvars.get_global_value( "zombs" ) ) == 1 ); + CHECK( std::stoi( globvars.get_global_value( "zombs_friends" ) ) == 1 ); + CHECK( std::stoi( globvars.get_global_value( "zombs_both" ) ) == 2 ); } TEST_CASE( "EOC_activity_ongoing", "[eoc][timed_event]" ) @@ -702,7 +702,7 @@ TEST_CASE( "EOC_activity_ongoing", "[eoc][timed_event]" ) complete_activity( get_avatar() ); // been going for 3 whole seconds should have incremented 3 times - CHECK( stoi( get_avatar().get_value( "npctalk_var_activitiy_incrementer" ) ) == 3 ); + CHECK( stoi( get_avatar().get_value( "activitiy_incrementer" ) ) == 3 ); } TEST_CASE( "EOC_stored_condition_test", "[eoc]" ) @@ -714,30 +714,30 @@ TEST_CASE( "EOC_stored_condition_test", "[eoc]" ) 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() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); - d.set_value( "npctalk_var_context", "0" ); + d.set_value( "context", "0" ); // running with a value of 0 will have the conditional evaluate to 0 CHECK( effect_on_condition_EOC_stored_condition_test->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 0 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key2" ) ) == Approx( 0 ) ); - CHECK( std::stod( d.get_value( "npctalk_var_context" ) ) == Approx( 0 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 0 ) ); + CHECK( std::stod( globvars.get_global_value( "key2" ) ) == Approx( 0 ) ); + CHECK( std::stod( d.get_value( "context" ) ) == Approx( 0 ) ); // try again with a different value globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key1" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); - d.set_value( "npctalk_var_context", "10" ); + d.set_value( "context", "10" ); // running with a value greater than 1 will have the conditional evaluate to 1 CHECK( effect_on_condition_EOC_stored_condition_test->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 1 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key2" ) ) == Approx( 1 ) ); - CHECK( std::stod( d.get_value( "npctalk_var_context" ) ) == Approx( 10 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 1 ) ); + CHECK( std::stod( globvars.get_global_value( "key2" ) ) == Approx( 1 ) ); + CHECK( std::stod( d.get_value( "context" ) ) == Approx( 10 ) ); } @@ -795,52 +795,52 @@ TEST_CASE( "EOC_meta_test", "[eoc]" ) globvars.clear_global_values(); CHECK( effect_on_condition_EOC_meta_test_talker_type->activate( d_avatar ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_avatar" ) == "yes" ); - CHECK( globvars.get_global_value( "npctalk_var_key_npc" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_character" ) == "yes" ); - CHECK( globvars.get_global_value( "npctalk_var_key_monster" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_item" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_furniture" ).empty() ); + CHECK( globvars.get_global_value( "key_avatar" ) == "yes" ); + CHECK( globvars.get_global_value( "key_npc" ).empty() ); + CHECK( globvars.get_global_value( "key_character" ) == "yes" ); + CHECK( globvars.get_global_value( "key_monster" ).empty() ); + CHECK( globvars.get_global_value( "key_item" ).empty() ); + CHECK( globvars.get_global_value( "key_furniture" ).empty() ); globvars.clear_global_values(); CHECK( effect_on_condition_EOC_meta_test_talker_type->activate( d_npc ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_avatar" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_npc" ) == "yes" ); - CHECK( globvars.get_global_value( "npctalk_var_key_character" ) == "yes" ); - CHECK( globvars.get_global_value( "npctalk_var_key_monster" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_item" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_furniture" ).empty() ); + CHECK( globvars.get_global_value( "key_avatar" ).empty() ); + CHECK( globvars.get_global_value( "key_npc" ) == "yes" ); + CHECK( globvars.get_global_value( "key_character" ) == "yes" ); + CHECK( globvars.get_global_value( "key_monster" ).empty() ); + CHECK( globvars.get_global_value( "key_item" ).empty() ); + CHECK( globvars.get_global_value( "key_furniture" ).empty() ); globvars.clear_global_values(); CHECK( effect_on_condition_EOC_meta_test_talker_type->activate( d_monster ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_avatar" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_npc" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_character" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_monster" ) == "yes" ); - CHECK( globvars.get_global_value( "npctalk_var_key_item" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_furniture" ).empty() ); + CHECK( globvars.get_global_value( "key_avatar" ).empty() ); + CHECK( globvars.get_global_value( "key_npc" ).empty() ); + CHECK( globvars.get_global_value( "key_character" ).empty() ); + CHECK( globvars.get_global_value( "key_monster" ) == "yes" ); + CHECK( globvars.get_global_value( "key_item" ).empty() ); + CHECK( globvars.get_global_value( "key_furniture" ).empty() ); globvars.clear_global_values(); CHECK( effect_on_condition_EOC_meta_test_talker_type->activate( d_item ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_avatar" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_npc" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_character" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_monster" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_item" ) == "yes" ); - CHECK( globvars.get_global_value( "npctalk_var_key_furniture" ).empty() ); + CHECK( globvars.get_global_value( "key_avatar" ).empty() ); + CHECK( globvars.get_global_value( "key_npc" ).empty() ); + CHECK( globvars.get_global_value( "key_character" ).empty() ); + CHECK( globvars.get_global_value( "key_monster" ).empty() ); + CHECK( globvars.get_global_value( "key_item" ) == "yes" ); + CHECK( globvars.get_global_value( "key_furniture" ).empty() ); globvars.clear_global_values(); CHECK( effect_on_condition_EOC_meta_test_talker_type->activate( d_furniture ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_avatar" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_npc" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_character" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_monster" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_item" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key_furniture" ) == "yes" ); + CHECK( globvars.get_global_value( "key_avatar" ).empty() ); + CHECK( globvars.get_global_value( "key_npc" ).empty() ); + CHECK( globvars.get_global_value( "key_character" ).empty() ); + CHECK( globvars.get_global_value( "key_monster" ).empty() ); + CHECK( globvars.get_global_value( "key_item" ).empty() ); + CHECK( globvars.get_global_value( "key_furniture" ) == "yes" ); } TEST_CASE( "EOC_increment_var_var", "[eoc]" ) @@ -852,15 +852,15 @@ TEST_CASE( "EOC_increment_var_var", "[eoc]" ) 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() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); CHECK( effect_on_condition_EOC_increment_var_var->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 5 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key2" ) ) == Approx( 10 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_global_u" ) ) == Approx( 6 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_global_context" ) ) == Approx( 4 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_global_nested" ) ) == Approx( 2 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 5 ) ); + CHECK( std::stod( globvars.get_global_value( "key2" ) ) == Approx( 10 ) ); + CHECK( std::stod( globvars.get_global_value( "global_u" ) ) == Approx( 6 ) ); + CHECK( std::stod( globvars.get_global_value( "global_context" ) ) == Approx( 4 ) ); + CHECK( std::stod( globvars.get_global_value( "global_nested" ) ) == Approx( 2 ) ); } TEST_CASE( "EOC_string_var_var", "[eoc]" ) @@ -872,16 +872,16 @@ TEST_CASE( "EOC_string_var_var", "[eoc]" ) 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() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key4" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key4" ).empty() ); CHECK( effect_on_condition_EOC_string_var_var->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "Works_global" ); - CHECK( globvars.get_global_value( "npctalk_var_key2" ) == "Works_context" ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ) == "Works_u" ); - CHECK( globvars.get_global_value( "npctalk_var_key4" ) == "Works_npc" ); + CHECK( globvars.get_global_value( "key1" ) == "Works_global" ); + CHECK( globvars.get_global_value( "key2" ) == "Works_context" ); + CHECK( globvars.get_global_value( "key3" ) == "Works_u" ); + CHECK( globvars.get_global_value( "key4" ) == "Works_npc" ); } TEST_CASE( "EOC_run_with_test", "[eoc]" ) @@ -893,19 +893,19 @@ TEST_CASE( "EOC_run_with_test", "[eoc]" ) 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() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); CHECK( effect_on_condition_EOC_run_with_test->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 1 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key2" ) ) == Approx( 2 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key3" ) ) == Approx( 3 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 1 ) ); + CHECK( std::stod( globvars.get_global_value( "key2" ) ) == Approx( 2 ) ); + CHECK( std::stod( globvars.get_global_value( "key3" ) ) == Approx( 3 ) ); // value shouldn't exist in the original dialogue - CHECK( d.get_value( "npctalk_var_key" ).empty() ); - CHECK( d.get_value( "npctalk_var_key2" ).empty() ); - CHECK( d.get_value( "npctalk_var_key3" ).empty() ); + CHECK( d.get_value( "key" ).empty() ); + CHECK( d.get_value( "key2" ).empty() ); + CHECK( d.get_value( "key3" ).empty() ); } TEST_CASE( "EOC_run_until_test", "[eoc]" ) @@ -917,10 +917,10 @@ TEST_CASE( "EOC_run_until_test", "[eoc]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); CHECK( effect_on_condition_EOC_run_until_test->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 10000 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 10000 ) ); } TEST_CASE( "EOC_run_with_test_expects", "[eoc]" ) @@ -932,23 +932,23 @@ TEST_CASE( "EOC_run_with_test_expects", "[eoc]" ) 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() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); CHECK( capture_debugmsg_during( [&]() { effect_on_condition_EOC_run_with_test_expects_fail->activate( d ); } ) == "Missing required variables: key1, key2, key3, " ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key2" ).empty() ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + CHECK( globvars.get_global_value( "key1" ).empty() ); + CHECK( globvars.get_global_value( "key2" ).empty() ); + CHECK( globvars.get_global_value( "key3" ).empty() ); globvars.clear_global_values(); effect_on_condition_EOC_run_with_test_expects_pass->activate( d ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 1 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key2" ) ) == Approx( 2 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key3" ) ) == Approx( 3 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 1 ) ); + CHECK( std::stod( globvars.get_global_value( "key2" ) ) == Approx( 2 ) ); + CHECK( std::stod( globvars.get_global_value( "key3" ) ) == Approx( 3 ) ); } TEST_CASE( "EOC_run_with_test_queue", "[eoc]" ) @@ -960,23 +960,23 @@ TEST_CASE( "EOC_run_with_test_queue", "[eoc]" ) 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() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); CHECK( effect_on_condition_EOC_run_with_test_queued->activate( d ) ); set_time( calendar::turn + 2_seconds ); effect_on_conditions::process_effect_on_conditions( get_avatar() ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key1" ) ) == Approx( 1 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key2" ) ) == Approx( 2 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_key3" ) ) == Approx( 3 ) ); + CHECK( std::stod( globvars.get_global_value( "key1" ) ) == Approx( 1 ) ); + CHECK( std::stod( globvars.get_global_value( "key2" ) ) == Approx( 2 ) ); + CHECK( std::stod( globvars.get_global_value( "key3" ) ) == Approx( 3 ) ); // value shouldn't exist in the original dialogue - CHECK( d.get_value( "npctalk_var_key" ).empty() ); - CHECK( d.get_value( "npctalk_var_key2" ).empty() ); - CHECK( d.get_value( "npctalk_var_key3" ).empty() ); + CHECK( d.get_value( "key" ).empty() ); + CHECK( d.get_value( "key2" ).empty() ); + CHECK( d.get_value( "key3" ).empty() ); } TEST_CASE( "EOC_run_inv_test", "[eoc]" ) @@ -991,7 +991,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) effect_on_condition_EOC_run_inv_prepare->activate( d ); std::vector items_before = get_avatar().items_with( []( const item & it ) { - return it.get_var( "npctalk_var_general_run_inv_test_key1" ).empty(); + return it.get_var( "general_run_inv_test_key1" ).empty(); } ); REQUIRE( items_before.size() == 4 ); @@ -1000,7 +1000,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) CHECK( effect_on_condition_EOC_run_inv_test1->activate( d ) ); std::vector items_after = get_avatar().items_with( []( const item & it ) { - return it.get_var( "npctalk_var_general_run_inv_test_key1" ) == "yes"; + return it.get_var( "general_run_inv_test_key1" ) == "yes"; } ); CHECK( items_after.size() == 4 ); @@ -1009,7 +1009,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) CHECK( effect_on_condition_EOC_run_inv_test2->activate( d ) ); items_after = get_avatar().items_with( []( const item & it ) { - return it.get_var( "npctalk_var_general_run_inv_test_key2" ) == "yes"; + return it.get_var( "general_run_inv_test_key2" ) == "yes"; } ); CHECK( items_after.size() == 1 ); @@ -1018,7 +1018,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) CHECK( effect_on_condition_EOC_run_inv_test3->activate( d ) ); items_after = get_avatar().items_with( []( const item & it ) { - return it.get_var( "npctalk_var_general_run_inv_test_key3" ) == "yes"; + return it.get_var( "general_run_inv_test_key3" ) == "yes"; } ); CHECK( items_after.empty() ); @@ -1030,7 +1030,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) CHECK( effect_on_condition_EOC_run_inv_test3->activate( d ) ); items_after = get_avatar().items_with( []( const item & it ) { - return it.get_var( "npctalk_var_general_run_inv_test_key3" ) == "yes"; + return it.get_var( "general_run_inv_test_key3" ) == "yes"; } ); CHECK( items_after.size() == 1 ); @@ -1039,7 +1039,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) CHECK( effect_on_condition_EOC_run_inv_test4->activate( d ) ); items_after = get_avatar().items_with( []( const item & it ) { - return it.get_var( "npctalk_var_general_run_inv_test_key4" ) == "yes"; + return it.get_var( "general_run_inv_test_key4" ) == "yes"; } ); CHECK( items_after.size() == 1 ); @@ -1048,7 +1048,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) 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"; + return it.get_var( "general_run_inv_test_key5" ) == "yes"; } ); CHECK( items_after.size() == 3 ); @@ -1057,7 +1057,7 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) CHECK( effect_on_condition_EOC_item_flag_test->activate( d ) ); items_after = get_avatar().items_with( []( const item & it ) { - return it.get_var( "npctalk_var_general_run_inv_test_is_filthy" ) == "yes"; + return it.get_var( "general_run_inv_test_is_filthy" ) == "yes"; } ); CHECK( items_after.size() == 1 ); @@ -1096,10 +1096,10 @@ TEST_CASE( "EOC_run_inv_test", "[eoc]" ) 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 ) ); + CHECK( std::stod( get_avatar().get_value( "key1" ) ) == Approx( 27 ) ); + CHECK( std::stod( get_avatar().get_value( "key2" ) ) == Approx( 2 ) ); + CHECK( std::stod( check_item.get_var( "key1" ) ) == Approx( 27 ) ); + CHECK( std::stod( check_item.get_var( "key2" ) ) == Approx( 2 ) ); } TEST_CASE( "math_weapon_damage", "[eoc]" ) @@ -1123,10 +1123,10 @@ TEST_CASE( "math_weapon_damage", "[eoc]" ) int const bullet_damage = myweapon.gun_damage().type_damage( STATIC( damage_type_id( "bullet" ) ) ); CAPTURE( myweapon.typeId().c_str() ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_mymelee" ) ) == total_damage ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_mymelee_bash" ) ) == bash_damage ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_mygun" ) ) == gun_damage ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_mygun_bullet" ) ) == bullet_damage ); + CHECK( std::stoi( globvars.get_global_value( "mymelee" ) ) == total_damage ); + CHECK( std::stoi( globvars.get_global_value( "mymelee_bash" ) ) == bash_damage ); + CHECK( std::stoi( globvars.get_global_value( "mygun" ) ) == gun_damage ); + CHECK( std::stoi( globvars.get_global_value( "mygun_bullet" ) ) == bullet_damage ); } TEST_CASE( "EOC_event_test", "[eoc]" ) @@ -1138,51 +1138,51 @@ TEST_CASE( "EOC_event_test", "[eoc]" ) 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() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key2" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); // character_casts_spell spell temp_spell( spell_test_eoc_spell ); temp_spell.set_level( get_avatar(), 5 ); temp_spell.cast_all_effects( get_avatar(), tripoint_bub_ms() ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "test_eoc_spell" ); - CHECK( globvars.get_global_value( "npctalk_var_key2" ) == "test_trait" ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ) == "5" ); - CHECK( globvars.get_global_value( "npctalk_var_key4" ) == "150" ); - CHECK( globvars.get_global_value( "npctalk_var_key5" ) == "100" ); - CHECK( globvars.get_global_value( "npctalk_var_key6" ) == "45" ); + CHECK( globvars.get_global_value( "key1" ) == "test_eoc_spell" ); + CHECK( globvars.get_global_value( "key2" ) == "test_trait" ); + CHECK( globvars.get_global_value( "key3" ) == "5" ); + CHECK( globvars.get_global_value( "key4" ) == "150" ); + CHECK( globvars.get_global_value( "key5" ) == "100" ); + CHECK( globvars.get_global_value( "key6" ) == "45" ); // character_starts_activity globvars.clear_global_values(); get_avatar().assign_activity( ACT_GENERIC_EOC, 1 ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "ACT_GENERIC_EOC" ); - CHECK( globvars.get_global_value( "npctalk_var_key2" ) == "0" ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ) == "activity start" ); + CHECK( globvars.get_global_value( "key1" ) == "ACT_GENERIC_EOC" ); + CHECK( globvars.get_global_value( "key2" ) == "0" ); + CHECK( globvars.get_global_value( "key3" ) == "activity start" ); // character_finished_activity get_avatar().cancel_activity(); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "ACT_GENERIC_EOC" ); - CHECK( globvars.get_global_value( "npctalk_var_key2" ) == "1" ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ) == "activity finished" ); + CHECK( globvars.get_global_value( "key1" ) == "ACT_GENERIC_EOC" ); + CHECK( globvars.get_global_value( "key2" ) == "1" ); + CHECK( globvars.get_global_value( "key3" ) == "activity finished" ); // character_wields_item item weapon_item( itype_test_knife_combat ); get_avatar().wield( weapon_item ); item_location weapon = get_avatar().get_wielded_item(); - CHECK( get_avatar().get_value( "npctalk_var_test_event_last_event" ) == "character_wields_item" ); - CHECK( weapon->get_var( "npctalk_var_test_event_last_event" ) == "character_wields_item" ); + CHECK( get_avatar().get_value( "test_event_last_event" ) == "character_wields_item" ); + CHECK( weapon->get_var( "test_event_last_event" ) == "character_wields_item" ); // character_wears_item std::list::iterator armor = *get_avatar().worn.wear_item( get_avatar(), item( itype_backpack ), false, true, true ); - CHECK( get_avatar().get_value( "npctalk_var_test_event_last_event" ) == "character_wears_item" ); - CHECK( armor->get_var( "npctalk_var_test_event_last_event" ) == "character_wears_item" ); + CHECK( get_avatar().get_value( "test_event_last_event" ) == "character_wears_item" ); + CHECK( armor->get_var( "test_event_last_event" ) == "character_wears_item" ); } TEST_CASE( "EOC_combat_event_test", "[eoc]" ) @@ -1200,24 +1200,24 @@ TEST_CASE( "EOC_combat_event_test", "[eoc]" ) get_avatar().wield( weapon_item ); get_avatar().melee_attack( npc_dst_melee, false ); - CHECK( get_avatar().get_value( "npctalk_var_test_event_last_event" ) == + CHECK( get_avatar().get_value( "test_event_last_event" ) == "character_melee_attacks_character" ); - CHECK( npc_dst_melee.get_value( "npctalk_var_test_event_last_event" ) == + CHECK( npc_dst_melee.get_value( "test_event_last_event" ) == "character_melee_attacks_character" ); - CHECK( globvars.get_global_value( "npctalk_var_weapon" ) == "test_knife_combat" ); - CHECK( globvars.get_global_value( "npctalk_var_victim_name" ) == npc_dst_melee.get_name() ); + CHECK( globvars.get_global_value( "weapon" ) == "test_knife_combat" ); + CHECK( globvars.get_global_value( "victim_name" ) == npc_dst_melee.get_name() ); // character_melee_attacks_monster clear_map(); monster &mon_dst_melee = spawn_test_monster( "mon_zombie", get_avatar().pos_bub() + tripoint_east ); get_avatar().melee_attack( mon_dst_melee, false ); - CHECK( get_avatar().get_value( "npctalk_var_test_event_last_event" ) == + CHECK( get_avatar().get_value( "test_event_last_event" ) == "character_melee_attacks_monster" ); - CHECK( mon_dst_melee.get_value( "npctalk_var_test_event_last_event" ) == + CHECK( mon_dst_melee.get_value( "test_event_last_event" ) == "character_melee_attacks_monster" ); - CHECK( globvars.get_global_value( "npctalk_var_weapon" ) == "test_knife_combat" ); - CHECK( globvars.get_global_value( "npctalk_var_victim_type" ) == "mon_zombie" ); + CHECK( globvars.get_global_value( "weapon" ) == "test_knife_combat" ); + CHECK( globvars.get_global_value( "victim_type" ) == "mon_zombie" ); // character_ranged_attacks_character const tripoint_bub_ms target_pos = get_avatar().pos_bub() + point_east; @@ -1228,17 +1228,17 @@ TEST_CASE( "EOC_combat_event_test", "[eoc]" ) arm_shooter( get_avatar(), "shotgun_s" ); get_avatar().recoil = 0; get_avatar().fire_gun( target_pos, 1, *get_avatar().get_wielded_item() ); - if( !npc_dst_ranged.get_value( "npctalk_var_test_event_last_event" ).empty() ) { + if( !npc_dst_ranged.get_value( "test_event_last_event" ).empty() ) { break; } } - CHECK( get_avatar().get_value( "npctalk_var_test_event_last_event" ) == + CHECK( get_avatar().get_value( "test_event_last_event" ) == "character_ranged_attacks_character" ); - CHECK( npc_dst_ranged.get_value( "npctalk_var_test_event_last_event" ) == + CHECK( npc_dst_ranged.get_value( "test_event_last_event" ) == "character_ranged_attacks_character" ); - CHECK( globvars.get_global_value( "npctalk_var_weapon" ) == "shotgun_s" ); - CHECK( globvars.get_global_value( "npctalk_var_victim_name" ) == npc_dst_ranged.get_name() ); + CHECK( globvars.get_global_value( "weapon" ) == "shotgun_s" ); + CHECK( globvars.get_global_value( "victim_name" ) == npc_dst_ranged.get_name() ); // character_ranged_attacks_monster clear_map(); @@ -1248,26 +1248,26 @@ TEST_CASE( "EOC_combat_event_test", "[eoc]" ) arm_shooter( get_avatar(), "shotgun_s" ); get_avatar().recoil = 0; get_avatar().fire_gun( mon_dst_ranged.pos_bub(), 1, *get_avatar().get_wielded_item() ); - if( !mon_dst_ranged.get_value( "npctalk_var_test_event_last_event" ).empty() ) { + if( !mon_dst_ranged.get_value( "test_event_last_event" ).empty() ) { break; } } - CHECK( get_avatar().get_value( "npctalk_var_test_event_last_event" ) == + CHECK( get_avatar().get_value( "test_event_last_event" ) == "character_ranged_attacks_monster" ); - CHECK( mon_dst_ranged.get_value( "npctalk_var_test_event_last_event" ) == + CHECK( mon_dst_ranged.get_value( "test_event_last_event" ) == "character_ranged_attacks_monster" ); - CHECK( globvars.get_global_value( "npctalk_var_weapon" ) == "shotgun_s" ); - CHECK( globvars.get_global_value( "npctalk_var_victim_type" ) == "mon_zombie" ); + CHECK( globvars.get_global_value( "weapon" ) == "shotgun_s" ); + CHECK( globvars.get_global_value( "victim_type" ) == "mon_zombie" ); // character_kills_monster clear_map(); monster &victim = spawn_test_monster( "mon_zombie", target_pos ); victim.die( &get_avatar() ); - CHECK( get_avatar().get_value( "npctalk_var_test_event_last_event" ) == "character_kills_monster" ); - CHECK( globvars.get_global_value( "npctalk_var_victim_type" ) == "mon_zombie" ); - CHECK( globvars.get_global_value( "npctalk_var_test_exp" ) == "4" ); + CHECK( get_avatar().get_value( "test_event_last_event" ) == "character_kills_monster" ); + CHECK( globvars.get_global_value( "victim_type" ) == "mon_zombie" ); + CHECK( globvars.get_global_value( "test_exp" ) == "4" ); } TEST_CASE( "EOC_spell_exp", "[eoc]" ) @@ -1279,13 +1279,13 @@ TEST_CASE( "EOC_spell_exp", "[eoc]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key1" ).empty() ); + REQUIRE( globvars.get_global_value( "key1" ).empty() ); get_avatar().magic->learn_spell( "test_eoc_spell", get_avatar(), true ); CHECK( effect_on_condition_EOC_math_spell_xp->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "1000" ); + CHECK( globvars.get_global_value( "key1" ) == "1000" ); } TEST_CASE( "EOC_recipe_test", "[eoc]" ) @@ -1321,16 +1321,16 @@ TEST_CASE( "EOC_map_test", "[eoc]" ) m.furn_set( tgt, furn_test_f_eoc ); m.furn( tgt )->examine( get_avatar(), tgt ); - CHECK( globvars.get_global_value( "npctalk_var_this" ) == "test_f_eoc" ); - CHECK( globvars.get_global_value( "npctalk_var_pos" ) == m.getglobal( tgt ).to_string() ); + CHECK( globvars.get_global_value( "this" ) == "test_f_eoc" ); + CHECK( globvars.get_global_value( "pos" ) == m.getglobal( tgt ).to_string() ); const tripoint_bub_ms target_pos = get_avatar().pos_bub() + point_east * 10; npc &npc_dst = spawn_npc( target_pos.xy(), "thug" ); dialogue d( get_talker_for( get_avatar() ), get_talker_for( npc_dst ) ); CHECK( effect_on_condition_EOC_map_test->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key_distance_loc" ) == "14" ); - CHECK( globvars.get_global_value( "npctalk_var_key_distance_npc" ) == "10" ); + CHECK( globvars.get_global_value( "key_distance_loc" ) == "14" ); + CHECK( globvars.get_global_value( "key_distance_npc" ) == "10" ); } TEST_CASE( "EOC_loc_relative_test", "[eoc]" ) @@ -1354,9 +1354,9 @@ TEST_CASE( "EOC_loc_relative_test", "[eoc]" ) CHECK( effect_on_condition_EOC_loc_relative_test->activate( d ) ); tripoint_abs_ms tmp_abs_a = tripoint_abs_ms( tripoint::from_string( - globvars.get_global_value( "npctalk_var_map_test_loc_a" ) ) ); + globvars.get_global_value( "map_test_loc_a" ) ) ); tripoint_abs_ms tmp_abs_b = tripoint_abs_ms( tripoint::from_string( - globvars.get_global_value( "npctalk_var_map_test_loc_b" ) ) ); + globvars.get_global_value( "map_test_loc_b" ) ) ); CHECK( m.bub_from_abs( tmp_abs_a ) == tripoint_bub_ms( 70, 70, 0 ) ); CHECK( m.bub_from_abs( tmp_abs_b ) == tripoint_bub_ms( 70, 60, 0 ) ); @@ -1401,17 +1401,17 @@ TEST_CASE( "EOC_string_test", "[eoc]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_key3" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_key4" ).empty() ); + REQUIRE( globvars.get_global_value( "key3" ).empty() ); + REQUIRE( globvars.get_global_value( "key4" ).empty() ); CHECK( effect_on_condition_EOC_string_test->activate( d ) ); - CHECK( globvars.get_global_value( "npctalk_var_key3" ) == " " ); - CHECK( globvars.get_global_value( "npctalk_var_key4" ) == "test1 test2" ); + CHECK( globvars.get_global_value( "key3" ) == " " ); + CHECK( globvars.get_global_value( "key4" ) == "test1 test2" ); CHECK( effect_on_condition_EOC_string_test_nest->activate( d ) ); - CHECK( get_avatar().get_value( "npctalk_var_key1" ) == "nest2" ); - CHECK( get_avatar().get_value( "npctalk_var_key2" ) == "nest3" ); - CHECK( get_avatar().get_value( "npctalk_var_key3" ) == "nest4" ); + CHECK( get_avatar().get_value( "key1" ) == "nest2" ); + CHECK( get_avatar().get_value( "key2" ) == "nest3" ); + CHECK( get_avatar().get_value( "key3" ) == "nest4" ); } TEST_CASE( "EOC_run_eocs", "[eoc]" ) @@ -1423,12 +1423,12 @@ TEST_CASE( "EOC_run_eocs", "[eoc]" ) global_variables &globvars = get_globals(); globvars.clear_global_values(); - REQUIRE( globvars.get_global_value( "npctalk_var_run_eocs_1" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_run_eocs_2" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_run_eocs_3" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_run_eocs_5" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_test_global_key_M" ).empty() ); - REQUIRE( globvars.get_global_value( "npctalk_var_test_global_key_N" ).empty() ); + REQUIRE( globvars.get_global_value( "run_eocs_1" ).empty() ); + REQUIRE( globvars.get_global_value( "run_eocs_2" ).empty() ); + REQUIRE( globvars.get_global_value( "run_eocs_3" ).empty() ); + REQUIRE( globvars.get_global_value( "run_eocs_5" ).empty() ); + REQUIRE( globvars.get_global_value( "test_global_key_M" ).empty() ); + REQUIRE( globvars.get_global_value( "test_global_key_N" ).empty() ); CHECK( effect_on_condition_run_eocs_1->activate( d ) ); CHECK( effect_on_condition_run_eocs_2->activate( d ) ); @@ -1436,21 +1436,21 @@ TEST_CASE( "EOC_run_eocs", "[eoc]" ) CHECK( effect_on_condition_run_eocs_5->activate( d ) ); CHECK( effect_on_condition_run_eocs_7->activate( d ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_run_eocs_1" ) ) == Approx( 2 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_run_eocs_2" ) ) == Approx( 20 ) ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_run_eocs_5" ) ) == Approx( 4 ) ); + CHECK( std::stod( globvars.get_global_value( "run_eocs_1" ) ) == Approx( 2 ) ); + CHECK( std::stod( globvars.get_global_value( "run_eocs_2" ) ) == Approx( 20 ) ); + CHECK( std::stod( globvars.get_global_value( "run_eocs_5" ) ) == Approx( 4 ) ); set_time( calendar::turn + 1_seconds ); effect_on_conditions::process_effect_on_conditions( get_avatar() ); - REQUIRE( globvars.get_global_value( "npctalk_var_run_eocs_3" ).empty() ); + REQUIRE( globvars.get_global_value( "run_eocs_3" ).empty() ); set_time( calendar::turn + 1_seconds ); effect_on_conditions::process_effect_on_conditions( get_avatar() ); - CHECK( std::stod( globvars.get_global_value( "npctalk_var_run_eocs_3" ) ) == Approx( 2 ) ); + CHECK( std::stod( globvars.get_global_value( "run_eocs_3" ) ) == Approx( 2 ) ); set_time( calendar::turn + 8_seconds ); effect_on_conditions::process_effect_on_conditions( get_avatar() ); - CHECK( globvars.get_global_value( "npctalk_var_test_global_key_M" ) == "test_context_value_M" ); - CHECK( globvars.get_global_value( "npctalk_var_test_global_key_N" ) == "test_context_value_N" ); + CHECK( globvars.get_global_value( "test_global_key_M" ) == "test_context_value_M" ); + CHECK( globvars.get_global_value( "test_global_key_N" ) == "test_context_value_N" ); globvars.clear_global_values(); avatar &u = get_avatar(); @@ -1472,31 +1472,31 @@ TEST_CASE( "EOC_run_eocs", "[eoc]" ) talker *alpha_talker = d2.actor( false ); talker *beta_talker = d2.actor( true ); - d2.set_value( "npctalk_var_alpha_var", "u" ); - d2.set_value( "npctalk_var_beta_var", "npc" ); + d2.set_value( "alpha_var", "u" ); + d2.set_value( "beta_var", "npc" ); CHECK( effect_on_condition_run_eocs_talker_mixes->activate( d2 ) ); - CHECK( globvars.get_global_value( "npctalk_var_alpha_name" ) == alpha_talker->get_name() ); - CHECK( globvars.get_global_value( "npctalk_var_beta_name" ) == beta_talker->get_name() ); + CHECK( globvars.get_global_value( "alpha_name" ) == alpha_talker->get_name() ); + CHECK( globvars.get_global_value( "beta_name" ) == beta_talker->get_name() ); - d2.set_value( "npctalk_var_alpha_var", "npc" ); - d2.set_value( "npctalk_var_beta_var", "u" ); + d2.set_value( "alpha_var", "npc" ); + d2.set_value( "beta_var", "u" ); CHECK( effect_on_condition_run_eocs_talker_mixes->activate( d2 ) ); - CHECK( globvars.get_global_value( "npctalk_var_alpha_name" ) == beta_talker->get_name() ); - CHECK( globvars.get_global_value( "npctalk_var_beta_name" ) == alpha_talker->get_name() ); + CHECK( globvars.get_global_value( "alpha_name" ) == beta_talker->get_name() ); + CHECK( globvars.get_global_value( "beta_name" ) == alpha_talker->get_name() ); - d2.set_value( "npctalk_var_alpha_var", "avatar" ); - d2.set_value( "npctalk_var_beta_var", std::to_string( guy->getID().get_value() ) ); + d2.set_value( "alpha_var", "avatar" ); + d2.set_value( "beta_var", std::to_string( guy->getID().get_value() ) ); CHECK( effect_on_condition_run_eocs_talker_mixes->activate( d2 ) ); - CHECK( globvars.get_global_value( "npctalk_var_alpha_name" ) == get_avatar().get_name() ); - CHECK( globvars.get_global_value( "npctalk_var_beta_name" ) == guy->get_name() ); + CHECK( globvars.get_global_value( "alpha_name" ) == get_avatar().get_name() ); + CHECK( globvars.get_global_value( "beta_name" ) == guy->get_name() ); - d2.set_value( "npctalk_var_alpha_var", std::string{} ); - d2.set_value( "npctalk_var_beta_var", std::string{} ); + d2.set_value( "alpha_var", std::string{} ); + d2.set_value( "beta_var", std::string{} ); CHECK( effect_on_condition_run_eocs_talker_mixes->activate( d2 ) ); - CHECK( globvars.get_global_value( "npctalk_var_alpha_name" ) == "mixin fail alpha" ); - CHECK( globvars.get_global_value( "npctalk_var_beta_name" ) == "mixin fail beta" ); + CHECK( globvars.get_global_value( "alpha_name" ) == "mixin fail alpha" ); + CHECK( globvars.get_global_value( "beta_name" ) == "mixin fail beta" ); - d2.set_value( "npctalk_var_alpha_var", mon_loc.to_string() ); + d2.set_value( "alpha_var", mon_loc.to_string() ); CHECK( effect_on_condition_run_eocs_talker_mixes_loc->activate( d2 ) ); - CHECK( globvars.get_global_value( "npctalk_var_alpha_name" ) == zombie->get_name() ); + CHECK( globvars.get_global_value( "alpha_name" ) == zombie->get_name() ); } diff --git a/tests/faction_price_rules_test.cpp b/tests/faction_price_rules_test.cpp index 7dca30da08d22..7f987668bfba6 100644 --- a/tests/faction_price_rules_test.cpp +++ b/tests/faction_price_rules_test.cpp @@ -126,7 +126,7 @@ TEST_CASE( "faction_price_rules", "[npc][factions][trade]" ) Approx( units::to_cent( carafe.type->price_post ) * 1.25 ).margin( 1 ) ); } WHEN( "condition for price rules satisfied" ) { - guy.set_value( "npctalk_var_bool_allnighter_thirsty", "yes" ); + guy.set_value( "bool_allnighter_thirsty", "yes" ); REQUIRE( fac.get_price_rules( carafe, guy )->markup == 2.0 ); THEN( "NPC selling to avatar includes markup and positive fixed adjustment" ) { REQUIRE( npc_trading::adjusted_price( &carafe, 1, get_avatar(), guy ) == @@ -141,7 +141,7 @@ TEST_CASE( "faction_price_rules", "[npc][factions][trade]" ) double const fmarkup = fac.get_price_rules( pants_fur, guy )->markup; REQUIRE( guy.get_price_rules( pants_fur )->markup == fmarkup ); REQUIRE( fmarkup != - 100 ); - guy.set_value( "npctalk_var_bool_preference_vegan", "yes" ); + guy.set_value( "bool_preference_vegan", "yes" ); REQUIRE( guy.get_price_rules( pants_fur )->markup == -100 ); } WHEN( "price rule affects magazine contents" ) { diff --git a/tests/math_parser_test.cpp b/tests/math_parser_test.cpp index ac07089d7608c..ac821d4a80ec1 100644 --- a/tests/math_parser_test.cpp +++ b/tests/math_parser_test.cpp @@ -270,13 +270,13 @@ TEST_CASE( "math_parser_dialogue_integration", "[math_parser]" ) global_variables &globvars = get_globals(); // reading scoped variables - globvars.set_global_value( "npctalk_var_x", "100" ); + globvars.set_global_value( "x", "100" ); CHECK( testexp.parse( "x" ) ); CHECK( testexp.eval( d ) == Approx( 100 ) ); - get_avatar().set_value( "npctalk_var_x", "92" ); + get_avatar().set_value( "x", "92" ); CHECK( testexp.parse( "u_x" ) ); CHECK( testexp.eval( d ) == Approx( 92 ) ); - dude.set_value( "npctalk_var_x", "21" ); + dude.set_value( "x", "21" ); CHECK( testexp.parse( "n_x" ) ); CHECK( testexp.eval( d ) == Approx( 21 ) ); CHECK( testexp.parse( "x + u_x + n_x" ) ); @@ -290,7 +290,7 @@ TEST_CASE( "math_parser_dialogue_integration", "[math_parser]" ) CHECK( testexp.parse( "has_var(_ctx)?19:20" ) ); CHECK( testexp.eval( d ) == Approx( 20 ) ); - d.set_value( "npctalk_var_ctx", "14" ); + d.set_value( "ctx", "14" ); CHECK( testexp.parse( "_ctx" ) ); CHECK( testexp.eval( d ) == Approx( 14 ) ); @@ -318,7 +318,7 @@ TEST_CASE( "math_parser_dialogue_integration", "[math_parser]" ) CHECK( testexp.eval( d ) == 25000000 ); // evaluating string variables in dialogue functions - globvars.set_global_value( "npctalk_var_someskill", "survival" ); + globvars.set_global_value( "someskill", "survival" ); CHECK( testexp.parse( "u_skill(someskill)" ) ); get_avatar().set_skill_level( skill_survival, 3 ); CHECK( testexp.eval( d ) == 3 ); @@ -326,16 +326,16 @@ TEST_CASE( "math_parser_dialogue_integration", "[math_parser]" ) // assignment to scoped variables CHECK( testexp.parse( "u_testvar", true ) ); testexp.assign( d, 159 ); - CHECK( std::stoi( get_avatar().get_value( "npctalk_var_testvar" ) ) == 159 ); + CHECK( std::stoi( get_avatar().get_value( "testvar" ) ) == 159 ); CHECK( testexp.parse( "testvar", true ) ); testexp.assign( d, 259 ); - CHECK( std::stoi( globvars.get_global_value( "npctalk_var_testvar" ) ) == 259 ); + CHECK( std::stoi( globvars.get_global_value( "testvar" ) ) == 259 ); CHECK( testexp.parse( "n_testvar", true ) ); testexp.assign( d, 359 ); - CHECK( std::stoi( dude.get_value( "npctalk_var_testvar" ) ) == 359 ); + CHECK( std::stoi( dude.get_value( "testvar" ) ) == 359 ); CHECK( testexp.parse( "_testvar", true ) ); testexp.assign( d, 159 ); - CHECK( std::stoi( d.get_value( "npctalk_var_testvar" ) ) == 159 ); + CHECK( std::stoi( d.get_value( "testvar" ) ) == 159 ); // assignment to scoped values with u_val shim CHECK( testexp.parse( "u_val('stamina')", true ) ); diff --git a/tests/melee_test.cpp b/tests/melee_test.cpp index 7967fe6000ba0..41ad5dc7de4d8 100644 --- a/tests/melee_test.cpp +++ b/tests/melee_test.cpp @@ -334,15 +334,15 @@ static void check_damage_from_test_fire( const std::string &mon_id, int expected REQUIRE( mon.get_armor_type( damage_test_fire, body_part_bp_null ) == expected_resist ); REQUIRE( mon.is_immune_damage( damage_test_fire ) == is_immune ); REQUIRE( mon.get_hp() == mon.get_hp_max() ); - REQUIRE( dude.get_value( "npctalk_var_general_dmg_type_test_test_fire" ).empty() ); - REQUIRE( mon.get_value( "npctalk_var_general_dmg_type_test_test_fire" ).empty() ); + REQUIRE( dude.get_value( "general_dmg_type_test_test_fire" ).empty() ); + REQUIRE( mon.get_value( "general_dmg_type_test_test_fire" ).empty() ); dude.set_wielded_item( item( "test_fire_sword" ) ); dude.melee_attack( mon, false ); if( mon.get_hp() < mon.get_hp_max() ) { total_hits++; total_dmg += mon.get_hp_max() - mon.get_hp(); - if( mon.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "target" ) { - REQUIRE( dude.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "source" ); + if( mon.get_value( "general_dmg_type_test_test_fire" ) == "target" ) { + REQUIRE( dude.get_value( "general_dmg_type_test_test_fire" ) == "source" ); set_on_fire++; } } @@ -361,22 +361,22 @@ static void check_eocs_from_test_fire( const std::string &mon_id ) monster &mon = spawn_test_monster( mon_id, dude.pos_bub() + tripoint_east ); REQUIRE( mon.pos() == dude.pos() + tripoint_east ); REQUIRE( mon.get_hp() == mon.get_hp_max() ); - REQUIRE( dude.get_value( "npctalk_var_general_dmg_type_test_test_fire" ).empty() ); - REQUIRE( mon.get_value( "npctalk_var_general_dmg_type_test_test_fire" ).empty() ); + REQUIRE( dude.get_value( "general_dmg_type_test_test_fire" ).empty() ); + REQUIRE( mon.get_value( "general_dmg_type_test_test_fire" ).empty() ); item firesword( "test_fire_sword" ); dude.set_wielded_item( firesword ); for( int i = 0; i < 1000; ++i ) { - if( dude.melee_attack( mon, false ) && !dude.get_value( "npctalk_var_test_bp" ).empty() ) { + if( dude.melee_attack( mon, false ) && !dude.get_value( "test_bp" ).empty() ) { break; } } - CHECK( !dude.get_value( "npctalk_var_test_bp" ).empty() ); - if( mon.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "target" ) { - REQUIRE( dude.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "source" ); + CHECK( !dude.get_value( "test_bp" ).empty() ); + if( mon.get_value( "general_dmg_type_test_test_fire" ) == "target" ) { + REQUIRE( dude.get_value( "general_dmg_type_test_test_fire" ) == "source" ); } eoc_total_dmg = std::round( std::stod( - dude.get_value( "npctalk_var_test_damage_taken" ) ) ); + dude.get_value( "test_damage_taken" ) ) ); Messages::clear_messages(); CHECK( eoc_total_dmg == firesword.damage_melee( damage_test_fire ) ); @@ -400,15 +400,15 @@ static void check_damage_from_test_fire( const std::vector &armor_i REQUIRE( dude2.get_armor_type( damage_test_fire, checked_bp ) == expected_resist ); REQUIRE( dude2.is_immune_damage( damage_test_fire ) == is_immune ); REQUIRE( dude2.get_hp() == dude2.get_hp_max() ); - REQUIRE( dude.get_value( "npctalk_var_general_dmg_type_test_test_fire" ).empty() ); - REQUIRE( dude2.get_value( "npctalk_var_general_dmg_type_test_test_fire" ).empty() ); + REQUIRE( dude.get_value( "general_dmg_type_test_test_fire" ).empty() ); + REQUIRE( dude2.get_value( "general_dmg_type_test_test_fire" ).empty() ); dude.set_wielded_item( item( "test_fire_sword" ) ); dude.melee_attack( dude2, false ); if( dude2.get_hp() < dude2.get_hp_max() ) { total_hits++; total_dmg += dude2.get_hp_max() - dude2.get_hp(); - if( dude2.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "target" ) { - REQUIRE( dude.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "source" ); + if( dude2.get_value( "general_dmg_type_test_test_fire" ) == "target" ) { + REQUIRE( dude.get_value( "general_dmg_type_test_test_fire" ) == "source" ); set_on_fire++; } } diff --git a/tests/npc_blacklist_test.cpp b/tests/npc_blacklist_test.cpp index 1f24bc36a15f1..58b99a81fc05d 100644 --- a/tests/npc_blacklist_test.cpp +++ b/tests/npc_blacklist_test.cpp @@ -9,6 +9,6 @@ TEST_CASE( "npc_blacklist", "[npc][trade]" ) guy.load_npc_template( npc_template_test_npc_trader ); REQUIRE( guy.wants_to_buy( item( "bow_saw" ) ) ); - guy.set_value( "npctalk_var_bool_bigotry_hates_bow_saws", "yes" ); + guy.set_value( "bool_bigotry_hates_bow_saws", "yes" ); REQUIRE( !guy.wants_to_buy( item( "bow_saw" ) ) ); } diff --git a/tests/npc_shop_cons_rates_test.cpp b/tests/npc_shop_cons_rates_test.cpp index 215fc5f64e9e4..6f24a1843ead8 100644 --- a/tests/npc_shop_cons_rates_test.cpp +++ b/tests/npc_shop_cons_rates_test.cpp @@ -23,7 +23,7 @@ TEST_CASE( "npc_shop_cons_rates", "[npc][trade]" ) REQUIRE( myrates.get_rate( item( "bow_saw" ), guy ) == 2 ); } WHEN( "item is matched by typeid and condition is true" ) { - guy.set_value( "npctalk_var_bool_dinner_bow_saw_eater", "yes" ); + guy.set_value( "bool_dinner_bow_saw_eater", "yes" ); REQUIRE( myrates.get_rate( item( "bow_saw" ), guy ) == 99 ); } WHEN( "item is matched by category" ) { diff --git a/tests/npc_shopkeeper_item_groups_test.cpp b/tests/npc_shopkeeper_item_groups_test.cpp index 03be4beb6dbc3..76d05991fd644 100644 --- a/tests/npc_shopkeeper_item_groups_test.cpp +++ b/tests/npc_shopkeeper_item_groups_test.cpp @@ -83,7 +83,7 @@ TEST_CASE( "npc_shopkeeper_item_groups", "[npc][trade]" ) } } WHEN( "condition met" ) { - get_avatar().set_value( "npctalk_var_bool_test_tools_access", "yes" ); + get_avatar().set_value( "bool_test_tools_access", "yes" ); std::pair har_hammer = has_and_can_restock( guy, hammer ); THEN( "item is available for selling and restocking" ) { REQUIRE( har_hammer.first == true ); @@ -105,7 +105,7 @@ TEST_CASE( "npc_shopkeeper_item_groups", "[npc][trade]" ) } } WHEN( "condition met" ) { - get_avatar().set_value( "npctalk_var_bool_test_multitool_access", "yes" ); + get_avatar().set_value( "bool_test_multitool_access", "yes" ); std::pair har_multitool = has_and_can_restock( guy, multitool ); THEN( "item is available for selling and restocking" ) { REQUIRE( har_multitool.first == true ); @@ -133,7 +133,7 @@ TEST_CASE( "npc_shopkeeper_item_groups", "[npc][trade]" ) } } WHEN( "condition for contents met" ) { - get_avatar().set_value( "npctalk_var_bool_test_multitool_access", "yes" ); + get_avatar().set_value( "bool_test_multitool_access", "yes" ); THEN( "container can be sold" ) { REQUIRE( guy.wants_to_sell( loc ) ); } diff --git a/tests/npc_talk_test.cpp b/tests/npc_talk_test.cpp index c6cb8f9bb26da..e99a0d9aadf7f 100644 --- a/tests/npc_talk_test.cpp +++ b/tests/npc_talk_test.cpp @@ -129,7 +129,7 @@ static npc &prep_test( dialogue &d, bool shopkeep = false ) clear_vehicles(); clear_map(); avatar &player_character = get_avatar(); - player_character.set_value( "npctalk_var_test_var", "It's avatar" ); + player_character.set_value( "test_var", "It's avatar" ); player_character.name = "Alpha Avatar"; REQUIRE_FALSE( player_character.in_vehicle ); @@ -139,7 +139,7 @@ static npc &prep_test( dialogue &d, bool shopkeep = false ) g->faction_manager_ptr->create_if_needed(); npc &beta = create_test_talker( shopkeep ); - beta.set_value( "npctalk_var_test_var", "It's npc" ); + beta.set_value( "test_var", "It's npc" ); d = dialogue( get_talker_for( player_character ), get_talker_for( beta ) ); return beta; } @@ -1013,10 +1013,10 @@ TEST_CASE( "npc_test_tags", "[npc_talk]" ) prep_test( d ); global_variables &globvars = get_globals(); - globvars.set_global_value( "npctalk_var_test_var", "It's global" ); + globvars.set_global_value( "test_var", "It's global" ); d.add_topic( "TALK_TEST_TAGS" ); - d.set_value( "npctalk_var_test_var", "It's context" ); + d.set_value( "test_var", "It's context" ); gen_response_lines( d, 8 ); CHECK( d.responses[0].create_option_line( d, input_event() ).text == "Avatar tag is set to It's avatar." ); @@ -1078,7 +1078,7 @@ TEST_CASE( "npc_compare_int", "[npc_talk]" ) it.get_category_shallow().get_id() == item_category_food || it.typeId() == itype_bottle_glass; } ); - player_character.remove_value( "npctalk_var_test_var_time_test_test" ); + player_character.remove_value( "test_var_time_test_test" ); calendar::turn = calendar::turn_zero; int expected_answers = 7; @@ -1215,7 +1215,7 @@ TEST_CASE( "npc_compare_int", "[npc_talk]" ) CHECK( d.responses[ 15 ].text == "This is a time since u_var test response for > 3_days." ); // Teardown - player_character.remove_value( "npctalk_var_test_var_time_test_test" ); + player_character.remove_value( "test_var_time_test_test" ); } TEST_CASE( "npc_arithmetic", "[npc_talk]" ) @@ -1287,7 +1287,7 @@ TEST_CASE( "npc_arithmetic", "[npc_talk]" ) effects.apply( d ); CHECK( player_character.per_max == 9 ); - std::string var_name = "npctalk_var_test_var_time_test_test"; + std::string var_name = "test_var_time_test_test"; player_character.set_value( var_name, std::to_string( 1 ) ); // "Sets custom var to 10." effects = d.responses[ 9 ].success; @@ -1519,5 +1519,5 @@ TEST_CASE( "test_topic_item_mutator", "[npc_talk]" ) gen_response_lines( d, 1 ); chosen = d.responses[0]; chosen.success.apply( d ); - CHECK( globvars.get_global_value( "npctalk_var_key1" ) == "bottle_glass" ); + CHECK( globvars.get_global_value( "key1" ) == "bottle_glass" ); } diff --git a/tests/ranged_balance_test.cpp b/tests/ranged_balance_test.cpp index b577d89593219..c5c714755e06b 100644 --- a/tests/ranged_balance_test.cpp +++ b/tests/ranged_balance_test.cpp @@ -585,8 +585,8 @@ TEST_CASE( "shot_custom_damage_type", "[gun]" "[slow]" ) { clear_map(); auto check_eocs = []( const standard_npc & src, const monster & tgt ) { - return src.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "source" && - tgt.get_value( "npctalk_var_general_dmg_type_test_test_fire" ) == "target"; + return src.get_value( "general_dmg_type_test_test_fire" ) == "source" && + tgt.get_value( "general_dmg_type_test_test_fire" ) == "target"; }; // Check that ballistics damage processes weird damage types and on-hit EOCs shoot_monster( "shotgun_s", {}, "test_shot_00_fire_damage", 1, 80, diff --git a/tests/submap_load_test.cpp b/tests/submap_load_test.cpp index 5bdb5be306a89..e426a84dc9278 100644 --- a/tests/submap_load_test.cpp +++ b/tests/submap_load_test.cpp @@ -851,7 +851,7 @@ static JsonValue submap_fd_pre_migration = json_loader::from_string( submap_fd_p static void load_from_jsin( submap &sm, const JsonValue &jsin ) { // Ensure that the JSON is up to date for our savegame version - REQUIRE( savegame_version == 34 ); + REQUIRE( savegame_version == 35 ); int version = 0; JsonObject sm_json = jsin.get_object(); if( sm_json.has_member( "version" ) ) { From 4db2d546b39eab8b7ddb6d2e5eb7e844a95a7504 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Sat, 16 Nov 2024 22:58:25 -0600 Subject: [PATCH 17/19] Martial Mastery: Defensive Perks (#77405) * New defensive perks * Defer pressure points perk until later. * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Anton Burmistrov --------- Co-authored-by: Anton Burmistrov --- data/mods/Perk_melee/EOC/shrug_off.json | 45 ++++++ data/mods/Perk_melee/PERKS/insight.json | 71 +++++++++ data/mods/Perk_melee/PERKS/momentum.json | 28 ++++ data/mods/Perk_melee/PERKS/perks.json | 76 ++++++++++ data/mods/Perk_melee/PERKS/tempo.json | 35 +++++ data/mods/Perk_melee/enchantments.json | 19 +++ data/mods/Perk_melee/menu.json | 60 ++++++++ data/mods/Perk_melee/perks.json | 177 ----------------------- 8 files changed, 334 insertions(+), 177 deletions(-) create mode 100644 data/mods/Perk_melee/EOC/shrug_off.json create mode 100644 data/mods/Perk_melee/PERKS/insight.json create mode 100644 data/mods/Perk_melee/PERKS/momentum.json create mode 100644 data/mods/Perk_melee/PERKS/perks.json create mode 100644 data/mods/Perk_melee/PERKS/tempo.json delete mode 100644 data/mods/Perk_melee/perks.json diff --git a/data/mods/Perk_melee/EOC/shrug_off.json b/data/mods/Perk_melee/EOC/shrug_off.json new file mode 100644 index 0000000000000..5aa89543703f4 --- /dev/null +++ b/data/mods/Perk_melee/EOC/shrug_off.json @@ -0,0 +1,45 @@ +[ + { + "id": "EOC_PERK_SHRUG_OFF", + "type": "effect_on_condition", + "condition": { "u_using_martial_art": "style_none" }, + "deactivate_condition": { "not": { "u_has_flag": "MELEE_PERK_SHRUG_OFF" } }, + "recurrence": "15 seconds", + "effect": [ { "math": [ "u_shrug_off_ready", "=", "1" ] } ] + }, + { + "type": "enchantment", + "id": "melee_perk_ench_shrug_off", + "condition": { "math": [ "u_shrug_off_ready", "==", "1" ] }, + "name": { "str": "Shrug it off" }, + "description": "You will completely negate the next attack that hits you.", + "values": [ { "value": "FORCEFIELD", "add": 1 } ], + "hit_me_effect": [ + { + "id": "sp_shrug_off_hit", + "hit_self": true, + "message": "You shrug off the attack.", + "npc_message": "%1$s's no sells the incoming attack." + } + ] + }, + { + "id": "sp_shrug_off_hit", + "type": "SPELL", + "name": { "str": "Shrug Off Trigger" }, + "description": { "str": "Shrug off trigger", "//~": "NO_I18N" }, + "valid_targets": [ "self" ], + "flags": [ "SILENT", "NO_EXPLOSION_SFX" ], + "shape": "blast", + "min_range": 1, + "max_range": 1, + "message": "", + "effect": "effect_on_condition", + "effect_str": "EOC_PERK_SHRUG_OFF_TRIGGER" + }, + { + "id": "EOC_PERK_SHRUG_OFF_TRIGGER", + "type": "effect_on_condition", + "effect": [ { "math": [ "u_shrug_off_ready", "=", "0" ] } ] + } +] diff --git a/data/mods/Perk_melee/PERKS/insight.json b/data/mods/Perk_melee/PERKS/insight.json new file mode 100644 index 0000000000000..9139255755373 --- /dev/null +++ b/data/mods/Perk_melee/PERKS/insight.json @@ -0,0 +1,71 @@ +[ + { + "type": "mutation", + "id": "MELEE_PERK_INSIGHT", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Insight I" }, + "description": "You passively accumulate up to 20 insight stacks while near enemies. Each insight stack increases all damage dealt by 1 until your next attack. Insight greatly favors perceptive warriors.", + "flags": "MELEE_PERK_INSIGHT", + "enchantments": [ "melee_perk_ench_insight" ] + }, + { + "type": "mutation", + "id": "MELEE_PERK_INSIGHT_DODGE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Like Water" }, + "description": "You gain a +25 dodge chance if you have at least 10 insight stacks.", + "flags": "MELEE_PERK_LIKE_WATER", + "enchantments": [ "melee_perk_ench_insight_dodge" ] + }, + { + "type": "mutation", + "id": "MELEE_PERK_SIXTH_SENSE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Sixth Sense" }, + "description": "You accumulate up to 20 insight stacks even from enemies you can't see. You can perceive unseen enemies within 10 tiles if you have at least 10 insight stacks.", + "flags": "MELEE_PERK_SIXTH_SENSE", + "enchantments": [ "melee_perk_ench_six_sense" ] + }, + { + "type": "mutation", + "id": "MELEE_PERK_INSIGHT_INFINITE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "The Psychic Sea" }, + "description": "You can accumulate an infinite number of insight stacks.", + "flags": "MELEE_PERK_INSIGHT_INFINITE" + }, + { + "type": "mutation", + "id": "MELEE_PERK_TWILIGHT_FORM", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Twilight Form" }, + "description": "Whenever you kill an enemy in melee, you retain 50% of your insight stacks.", + "flags": "MELEE_PERK_TWILIGHT_FORM" + }, + { + "type": "mutation", + "id": "MELEE_PERK_BLIND_CALCULUS", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Blind Calculus" }, + "description": "If you have been blind for at least 15 turns, every time you would gain an insight stack you instead gain 5.", + "flags": "MELEE_PERK_BLIND_CALCULUS" + }, + { + "type": "mutation", + "id": "MELEE_PERK_MYSTIC_SHOT", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Mystic Shot I" }, + "description": "Insight stacks also increase the accuracy of ranged bow and crossbow attacks by 2% per stack. Ranged attacks will consume insight stacks.", + "flags": "MELEE_PERK_MYSTIC_SHOT", + "enchantments": [ "melee_perk_ench_insight_mystic_shot" ] + }, + { + "type": "mutation", + "id": "MELEE_PERK_MYSTIC_SHOT_2", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Mystic Shot II" }, + "description": "Insight stacks also increase the damage of ranged bow and crossbow attacks by 1% per stack.", + "flags": "MELEE_PERK_MYSTIC_SHOT_2", + "enchantments": [ "melee_perk_ench_insight_mystic_shot_2" ] + } +] diff --git a/data/mods/Perk_melee/PERKS/momentum.json b/data/mods/Perk_melee/PERKS/momentum.json new file mode 100644 index 0000000000000..d7a56aed21bd1 --- /dev/null +++ b/data/mods/Perk_melee/PERKS/momentum.json @@ -0,0 +1,28 @@ +[ + { + "type": "mutation", + "id": "MELEE_PERK_MOMENTUM", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Momentum I" }, + "description": "Rapid movement generates momentum stacks. Momentum greatly favors dextrous warriors.", + "changes_to": [ "MELEE_PERK_MOMENTUM_2" ], + "flags": "MELEE_PERK_MOMENTUM" + }, + { + "type": "mutation", + "id": "MELEE_PERK_MOMENTUM_2", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Momentum II" }, + "description": "Rapid movement generates momentum stacks. As long as momentum is active your attacks gain extra physical damage equal to 10% of your dexterity. You gain a point of dexterity for every 2 momentum stacks.", + "flags": "MELEE_PERK_MOMENTUM" + }, + { + "type": "mutation", + "id": "MELEE_PERK_MOMENTUM_BULLET_DODGE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Ballistic Evasion" }, + "description": "If you have at least 4 momentum stacks, gain a 5% chance to dodge any ranged attack for every point of dexterity you have. If you have less than 4 momentum stacks, gain a 1% chance to dodge any ranged attack for every point of dexterity you have.", + "flags": "MELEE_PERK_MOMENTUM_BULLET_DODGE", + "enchantments": [ "melee_perk_ench_momentum_bullet_dodge" ] + } +] diff --git a/data/mods/Perk_melee/PERKS/perks.json b/data/mods/Perk_melee/PERKS/perks.json new file mode 100644 index 0000000000000..16b59a7fab27f --- /dev/null +++ b/data/mods/Perk_melee/PERKS/perks.json @@ -0,0 +1,76 @@ +[ + { + "type": "mutation_type", + "id": "perk" + }, + { + "type": "mutation", + "id": "perk_ma_perk_menu", + "name": { "str": "Practice Martial Arts" }, + "points": 0, + "purifiable": false, + "description": "Learn new martial arts techniques and perks.", + "active": true, + "activated_eocs": [ "EOC_open_ma_perk_menu" ] + }, + { + "type": "mutation", + "id": "MELEE_PERK_BASE", + "name": { "str": "Melee Perk" }, + "points": 0, + "description": "We copy from this one.", + "valid": false, + "purifiable": false + }, + { + "type": "mutation", + "id": "MELEE_PERK_CAREFREE_STANCE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Carefree Stance" }, + "description": "You aren't even trying.\nYou clear all combat buffs whenever you wait.", + "flags": "MELEE_PERK_CAREFREE_STANCE" + }, + { + "type": "mutation", + "id": "MELEE_PERK_MOVING_DODGE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Flowing Retreat" }, + "description": "You'll attempt to move away from your attackers when you successfully dodge an attack. You'll gain a momentum stack if you can normally gain them.", + "flags": "MELEE_PERK_MOVING_DODGE" + }, + { + "type": "mutation", + "id": "MELEE_PERK_RIPOSTE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Counter Strikes" }, + "description": "You gain +1 accuracy for two turns after a successful block.", + "flags": "MELEE_PERK_RIPOSTE" + }, + { + "type": "mutation", + "id": "MELEE_PERK_BLOCK", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Stalwart" }, + "description": "You have an extra block attempt per turn.", + "flags": "MELEE_PERK_BLOCK", + "enchantments": [ { "values": [ { "value": "BONUS_BLOCK", "add": 1 } ] } ] + }, + { + "type": "mutation", + "id": "MELEE_PERK_SHRUG_OFF", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Shrug it off" }, + "description": "Automatically block the first attack that hits you every 15 turns.", + "flags": "MELEE_PERK_SHRUG_OFF", + "enchantments": [ "melee_perk_ench_shrug_off" ] + }, + { + "type": "mutation", + "id": "MELEE_PERK_DODGE", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Spry footwork" }, + "description": "You have an extra dodge attempt per turn.", + "flags": "MELEE_PERK_DODGE", + "enchantments": [ { "values": [ { "value": "BONUS_DODGE", "add": 1 } ] } ] + } +] diff --git a/data/mods/Perk_melee/PERKS/tempo.json b/data/mods/Perk_melee/PERKS/tempo.json new file mode 100644 index 0000000000000..7e1bf6e5d9d46 --- /dev/null +++ b/data/mods/Perk_melee/PERKS/tempo.json @@ -0,0 +1,35 @@ +[ + { + "type": "mutation", + "id": "MELEE_PERK_COMBAT_TEMPO", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Combat Tempo I" }, + "description": "Perfect. Now do it again.\nAttacks generate stacks of combat tempo. Tempo greatly favors the strong.", + "flags": "MELEE_PERK_TEMPO" + }, + { + "type": "mutation", + "id": "MELEE_PERK_TEMPO_SHIFT", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Tempo Shift" }, + "description": "Gain a stack of combat tempo whenever you successfully block an attack.", + "flags": "MELEE_PERK_TEMPO_SHIFT" + }, + { + "type": "mutation", + "id": "MELEE_PERK_TEMPO_THROW", + "copy-from": "MELEE_PERK_BASE", + "name": { "str": "Measured Throws" }, + "description": "Your throwing attacks deal 100% more damage for every combat tempo stack you have.", + "enchantments": [ + { + "values": [ + { + "value": "THROW_DAMAGE", + "multiply": { "math": [ "u_effect_intensity('mabuff:buff_perk_tempo') > 0 ? u_effect_intensity('mabuff:buff_perk_tempo') : 0" ] } + } + ] + } + ] + } +] diff --git a/data/mods/Perk_melee/enchantments.json b/data/mods/Perk_melee/enchantments.json index c4cc1fccf0258..e9065ec2fa2b9 100644 --- a/data/mods/Perk_melee/enchantments.json +++ b/data/mods/Perk_melee/enchantments.json @@ -15,6 +15,12 @@ "condition": { "math": [ "u_effect_intensity('perk_insight')", ">", "9" ] }, "values": [ { "value": "MOTION_VISION_RANGE", "add": 10 } ] }, + { + "type": "enchantment", + "id": "melee_perk_ench_insight_dodge", + "condition": { "math": [ "u_effect_intensity('perk_insight')", ">", "9" ] }, + "values": [ { "value": "DODGE_CHANCE", "add": 25 } ] + }, { "type": "enchantment", "id": "melee_perk_ench_insight_mystic_shot", @@ -33,5 +39,18 @@ "id": "melee_perk_ench_insight_mystic_shot_2", "condition": { "and": [ { "u_has_wielded_with_flag": "PRIMITIVE_RANGED_WEAPON" }, { "u_has_effect": "perk_insight" } ] }, "values": [ { "value": "RANGED_DAMAGE", "multiply": { "math": [ "u_effect_intensity('perk_insight')* 0.01" ] } } ] + }, + { + "type": "enchantment", + "id": "melee_perk_ench_momentum_bullet_dodge", + "condition": { "math": [ "u_effect_intensity('perk_insight')", ">", "9" ] }, + "values": [ + { + "value": "RANGE_DODGE", + "add": { + "math": [ "u_effect_intensity('mabuff:buff_perk_momentum') > 4 ? u_val('dexterity') * 0.05 : u_val('dexterity') * 0.01" ] + } + } + ] } ] diff --git a/data/mods/Perk_melee/menu.json b/data/mods/Perk_melee/menu.json index beffa1f85b931..71c813c7d594a 100644 --- a/data/mods/Perk_melee/menu.json +++ b/data/mods/Perk_melee/menu.json @@ -164,6 +164,28 @@ ], "topic": "TALK_MA_PERK_MENU_SELECT" }, + { + "condition": { "not": { "u_has_trait": "MELEE_PERK_MOMENTUM_BULLET_DODGE" } }, + "text": "Learn []", + "effect": [ + { "set_string_var": "", "target_var": { "context_val": "trait_name" } }, + { + "set_string_var": "", + "target_var": { "context_val": "trait_description" } + }, + { "set_string_var": "MELEE_PERK_MOMENTUM_BULLET_DODGE", "target_var": { "context_val": "trait_id" } }, + { + "set_string_var": "Requires Momentum I and Spry Footwork", + "target_var": { "context_val": "trait_requirement_description" }, + "i18n": true + }, + { + "set_condition": "perk_condition", + "condition": { "and": [ { "u_has_trait": "MELEE_PERK_MOMENTUM" }, { "u_has_trait": "MELEE_PERK_DODGE" } ] } + } + ], + "topic": "TALK_MA_PERK_MENU_SELECT" + }, { "condition": { "not": { "u_has_trait": "MELEE_PERK_COILING_STRIKE" } }, "text": "Learn []", @@ -287,6 +309,25 @@ ], "topic": "TALK_MA_PERK_MENU_SELECT" }, + { + "condition": { "not": { "u_has_trait": "MELEE_PERK_INSIGHT_DODGE" } }, + "text": "Learn []", + "effect": [ + { "set_string_var": "", "target_var": { "context_val": "trait_name" } }, + { + "set_string_var": "", + "target_var": { "context_val": "trait_description" } + }, + { "set_string_var": "MELEE_PERK_INSIGHT_DODGE", "target_var": { "context_val": "trait_id" } }, + { + "set_string_var": "Requires Insight I", + "target_var": { "context_val": "trait_requirement_description" }, + "i18n": true + }, + { "set_condition": "perk_condition", "condition": { "u_has_trait": "MELEE_PERK_INSIGHT" } } + ], + "topic": "TALK_MA_PERK_MENU_SELECT" + }, { "condition": { "not": { "u_has_trait": "MELEE_PERK_MYSTIC_SHOT" } }, "text": "Learn []", @@ -410,6 +451,25 @@ ], "topic": "TALK_MA_PERK_MENU_SELECT" }, + { + "condition": { "not": { "u_has_trait": "MELEE_PERK_SHRUG_OFF" } }, + "text": "Learn []", + "effect": [ + { "set_string_var": "", "target_var": { "context_val": "trait_name" } }, + { + "set_string_var": "", + "target_var": { "context_val": "trait_description" } + }, + { "set_string_var": "MELEE_PERK_SHRUG_OFF", "target_var": { "context_val": "trait_id" } }, + { + "set_string_var": "No Requirements", + "target_var": { "context_val": "trait_requirement_description" }, + "i18n": true + }, + { "set_condition": "perk_condition", "condition": { "math": [ "0", "==", "0" ] } } + ], + "topic": "TALK_MA_PERK_MENU_SELECT" + }, { "condition": { "not": { "u_has_trait": "MELEE_PERK_RIPOSTE" } }, "text": "Learn []", diff --git a/data/mods/Perk_melee/perks.json b/data/mods/Perk_melee/perks.json deleted file mode 100644 index 69287a1335b6a..0000000000000 --- a/data/mods/Perk_melee/perks.json +++ /dev/null @@ -1,177 +0,0 @@ -[ - { - "type": "mutation_type", - "id": "perk" - }, - { - "type": "mutation", - "id": "perk_ma_perk_menu", - "name": { "str": "Practice Martial Arts" }, - "points": 0, - "purifiable": false, - "description": "Learn new martial arts techniques and perks.", - "active": true, - "activated_eocs": [ "EOC_open_ma_perk_menu" ] - }, - { - "type": "mutation", - "id": "MELEE_PERK_BASE", - "name": { "str": "Melee Perk" }, - "points": 0, - "description": "We copy from this one.", - "valid": false, - "purifiable": false - }, - { - "type": "mutation", - "id": "MELEE_PERK_CAREFREE_STANCE", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Carefree Stance" }, - "description": "You aren't even trying.\nYou clear all combat buffs whenever you wait.", - "flags": "MELEE_PERK_CAREFREE_STANCE" - }, - { - "type": "mutation", - "id": "MELEE_PERK_MOVING_DODGE", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Flowing retreat" }, - "description": "You'll attempt to move away from your attackers when you successfully dodge an attack. You'll gain a momentum stack if you can normally gain them.", - "flags": "MELEE_PERK_MOVING_DODGE" - }, - { - "type": "mutation", - "id": "MELEE_PERK_RIPOSTE", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Counter strikes" }, - "description": "You gain +1 accuracy for two turns after a successful block.", - "flags": "MELEE_PERK_RIPOSTE" - }, - { - "type": "mutation", - "id": "MELEE_PERK_BLOCK", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Stalwart" }, - "description": "You have an extra block attempt per turn.", - "flags": "MELEE_PERK_BLOCK", - "enchantments": [ { "values": [ { "value": "BONUS_BLOCK", "add": 1 } ] } ] - }, - { - "type": "mutation", - "id": "MELEE_PERK_DODGE", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Spry footwork" }, - "description": "You have an extra dodge attempt per turn.", - "flags": "MELEE_PERK_DODGE", - "enchantments": [ { "values": [ { "value": "BONUS_DODGE", "add": 1 } ] } ] - }, - { - "type": "mutation", - "id": "MELEE_PERK_INSIGHT", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Insight I" }, - "description": "You passively accumulate up to 20 insight stacks while near enemies. Each insight stack increases all damage dealt by 1 until your next attack. Insight greatly favors perceptive warriors.", - "flags": "MELEE_PERK_INSIGHT", - "enchantments": [ "melee_perk_ench_insight" ] - }, - { - "type": "mutation", - "id": "MELEE_PERK_SIXTH_SENSE", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Sixth Sense" }, - "description": "You accumulate up to 20 insight stacks even from enemies you can't see. You can perceive unseen enemies within 10 tiles if you have at least 5 insight stacks.", - "flags": "MELEE_PERK_SIXTH_SENSE", - "enchantments": [ "melee_perk_ench_six_sense" ] - }, - { - "type": "mutation", - "id": "MELEE_PERK_INSIGHT_INFINITE", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "The psychic sea" }, - "description": "You can accumulate an infinite number of insight stacks.", - "flags": "MELEE_PERK_INSIGHT_INFINITE" - }, - { - "type": "mutation", - "id": "MELEE_PERK_TWILIGHT_FORM", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Twilight Form" }, - "description": "Whenever you kill an enemy in melee, you retain 50% of your insight stacks.", - "flags": "MELEE_PERK_TWILIGHT_FORM" - }, - { - "type": "mutation", - "id": "MELEE_PERK_BLIND_CALCULUS", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Blind Calculus" }, - "description": "If you have been blind for at least 15 turns, every time you would gain an insight stack you instead gain 5.", - "flags": "MELEE_PERK_BLIND_CALCULUS" - }, - { - "type": "mutation", - "id": "MELEE_PERK_MYSTIC_SHOT", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Mystic Shot I" }, - "description": "Insight stacks also increase the accuracy of ranged bow and crossbow attacks by 2% per stack. Ranged attacks will consume insight stacks.", - "flags": "MELEE_PERK_MYSTIC_SHOT", - "enchantments": [ "melee_perk_ench_insight_mystic_shot" ] - }, - { - "type": "mutation", - "id": "MELEE_PERK_MYSTIC_SHOT_2", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Mystic Shot II" }, - "description": "Insight stacks also increase the damage of ranged bow and crossbow attacks by 1% per stack.", - "flags": "MELEE_PERK_MYSTIC_SHOT_2", - "enchantments": [ "melee_perk_ench_insight_mystic_shot_2" ] - }, - { - "type": "mutation", - "id": "MELEE_PERK_MOMENTUM", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Momentum I" }, - "description": "Rapid movement generates momentum stacks. Momentum greatly favors dextrous warriors.", - "changes_to": [ "MELEE_PERK_MOMENTUM_2" ], - "flags": "MELEE_PERK_MOMENTUM" - }, - { - "type": "mutation", - "id": "MELEE_PERK_MOMENTUM_2", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Momentum II" }, - "description": "Rapid movement generates momentum stacks. As long as momentum is active your attacks gain extra physical damage equal to 10% of your dexterity. You gain a point of dexterity for every 2 momentum stacks.", - "flags": "MELEE_PERK_MOMENTUM" - }, - { - "type": "mutation", - "id": "MELEE_PERK_COMBAT_TEMPO", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Combat Tempo I" }, - "description": "Perfect. Now do it again.\nAttacks generate stacks of combat tempo. Tempo greatly favors the strong.", - "flags": "MELEE_PERK_TEMPO" - }, - { - "type": "mutation", - "id": "MELEE_PERK_TEMPO_SHIFT", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Tempo Shift" }, - "description": "Gain a stack of combat tempo whenever you successfully block an attack.", - "flags": "MELEE_PERK_TEMPO_SHIFT" - }, - { - "type": "mutation", - "id": "MELEE_PERK_TEMPO_THROW", - "copy-from": "MELEE_PERK_BASE", - "name": { "str": "Measured throws" }, - "description": "Your throwing attacks deal 100% more damage for every combat tempo stack you have.", - "enchantments": [ - { - "values": [ - { - "value": "THROW_DAMAGE", - "multiply": { "math": [ "u_effect_intensity('mabuff:buff_perk_tempo') > 0 ? u_effect_intensity('mabuff:buff_perk_tempo') : 0" ] } - } - ] - } - ] - } -] From 9ac7d0512f98decae0b73c842c70d3ef627ced46 Mon Sep 17 00:00:00 2001 From: Anton Simakov <67688115+GuardianDll@users.noreply.github.com> Date: Sun, 17 Nov 2024 07:32:04 +0100 Subject: [PATCH 18/19] Transformation use action can pick random item from itemgroups (#77893) * transformation use action can pick random item from itemgroups * add some description for use action --- doc/JSON_INFO.md | 1 + src/iuse_actor.cpp | 27 ++++++++++++++++++++++----- src/iuse_actor.h | 3 +++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index ff3c58ced9f00..818e05850c994 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -4508,6 +4508,7 @@ The contents of `use_action` fields can either be a string indicating a built-in "use_action": { "type": "transform", // The type of method, in this case one that transforms the item "target": "gasoline_lantern_on", // The item to transform to + "target_group": "twisted_geometry", // If used, target is a random item from itemgroup "variant_type": "condom_plain", // (optional) Defaults to ``. Specific variant type to set for the transformed item. Special string `` will pick a random variant from all available variants, based on the variant's defined weight "active": true, // Whether the item is active once transformed "ammo_scale": 0, // For use when an item automatically transforms into another when its ammo drops to 0, or to allow guns to transform with 0 ammo diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 1d9156a35e62e..f6c4fe7767432 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -171,6 +171,11 @@ std::unique_ptr iuse_transform::clone() const void iuse_transform::load( const JsonObject &obj, const std::string & ) { obj.read( "target", target, true ); + obj.read( "target_group", target_group, true ); + + if( !target.is_empty() && !target_group.is_empty() ) { + obj.throw_error_at( "target_group", "Cannot use both target and target_group at once" ); + } obj.read( "msg", msg_transform ); obj.read( "variant_type", variant_type ); @@ -272,7 +277,8 @@ std::optional iuse_transform::use( Character *p, item &it, const tripoint & } } - if( it.count_by_charges() != target->count_by_charges() && it.count() > 1 ) { + if( target_group.is_empty() && it.count_by_charges() != target->count_by_charges() && + it.count() > 1 ) { item take_one = it.split( 1 ); do_transform( p, take_one, variant_type ); p->i_add_or_drop( take_one ); @@ -293,8 +299,12 @@ void iuse_transform::do_transform( Character *p, item &it, const std::string &va // defined here to allow making a new item assigned to the pointer item obj_it; if( container.is_empty() ) { - obj = &it.convert( target, p ); - obj->set_itype_variant( variant_type ); + if( !target_group.is_empty() ) { + obj = &it.convert( item_group::item_from( target_group ).typeId(), p ); + } else { + obj = &it.convert( target, p ); + obj->set_itype_variant( variant_type ); + } if( ammo_qty >= 0 || !random_ammo_qty.empty() ) { int qty; if( !random_ammo_qty.empty() ) { @@ -320,7 +330,9 @@ void iuse_transform::do_transform( Character *p, item &it, const std::string &va obj->set_itype_variant( variant_type ); int count = std::max( ammo_qty, 1 ); item cont; - if( target->count_by_charges() ) { + if( !target_group.is_empty() ) { + cont = item( item_group::item_from( target_group ).typeId(), calendar::turn ); + } else if( target->count_by_charges() ) { cont = item( target, calendar::turn, count ); count = 1; } else { @@ -423,7 +435,7 @@ std::string iuse_transform::get_name() const void iuse_transform::finalize( const itype_id & ) { - if( !item::type_is_defined( target ) ) { + if( !item::type_is_defined( target ) && target_group.is_empty() ) { debugmsg( "Invalid transform target: %s", target.c_str() ); } @@ -439,6 +451,11 @@ void iuse_transform::finalize( const itype_id & ) void iuse_transform::info( const item &it, std::vector &dump ) const { + + if( !target_group.is_empty() ) { + dump.emplace_back( "TOOL", _( "Can transform into one of several items" ) ); + return; + } int amount = std::max( ammo_qty, 1 ); item dummy( target, calendar::turn, target->count_by_charges() ? amount : 1 ); dummy.set_itype_variant( variant_type ); diff --git a/src/iuse_actor.h b/src/iuse_actor.h index c42b1ba9b33ce..b68b227a3beb0 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -53,6 +53,9 @@ class iuse_transform : public iuse_actor /** type of the resulting item */ itype_id target; + /** or one of items from itemgroup */ + item_group_id target_group; + /** if set transform item to container and place new item (of type @ref target) inside */ itype_id container; From 2ca630fc814591015b2af9dc2c16a2308c01ac77 Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Sun, 17 Nov 2024 15:26:18 -0500 Subject: [PATCH 19/19] Remove leftovers of "ident" (#77796) --- .../mod_interactions/innawood/skills.json | 2 +- data/mods/Xedra_Evolved/skills.json | 2 +- src/generic_factory.h | 30 ++++--------------- src/mod_manager.cpp | 3 +- src/skill.cpp | 9 ++---- 5 files changed, 10 insertions(+), 36 deletions(-) diff --git a/data/mods/Xedra_Evolved/mod_interactions/innawood/skills.json b/data/mods/Xedra_Evolved/mod_interactions/innawood/skills.json index c8872f46dadac..cb573cf8f97e3 100644 --- a/data/mods/Xedra_Evolved/mod_interactions/innawood/skills.json +++ b/data/mods/Xedra_Evolved/mod_interactions/innawood/skills.json @@ -1,7 +1,7 @@ [ { "type": "skill", - "ident": "deduction", + "id": "deduction", "name": { "str": "occult" }, "description": "Your knowledge of spirits, the unseen world, and other mystical topics, occult is a path to abilities many might consider to be unnatural.", "companion_industry_rank_factor": 1, diff --git a/data/mods/Xedra_Evolved/skills.json b/data/mods/Xedra_Evolved/skills.json index 66b5741052473..6301e1dbaa8e2 100644 --- a/data/mods/Xedra_Evolved/skills.json +++ b/data/mods/Xedra_Evolved/skills.json @@ -1,7 +1,7 @@ [ { "type": "skill", - "ident": "deduction", + "id": "deduction", "name": { "str": "deduction" }, "description": "Your ability to see the pattern behind a series of data points. Allows you to ask questions that you otherwise couldn't ask and find things you might have missed otherwise.", "companion_industry_rank_factor": 1, diff --git a/src/generic_factory.h b/src/generic_factory.h index b4850bf88d31c..f792c8b4a0e89 100644 --- a/src/generic_factory.h +++ b/src/generic_factory.h @@ -143,8 +143,6 @@ class generic_factory std::string type_name; std::string id_member_name; - // TEMPORARY until 0.G: Remove "ident" support - const std::string legacy_id_member_name = "ident"; bool find_id( const string_id &id, int_id &result ) const { if( id._version == version ) { @@ -243,9 +241,9 @@ class generic_factory } if( jo.has_string( abstract_member_name ) ) { - if( jo.has_string( id_member_name ) || jo.has_string( legacy_id_member_name ) ) { - jo.throw_error( string_format( "cannot specify both '%s' and '%s'/'%s'", - abstract_member_name, id_member_name, legacy_id_member_name ) ); + if( jo.has_string( id_member_name ) ) { + jo.throw_error( string_format( "cannot specify both '%s' and '%s'", + abstract_member_name, id_member_name ) ); } restore_on_out_of_scope restore_check_plural( check_plural ); check_plural = check_plural_t::none; @@ -292,27 +290,9 @@ class generic_factory insert( def ); } - } else if( jo.has_string( legacy_id_member_name ) ) { - def.id = string_id( jo.get_string( legacy_id_member_name ) ); - mod_tracker::assign_src( def, src ); - def.load( jo, src ); - insert( def ); - - } else if( jo.has_array( legacy_id_member_name ) ) { - for( const JsonValue e : jo.get_array( legacy_id_member_name ) ) { - T def; - if( !handle_inheritance( def, jo, src ) ) { - break; - } - def.id = string_id( e ); - mod_tracker::assign_src( def, src ); - def.load( jo, src ); - insert( def ); - } - } else if( !jo.has_string( abstract_member_name ) ) { - jo.throw_error( string_format( "must specify either '%s' or '%s'/'%s'", - abstract_member_name, id_member_name, legacy_id_member_name ) ); + jo.throw_error( string_format( "must specify either '%s' or '%s'", + abstract_member_name, id_member_name ) ); } } /** diff --git a/src/mod_manager.cpp b/src/mod_manager.cpp index a7cd1f837aa91..0bbd2848cebc0 100644 --- a/src/mod_manager.cpp +++ b/src/mod_manager.cpp @@ -226,8 +226,7 @@ void mod_manager::load_modfile( const JsonObject &jo, const cata_path &path ) return; } - // TEMPORARY until 0.G: Remove "ident" support - const mod_id m_ident( jo.has_string( "ident" ) ? jo.get_string( "ident" ) : jo.get_string( "id" ) ); + const mod_id m_ident( jo.get_string( "id" ) ); // can't use string_id::is_valid as the global mod_manger instance does not exist yet if( mod_map.count( m_ident ) > 0 ) { // TODO: change this to make unique ident for the mod diff --git a/src/skill.cpp b/src/skill.cpp index e56b6ecc3a846..8847093c8a145 100644 --- a/src/skill.cpp +++ b/src/skill.cpp @@ -116,9 +116,7 @@ void Skill::reset() void Skill::load_skill( const JsonObject &jsobj ) { - // TEMPORARY until 0.G: Remove "ident" support - skill_id ident = skill_id( jsobj.has_string( "ident" ) ? jsobj.get_string( "ident" ) : - jsobj.get_string( "id" ) ); + skill_id ident = skill_id( jsobj.get_string( "id" ) ); skills.erase( std::remove_if( begin( skills ), end( skills ), [&]( const Skill & s ) { return s._ident == ident; } ), end( skills ) ); @@ -188,10 +186,7 @@ const SkillDisplayType &skill_displayType_id::obj() const void SkillDisplayType::load( const JsonObject &jsobj ) { - // TEMPORARY until 0.G: Remove "ident" support - skill_displayType_id ident = skill_displayType_id( - jsobj.has_string( "ident" ) ? jsobj.get_string( "ident" ) : - jsobj.get_string( "id" ) ); + skill_displayType_id ident = skill_displayType_id( jsobj.get_string( "id" ) ); skillTypes.erase( std::remove_if( begin( skillTypes ), end( skillTypes ), [&]( const SkillDisplayType & s ) { return s._ident == ident;