another huge sync

This commit is contained in:
LetterJay
2017-06-21 18:00:00 -05:00
parent 0719541100
commit d04001c09d
51 changed files with 1443 additions and 981 deletions
+23 -17
View File
@@ -20,22 +20,28 @@
to_chat(AI, "<span class='userdanger'>Anomaly Detected. Returned to core!</span>") //The AI needs to be in its core to properly be converted
. = is_eligible_servant(new_owner.current)
if(!silent && new_owner.current)
if(issilicon(new_owner.current))
to_chat(new_owner.current, "<span class='heavy_brass'>You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the \
Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm.</span>")
if(.)
to_chat(new_owner.current, "<span class='heavy_brass'>The world before you suddenly glows a brilliant yellow. [issilicon(new_owner.current) ? "You cannot compute this truth!" : \
"Your mind is racing!"] You hear the whooshing steam and cl[pick("ank", "ink", "unk", "ang")]ing cogs of a billion billion machines, and all at once it comes to you.<br>\
Ratvar, the Clockwork Justiciar, [GLOB.ratvar_awakens ? "has been freed from his eternal prison" : "lies in exile, derelict and forgotten in an unseen realm"].</span>")
flash_color(new_owner.current, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 50)
else
to_chat(new_owner.current, "<span class='heavy_brass'>[iscarbon(new_owner.current) ? "Your mind is racing! Your body feels incredibly light! ":""]Your world glows a brilliant \
yellow! All at once it comes to you. Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm.</span>")
if(!.)
new_owner.current.visible_message("<span class='boldwarning'>[new_owner.current] seems to resist an unseen force!</span>")
to_chat(new_owner.current, "<span class='userdanger'>And yet, you somehow push it all away.</span>")
new_owner.current.visible_message("<span class='boldwarning'>[new_owner.current] seems to resist an unseen force!</span>", null, null, 7, new_owner.current)
to_chat(new_owner.current, "<span class='heavy_brass'>The world before you suddenly glows a brilliant yellow. [issilicon(new_owner.current) ? "You cannot compute this truth!" : \
"Your mind is racing!"] You hear the whooshing steam and cl[pick("ank", "ink", "unk", "ang")]ing cogs of a billion billion machines, and the sound</span> <span class='boldwarning'>\
is a meaningless cacophony.</span><br>\
<span class='userdanger'>You see an abomination of rusting parts[GLOB.ratvar_awakens ? ", and it is here.<br>It is too late" : \
" in an endless grey void.<br>It cannot be allowed to escape"].</span>")
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/clockcultalr.ogg', 40, TRUE, frequency = 100000, pressure_affected = FALSE)
flash_color(new_owner.current, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 5)
/datum/antagonist/clockcult/greet()
if(!owner.current || silent)
return
owner.current.visible_message("<span class='heavy_brass'>[owner.current]'s eyes glow a blazing yellow!</span>")
owner.current.visible_message("<span class='heavy_brass'>[owner.current]'s eyes glow a blazing yellow!</span>", null, null, 7, owner.current) //don't show the owner this message
to_chat(owner.current, "<span class='heavy_brass'>Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork \
Justiciar above all else. Perform his every whim without hesitation.</span>")
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/clockcultalr.ogg', 70, FALSE, pressure_affected = FALSE)
/datum/antagonist/clockcult/on_gain()
var/mob/living/current = owner.current
@@ -47,10 +53,14 @@
owner.current.log_message("<font color=#BE8700>Has been converted to the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
if(issilicon(current))
if(iscyborg(current) && !silent)
to_chat(current, "<span class='boldwarning'>You have been desynced from your master AI.</span>")
to_chat(current, "<span class='boldwarning'>In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
var/mob/living/silicon/robot/R = current
if(R.connected_ai && !is_servant_of_ratvar(R.connected_ai))
to_chat(R, "<span class='boldwarning'>You have been desynced from your master AI.<br>\
In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
else
to_chat(R, "<span class='boldwarning'>Your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
if(isAI(current))
to_chat(current, "<span class='boldwarning'>You are able to use your cameras to listen in on conversations.</span>")
to_chat(current, "<span class='boldwarning'>You are now able to use your cameras to listen in on conversations, but can no longer speak in anything but Ratvarian.</span>")
to_chat(current, "<span class='heavy_brass'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
else if(isbrain(current) || isclockmob(current))
to_chat(current, "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
@@ -88,11 +98,7 @@
A.eyeobj.relay_speech = TRUE
for(var/mob/living/silicon/robot/R in A.connected_robots)
if(R.connected_ai == A)
R.visible_message("<span class='heavy_brass'>[R]'s eyes glow a blazing yellow!</span>", \
"<span class='heavy_brass'>Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \
whim without hesitation.</span>")
to_chat(R, "<span class='boldwarning'>Your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
add_servant_of_ratvar(R, TRUE)
add_servant_of_ratvar(R)
S.laws = new/datum/ai_laws/ratvar
S.laws.associate(S)
S.update_icons()
+11
View File
@@ -0,0 +1,11 @@
/datum/antagonist/iaa
/datum/antagonist/iaa/apply_innate_effects()
.=..() //in case the base is used in future
if(owner&&owner.current)
give_pinpointer(owner.current)
/datum/antagonist/iaa/remove_innate_effects()
.=..()
if(owner&&owner.current)
owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer)
@@ -0,0 +1,327 @@
#define PINPOINTER_MINIMUM_RANGE 15
#define PINPOINTER_EXTRA_RANDOM_RANGE 10
#define PINPOINTER_PING_TIME 40
#define PROB_ACTUAL_TRAITOR 20
#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/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/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/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"
duration = -1
tick_interval = PINPOINTER_PING_TIME
alert_type = /obj/screen/alert/status_effect/agent_pinpointer
var/minimum_range = PINPOINTER_MINIMUM_RANGE
var/mob/scan_target = null
/obj/screen/alert/status_effect/agent_pinpointer
name = "Internal Affairs Integrated Pinpointer"
desc = "Even stealthier than a normal implant."
icon = 'icons/obj/device.dmi'
icon_state = "pinon"
/datum/status_effect/agent_pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
if(!scan_target)
linked_alert.icon_state = "pinonnull"
return
var/turf/here = get_turf(owner)
var/turf/there = get_turf(scan_target)
if(here.z != there.z)
linked_alert.icon_state = "pinonnull"
return
if(get_dist_euclidian(here,there)<=minimum_range + rand(0, PINPOINTER_EXTRA_RANDOM_RANGE))
linked_alert.icon_state = "pinondirect"
else
linked_alert.setDir(get_dir(here, there))
switch(get_dist(here, there))
if(1 to 8)
linked_alert.icon_state = "pinonclose"
if(9 to 16)
linked_alert.icon_state = "pinonmedium"
if(16 to INFINITY)
linked_alert.icon_state = "pinonfar"
/datum/status_effect/agent_pinpointer/proc/scan_for_target()
scan_target = null
if(owner)
if(owner.mind)
if(owner.mind.objectives)
for(var/datum/objective/objective_ in owner.mind.objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
var/mob/current = objective.target.current
if(current&&current.stat!=DEAD)
scan_target = current
break
/datum/status_effect/agent_pinpointer/tick()
if(!owner)
qdel(src)
return
scan_for_target()
point_to_target()
/proc/is_internal_objective(datum/objective/O)
return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal))
/datum/antagonist/traitor/proc/replace_escape_objective()
if(!owner||!owner.objectives)
return
for (var/objective_ in owner.objectives)
if(!(istype(objective_, /datum/objective/escape)||istype(objective_,/datum/objective/survive)))
continue
remove_objective(objective_)
var/datum/objective/martyr/martyr_objective = new
martyr_objective.owner = owner
add_objective(martyr_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_)
/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, "<span class='userdanger'> Target eliminated: [victim.name]</span>")
for(var/objective_ in victim.objectives)
if(istype(objective_, /datum/objective/assassinate/internal))
var/datum/objective/assassinate/internal/objective = objective_
if(objective.target==owner)
continue
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)
this.targets_stolen += objective.target
var/status_text = objective.check_completion() ? "neutralised" : "active"
to_chat(owner.current, "<span class='userdanger'> New target added to database: [objective.target.name] ([status_text]) </span>")
else if(istype(objective_, /datum/objective/destroy/internal))
var/datum/objective/destroy/internal/objective = objective_
var/datum/objective/destroy/internal/new_objective = new
if(objective.target==owner)
continue
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)
this.targets_stolen += objective.target
var/status_text = objective.check_completion() ? "neutralised" : "active"
to_chat(owner.current, "<span class='userdanger'> New target added to database: [objective.target.name] ([status_text]) </span>")
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())
this.last_man_standing = FALSE
return
if(this.last_man_standing)
if(this.syndicate)
to_chat(owner.current,"<span class='userdanger'> All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. </span>")
else
to_chat(owner.current,"<span class='userdanger'> 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.</span>")
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
if(owner&&owner.current&&owner.current.stat!=DEAD)
for(var/objective_ in owner.objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
if(!objective.target)
continue
if(objective.check_completion())
if(objective.stolen)
continue
else
steal_targets(objective.target)
objective.stolen = TRUE
else
if(objective.stolen)
var/fail_msg = "<span class='userdanger'>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! </span>"
if(this.last_man_standing)
if(this.syndicate)
fail_msg += "<span class='userdanger'> You no longer have permission to die. </span>"
else
fail_msg += "<span class='userdanger'> The truth could still slip out!</font><B><font size=5 color=red> Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated.</span>"
reinstate_escape_objective(owner)
this.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
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))
var/datum/objective/destroy/internal/destroy_objective = new
destroy_objective.owner = owner
destroy_objective.target = target_mind
destroy_objective.update_explanation_text()
else
var/datum/objective/assassinate/internal/kill_objective = new
kill_objective.owner = owner
kill_objective.target = target_mind
kill_objective.update_explanation_text()
add_objective(kill_objective)
//Optional traitor objective
if(prob(PROB_ACTUAL_TRAITOR))
employer = "The Syndicate"
owner.special_role = TRAITOR_AGENT_ROLE
special_role = TRAITOR_AGENT_ROLE
this.syndicate = TRUE
forge_single_objective()
else
..() // Give them standard objectives.
return
/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, "<span class='userdanger'>You are the [special_role].</span>")
if(this.syndicate)
to_chat(owner.current, "<span class='userdanger'>Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.</span>")
to_chat(owner.current, "<B><font size=5 color=red>Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.</font></B>")
to_chat(owner.current, "<span class='userdanger'> You have been provided with a standard uplink to accomplish your task. </span>")
else
to_chat(owner.current, "<span class='userdanger'>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</span>")
to_chat(owner.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
to_chat(owner.current, "<span class='userdanger'>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</span>")
to_chat(owner.current, "<span class='userdanger'>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.</span>")
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
#undef PINPOINTER_PING_TIME
+326
View File
@@ -0,0 +1,326 @@
/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/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)
forge_traitor_objectives()
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,"<span class='userdanger'> You are no longer the [special_role]! </span>")
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)
..()
/datum/antagonist/traitor/proc/add_objective(var/datum/objective/O)
owner.objectives += O
objectives_given += O
/datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O)
owner.objectives -= O
objectives_given -= O
/datum/antagonist/traitor/proc/forge_traitor_objectives()
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(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/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)
else
var/datum/objective/steal/steal_objective = new
steal_objective.owner = owner
steal_objective.find_target()
add_objective(steal_objective)
/datum/antagonist/traitor/AI/forge_single_objective()
.=1
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, "<B><font size=3 color=red>You are the [owner.special_role].</font></B>")
owner.announce_objectives()
if(should_give_codewords)
give_codewords()
/datum/antagonist/traitor/proc/finalize_traitor()
SSticker.mode.update_traitor_icons_added(owner)
return
/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/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
var/mob/traitor_mob=owner.current
to_chat(traitor_mob, "<U><B>The Syndicate provided you with the following information on how to identify their agents:</B></U>")
to_chat(traitor_mob, "<B>Code Phrase</B>: <span class='danger'>[GLOB.syndicate_code_phrase]</span>")
to_chat(traitor_mob, "<B>Code Response</B>: <span class='danger'>[GLOB.syndicate_code_response]</span>")
traitor_mob.mind.store_memory("<b>Code Phrase</b>: [GLOB.syndicate_code_phrase]")
traitor_mob.mind.store_memory("<b>Code Response</b>: [GLOB.syndicate_code_response]")
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()
var/mob/living/silicon/ai/killer = owner.current
if(!killer || !istype(killer))
return
var/law = "Accomplish your objectives at all costs."
var/law_borg = "Accomplish your AI's objectives at all costs."
killer.set_zeroth_law(law, law_borg)
killer.set_syndie_radio()
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(var/silent = FALSE)
/datum/antagonist/traitor/human/equip(var/silent = FALSE)
owner.equip_traitor(employer, silent)
/datum/antagonist/traitor/human/proc/assign_exchange_role()
//set faction
var/faction = "red"
if(owner == SSticker.mode.exchange_blue)
faction = "blue"
//Assign objectives
var/datum/objective/steal/exchange/exchange_objective = new
exchange_objective.set_faction(faction,((faction == "red") ? SSticker.mode.exchange_blue : SSticker.mode.exchange_red))
exchange_objective.owner = owner
add_objective(exchange_objective)
if(prob(20))
var/datum/objective/steal/exchange/backstab/backstab_objective = new
backstab_objective.set_faction(faction)
backstab_objective.owner = owner
add_objective(backstab_objective)
//Spawn and equip documents
var/mob/living/carbon/human/mob = owner.current
var/obj/item/weapon/folder/syndicate/folder
if(owner == SSticker.mode.exchange_red)
folder = new/obj/item/weapon/folder/syndicate/red(mob.loc)
else
folder = new/obj/item/weapon/folder/syndicate/blue(mob.loc)
var/list/slots = list (
"backpack" = slot_in_backpack,
"left pocket" = slot_l_store,
"right pocket" = slot_r_store
)
var/where = "At your feet"
var/equipped_slot = mob.equip_in_one_of_slots(folder, slots)
if (equipped_slot)
where = "In your [equipped_slot]"
to_chat(mob, "<BR><BR><span class='info'>[where] is a folder containing <b>secret documents</b> that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.</span><BR>")
+83 -28
View File
@@ -187,15 +187,7 @@
/datum/mind/proc/remove_traitor()
if(src in SSticker.mode.traitors)
SSticker.mode.traitors -= src
if(isAI(current))
var/mob/living/silicon/ai/A = current
A.set_zeroth_law("")
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
A.malf_picker.remove_verbs(A)
qdel(A.malf_picker)
special_role = null
remove_antag_equip()
src.remove_antag_datum(ANTAG_DATUM_TRAITOR)
SSticker.mode.update_traitor_icons_removed(src)
/datum/mind/proc/remove_nukeop()
@@ -263,6 +255,68 @@
if(gang_datum)
gang_datum.remove_gang_hud(src)
/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
var/list/all_contents = traitor_mob.GetAllContents()
var/obj/item/device/pda/PDA = locate() in all_contents
var/obj/item/device/radio/R = locate() in all_contents
var/obj/item/weapon/pen/P = locate() in all_contents //including your PDA-pen!
var/obj/item/uplink_loc
if(traitor_mob.client && traitor_mob.client.prefs)
switch(traitor_mob.client.prefs.uplink_spawn_loc)
if(UPLINK_PDA)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = R
if(!uplink_loc)
uplink_loc = P
if(UPLINK_RADIO)
uplink_loc = R
if(!uplink_loc)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = P
if(UPLINK_PEN)
uplink_loc = P
if(!uplink_loc)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = R
if (!uplink_loc)
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)
U.owner = "[traitor_mob.key]"
uplink_loc.hidden_uplink = U
if(uplink_loc == R)
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
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("<B>Radio Frequency:</B> [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")]"
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("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
else if(uplink_loc == P)
P.traitor_unlock_degrees = rand(1, 360)
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("<B>Uplink Degrees:</B> [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.
@@ -1157,27 +1211,29 @@
else if (href_list["traitor"])
switch(href_list["traitor"])
if("clear")
to_chat(current, "<span class='userdanger'>You have been brainwashed!</span>")
remove_traitor()
to_chat(current, "<span class='userdanger'>You have been brainwashed! You are no longer a traitor!</span>")
message_admins("[key_name_admin(usr)] has de-traitor'ed [current].")
log_admin("[key_name(usr)] has de-traitor'ed [current].")
SSticker.mode.update_traitor_icons_removed(src)
if("traitor")
if(!(src in SSticker.mode.traitors))
SSticker.mode.traitors += src
special_role = "traitor"
to_chat(current, "<span class='boldannounce'>You are a traitor!</span>")
message_admins("[key_name_admin(usr)] has traitor'ed [current].")
log_admin("[key_name(usr)] has traitor'ed [current].")
if(isAI(current))
var/mob/living/silicon/ai/A = current
SSticker.mode.add_law_zero(A)
SSticker.mode.update_traitor_icons_added(src)
make_Traitor()
if("autoobjectives")
SSticker.mode.forge_traitor_objectives(src)
to_chat(usr, "<span class='notice'>The objectives for traitor [key] have been generated. You can edit them and anounce manually.</span>")
var/datum/antagonist/traitor/traitordatum = has_antag_datum(ANTAG_DATUM_TRAITOR)
if(!traitordatum)
message_admins("[key_name_admin(usr)] has traitor'ed [current] as part of autoobjectives.")
log_admin("[key_name(usr)] has traitor'ed [current] as part of autoobjectives.")
make_Traitor()
else
log_admin("[key_name(usr)] has forged objectives for [current] as part of autoobjectives.")
traitordatum.forge_traitor_objectives()
to_chat(usr, "<span class='notice'>The objectives for traitor [key] have been generated. You can edit them and anounce manually.</span>")
else if(href_list["devil"])
var/datum/antagonist/devil/devilinfo = has_antag_datum(ANTAG_DATUM_DEVIL)
@@ -1353,9 +1409,11 @@
message_admins("[key_name_admin(usr)] changed [current]'s telecrystal count to [crystals].")
log_admin("[key_name(usr)] changed [current]'s telecrystal count to [crystals].")
if("uplink")
if(!SSticker.mode.equip_traitor(current, !(src in SSticker.mode.traitors)))
if(!equip_traitor())
to_chat(usr, "<span class='danger'>Equipping a syndicate failed!</span>")
log_admin("[key_name(usr)] attempted to give [current] an uplink.")
log_admin("[key_name(usr)] tried and failed to give [current] an uplink.")
else
log_admin("[key_name(usr)] gave [current] an uplink.")
else if (href_list["obj_announce"])
announce_objectives()
@@ -1383,12 +1441,10 @@
qdel(H)
/datum/mind/proc/make_Traitor()
if(!(src in SSticker.mode.traitors))
SSticker.mode.traitors += src
special_role = "traitor"
SSticker.mode.forge_traitor_objectives(src)
SSticker.mode.finalize_traitor(src)
SSticker.mode.greet_traitor(src)
if(!(has_antag_datum(ANTAG_DATUM_TRAITOR)))
var/datum/antagonist/traitor/traitordatum = add_antag_datum(ANTAG_DATUM_TRAITOR)
return traitordatum
/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE)
if(!(src in SSticker.mode.syndicates))
@@ -1494,7 +1550,6 @@
qdel(flash)
take_uplink()
var/fail = 0
// fail |= !SSticker.mode.equip_traitor(current, 1)
fail |= !SSticker.mode.equip_revolutionary(current)