diff --git a/data/json/effects_on_condition/npc_eocs/hallucination_eocs.json b/data/json/effects_on_condition/npc_eocs/hallucination_eocs.json index d4eaa975e495b..7856c32ad7a8e 100644 --- a/data/json/effects_on_condition/npc_eocs/hallucination_eocs.json +++ b/data/json/effects_on_condition/npc_eocs/hallucination_eocs.json @@ -175,25 +175,30 @@ "type": "effect_on_condition", "id": "creature_hallucinations", "//TODO": "ideally checks is the tile visible, and then spawns hallu where player can't see it", - "//": "if monsters are nearby, 3/4 chance to get copy of random monster nearby and run again (with 1/2 prob) and 1/4 chance to spawns one of YOUR_FEARS. If not, spawns one of YOUR_FEARS", + "//": "If monsters are nearby, 3/4 chance to spawn some hallucinations of random monsters nearby and run again half the time, 1/4 chance to spawn some of YOUR_FEARS. If not, spawns some of YOUR_FEARS", + "condition": { "and": [ { "math": [ "rand(3)", "<", "3" ] }, { "math": [ "u_monsters_nearby()", ">", "0" ] } ] }, "effect": [ { - "if": { "and": [ { "math": [ "rand(3)", "==", "3" ] }, { "not": { "math": [ "u_monsters_nearby()", ">", "1" ] } } ] }, - "then": { - "u_spawn_monster": "GROUP_YOUR_FEARS", - "group": true, - "hallucination_count": { "math": [ "1 + rand(2)" ] }, - "max_radius": 40, - "lifespan": [ "1 hours", "4 hours" ] - }, - "else": { - "u_spawn_monster": "", - "hallucination_count": { "math": [ "1 + rand(4)" ] }, - "target_range": 50, - "lifespan": [ "2 hours", "9 hours" ] - } - } - ] + "u_spawn_monster": "", + "hallucination_count": { "math": [ "1 + rand(4)" ] }, + "target_range": 50, + "lifespan": [ "2 hours", "9 hours" ] + }, + { "weighted_list_eocs": [ [ "creature_hallucinations", 1 ], [ "EOC_NONE", 1 ] ] } + ], + "false_effect": { "run_eocs": "creature_hallucinations_fears" } + }, + { + "type": "effect_on_condition", + "id": "creature_hallucinations_fears", + "//TODO": "ideally checks is the tile visible, and then spawns hallu where player can't see it", + "effect": { + "u_spawn_monster": "GROUP_YOUR_FEARS", + "group": true, + "hallucination_count": { "math": [ "1 + rand(2)" ] }, + "max_radius": 40, + "lifespan": [ "1 hours", "4 hours" ] + } }, { "type": "effect_on_condition", @@ -209,19 +214,11 @@ "condition": { "math": [ "u_monsters_nearby()", ">", "1" ] }, "effect": [ { - "if": { "math": [ "u_i", "<", "rng(50, 100)" ] }, - "then": [ - { - "u_spawn_monster": "", - "hallucination_count": 1, - "target_range": 50, - "max_radius": 50, - "lifespan": [ "2 hours", "9 hours" ] - }, - { "math": [ "u_i", "++" ] }, - { "run_eocs": "hallucination_swarm" } - ], - "else": { "math": [ "u_i", "=", "0" ] } + "u_spawn_monster": "", + "hallucination_count": [ 50, 100 ], + "target_range": 50, + "max_radius": 50, + "lifespan": [ "2 hours", "9 hours" ] } ] } diff --git a/data/json/effects_on_condition/scenario_specific_eocs.json b/data/json/effects_on_condition/scenario_specific_eocs.json index 87b2d71491584..88852befc60d1 100644 --- a/data/json/effects_on_condition/scenario_specific_eocs.json +++ b/data/json/effects_on_condition/scenario_specific_eocs.json @@ -131,30 +131,13 @@ "type": "effect_on_condition", "id": "scenario_surrounded_zombie", "eoc_type": "SCENARIO_SPECIFIC", - "effect": [ - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 12, "max_radius": 20 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 12, "max_radius": 20 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 15, "max_radius": 22 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 15, "max_radius": 22 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 18, "max_radius": 30 } - ] + "effect": [ { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 5, "min_radius": 12, "max_radius": 30 } ] }, { "type": "effect_on_condition", "id": "scenario_surrounded_zombie_heavy", "eoc_type": "SCENARIO_SPECIFIC", - "effect": [ - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 14, "max_radius": 20 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 14, "max_radius": 20 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 14, "max_radius": 20 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 14, "max_radius": 20 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 18, "max_radius": 25 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 18, "max_radius": 25 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 18, "max_radius": 25 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 18, "max_radius": 25 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 20, "max_radius": 30 }, - { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 1, "min_radius": 20, "max_radius": 30 } - ] + "effect": [ { "u_spawn_monster": "GROUP_ZOMBIE", "group": true, "real_count": 10, "min_radius": 14, "max_radius": 30 } ] }, { "type": "effect_on_condition", diff --git a/data/json/monsters/zed_lieutenant.json b/data/json/monsters/zed_lieutenant.json index 6e1c9b2aaaf90..928fedb9ccf5d 100644 --- a/data/json/monsters/zed_lieutenant.json +++ b/data/json/monsters/zed_lieutenant.json @@ -165,9 +165,8 @@ { "u_spawn_monster": "GROUP_AMALGAMATIONS_SPAWNED", "group": true, - "//": "This always spawns 6 of the same type, which is not ideal (6 soldiers is way too deadly). Consider revising the weights if/when talk_effect_fun_t::set_spawn_monster can pick each individual spawn from the group.", "real_count": 6, - "//2": "The maximum lifespan should not be terribly longer than the cooldown(currently 20 seconds), or else multiple groups can be active at once and make this much harder than desired.", + "//": "The maximum lifespan should not be terribly longer than the cooldown(currently 20 seconds), or else multiple groups can be active at once and make this much harder than desired.", "lifespan": [ "15 seconds", "30 seconds" ], "target_var": { "global_val": "drain_terrain" } }, diff --git a/data/mods/Defense_Mode/effects_on_condition/wave_eocs.json b/data/mods/Defense_Mode/effects_on_condition/wave_eocs.json index e6aa527dadf19..d9c7ed6dd1da9 100644 --- a/data/mods/Defense_Mode/effects_on_condition/wave_eocs.json +++ b/data/mods/Defense_Mode/effects_on_condition/wave_eocs.json @@ -77,23 +77,7 @@ "effect": [ { "u_spawn_monster": "GROUP_VANILLA_ONLY_HUMANS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_VANILLA_ONLY_HUMANS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_VANILLA_ONLY_HUMANS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -109,23 +93,7 @@ "effect": [ { "u_spawn_monster": "GROUP_ZOMBIE", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_ZOMBIE", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_ZOMBIE", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -141,23 +109,7 @@ "effect": [ { "u_spawn_monster": "GROUP_SPIDER_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_SPIDER_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_SPIDER_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -173,23 +125,7 @@ "effect": [ { "u_spawn_monster": "GROUP_ROBOT_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_ROBOT_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_ROBOT_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -205,23 +141,7 @@ "effect": [ { "u_spawn_monster": "GROUP_TRIFFID_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_TRIFFID_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_TRIFFID_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -237,23 +157,7 @@ "effect": [ { "u_spawn_monster": "GROUP_NETHER_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_NETHER_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_NETHER_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -269,23 +173,7 @@ "effect": [ { "u_spawn_monster": "GROUP_FERAL", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_FERAL", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_FERAL", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -305,23 +193,7 @@ "effect": [ { "u_spawn_monster": "GROUP_RATKIN_EVOLVED", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_RATKIN_EVOLVED", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_RATKIN_EVOLVED", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -341,23 +213,7 @@ "effect": [ { "u_spawn_monster": "GROUP_MIL_HELIPAD", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_MIL_HELIPAD", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_MIL_HELIPAD", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/Aftershock/eocs.json b/data/mods/Defense_Mode/mod_interactions/Aftershock/eocs.json index e1dadfa0e4cd3..9d2dc4c50c8db 100644 --- a/data/mods/Defense_Mode/mod_interactions/Aftershock/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/Aftershock/eocs.json @@ -6,23 +6,7 @@ "effect": [ { "u_spawn_monster": "AFS_GROUP_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "AFS_GROUP_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "AFS_GROUP_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/DinoMod/eocs.json b/data/mods/Defense_Mode/mod_interactions/DinoMod/eocs.json index 7c4bd139d4c37..642fb9d88bde3 100644 --- a/data/mods/Defense_Mode/mod_interactions/DinoMod/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/DinoMod/eocs.json @@ -6,23 +6,7 @@ "effect": [ { "u_spawn_monster": "GROUP_DINOSAUR_DANGEROUS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_DINOSAUR_DANGEROUS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_DINOSAUR_DANGEROUS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/Magiclysm/eocs.json b/data/mods/Defense_Mode/mod_interactions/Magiclysm/eocs.json index 39470b5c402d4..d78bc806189c2 100644 --- a/data/mods/Defense_Mode/mod_interactions/Magiclysm/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/Magiclysm/eocs.json @@ -6,23 +6,7 @@ "effect": [ { "u_spawn_monster": "GROUP_LIZARDFOLK_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_LIZARDFOLK_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_LIZARDFOLK_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -38,23 +22,7 @@ "effect": [ { "u_spawn_monster": "GROUP_GOLEM_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_GOLEM_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_GOLEM_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -70,23 +38,7 @@ "effect": [ { "u_spawn_monster": "GROUP_GOBLIN_STANDARD", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_GOBLIN_STANDARD", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_GOBLIN_STANDARD", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -102,23 +54,7 @@ "effect": [ { "u_spawn_monster": "GROUP_ORC_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_ORC_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_ORC_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/Megafauna/eocs.json b/data/mods/Defense_Mode/mod_interactions/Megafauna/eocs.json index ca070881ef7a3..ad881eef1d8dd 100644 --- a/data/mods/Defense_Mode/mod_interactions/Megafauna/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/Megafauna/eocs.json @@ -6,23 +6,7 @@ "effect": [ { "u_spawn_monster": "GROUP_MEGAFAUNA_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_MEGAFAUNA_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_MEGAFAUNA_DM", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/MindOverMatter/eocs.json b/data/mods/Defense_Mode/mod_interactions/MindOverMatter/eocs.json index 6b399670b0ac2..0a5e038af8167 100644 --- a/data/mods/Defense_Mode/mod_interactions/MindOverMatter/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/MindOverMatter/eocs.json @@ -14,15 +14,7 @@ }, { "u_spawn_monster": "GROUP_VANILLA_ONLY_HUMANS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_VANILLA_ONLY_HUMANS", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 2" ], "default": 2 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/My_Sweet_Cataclysm/eocs.json b/data/mods/Defense_Mode/mod_interactions/My_Sweet_Cataclysm/eocs.json index ce48f736a7569..1a1da4f42bb0a 100644 --- a/data/mods/Defense_Mode/mod_interactions/My_Sweet_Cataclysm/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/My_Sweet_Cataclysm/eocs.json @@ -6,23 +6,7 @@ "effect": [ { "u_spawn_monster": "GROUP_SWEET_HORDE", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_SWEET_HORDE", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_SWEET_HORDE", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/Mythos/eocs.json b/data/mods/Defense_Mode/mod_interactions/Mythos/eocs.json index 7da7b7001ea24..702574de60dad 100644 --- a/data/mods/Defense_Mode/mod_interactions/Mythos/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/Mythos/eocs.json @@ -6,23 +6,7 @@ "effect": [ { "u_spawn_monster": "GROUP_MYTHOS_SPAWN", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_MYTHOS_SPAWN", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_MYTHOS_SPAWN", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/data/mods/Defense_Mode/mod_interactions/Xedra_Evolved/eocs.json b/data/mods/Defense_Mode/mod_interactions/Xedra_Evolved/eocs.json index aa6b5d15bd633..e71b62e366bd6 100644 --- a/data/mods/Defense_Mode/mod_interactions/Xedra_Evolved/eocs.json +++ b/data/mods/Defense_Mode/mod_interactions/Xedra_Evolved/eocs.json @@ -6,23 +6,7 @@ "effect": [ { "u_spawn_monster": "GROUP_DEFENSE_MODE_EXODII", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_DEFENSE_MODE_EXODII", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_DEFENSE_MODE_EXODII", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, @@ -38,23 +22,7 @@ "effect": [ { "u_spawn_monster": "GROUP_DEFENSE_MODE_XEDRA", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_DEFENSE_MODE_XEDRA", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, - "outdoor_only": true, - "group": true, - "min_radius": 20, - "max_radius": 40 - }, - { - "u_spawn_monster": "GROUP_DEFENSE_MODE_XEDRA", - "real_count": { "math": [ "wave_spawn_number()" ], "default": 1 }, + "real_count": { "math": [ "wave_spawn_number() * 3" ], "default": 3 }, "outdoor_only": true, "group": true, "min_radius": 20, diff --git a/doc/EFFECT_ON_CONDITION.md b/doc/EFFECT_ON_CONDITION.md index e4b4e021421b9..c19dbef549fbe 100644 --- a/doc/EFFECT_ON_CONDITION.md +++ b/doc/EFFECT_ON_CONDITION.md @@ -3688,10 +3688,11 @@ Spawn some monsters around you, NPC or `target_var` | Syntax | Optionality | Value | Info | | --- | --- | --- | --- | -| "u_spawn_monster", "npc_spawn_monster" | **mandatory** | string or [variable object](##variable-object) | monster that would be spawned | +| "u_spawn_monster", "npc_spawn_monster" | **mandatory** | string or [variable object](##variable-object) | monster or monstergroup that would be spawned, using "" picks randomly from nearby monsters | | "real_count" | optional | int, [variable object](##variable-object) or value between two | default 0; amount of monsters, that would be spawned | | "hallucination_count" | optional | int, [variable object](##variable-object) or value between two | default 0; amount of hallucination versions of the monster that would be spawned | -| "group" | optional | boolean | default false; if true, `_spawn_monster` would spawn a monster from `monstergroup`; the game pick only one monster from group, so to create mix from different monsters from monstergroup, multiple `u_spawn_monster` should be used | +| "group" | optional | boolean | default false; if true, `_spawn_monster` will spawn a monster from `monstergroup` | +| "single_target" | optional | boolean | default false; if true, `_spawn_monster` the game pick only one monster from the provided `monstergroup` or from nearby monsters | | "min_radius", "max_radius" | optional | int, [variable object](##variable-object) or value between two | default 1 and 10 respectively; range around the target, where the monster would spawn | | "outdoor_only"/ "indoor_only" | optional | boolean | default false; if used, monsters would be able to spawn only outside or only inside buildings | | "open_air_allowed" | optional | boolean | default false; if true, monsters can spawn in the open air | diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 84c7a116a5a35..dc60d38412c11 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -5658,6 +5658,7 @@ void talk_effect_fun_t::set_spawn_monster( const JsonObject &jo, std::string_vie bool is_npc ) { bool group = jo.get_bool( "group", false ); + bool single_target = jo.get_bool( "single_target", false ); str_or_var monster_id = get_str_or_var( jo.get_member( member ), member ); dbl_or_var dov_target_range = get_dbl_or_var( jo, "target_range", false, 0 ); dbl_or_var dov_hallucination_count = get_dbl_or_var( jo, "hallucination_count", false, 0 ); @@ -5683,29 +5684,63 @@ void talk_effect_fun_t::set_spawn_monster( const JsonObject &jo, std::string_vie std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); function = [monster_id, dov_target_range, dov_hallucination_count, dov_real_count, dov_min_radius, - dov_max_radius, outdoor_only, indoor_only, group, dov_lifespan, target_var, + dov_max_radius, outdoor_only, indoor_only, group, single_target, dov_lifespan, target_var, spawn_message, spawn_message_plural, true_eocs, false_eocs, open_air_allowed, friendly, is_npc]( dialogue & d ) { monster target_monster; + std::vector target_monsters; + mongroup_id target_mongroup; if( group ) { - target_monster = monster( MonsterGroupManager::GetRandomMonsterFromGroup( mongroup_id( - monster_id.evaluate( d ) ) ) ); + if( monster_id.evaluate( d ).empty() ) { + debugmsg( "Cannot use group without a valid monstergroup. %s", d.get_callstack() ); + } + if( single_target ) { + target_monster = monster( MonsterGroupManager::GetRandomMonsterFromGroup( mongroup_id( + monster_id.evaluate( d ) ) ) ); + } else { + target_mongroup = mongroup_id( monster_id.evaluate( d ) ); + } } else if( monster_id.evaluate( d ).empty() ) { int target_range = dov_target_range.evaluate( d ); - //grab a random nearby hostile creature to create a hallucination or copy of - Creature *copy = g->get_creature_if( [target_range]( const Creature & critter ) -> bool { - bool not_self = get_player_character().pos() != critter.pos(); - bool in_range = std::round( rl_dist_exact( get_player_character().pos(), critter.pos() ) ) <= target_range; - bool valid_target = get_player_character().attitude_to( critter ) == Creature::Attitude::HOSTILE; - return not_self && in_range && valid_target; - } ); - if( copy == nullptr ) { - run_eoc_vector( false_eocs, d ); - return; + if( single_target ) { + // Find a hostile creature in range to be used to create a hallucination or a copy of + Creature *copy = g->get_creature_if( [target_range]( const Creature & critter ) -> bool { + bool not_self = get_player_character().pos() != critter.pos(); + bool in_range = std::round( rl_dist_exact( get_player_character().pos(), critter.pos() ) ) <= target_range; + bool valid_target = get_player_character().attitude_to( critter ) == Creature::Attitude::HOSTILE; + return not_self && in_range && valid_target; + } ); + if( copy == nullptr ) { + run_eoc_vector( false_eocs, d ); + return; + } + target_monster = *copy->as_monster(); + } else { + // Find all hostile creatures in range to be used to create hallucinations or copies of + std::vector monsters_in_range = g->get_creatures_if( [target_range]( + const Creature & critter ) -> bool { + bool not_self = get_player_character().pos() != critter.pos(); + bool in_range = std::round( rl_dist_exact( get_player_character().pos(), critter.pos() ) ) <= target_range; + bool valid_target = get_player_character().attitude_to( critter ) == Creature::Attitude::HOSTILE; + return not_self && in_range && valid_target; + } ); + int valid_monsters = monsters_in_range.size(); + if( valid_monsters == 0 ) { + run_eoc_vector( false_eocs, d ); + return; + } else if( valid_monsters == 1 ) { + Creature *copy = monsters_in_range[0]; + target_monster = *copy->as_monster(); + } else { + target_monsters = monsters_in_range; + } } - target_monster = *copy->as_monster(); } else { + if( single_target ) { + debugmsg( "single_target should not be defined for a singlular monster_id. %s", + d.get_callstack() ); + } target_monster = monster( mtype_id( monster_id.evaluate( d ) ) ); } int min_radius = dov_min_radius.evaluate( d ); @@ -5721,6 +5756,14 @@ void talk_effect_fun_t::set_spawn_monster( const JsonObject &jo, std::string_vie int spawns = 0; for( int i = 0; i < hallucination_count; i++ ) { tripoint spawn_point; + if( !single_target ) { + if( group ) { + target_monster = monster( MonsterGroupManager::GetRandomMonsterFromGroup( target_mongroup ) ); + } else { + Creature *copy = target_monsters[ rng( 0, target_monsters.size() - 1 ) ]; + target_monster = *copy->as_monster(); + } + } if( g->find_nearby_spawn_point( target_pos, target_monster.type->id, min_radius, max_radius, spawn_point, outdoor_only, indoor_only, open_air_allowed ) ) { lifespan = dov_lifespan.evaluate( d ); @@ -5743,6 +5786,14 @@ void talk_effect_fun_t::set_spawn_monster( const JsonObject &jo, std::string_vie } for( int i = 0; i < real_count; i++ ) { tripoint spawn_point; + if( !single_target ) { + if( group ) { + target_monster = monster( MonsterGroupManager::GetRandomMonsterFromGroup( target_mongroup ) ); + } else { + Creature *copy = target_monsters[ rng( 0, target_monsters.size() - 1 ) ]; + target_monster = *copy->as_monster(); + } + } if( g->find_nearby_spawn_point( target_pos, target_monster.type->id, min_radius, max_radius, spawn_point, outdoor_only, indoor_only, open_air_allowed ) ) { monster *spawned = g->place_critter_at( target_monster.type->id, spawn_point );