Files
CHOMPStation2/code/game/gamemodes/traitor/traitor.dm
PsiOmega 87998f7eb1 Fixes #7295.
Cleans up round end summary.
Removes duplication of traitor summaries.
Attempts to improve how the traitor purchase log is presented.
Ghosts made manifest now have different names and assignments, otherwise one would get messages like "Anguished Phantom played as an Anguished Phantom".
Instead the message is "Anguished Phantom played as a Manifest Ghost".
2014-12-08 17:06:36 +01:00

301 lines
11 KiB
Plaintext

/datum/game_mode
// this includes admin-appointed traitors and multitraitors. Easy!
var/list/datum/mind/traitors = list()
/datum/game_mode/traitor
name = "traitor"
config_tag = "traitor"
restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")//AI", Currently out of the list as malf does not work for shit
required_players = 0
required_enemies = 1
recommended_enemies = 4
uplink_welcome = "AntagCorp Portable Teleportation Relay:"
uplink_uses = 10
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
var/traitors_possible = 4 //hard limit on traitors if scaling is turned off
var/const/traitor_scaling_coeff = 5.0 //how much does the amount of players get divided by to determine traitors
/datum/game_mode/traitor/announce()
world << "<B>The current game mode is - Traitor!</B>"
world << "<B>There is a foreign agent or traitor on the station. Do not let the traitor succeed!</B>"
/datum/game_mode/traitor/pre_setup()
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
var/list/possible_traitors = get_players_for_role(BE_TRAITOR)
// stop setup if no possible traitors
if(!possible_traitors.len)
return 0
var/num_traitors = 1
if(config.traitor_scaling)
num_traitors = max(1, round((num_players())/(traitor_scaling_coeff)))
else
num_traitors = max(1, min(num_players(), traitors_possible))
for(var/datum/mind/player in possible_traitors)
for(var/job in restricted_jobs)
if(player.assigned_role == job)
possible_traitors -= player
for(var/j = 0, j < num_traitors, j++)
if (!possible_traitors.len)
break
var/datum/mind/traitor = pick(possible_traitors)
traitors += traitor
traitor.special_role = "traitor"
possible_traitors.Remove(traitor)
if(!traitors.len)
return 0
return 1
/datum/game_mode/traitor/post_setup()
for(var/datum/mind/traitor in traitors)
if (!config.objectives_disabled)
forge_traitor_objectives(traitor)
spawn(rand(10,100))
finalize_traitor(traitor)
greet_traitor(traitor)
modePlayer += traitors
spawn (rand(waittime_l, waittime_h))
send_intercept()
..()
return 1
/datum/game_mode/proc/forge_traitor_objectives(var/datum/mind/traitor)
if (config.objectives_disabled)
return
if(istype(traitor.current, /mob/living/silicon))
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = traitor
kill_objective.find_target()
traitor.objectives += kill_objective
var/datum/objective/survive/survive_objective = new
survive_objective.owner = traitor
traitor.objectives += survive_objective
if(prob(10))
var/datum/objective/block/block_objective = new
block_objective.owner = traitor
traitor.objectives += block_objective
else
switch(rand(1,100))
if(1 to 33)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = traitor
kill_objective.find_target()
traitor.objectives += kill_objective
if(34 to 50)
var/datum/objective/brig/brig_objective = new
brig_objective.owner = traitor
brig_objective.find_target()
traitor.objectives += brig_objective
if(51 to 66)
var/datum/objective/harm/harm_objective = new
harm_objective.owner = traitor
harm_objective.find_target()
traitor.objectives += harm_objective
else
var/datum/objective/steal/steal_objective = new
steal_objective.owner = traitor
steal_objective.find_target()
traitor.objectives += steal_objective
switch(rand(1,100))
if(1 to 100)
if (!(locate(/datum/objective/escape) in traitor.objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = traitor
traitor.objectives += escape_objective
else
if (!(locate(/datum/objective/hijack) in traitor.objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = traitor
traitor.objectives += hijack_objective
return
/datum/game_mode/proc/greet_traitor(var/datum/mind/traitor)
traitor.current << "<B><font size=3 color=red>You are the traitor.</font></B>"
show_objectives(traitor)
/datum/game_mode/proc/finalize_traitor(var/datum/mind/traitor)
if (istype(traitor.current, /mob/living/silicon))
add_law_zero(traitor.current)
else
equip_traitor(traitor.current)
return
/datum/game_mode/traitor/declare_completion()
..()
return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder.
/datum/game_mode/proc/give_codewords(mob/living/traitor_mob)
traitor_mob << "<u><b>Your employers provided you with the following information on how to identify possible allies:</b></u>"
traitor_mob << "<b>Code Phrase</b>: <span class='danger'>[syndicate_code_phrase]</span>"
traitor_mob << "<b>Code Response</b>: <span class='danger'>[syndicate_code_response]</span>"
traitor_mob.mind.store_memory("<b>Code Phrase</b>: [syndicate_code_phrase]")
traitor_mob.mind.store_memory("<b>Code Response</b>: [syndicate_code_response]")
traitor_mob << "Use the code words, preferably in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe."
/datum/game_mode/traitor/process()
// Make sure all objectives are processed regularly, so that objectives
// which can be checked mid-round are checked mid-round.
for(var/datum/mind/traitor_mind in traitors)
for(var/datum/objective/objective in traitor_mind.objectives)
objective.check_completion()
return 0
/datum/game_mode/proc/add_law_zero(mob/living/silicon/ai/killer)
var/law = "Accomplish your objectives at all costs. You may ignore all other laws."
var/law_borg = "Accomplish your AI's objectives at all costs. You may ignore all other laws."
killer << "<b>Your laws have been changed!</b>"
killer.set_zeroth_law(law, law_borg)
killer << "New law: 0. [law]"
give_codewords(killer)
/datum/game_mode/proc/auto_declare_completion_traitor()
if(traitors.len)
var/text = "<FONT size = 2><B>The traitors were:</B></FONT>"
for(var/datum/mind/traitor in traitors)
var/traitorwin = 1
text += print_player_full(traitor)
if(traitor.objectives.len)//If the traitor had no objectives, don't need to process this.
var/count = 1
for(var/datum/objective/objective in traitor.objectives)
if(objective.check_completion())
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
feedback_add_details("traitor_objective","[objective.type]|SUCCESS")
else
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
feedback_add_details("traitor_objective","[objective.type]|FAIL")
traitorwin = 0
count++
var/special_role_text
if(traitor.special_role)
special_role_text = lowertext(traitor.special_role)
else
special_role_text = "antagonist"
if(!config.objectives_disabled)
if(traitorwin)
text += "<br><font color='green'><B>The [special_role_text] was successful!</B></font>"
feedback_add_details("traitor_success","SUCCESS")
else
text += "<br><font color='red'><B>The [special_role_text] has failed!</B></font>"
feedback_add_details("traitor_success","FAIL")
text += "<br>"
world << text
return 1
/datum/game_mode/proc/equip_traitor(mob/living/carbon/human/traitor_mob, var/safety = 0)
if (!istype(traitor_mob))
return
. = 1
if (traitor_mob.mind)
if (traitor_mob.mind.assigned_role == "Clown")
traitor_mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
traitor_mob.mutations.Remove(CLUMSY)
// find a radio! toolbox(es), backpack, belt, headset
var/loc = ""
var/obj/item/R = locate() //Hide the uplink in a PDA if available, otherwise radio
if(traitor_mob.client.prefs.uplinklocation == "Headset")
R = locate(/obj/item/device/radio) in traitor_mob.contents
if(!R)
R = locate(/obj/item/device/pda) in traitor_mob.contents
traitor_mob << "Could not locate a Radio, installing in PDA instead!"
if (!R)
traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed."
else if(traitor_mob.client.prefs.uplinklocation == "PDA")
R = locate(/obj/item/device/pda) in traitor_mob.contents
if(!R)
R = locate(/obj/item/device/radio) in traitor_mob.contents
traitor_mob << "Could not locate a PDA, installing into a Radio instead!"
if (!R)
traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed."
else if(traitor_mob.client.prefs.uplinklocation == "None")
traitor_mob << "You have elected to not have an AntagCorp portable teleportation relay installed!"
R = null
else
traitor_mob << "You have not selected a location for your relay in the antagonist options! Defaulting to PDA!"
R = locate(/obj/item/device/pda) in traitor_mob.contents
if (!R)
R = locate(/obj/item/device/radio) in traitor_mob.contents
traitor_mob << "Could not locate a PDA, installing into a Radio instead!"
if (!R)
traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed."
if (!R)
. = 0
else
if (istype(R, /obj/item/device/radio))
// generate list of radio freqs
var/obj/item/device/radio/target_radio = R
var/freq = 1441
var/list/freqlist = list()
while (freq <= 1489)
if (freq < 1451 || freq > PUB_FREQ)
freqlist += freq
freq += 2
if ((freq % 2) == 0)
freq += 1
freq = freqlist[rand(1, freqlist.len)]
var/obj/item/device/uplink/hidden/T = new(R)
T.uplink_owner = traitor_mob.mind
target_radio.hidden_uplink = T
target_radio.traitor_frequency = freq
traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features."
traitor_mob.mind.store_memory("<B>Radio Freq:</B> [format_frequency(freq)] ([R.name] [loc]).")
else if (istype(R, /obj/item/device/pda))
// generate a passcode if the uplink is hidden in a PDA
var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]"
var/obj/item/device/uplink/hidden/T = new(R)
T.uplink_owner = traitor_mob.mind
R.hidden_uplink = T
var/obj/item/device/pda/P = R
P.lock_code = pda_pass
traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features."
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [pda_pass] ([R.name] [loc]).")
//Begin code phrase.
if(!safety)//If they are not a rev. Can be added on to.
give_codewords(traitor_mob)
// Tell them about people they might want to contact.
var/mob/living/carbon/human/M = get_nt_opposed()
if(M && M != traitor_mob)
traitor_mob << "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them."
traitor_mob.mind.store_memory("<b>Potential Collaborator</b>: [M.real_name]")