diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm index d458e557a07..b6a483b22b8 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm @@ -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 diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm index d0df25f334d..6052378a0ed 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm @@ -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) diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm index d10252bc401..f53c179cf1f 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm @@ -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 diff --git a/html/changelogs/hellfirejag-fix-hivebot-testfail.yml b/html/changelogs/hellfirejag-fix-hivebot-testfail.yml new file mode 100644 index 00000000000..8cbd0d0837f --- /dev/null +++ b/html/changelogs/hellfirejag-fix-hivebot-testfail.yml @@ -0,0 +1,4 @@ +author: Hellfirejag +delete-after: True +changes: + - bugfix: "Fixed both a hard delete and a random test fail related to hivebot beacons."