From 5d32994e9f8e4b64c8f2c8c175fcf25a2619c53c Mon Sep 17 00:00:00 2001 From: RenechCDDA <84619419+RenechCDDA@users.noreply.github.com> Date: Tue, 15 Oct 2024 19:31:33 -0400 Subject: [PATCH] Load mission deadlines as a single object --- .../npcs/exodii/exodii_merchant_missions.json | 3 +-- data/json/npcs/missiondef.json | 9 +++------ .../robofac_intercom_missions.json | 3 +-- data/mods/classic_zombies/missiondef.json | 3 +-- data/mods/innawood/npcs/missiondef.json | 6 ++---- doc/MISSIONS_JSON.md | 20 +++++++++++++++++++ src/mission.cpp | 14 ++++++------- src/mission.h | 6 +++--- src/missiondef.cpp | 3 +-- 9 files changed, 38 insertions(+), 29 deletions(-) diff --git a/data/json/npcs/exodii/exodii_merchant_missions.json b/data/json/npcs/exodii/exodii_merchant_missions.json index d44f0e89ecdeb..0b03076e283d2 100644 --- a/data/json/npcs/exodii/exodii_merchant_missions.json +++ b/data/json/npcs/exodii/exodii_merchant_missions.json @@ -535,8 +535,7 @@ "fail": { "effect": { "math": [ "faction_trust('exodii')", "-=", "20" ] } }, "origins": [ "ORIGIN_SECONDARY" ], "has_generic_rewards": false, - "deadline_low": 20, - "deadline_high": 20, + "deadline": [ "20 days", "20 days" ], "//": "Dialogue for this mission is handled externally.", "dialogue": { "describe": ".", diff --git a/data/json/npcs/missiondef.json b/data/json/npcs/missiondef.json index e303fc91d1c29..07fc4f874f050 100644 --- a/data/json/npcs/missiondef.json +++ b/data/json/npcs/missiondef.json @@ -40,8 +40,7 @@ "value": 150000, "urgent": true, "origins": [ "ORIGIN_OPENER_NPC", "ORIGIN_ANY_NPC" ], - "deadline_low": 30, - "deadline_high": 48, + "deadline": [ "30 days", "48 days" ], "dialogue": { "describe": "I'm… short… of breath…", "offer": "I'm asthmatic. I need you to get an inhaler for me…", @@ -74,8 +73,7 @@ "urgent": true, "goal_condition": { "or": [ { "u_has_item": "antibiotics" }, { "u_has_item": "strong_antibiotic" }, { "u_has_item": "panacea" } ] }, "origins": [ "ORIGIN_OPENER_NPC" ], - "deadline_low": 24, - "deadline_high": 48, + "deadline": [ "24 days", "48 days" ], "dialogue": { "describe": "This infection is bad, bad…", "offer": "I'm infected. Badly. I need you to get some good antibiotics for me…", @@ -969,8 +967,7 @@ "description": "You have some time left until you can transfer control to your companions, provided you have established a Basecamp and have at least 1 NPC companion.", "difficulty": 0, "value": 0, - "deadline_low": { "math": [ "time_between_succession" ] }, - "deadline_high": { "math": [ "time_between_succession" ] }, + "deadline": { "math": [ "time_between_succession" ] }, "invisible_on_complete": true, "start": { "effect": [ diff --git a/data/json/npcs/robofac/robofac_intercom/robofac_intercom_missions.json b/data/json/npcs/robofac/robofac_intercom/robofac_intercom_missions.json index 3790c06c26336..79ad6d4e202bf 100644 --- a/data/json/npcs/robofac/robofac_intercom/robofac_intercom_missions.json +++ b/data/json/npcs/robofac/robofac_intercom/robofac_intercom_missions.json @@ -1087,8 +1087,7 @@ "fail": { "effect": { "math": [ "faction_trust('robofac')", "-=", "20" ] } }, "origins": [ "ORIGIN_SECONDARY" ], "has_generic_rewards": false, - "deadline_low": 20, - "deadline_high": 20, + "deadline": [ "20 days", "20 days" ], "//": "Dialogue for this mission is handled externally.", "dialogue": { "describe": ".", diff --git a/data/mods/classic_zombies/missiondef.json b/data/mods/classic_zombies/missiondef.json index 9ee5fbd6e80c4..ed8adc2cde7c8 100644 --- a/data/mods/classic_zombies/missiondef.json +++ b/data/mods/classic_zombies/missiondef.json @@ -5,8 +5,7 @@ "type": "mission_definition", "name": { "str": "Reach Refugee Center" }, "goal": "MGOAL_NULL", - "deadline_low": "1s", - "deadline_high": "1s", + "deadline": "1 seconds", "difficulty": 0, "value": 0 } diff --git a/data/mods/innawood/npcs/missiondef.json b/data/mods/innawood/npcs/missiondef.json index b3ed113d9a9da..8035a77f25c13 100644 --- a/data/mods/innawood/npcs/missiondef.json +++ b/data/mods/innawood/npcs/missiondef.json @@ -9,8 +9,7 @@ "value": 150000, "urgent": true, "origins": [ "ORIGIN_OPENER_NPC", "ORIGIN_ANY_NPC" ], - "deadline_low": 30, - "deadline_high": 48, + "deadline": [ "30 days", "48 days" ], "dialogue": { "describe": "I'm… short… of breath…", "offer": "I'm asthmatic. I need you to get some kind of medicinal tea for me…", @@ -45,8 +44,7 @@ "urgent": true, "goal_condition": { "u_has_item": "cattail_jelly" }, "origins": [ "ORIGIN_OPENER_NPC" ], - "deadline_low": 24, - "deadline_high": 48, + "deadline": [ "24 days", "48 days" ], "dialogue": { "describe": "This infection is bad, bad…", "offer": "I'm infected. Badly. I need you to get something antiseptic for me…", diff --git a/doc/MISSIONS_JSON.md b/doc/MISSIONS_JSON.md index 50b35c079cc57..3126e1a62b2f5 100644 --- a/doc/MISSIONS_JSON.md +++ b/doc/MISSIONS_JSON.md @@ -9,6 +9,7 @@ NPCs can assign missions to the player. There is a fairly regular structure for "name": "Retrieve Black Box Transcript", "description": "Decrypt the contents of the black box using a terminal from a nearby lab.", "goal": "MGOAL_FIND_ITEM", + "deadline": [ "16 hours", "math": [ "time(' 16 h') * 2" ] ], "difficulty": 2, "value": 150000, "item": "black_box_transcript", @@ -17,6 +18,14 @@ NPCs can assign missions to the player. There is a fairly regular structure for "effect": { "u_buy_item": "black_box" }, "assign_mission_target": { "om_terrain": "lab", "reveal_radius": 3 } }, + "urgent": false, + "has_generic_rewards": true, + "item": "pencil", + "item_group": "pencil_box_with_pencil", + "count": 6, + "required_container": "pencil_box", + "remove_container": true; + "empty_container": "can_drink", "origins": [ "ORIGIN_SECONDARY" ], "followup": "MISSION_EXPLORE_SARCOPHAGUS", "dialogue": { @@ -43,6 +52,11 @@ it with "MISSION" and to use a fairly descriptive name. ### name The name is also required, and is displayed to the user in the 'm'issions menu. +### deadline +How long after being assigned this mission before it will automatically fail (if not already completed). Can be a pair of values, in which case a random value between the two is picked. If only a single value is given, always uses that value. + +Supports variable objects and math expressions. + ### description Not required, but it's strongly recommended that you summarize all relevant info for the mission. You may refer to mission end effects of the "u_buy_item" type, as long as they do not come at a @@ -61,6 +75,12 @@ cost to the player. See the example below: ``` This system may be expanded in the future to allow referring to other mission parameters and effects. +### name +The name is also required, and is displayed to the user in the 'm'issions menu. + +### urgent +If true, the NPC giving this mission will refuse to speak on any other topics besides completing this mission while it is active. + ### goal Must be included, and must be one of these strings: diff --git a/src/mission.cpp b/src/mission.cpp index ae9e206bef203..3fe8043d99190 100644 --- a/src/mission.cpp +++ b/src/mission.cpp @@ -62,10 +62,9 @@ mission mission_type::create( const character_id &npc_id ) const struct dialogue d( get_talker_for( get_player_character() ), get_talker_for( g->find_npc( npc_id ) ) ); - time_duration deadline_low_as_var = deadline_low.evaluate( d ); - time_duration deadline_high_as_var = deadline_high.evaluate( d ); - if( deadline_low_as_var != 0_turns || deadline_high_as_var != 0_turns ) { - ret.deadline = calendar::turn + rng( deadline_low_as_var, deadline_high_as_var ); + time_duration deadline_as_var = deadline.evaluate( d ); + if( deadline_as_var != 0_turns ) { + ret.deadline = calendar::turn + deadline_as_var; } else { ret.deadline = calendar::turn_zero; } @@ -323,10 +322,9 @@ void mission::assign( avatar &u ) kill_count_to_reach = kills.kill_count( monster_species ) + monster_kill_goal; } dialogue d( get_talker_for( u ), get_talker_for( g->find_npc( npc_id ) ) ); - time_duration deadline_low = type->deadline_low.evaluate( d ); - time_duration deadline_high = type->deadline_high.evaluate( d ); - if( deadline_low != 0_turns || deadline_high != 0_turns ) { - deadline = calendar::turn + rng( deadline_low, deadline_high ); + time_duration deadline_as_var = type->deadline.evaluate( d ); + if( deadline_as_var != 0_turns ) { + deadline = calendar::turn + deadline_as_var; } else { deadline = calendar::turn_zero; } diff --git a/src/mission.h b/src/mission.h index f55f57a8addf6..1fb5b241dfb32 100644 --- a/src/mission.h +++ b/src/mission.h @@ -192,9 +192,9 @@ struct mission_type { int difficulty = 0; // Value; determines rewards and such int value = 0; - // Low and high deadlines - duration_or_var deadline_low; - duration_or_var deadline_high; + // When this mission will auto-fail, if ever. Can be pair of values or just one + // If loaded as a pair, automatically calls rng(min, max) when evaluated, standard stuff + duration_or_var deadline; // If true, the NPC will press this mission! bool urgent = false; // If the mission has generic rewards, so that the completion dialogue knows whether to offer them. diff --git a/src/missiondef.cpp b/src/missiondef.cpp index 88dc6666ab849..bacdb435d4c5f 100644 --- a/src/missiondef.cpp +++ b/src/missiondef.cpp @@ -384,8 +384,7 @@ void mission_type::load( const JsonObject &jo, const std::string &src ) return; } - deadline_low = get_duration_or_var( jo, "deadline_low", false ); - deadline_high = get_duration_or_var( jo, "deadline_high", false ); + deadline = get_duration_or_var( jo, "deadline", false ); if( jo.has_member( "followup" ) ) { follow_up = mission_type_id( jo.get_string( "followup" ) );