/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 = "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 << "The current game mode is - Traitor!" world << "There is a syndicate traitor on the station. Do not let the traitor succeed!" /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(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 << "You are the traitor." if (!config.objectives_disabled) var/obj_count = 1 for(var/datum/objective/objective in traitor.objectives) traitor.current << "Objective #[obj_count]: [objective.explanation_text]" obj_count++ else traitor.current << "You have been selected this round as an antagonist- Within the rules, try to act as an opposing force to the crew- This can be via corporate payoff, personal motives, or maybe just being a dick. Further RP and try to make sure other players have fun! If you are confused or at a loss, always adminhelp, and before taking extreme actions, please try to also contact the administration! Think through your actions and make the roleplay immersive! Please remember all rules aside from those without explicit exceptions apply to antagonist." 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/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 << "Your laws have been changed!" killer.set_zeroth_law(law, law_borg) 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("Code Phrase: [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("Code Response: [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() if(traitors.len) var/text = "The traitors were:" for(var/datum/mind/traitor in traitors) var/traitorwin = 1 text += "
[traitor.key] was [traitor.name] (" if(traitor.current) if(traitor.current.stat == DEAD) text += "died" else text += "survived" if(traitor.current.real_name != traitor.name) text += " as [traitor.current.real_name]" else text += "body destroyed" text += ")" 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 += "
Objective #[count]: [objective.explanation_text] Success!" feedback_add_details("traitor_objective","[objective.type]|SUCCESS") else text += "
Objective #[count]: [objective.explanation_text] Fail." 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 += "
The [special_role_text] was successful!" feedback_add_details("traitor_success","SUCCESS") else text += "
The [special_role_text] has failed!" feedback_add_details("traitor_success","FAIL") 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 > 1459) 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) 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("Radio Freq: [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) 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("Uplink Passcode: [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("Code Phrase: [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("Code Response: [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. // 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("Potential Collaborator: [M.real_name]")