Hivebot Beacon Testfail Fix (#22382)

I got annoyed with the Hivebot beacon causing me a test fail 3 times in
a row, so I decided to fix it myself. I've done so by:

1. Reworked hivebots to use a weakref to their beacon. No more circular
references.
2. Removed the stupid signal registries on qdeling spam, it's no longer
necessary since there's no longer a circular reference.
3. Fixed a stacktrace in the beacon calling the same function twice.
4. Made the beacon generate its smoke cloud when KILLED rather than when
DELETED (kill calls delete on a timer), so that it can no longer spawn
stupid smoke effects during the unit tests.
5. Made the beacon clear its giant lists of references to a bunch of
turfs when deleted.
This commit is contained in:
VMSolidus
2026-05-03 17:03:09 +00:00
committed by GitHub
parent c51ada1aa6
commit 06db06a46e
4 changed files with 44 additions and 113 deletions
@@ -43,42 +43,19 @@
psi_pingable = FALSE
sample_data = null
/**
* The hivebot beacon that we are liked to (and likely generated us)
*/
var/mob/living/simple_animal/hostile/hivebotbeacon/linked_parent = null
/// Weakref to the beacon that potentially spawned us.
var/datum/weakref/parent_beacon
/mob/living/simple_animal/hostile/hivebot/Initialize(mapload,mob/living/simple_animal/hostile/hivebotbeacon/beacon)
/mob/living/simple_animal/hostile/hivebot/Initialize(mapload, mob/living/simple_animal/hostile/hivebotbeacon/beacon)
. = ..()
do_link(beacon)
parent_beacon = WEAKREF(beacon)
if(!mapload)
spark(get_turf(src), 2, GLOB.alldirs)
/mob/living/simple_animal/hostile/hivebot/Destroy()
unlink()
. = ..()
/mob/living/simple_animal/hostile/hivebot/proc/do_link(mob/living/simple_animal/hostile/hivebotbeacon/beacon)
if(QDELETED(beacon))
return
if(linked_parent)
if(linked_parent == beacon)
return
unlink()
linked_parent = beacon
beacon.do_link(src)
RegisterSignal(linked_parent, COMSIG_QDELETING, PROC_REF(unlink))
/mob/living/simple_animal/hostile/hivebot/proc/unlink()
SIGNAL_HANDLER
if(!linked_parent)
return
linked_parent.unlink(src)
UnregisterSignal(linked_parent, COMSIG_QDELETING)
linked_parent = null
astype(parent_beacon?.resolve(), /mob/living/simple_animal/hostile/hivebotbeacon)?.linked_bots.Remove(src)
parent_beacon = null
return ..()
/mob/living/simple_animal/hostile/hivebot/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL
@@ -169,8 +146,16 @@
mob_swap_flags = ~HEAVY
mob_push_flags = 0
/mob/living/simple_animal/hostile/hivebot/guardian/Initialize(mapload, mob/living/simple_animal/hostile/hivebotbeacon/beacon)
. = ..()
beacon?.guard_amt++
/mob/living/simple_animal/hostile/hivebot/guardian/Destroy()
astype(parent_beacon?.resolve(), /mob/living/simple_animal/hostile/hivebotbeacon)?.guard_amt--
return ..()
/mob/living/simple_animal/hostile/hivebot/guardian/think()
. =..()
. = ..()
if(stance != HOSTILE_STANCE_IDLE)
wander = 1
@@ -127,61 +127,12 @@
set_light(6,0.5,LIGHT_COLOR_GREEN)
/mob/living/simple_animal/hostile/hivebotbeacon/Destroy()
//Remove the reference from all linked bots to us
for(var/mob/living/simple_animal/hostile/retaliate/hivebotharvester/hbh in linked_bots)
hbh.unlink()
for(var/mob/living/simple_animal/hostile/hivebot/hb in linked_bots)
hb.unlink()
linked_bots.Cut()
destinations.Cut()
close_destinations.Cut()
latest_area = null
//Smoke effect, we disappear in a smoke
var/datum/effect/effect/system/smoke_spread/S = new /datum/effect/effect/system/smoke_spread()
S.set_up(5, 0, src.loc)
S.start()
. = ..()
/mob/living/simple_animal/hostile/hivebotbeacon/proc/do_link(mob/living/simple_animal/hostile/add)
if(QDELETED(add) || (add in linked_bots))
return
var/mob/living/simple_animal/hostile/hivebot/hb = astype(add)
if(!hb)
var/mob/living/simple_animal/hostile/retaliate/hivebotharvester/hbh = astype(add)
if(hbh)
if(hbh.linked_parent != src)
hbh.do_link(src)
harvester_amt++
. = TRUE
else
if(hb.linked_parent != src)
hb.do_link(src)
if(istype(add, /mob/living/simple_animal/hostile/hivebot/guardian))
guard_amt++
. = TRUE
if(.)
linked_bots += add
RegisterSignal(add, COMSIG_QDELETING, PROC_REF(unlink))
/mob/living/simple_animal/hostile/hivebotbeacon/proc/unlink(mob/living/simple_animal/hostile/remove)
SIGNAL_HANDLER
if(!remove || !(remove in linked_bots))
return
UnregisterSignal(remove, COMSIG_QDELETING)
linked_bots -= remove
var/mob/living/simple_animal/hostile/hivebot/hb = astype(remove)
if(hb)
if(hb.linked_parent == src)
hb.unlink()
if(istype(remove, /mob/living/simple_animal/hostile/hivebot/guardian))
guard_amt--
else
var/mob/living/simple_animal/hostile/retaliate/hivebotharvester/hbh = astype(remove)
if(hbh)
if(hbh.linked_parent == src)
hbh.unlink()
harvester_amt--
return ..()
/mob/living/simple_animal/hostile/hivebotbeacon/proc/generate_warp_destinations()
@@ -214,6 +165,10 @@
var/T = get_turf(src)
new /obj/effect/gibspawner/robot(T)
spark(T, 3, GLOB.alldirs)
//Smoke effect, we disappear in a smoke
var/datum/effect/effect/system/smoke_spread/S = new /datum/effect/effect/system/smoke_spread()
S.set_up(5, 0, src.loc)
S.start()
QDEL_IN(src, 0)
return
@@ -227,9 +182,7 @@
/mob/living/simple_animal/hostile/hivebotbeacon/MoveToTarget()
if(!stop_automated_movement)
stop_automated_movement = 1
if(QDELETED(last_found_target) || SA_attackable(last_found_target))
LoseTarget()
if(!see_target(last_found_target))
if(last_found_target && (QDELETED(last_found_target) || SA_attackable(last_found_target) || !see_target(last_found_target)))
LoseTarget()
if(last_found_target in targets)
if(get_dist(src, last_found_target) <= 6)
@@ -32,7 +32,10 @@
mob_size = MOB_LARGE
pass_flags = PASSTABLE|PASSRAILING
attack_emote = "focuses on"
var/mob/living/simple_animal/hostile/hivebotbeacon/linked_parent = null
/// Weakref to the beacon that potentially spawned us.
var/datum/weakref/parent_beacon
var/turf/last_processed_turf
var/turf/last_prospect_target
var/turf/last_prospect_loc
@@ -46,41 +49,27 @@
sample_data = null
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/Initialize(mapload,mob/living/simple_animal/hostile/hivebotbeacon/beacon)
do_link(beacon)
. = ..()
if (beacon)
parent_beacon = WEAKREF(beacon)
beacon.harvester_amt++
set_light(3,2,LIGHT_COLOR_RED)
if(!mapload)
spark(get_turf(src), 3, GLOB.alldirs)
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/proc/do_link(mob/living/simple_animal/hostile/hivebotbeacon/beacon)
if(QDELETED(beacon))
return
if(linked_parent)
if(linked_parent == beacon)
return
linked_parent.unlink(src)
linked_parent = beacon
beacon.do_link(src)
RegisterSignal(linked_parent, COMSIG_QDELETING, PROC_REF(unlink))
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/proc/unlink()
SIGNAL_HANDLER
if(!linked_parent)
return
linked_parent.unlink(src)
UnregisterSignal(linked_parent, COMSIG_QDELETING)
linked_parent = null
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/death()
..(null,"teleports away!")
spark(get_turf(src), 3, GLOB.alldirs)
qdel(src)
QDEL_IN(src, 0)
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/Destroy()
unlink()
. = ..()
var/mob/living/simple_animal/hostile/hivebotbeacon/beacon = parent_beacon?.resolve()
if (beacon)
beacon.linked_bots.Remove(src)
beacon.harvester_amt--
parent_beacon = null
return ..()
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/Allow_Spacemove(var/check_drift = 0)
return 1