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.