diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index 0b4adc0f2cd..88dcc4cd074 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -42,7 +42,7 @@ /// A list of TOTAL how many high value sacrifices completed. var/high_value_sacrifices = 0 /// Lazy assoc list of [weakrefs to humans] to [image previews of the human]. Humans that we have as sacrifice targets. - var/list/datum/weakref/sac_targets + var/list/mob/living/carbon/human/sac_targets /// Whether we're drawing a rune or not var/drawing_rune = FALSE /// A static typecache of all tools we can scribe with. @@ -50,6 +50,10 @@ /// A blacklist of turfs we cannot scribe on. var/static/list/blacklisted_rune_turfs = typecacheof(list(/turf/open/space, /turf/open/openspace, /turf/open/lava, /turf/open/chasm)) +/datum/antagonist/heretic/Destroy() + LAZYNULL(sac_targets) + return ..() + /datum/antagonist/heretic/ui_data(mob/user) var/list/data = list() @@ -356,7 +360,29 @@ var/image/target_image = image(icon = target.icon, icon_state = target.icon_state) target_image.overlays = target.overlays - LAZYSET(sac_targets, WEAKREF(target), target_image) + LAZYSET(sac_targets, target, target_image) + RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/on_target_deleted) + +/** + * Removes [target] from the heretic's sacrifice list. + * Returns FALSE if no one was removed, TRUE otherwise + */ +/datum/antagonist/heretic/proc/remove_sacrifice_target(mob/living/carbon/human/target) + if(!(target in sac_targets)) + return FALSE + + LAZYREMOVE(sac_targets, target) + UnregisterSignal(target, COMSIG_PARENT_QDELETING) + return TRUE + +/** + * Signal proc for [COMSIG_PARENT_QDELETING] registered on sac targets + * if sacrifice targets are deleted (gibbed, dusted, whatever), free their slot and reference + */ +/datum/antagonist/heretic/proc/on_target_deleted(mob/living/carbon/human/source) + SIGNAL_HANDLER + + remove_sacrifice_target(source) /** * Increments knowledge by one. @@ -462,10 +488,8 @@ return var/list/removable = list() - for(var/datum/weakref/ref as anything in sac_targets) - var/mob/living/carbon/human/old_target = ref.resolve() - if(!QDELETED(old_target)) - removable[old_target.name] = old_target + for(var/mob/living/carbon/human/old_target as anything in sac_targets) + removable[old_target.name] = old_target var/name_of_removed = tgui_input_list(admin, "Choose a human to remove", "Who to Spare", removable) if(QDELETED(src) || !admin.client?.holder || isnull(name_of_removed)) @@ -473,10 +497,10 @@ var/mob/living/carbon/human/chosen_target = removable[name_of_removed] if(QDELETED(chosen_target) || !ishuman(chosen_target)) return - if(!(WEAKREF(chosen_target) in sac_targets)) - return - LAZYREMOVE(sac_targets, WEAKREF(chosen_target)) + if(!remove_sacrifice_target(chosen_target)) + to_chat(admin, span_warning("Failed to remove [name_of_removed] from [owner]'s sacrifice list. Perhaps they're no longer in the list anyways.")) + return if(tgui_alert(admin, "Let them know their targets have been updated?", "Whispers of the Mansus", list("Yes", "No")) == "Yes") to_chat(owner.current, span_danger("The Mansus has modified your targets.")) @@ -513,11 +537,9 @@ . += "
" . += "Current Targets:
" if(LAZYLEN(sac_targets)) - for(var/datum/weakref/ref as anything in sac_targets) - var/mob/living/carbon/human/actual_target = ref.resolve() - if(QDELETED(actual_target)) - continue - . += " - [actual_target.real_name], the [actual_target.mind?.assigned_role?.title || "human"].
" + for(var/mob/living/carbon/human/target as anything in sac_targets) + . += " - [target.real_name], the [target.mind?.assigned_role?.title || "human"].
" + else . += "None!
" . += "
" diff --git a/code/modules/antagonists/heretic/heretic_living_heart.dm b/code/modules/antagonists/heretic/heretic_living_heart.dm index 0019e276506..a619e242376 100644 --- a/code/modules/antagonists/heretic/heretic_living_heart.dm +++ b/code/modules/antagonists/heretic/heretic_living_heart.dm @@ -118,13 +118,9 @@ var/list/targets_to_choose = list() var/list/mob/living/carbon/human/human_targets = list() - for(var/datum/weakref/target_ref as anything in heretic_datum.sac_targets) - var/mob/living/carbon/human/real_target = target_ref.resolve() - if(QDELETED(real_target)) - continue - - human_targets[real_target.real_name] = real_target - targets_to_choose[real_target.real_name] = heretic_datum.sac_targets[target_ref] + for(var/mob/living/carbon/human/sac_target as anything in heretic_datum.sac_targets) + human_targets[sac_target.real_name] = sac_target + targets_to_choose[sac_target.real_name] = heretic_datum.sac_targets[sac_target] // If we don't have a last tracked name, open a radial to set one. // If we DO have a last tracked name, we skip the radial if they right click the action. diff --git a/code/modules/antagonists/heretic/knowledge/general_side.dm b/code/modules/antagonists/heretic/knowledge/general_side.dm index e56af034337..fafaa3f77ba 100644 --- a/code/modules/antagonists/heretic/knowledge/general_side.dm +++ b/code/modules/antagonists/heretic/knowledge/general_side.dm @@ -27,7 +27,8 @@ /datum/heretic_knowledge/reroll_targets/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc) var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user) - LAZYCLEARLIST(heretic_datum.sac_targets) + for(var/mob/living/carbon/human/target as anything in heretic_datum.sac_targets) + heretic_datum.remove_sacrifice_target(target) var/datum/heretic_knowledge/hunt_and_sacrifice/target_finder = heretic_datum.get_knowledge(/datum/heretic_knowledge/hunt_and_sacrifice) if(!target_finder) diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm index 53db0c5a14f..7c04393f18f 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm @@ -65,7 +65,7 @@ // Let's remove any humans in our atoms list that aren't a sac target for(var/mob/living/carbon/human/sacrifice in atoms) // If the mob's not in soft crit or worse, or isn't one of the sacrifices, remove it from the list - if(sacrifice.stat < SOFT_CRIT || !(WEAKREF(sacrifice) in heretic_datum.sac_targets)) + if(sacrifice.stat < SOFT_CRIT || !(sacrifice in heretic_datum.sac_targets)) atoms -= sacrifice // Finally, return TRUE if we have a target in the list @@ -179,12 +179,12 @@ var/mob/living/carbon/human/sacrifice = locate() in selected_atoms if(!sacrifice) CRASH("[type] sacrifice_process didn't have a human in the atoms list. How'd it make it so far?") - if(!(WEAKREF(sacrifice) in heretic_datum.sac_targets)) + if(!(sacrifice in heretic_datum.sac_targets)) CRASH("[type] sacrifice_process managed to get a non-target human. This is incorrect.") if(sacrifice.mind) LAZYADD(target_blacklist, sacrifice.mind) - LAZYREMOVE(heretic_datum.sac_targets, WEAKREF(sacrifice)) + heretic_datum.remove_sacrifice_target(sacrifice) to_chat(user, span_hypnophrase("Your patrons accepts your offer."))