From 53b341d1b459829420aad7aace81c1af45d20cd4 Mon Sep 17 00:00:00 2001 From: 4DPlanner <3combined@gmail.com> Date: Thu, 1 Jun 2017 22:34:19 +0100 Subject: [PATCH] Reflection hell --- code/__DEFINES/antagonists.dm | 9 + .../antagonists/datum_internal_affairs.dm | 165 ++++++--- code/datums/antagonists/datum_traitor.dm | 320 +++++++++++------- code/datums/mind.dm | 16 +- code/modules/admin/secrets.dm | 4 +- code/modules/admin/verbs/randomverbs.dm | 4 - 6 files changed, 337 insertions(+), 181 deletions(-) diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 9b68c38f905..98420bc4294 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -8,4 +8,13 @@ #define ANTAG_DATUM_NINJA_RANDOM /datum/antagonist/ninja/randomAllegiance/ #define ANTAG_DATUM_TRAITOR /datum/antagonist/traitor #define ANTAG_DATUM_TRAITOR_CUSTOM /datum/antagonist/traitor/custom +#define ANTAG_DATUM_TRAITOR_HUMAN /datum/antagonist/traitor/human +#define ANTAG_DATUM_TRAITOR_HUMAN_CUSTOM /datum/antagonist/traitor/human/custom +#define ANTAG_DATUM_TRAITOR_AI /datum/antagonist/traitor/AI +#define ANTAG_DATUM_TRAITOR_AI_CUSTOM /datum/antagonist/traitor/AI/custom #define ANTAG_DATUM_IAA /datum/antagonist/traitor/internal_affairs +#define ANTAG_DATUM_IAA_CUSTOM /datum/antagonist/traitor/internal_affairs/custom +#define ANTAG_DATUM_IAA_HUMAN /datum/antagonist/traitor/human/internal_affairs +#define ANTAG_DATUM_IAA_HUMAN_CUSTOM /datum/antagonist/traitor/human/internal_affairs/custom +#define ANTAG_DATUM_IAA_AI_CUSTOM /datum/antagonist/traitor/AI/internal_affairs/custom +#define ANTAG_DATUM_IAA_AI /datum/antagonist/traitor/AI/internal_affairs diff --git a/code/datums/antagonists/datum_internal_affairs.dm b/code/datums/antagonists/datum_internal_affairs.dm index 352b5c66c5c..e3a8077732b 100644 --- a/code/datums/antagonists/datum_internal_affairs.dm +++ b/code/datums/antagonists/datum_internal_affairs.dm @@ -5,26 +5,88 @@ #define TRAITOR_AGENT_ROLE "Syndicate External Affairs Agent" /datum/antagonist/traitor/internal_affairs + base_datum_custom = ANTAG_DATUM_IAA_CUSTOM + human_datum = ANTAG_DATUM_IAA_HUMAN + ai_datum = ANTAG_DATUM_IAA_AI + + + +/datum/antagonist/traitor/AI/internal_affairs name = "Internal Affairs Agent" employer = "Nanotrasen" special_role = "internal affairs agent" + base_datum_custom = ANTAG_DATUM_IAA_CUSTOM var/syndicate = FALSE var/last_man_standing = FALSE var/list/datum/mind/targets_stolen -/datum/antagonist/traitor/internal_affairs/apply_innate_effects() +/datum/antagonist/traitor/AI/internal_affairs/custom + silent = TRUE + should_give_codewords = FALSE + give_objectives = FALSE + +/datum/antagonist/traitor/human/internal_affairs + name = "Internal Affairs Agent" + employer = "Nanotrasen" + special_role = "internal affairs agent" + base_datum_custom = ANTAG_DATUM_IAA_CUSTOM + var/syndicate = FALSE + var/last_man_standing = FALSE + var/list/datum/mind/targets_stolen + +/datum/antagonist/traitor/human/internal_affairs/custom + silent = TRUE + should_give_codewords = FALSE + give_objectives = FALSE + should_equip = FALSE //Duplicating TCs is dangerous + +/datum/antagonist/traitor/human/internal_affairs/transfer_important_variables(datum/antagonist/traitor/human/internal_affairs/other) + ..(other) + other.syndicate = syndicate + other.last_man_standing = last_man_standing + other.targets_stolen = targets_stolen + +/datum/antagonist/traitor/AI/internal_affairs/transfer_important_variables(datum/antagonist/traitor/human/internal_affairs/other) + ..(other) + other.syndicate = syndicate + other.last_man_standing = last_man_standing + other.targets_stolen = targets_stolen + +/datum/antagonist/traitor/human/internal_affairs/proc/give_pinpointer() + if(owner && owner.current) + owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer) + +/datum/antagonist/traitor/human/internal_affairs/apply_innate_effects() .=..() //in case the base is used in future if(owner&&owner.current) give_pinpointer(owner.current) -/datum/antagonist/traitor/internal_affairs/remove_innate_effects() +/datum/antagonist/traitor/human/internal_affairs/remove_innate_effects() .=..() if(owner&&owner.current) owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer) -/datum/antagonist/traitor/internal_affairs/on_removal() +/datum/antagonist/traitor/internal_affairs/custom + ai_datum = ANTAG_DATUM_IAA_AI_CUSTOM + human_datum = ANTAG_DATUM_IAA_HUMAN_CUSTOM + +/datum/antagonist/traitor/human/internal_affairs/on_gain() + START_PROCESSING(SSprocessing, src) + .=..() +/datum/antagonist/traitor/human/internal_affairs/on_removal() STOP_PROCESSING(SSprocessing,src) .=..() +/datum/antagonist/traitor/human/internal_affairs/process() + iaa_process() + +/datum/antagonist/traitor/AI/internal_affairs/on_gain() + START_PROCESSING(SSprocessing, src) + .=..() +/datum/antagonist/traitor/AI/internal_affairs/on_removal() + STOP_PROCESSING(SSprocessing,src) + .=..() +/datum/antagonist/traitor/AI/internal_affairs/process() + iaa_process() /datum/status_effect/agent_pinpointer id = "agent_pinpointer" @@ -82,14 +144,11 @@ scan_for_target() point_to_target() -/datum/antagonist/traitor/internal_affairs/proc/give_pinpointer() - if(owner && owner.current) - owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer) /proc/is_internal_objective(datum/objective/O) return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal)) -/datum/antagonist/traitor/internal_affairs/proc/replace_escape_objective() +/datum/antagonist/traitor/proc/replace_escape_objective() if(!owner||!owner.objectives) return for (var/objective_ in owner.objectives) @@ -101,23 +160,29 @@ martyr_objective.owner = owner add_objective(martyr_objective) -/datum/antagonist/traitor/internal_affairs/proc/reinstate_escape_objective() +/datum/antagonist/traitor/proc/reinstate_escape_objective() if(!owner||!owner.objectives) return for (var/objective_ in owner.objectives) if(!istype(objective_, /datum/objective/martyr)) continue remove_objective(objective_) - if(issilicon(owner)) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = owner - add_objective(survive_objective) - else - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - add_objective(escape_objective) -/datum/antagonist/traitor/internal_affairs/proc/steal_targets(datum/mind/victim) +/datum/antagonist/traitor/human/internal_affairs/reinstate_escape_objective() + ..() + var/datum/objective/escape/escape_objective = new + escape_objective.owner = owner + add_objective(escape_objective) + +/datum/antagonist/traitor/AI/internal_affairs/reinstate_escape_objective() + ..() + var/datum/objective/survive/survive_objective = new + survive_objective.owner = owner + add_objective(survive_objective) + +/datum/antagonist/traitor/proc/steal_targets(datum/mind/victim) + var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA + if(!owner.current||owner.current.stat==DEAD) return to_chat(owner.current, " Target eliminated: [victim.name]") @@ -126,13 +191,13 @@ var/datum/objective/assassinate/internal/objective = objective_ if(objective.target==owner) continue - else if(targets_stolen.Find(objective.target) == 0) + else if(this.targets_stolen.Find(objective.target) == 0) var/datum/objective/assassinate/internal/new_objective = new new_objective.owner = owner new_objective.target = objective.target new_objective.update_explanation_text() add_objective(new_objective) - targets_stolen += objective.target + this.targets_stolen += objective.target var/status_text = objective.check_completion() ? "neutralised" : "active" to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") else if(istype(objective_, /datum/objective/destroy/internal)) @@ -140,30 +205,31 @@ var/datum/objective/destroy/internal/new_objective = new if(objective.target==owner) continue - else if(targets_stolen.Find(objective.target) == 0) + else if(this.targets_stolen.Find(objective.target) == 0) new_objective.owner = owner new_objective.target = objective.target new_objective.update_explanation_text() add_objective(new_objective) - targets_stolen += objective.target + this.targets_stolen += objective.target var/status_text = objective.check_completion() ? "neutralised" : "active" to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") - last_man_standing = TRUE + this.last_man_standing = TRUE for(var/objective_ in owner.objectives) if(!is_internal_objective(objective_)) continue var/datum/objective/assassinate/internal/objective = objective_ if(!objective.check_completion()) - last_man_standing = FALSE + this.last_man_standing = FALSE return - if(last_man_standing) - if(syndicate) + if(this.last_man_standing) + if(this.syndicate) to_chat(owner.current," All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. ") else to_chat(owner.current," All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.") replace_escape_objective(owner) -/datum/antagonist/traitor/internal_affairs/process() +/datum/antagonist/traitor/proc/iaa_process() + var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA if(owner&&owner.current&&owner.current.stat!=DEAD) for(var/objective_ in owner.objectives) if(!is_internal_objective(objective_)) @@ -180,17 +246,18 @@ else if(objective.stolen) var/fail_msg = "Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! " - if(last_man_standing) - if(syndicate) + if(this.last_man_standing) + if(this.syndicate) fail_msg += " You no longer have permission to die. " else fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated." reinstate_escape_objective(owner) - last_man_standing = FALSE + this.last_man_standing = FALSE to_chat(owner.current, fail_msg) objective.stolen = FALSE -/datum/antagonist/traitor/internal_affairs/forge_traitor_objectives() +/datum/antagonist/traitor/proc/forge_iaa_objectives() + var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA if(SSticker.mode.target_list.len && SSticker.mode.target_list[owner]) // Is a double agent // Assassinate @@ -200,7 +267,6 @@ destroy_objective.owner = owner destroy_objective.target = target_mind destroy_objective.update_explanation_text() - add_objective(destroy_objective) else var/datum/objective/assassinate/internal/kill_objective = new kill_objective.owner = owner @@ -208,35 +274,36 @@ kill_objective.update_explanation_text() add_objective(kill_objective) - // Escape - if(issilicon(owner.current)) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = owner - add_objective(survive_objective) - else - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - add_objective(escape_objective) - START_PROCESSING(SSprocessing, src) - if(!issilicon(owner.current)) - give_pinpointer() //Optional traitor objective if(prob(PROB_ACTUAL_TRAITOR)) employer = "The Syndicate" owner.special_role = TRAITOR_AGENT_ROLE special_role = TRAITOR_AGENT_ROLE - syndicate = TRUE + this.syndicate = TRUE forge_single_objective() else ..() // Give them standard objectives. return -/datum/antagonist/traitor/internal_affairs/greet() +/datum/antagonist/traitor/human/internal_affairs/forge_traitor_objectives() + forge_iaa_objectives() + var/datum/objective/escape/escape_objective = new + escape_objective.owner = owner + add_objective(escape_objective) + +/datum/antagonist/traitor/AI/internal_affairs/forge_traitor_objectives() + forge_iaa_objectives() + var/datum/objective/survive/survive_objective = new + survive_objective.owner = owner + add_objective(survive_objective) + +/datum/antagonist/traitor/proc/greet_iaa() + var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence") to_chat(owner.current, "You are the [special_role].") - if(syndicate) + if(this.syndicate) to_chat(owner.current, "Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.") to_chat(owner.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.") to_chat(owner.current, " You have been provided with a standard uplink to accomplish your task. ") @@ -248,6 +315,12 @@ to_chat(owner.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.") owner.announce_objectives() +/datum/antagonist/traitor/AI/internal_affairs/greet() + greet_iaa() +/datum/antagonist/traitor/human/internal_affairs/greet() + greet_iaa() + + #undef PROB_ACTUAL_TRAITOR #undef PINPOINTER_EXTRA_RANDOM_RANGE #undef PINPOINTER_MINIMUM_RANGE diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index a627b21e682..a57c2087e30 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -1,17 +1,77 @@ /datum/antagonist/traitor name = "Traitor" + var/should_specialise = TRUE //do we split into AI and human + var/base_datum_custom = ANTAG_DATUM_TRAITOR_CUSTOM //used for body transfer + var/ai_datum = ANTAG_DATUM_TRAITOR_AI + var/human_datum = ANTAG_DATUM_TRAITOR_HUMAN var/special_role = "traitor" var/employer = "The Syndicate" var/give_objectives = TRUE var/should_give_codewords = TRUE var/list/objectives_given = list() -/datum/antagonist/traitor/custom //used to give custom objectives +/datum/antagonist/traitor/proc/transfer_important_variables(datum/antagonist/traitor/other) + other.silent = silent + other.employer = employer + other.special_role = special_role + other.objectives_given = objectives_given + +/datum/antagonist/traitor/custom + ai_datum = ANTAG_DATUM_TRAITOR_AI_CUSTOM + human_datum = ANTAG_DATUM_TRAITOR_HUMAN_CUSTOM + +/datum/antagonist/traitor/human + should_specialise = FALSE + var/should_equip = TRUE +/datum/antagonist/traitor/human/custom + silent = TRUE + should_give_codewords = FALSE + give_objectives = FALSE + should_equip = FALSE //Duplicating TCs is dangerous + +/datum/antagonist/traitor/AI + should_specialise = FALSE +/datum/antagonist/traitor/AI/custom + silent = TRUE + should_give_codewords = FALSE + give_objectives = FALSE + + +/datum/antagonist/traitor/on_body_transfer(mob/living/old_body, mob/living/new_body) + if(istype(new_body,/mob/living/silicon/ai)==istype(old_body,/mob/living/silicon/ai)) + ..() + else + silent = TRUE + owner.add_antag_datum(base_datum_custom) + for(var/datum/antagonist/traitor/new_datum in owner.antag_datums) + if(new_datum == src) + continue + transfer_important_variables(new_datum) + break + on_removal() + + + +/datum/antagonist/traitor/human/custom //used to give custom objectives + silent = TRUE + give_objectives = FALSE + should_give_codewords = FALSE +/datum/antagonist/traitor/AI/custom //used to give custom objectives silent = TRUE give_objectives = FALSE should_give_codewords = FALSE +/datum/antagonist/traitor/proc/specialise() + silent = TRUE + if(owner.current&&istype(owner.current,/mob/living/silicon/ai)) + owner.add_antag_datum(ai_datum) + else owner.add_antag_datum(human_datum) + on_removal() + /datum/antagonist/traitor/on_gain() + if(should_specialise) + specialise() + return SSticker.mode.traitors+=owner owner.special_role = special_role if(give_objectives) @@ -19,21 +79,38 @@ finalize_traitor() ..() +/datum/antagonist/traitor/apply_innate_effects() + if(owner.assigned_role == "Clown") + var/mob/living/carbon/human/traitor_mob = owner.current + if(traitor_mob&&istype(traitor_mob)) + if(!silent) to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + traitor_mob.dna.remove_mutation(CLOWNMUT) + +/datum/antagonist/traitor/remove_innate_effects() + if(owner.assigned_role == "Clown") + var/mob/living/carbon/human/traitor_mob = owner.current + if(traitor_mob&&istype(traitor_mob)) + traitor_mob.dna.add_mutation(CLOWNMUT) + /datum/antagonist/traitor/on_removal() + if(should_specialise) + return ..()//we never did any of this anyway SSticker.mode.traitors -= owner + for(var/O in objectives_given) + owner.objectives -= O + objectives_given = list() + if(!silent && owner.current) + to_chat(owner.current," You are no longer the [special_role]! ") + owner.special_role = null + ..() + +/datum/antagonist/traitor/AI/on_removal() if(owner.current && isAI(owner.current)) var/mob/living/silicon/ai/A = owner.current A.set_zeroth_law("") A.verbs -= /mob/living/silicon/ai/proc/choose_modules A.malf_picker.remove_verbs(A) qdel(A.malf_picker) - owner.remove_antag_equip() - for(var/O in objectives_given) - owner.objectives -= O - objectives_given = list() - if(owner.current) - to_chat(owner.current," You are no longer the [special_role]! ") - owner.special_role = null ..() /datum/antagonist/traitor/proc/add_objective(var/datum/objective/O) @@ -45,116 +122,118 @@ objectives_given -= O /datum/antagonist/traitor/proc/forge_traitor_objectives() - if(issilicon(owner.current)) - var/objective_count = 0 + return +/datum/antagonist/traitor/human/forge_traitor_objectives() + var/is_hijacker = prob(10) + var/martyr_chance = prob(20) + var/objective_count = is_hijacker //Hijacking counts towards number of objectives + if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors + if(!SSticker.mode.exchange_red) + SSticker.mode.exchange_red = owner + else + SSticker.mode.exchange_blue = owner + assign_exchange_role(SSticker.mode.exchange_red) + assign_exchange_role(SSticker.mode.exchange_blue) + objective_count += 1 //Exchange counts towards number of objectives + for(var/i = objective_count, i < config.traitor_objectives_amount, i++) + forge_single_objective() - if(prob(30)) - objective_count+=forge_single_objective() + if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount + if (!(locate(/datum/objective/hijack) in owner.objectives)) + var/datum/objective/hijack/hijack_objective = new + hijack_objective.owner = owner + add_objective(hijack_objective) + return - for(var/i = objective_count, i < config.traitor_objectives_amount, i++) + + var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead. + for(var/datum/objective/O in owner.objectives) + if(!O.martyr_compatible) + martyr_compatibility = 0 + break + + if(martyr_compatibility && martyr_chance) + var/datum/objective/martyr/martyr_objective = new + martyr_objective.owner = owner + add_objective(martyr_objective) + return + + else + if(!(locate(/datum/objective/escape) in owner.objectives)) + var/datum/objective/escape/escape_objective = new + escape_objective.owner = owner + add_objective(escape_objective) + return + +/datum/antagonist/traitor/AI/forge_traitor_objectives() + var/objective_count = 0 + + if(prob(30)) + objective_count += forge_single_objective() + + for(var/i = objective_count, i < config.traitor_objectives_amount, i++) + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = owner + kill_objective.find_target() + add_objective(kill_objective) + + var/datum/objective/survive/survive_objective = new + survive_objective.owner = owner + add_objective(survive_objective) +/datum/antagonist/traitor/proc/forge_single_objective() + return 0 +/datum/antagonist/traitor/human/forge_single_objective() //Returns how many objectives are added + .=1 + if(prob(50)) + var/list/active_ais = active_ais() + if(active_ais.len && prob(100/GLOB.joined_player_list.len)) + var/datum/objective/destroy/destroy_objective = new + destroy_objective.owner = owner + destroy_objective.find_target() + add_objective(destroy_objective) + else if(prob(30)) + var/datum/objective/maroon/maroon_objective = new + maroon_objective.owner = owner + maroon_objective.find_target() + add_objective(maroon_objective) + else var/datum/objective/assassinate/kill_objective = new kill_objective.owner = owner kill_objective.find_target() add_objective(kill_objective) - - var/datum/objective/survive/survive_objective = new - survive_objective.owner = owner - add_objective(survive_objective) - else - var/is_hijacker = prob(10) - var/martyr_chance = prob(20) - var/objective_count = is_hijacker //Hijacking counts towards number of objectives - if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors - if(!SSticker.mode.exchange_red) - SSticker.mode.exchange_red = owner - else - SSticker.mode.exchange_blue = owner - assign_exchange_role(SSticker.mode.exchange_red) - assign_exchange_role(SSticker.mode.exchange_blue) - objective_count += 1 //Exchange counts towards number of objectives - for(var/i = objective_count, i < config.traitor_objectives_amount, i++) - forge_single_objective() + var/datum/objective/steal/steal_objective = new + steal_objective.owner = owner + steal_objective.find_target() + add_objective(steal_objective) - if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount - if (!(locate(/datum/objective/hijack) in owner.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = owner - add_objective(hijack_objective) - return - - - var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead. - for(var/datum/objective/O in owner.objectives) - if(!O.martyr_compatible) - martyr_compatibility = 0 - break - - if(martyr_compatibility && martyr_chance) - var/datum/objective/martyr/martyr_objective = new - martyr_objective.owner = owner - add_objective(martyr_objective) - return - - else - if(!(locate(/datum/objective/escape) in owner.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = owner - add_objective(escape_objective) - return - -/datum/antagonist/traitor/proc/forge_single_objective() //Returns how many objectives are added +/datum/antagonist/traitor/AI/forge_single_objective() .=1 - if(issilicon(owner.current)) - var/special_pick = rand(1,4) - switch(special_pick) - if(1) - var/datum/objective/block/block_objective = new - block_objective.owner = owner - add_objective(block_objective) - if(2) - var/datum/objective/purge/purge_objective = new - purge_objective.owner = owner - add_objective(purge_objective) - if(3) - var/datum/objective/robot_army/robot_objective = new - robot_objective.owner = owner - add_objective(robot_objective) - if(4) //Protect and strand a target - var/datum/objective/protect/yandere_one = new - yandere_one.owner = owner - add_objective(yandere_one) - yandere_one.find_target() - var/datum/objective/maroon/yandere_two = new - yandere_two.owner = owner - yandere_two.target = yandere_one.target - yandere_two.update_explanation_text() // normally called in find_target() - add_objective(yandere_two) - .=2 - else - if(prob(50)) - var/list/active_ais = active_ais() - if(active_ais.len && prob(100/GLOB.joined_player_list.len)) - var/datum/objective/destroy/destroy_objective = new - destroy_objective.owner = owner - destroy_objective.find_target() - add_objective(destroy_objective) - else if(prob(30)) - var/datum/objective/maroon/maroon_objective = new - maroon_objective.owner = owner - maroon_objective.find_target() - add_objective(maroon_objective) - else - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = owner - kill_objective.find_target() - add_objective(kill_objective) - else - var/datum/objective/steal/steal_objective = new - steal_objective.owner = owner - steal_objective.find_target() - add_objective(steal_objective) - + var/special_pick = rand(1,4) + switch(special_pick) + if(1) + var/datum/objective/block/block_objective = new + block_objective.owner = owner + add_objective(block_objective) + if(2) + var/datum/objective/purge/purge_objective = new + purge_objective.owner = owner + add_objective(purge_objective) + if(3) + var/datum/objective/robot_army/robot_objective = new + robot_objective.owner = owner + add_objective(robot_objective) + if(4) //Protect and strand a target + var/datum/objective/protect/yandere_one = new + yandere_one.owner = owner + add_objective(yandere_one) + yandere_one.find_target() + var/datum/objective/maroon/yandere_two = new + yandere_two.owner = owner + yandere_two.target = yandere_one.target + yandere_two.update_explanation_text() // normally called in find_target() + add_objective(yandere_two) + .=2 /datum/antagonist/traitor/greet() to_chat(owner.current, "You are the [owner.special_role].") owner.announce_objectives() @@ -162,15 +241,15 @@ give_codewords() /datum/antagonist/traitor/proc/finalize_traitor() - if(issilicon(owner.current)) - add_law_zero() - owner.current.playsound_local('sound/ambience/antag/Malf.ogg',100,0) - owner.current.grant_language(/datum/language/codespeak) - else - equip() - owner.current.playsound_local('sound/ambience/antag/TatorAlert.ogg',100,0) SSticker.mode.update_traitor_icons_added(owner) return +/datum/antagonist/traitor/AI/finalize_traitor() + add_law_zero() + owner.current.playsound_local('sound/ambience/antag/Malf.ogg',100,0) + owner.current.grant_language(/datum/language/codespeak) +/datum/antagonist/traitor/human/finalize_traitor() + if(should_equip) equip(silent) + owner.current.playsound_local('sound/ambience/antag/TatorAlert.ogg',100,0) /datum/antagonist/traitor/proc/give_codewords() if(!owner.current) @@ -186,7 +265,7 @@ to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.") -/datum/antagonist/traitor/proc/add_law_zero() +/datum/antagonist/traitor/AI/proc/add_law_zero() var/mob/living/silicon/ai/killer = owner.current if(!killer || !istype(killer)) return @@ -197,10 +276,11 @@ to_chat(killer, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!") killer.add_malf_picker() -/datum/antagonist/traitor/proc/equip(safety = 0, employer) - owner.equip_traitor(employer) +/datum/antagonist/traitor/proc/equip(var/silent = FALSE) +/datum/antagonist/traitor/human/equip(var/silent = FALSE) + owner.equip_traitor(employer, silent) -/datum/antagonist/traitor/proc/assign_exchange_role() +/datum/antagonist/traitor/human/proc/assign_exchange_role() //set faction var/faction = "red" if(owner == SSticker.mode.exchange_blue) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index c69f93c4195..ab42fa2c791 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -146,6 +146,7 @@ A.on_removal() return TRUE + /datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. for(var/a in antag_datums) var/datum/antagonist/A = a @@ -254,17 +255,13 @@ if(gang_datum) gang_datum.remove_gang_hud(src) -/datum/mind/proc/equip_traitor(var/employer = "The Syndicate") +/datum/mind/proc/equip_traitor(var/employer = "The Syndicate", var/silent = FALSE) if(!current) return var/mob/living/carbon/human/traitor_mob = current if (!istype(traitor_mob)) return . = 1 - if (traitor_mob.mind) - if (traitor_mob.mind.assigned_role == "Clown") - to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - traitor_mob.dna.remove_mutation(CLOWNMUT) var/list/all_contents = traitor_mob.GetAllContents() var/obj/item/device/pda/PDA = locate() in all_contents @@ -295,7 +292,7 @@ uplink_loc = R if (!uplink_loc) - to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.") + if(!silent) to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.") . = 0 else var/obj/item/device/uplink/U = new(uplink_loc) @@ -305,19 +302,19 @@ if(uplink_loc == R) R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.") + if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.") traitor_mob.mind.store_memory("Radio Frequency: [format_frequency(R.traitor_frequency)] ([R.name]).") else if(uplink_loc == PDA) PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]" - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.") + if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.") traitor_mob.mind.store_memory("Uplink Passcode: [PDA.lock_code] ([PDA.name]).") else if(uplink_loc == P) P.traitor_unlock_degrees = rand(1, 360) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.") + if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.") traitor_mob.mind.store_memory("Uplink Degrees: [P.traitor_unlock_degrees] ([P.name]).") //Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does. @@ -1552,7 +1549,6 @@ qdel(flash) take_uplink() var/fail = 0 -// fail |= !SSticker.mode.equip_traitor(current, 1) fail |= !SSticker.mode.equip_revolutionary(current) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index c291b147c05..428ae959849 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -338,11 +338,13 @@ if(!(istype(H, /mob/living/carbon/human)||istype(H, /mob/living/silicon/))) continue if(H.stat == 2 || !H.client || !H.mind || ispAI(H)) continue if(is_special_character(H)) continue - var/datum/antagonist/traitor/traitordatum = H.mind.add_antag_datum(ANTAG_DATUM_TRAITOR_CUSTOM) + H.mind.add_antag_datum(ANTAG_DATUM_TRAITOR_CUSTOM) + var/datum/antagonist/traitor/traitordatum = H.mind.has_antag_datum(ANTAG_DATUM_TRAITOR) //original datum self deletes var/datum/objective/new_objective = new new_objective.owner = H new_objective.explanation_text = objective traitordatum.add_objective(new_objective) + traitordatum.equip(FALSE) traitordatum.greet() message_admins("[key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]") log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 49e54a1e9bb..f9f54a8ea59 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -399,12 +399,8 @@ Traitors and the like can also be revived with the previous role mostly intact. switch(new_character.mind.assigned_role) if("Cyborg")//More rigging to make em' work and check if they're traitor. new_character = new_character.Robotize() - if(traitordatum) - traitordatum.add_law_zero(new_character) if("AI") new_character = new_character.AIize() - if(traitordatum) - traitordatum.add_law_zero(new_character) else SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.