diff --git a/code/datums/components/soul_stealer.dm b/code/datums/components/soul_stealer.dm
index ed2ca0567f6..88ce917e7e1 100644
--- a/code/datums/components/soul_stealer.dm
+++ b/code/datums/components/soul_stealer.dm
@@ -5,13 +5,17 @@
* Used in the cult bastard sword!
*/
/datum/component/soul_stealer
- /// weakref list of soulstones captured by this item.
- var/list/weak_souls = list()
+ /// List of soulstones captured by this item.
+ var/list/obj/item/soulstone/soulstones = list()
/datum/component/soul_stealer/Initialize()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
+/datum/component/soul_stealer/Destroy()
+ QDEL_LIST(soulstones) // We own these, so we'll also just get rid of them. Any souls inside will die, this is fine.
+ return ..()
+
/datum/component/soul_stealer/RegisterWithParent()
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, PROC_REF(on_afterattack))
@@ -25,16 +29,14 @@
examine_list += span_notice("It will steal the soul of anyone it defeats in battle.")
- //clears out any weakrefs that do not exist anymore
- var/list/souls = recursive_list_resolve(weak_souls)
-
- switch(souls.len)
+ var/num_souls = length(soulstones)
+ switch(num_souls)
if(0)
examine_list += span_notice("It has not consumed any souls yet.")
if(1 to 9)
- examine_list += span_notice("There are [souls.len] souls trapped within it.")
+ examine_list += span_notice("There are [num_souls] souls trapped within it.")
if(10 to INFINITY)
- examine_list += span_notice("A staggering [souls.len] souls have been claimed by it! And it hungers for more!")
+ examine_list += span_notice("A staggering [num_souls] souls have been claimed by it! And it hungers for more!")
/datum/component/soul_stealer/proc/on_afterattack(obj/item/source, atom/target, mob/living/user, proximity_flag, click_parameters)
SIGNAL_HANDLER
@@ -45,19 +47,22 @@
if(ishuman(target))
INVOKE_ASYNC(src, PROC_REF(try_capture), target, user)
- var/list/souls = recursive_list_resolve(weak_souls)
-
- if(istype(target, /obj/structure/constructshell) && souls.len)
- var/obj/item/soulstone/soulstone = souls[1]
+ if(istype(target, /obj/structure/constructshell) && length(soulstones))
+ var/obj/item/soulstone/soulstone = soulstones[1]
INVOKE_ASYNC(soulstone, TYPE_PROC_REF(/obj/item/soulstone, transfer_to_construct), target, user)
- ///soulstone will be deleted from souls if successful
+ if(QDELETED(soulstone)) // successful transfer (transfer deletes us)
+ soulstones -= soulstone
+ else if(!length(soulstone.contents)) // something fucky happened
+ qdel(soulstone)
+ soulstones -= soulstone
+
/datum/component/soul_stealer/proc/try_capture(mob/living/carbon/human/victim, mob/living/captor)
if(victim.stat == CONSCIOUS)
return
- var/obj/item/soulstone/soulstone = new /obj/item/soulstone(parent)
+ var/obj/item/soulstone/soulstone = new(parent)
soulstone.attack(victim, captor)
- if(!LAZYLEN(soulstone.contents))
+ if(!length(soulstone.contents)) // failed
qdel(soulstone)
return
- weak_souls += WEAKREF(soulstone)
+ soulstones += soulstone