diff --git a/code/__DEFINES.dm b/code/__DEFINES.dm
index 00ad7c3e2c..3a8647ff2b 100644
--- a/code/__DEFINES.dm
+++ b/code/__DEFINES.dm
@@ -419,9 +419,11 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define BE_CULTIST 256
#define BE_MONKEY 512
#define BE_NINJA 1024
+#define BE_CLONE 2048
var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR,
+ "Clone" = BE_CLONE,
"Operative" = BE_OPERATIVE,
"Changeling" = BE_CHANGELING,
"Wizard" = BE_WIZARD,
diff --git a/code/game/gamemodes/clone/clone.dm b/code/game/gamemodes/clone/clone.dm
new file mode 100644
index 0000000000..80cd0a4b3a
--- /dev/null
+++ b/code/game/gamemodes/clone/clone.dm
@@ -0,0 +1,252 @@
+/datum/game_mode
+ // this includes admin-appointed clones and multiclones. Easy!
+ var/list/datum/mind/clones = list()
+
+/datum/game_mode/clone
+ name = "clone"
+ config_tag = "clone"
+ restricted_jobs = list("Cyborg")//They are part of the AI if he is clone so are they, they use to get double chances
+ protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "AI")
+ 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/clones_possible = 4 //hard limit on clones if scaling is turned off
+ var/const/clone_scaling_coeff = 5.0 //how much does the amount of players get divided by to determine clones
+
+
+/datum/game_mode/clone/announce()
+ world << "The current game mode is - Clone!"
+ world << "The Syndicate stole the cloning records of all the crew! If anyone dies, they will respawn as a random antagonist! Space Wizards, Changelings, Nuclear Operatives, oh my!"
+
+
+/datum/game_mode/clone/pre_setup()
+
+ if(config.protect_roles_from_antagonist)
+ restricted_jobs += protected_jobs
+
+ var/list/possible_clones = get_players_for_role(BE_TRAITOR)
+
+ // stop setup if no possible clones
+ if(!possible_clones.len)
+ return 0
+
+ var/num_clones = 1
+
+ if(config.traitor_scaling)
+ num_clones = max(1, round((num_players())/(clone_scaling_coeff)))
+ else
+ num_clones = max(1, min(num_players(), clones_possible))
+
+ for(var/datum/mind/player in possible_clones)
+ for(var/job in restricted_jobs)
+ if(player.assigned_role == job)
+ possible_clones -= player
+
+ for(var/j = 0, j < num_clones, j++)
+ if (!possible_clones.len)
+ break
+ var/datum/mind/clone = pick(possible_clones)
+ clones += clone
+ clone.special_role = "traitor"
+ possible_clones.Remove(clone)
+
+ if(!clones.len)
+ return 0
+ return 1
+
+
+/datum/game_mode/clone/post_setup()
+ for(var/datum/mind/clone in clones)
+ forge_clone_objectives(clone)
+ spawn(rand(10,100))
+ finalize_clone(clone)
+ greet_clone(clone)
+ modePlayer += clones
+ spawn (rand(waittime_l, waittime_h))
+ send_intercept()
+ ..()
+ return 1
+
+/datum/game_mode/clone/process()
+ var/clonespawnantag = 0
+ clonespawnantag=rand(1,4)
+ switch(clonespawnantag)
+ if(1)
+ makeCWizard()
+ if(2)
+ makeCTratiors()
+ if(3)
+ makeCRevs()
+ else makeCChanglings()
+
+/datum/game_mode/proc/forge_clone_objectives(var/datum/mind/clone)
+ if(istype(clone.current, /mob/living/silicon))
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = clone
+ kill_objective.find_target()
+ clone.objectives += kill_objective
+
+ var/datum/objective/survive/survive_objective = new
+ survive_objective.owner = clone
+ clone.objectives += survive_objective
+
+ if(prob(10))
+ var/datum/objective/block/block_objective = new
+ block_objective.owner = clone
+ clone.objectives += block_objective
+
+ else
+ switch(rand(1,100))
+ if(1 to 50)
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = clone
+ kill_objective.find_target()
+ clone.objectives += kill_objective
+ else
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = clone
+ steal_objective.find_target()
+ clone.objectives += steal_objective
+ return
+
+
+/datum/game_mode/proc/greet_clone(var/datum/mind/clone)
+ clone.current << "You are the traitor."
+ var/obj_count = 1
+ for(var/datum/objective/objective in clone.objectives)
+ clone.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ return
+
+
+/datum/game_mode/proc/finalize_clone(var/datum/mind/clone)
+ if (istype(clone.current, /mob/living/silicon))
+ add_law_zero(clone.current)
+ else
+ equip_clone(clone.current)
+ return
+
+
+/datum/game_mode/clone/declare_completion()
+ ..()
+ return//clones will be checked as part of check_extra_completion. Leaving this here as a reminder.
+
+
+/datum/game_mode/proc/auto_declare_completion_clone()
+ if(clones.len)
+ var/text = "The ORIGINAL traitors were:"
+ for(var/datum/mind/clone in clones)
+ var/clonewin = 1
+
+ text += "
[clone.key] was [clone.name] ("
+ if(clone.current)
+ if(clone.current.stat == DEAD)
+ text += "died"
+ else
+ text += "survived"
+ if(clone.current.real_name != clone.name)
+ text += " as [clone.current.real_name]"
+ else
+ text += "body destroyed"
+ text += ")"
+
+ if(clone.objectives.len)//If the clone had no objectives, don't need to process this.
+ var/count = 1
+ for(var/datum/objective/objective in clone.objectives)
+ if(objective.check_completion())
+ text += "
Objective #[count]: [objective.explanation_text] Success!"
+ feedback_add_details("clone_objective","[objective.type]|SUCCESS")
+ else
+ text += "
Objective #[count]: [objective.explanation_text] Fail."
+ feedback_add_details("clone_objective","[objective.type]|FAIL")
+ clonewin = 0
+ count++
+
+ var/special_role_text
+ if(clone.special_role)
+ special_role_text = lowertext(clone.special_role)
+ else
+ special_role_text = "antagonist"
+
+ if(clonewin)
+ text += "
The [special_role_text] was successful!"
+ feedback_add_details("clone_success","SUCCESS")
+ else
+ text += "
The [special_role_text] has failed!"
+ feedback_add_details("clone_success","FAIL")
+
+ world << text
+ return 1
+
+
+/datum/game_mode/proc/equip_clone(mob/living/carbon/human/clone_mob, var/safety = 0)
+ if (!istype(clone_mob))
+ return
+ . = 1
+ if (clone_mob.mind)
+ if (clone_mob.mind.assigned_role == "Clown")
+ clone_mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
+ clone_mob.mutations.Remove(CLUMSY)
+
+ // find a radio! toolbox(es), backpack, belt, headset
+ var/loc = ""
+ var/obj/item/R = locate(/obj/item/device/pda) in clone_mob.contents //Hide the uplink in a PDA if available, otherwise radio
+ if(!R)
+ R = locate(/obj/item/device/radio) in clone_mob.contents
+
+ if (!R)
+ clone_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/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
+ clone_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."
+ clone_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
+
+ clone_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."
+ clone_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.
+ clone_mob << "The Syndicate provided you with the following information on how to identify other agents:"
+ if(prob(80))
+ clone_mob << "\red Code Phrase: \black [syndicate_code_phrase]"
+ clone_mob.mind.store_memory("Code Phrase: [syndicate_code_phrase]")
+ else
+ clone_mob << "Unfortunetly, the Syndicate did not provide you with a code phrase."
+ if(prob(80))
+ clone_mob << "\red Code Response: \black [syndicate_code_response]"
+ clone_mob.mind.store_memory("Code Response: [syndicate_code_response]")
+ else
+ clone_mob << "Unfortunately, the Syndicate did not provide you with a code response."
+ clone_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.
\ No newline at end of file
diff --git a/code/game/gamemodes/clone/procsclone.dm b/code/game/gamemodes/clone/procsclone.dm
new file mode 100644
index 0000000000..186f19879c
--- /dev/null
+++ b/code/game/gamemodes/clone/procsclone.dm
@@ -0,0 +1,400 @@
+var/is_gettingdatfukkendiskwithmagic = 0
+/datum/game_mode/proc/makeMalfAImode()
+
+ var/list/mob/living/silicon/AIs = list()
+ var/mob/living/silicon/malfAI = null
+ var/datum/mind/themind = null
+
+ for(var/mob/living/silicon/ai/ai in player_list)
+ if(ai.client)
+ AIs += ai
+
+ if(AIs.len)
+ malfAI = pick(AIs)
+
+ if(malfAI)
+ themind = malfAI.mind
+ themind.make_AI_Malf()
+ return 1
+
+ return 0
+
+
+/datum/game_mode/proc/makeCTratiors()
+ var/list/mob/dead/observer/candidates = list()
+ var/mob/dead/observer/theghost = null
+ var/time_passed = world.time
+
+ for(var/mob/dead/observer/G in player_list)
+ if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
+ spawn(0)
+ switch(alert(G, "Your random role is: Traitor","Please answer in 30 seconds!","Become Traitor"))
+ if("Become Traitor")
+ if((world.time-time_passed)>300)//If more than 30 game seconds passed.
+ return
+ candidates += G
+
+ sleep(50)
+
+ if(candidates.len)
+ shuffle(candidates)
+ for(var/mob/i in candidates)
+ if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
+
+ theghost = i
+ break
+
+ if(theghost)
+ var/mob/living/carbon/human/new_character=makeBody(theghost)
+ new_character.mind.make_Tratior()
+ return 1
+
+ return 0
+
+
+/datum/game_mode/proc/makeCChanglings()
+
+ var/list/mob/dead/observer/candidates = list()
+ var/mob/dead/observer/theghost = null
+ var/time_passed = world.time
+
+ for(var/mob/dead/observer/G in player_list)
+ if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
+ spawn(0)
+ switch(alert(G, "Your random role is: Changling","Random Role", "Become Changling"))
+ if("Become Changling")
+ if((world.time-time_passed)>300)//If more than 30 game seconds passed.
+ return
+ candidates += G
+ sleep(50)
+
+ if(candidates.len)
+ shuffle(candidates)
+ for(var/mob/i in candidates)
+ if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
+
+ theghost = i
+ break
+
+ if(theghost)
+ var/mob/living/carbon/human/new_character=makeBody(theghost)
+ new_character.mind.make_Changling()
+ return 1
+
+ return 0
+/datum/game_mode/proc/makeCRevs()
+ var/list/mob/dead/observer/candidates = list()
+ var/mob/dead/observer/theghost = null
+ var/time_passed = world.time
+
+ for(var/mob/dead/observer/G in player_list)
+ if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
+ spawn(0)
+ switch(alert(G, "Your random role is: Head Revolutionary.","Random Role","Become Head Revolutionary"))
+ if("Become Head Revolutionary")
+ if((world.time-time_passed)>300)//If more than 30 game seconds passed.
+ return
+ candidates += G
+
+ sleep(50)
+
+ if(candidates.len)
+ shuffle(candidates)
+ for(var/mob/i in candidates)
+ if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
+
+ theghost = i
+ break
+
+ if(theghost)
+ var/mob/living/carbon/human/new_character=makeBody(theghost)
+ new_character.mind.make_Rev()
+ return 1
+
+ return 0
+
+/datum/game_mode/proc/makeCWizard()
+ var/list/mob/dead/observer/candidates = list()
+ var/mob/dead/observer/theghost = null
+ var/time_passed = world.time
+
+ for(var/mob/dead/observer/G in player_list)
+ if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
+ spawn(0)
+ switch(alert(G, "Your random role is: Space Wizard.","Please answer in 30 seconds!","Become Space Wizard"))
+ if("Become Space Wizard")
+ is_gettingdatfukkendiskwithmagic = 1
+ if((world.time-time_passed)>300)//If more than 30 game seconds passed.
+ return
+ candidates += G
+
+ sleep(50)
+
+ if(candidates.len)
+ shuffle(candidates)
+ for(var/mob/i in candidates)
+ if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
+
+ theghost = i
+ break
+
+ if(theghost)
+ var/mob/living/carbon/human/new_character=makeBody(theghost)
+ new_character.mind.make_Wizard()
+ return 1
+
+ return 0
+
+
+/datum/game_mode/proc/makeCCult()
+ var/list/mob/dead/observer/candidates = list()
+ var/mob/dead/observer/theghost = null
+ var/time_passed = world.time
+
+ for(var/mob/dead/observer/G in player_list)
+ if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
+ spawn(0)
+ switch(alert(G, "Your random role is: Cultist.","Random Role","Become Cultist"))
+ if("Become Head Revolutionary")
+ if((world.time-time_passed)>300)//If more than 30 game seconds passed.
+ return
+ candidates += G
+
+ sleep(50)
+
+ if(candidates.len)
+ shuffle(candidates)
+ for(var/mob/i in candidates)
+ if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
+
+ theghost = i
+ break
+
+ if(theghost)
+ var/mob/living/carbon/human/new_character=makeBody(theghost)
+ new_character.mind.make_Cultist()
+ return 1
+
+ return 0
+
+
+
+
+/datum/game_mode/proc/makeCNukeTeam()
+
+ var/list/mob/dead/observer/candidates = list()
+ var/mob/dead/observer/theghost = null
+ var/time_passed = world.time
+
+ for(var/mob/dead/observer/G in player_list)
+ if(!jobban_isbanned(G, "operative") && !jobban_isbanned(G, "Syndicate"))
+ spawn(0)
+ switch(alert(G,"Your random role is: Nuclear Operative","Please answer in 30 seconds!","Become Nuke Operative"))
+ if("Yes")
+ is_gettingdatfukkendiskwithmagic = 1
+ if((world.time-time_passed)>300)//If more than 30 game seconds passed.
+ return
+ candidates += G
+ else
+ return
+
+ sleep(50)
+
+ if(candidates.len)
+ var/numagents = 5
+ var/agentcount = 0
+
+ for(var/i = 0, i300)//If more than 30 game seconds passed.
+ return
+ candidates += G
+ if("No")
+ return
+ else
+ return
+ sleep(300)
+
+ for(var/mob/dead/observer/G in candidates)
+ if(!G.key)
+ candidates.Remove(G)
+
+ if(candidates.len)
+ var/numagents = 6
+ //Spawns commandos and equips them.
+ for (var/obj/effect/landmark/L in /area/syndicate_mothership/elite_squad)
+ if(numagents<=0)
+ break
+ if (L.name == "Syndicate-Commando")
+ syndicate_leader_selected = numagents == 1?1:0
+
+ var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, syndicate_leader_selected)
+
+
+ while((!theghost || !theghost.client) && candidates.len)
+ theghost = pick(candidates)
+ candidates.Remove(theghost)
+
+ if(!theghost)
+ del(new_syndicate_commando)
+ break
+
+ new_syndicate_commando.key = theghost.key
+ new_syndicate_commando.internal = new_syndicate_commando.s_store
+ new_syndicate_commando.internals.icon_state = "internal1"
+
+ //So they don't forget their code or mission.
+
+
+ new_syndicate_commando << "\blue You are an Elite Syndicate. [!syndicate_leader_selected?"commando":"LEADER"] in the service of the Syndicate. \nYour current mission is: \red [input]"
+
+ numagents--
+ if(numagents >= 6)
+ return 0
+
+ for (var/obj/effect/landmark/L in /area/shuttle/syndicate_elite)
+ if (L.name == "Syndicate-Commando-Bomb")
+ new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
+
+ return 1
+*/
+
+/datum/game_mode/proc/makeBody(var/mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
+ if(!G_found || !G_found.key) return
+
+ //First we spawn a dude.
+ var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
+
+ new_character.gender = pick(MALE,FEMALE)
+
+ var/datum/preferences/A = new()
+ A.copy_to(new_character)
+
+ new_character.dna.ready_dna(new_character)
+ new_character.key = G_found.key
+ // Here it determins if you are getting dat fukken disk or if you're a wizard, harry, so it can NOT replace essential items with the assigning a job.
+ if(is_gettingdatfukkendiskwithmagic == 1)
+ is_gettingdatfukkendiskwithmagic = 0
+ return new_character
+ else
+ job_master.GiveRandomJob(new_character)
+ job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)
+ return new_character
+/* DEATH SQUADS
+/datum/game_mode/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0)
+ var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc)
+ var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major")
+ var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major")
+ var/syndicate_commando_name = pick(last_names)
+
+ new_syndicate_commando.gender = pick(MALE, FEMALE)
+
+ var/datum/preferences/A = new()//Randomize appearance for the commando.
+ A.randomize_appearance_for(new_syndicate_commando)
+
+ new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]"
+ new_syndicate_commando.name = new_syndicate_commando.real_name
+ new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45)
+
+ new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA.
+
+ //Creates mind stuff.
+ new_syndicate_commando.mind_initialize()
+ new_syndicate_commando.mind.assigned_role = "MODE"
+ new_syndicate_commando.mind.special_role = "Syndicate Commando"
+
+ //Adds them to current traitor list. Which is really the extra antagonist list.
+ ticker.mode.traitors += new_syndicate_commando.mind
+ new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected)
+
+ return new_syndicate_commando
+ */
\ No newline at end of file
diff --git a/code/game/gamemodes/crystal/crystal.dm b/code/game/gamemodes/crystal/crystal.dm
new file mode 100644
index 0000000000..3853b4028e
--- /dev/null
+++ b/code/game/gamemodes/crystal/crystal.dm
@@ -0,0 +1,134 @@
+/datum/game_mode
+ var/list/datum/mind/crystal_holders = list()
+
+/datum/game_mode/crystal
+ name = "crystal"
+ config_tag = "crystal"
+ restricted_jobs = list("Cyborg", "AI", "Captain", "Head of Personnel", "Chief Medical Officer", "Research Director", "Chief Engineer", "Head of Security")
+ protected_jobs = list("Security Officer", "Warden", "Detective")
+ required_players = 12
+ required_enemies = 3
+ recommended_enemies = 3
+
+ 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)
+
+/datum/game_mode/crystal/announce()
+ world << "The current game mode is - Crystal!"
+ world << "There are crystal zealots trying to bring a powerful alien crystal to centcom. Stop them at all costs!"
+
+/datum/game_mode/crystal/pre_setup()
+
+ if(config.protect_roles_from_antagonist)
+ restricted_jobs += protected_jobs
+
+ var/list/possible_zealots = get_players_for_role(BE_TRAITOR) // will make a new role type if this mode becomes a serious candidate for being a new mode type
+ if(!possible_zealots.len)
+ return 0
+
+ for(var/i = 0; i < required_enemies; i++)
+ if(!possible_zealots.len)
+ break
+ var/datum/mind/zealot = pick(possible_zealots)
+ crystal_holders += zealot
+ zealot.special_role = "crystal zealot"
+ possible_zealots -= zealot
+
+ if(crystal_holders.len < required_enemies)
+ return 0
+ return 1
+
+/datum/game_mode/crystal/post_setup()
+ for(var/datum/mind/zealot in crystal_holders)
+ spawn(rand(10,100))
+ equip_and_greet_zealots(zealot)
+ modePlayer += traitors
+ spawn (rand(waittime_l, waittime_h))
+ send_intercept()
+ ..()
+ return 1
+
+/datum/game_mode/crystal/proc/assign_objectives(var/datum/mind/zealot)
+ var/datum/objective/crystal_steal/crystal_obj = new
+ crystal_obj.owner = zealot
+ crystal_obj.find_target()
+ zealot.objectives += crystal_obj
+
+ zealot.current << "You are the zealot."
+ var/obj_count = 1
+ for(var/datum/objective/objective in zealot.objectives)
+ zealot.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ zealot.current << "\nYou are tasked with smuggling the required number of crystals onto Central Command from their Escape Shuttle."
+ zealot.current << "If you do not have enough crystals you can steal some from other zealots who have the same task."
+ zealot.current << "Your crystal glows when other crystals are near, examine it to see how close you are. You can touch your crystal to activate it's alien power."
+ zealot.current << "All crystals have different powers which you can use to help complete your objective, make sure you aren't seen with it however."
+
+/datum/game_mode/crystal/proc/equip_and_greet_zealots(var/datum/mind/zealot)
+
+ if(crystal_types.len)
+ if(zealot && ishuman(zealot.current))
+
+ var/crystal_type = pick_n_take(crystal_types)
+ var/mob/living/carbon/human/H = zealot.current
+
+ var/obj/item/crystal/C = new crystal_type(null)
+
+ var/obj/item/weapon/storage/backpack/B = locate() in H
+
+ if(B && B.storage_slots > B.contents.len)
+ C.loc = B
+ else
+ C.loc = H
+ H.put_in_hands(C)
+
+ assign_objectives(zealot)
+
+ return
+
+
+/datum/game_mode/proc/auto_declare_completion_crystal()
+ if(crystal_holders.len)
+ var/text = "The zealots were:"
+ for(var/datum/mind/zealot in crystal_holders)
+ var/zealotwin = 1
+
+ text += "
[zealot.key] was [zealot.name] ("
+ if(zealot.current)
+ if(zealot.current.stat == DEAD)
+ text += "died"
+ else
+ text += "survived"
+ if(zealot.current.real_name != zealot.name)
+ text += " as [zealot.current.real_name]"
+ else
+ text += "body destroyed"
+ text += ")"
+
+ if(zealot.objectives.len)//If the zealot had no objectives, don't need to process this.
+ var/count = 1
+ for(var/datum/objective/objective in zealot.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")
+ zealotwin = 0
+ count++
+
+ var/special_role_text
+ if(zealot.special_role)
+ special_role_text = lowertext(zealot.special_role)
+ else
+ special_role_text = "antagonist"
+
+ if(zealotwin)
+ 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
\ No newline at end of file
diff --git a/code/game/gamemodes/crystal/crystal_objective.dm b/code/game/gamemodes/crystal/crystal_objective.dm
new file mode 100644
index 0000000000..3faf46cf10
--- /dev/null
+++ b/code/game/gamemodes/crystal/crystal_objective.dm
@@ -0,0 +1,32 @@
+
+// Objectives for the crystal mode.
+
+/datum/objective/crystal_steal
+
+ var/steal_amount = 2
+
+ find_target()
+ explanation_text = "Smuggle aboard [steal_amount] alien crystals to Central Command via the Escape Shuttle. There are other zealots with their own crystals, steal theirs to get more crystals."
+
+ check_completion()
+ if(!owner.current) return 0
+ if(!isliving(owner.current)) return 0
+ var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
+
+ var/crystals = 0
+
+ var/turf/location = get_turf(owner.current.loc)
+ if(!location)
+ return 0
+
+ if(istype(location, /turf/simulated/shuttle/floor4))
+ return 0
+
+ var/area/check_area = location.loc
+ if(istype(check_area, /area/shuttle/escape/centcom))
+ for(var/obj/I in all_items) //Check for items
+ if(istype(I, /obj/item/crystal))
+ crystals += 1
+ if(crystals >= steal_amount)
+ return 1
+ return 0
\ No newline at end of file
diff --git a/code/game/gamemodes/crystal/the_crystal.dm b/code/game/gamemodes/crystal/the_crystal.dm
new file mode 100644
index 0000000000..0a6084f204
--- /dev/null
+++ b/code/game/gamemodes/crystal/the_crystal.dm
@@ -0,0 +1,108 @@
+var/list/crystals = list()
+var/list/crystal_types = typesof(/obj/item/crystal) - /obj/item/crystal
+
+var/const/CRYSTAL_POWER_EMP = 1
+var/const/CRYSTAL_POWER_FIRE = 2
+var/const/CRYSTAL_POWER_HEAL = 4
+
+/obj/item/crystal
+ name = "crystal"
+ desc = "A giant mystical alien crystal. The power inside can be activated with a touch."
+ w_class = 3
+ icon = 'icons/obj/crystal.dmi'
+
+ var/powers = 0
+ var/cooldown = 0
+ var/cooldown_timer = 300
+
+/obj/item/crystal/New()
+ ..()
+ crystals += src
+
+/obj/item/crystal/Del()
+ crystals -= src
+ ..()
+
+/obj/item/crystal/attack_self(var/mob/living/L)
+ ..()
+
+ if(cooldown)
+ L << "The crystal is recharging..."
+ return
+
+ L.visible_message("[L] activates the [src]!")
+
+ if(powers & CRYSTAL_POWER_EMP)
+ empulse(src, 4, 10)
+
+ if(powers & CRYSTAL_POWER_FIRE)
+ for(var/mob/living/M in oview(7, L))
+ M.adjustFireLoss(rand(25, 40))
+ M << "You feel your insides burning!"
+
+ if(powers & CRYSTAL_POWER_HEAL)
+ for(var/mob/living/M in view(7, L))
+ var/heal = rand(15, 30)
+ M.adjustFireLoss(-heal)
+ M.adjustToxLoss(-heal)
+ M.adjustBruteLoss(-heal)
+ M.adjustCloneLoss(-heal)
+ M << "You suddenly feel better."
+
+ playsound(loc, 'sound/weapons/emitter.ogg', 50, 1)
+
+ cooldown = 1
+ spawn(cooldown_timer)
+ cooldown = 0
+
+// Strong glows depending on how close other crystals are.
+/obj/item/crystal/examine()
+
+ ..()
+ var/dist = 255
+ var/message = "The crystal isn't glowing at all."
+
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
+
+ for(var/obj/item/crystal/C in crystals)
+ if(C == src)
+ continue
+ var/turf/crystal_turf = get_turf(C)
+ if(!crystal_turf)
+ continue
+
+ dist = min(get_dist(T, crystal_turf), dist)
+
+ switch(dist)
+ if(0 to 1)
+ message = "The crystal is glowing very strongly!"
+ if(2 to 5)
+ message = "The crystal is glowing quite strongly."
+ if(6 to 10)
+ message = "The crystal is glowing."
+ if(11 to 25)
+ message = "The crystal is glowing a little."
+ if(26 to 40)
+ message = "The crystal is barely glowing."
+
+ usr << message
+
+
+// TYPES OF CRYSTALS
+
+/obj/item/crystal/red
+ name = "red crystal"
+ powers = CRYSTAL_POWER_FIRE
+ icon_state = "crystal_red"
+
+/obj/item/crystal/blue
+ name = "blue crystal"
+ powers = CRYSTAL_POWER_EMP
+ icon_state = "crystal_blue"
+
+/obj/item/crystal/green
+ name = "green crystal"
+ powers = CRYSTAL_POWER_HEAL
+ icon_state = "crystal_green"
\ No newline at end of file
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 18452b0952..a3480f8e0d 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -163,7 +163,7 @@
intercepttext += " Cent. Com has recently been contacted by the following syndicate affiliated organisations in your area, please investigate any information you may have:"
var/list/possible_modes = list()
- possible_modes.Add("revolution", "wizard", "nuke", "traitor", "malf", "changeling", "cult")
+ possible_modes.Add("revolution", "wizard", "nuke", "traitor", "malf", "changeling", "cult", "clone")
possible_modes -= "[ticker.mode]"
var/number = pick(2, 3)
var/i = 0
@@ -213,6 +213,7 @@
if(BE_WIZARD) roletext="wizard"
if(BE_REV) roletext="revolutionary"
if(BE_CULTIST) roletext="cultist"
+ if(BE_CLONE) roletext="clone"
// Ultimate randomizing code right here
diff --git a/code/game/gamemodes/hotline/hotline.dm b/code/game/gamemodes/hotline/hotline.dm
new file mode 100644
index 0000000000..d34f3bae2c
--- /dev/null
+++ b/code/game/gamemodes/hotline/hotline.dm
@@ -0,0 +1,298 @@
+var/global/list/animal_masks = list(/obj/item/clothing/mask/horsehead, \
+ /obj/item/clothing/mask/pig, \
+ /obj/item/clothing/mask/monkeymask, \
+ /obj/item/clothing/mask/owl_mask)
+
+#define GREETING "Hello, mother."
+
+/datum/game_mode/hotline
+ name = "Hotline"
+ config_tag = "hotline"
+ required_players = 0
+ var/datum/sadistic_objective/sadObj = null
+ var/objectives_completed = 0
+ var/list/sadistic_objectives = list()
+
+
+/datum/game_mode/hotline/announce()
+ world << "The current game mode is - Hotline!"
+ world << "The singularity is upon us: an AI at Centcomm has achieved superintelligence. Follow it's sadistic instructions and maybe there is some hope of survival."
+
+
+/datum/game_mode/hotline/post_setup()
+ ..()
+ //objectives!
+ for(var/path in typesof(/datum/sadistic_objective))
+ if(path == /datum/sadistic_objective)
+ continue
+ var/datum/sadistic_objective/S = new path()
+ sadistic_objectives += S
+
+ //masks!
+ for(var/mob/living/carbon/human/player in player_list)
+ var/mask = pick(animal_masks)
+ var/obj/item/clothing/a_mask = new mask(player)
+ a_mask.canremove = 0
+ if(player.wear_mask)
+ player.wear_mask.loc = null
+ player.wear_mask = null
+ player.equip_to_slot_or_del(a_mask, slot_wear_mask)
+
+ //hallucinations!
+ player.hallucination += rand(30, 50)
+
+ //blood!
+ for(var/turf/simulated/floor/F in world)
+ if(prob(96))
+ continue
+
+ new /obj/effect/decal/cleanable/blood(F)
+
+ //lights!
+ var/list/epicentreList = list()
+ for(var/obj/machinery/power/apc/A in world)
+ if(A.z == 1)
+ epicentreList += A
+
+ if(!epicentreList.len)
+ return
+
+ for(var/i = 1, i <= 16, i++)
+ var/obj/machinery/power/apc/A = pick(epicentreList)
+ A.overload_lighting()
+ epicentreList -= A
+
+ //cloner!
+ for(var/obj/machinery/clonepod/C in world)
+ C.loc.ex_act(3)
+ C.loc.ex_act(3)
+ del(C)
+
+
+/datum/game_mode/hotline/declare_completion()
+ ..()
+ world << "The despair squid successfully destroyed the station!"
+ return 1
+
+
+/datum/game_mode/hotline/process()
+ if(!sadObj)
+ sadObj = pick(sort_objective_level(objectives_completed))
+ sadObj.Announce()
+ if(sadObj.CheckCompletion())
+ sadObj = null
+ objectives_completed++
+
+
+/datum/game_mode/hotline/proc/sort_objective_level(ideallevel = 0)
+ var/list/matching_objectives = list()
+ for(var/datum/sadistic_objective/objective in sadistic_objectives)
+ if(objective.level == ideallevel)
+ matching_objectives += objective
+
+ return matching_objectives
+
+
+/datum/sadistic_objective
+ var/level = 0
+ var/alert = "I appear to be malfunctioning. You should never see this."
+ var/mob/target = 0
+
+/datum/sadistic_objective/proc/CheckCompletion()
+ return 0
+
+/datum/sadistic_objective/proc/Announce()
+ var/Ualert = alert
+
+ if(target)
+ var/list/living_players = living_mob_list
+ living_players &= player_list
+ target = pick(living_players)
+ Ualert = replacetextEx(Ualert, "%target%", "[target]")
+ Ualert = replacetextEx(Ualert, "%He%", (target.gender == "male" ? "He" : "She"))
+ Ualert = replacetextEx(Ualert, "%His%", (target.gender == "male" ? "His" : "Her"))
+ Ualert = replacetextEx(Ualert, "%Him%", (target.gender == "male" ? "Him" : "Her"))
+ Ualert = replacetextEx(Ualert, "%he%", (target.gender == "male" ? "he" : "she"))
+ Ualert = replacetextEx(Ualert, "%his%", (target.gender == "male" ? "his" : "her"))
+ Ualert = replacetextEx(Ualert, "%him%", (target.gender == "male" ? "him" : "her"))
+
+ command_alert("[GREETING] [Ualert]")
+
+
+/datum/sadistic_objective/ian
+ level = 0
+ alert = "Kill Ian."
+
+/datum/sadistic_objective/ian/CheckCompletion()
+ if(!target)
+ target = locate(/mob/living/simple_animal/corgi/Ian) in world
+ if(target.stat == DEAD)
+ return 1
+ return 0
+
+
+/datum/sadistic_objective/runtime
+ level = 0
+ alert = "Kill Runtime."
+
+/datum/sadistic_objective/runtime/CheckCompletion()
+ if(!target)
+ target = locate(/mob/living/simple_animal/cat/Runtime) in world
+ if(target.stat == DEAD)
+ return 1
+ return 0
+
+
+/datum/sadistic_objective/monkeys
+ level = 1
+ alert = "Gas at least three monkeys."
+ var/list/targets = null
+
+/datum/sadistic_objective/monkeys/CheckCompletion()
+ if(!targets)
+ targets = list()
+ for(var/mob/living/carbon/monkey/M in living_mob_list)
+ targets += M
+ if(targets)
+ var/count = 0
+ for(var/mob/living/carbon/monkey/M in targets)
+ if(M.stat)
+ if(M.oxyloss > 50 || M.toxloss > 50) //magic numbers!
+ if(!istype(M.loc, /turf/space))
+ count++
+ if(count >= 3)
+ return 1
+
+ return 0
+
+
+/datum/sadistic_objective/burn
+ level = 1
+ alert = "Burn %target%'s arms and legs. %He% may survive."
+ target = 1
+
+/datum/sadistic_objective/burn/CheckCompletion()
+ if(!target)
+ var/list/living_players = living_mob_list
+ living_players &= player_list
+ target = pick(living_players)
+ command_alert("[GREETING] Do it to [target] instead.")
+ if(target)
+ var/mob/living/carbon/human/H = target
+ var/count = 0
+ for(var/datum/limb/O in H.organs)
+ if(istype(O, /datum/limb/r_arm) || istype(O, /datum/limb/l_arm) || istype(O, /datum/limb/r_leg) || istype(O, /datum/limb/l_leg))
+ if(O.burn_dam)
+ count++
+ if(count >= 4)
+ return 1
+
+ return 0
+
+
+/datum/sadistic_objective/stab
+ level = 2
+ alert = "Put out %target%'s eyes."
+ target = 1
+
+/datum/sadistic_objective/stab/CheckCompletion()
+ if(!target)
+ var/list/living_players = living_mob_list
+ living_players &= player_list
+ target = pick(living_players)
+ command_alert("[GREETING] Do it to [target] instead.")
+ if(target)
+ var/mob/living/carbon/human/H = target
+ if(H.blinded)
+ return 1
+
+ return 0
+
+
+/datum/sadistic_objective/jacket
+ level = 2
+ alert = "%target% wishes you harm. Straightjacket %him% to ensure his cooperation."
+ target = 1
+
+/datum/sadistic_objective/jacket/CheckCompletion()
+ if(!target)
+ var/list/living_players = living_mob_list
+ living_players &= player_list
+ target = pick(living_players)
+ command_alert("[GREETING] Do it to [target] instead.")
+ if(target)
+ var/mob/living/carbon/human/H = target
+ if(istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket))
+ return 1
+
+ return 0
+
+
+/datum/sadistic_objective/gib
+ level = 3
+ alert = "Gib %target%, and then consume %his% meat."
+ target = 1
+ var/meat = 0
+ var/targetname = null
+
+/datum/sadistic_objective/gib/Announce()
+ ..()
+ var/mob/living/carbon/C = target
+ var/mask = C.wear_mask
+ C.drop_from_inventory(mask)
+ del(mask)
+
+/datum/sadistic_objective/gib/CheckCompletion()
+ if(!target)
+ var/obj/item/weapon/reagent_containers/food/snacks/meat/human/H = locate() in world
+ if(H && H.subjectname == targetname && !meat)
+ meat = 1
+ command_alert("[GREETING] Now consume the meat.")
+ else if(!H)
+ return 1
+ if(target && !targetname)
+ var/mob/living/carbon/human/H = target
+ targetname = H.real_name
+
+ return 0
+
+
+/datum/sadistic_objective/suicide
+ level = 4
+ alert = "Three humans must die."
+ var/initialhumans = 0
+
+/datum/sadistic_objective/suicide/Announce()
+ ..()
+ initialhumans = player_list.len
+
+/datum/sadistic_objective/suicide/CheckCompletion()
+ if(player_list.len <= initialhumans - 3)
+ return 1
+
+ return 0
+
+
+/datum/sadistic_objective/nuke
+ level = 5
+ alert = "Detonate the station nuke. The code is 00000."
+
+/datum/sadistic_objective/nuke/Announce()
+ ..()
+ var/obj/machinery/nuclearbomb/nuke = locate() in world
+ nuke.r_code = "00000"
+
+
+//non gas masks
+/obj/item/clothing/mask/monkeymask
+ name = "monkey mask"
+ desc = "A mask used when acting as a monkey."
+ icon_state = "monkeymask"
+ item_state = "monkeymask"
+
+/obj/item/clothing/mask/owl_mask
+ name = "owl mask"
+ desc = "Twoooo!"
+ icon_state = "owl"
+
+#undef GREETING
\ No newline at end of file
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 66de6a861b..ff908c01f6 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -270,29 +270,33 @@ datum/objective/steal
"a hand teleporter" = /obj/item/weapon/hand_tele,
"an RCD" = /obj/item/weapon/rcd,
"a jetpack" = /obj/item/weapon/tank/jetpack,
- "a captain's jumpsuit" = /obj/item/clothing/under/rank/captain,
"a functional AI" = /obj/item/device/aicard,
"a pair of magboots" = /obj/item/clothing/shoes/magboots,
"the station blueprints" = /obj/item/blueprints,
"28 moles of plasma (full tank)" = /obj/item/weapon/tank,
"an unused sample of slime extract" = /obj/item/slime_extract,
"a piece of corgi meat" = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi,
+ "the medal of captaincy" = /obj/item/clothing/tie/medal/gold/captain,
+ "the hypospray" = /obj/item/weapon/reagent_containers/hypospray,
+ "the captain's pinpointer" = /obj/item/weapon/pinpointer,
+ "an ablative armor vest" = /obj/item/clothing/suit/armor/laserproof,
+/*
+Nobody takes these seriously anyways -- Ikki
+ "a captain's jumpsuit" = /obj/item/clothing/under/rank/captain,
"a research director's jumpsuit" = /obj/item/clothing/under/rank/research_director,
"a chief engineer's jumpsuit" = /obj/item/clothing/under/rank/chief_engineer,
"a chief medical officer's jumpsuit" = /obj/item/clothing/under/rank/chief_medical_officer,
"a head of security's jumpsuit" = /obj/item/clothing/under/rank/head_of_security,
"a head of personnel's jumpsuit" = /obj/item/clothing/under/rank/head_of_personnel,
- "the hypospray" = /obj/item/weapon/reagent_containers/hypospray,
- "the captain's pinpointer" = /obj/item/weapon/pinpointer,
- "an ablative armor vest" = /obj/item/clothing/suit/armor/laserproof,
+*/
)
var/global/possible_items_special[] = list(
- // "nuclear authentication disk" = /obj/item/weapon/disk/nuclear, //Broken with the change to nuke disk making it respawn on z level change.
- "advanced energy gun" = /obj/item/weapon/gun/energy/gun/nuclear,
- "diamond drill" = /obj/item/weapon/pickaxe/diamonddrill,
- "bag of holding" = /obj/item/weapon/storage/backpack/holding,
- "hyper-capacity cell" = /obj/item/weapon/cell/hyper,
+ "the nuclear authentication disk" = /obj/item/weapon/disk/nuclear,
+ "an advanced energy gun" = /obj/item/weapon/gun/energy/gun/nuclear,
+ "a diamond drill" = /obj/item/weapon/pickaxe/diamonddrill,
+ "a bag of holding" = /obj/item/weapon/storage/backpack/holding,
+ "a hyper-capacity cell" = /obj/item/weapon/cell/hyper,
"10 diamonds" = /obj/item/stack/sheet/mineral/diamond,
"50 gold bars" = /obj/item/stack/sheet/mineral/gold,
"25 refined uranium bars" = /obj/item/stack/sheet/mineral/uranium,
diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm
new file mode 100644
index 0000000000..8c68e0eb60
--- /dev/null
+++ b/code/game/gamemodes/traitor/double_agents.dm
@@ -0,0 +1,40 @@
+/datum/game_mode/traitor/double_agents
+ name = "double agents"
+ config_tag = "double_agents"
+ restricted_jobs = list("Cyborg", "AI", "Captain", "Head of Personnel", "Chief Medical Officer", "Research Director", "Chief Engineer", "Head of Security") // Human / Minor roles only.
+ required_players = 12
+ required_enemies = 3
+ recommended_enemies = 6
+
+ traitor_name = "double agent"
+
+ var/list/target_list = list()
+
+/datum/game_mode/traitor/double_agents/announce()
+ world << "The current game mode is - Double Agents!"
+ world << "There are double agents killing eachother! Do not let them succeed!"
+
+/datum/game_mode/traitor/double_agents/post_setup()
+ var/i = 0
+ for(var/datum/mind/traitor in traitors)
+ i++
+ if(i + 1 > traitors.len)
+ i = 0
+ target_list[traitor] = traitors[i + 1]
+ ..()
+
+/datum/game_mode/traitor/double_agents/forge_traitor_objectives(var/datum/mind/traitor)
+
+ if(target_list.len > 1)
+ // Assassinate
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = traitor
+ kill_objective.target = target_list[traitor]
+ kill_objective.explanation_text = "Assassinate [kill_objective.target.current.real_name], the [kill_objective.target.special_role]."
+ traitor.objectives += kill_objective
+
+ // Escape
+ var/datum/objective/escape/escape_objective = new
+ escape_objective.owner = traitor
+ traitor.objectives += escape_objective
+ return
\ No newline at end of file
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 9e7483e96d..36520675ce 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -1,5 +1,6 @@
/datum/game_mode
// this includes admin-appointed traitors and multitraitors. Easy!
+ var/traitor_name = "traitor"
var/list/datum/mind/traitors = list()
/datum/game_mode/traitor
@@ -55,7 +56,7 @@
break
var/datum/mind/traitor = pick(possible_traitors)
traitors += traitor
- traitor.special_role = "traitor"
+ traitor.special_role = traitor_name
possible_traitors.Remove(traitor)
if(!traitors.len)
@@ -120,7 +121,7 @@
/datum/game_mode/proc/greet_traitor(var/datum/mind/traitor)
- traitor.current << "You are the traitor."
+ traitor.current << "You are the [traitor_name]."
var/obj_count = 1
for(var/datum/objective/objective in traitor.objectives)
traitor.current << "Objective #[obj_count]: [objective.explanation_text]"
@@ -166,7 +167,7 @@
/datum/game_mode/proc/auto_declare_completion_traitor()
if(traitors.len)
- var/text = "The traitors were:"
+ var/text = "The [traitor_name]s were:"
for(var/datum/mind/traitor in traitors)
var/traitorwin = 1
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index f23a048683..6cb18b9ec7 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -591,7 +591,8 @@ var/global/list/g_fancy_list_of_safe_types = null
return
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/dresspacks = list(
- "strip",
+ "naked",
+ "assistant grey",
"standard space gear",
"tournament standard red",
"tournament standard green",
@@ -605,7 +606,7 @@ var/global/list/g_fancy_list_of_safe_types = null
"masked killer",
"assassin",
"death commando",
- "syndicate commando",
+// "syndicate commando",
"centcom official",
"centcom commander",
"special ops officer",
@@ -622,8 +623,29 @@ var/global/list/g_fancy_list_of_safe_types = null
continue
del(I)
switch(dresscode)
- if ("strip")
+ if ("naked")
//do nothing
+
+ if ("assistant grey")
+ var/obj/item/weapon/storage/backpack/BPK = new/obj/item/weapon/storage/backpack(M)
+ new /obj/item/weapon/storage/box/survival(BPK)
+ M.equip_to_slot_or_del(BPK, slot_back,1)
+ M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
+ M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform)
+ M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
+
+ var/obj/item/weapon/card/id/W = new(M)
+ W.name = "[M.real_name]'s ID Card (Assistant)"
+ W.assignment = "Assistant"
+ W.registered_name = M.real_name
+ M.equip_to_slot_or_del(W, slot_wear_id)
+ var/obj/item/device/pda/P = new(M)
+ P.owner = M.real_name
+ P.ownjob = "Assistant"
+ P.name = "PDA-[M.real_name] (Assistant)"
+ M.equip_to_slot_or_del(P, slot_belt)
+
+
if ("standard space gear")
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
@@ -795,10 +817,52 @@ var/global/list/g_fancy_list_of_safe_types = null
W.assignment = "Reaper"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
-/* DEATH SQUADS
+// DEATH SQUADS
if("death commando")//Was looking to add this for a while.
- M.equip_death_commando()
+ var/obj/item/device/radio/R = new /obj/item/device/radio/headset(M)
+ R.set_frequency(1441)
+ M.equip_to_slot_or_del(R, slot_ears)
+
+ M.equip_to_slot_or_del(new /obj/item/clothing/under/color/green(M), slot_w_uniform)
+ M.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(M), slot_shoes)
+ M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/swat(M), slot_wear_suit)
+ M.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(M), slot_gloves)
+ M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(M), slot_head)
+ M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(M), slot_wear_mask)
+ M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(M), slot_glasses)
+
+ M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(M), slot_back)
+ M.equip_to_slot_or_del(new /obj/item/weapon/storage/box(M), slot_in_backpack)
+
+ M.equip_to_slot_or_del(new /obj/item/ammo_magazine/a357(M), slot_in_backpack)
+ M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(M), slot_in_backpack)
+ M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(M), slot_in_backpack)
+ M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
+
+ M.equip_to_slot_or_del(new /obj/item/weapon/plastique(M), slot_in_backpack)
+
+ M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(M), slot_l_store)
+ M.equip_to_slot_or_del(new /obj/item/weapon/grenade/flashbang(M), slot_r_store)
+ M.equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(M), slot_s_store)
+ M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(M), slot_belt)
+
+ M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(M), slot_r_hand)
+
+
+ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M)//Here you go Deuryn
+ L.imp_in = M
+ L.implanted = 1
+
+ var/obj/item/weapon/card/id/W = new(M)
+ W.name = "[M.real_name]'s ID Card"
+ W.icon_state = "centcom"
+ W.access = get_all_accesses()//They get full station access.
+ W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)//Let's add their alloted CentCom access.
+ W.assignment = "Death Commando"
+ W.registered_name = M.real_name
+ M.equip_to_slot_or_del(W, slot_wear_id)
+/*
if("syndicate commando")
M.equip_syndicate_commando()
*/
@@ -813,7 +877,7 @@ var/global/list/g_fancy_list_of_safe_types = null
var/obj/item/device/pda/heads/pda = new(M)
pda.owner = M.real_name
- pda.ownjob = "CentCom Review Official"
+ pda.ownjob = "CentCom Official"
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
M.equip_to_slot_or_del(pda, slot_r_store)
@@ -821,11 +885,11 @@ var/global/list/g_fancy_list_of_safe_types = null
M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_l_hand)
var/obj/item/weapon/card/id/W = new(M)
- W.name = "[M.real_name]'s ID Card"
+ W.name = "[M.real_name]'s ID Card (CentCom Official)"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer")
- W.assignment = "CentCom Review Official"
+ W.assignment = "CentCom Official"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
@@ -843,11 +907,11 @@ var/global/list/g_fancy_list_of_safe_types = null
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/a357(M), slot_l_store)
var/obj/item/weapon/card/id/W = new(M)
- W.name = "[M.real_name]'s ID Card"
+ W.name = "[M.real_name]'s ID Card (CentCom Commander)"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
- W.assignment = "CentCom Commanding Officer"
+ W.assignment = "CentCom Commander"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
@@ -865,11 +929,11 @@ var/global/list/g_fancy_list_of_safe_types = null
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
var/obj/item/weapon/card/id/W = new(M)
- W.name = "[M.real_name]'s ID Card"
+ W.name = "[M.real_name]'s ID Card (Special Ops Officer)"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
- W.assignment = "Special Operations Officer"
+ W.assignment = "Special Ops Officer"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
@@ -919,7 +983,7 @@ var/global/list/g_fancy_list_of_safe_types = null
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
var/obj/item/weapon/card/id/W = new(M)
- W.name = "[M.real_name]'s ID Card"
+ W.name = "[M.real_name]'s ID Card (Admiral)"
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
diff --git a/config/admins.txt b/config/admins.txt
index aa583944a8..ba59f7d7f3 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -5,7 +5,7 @@
# Ranks can be anything defined in admin_ranks.txt ~Carn #
######################################################################
-quarxink - Game Master
+iamgoofball - Game Master
tle - Game Master
xsi - Game Master
scaredofshadows - Game Master
diff --git a/data/mode.txt b/data/mode.txt
index cf1ffd5c99..cbc1a20072 100644
--- a/data/mode.txt
+++ b/data/mode.txt
@@ -1 +1 @@
-extended
\ No newline at end of file
+clone
\ No newline at end of file
diff --git a/html/changelog.html b/html/changelog.html
index 133345c8cc..e19605a54b 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,10 @@ Aranclanos updated:
- Exosuit fabritcators will now need to be manually updated
+ Ikarrus updated:
+
+ - Centcom intelligence suggests that the Syndicate no longer seeks to capture Nanotrasen officer jumpsuits. They may be targetting an item of more worth, particularly the Medal of Captaincy issued to Nanotrasen commanders.
+
diff --git a/icons/obj/crystal.dmi b/icons/obj/crystal.dmi
new file mode 100644
index 0000000000..79dfa899c3
Binary files /dev/null and b/icons/obj/crystal.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 2e5a43ecc0..fb00268fc8 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1,15 +1,51 @@
// DM Environment file for tgstation.dme.
// All manual changes should be made outside the BEGIN_ and END_ blocks.
- // New source code should be placed in .dm files: choose File/New --> Code File.
+// New source code should be placed in .dm files: choose File/New --> Code File.
+
// BEGIN_INTERNALS
// END_INTERNALS
// BEGIN_FILE_DIR
#define FILE_DIR .
+#define FILE_DIR "html"
+#define FILE_DIR "icons"
+#define FILE_DIR "icons/effects"
+#define FILE_DIR "icons/mecha"
+#define FILE_DIR "icons/misc"
+#define FILE_DIR "icons/mob"
+#define FILE_DIR "icons/obj"
+#define FILE_DIR "icons/obj/assemblies"
+#define FILE_DIR "icons/obj/atmospherics"
+#define FILE_DIR "icons/obj/clothing"
+#define FILE_DIR "icons/obj/doors"
+#define FILE_DIR "icons/obj/flora"
+#define FILE_DIR "icons/obj/machines"
+#define FILE_DIR "icons/obj/pipes"
+#define FILE_DIR "icons/obj/power_cond"
+#define FILE_DIR "icons/pda_icons"
+#define FILE_DIR "icons/spideros_icons"
+#define FILE_DIR "icons/Testing"
+#define FILE_DIR "icons/turf"
+#define FILE_DIR "icons/vending_icons"
+#define FILE_DIR "sound"
+#define FILE_DIR "sound/AI"
+#define FILE_DIR "sound/ambience"
+#define FILE_DIR "sound/effects"
+#define FILE_DIR "sound/hallucinations"
+#define FILE_DIR "sound/items"
+#define FILE_DIR "sound/machines"
+#define FILE_DIR "sound/mecha"
+#define FILE_DIR "sound/misc"
+#define FILE_DIR "sound/piano"
+#define FILE_DIR "sound/violin"
+#define FILE_DIR "sound/voice"
+#define FILE_DIR "sound/weapons"
+#define FILE_DIR "tools"
+#define FILE_DIR "tools/AddToChangelog"
+#define FILE_DIR "tools/AddToChangelog/AddToChangelog"
// END_FILE_DIR
// BEGIN_PREFERENCES
-#define DEBUG
// END_PREFERENCES
// BEGIN_INCLUDE
@@ -98,7 +134,6 @@
#include "code\datums\diseases\pierrot_throat.dm"
#include "code\datums\diseases\plasmatoid.dm"
#include "code\datums\diseases\retrovirus.dm"
-#include "code\datums\diseases\rhumba_beat.dm"
#include "code\datums\diseases\robotic_transformation.dm"
#include "code\datums\diseases\wizarditis.dm"
#include "code\datums\diseases\xeno_transformation.dm"
@@ -167,6 +202,7 @@
#include "code\defines\procs\command_alert.dm"
#include "code\defines\procs\dbcore.dm"
#include "code\defines\procs\statistics.dm"
+#include "code\FEA\DEBUG_REMOVE_BEFORE_RELEASE.dm"
#include "code\FEA\FEA_airgroup.dm"
#include "code\FEA\FEA_fire.dm"
#include "code\FEA\FEA_gas_mixture.dm"
@@ -205,6 +241,11 @@
#include "code\game\gamemodes\changeling\changeling_powers.dm"
#include "code\game\gamemodes\changeling\modularchangling.dm"
#include "code\game\gamemodes\changeling\traitor_chan.dm"
+#include "code\game\gamemodes\clone\clone.dm"
+#include "code\game\gamemodes\clone\procsclone.dm"
+#include "code\game\gamemodes\crystal\crystal.dm"
+#include "code\game\gamemodes\crystal\crystal_objective.dm"
+#include "code\game\gamemodes\crystal\the_crystal.dm"
#include "code\game\gamemodes\cult\cult.dm"
#include "code\game\gamemodes\cult\cult_items.dm"
#include "code\game\gamemodes\cult\cult_structures.dm"
@@ -212,6 +253,7 @@
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\talisman.dm"
#include "code\game\gamemodes\extended\extended.dm"
+#include "code\game\gamemodes\hotline\hotline.dm"
#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
#include "code\game\gamemodes\malfunction\malfunction.dm"
#include "code\game\gamemodes\meteor\meteor.dm"
@@ -222,6 +264,7 @@
#include "code\game\gamemodes\revolution\revolution.dm"
#include "code\game\gamemodes\sandbox\h_sandbox.dm"
#include "code\game\gamemodes\sandbox\sandbox.dm"
+#include "code\game\gamemodes\traitor\double_agents.dm"
#include "code\game\gamemodes\traitor\traitor.dm"
#include "code\game\gamemodes\wizard\artefact.dm"
#include "code\game\gamemodes\wizard\rightandwrong.dm"
@@ -376,6 +419,7 @@
#include "code\game\mecha\equipment\mecha_equipment.dm"
#include "code\game\mecha\equipment\tools\medical_tools.dm"
#include "code\game\mecha\equipment\tools\tools.dm"
+#include "code\game\mecha\equipment\tools\unused_tools.dm"
#include "code\game\mecha\equipment\weapons\weapons.dm"
#include "code\game\mecha\medical\medical.dm"
#include "code\game\mecha\medical\odysseus.dm"
@@ -440,7 +484,6 @@
#include "code\game\objects\items\devices\violin.dm"
#include "code\game\objects\items\devices\PDA\cart.dm"
#include "code\game\objects\items\devices\PDA\chatroom.dm"
-#include "code\game\objects\items\devices\PDA\PDA.dm"
#include "code\game\objects\items\devices\PDA\radio.dm"
#include "code\game\objects\items\devices\radio\beacon.dm"
#include "code\game\objects\items\devices\radio\electropack.dm"
@@ -744,6 +787,7 @@
#include "code\modules\events\spacevine.dm"
#include "code\modules\events\spider_infestation.dm"
#include "code\modules\events\spontaneous_appendicitis.dm"
+#include "code\modules\events\weightless.dm"
#include "code\modules\events\wormholes.dm"
#include "code\modules\events\holiday\xmas.dm"
#include "code\modules\flufftext\Dreaming.dm"
@@ -789,6 +833,7 @@
#include "code\modules\mob\update_icons.dm"
#include "code\modules\mob\dead\death.dm"
#include "code\modules\mob\dead\observer\hud.dm"
+#include "code\modules\mob\dead\observer\login.dm"
#include "code\modules\mob\dead\observer\logout.dm"
#include "code\modules\mob\dead\observer\observer.dm"
#include "code\modules\mob\dead\observer\say.dm"
@@ -829,6 +874,7 @@
#include "code\modules\mob\living\carbon\alien\larva\inventory.dm"
#include "code\modules\mob\living\carbon\alien\larva\larva.dm"
#include "code\modules\mob\living\carbon\alien\larva\life.dm"
+#include "code\modules\mob\living\carbon\alien\larva\login.dm"
#include "code\modules\mob\living\carbon\alien\larva\powers.dm"
#include "code\modules\mob\living\carbon\alien\larva\update_icons.dm"
#include "code\modules\mob\living\carbon\alien\special\alien_embryo.dm"
@@ -839,6 +885,7 @@
#include "code\modules\mob\living\carbon\brain\emote.dm"
#include "code\modules\mob\living\carbon\brain\hud.dm"
#include "code\modules\mob\living\carbon\brain\life.dm"
+#include "code\modules\mob\living\carbon\brain\login.dm"
#include "code\modules\mob\living\carbon\brain\MMI.dm"
#include "code\modules\mob\living\carbon\brain\say.dm"
#include "code\modules\mob\living\carbon\human\death.dm"
@@ -985,6 +1032,7 @@
#include "code\modules\power\switch.dm"
#include "code\modules\power\terminal.dm"
#include "code\modules\power\tracker.dm"
+#include "code\modules\power\turbine.dm"
#include "code\modules\power\antimatter\containment_jar.dm"
#include "code\modules\power\antimatter\control.dm"
#include "code\modules\power\antimatter\shielding.dm"
@@ -1105,14 +1153,21 @@
#include "code\modules\surgery\xenomorph_removal.dm"
#include "code\modules\surgery\organs\helpers.dm"
#include "code\modules\surgery\organs\organ.dm"
-#include "code\WorkInProgress\buildmode.dm"
-#include "code\WorkInProgress\explosion_particles.dm"
-#include "code\WorkInProgress\Sigyn\Department Sec\jobs.dm"
-#include "interface\interface.dm"
-#include "interface\skin.dmf"
+#include "maps\MetaStation v27G-II.dmm"
#include "maps\tgstation.2.1.2.dmm"
#include "maps\RandomZLevels\Academy.dm"
#include "maps\RandomZLevels\challenge.dm"
#include "maps\RandomZLevels\stationCollision.dm"
#include "maps\RandomZLevels\wildwest.dm"
+#include "maps\RandomZLevels\Academy.dmm"
+#include "maps\RandomZLevels\arcticwaste.dmm"
+#include "maps\RandomZLevels\beach.dmm"
+#include "maps\RandomZLevels\blackmarketpackers.dmm"
+#include "maps\RandomZLevels\challenge.dmm"
+#include "maps\RandomZLevels\example.dmm"
+#include "maps\RandomZLevels\listeningpost.dmm"
+#include "maps\RandomZLevels\spacebattle.dmm"
+#include "maps\RandomZLevels\stationCollision.dmm"
+#include "maps\RandomZLevels\wildwest.dmm"
// END_INCLUDE
+