Fixes a bitrunning runtime & adds a component initialize result (#90099)

## About The Pull Request
Noticed that bitrunning virtual spawners were runtiming if the server
was already emagged. Basically, the guardrail component is added
(virtual_entity), then immediately deleted because it's emagged, leading
to a race condition in `JoinParent()` where parent is null. I still want
to keep this "valid, but delete me" state for components, so I made
`COMPONENT_REDUNDANT` (thx @LemonInTheDark).

I can't say for certain because I couldn't repro, but this /probably/
fixes #89992
## Why It's Good For The Game
Fixes a runtime
Allows devs to add components that execute an arbitrary amount of logic
while still qdeling themselves due to some in-game incompatibility issue
## Changelog
N/A
This commit is contained in:
Jeremiah
2025-03-20 13:51:47 +01:00
committed by GitHub
parent 639908387e
commit 70d356506f
6 changed files with 47 additions and 19 deletions
@@ -1,19 +1,35 @@
/// Handles all special considerations for "virtual entities" such as bitrunning ghost roles or digital anomaly antagonists.
/datum/component/virtual_entity
///The cooldown for balloon alerts, so the player isn't spammed while trying to enter a restricted area.
/// The cooldown for balloon alerts, so the player isn't spammed while trying to enter a restricted area.
COOLDOWN_DECLARE(OOB_cooldown)
/datum/component/virtual_entity/Initialize(obj/machinery/quantum_server)
. = ..()
/datum/component/virtual_entity/Initialize(obj/machinery/quantum_server)
if(quantum_server.obj_flags & EMAGGED)
jailbreak_mobs() //This just sends a message and self-deletes, a bit messy but it works.
return
jailbreak_mobs()
return COMPONENT_REDUNDANT
RegisterSignal(parent, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_parent_pre_move))
RegisterSignal(quantum_server, COMSIG_ATOM_EMAG_ACT, PROC_REF(jailbreak_mobs))
RegisterSignal(quantum_server, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emagged))
///Prevents entry to a certain area if it has flags preventing virtual entities from entering.
/// Self-destructs the component, allowing free-roam by all entities with this restriction.
/datum/component/virtual_entity/proc/jailbreak_mobs()
to_chat(parent, span_bolddanger("You shiver for a moment with a sense of clarity you haven't felt before."))
to_chat(parent, span_notice("You could go <i>anywhere</i>, do <i>anything</i>! You could leave this simulation right now if you wanted!"))
to_chat(parent, span_danger("But be warned, quantum entanglement will interfere with any previous lives."))
to_chat(parent, span_notice("You'll have just one chance to go nova, and there's no turning back."))
/// Remove any restrictions AFTER the mob has spawned
/datum/component/virtual_entity/proc/on_emagged(datum/source)
SIGNAL_HANDLER
jailbreak_mobs()
qdel(src)
/// Prevents entry to a certain area if it has flags preventing virtual entities from entering.
/datum/component/virtual_entity/proc/on_parent_pre_move(atom/movable/source, atom/new_location)
SIGNAL_HANDLER
@@ -27,12 +43,3 @@
COOLDOWN_START(src, OOB_cooldown, 2 SECONDS)
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
///Self-destructs the component, allowing free-roam by all entities with this restriction.
/datum/component/virtual_entity/proc/jailbreak_mobs()
SIGNAL_HANDLER
to_chat(parent, span_bolddanger("You shiver for a moment with a sense of clarity you haven't felt before."))
to_chat(parent, span_notice("You could go <i>anywhere</i>, do <i>anything</i>! You could leave this simulation right now if you wanted!"))
to_chat(parent, span_danger("But be warned, quantum entanglement will interfere with any previous lives."))
to_chat(parent, span_notice("You'll have just one chance to go nova, and there's no turning back."))
qdel(src)