mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-06 07:32:15 +00:00
Several head objects path changed so they are not helmets, head means can fit on your head, helmet was securities helmets, space helmets currently still helmet. Cult restricted job list now has the sec force + cap because you can’t convert them as is. AI removed from protected traitor jobs as malf is currently effectively out of commission. A Protected list was added to changling. Removed the furry mob files that were not checked. Moved two unchecked files to unused git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3896 316c924e-a436-60f5-8080-3fe189b3f50e
305 lines
12 KiB
Plaintext
305 lines
12 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", "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 = "Syndicate Uplink Console:"
|
|
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 syndicate 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)
|
|
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(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 50)
|
|
var/datum/objective/assassinate/kill_objective = new
|
|
kill_objective.owner = traitor
|
|
kill_objective.find_target()
|
|
traitor.objectives += kill_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 90)
|
|
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>"
|
|
var/obj_count = 1
|
|
for(var/datum/objective/objective in traitor.objectives)
|
|
traitor.current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
|
|
obj_count++
|
|
return
|
|
|
|
|
|
/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/add_law_zero(mob/living/silicon/ai/killer)
|
|
var/law = "Accomplish your objectives at all costs."
|
|
killer << "<b>Your laws have been changed!</b>"
|
|
killer.set_zeroth_law(law)
|
|
killer << "New law: 0. [law]"
|
|
|
|
//Begin code phrase.
|
|
killer << "The Syndicate provided you with the following information on how to identify their agents:"
|
|
if(prob(80))
|
|
killer << "\red Code Phrase: \black [syndicate_code_phrase]"
|
|
killer.mind.store_memory("<b>Code Phrase</b>: [syndicate_code_phrase]")
|
|
else
|
|
killer << "Unfortunately, the Syndicate did not provide you with a code phrase."
|
|
if(prob(80))
|
|
killer << "\red Code Response: \black [syndicate_code_response]"
|
|
killer.mind.store_memory("<b>Code Response</b>: [syndicate_code_response]")
|
|
else
|
|
killer << "Unfortunately, the Syndicate did not provide you with a code response."
|
|
killer << "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."
|
|
//End code phrase.
|
|
|
|
|
|
/datum/game_mode/proc/auto_declare_completion_traitor()
|
|
for(var/datum/mind/traitor in traitors)
|
|
var/traitor_name
|
|
|
|
if(traitor.current)
|
|
if(traitor.current == traitor.original)
|
|
traitor_name = "[traitor.current.real_name] (played by [traitor.key])"
|
|
else if (traitor.original)
|
|
traitor_name = "[traitor.current.real_name] (originally [traitor.original.real_name]) (played by [traitor.key])"
|
|
else
|
|
traitor_name = "[traitor.current.real_name] (original character destroyed) (played by [traitor.key])"
|
|
else
|
|
traitor_name = "[traitor.key] (character destroyed)"
|
|
var/special_role_text = traitor.special_role?(lowertext(traitor.special_role)):"antagonist"
|
|
world << "<B>The [special_role_text] was [traitor_name]</B>"
|
|
if(traitor.objectives.len)//If the traitor had no objectives, don't need to process this.
|
|
var/traitorwin = 1
|
|
var/count = 1
|
|
for(var/datum/objective/objective in traitor.objectives)
|
|
if(objective.check_completion())
|
|
world << "<B>Objective #[count]</B>: [objective.explanation_text] \green <B>Success</B>"
|
|
feedback_add_details("traitor_objective","[objective.type]|SUCCESS")
|
|
else
|
|
world << "<B>Objective #[count]</B>: [objective.explanation_text] \red Failed"
|
|
feedback_add_details("traitor_objective","[objective.type]|FAIL")
|
|
traitorwin = 0
|
|
count++
|
|
|
|
if(traitorwin)
|
|
world << "<B>The [special_role_text] was successful!<B>"
|
|
feedback_add_details("traitor_success","SUCCESS")
|
|
else
|
|
world << "<B>The [special_role_text] has failed!<B>"
|
|
feedback_add_details("traitor_success","FAIL")
|
|
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/device/R = null //Hide the uplink in a PDA if available, otherwise radio
|
|
if (!R && istype(traitor_mob.belt, /obj/item/device/pda))
|
|
R = traitor_mob.belt
|
|
loc = "on your belt"
|
|
if (!R && istype(traitor_mob.wear_id, /obj/item/device/pda))
|
|
R = traitor_mob.wear_id
|
|
loc = "on your jumpsuit"
|
|
if (!R && istype(traitor_mob.wear_id, /obj/item/device/pda))
|
|
R = traitor_mob.wear_id
|
|
loc = "on your jumpsuit"
|
|
if (!R && istype(traitor_mob.l_hand, /obj/item/weapon/storage))
|
|
var/obj/item/weapon/storage/S = traitor_mob.l_hand
|
|
var/list/L = S.return_inv()
|
|
for (var/obj/item/device/radio/foo in L)
|
|
R = foo
|
|
loc = "in the [S.name] in your left hand"
|
|
break
|
|
if (!R && istype(traitor_mob.r_hand, /obj/item/weapon/storage))
|
|
var/obj/item/weapon/storage/S = traitor_mob.r_hand
|
|
var/list/L = S.return_inv()
|
|
for (var/obj/item/device/radio/foo in L)
|
|
R = foo
|
|
loc = "in the [S.name] in your right hand"
|
|
break
|
|
if (!R && istype(traitor_mob.back, /obj/item/weapon/storage))
|
|
var/obj/item/weapon/storage/S = traitor_mob.back
|
|
var/list/L = S.return_inv()
|
|
for (var/obj/item/device/radio/foo in L)
|
|
R = foo
|
|
loc = "in the [S.name] on your back"
|
|
break
|
|
if (!R && istype(traitor_mob.l_store, /obj/item/device/pda))
|
|
R = traitor_mob.l_store
|
|
loc = "in your pocket"
|
|
if (!R && istype(traitor_mob.r_store, /obj/item/device/pda))
|
|
R = traitor_mob.r_store
|
|
loc = "in your pocket"
|
|
if (!R && traitor_mob.w_uniform && istype(traitor_mob.belt, /obj/item/device/radio))
|
|
R = traitor_mob.belt
|
|
loc = "on your belt"
|
|
if ((!R && istype(traitor_mob.ears, /obj/item/device/radio)) || prob(10))
|
|
R = traitor_mob.ears
|
|
loc = "on your head"
|
|
if (!R)
|
|
traitor_mob << "Unfortunately, the Syndicate wasn't able to get you a radio."
|
|
. = 0
|
|
else
|
|
if (istype(R, /obj/item/device/radio))
|
|
// generate list of radio freqs
|
|
var/freq = 1441
|
|
var/list/freqlist = list()
|
|
while (freq <= 1489)
|
|
if (freq < 1451 || freq > 1459)
|
|
freqlist += freq
|
|
freq += 2
|
|
if ((freq % 2) == 0)
|
|
freq += 1
|
|
freq = freqlist[rand(1, freqlist.len)]
|
|
|
|
var/obj/item/device/uplink/radio/T = new /obj/item/device/uplink/radio(R)
|
|
R:traitorradio = T
|
|
R:traitor_frequency = freq
|
|
T.name = R.name
|
|
T.icon_state = R.icon_state
|
|
T.origradio = R
|
|
traitor_mob << "The Syndicate have cunningly disguised a Syndicate Uplink as 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/pda/T = new /obj/item/device/uplink/pda(R)
|
|
R:uplink = T
|
|
T.lock_code = pda_pass
|
|
T.hostpda = R
|
|
traitor_mob << "The Syndicate have cunningly disguised a Syndicate Uplink as 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.
|
|
traitor_mob << "The Syndicate provided you with the following information on how to identify other agents:"
|
|
if(prob(80))
|
|
traitor_mob << "\red Code Phrase: \black [syndicate_code_phrase]"
|
|
traitor_mob.mind.store_memory("<b>Code Phrase</b>: [syndicate_code_phrase]")
|
|
else
|
|
traitor_mob << "Unfortunetly, the Syndicate did not provide you with a code phrase."
|
|
if(prob(80))
|
|
traitor_mob << "\red Code Response: \black [syndicate_code_response]"
|
|
traitor_mob.mind.store_memory("<b>Code Response</b>: [syndicate_code_response]")
|
|
else
|
|
traitor_mob << "Unfortunately, the Syndicate did not provide you with a code response."
|
|
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."
|
|
//End code phrase. |