[MIRROR] Ore vent fixes to spawning multiple megafauna. (#26862)

* Ore vent fixes to spawning multiple megafauna. (#81935)

## About The Pull Request

Ore vents can now no longer be scanned multiple times to spawn multiple
nodes, nor can they be used to duplicate lavaland bosses.

Vents now call for a `can_interact` check, as well as against the
cooldown timer, which has been moved a bit in the order of operations in
order to check things correctly when there's possibly multiple prompts
open for starting the defense waves.

Additionally, boss waves actually do what they're supposed to do, and
don't spawn in a node drone on boss summoning, but instead summon the
drone afterwards, which sets up the vent, then takes off visually. This
is reflected in the tgui alert before starting waves.

## Why It's Good For The Game

Fixes #81817. Improves visual clarity when doing boss vents so that
players don't get the wrong idea that they need to protect the drone as
well when fighting bosses.

## Changelog

🆑
fix: Ore vents have to be scanned while standing next to them.
fix: Menacing ore vents now correctly only spawn in a node drone after
the boss is defeated, instead of before.
/🆑

* Ore vent fixes to spawning multiple megafauna.

---------

Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-03-14 00:40:43 +01:00
committed by GitHub
parent f9ea4be02b
commit d53ced4e8d
@@ -21,6 +21,8 @@
var/discovered = FALSE
/// Is this type of vent exempt from the map's vent budget/limit? Think the free iron/glass vent or boss vents. This also causes it to not roll for random mineral breakdown.
var/unique_vent = FALSE
/// Does this vent spawn a node drone when tapped? Currently unique to boss vents so try not to VV it.
var/spawn_drone_on_tap = TRUE
/// What icon_state do we use when the ore vent has been tapped?
var/icon_state_tapped = "ore_vent_active"
/// A weighted list of what minerals are contained in this vent, with weight determining how likely each mineral is to be picked in produced boulders.
@@ -40,9 +42,7 @@
/// What string do we use to warn the player about the excavation event?
var/excavation_warning = "Are you ready to excavate this ore vent?"
///Are we currently spawning mobs?
var/spawning_mobs = FALSE
/// A list of mobs that can be spawned by this vent during a wave defense event.
/// A list of mobs that can be spawned by this vent during a wave defense event.
var/list/defending_mobs = list(
/mob/living/basic/mining/goliath,
/mob/living/basic/mining/legion/spawner_made,
@@ -198,6 +198,34 @@
/obj/structure/ore_vent/proc/ore_quantity_function(ore_floor)
return SHEET_MATERIAL_AMOUNT * round(boulder_size * (log(rand(1 + ore_floor, 4 + ore_floor)) ** -1))
/**
* This confirms that the user wants to start the wave defense event, and that they can start it.
*/
/obj/structure/ore_vent/proc/pre_wave_defense(mob/user, spawn_drone = TRUE)
if(tgui_alert(user, excavation_warning, "Begin defending ore vent?", list("Yes", "No")) != "Yes")
return FALSE
if(!can_interact(user))
return FALSE
if(!COOLDOWN_FINISHED(src, wave_cooldown) || node)
return FALSE
//This is where we start spitting out mobs.
Shake(duration = 3 SECONDS)
if(spawn_drone)
node = new /mob/living/basic/node_drone(loc)
node.arrive(src)
RegisterSignal(node, COMSIG_QDELETING, PROC_REF(handle_wave_conclusion))
particles = new /particles/smoke/ash()
for(var/i in 1 to 5) // Clears the surroundings of the ore vent before starting wave defense.
for(var/turf/closed/mineral/rock in oview(i))
if(istype(rock, /turf/open/misc/asteroid) && prob(35)) // so it's too common
new /obj/effect/decal/cleanable/rubble(rock)
if(prob(100 - (i * 15)))
rock.gets_drilled(user, FALSE)
if(prob(50))
new /obj/effect/decal/cleanable/rubble(rock)
sleep(0.6 SECONDS)
return TRUE
/**
* Starts the wave defense event, which will spawn a number of lavaland mobs based on the size of the ore vent.
* Called after the vent has been tapped by a scanning device.
@@ -221,7 +249,6 @@
wave_timer = 150 SECONDS
COOLDOWN_START(src, wave_cooldown, wave_timer)
addtimer(CALLBACK(src, PROC_REF(handle_wave_conclusion)), wave_timer)
spawning_mobs = TRUE
icon_state = icon_state_tapped
update_appearance(UPDATE_ICON_STATE)
@@ -272,7 +299,7 @@
if(tapped)
balloon_alert_to_viewers("vent tapped!")
return
if(!COOLDOWN_FINISHED(src, wave_cooldown))
if(!COOLDOWN_FINISHED(src, wave_cooldown) || node) //We're already defending the vent, so don't scan it again.
if(!scan_only)
balloon_alert_to_viewers("protect the node drone!")
return
@@ -302,27 +329,9 @@
return
if(scan_only)
return
if(tgui_alert(user, excavation_warning, "Begin defending ore vent?", list("Yes", "No")) != "Yes")
return
if(!COOLDOWN_FINISHED(src, wave_cooldown))
return
//This is where we start spitting out mobs.
Shake(duration = 3 SECONDS)
node = new /mob/living/basic/node_drone(loc)
node.arrive(src)
RegisterSignal(node, COMSIG_QDELETING, PROC_REF(handle_wave_conclusion))
particles = new /particles/smoke/ash()
for(var/i in 1 to 5) // Clears the surroundings of the ore vent before starting wave defense.
for(var/turf/closed/mineral/rock in oview(i))
if(istype(rock, /turf/open/misc/asteroid) && prob(35)) // so it's too common
new /obj/effect/decal/cleanable/rubble(rock)
if(prob(100 - (i * 15)))
rock.gets_drilled(user, FALSE)
if(prob(50))
new /obj/effect/decal/cleanable/rubble(rock)
sleep(0.6 SECONDS)
if(!pre_wave_defense(user, spawn_drone_on_tap))
return
start_wave_defense()
/**
@@ -463,6 +472,7 @@
name = "menacing ore vent"
desc = "An ore vent, brimming with underground ore. This one has an evil aura about it. Better be careful."
unique_vent = TRUE
spawn_drone_on_tap = FALSE
boulder_size = BOULDER_SIZE_LARGE
mineral_breakdown = list( // All the riches of the world, eeny meeny boulder room.
/datum/material/iron = 1,
@@ -481,7 +491,7 @@
/mob/living/simple_animal/hostile/megafauna/dragon,
/mob/living/simple_animal/hostile/megafauna/colossus,
)
excavation_warning = "Something big is nearby. Are you ABSOLUTELY ready to excavate this ore vent?"
excavation_warning = "Something big is nearby. Are you ABSOLUTELY ready to excavate this ore vent? A NODE drone will be deployed after threat is neutralized."
///What boss do we want to spawn?
var/summoned_boss = null
@@ -506,6 +516,8 @@
. += span_notice("[boss_string] is etched onto the side of the vent.")
/obj/structure/ore_vent/boss/start_wave_defense()
if(!COOLDOWN_FINISHED(src, wave_cooldown))
return
// Completely override the normal wave defense, and just spawn the boss.
var/mob/living/simple_animal/hostile/megafauna/boss = new summoned_boss(loc)
RegisterSignal(boss, COMSIG_LIVING_DEATH, PROC_REF(handle_wave_conclusion))