From d95f2fd97cffcbc72d21f065a23bcfadbbda3abf Mon Sep 17 00:00:00 2001 From: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com> Date: Sat, 3 Dec 2022 07:35:13 -0600 Subject: [PATCH] fix steal identity objectives not syncing to their linked assassinate objectives (#19809) --- code/__DEFINES/dcs/signals.dm | 4 ++ code/game/gamemodes/objective.dm | 51 +++++++++++++++---- .../changeling/datum_changeling.dm | 5 +- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index e968543612f..b878f39aafc 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -824,3 +824,7 @@ // /obj/machinery/door/airlock signals #define COMSIG_AIRLOCK_OPEN "airlock_open" #define COMSIG_AIRLOCK_CLOSE "airlock_close" + +// /datum/objective signals +///from datum/objective/proc/find_target() +#define COMSIG_OBJECTIVE_TARGET_FOUND "objective_target_found" diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 20d8d8463f9..2d6b8ac9c63 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -90,6 +90,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) if(possible_targets.len > 0) target = pick(possible_targets) + SEND_SIGNAL(src, COMSIG_OBJECTIVE_TARGET_FOUND, target) + /** * Called when the objective's target goes to cryo. */ @@ -348,23 +350,54 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/escape/escape_with_identity - var/target_real_name // Has to be stored because the target's real_name can change over the course of the round + /// Stored because the target's `[mob/var/real_name]` can change over the course of the round. + var/target_real_name + /// If the objective has an assassinate objective tied to it. + var/has_assassinate_objective = FALSE + +/datum/objective/escape/escape_with_identity/New(text, datum/objective/assassinate/assassinate) + ..() + if(!assassinate) + return + target = assassinate.target + target_real_name = assassinate.target.current.real_name + explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing [target.p_their()] identification card." + has_assassinate_objective = TRUE + RegisterSignal(assassinate, COMSIG_OBJECTIVE_TARGET_FOUND, PROC_REF(assassinate_found_target)) + +/datum/objective/escape/escape_with_identity/is_invalid_target(datum/mind/possible_target) + if(..() || !possible_target.current.client) + return TRUE + // If the target is geneless, then it's an invalid target. + return HAS_TRAIT(possible_target.current, TRAIT_GENELESS) /datum/objective/escape/escape_with_identity/find_target() - var/list/possible_targets = list() //Copypasta because NO_DNA races, yay for snowflakes. - for(var/datum/mind/possible_target in SSticker.minds) - if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && possible_target.current.client) - var/mob/living/carbon/human/H = possible_target.current - if(!HAS_TRAIT(H, TRAIT_GENELESS)) - possible_targets += possible_target - if(possible_targets.len > 0) - target = pick(possible_targets) + ..() if(target && target.current) target_real_name = target.current.real_name explanation_text = "Escape on the shuttle or an escape pod with the identity of [target_real_name], the [target.assigned_role] while wearing [target.p_their()] identification card." else explanation_text = "Free Objective" +/datum/objective/escape/escape_with_identity/proc/assassinate_found_target(datum/source, datum/mind/new_target) + SIGNAL_HANDLER + if(new_target) + target_real_name = new_target.current.real_name + return + // The assassinate objective was unable to find a new target after the old one cryo'd as was qdel'd. We're on our own. + find_target() + has_assassinate_objective = FALSE + +/datum/objective/escape/escape_with_identity/on_target_cryo() + if(has_assassinate_objective) + return // Our assassinate objective will handle this. + ..() + +/datum/objective/escape/escape_with_identity/post_target_cryo() + if(has_assassinate_objective) + return // Our assassinate objective will handle this. + ..() + // This objective should only be given to a single owner since only 1 person can have the ID card of the target. // We're fine to use `owner` instead of `get_owners()`. /datum/objective/escape/escape_with_identity/check_completion() diff --git a/code/modules/antagonists/changeling/datum_changeling.dm b/code/modules/antagonists/changeling/datum_changeling.dm index cc971efe0d2..096537992c6 100644 --- a/code/modules/antagonists/changeling/datum_changeling.dm +++ b/code/modules/antagonists/changeling/datum_changeling.dm @@ -151,11 +151,8 @@ var/mob/living/carbon/human/H = kill_objective.target?.current if(!(locate(/datum/objective/escape) in owner.get_all_objectives()) && H && !HAS_TRAIT(H, TRAIT_GENELESS)) - var/datum/objective/escape/escape_with_identity/identity_theft = new + var/datum/objective/escape/escape_with_identity/identity_theft = new(assassinate = kill_objective) identity_theft.owner = owner - identity_theft.target = kill_objective.target - identity_theft.target_real_name = kill_objective.target.current.real_name - identity_theft.explanation_text = "Escape on the shuttle or an escape pod with the identity of [identity_theft.target_real_name], the [identity_theft.target.assigned_role] while wearing [identity_theft.target.p_their()] identification card." objectives += identity_theft if(!(locate(/datum/objective/escape) in owner.get_all_objectives()))