diff --git a/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm b/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm index 452979890e2..d9fbab9245a 100644 --- a/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm +++ b/code/controllers/subsystem/dynamic/dynamic_ruleset_midround.dm @@ -678,21 +678,28 @@ min_pop = 10 max_antag_cap = 1 signup_atom_appearance = /obj/effect/bluespace_stream + /// Chance of getting another clone for the price of free + var/bonus_clone_chance = 20 + +/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/New(list/dynamic_config) + . = ..() + max_antag_cap += prob(bonus_clone_chance) /datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/can_be_selected() return ..() && !isnull(find_clone()) && !isnull(find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = FALSE)) +/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/create_execute_args() + return list(find_clone()) + /datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/create_ruleset_body() return // handled by assign_role() entirely -/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/assign_role(datum/mind/candidate) - var/mob/living/carbon/human/good_version = find_clone() +/datum/dynamic_ruleset/midround/from_ghosts/paradox_clone/assign_role(datum/mind/candidate, mob/living/carbon/human/good_version) var/mob/living/carbon/human/bad_version = good_version.make_full_human_copy(find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = FALSE)) candidate.transfer_to(bad_version, force_key_move = TRUE) var/datum/antagonist/paradox_clone/antag = candidate.add_antag_datum(/datum/antagonist/paradox_clone) - antag.original_ref = WEAKREF(good_version.mind) - antag.setup_clone() + antag.setup_clone(good_version.mind) playsound(bad_version, 'sound/items/weapons/zapbang.ogg', 30, TRUE) bad_version.put_in_hands(new /obj/item/storage/toolbox/mechanical()) //so they dont get stuck in maints diff --git a/code/modules/antagonists/paradox_clone/paradox_clone.dm b/code/modules/antagonists/paradox_clone/paradox_clone.dm index c5100bed01b..d009d9b5d48 100644 --- a/code/modules/antagonists/paradox_clone/paradox_clone.dm +++ b/code/modules/antagonists/paradox_clone/paradox_clone.dm @@ -8,9 +8,6 @@ suicide_cry = "THERE CAN BE ONLY ONE!!" preview_outfit = /datum/outfit/paradox_clone - ///Weakref to the mind of the original, the clone's target. - var/datum/weakref/original_ref - /datum/antagonist/paradox_clone/get_preview_icon() var/icon/final_icon = render_preview_outfit(preview_outfit) @@ -28,27 +25,27 @@ return clone_icon -/datum/antagonist/paradox_clone/Destroy() - original_ref = null - return ..() +/datum/antagonist/paradox_clone/proc/setup_clone(datum/mind/original_mind) + if(isnull(original_mind)) + CRASH("Tried to set up a paradox clone without an original mind!") -/datum/antagonist/paradox_clone/proc/setup_clone() - var/datum/mind/original_mind = original_ref?.resolve() - - var/datum/objective/assassinate/paradox_clone/kill = new + var/datum/objective/accept_no_substitutes/kill = new() kill.owner = owner - kill.target = original_mind - kill.update_explanation_text() + kill.set_target_name(original_mind.name || "Unknown") objectives += kill + var/datum/objective/paradox_clone_replace/replace = new() + replace.owner = owner + replace.name_and_job = "[original_mind.name], the [original_mind.assigned_role.title]" + replace.update_explanation_text() + objectives += replace + owner.set_assigned_role(SSjob.get_job_type(/datum/job/paradox_clone)) //clone doesnt show up on message lists var/obj/item/modular_computer/pda/messenger = locate() in owner.current - if(messenger) - var/datum/computer_file/program/messenger/message_app = locate() in messenger.stored_files - if(message_app) - message_app.invisible = TRUE + var/datum/computer_file/program/messenger/message_app = locate() in messenger?.stored_files + message_app?.invisible = TRUE //dont want anyone noticing there's two now var/mob/living/carbon/human/clone_human = owner.current @@ -64,6 +61,17 @@ /datum/antagonist/paradox_clone/roundend_report_header() return span_header("A paradox clone appeared on the station!
") +/datum/objective/paradox_clone_replace + name = "clone replace" + /// Name and job of the original to replace + var/name_and_job + +/datum/objective/paradox_clone_replace/update_explanation_text() + explanation_text = "Take [name_and_job || "someone's"]'s place. Avoid collateral damage - remember, your mission is to blend in!" + +/datum/objective/paradox_clone_replace/check_completion() + return completed || considered_alive(owner) + /datum/outfit/paradox_clone name = "Paradox Clone (Preview only)" @@ -71,20 +79,6 @@ gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/soft/purple -/** - * Paradox clone assassinate objective - * Similar to the original, but with a different flavortext. - */ -/datum/objective/assassinate/paradox_clone - name = "clone assassinate" - -/datum/objective/assassinate/paradox_clone/update_explanation_text() - . = ..() - if(!target?.current) - explanation_text = "Free Objective" - CRASH("WARNING! [ADMIN_LOOKUPFLW(owner)] paradox clone objectives forged without an original!") - explanation_text = "Murder and replace [target.name], the [!target_role_type ? target.assigned_role.title : english_list(target.get_special_roles())]. Remember, your mission is to blend in, do not kill anyone else unless you have to!" - ///Static bluespace stream used in its ghost poll icon. /obj/effect/bluespace_stream name = "bluespace stream"