diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 6c744b3d84..f377037301 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -202,9 +202,7 @@
special_role = null
/datum/mind/proc/remove_traitor()
- if(src in SSticker.mode.traitors)
- remove_antag_datum(/datum/antagonist/traitor)
- SSticker.mode.update_traitor_icons_removed(src)
+ remove_antag_datum(/datum/antagonist/traitor)
/datum/mind/proc/remove_brother()
if(src in SSticker.mode.brothers)
@@ -252,7 +250,6 @@
remove_wizard()
remove_cultist()
remove_rev()
- SSticker.mode.update_traitor_icons_removed(src)
SSticker.mode.update_cult_icons_removed(src)
/datum/mind/proc/equip_traitor(employer = "The Syndicate", silent = FALSE, datum/antagonist/uplink_owner)
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 95d1aaaa1d..919ee49b77 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -90,14 +90,4 @@
/datum/game_mode/traitor/generate_report()
return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \
- Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions."
-
-/datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind)
- var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
- traitorhud.join_hud(traitor_mind.current)
- set_antag_hud(traitor_mind.current, "traitor")
-
-/datum/game_mode/proc/update_traitor_icons_removed(datum/mind/traitor_mind)
- var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
- traitorhud.leave_hud(traitor_mind.current)
- set_antag_hud(traitor_mind.current, null)
+ Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions."
\ No newline at end of file
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 5138089a6c..a3f7823b58 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -367,7 +367,7 @@
continue
if(is_special_character(H))
continue
- var/datum/antagonist/traitor/human/T = new()
+ var/datum/antagonist/traitor/T = new()
T.give_objectives = FALSE
var/datum/objective/new_objective = new
new_objective.owner = H
diff --git a/code/modules/antagonists/traitor/IAA/internal_affairs.dm b/code/modules/antagonists/traitor/IAA/internal_affairs.dm
index 605db9797d..28f562d23e 100644
--- a/code/modules/antagonists/traitor/IAA/internal_affairs.dm
+++ b/code/modules/antagonists/traitor/IAA/internal_affairs.dm
@@ -6,11 +6,10 @@
/datum/antagonist/traitor/internal_affairs
name = "Internal Affairs Agent"
- human_datum = /datum/antagonist/traitor/human/internal_affairs
- ai_datum = /datum/antagonist/traitor/AI/internal_affairs
antagpanel_category = "IAA"
-/datum/antagonist/traitor/AI/internal_affairs
+
+/datum/antagonist/traitor/internal_affairs
name = "Internal Affairs Agent"
employer = "Nanotrasen"
special_role = "internal affairs agent"
@@ -20,47 +19,29 @@
var/list/datum/mind/targets_stolen
-/datum/antagonist/traitor/human/internal_affairs
- name = "Internal Affairs Agent"
- employer = "Nanotrasen"
- special_role = "internal affairs agent"
- antagpanel_category = "IAA"
- var/syndicate = FALSE
- var/last_man_standing = FALSE
- var/list/datum/mind/targets_stolen
-
-
-/datum/antagonist/traitor/human/internal_affairs/proc/give_pinpointer()
+/datum/antagonist/traitor/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()
+/datum/antagonist/traitor/internal_affairs/apply_innate_effects()
.=..() //in case the base is used in future
if(owner && owner.current)
give_pinpointer(owner.current)
-/datum/antagonist/traitor/human/internal_affairs/remove_innate_effects()
+/datum/antagonist/traitor/internal_affairs/remove_innate_effects()
.=..()
if(owner && owner.current)
owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer)
-/datum/antagonist/traitor/human/internal_affairs/on_gain()
+/datum/antagonist/traitor/internal_affairs/on_gain()
START_PROCESSING(SSprocessing, src)
.=..()
-/datum/antagonist/traitor/human/internal_affairs/on_removal()
+/datum/antagonist/traitor/internal_affairs/on_removal()
STOP_PROCESSING(SSprocessing,src)
.=..()
-/datum/antagonist/traitor/human/internal_affairs/process()
+/datum/antagonist/traitor/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"
@@ -142,21 +123,14 @@
continue
remove_objective(objective_)
-/datum/antagonist/traitor/human/internal_affairs/reinstate_escape_objective()
+/datum/antagonist/traitor/internal_affairs/reinstate_escape_objective()
..()
- var/datum/objective/escape/escape_objective = new
+ var/objtype = traitor_kind == TRAITOR_HUMAN ? /datum/objective/escape : /datum/objective/survive
+ var/datum/objective/escape_objective = new objtype
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
-
+/datum/antagonist/traitor/internal_affairs/proc/steal_targets(datum/mind/victim)
if(!owner.current||owner.current.stat==DEAD)
return
to_chat(owner.current, " Target eliminated: [victim.name]")
@@ -165,13 +139,13 @@
var/datum/objective/assassinate/internal/objective = objective_
if(objective.target==owner)
continue
- else if(this.targets_stolen.Find(objective.target) == 0)
+ else if(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)
- this.targets_stolen += objective.target
+ 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))
@@ -179,31 +153,30 @@
var/datum/objective/destroy/internal/new_objective = new
if(objective.target==owner)
continue
- else if(this.targets_stolen.Find(objective.target) == 0)
+ else if(targets_stolen.Find(objective.target) == 0)
new_objective.owner = owner
new_objective.target = objective.target
new_objective.update_explanation_text()
add_objective(new_objective)
- this.targets_stolen += objective.target
+ 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]) ")
- this.last_man_standing = TRUE
+ 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())
- this.last_man_standing = FALSE
+ last_man_standing = FALSE
return
- if(this.last_man_standing)
- if(this.syndicate)
+ if(last_man_standing)
+ if(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/proc/iaa_process()
- var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA
+/datum/antagonist/traitor/internal_affairs/proc/iaa_process()
if(owner&&owner.current&&owner.current.stat!=DEAD)
for(var/objective_ in owner.objectives)
if(!is_internal_objective(objective_))
@@ -220,20 +193,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(this.last_man_standing)
- if(this.syndicate)
+ if(last_man_standing)
+ if(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)
- this.last_man_standing = FALSE
+ last_man_standing = FALSE
to_chat(owner.current, fail_msg)
objective.stolen = FALSE
-/datum/antagonist/traitor/proc/forge_iaa_objectives()
- var/datum/antagonist/traitor/human/internal_affairs/this = src //Should only use this if IAA
+/datum/antagonist/traitor/internal_affairs/proc/forge_iaa_objectives()
if(SSticker.mode.target_list.len && SSticker.mode.target_list[owner]) // Is a double agent
-
// Assassinate
var/datum/mind/target_mind = SSticker.mode.target_list[owner]
if(issilicon(target_mind.current))
@@ -253,31 +224,25 @@
employer = "The Syndicate"
owner.special_role = TRAITOR_AGENT_ROLE
special_role = TRAITOR_AGENT_ROLE
- this.syndicate = TRUE
+ syndicate = TRUE
forge_single_objective()
-
else
..() // Give them standard objectives.
return
-/datum/antagonist/traitor/human/internal_affairs/forge_traitor_objectives()
+/datum/antagonist/traitor/internal_affairs/forge_traitor_objectives()
forge_iaa_objectives()
- var/datum/objective/escape/escape_objective = new
+
+ var/objtype = traitor_kind == TRAITOR_HUMAN ? /datum/objective/escape : /datum/objective/survive
+ var/datum/objective/escape_objective = new objtype
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
+/datum/antagonist/traitor/internal_affairs/proc/greet_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(this.syndicate)
+ if(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. ")
@@ -289,13 +254,9 @@
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()
+/datum/antagonist/traitor/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/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index ae750adebc..9066759648 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -1,39 +1,23 @@
+#define TRAITOR_HUMAN "human"
+#define TRAITOR_AI "AI"
+
/datum/antagonist/traitor
name = "Traitor"
roundend_category = "traitors"
antagpanel_category = "Traitor"
job_rank = ROLE_TRAITOR
antag_moodlet = /datum/mood_event/focused
- var/should_specialise = TRUE //do we split into AI and human, set to true on inital assignment only
- var/ai_datum = /datum/antagonist/traitor/AI
- var/human_datum = /datum/antagonist/traitor/human
var/special_role = ROLE_TRAITOR
var/employer = "The Syndicate"
var/give_objectives = TRUE
var/should_give_codewords = TRUE
-
-
-
-/datum/antagonist/traitor/human
- show_in_antagpanel = FALSE
- should_specialise = FALSE
var/should_equip = TRUE
-
-
-/datum/antagonist/traitor/AI
- show_in_antagpanel = FALSE
- should_specialise = FALSE
-
-/datum/antagonist/traitor/specialization(datum/mind/new_owner)
- if(should_specialise)
- if(new_owner.current && isAI(new_owner.current))
- return new ai_datum()
- else
- return new human_datum()
- else
- return ..()
+ var/traitor_kind = TRAITOR_HUMAN //Set on initial assignment
/datum/antagonist/traitor/on_gain()
+ if(owner.current && isAI(owner.current))
+ traitor_kind = TRAITOR_AI
+
SSticker.mode.traitors += owner
owner.special_role = special_role
if(give_objectives)
@@ -56,19 +40,18 @@
traitor_mob.dna.add_mutation(CLOWNMUT)
/datum/antagonist/traitor/on_removal()
- SSticker.mode.traitors -= owner
- 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))
+ //Remove malf powers.
+ if(traitor_kind == TRAITOR_AI && 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_malf_verbs(A)
qdel(A.malf_picker)
+
+ SSticker.mode.traitors -= owner
+ if(!silent && 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)
@@ -80,9 +63,13 @@
objectives -= O
/datum/antagonist/traitor/proc/forge_traitor_objectives()
- return
+ switch(traitor_kind)
+ if(TRAITOR_AI)
+ forge_ai_objectives()
+ else
+ forge_human_objectives()
-/datum/antagonist/traitor/human/forge_traitor_objectives()
+/datum/antagonist/traitor/proc/forge_human_objectives()
var/is_hijacker = FALSE
if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks
is_hijacker = prob(10)
@@ -127,7 +114,7 @@
add_objective(escape_objective)
return
-/datum/antagonist/traitor/AI/forge_traitor_objectives()
+/datum/antagonist/traitor/proc/forge_ai_objectives()
var/objective_count = 0
if(prob(30))
@@ -142,9 +129,16 @@
var/datum/objective/survive/exist/exist_objective = new
exist_objective.owner = owner
add_objective(exist_objective)
+
+
/datum/antagonist/traitor/proc/forge_single_objective()
- return 0
-/datum/antagonist/traitor/human/forge_single_objective() //Returns how many objectives are added
+ switch(traitor_kind)
+ if(TRAITOR_AI)
+ return forge_single_AI_objective()
+ else
+ return forge_single_human_objective()
+
+/datum/antagonist/traitor/proc/forge_single_human_objective() //Returns how many objectives are added
.=1
if(prob(50))
var/list/active_ais = active_ais()
@@ -175,7 +169,7 @@
steal_objective.find_target()
add_objective(steal_objective)
-/datum/antagonist/traitor/AI/forge_single_objective()
+/datum/antagonist/traitor/proc/forge_single_AI_objective()
.=1
var/special_pick = rand(1,4)
switch(special_pick)
@@ -209,34 +203,41 @@
if(should_give_codewords)
give_codewords()
+/datum/antagonist/traitor/proc/update_traitor_icons_added(datum/mind/traitor_mind)
+ var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
+ traitorhud.join_hud(owner.current)
+ set_antag_hud(owner.current, "traitor")
+
+/datum/antagonist/traitor/proc/update_traitor_icons_removed(datum/mind/traitor_mind)
+ var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
+ traitorhud.leave_hud(owner.current)
+ set_antag_hud(owner.current, null)
+
/datum/antagonist/traitor/proc/finalize_traitor()
- SSticker.mode.update_traitor_icons_added(owner)
- return
+ switch(traitor_kind)
+ if(TRAITOR_AI)
+ add_law_zero()
+ owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
+ owner.current.grant_language(/datum/language/codespeak)
+ if(TRAITOR_HUMAN)
+ if(should_equip)
+ equip(silent)
+ owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
-/datum/antagonist/traitor/AI/finalize_traitor()
- ..()
- add_law_zero()
- owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
- owner.current.grant_language(/datum/language/codespeak)
-
-/datum/antagonist/traitor/AI/apply_innate_effects(mob/living/mob_override)
+/datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override)
. = ..()
+ update_traitor_icons_added()
var/mob/living/silicon/ai/A = mob_override || owner.current
- if(istype(A))
+ if(istype(A) && traitor_kind == TRAITOR_AI)
A.hack_software = TRUE
-/datum/antagonist/traitor/AI/remove_innate_effects(mob/living/mob_override)
+/datum/antagonist/traitor/remove_innate_effects(mob/living/mob_override)
. = ..()
+ update_traitor_icons_removed()
var/mob/living/silicon/ai/A = mob_override || owner.current
- if(istype(A))
+ if(istype(A) && traitor_kind == TRAITOR_AI)
A.hack_software = FALSE
-/datum/antagonist/traitor/human/finalize_traitor()
- ..()
- if(should_equip)
- equip(silent)
- owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
-
/datum/antagonist/traitor/proc/give_codewords()
if(!owner.current)
return
@@ -251,7 +252,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/AI/proc/add_law_zero()
+/datum/antagonist/traitor/proc/add_law_zero()
var/mob/living/silicon/ai/killer = owner.current
if(!killer || !istype(killer))
return
@@ -263,12 +264,10 @@
killer.add_malf_picker()
/datum/antagonist/traitor/proc/equip(var/silent = FALSE)
- return
+ if(traitor_kind == TRAITOR_HUMAN)
+ owner.equip_traitor(employer, silent, src)
-/datum/antagonist/traitor/human/equip(var/silent = FALSE)
- owner.equip_traitor(employer, silent, src)
-
-/datum/antagonist/traitor/human/proc/assign_exchange_role()
+/datum/antagonist/traitor/proc/assign_exchange_role()
//set faction
var/faction = "red"
if(owner == SSticker.mode.exchange_blue)