From c952855442a48b59a0106af317fd58be38af5175 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 00:39:25 -0500 Subject: [PATCH 01/23] ambush controller stuff --- cev_eris.dme | 2 + code/__HELPERS/matrices.dm | 4 +- code/modules/mining/ambush.dm | 244 ++++++++++++++++++++++ code/modules/mining/ambush_structures.dm | 139 ++++++++++++ code/modules/mob/living/living_defines.dm | 3 + icons/obj/burrows.dmi | Bin 3557 -> 4114 bytes 6 files changed, 390 insertions(+), 2 deletions(-) create mode 100644 code/modules/mining/ambush.dm create mode 100644 code/modules/mining/ambush_structures.dm diff --git a/cev_eris.dme b/cev_eris.dme index d4b3c7fd594..55fbe207aec 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -1952,6 +1952,8 @@ #include "code\modules\media\mediamanager.dm" #include "code\modules\mining\abandonedcrates.dm" #include "code\modules\mining\alloys.dm" +#include "code\modules\mining\ambush.dm" +#include "code\modules\mining\ambush_structures.dm" #include "code\modules\mining\coins.dm" #include "code\modules\mining\machine_processing.dm" #include "code\modules\mining\machine_stacking.dm" diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index 5e66c27b4ba..8e5554f1e7b 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -43,11 +43,11 @@ animate(transform = transforms[3], time = 0.2) animate(transform = transforms[4], time = 0.3) -/atom/proc/shake_animation(intensity = 8) +/atom/proc/shake_animation(intensity = 8, duration = 0.5 SECONDS) var/init_px = pixel_x var/shake_dir = pick(-1, 1) animate(src, transform=turn(matrix(), intensity*shake_dir), pixel_x=init_px + 2*shake_dir, time=1) - animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING) + animate(transform=null, pixel_x=init_px, time=duration, easing=ELASTIC_EASING) /// Perform a shake on an atom, resets its position afterwards /atom/proc/Shake(pixelshiftx = 2, pixelshifty = 2, duration = 2.5 SECONDS, shake_interval = 0.02 SECONDS) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm new file mode 100644 index 00000000000..10722f72293 --- /dev/null +++ b/code/modules/mining/ambush.dm @@ -0,0 +1,244 @@ +#define AMBUSH_CLEANUP_DELAY 3 MINUTES //after the ambush ends, mobs & burrows will despawn this many minutes later. + +#define AMBUSH_SKIRMISH "ambush_skirmish" //burrows will immediately unload 1 wave of enemies, then close up +#define AMBUSH_SIEGE "ambush_siege" //burrows will periodically spawn mobs according to spawn_interval until the ambush ends. + +/datum/ambush_controller + + var/mob/living/ambushed_mob // the guy who triggered the ambush + var/turf/ambush_loc // Location of the ambush + var/list/obj/structure/ambush_burrow/burrows = list() // List of burrows tied to the controller + var/list/mob/living/carbon/superior_animal/ourmobs = list() // List of mobs tied to the controller + var/processing = TRUE + //var/obj/machinery/mining/deep_drill/DD + + var/datum/ambush_type/our_datum // ambush datum + var/count = 0 // Number of burrows created since the start + var/time_burrow = 0 // Timestamp of last created burrow + var/time_spawn = 0 // Timestamp of last spawn wave + var/start_time = 0 // reference to time ambush began + var/following = TRUE //Do ambush spawns appear around the mob who spawned them, even if they move? + +/datum/ambush_controller/New(turf/trigger_location, new_ambushed_mob, ambush_datum) + our_datum = new ambush_datum() + ambushed_mob = new_ambushed_mob + + if(!trigger_location || !our_datum)//if they forgot to pass a wave datum or trigger location, explode + log_runtime("[src.type] is missing required new() arguments!") + QDEL_NULL(src) + + if(ambushed_mob) //get the starting location for our ambush + ambush_loc = ambush_follow_check() + if(!ambush_loc) //if no ambushed mob, just use the trigger location + ambush_loc = trigger_location + + //give mobs in range a warning they're about to be ambushed + for(var/mob/ourmob in hearers(8, ambush_loc)) + ourmob.show_message(span_userdanger("You feel the ground tremble beneath you..."),2) + shake_camera(ourmob, 6, 0.5, 0.25) + playsound(ambush_loc, 'sound/effects/impacts/rumble4.ogg', 75, TRUE, extrarange = 4) + + start_time = world.time + START_PROCESSING(SSobj, src) + +/// gets the target's current loc if following is on or it hasn't been gotten before. +/datum/ambush_controller/proc/ambush_follow_check() + if((following || !ambush_loc) && ambushed_mob) + return ambushed_mob.loc + else//if no ambushed mob, just use existing loc + return ambush_loc + + +/datum/ambush_controller/Destroy() + processing = FALSE + QDEL_NULL(our_datum) + //DD = null + for(var/obj/structure/ambush_burrow/burrow in burrows) // Unlink burrows and controller + burrow.stop() + ..() + +/datum/ambush_controller/Process() + // Currently, STOP_PROCESSING does NOT instantly remove the object from processing queue + // This is a quick and dirty fix for runtime error spam caused by this + if(!processing) + return + + //our work here is done. End ambush + if(ambushed_mob.stat == DEAD || (world.time - start_time) - our_datum.setup_time >= our_datum.ambush_duration || count >= our_datum.spawn_cap) + stop() + + var/burrow_num = burrows.len + // Check if new burrows can be created + if((burrow_num < our_datum.max_burrows) && (world.time - time_burrow) > our_datum.burrow_interval) + time_burrow = world.time + for(var/mob/ourmob in hearers(8, ambush_loc)) + shake_camera(ourmob, 6, 0.5, 0.25) + for(var/burrow in 1 to our_datum.burrow_number) + count++ + spawn_burrow() + + if(our_datum.ambush_type == AMBUSH_SIEGE)//if we're in siege mode, ambush controller handles spawns directly + if((world.time - start_time) > our_datum.setup_time) + if((world.time - time_spawn) > our_datum.spawn_interval)// Check if a new spawn wave should occur + time_spawn = world.time + for(var/obj/structure/ambush_burrow/ourburrow in burrows) + if(!ourburrow.loc) // If the burrow is in nullspace for some reason + burrows -= ourburrow // Remove it from the pool of burrows + continue + ourburrow.spawn_mobs() + +///locates an appropriate turf to spawn a burrow, then creates it +/datum/ambush_controller/proc/spawn_burrow() + ambush_loc = ambush_follow_check() + // Spawn burrow randomly in a donut around our ambush turf + var/turf/burrow_turf = pick(getcircle(ambush_loc, 6)) + if(!istype(burrow_turf)) // Try again with a smaller circle + burrow_turf = pick(getcircle(ambush_loc, 5)) + if(!istype(burrow_turf)) // Something wrong is happening + log_and_message_admins("Ambush controller failed to create a new burrow around ([ambush_loc.x], [ambush_loc.y], [ambush_loc.z]).") + return + + //if we are in a closed space or target is not visible, move towards the spawn turf + while(ambush_loc && check_density_no_mobs(burrow_turf) && burrow_turf != ambush_loc || !can_see(burrow_turf, ambush_loc)) + burrow_turf = get_step(burrow_turf, get_dir(burrow_turf, ambush_loc)) + // If we end up on top of the trigger loc, just spawn next to it + if(burrow_turf == ambush_loc) + burrow_turf = get_step(ambush_loc, pick(GLOB.cardinal)) + + burrows += new /obj/structure/ambush_burrow(burrow_turf, src, our_datum) // Spawn burrow at final location + +///ends the ambush. Should preferentially be called before cleanup or a qdel +/datum/ambush_controller/proc/stop() + // Disable processing + processing = FALSE + //give mobs in range an indicate that it's over + for(var/mob/ourmob in hearers(8, ambush_loc)) + ourmob.show_message(span_danger("The shaking in the ground finally subsides."),2) + for(var/obj/structure/ambush_burrow/burrow in burrows) //visibly collapse burrows to show players it's over + burrow.crumble() + // Clean up controller and all remaining objects after given delay + addtimer(CALLBACK(src, PROC_REF(cleanup)), AMBUSH_CLEANUP_DELAY) + +///properly cleans up the controller. Final step of the deletion chain +/datum/ambush_controller/proc/cleanup() + // Delete any remaining burrows + for(var/obj/structure/ambush_burrow/burrow in burrows) + qdel(burrow) + + // Delete mobs + for(var/mob/living/carbon/superior_animal/mob in ourmobs) + if(mob.state == DEAD) + continue + qdel(mob) + + // Delete controller + qdel(src) + +//inherited from old golem controller. Why is it defined here? Good question +///check that determines if a turf is a wall or already holding a mob +/datum/ambush_controller/proc/check_density_no_mobs(turf/F) + if(F.density) + return TRUE + for(var/atom/A in F) + if(A.density && !(A.flags & ON_BORDER) && !ismob(A)) + return TRUE + return FALSE + +// AMBUSH TYPE DEFINES + + +/datum/ambush_type + //ambush behavior vars + /// Determines the logic burrows follow when spawning mobs + var/ambush_type = AMBUSH_SKIRMISH + /// Once this time passes, ambush ends + var/ambush_duration = 20 SECONDS + /// If set, ambush ends once this many burrows have spawned + var/spawn_cap = 8 + /// Amnt. of prep time given between when the ambush first triggers & mobs start spawning + var/setup_time = 5 SECONDS + + //burrow vars + /// If set, total number of burrows that can exist at any single time + var/max_burrows = 4 + /// the number of burrows to spawn in a single wave + var/burrow_number = 2 + /// Number of seconds that pass between each new burrow spawn wave + var/burrow_interval = 10 SECONDS + + //mob vars + /// Number of mobs spawned by each burrow on spawn event + var/mob_spawn = 3 + /// Probability of a mob being a special one instead of a normal one + var/special_probability = 35 + /// Types of mobs normally spawned by the ambush + var/list/normal_types = list(/mob/living/carbon/superior_animal/roach, + /mob/living/carbon/superior_animal/roach/hunter, + /mob/living/carbon/superior_animal/roach/support) + /// Types of unusual mobs to be passed to the spawn pool according to special_probability + var/list/special_types = list(/mob/living/carbon/superior_animal/roach/fuhrer, + /mob/living/carbon/superior_animal/roach/nanite, + /mob/living/carbon/superior_animal/roach/tank, + /mob/living/carbon/superior_animal/roach/toxic) + + ///Sound played before the ambush triggers + //var/ambush_sound = 'sound/effects/impacts/rumble4.ogg' + + //siege-specific vars + /// Number of seconds that pass between spawn events of burrows - if siege mode is enabled. + var/spawn_interval = 15 SECONDS + +/datum/ambush_type/golem + max_burrows = 6 + burrow_number = 3 + + special_probability = 5 + + normal_types = list(/mob/living/carbon/superior_animal/golem/coal, + /mob/living/carbon/superior_animal/golem/iron) + + special_types = list(/mob/living/carbon/superior_animal/golem/silver, + /mob/living/carbon/superior_animal/golem/gold, + /mob/living/carbon/superior_animal/golem/plasma, + /mob/living/carbon/superior_animal/golem/uranium) + + +// /datum/golem_wave/negligible +// burrow_count = 2 +// burrow_interval = 24 SECONDS +// golem_spawn = 2 +// spawn_interval = 20 SECONDS +// special_probability = 0 +// mineral_multiplier = 1.4 + +// /datum/golem_wave/typical +// burrow_count = 3 +// burrow_interval = 24 SECONDS +// golem_spawn = 3 +// spawn_interval = 18 SECONDS +// special_probability = 10 +// mineral_multiplier = 1.7 + +// /datum/golem_wave/substantial +// burrow_count = 3 +// burrow_interval = 24 SECONDS +// golem_spawn = 3 +// spawn_interval = 18 SECONDS +// special_probability = 20 +// mineral_multiplier = 2 + +// /datum/golem_wave/major +// burrow_count = 4 +// burrow_interval = 20 SECONDS +// golem_spawn = 4 +// spawn_interval = 14 SECONDS +// special_probability = 30 +// mineral_multiplier = 2.3 + +// /datum/golem_wave/abnormal +// burrow_count = 5 +// burrow_interval = 18 SECONDS +// golem_spawn = 4 +// spawn_interval = 12 SECONDS +// special_probability = 30 +// mineral_multiplier = 3.0 diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm new file mode 100644 index 00000000000..45a61c9c57e --- /dev/null +++ b/code/modules/mining/ambush_structures.dm @@ -0,0 +1,139 @@ +/obj/structure/ambush_burrow + name = "ambush burrow" + icon = 'icons/obj/burrows.dmi' + icon_state = "cracks_animated" + desc = "A pile of debris that regularly pulses and shifts. Something is coming..." + density = TRUE + anchored = TRUE + + maxHealth = 50 + health = 50 + explosion_coverage = 0.3 + var/datum/ambush_controller/controller + var/datum/ambush_type/our_ambush + +/obj/structure/ambush_burrow/New(loc, parent, ambush_datum) + ..() + controller = parent // Link burrow with controller + our_ambush = ambush_datum //Give burrow datum + if(!controller || !our_ambush) + log_runtime("[src.type] was spawned without required arguments!") + stop() + + shake_animation(duration = our_ambush.setup_time) + if(our_ambush.ambush_type == AMBUSH_SKIRMISH) + addtimer(CALLBACK(src, PROC_REF(spawn_mobs)), our_ambush.setup_time) + +///now we actually do the heavy lifting. +/obj/structure/ambush_burrow/proc/spawn_mobs() + + shake_animation(intensity = 14)//shake again for good measure + playsound(src, pick(crumble_sound), 40) + icon_state = "maint_hole" + //get potential directions to place a mob + var/list/possible_directions = GLOB.cardinal.Copy() + var/mobs_spawned = 0 + var/probability = our_ambush.special_probability + + while(mobs_spawned < our_ambush.mob_spawn && possible_directions.len) + var/turf/possible_T = get_step(loc, pick_n_take(possible_directions)) + new /obj/effect/decal/cleanable/rubble(possible_T) + var/mobtype + if(prob(probability))//if prob allows, pick a special mob + mobtype = pick(our_ambush.special_types) + //proba = max(0, probability - 5) // Decreasing probability to avoid mass spam of special mobs + else + mobtype = pick(our_ambush.normal_types) // Pick a normal mob + if(!controller.check_density_no_mobs(possible_T)) + new mobtype(possible_T) // Spawn mob at free location + else + new mobtype(loc) + mobs_spawned++ + if(our_ambush.ambush_type == AMBUSH_SKIRMISH) + addtimer(CALLBACK(src, PROC_REF(crumble)), 2 SECONDS) + +///visibly indicates to players that this burrow is out of commission. Also preps for deletion +/obj/structure/ambush_burrow/proc/crumble() + icon_state = "maint_hole_collapsed" + desc = "It's filled with lose debris. As you watch, it begins to crumble away..." + addtimer(CALLBACK(src, PROC_REF(stop)), 5 SECOND) + +/obj/structure/ambush_burrow/Destroy() + visible_message(SPAN_DANGER("\The [src] crumbles away!")) + new /obj/effect/decal/cleanable/rubble(src.loc) + if(controller) + controller.burrows -= src + controller = null + ..() + +/obj/structure/ambush_burrow/attack_generic(mob/user, damage) + user.do_attack_animation(src) + visible_message(SPAN_DANGER("\The [user] smashes \the [src]!")) + take_damage(damage) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN * 1.5) + +/obj/structure/ambush_burrow/attackby(obj/item/I, mob/user) + if (user.a_intent == I_HURT && user.Adjacent(src)) + if(!(I.flags & NOBLUDGEON)) + user.do_attack_animation(src) + var/damage = I.force * I.structure_damage_factor + var/volume = min(damage * 3.5, 15) + if (I.hitsound) + playsound(src, I.hitsound, volume, 1, -1) + visible_message(SPAN_DANGER("[src] has been hit by [user] with [I].")) + take_damage(damage) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN * 1.5) + return TRUE + +/obj/structure/ambush_burrow/bullet_act(obj/item/projectile/Proj) + ..() + // Bullet not really efficient against a pile of debris + take_damage(Proj.get_structure_damage() * 0.25) + +/obj/structure/ambush_burrow/take_damage(damage) + . = health - damage < 0 ? damage - (damage - health) : damage + . *= explosion_coverage + health = min(max(health - damage, 0), maxHealth) + if(health == 0) + qdel(src) + return + +/obj/structure/ambush_burrow/proc/stop() + qdel(src) // Delete burrow + +///lies in wait until a human mob enters its watched turfs, then creates an ambush event tied to them +/obj/effect/ambush_snare + name = "Ambush Trigger" + icon = 'icons/misc/landmarks.dmi' + icon_state = "trap_red" + alpha = 120 + anchored = TRUE + unacidable = 1 + simulated = FALSE + invisibility = 101 + ///the proximity trigger used to detect mobs in nearby turfs + var/datum/proximity_trigger/square/snare + ///the type of ambush deployed by this snare + var/datum/ambush_type/our_ambush_type = /datum/ambush_type + ///the range of turfs detected by this snare + var/triprange = 7 + +/obj/effect/ambush_snare/New() + ..() + snare = new(src, /obj/effect/ambush_snare/proc/trip_snare, /obj/effect/ambush_snare/proc/trip_snare, triprange, proc_owner = src) + snare.register_turfs() + +///triggers an ambush on the target, if they're human +/obj/effect/ambush_snare/proc/trip_snare(sucker) + if(!isturf(loc) || !ishuman(sucker) || !can_see(src, sucker))//let's keep this on visible players for now + return + var/mob/living/livingsucker = sucker + if(livingsucker.ambushed)//don't spam ambushes if someone walks into multiple snares + return + new /datum/ambush_controller(loc, sucker, our_ambush_type) + qdel(src) + +//gc our prox trigger +/obj/effect/ambush_snare/Destroy() + QDEL_NULL(snare) + ..() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index d03845c3605..96890ca51b7 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -112,3 +112,6 @@ spawn_frequency = 10 bad_type = /mob/living + + //set to TRUE while this mob is being ambushed. Prevents multiple ambush events from triggering at once. + var/ambushed = FALSE diff --git a/icons/obj/burrows.dmi b/icons/obj/burrows.dmi index 57cc6207d5b59f22fd6b4a40d035891cd6af66ee..5d657dcaaa849771e7f8c9698f16412746130f6b 100644 GIT binary patch delta 4087 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 delta 3526 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 AO#lD@ From c4e3959cceb0873322617578906e02e502999d10 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 02:58:28 -0500 Subject: [PATCH 02/23] misinput --- code/modules/mining/ambush.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 10722f72293..42dbd58bcfe 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -127,7 +127,7 @@ // Delete mobs for(var/mob/living/carbon/superior_animal/mob in ourmobs) - if(mob.state == DEAD) + if(mob.stat == DEAD) continue qdel(mob) From d27946a95af17d57f92adcb96c30cfa119e919eb Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:06:43 -0500 Subject: [PATCH 03/23] comment cleanup --- code/modules/mining/ambush.dm | 39 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 42dbd58bcfe..b2079bb6023 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -1,23 +1,33 @@ -#define AMBUSH_CLEANUP_DELAY 3 MINUTES //after the ambush ends, mobs & burrows will despawn this many minutes later. +#define AMBUSH_CLEANUP_DELAY 3 MINUTES //after the ambush ends, living mobs & any remaining burrows will be deleted this many minutes later. #define AMBUSH_SKIRMISH "ambush_skirmish" //burrows will immediately unload 1 wave of enemies, then close up #define AMBUSH_SIEGE "ambush_siege" //burrows will periodically spawn mobs according to spawn_interval until the ambush ends. /datum/ambush_controller - var/mob/living/ambushed_mob // the guy who triggered the ambush - var/turf/ambush_loc // Location of the ambush - var/list/obj/structure/ambush_burrow/burrows = list() // List of burrows tied to the controller - var/list/mob/living/carbon/superior_animal/ourmobs = list() // List of mobs tied to the controller + ///the mob that triggered the ambush + var/mob/living/ambushed_mob + /// The location of the ambush + var/turf/ambush_loc + /// A List of burrows tied to this controller + var/list/obj/structure/ambush_burrow/burrows = list() + /// A List of mobs tied to this controller + var/list/mob/living/carbon/superior_animal/ourmobs = list() + ///Allegedly used to keep processing() from runtiming var/processing = TRUE - //var/obj/machinery/mining/deep_drill/DD - var/datum/ambush_type/our_datum // ambush datum - var/count = 0 // Number of burrows created since the start - var/time_burrow = 0 // Timestamp of last created burrow - var/time_spawn = 0 // Timestamp of last spawn wave - var/start_time = 0 // reference to time ambush began - var/following = TRUE //Do ambush spawns appear around the mob who spawned them, even if they move? + ///A datum containing the behavior of our ambush + var/datum/ambush_type/our_datum + /// Number of burrows created since the start of the ambush + var/count = 0 + /// A Timestamp of the last created burrow + var/time_burrow = 0 + // A Timestamp of last spawn wave (in siege mode) + var/time_spawn = 0 + /// reference to time ambush began + var/start_time = 0 + ///Do ambush burrows appear around the mob who spawned them, even if they move? + var/following = TRUE /datum/ambush_controller/New(turf/trigger_location, new_ambushed_mob, ambush_datum) our_datum = new ambush_datum() @@ -52,12 +62,12 @@ /datum/ambush_controller/Destroy() processing = FALSE QDEL_NULL(our_datum) - //DD = null for(var/obj/structure/ambush_burrow/burrow in burrows) // Unlink burrows and controller burrow.stop() ..() /datum/ambush_controller/Process() + // I'm too scared to test this -Sun // Currently, STOP_PROCESSING does NOT instantly remove the object from processing queue // This is a quick and dirty fix for runtime error spam caused by this if(!processing) @@ -144,9 +154,10 @@ return TRUE return FALSE -// AMBUSH TYPE DEFINES +// AMBUSH TYPE DEFINES + /datum/ambush_type //ambush behavior vars /// Determines the logic burrows follow when spawning mobs From fd071a6443b907eb72d3b05d25aa1d8296021102 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:34:17 -0500 Subject: [PATCH 04/23] improve burrow placement logic + customization --- code/modules/mining/ambush.dm | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index b2079bb6023..937a0ca7900 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -101,12 +101,16 @@ /datum/ambush_controller/proc/spawn_burrow() ambush_loc = ambush_follow_check() // Spawn burrow randomly in a donut around our ambush turf - var/turf/burrow_turf = pick(getcircle(ambush_loc, 6)) - if(!istype(burrow_turf)) // Try again with a smaller circle - burrow_turf = pick(getcircle(ambush_loc, 5)) - if(!istype(burrow_turf)) // Something wrong is happening - log_and_message_admins("Ambush controller failed to create a new burrow around ([ambush_loc.x], [ambush_loc.y], [ambush_loc.z]).") - return + var/radius = our_datum.burrow_spawn_range + var/turf/burrow_turf + while(radius > 2) + burrow_turf = pick(getcircle(ambush_loc, radius)) + if(!istype(burrow_turf)) // Try again with a smaller circle + radius-- + continue + if(!istype(burrow_turf)) // Something wrong is happening + log_and_message_admins("Ambush controller failed to create a new burrow around ([ambush_loc.x], [ambush_loc.y], [ambush_loc.z]).") + return //if we are in a closed space or target is not visible, move towards the spawn turf while(ambush_loc && check_density_no_mobs(burrow_turf) && burrow_turf != ambush_loc || !can_see(burrow_turf, ambush_loc)) @@ -166,8 +170,8 @@ var/ambush_duration = 20 SECONDS /// If set, ambush ends once this many burrows have spawned var/spawn_cap = 8 - /// Amnt. of prep time given between when the ambush first triggers & mobs start spawning - var/setup_time = 5 SECONDS + /// Amnt. of prep time given between when the burrows first appear & mobs start spawning + var/setup_time = 4 SECONDS //burrow vars /// If set, total number of burrows that can exist at any single time @@ -176,6 +180,8 @@ var/burrow_number = 2 /// Number of seconds that pass between each new burrow spawn wave var/burrow_interval = 10 SECONDS + ///the starting range at which the ambush controller will try to place burrows + var/burrow_spawn_range = 6 //mob vars /// Number of mobs spawned by each burrow on spawn event From d8c0292707a2cd4fa8318d11874a7f07dc3c76da Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:38:49 -0500 Subject: [PATCH 05/23] Update code/modules/mining/ambush.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 937a0ca7900..e1cade2292b 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -36,6 +36,7 @@ if(!trigger_location || !our_datum)//if they forgot to pass a wave datum or trigger location, explode log_runtime("[src.type] is missing required new() arguments!") QDEL_NULL(src) + return if(ambushed_mob) //get the starting location for our ambush ambush_loc = ambush_follow_check() From f7f3b642a0b6cbd77c31c70a23c3fd46aaaa9bcd Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:38:57 -0500 Subject: [PATCH 06/23] Update code/modules/mining/ambush.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index e1cade2292b..9ab00c57e01 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -44,7 +44,7 @@ ambush_loc = trigger_location //give mobs in range a warning they're about to be ambushed - for(var/mob/ourmob in hearers(8, ambush_loc)) + for(var/mob/ourmob as anything in hearers(8, ambush_loc)) ourmob.show_message(span_userdanger("You feel the ground tremble beneath you..."),2) shake_camera(ourmob, 6, 0.5, 0.25) playsound(ambush_loc, 'sound/effects/impacts/rumble4.ogg', 75, TRUE, extrarange = 4) From bd1443a4f0d662f934682e6336fc5fd24fbc240c Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:41:34 -0500 Subject: [PATCH 07/23] fixes --- code/modules/mining/ambush.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 9ab00c57e01..c1942e7df16 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -62,10 +62,10 @@ /datum/ambush_controller/Destroy() processing = FALSE - QDEL_NULL(our_datum) for(var/obj/structure/ambush_burrow/burrow in burrows) // Unlink burrows and controller burrow.stop() - ..() + QDEL_NULL(our_datum) + . = ..() /datum/ambush_controller/Process() // I'm too scared to test this -Sun @@ -82,7 +82,7 @@ // Check if new burrows can be created if((burrow_num < our_datum.max_burrows) && (world.time - time_burrow) > our_datum.burrow_interval) time_burrow = world.time - for(var/mob/ourmob in hearers(8, ambush_loc)) + for(var/mob/ourmob as anything in hearers(8, ambush_loc)) shake_camera(ourmob, 6, 0.5, 0.25) for(var/burrow in 1 to our_datum.burrow_number) count++ @@ -127,7 +127,7 @@ // Disable processing processing = FALSE //give mobs in range an indicate that it's over - for(var/mob/ourmob in hearers(8, ambush_loc)) + for(var/mob/ourmob as anything in hearers(8, ambush_loc)) ourmob.show_message(span_danger("The shaking in the ground finally subsides."),2) for(var/obj/structure/ambush_burrow/burrow in burrows) //visibly collapse burrows to show players it's over burrow.crumble() From 0de469ae8956020d3caf835c60a58df7ec740ba7 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:42:40 -0500 Subject: [PATCH 08/23] Update code/modules/mining/ambush.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush.dm | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index c1942e7df16..d02ca6b7e39 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -88,15 +88,25 @@ count++ spawn_burrow() - if(our_datum.ambush_type == AMBUSH_SIEGE)//if we're in siege mode, ambush controller handles spawns directly - if((world.time - start_time) > our_datum.setup_time) - if((world.time - time_spawn) > our_datum.spawn_interval)// Check if a new spawn wave should occur - time_spawn = world.time - for(var/obj/structure/ambush_burrow/ourburrow in burrows) - if(!ourburrow.loc) // If the burrow is in nullspace for some reason - burrows -= ourburrow // Remove it from the pool of burrows - continue - ourburrow.spawn_mobs() + // if we're in siege mode, ambush controller handles spawns directly + if(our_datum.ambush_type != AMBUSH_SIEGE) + return + + if((world.time - start_time) <= our_datum.setup_time) + return + + // Check if a new spawn wave should occur + if((world.time - time_spawn) <= our_datum.spawn_interval) + return + + time_spawn = world.time + + for(var/obj/structure/ambush_burrow/ourburrow as anything in burrows) + if(!get_turf(ourburrow)) // If the burrow is in nullspace for some reason + burrows -= ourburrow // Remove it from the pool of burrows + continue + ourburrow.spawn_mobs() + ///locates an appropriate turf to spawn a burrow, then creates it /datum/ambush_controller/proc/spawn_burrow() From 10c99f894f387c39c68a6022426728e8e30eec01 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:43:25 -0500 Subject: [PATCH 09/23] Update code/modules/mining/ambush.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index d02ca6b7e39..bb45f2f3df0 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -147,16 +147,15 @@ ///properly cleans up the controller. Final step of the deletion chain /datum/ambush_controller/proc/cleanup() // Delete any remaining burrows - for(var/obj/structure/ambush_burrow/burrow in burrows) + for(var/obj/structure/ambush_burrow/burrow as anything in burrows) qdel(burrow) // Delete mobs - for(var/mob/living/carbon/superior_animal/mob in ourmobs) + for(var/mob/living/carbon/superior_animal/mob as anything in ourmobs) if(mob.stat == DEAD) continue qdel(mob) - // Delete controller qdel(src) //inherited from old golem controller. Why is it defined here? Good question From 395c1d38e6e10977ecd18fd87627f874602af721 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:43:40 -0500 Subject: [PATCH 10/23] Update code/modules/mining/ambush.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index bb45f2f3df0..5868e111729 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -188,7 +188,7 @@ var/max_burrows = 4 /// the number of burrows to spawn in a single wave var/burrow_number = 2 - /// Number of seconds that pass between each new burrow spawn wave + /// Number of seconds that pass between each new burrow spawn wave var/burrow_interval = 10 SECONDS ///the starting range at which the ambush controller will try to place burrows var/burrow_spawn_range = 6 From 05dc2670557e5c026b74e4f272d93546dffdfea0 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:48:45 -0500 Subject: [PATCH 11/23] removes stop() from burrows --- code/modules/mining/ambush.dm | 2 +- code/modules/mining/ambush_structures.dm | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index c1942e7df16..40be0933b1f 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -63,7 +63,7 @@ /datum/ambush_controller/Destroy() processing = FALSE for(var/obj/structure/ambush_burrow/burrow in burrows) // Unlink burrows and controller - burrow.stop() + QDEL(burrow) QDEL_NULL(our_datum) . = ..() diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index 45a61c9c57e..31fc90aa3c6 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -18,7 +18,7 @@ our_ambush = ambush_datum //Give burrow datum if(!controller || !our_ambush) log_runtime("[src.type] was spawned without required arguments!") - stop() + QDEL(src) shake_animation(duration = our_ambush.setup_time) if(our_ambush.ambush_type == AMBUSH_SKIRMISH) @@ -56,7 +56,7 @@ /obj/structure/ambush_burrow/proc/crumble() icon_state = "maint_hole_collapsed" desc = "It's filled with lose debris. As you watch, it begins to crumble away..." - addtimer(CALLBACK(src, PROC_REF(stop)), 5 SECOND) + QDEL_IN(src, 3 SECONDS) /obj/structure/ambush_burrow/Destroy() visible_message(SPAN_DANGER("\The [src] crumbles away!")) @@ -98,9 +98,6 @@ qdel(src) return -/obj/structure/ambush_burrow/proc/stop() - qdel(src) // Delete burrow - ///lies in wait until a human mob enters its watched turfs, then creates an ambush event tied to them /obj/effect/ambush_snare name = "Ambush Trigger" From 4f964888980f260eb1914c389635648f6d92ce6e Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:49:44 -0500 Subject: [PATCH 12/23] Update code/modules/mining/ambush_structures.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush_structures.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index 31fc90aa3c6..1312420c141 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -133,4 +133,4 @@ //gc our prox trigger /obj/effect/ambush_snare/Destroy() QDEL_NULL(snare) - ..() + . = ..() From 9abcce8d1ca4dbe35cbe9f6b388ed265c5929491 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:50:14 -0500 Subject: [PATCH 13/23] Update code/modules/mining/ambush_structures.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush_structures.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index 1312420c141..86f1cb59551 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -59,7 +59,7 @@ QDEL_IN(src, 3 SECONDS) /obj/structure/ambush_burrow/Destroy() - visible_message(SPAN_DANGER("\The [src] crumbles away!")) + visible_message(span_danger("\The [src] crumbles away!")) new /obj/effect/decal/cleanable/rubble(src.loc) if(controller) controller.burrows -= src From 99e729ba83ed8b1a3fdee7739b99ab6f92f2ff77 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:50:25 -0500 Subject: [PATCH 14/23] Update code/modules/mining/ambush_structures.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush_structures.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index 86f1cb59551..26df7bf1e0f 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -68,7 +68,7 @@ /obj/structure/ambush_burrow/attack_generic(mob/user, damage) user.do_attack_animation(src) - visible_message(SPAN_DANGER("\The [user] smashes \the [src]!")) + visible_message(span_danger("\The [user] smashes \the [src]!")) take_damage(damage) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN * 1.5) From 2ce1cc88706cb910f317f1ed63e99e20ece648e0 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 03:50:33 -0500 Subject: [PATCH 15/23] Update code/modules/mining/ambush_structures.dm Co-authored-by: Chen Marisa <18307183+flleeppyy@users.noreply.github.com> --- code/modules/mining/ambush_structures.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index 26df7bf1e0f..dd347fff361 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -80,7 +80,7 @@ var/volume = min(damage * 3.5, 15) if (I.hitsound) playsound(src, I.hitsound, volume, 1, -1) - visible_message(SPAN_DANGER("[src] has been hit by [user] with [I].")) + visible_message(span_danger("[src] has been hit by [user] with [I].")) take_damage(damage) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN * 1.5) return TRUE From f2fce41f0ac5b2ca748a8cf94fd9b9f369ca6d64 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 04:18:11 -0500 Subject: [PATCH 16/23] oops --- code/modules/mining/ambush.dm | 2 +- code/modules/mining/ambush_structures.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 7ed180226a6..b91f0442d17 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -63,7 +63,7 @@ /datum/ambush_controller/Destroy() processing = FALSE for(var/obj/structure/ambush_burrow/burrow in burrows) // Unlink burrows and controller - QDEL(burrow) + qdel(burrow) QDEL_NULL(our_datum) . = ..() diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index dd347fff361..ffc18e143e9 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -18,7 +18,7 @@ our_ambush = ambush_datum //Give burrow datum if(!controller || !our_ambush) log_runtime("[src.type] was spawned without required arguments!") - QDEL(src) + qdel(src) shake_animation(duration = our_ambush.setup_time) if(our_ambush.ambush_type == AMBUSH_SKIRMISH) From 7f3debbe402589c7f6c6dfd010c8d71d489c7e5c Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 04:44:21 -0500 Subject: [PATCH 17/23] total var/ambushed death this feels like a violation of sacred ground --- code/controllers/subsystems/processing/mobs.dm | 3 +++ code/modules/mining/ambush.dm | 15 ++++++++++++++- code/modules/mining/ambush_structures.dm | 2 +- code/modules/mob/living/living_defines.dm | 2 -- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystems/processing/mobs.dm b/code/controllers/subsystems/processing/mobs.dm index d8ca0822258..2c18bb54eba 100644 --- a/code/controllers/subsystems/processing/mobs.dm +++ b/code/controllers/subsystems/processing/mobs.dm @@ -9,9 +9,12 @@ PROCESSING_SUBSYSTEM_DEF(mobs) var/list/mob_list var/list/mob_living_by_zlevel[][] + ///used by ambushcode to keep track of which mobs are currently involved in ambushes + var/list/ambushed_mobs /datum/controller/subsystem/processing/mobs/PreInit() mob_list = processing // Simply setups a more recognizable var name than "processing" + ambushed_mobs = new() MaxZChanged() /datum/controller/subsystem/processing/mobs/proc/MaxZChanged() diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index b91f0442d17..2e7e1874e2d 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -29,6 +29,9 @@ ///Do ambush burrows appear around the mob who spawned them, even if they move? var/following = TRUE + ///Essentially local list of ambushed mobs, to compare ssmobs.ambushed_mobs to + var/list/our_ambushed_mobs + /datum/ambush_controller/New(turf/trigger_location, new_ambushed_mob, ambush_datum) our_datum = new ambush_datum() ambushed_mob = new_ambushed_mob @@ -43,8 +46,12 @@ if(!ambush_loc) //if no ambushed mob, just use the trigger location ambush_loc = trigger_location + var/list/our_ambushed_mobs = new() //give mobs in range a warning they're about to be ambushed - for(var/mob/ourmob as anything in hearers(8, ambush_loc)) + for(var/mob/living/ourmob as anything in hearers(8, ambush_loc)) + //add the mob to ambush reference lists + our_ambushed_mobs += ourmob + SSmobs.ambushed_mobs += ourmob ourmob.show_message(span_userdanger("You feel the ground tremble beneath you..."),2) shake_camera(ourmob, 6, 0.5, 0.25) playsound(ambush_loc, 'sound/effects/impacts/rumble4.ogg', 75, TRUE, extrarange = 4) @@ -62,6 +69,9 @@ /datum/ambush_controller/Destroy() processing = FALSE + //just in case the controller was qdel'd + for(var/mob/living/ambushee as anything in our_ambushed_mobs) + SSmobs.ambushed_mobs.Remove(ambushee) for(var/obj/structure/ambush_burrow/burrow in burrows) // Unlink burrows and controller qdel(burrow) QDEL_NULL(our_datum) @@ -141,6 +151,9 @@ ourmob.show_message(span_danger("The shaking in the ground finally subsides."),2) for(var/obj/structure/ambush_burrow/burrow in burrows) //visibly collapse burrows to show players it's over burrow.crumble() + //allow mobs in the original ambush range to once again trigger ambushes + for(var/mob/living/ambushee as anything in our_ambushed_mobs) + SSmobs.ambushed_mobs.Remove(ambushee) // Clean up controller and all remaining objects after given delay addtimer(CALLBACK(src, PROC_REF(cleanup)), AMBUSH_CLEANUP_DELAY) diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index ffc18e143e9..7d9f50a6b71 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -125,7 +125,7 @@ if(!isturf(loc) || !ishuman(sucker) || !can_see(src, sucker))//let's keep this on visible players for now return var/mob/living/livingsucker = sucker - if(livingsucker.ambushed)//don't spam ambushes if someone walks into multiple snares + if(livingsucker in SSmobs.ambushed_mobs)//don't spam ambushes if someone walks into multiple snares return new /datum/ambush_controller(loc, sucker, our_ambush_type) qdel(src) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 96890ca51b7..dfbef5cfcaa 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -113,5 +113,3 @@ spawn_frequency = 10 bad_type = /mob/living - //set to TRUE while this mob is being ambushed. Prevents multiple ambush events from triggering at once. - var/ambushed = FALSE From 424ad179822f81fc153b477d81dc0c1e5a68347a Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 8 Nov 2025 05:37:59 -0500 Subject: [PATCH 18/23] minor stuff forgot to remove that def + desc stuff --- code/modules/mining/ambush_structures.dm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/modules/mining/ambush_structures.dm b/code/modules/mining/ambush_structures.dm index 7d9f50a6b71..ee08cead2f2 100644 --- a/code/modules/mining/ambush_structures.dm +++ b/code/modules/mining/ambush_structures.dm @@ -1,5 +1,5 @@ /obj/structure/ambush_burrow - name = "ambush burrow" + name = "burrow" icon = 'icons/obj/burrows.dmi' icon_state = "cracks_animated" desc = "A pile of debris that regularly pulses and shifts. Something is coming..." @@ -55,7 +55,7 @@ ///visibly indicates to players that this burrow is out of commission. Also preps for deletion /obj/structure/ambush_burrow/proc/crumble() icon_state = "maint_hole_collapsed" - desc = "It's filled with lose debris. As you watch, it begins to crumble away..." + desc = "It's filled with loose debris. As you watch, it begins to crumble away..." QDEL_IN(src, 3 SECONDS) /obj/structure/ambush_burrow/Destroy() @@ -124,8 +124,7 @@ /obj/effect/ambush_snare/proc/trip_snare(sucker) if(!isturf(loc) || !ishuman(sucker) || !can_see(src, sucker))//let's keep this on visible players for now return - var/mob/living/livingsucker = sucker - if(livingsucker in SSmobs.ambushed_mobs)//don't spam ambushes if someone walks into multiple snares + if(sucker in SSmobs.ambushed_mobs)//don't spam ambushes if someone walks into multiple snares return new /datum/ambush_controller(loc, sucker, our_ambush_type) qdel(src) From 9ba4d7c6cee9a51f5663397f1fced57eaf8570d7 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sun, 9 Nov 2025 07:06:19 -0500 Subject: [PATCH 19/23] WIP anmbush implementation & golem pathing for when I do cave implementation --- code/modules/dungeons/procedural/deepmaint.dm | 10 ++ code/modules/mining/ambush.dm | 111 +++++++++++------- 2 files changed, 78 insertions(+), 43 deletions(-) diff --git a/code/modules/dungeons/procedural/deepmaint.dm b/code/modules/dungeons/procedural/deepmaint.dm index 42420eb16d9..c0bdb66cad0 100644 --- a/code/modules/dungeons/procedural/deepmaint.dm +++ b/code/modules/dungeons/procedural/deepmaint.dm @@ -126,6 +126,8 @@ var/global/list/big_deepmaint_room_templates = list() /obj/procedural/jp_DungeonGenerator/deepmaint/proc/makeNiche(turf/T) var/list/nicheline = list() + //only 1 hard encounter per niche zone please + var/ambush_placed = FALSE for(var/i in list(NORTH,EAST,SOUTH,WEST)) //Checks range of 5 tiles in all 4 directions from the turf tile being passed switch(i) if(NORTH) @@ -146,6 +148,8 @@ var/global/list/big_deepmaint_room_templates = list() for(var/turf/W in nicheline) //Every turf in the path returned by findNicheTurfs has a 30% chance of becoming a random deepmaint machine if(prob(30)) new /obj/spawner/pack/deep_machine(W) + if(prob(1)) + new /obj/effect/ambush_snare for(var/turf/W in wall_line) //Every turf in the path returned by checkForWalls is turned into a floor tile, and has a 70% chance of becoming a random deepmaint machine if(locate(/obj/machinery/light/small/autoattach, W)) var/obj/machinery/light/small/autoattach/L = locate(/obj/machinery/light/small/autoattach, W) @@ -176,6 +180,7 @@ var/global/list/big_deepmaint_room_templates = list() var/niche_count = 20 var/try_count = niche_count * 7 //In case it somehow zig-zags all of the corridors and stucks in a loop var/trap_count = 100 + var/ambush_count = rand(4, 8)// Add a few ambushes in corridors to keep players on their toes var/list/path_turfs_copy = path_turfs.Copy() while(niche_count > 0 && try_count > 0) try_count = try_count - 1 @@ -188,6 +193,11 @@ var/global/list/big_deepmaint_room_templates = list() var/turf/N = pick(path_turfs_copy) path_turfs_copy -= N new /obj/spawner/traps(N) + while(ambush_count > 0) + ambush_count = ambush_count - 1 + var/turf/ourturf = pick(path_turfs_copy) + path_turfs_copy -= ourturf + new /obj/effect/ambush_snare(ourturf) for(var/turf/T in path_turfs) if(prob(30)) new /obj/effect/decal/cleanable/dirt(T) //Wanted to put rust on the floors in deep maint, but by god, the overlay looks like ASS diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 2e7e1874e2d..0f7b4563097 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -182,9 +182,7 @@ return FALSE - -// AMBUSH TYPE DEFINES - +///contains the code that manages an ambush controller's behavior /datum/ambush_type //ambush behavior vars /// Determines the logic burrows follow when spawning mobs @@ -228,57 +226,84 @@ /// Number of seconds that pass between spawn events of burrows - if siege mode is enabled. var/spawn_interval = 15 SECONDS + +// AMBUSH TYPE DEFINES + /datum/ambush_type/golem + ambush_duration = 30 SECONDS + spawn_cap = 12 + max_burrows = 6 burrow_number = 3 - special_probability = 5 + special_probability = 25 normal_types = list(/mob/living/carbon/superior_animal/golem/coal, /mob/living/carbon/superior_animal/golem/iron) special_types = list(/mob/living/carbon/superior_animal/golem/silver, + /mob/living/carbon/superior_animal/golem/silver/enhanced, /mob/living/carbon/superior_animal/golem/gold, + /mob/living/carbon/superior_animal/golem/plasma, + /mob/living/carbon/superior_animal/golem/ansible, + /mob/living/carbon/superior_animal/golem/coal/enhanced, + /mob/living/carbon/superior_animal/golem/diamond, + /mob/living/carbon/superior_animal/golem/uranium) + + +/datum/ambush_type/golem/beginner + special_probability = 0 + + +/datum/ambush_type/golem/novice + special_probability = 25 + + special_types = list(/mob/living/carbon/superior_animal/golem/silver) + + +/datum/ambush_type/golem/adept + normal_types = list(/mob/living/carbon/superior_animal/golem/coal, + /mob/living/carbon/superior_animal/golem/iron, + /mob/living/carbon/superior_animal/golem/silver) + + special_types = list(/mob/living/carbon/superior_animal/golem/platinum, + /mob/living/carbon/superior_animal/golem/coal/enhanced, + /mob/living/carbon/superior_animal/golem/plasma, + /mob/living/carbon/superior_animal/golem/uranium) + + +/datum/ambush_type/golem/experienced + normal_types = list(/mob/living/carbon/superior_animal/golem/coal/enhanced, + /mob/living/carbon/superior_animal/golem/iron, + /mob/living/carbon/superior_animal/golem/silver) + + special_types = list(/mob/living/carbon/superior_animal/golem/platinum, /mob/living/carbon/superior_animal/golem/plasma, /mob/living/carbon/superior_animal/golem/uranium) -// /datum/golem_wave/negligible -// burrow_count = 2 -// burrow_interval = 24 SECONDS -// golem_spawn = 2 -// spawn_interval = 20 SECONDS -// special_probability = 0 -// mineral_multiplier = 1.4 - -// /datum/golem_wave/typical -// burrow_count = 3 -// burrow_interval = 24 SECONDS -// golem_spawn = 3 -// spawn_interval = 18 SECONDS -// special_probability = 10 -// mineral_multiplier = 1.7 - -// /datum/golem_wave/substantial -// burrow_count = 3 -// burrow_interval = 24 SECONDS -// golem_spawn = 3 -// spawn_interval = 18 SECONDS -// special_probability = 20 -// mineral_multiplier = 2 - -// /datum/golem_wave/major -// burrow_count = 4 -// burrow_interval = 20 SECONDS -// golem_spawn = 4 -// spawn_interval = 14 SECONDS -// special_probability = 30 -// mineral_multiplier = 2.3 - -// /datum/golem_wave/abnormal -// burrow_count = 5 -// burrow_interval = 18 SECONDS -// golem_spawn = 4 -// spawn_interval = 12 SECONDS -// special_probability = 30 -// mineral_multiplier = 3.0 +/datum/ambush_type/golem/expert + special_probability = 30 + normal_types = list(/mob/living/carbon/superior_animal/golem/coal/enhanced, + /mob/living/carbon/superior_animal/golem/iron + /mob/living/carbon/superior_animal/golem/uranium, + /mob/living/carbon/superior_animal/golem/platinum, + /mob/living/carbon/superior_animal/golem/silver/enhanced) + + special_types = list(/mob/living/carbon/superior_animal/golem/plasma, + /mob/living/carbon/superior_animal/golem/gold) + + +/datum/ambush_type/golem/nightmare + special_probability = 35 + normal_types = list(/mob/living/carbon/superior_animal/golem/coal/enhanced, + /mob/living/carbon/superior_animal/golem/iron + /mob/living/carbon/superior_animal/golem/uranium, + /mob/living/carbon/superior_animal/golem/platinum, + /mob/living/carbon/superior_animal/golem/silver/enhanced) + + special_types = list(/mob/living/carbon/superior_animal/golem/plasma, + /mob/living/carbon/superior_animal/golem/ansible, + /mob/living/carbon/superior_animal/golem/diamond, + /mob/living/carbon/superior_animal/golem/gold) + From 2698a2cd695d2ffef4a32cfb3e315912e5d7f4c7 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sun, 9 Nov 2025 07:08:49 -0500 Subject: [PATCH 20/23] skill issue --- code/modules/mining/ambush.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 0f7b4563097..3f12e8a41f7 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -297,7 +297,7 @@ /datum/ambush_type/golem/nightmare special_probability = 35 normal_types = list(/mob/living/carbon/superior_animal/golem/coal/enhanced, - /mob/living/carbon/superior_animal/golem/iron + /mob/living/carbon/superior_animal/golem/iron, /mob/living/carbon/superior_animal/golem/uranium, /mob/living/carbon/superior_animal/golem/platinum, /mob/living/carbon/superior_animal/golem/silver/enhanced) From 2b27d99011c29dbd93a2d7695754dc61e9746bde Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sun, 9 Nov 2025 07:18:40 -0500 Subject: [PATCH 21/23] fixes & shorter warn time --- code/modules/mining/ambush.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 3f12e8a41f7..194b47356fb 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -140,6 +140,7 @@ if(burrow_turf == ambush_loc) burrow_turf = get_step(ambush_loc, pick(GLOB.cardinal)) + burrow_turf.shake_animation(14)//HEY! Pay attention to this spot burrows += new /obj/structure/ambush_burrow(burrow_turf, src, our_datum) // Spawn burrow at final location ///ends the ambush. Should preferentially be called before cleanup or a qdel @@ -191,8 +192,8 @@ var/ambush_duration = 20 SECONDS /// If set, ambush ends once this many burrows have spawned var/spawn_cap = 8 - /// Amnt. of prep time given between when the burrows first appear & mobs start spawning - var/setup_time = 4 SECONDS + /// Amnt. of prep time given between when burrows first appear & mobs start spawning + var/setup_time = 3 SECONDS //burrow vars /// If set, total number of burrows that can exist at any single time @@ -285,7 +286,7 @@ /datum/ambush_type/golem/expert special_probability = 30 normal_types = list(/mob/living/carbon/superior_animal/golem/coal/enhanced, - /mob/living/carbon/superior_animal/golem/iron + /mob/living/carbon/superior_animal/golem/iron, /mob/living/carbon/superior_animal/golem/uranium, /mob/living/carbon/superior_animal/golem/platinum, /mob/living/carbon/superior_animal/golem/silver/enhanced) From 0a67f9c09fbdbed8a81b4072c566fd610d481277 Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:00:05 -0500 Subject: [PATCH 22/23] fixes ambush check in gen --- code/modules/dungeons/procedural/deepmaint.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/dungeons/procedural/deepmaint.dm b/code/modules/dungeons/procedural/deepmaint.dm index c0bdb66cad0..3202bf37438 100644 --- a/code/modules/dungeons/procedural/deepmaint.dm +++ b/code/modules/dungeons/procedural/deepmaint.dm @@ -148,8 +148,9 @@ var/global/list/big_deepmaint_room_templates = list() for(var/turf/W in nicheline) //Every turf in the path returned by findNicheTurfs has a 30% chance of becoming a random deepmaint machine if(prob(30)) new /obj/spawner/pack/deep_machine(W) - if(prob(1)) + if(!ambush_placed && prob(1)) new /obj/effect/ambush_snare + ambush_placed = TRUE for(var/turf/W in wall_line) //Every turf in the path returned by checkForWalls is turned into a floor tile, and has a 70% chance of becoming a random deepmaint machine if(locate(/obj/machinery/light/small/autoattach, W)) var/obj/machinery/light/small/autoattach/L = locate(/obj/machinery/light/small/autoattach, W) From 25363491ea9c38835a5e0ae3e3d9ffb56c14cd3a Mon Sep 17 00:00:00 2001 From: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com> Date: Sat, 21 Feb 2026 23:27:35 -0500 Subject: [PATCH 23/23] booboo the fool oughhhhh --- code/modules/mining/ambush.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mining/ambush.dm b/code/modules/mining/ambush.dm index 194b47356fb..081a04da8a2 100644 --- a/code/modules/mining/ambush.dm +++ b/code/modules/mining/ambush.dm @@ -129,6 +129,7 @@ if(!istype(burrow_turf)) // Try again with a smaller circle radius-- continue + break if(!istype(burrow_turf)) // Something wrong is happening log_and_message_admins("Ambush controller failed to create a new burrow around ([ambush_loc.x], [ambush_loc.y], [ambush_loc.z]).") return