another huge sync

This commit is contained in:
LetterJay
2017-06-21 18:00:00 -05:00
parent 0719541100
commit d04001c09d
51 changed files with 1443 additions and 981 deletions
+5 -5
View File
@@ -200,7 +200,7 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
to_chat(changeling.current, "<span class='boldannounce'>You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human.</span>")
to_chat(changeling.current, "<span class='boldannounce'>Use say \":g message\" to communicate with your fellow changelings.</span>")
to_chat(changeling.current, "<b>You must complete the following tasks:</b>")
changeling.current.playsound_local('sound/ambience/antag/ling_aler.ogg',100,0)
changeling.current.playsound_local(get_turf(changeling.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
if (changeling.current.mind)
var/mob/living/carbon/human/H = changeling.current
@@ -255,19 +255,19 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
for(var/datum/objective/objective in changeling.objectives)
if(objective.check_completion())
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <font color='green'><b>Success!</b></font>"
SSblackbox.add_details("changeling_objective","[objective.type]|SUCCESS")
SSblackbox.add_details("changeling_objective","[objective.type]|SUCCESS")
else
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <span class='danger'>Fail.</span>"
SSblackbox.add_details("changeling_objective","[objective.type]|FAIL")
SSblackbox.add_details("changeling_objective","[objective.type]|FAIL")
changelingwin = 0
count++
if(changelingwin)
text += "<br><font color='green'><b>The changeling was successful!</b></font>"
SSblackbox.add_details("changeling_success","SUCCESS")
SSblackbox.add_details("changeling_success","SUCCESS")
else
text += "<br><span class='boldannounce'>The changeling has failed.</span>"
SSblackbox.add_details("changeling_success","FAIL")
SSblackbox.add_details("changeling_success","FAIL")
text += "<br>"
to_chat(world, text)
+1 -1
View File
@@ -146,7 +146,7 @@ Credit where due:
Rusting eternally in the Celestial Derelict, Ratvar has formed a covenant of mortals, with you as one of its members. As one of the Justiciar's servants, you are to work to the best of your \
ability to assist in completion of His agenda. You may not know the specifics of how to do so, but luckily you have a vessel to help you learn.</b>"
to_chat(M, greeting_text)
M.playsound_local('sound/ambience/antag/ClockCultAlr.ogg',100,0)
M.playsound_local(get_turf(M), 'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, pressure_affected = FALSE)
return 1
/datum/game_mode/proc/equip_servant(mob/living/L) //Grants a clockwork slab to the mob, with one of each component
@@ -116,26 +116,29 @@
successful = TRUE
to_chat(ranged_ability_user, "<span class='brass'>You bathe [L == ranged_ability_user ? "yourself":"[L]"] in Inath-neq's power!</span>")
var/targetturf = get_turf(L)
var/has_holy_water = (L.reagents && L.reagents.has_reagent("holywater"))
var/healseverity = max(round(totaldamage*0.05, 1), 1) //shows the general severity of the damage you just healed, 1 glow per 20
for(var/i in 1 to healseverity)
new /obj/effect/temp_visual/heal(targetturf, "#1E8CE1")
if(totaldamage)
L.adjustBruteLoss(-brutedamage)
L.adjustFireLoss(-burndamage)
L.adjustOxyLoss(-oxydamage)
L.adjustToxLoss(totaldamage * 0.5, TRUE, TRUE)
var/healseverity = max(round(totaldamage*0.05, 1), 1) //shows the general severity of the damage you just healed, 1 glow per 20
for(var/i in 1 to healseverity)
new /obj/effect/temp_visual/heal(targetturf, "#1E8CE1")
clockwork_say(ranged_ability_user, text2ratvar("Mend wounded flesh!"))
clockwork_say(ranged_ability_user, text2ratvar("[has_holy_water ? "Heal tainted" : "Mend wounded"] flesh!"))
add_logs(ranged_ability_user, L, "healed with Sentinel's Compromise")
L.visible_message("<span class='warning'>A blue light washes over [L], [has_holy_water ? "causing [L.p_them()] to briefly glow as it mends" : " mending"] [L.p_their()] bruises and burns!</span>", \
"<span class='heavy_brass'>You feel Inath-neq's power healing your wounds[has_holy_water ? " and purging the darkness within you" : ""], but a deep nausea overcomes you!</span>")
else
clockwork_say(ranged_ability_user, text2ratvar("Purge foul darkness!"))
add_logs(ranged_ability_user, L, "purged of holy water with Sentinel's Compromise")
to_chat(ranged_ability_user, "<span class='brass'>You bathe [L == ranged_ability_user ? "yourself":"[L]"] in Inath-neq's power!</span>")
L.visible_message("<span class='warning'>A blue light washes over [L], mending [L.p_their()] bruises and burns!</span>", \
"<span class='heavy_brass'>You feel Inath-neq's power healing your wounds, but a deep nausea overcomes you!</span>")
L.visible_message("<span class='warning'>A blue light washes over [L], causing [L.p_them()] to briefly glow!</span>", \
"<span class='heavy_brass'>You feel Inath-neq's power purging the darkness within you!</span>")
playsound(targetturf, 'sound/magic/Staff_Healing.ogg', 50, 1)
if(L.reagents && L.reagents.has_reagent("holywater"))
if(has_holy_water)
L.reagents.remove_reagent("holywater", 1000)
to_chat(L, "<span class='heavy_brass'>Ratvar's light flares, banishing the darkness. Your devotion remains intact!</span>")
+1 -1
View File
@@ -112,7 +112,7 @@
equip_cultist(cult_mind.current)
update_cult_icons_added(cult_mind)
to_chat(cult_mind.current, "<span class='userdanger'>You are a member of the cult!</span>")
cult_mind.current.playsound_local('sound/ambience/antag/bloodcult.ogg',100,0)//subject to change
cult_mind.current.playsound_local(get_turf(cult_mind.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change
add_cultist(cult_mind, 0)
..()
@@ -10,8 +10,8 @@
num_modifier = 4
objective_count = 2
var/list/target_list = list()
var/list/late_joining_list = list()
var/list/devil_target_list = list() //will update to be a child of internal affairs when bothered
var/list/devil_late_joining_list = list()
minimum_devils = 3
announce_text = "There are devil agents onboard the station, trying to outbid each other!\n\
@@ -24,7 +24,7 @@
i++
if(i + 1 > devils.len)
i = 0
target_list[devil] = devils[i + 1]
devil_target_list[devil] = devils[i + 1]
..()
/datum/game_mode/devil/devil_agents/add_devil_objectives(datum/mind/devil_mind, quantity)
@@ -32,8 +32,8 @@
/datum/game_mode/devil/devil_agents/proc/give_outsell_objective(datum/mind/devil)
//If you override this method, have it return the number of objectives added.
if(target_list.len && target_list[devil]) // Is a double agent
var/datum/mind/target_mind = target_list[devil]
if(devil_target_list.len && devil_target_list[devil]) // Is a double agent
var/datum/mind/target_mind = devil_target_list[devil]
var/datum/objective/devil/outsell/outsellobjective = new
outsellobjective.owner = devil
outsellobjective.target = target_mind
+11 -19
View File
@@ -162,6 +162,10 @@
. = 1
sleep(rand(600,1800))
if(!SSticker.IsRoundInProgress())
message_admins("Roundtype conversion cancelled, the game appears to have finished!")
round_converted = 0
return
//somewhere between 1 and 3 minutes from now
if(!config.midround_antag[SSticker.mode.config_tag])
round_converted = 0
@@ -177,7 +181,7 @@
return 0
/datum/game_mode/proc/check_finished() //to be called by SSticker
/datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker
if(replacementmode && round_converted == 2)
return replacementmode.check_finished()
if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME))
@@ -208,7 +212,7 @@
living_antag_player = Player
return 0
if(!config.continuous[config_tag])
if(!config.continuous[config_tag] || force_ending)
return 1
else
@@ -345,7 +349,7 @@
// Ultimate randomizing code right here
for(var/mob/dead/new_player/player in GLOB.player_list)
if(player.client && player.ready)
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
players += player
// Shuffling, the players list is now ping-independent!!!
@@ -353,7 +357,7 @@
players = shuffle(players)
for(var/mob/dead/new_player/player in players)
if(player.client && player.ready)
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(role in player.client.prefs.be_special)
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans
if(age_check(player.client)) //Must be older than the minimum age
@@ -367,7 +371,7 @@
if(candidates.len < recommended_enemies)
for(var/mob/dead/new_player/player in players)
if(player.client && player.ready)
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a seperate list of people who don't want to be one
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans
drafted += player.mind
@@ -389,13 +393,7 @@
else // Not enough scrubs, ABORT ABORT ABORT
break
/*
if(candidates.len < recommended_enemies && override_jobbans) //If we still don't have enough people, we're going to start drafting banned people.
for(var/mob/dead/new_player/player in players)
if (player.client && player.ready)
if(jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans
drafted += player.mind
*/
if(restricted_jobs)
for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist
for(var/job in restricted_jobs)
@@ -418,17 +416,11 @@
// recommended_enemies if the number of people with that role set to yes is less than recomended_enemies,
// Less if there are not enough valid players in the game entirely to make recommended_enemies.
/*
/datum/game_mode/proc/check_player_role_pref(var/role, var/mob/dead/new_player/player)
if(player.preferences.be_special & role)
return 1
return 0
*/
/datum/game_mode/proc/num_players()
. = 0
for(var/mob/dead/new_player/P in GLOB.player_list)
if(P.client && P.ready)
if(P.client && P.ready == PLAYER_READY_TO_PLAY)
. ++
///////////////////////////////////
+1 -1
View File
@@ -93,7 +93,7 @@
agent_number++
spawnpos++
update_synd_icons_added(synd_mind)
synd_mind.current.playsound_local('sound/ambience/antag/ops.ogg',100,0)
synd_mind.current.playsound_local(get_turf(synd_mind.current), 'sound/ambience/antag/ops.ogg',100,0)
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
if(nuke)
+2 -2
View File
@@ -658,7 +658,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
var/n_p = 1 //autowin
if (SSticker.current_state == GAME_STATE_SETTING_UP)
for(var/mob/dead/new_player/P in GLOB.player_list)
if(P.client && P.ready && P.mind!=owner)
if(P.client && P.ready == PLAYER_READY_TO_PLAY && P.mind!=owner)
n_p ++
else if (SSticker.IsRoundInProgress())
for(var/mob/living/carbon/human/P in GLOB.player_list)
@@ -701,7 +701,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
explanation_text = "Destroy [target.name], the experimental AI."
else
explanation_text = "Free Objective"
/datum/objective/destroy/internal
var/stolen = FALSE //Have we already eliminated this target?
+54 -307
View File
@@ -1,327 +1,74 @@
#define PINPOINTER_MINIMUM_RANGE 15
#define PINPOINTER_EXTRA_RANDOM_RANGE 10
#define PINPOINTER_PING_TIME 40
#define PROB_ACTUAL_TRAITOR 20
#define TRAITOR_AGENT_ROLE "Syndicate External Affairs Agent"
/datum/game_mode
var/list/target_list = list()
var/list/late_joining_list = list()
/datum/game_mode/traitor/internal_affairs
name = "Internal Affairs"
config_tag = "internal_affairs"
employer = "Internal Affairs"
required_players = 25
required_enemies = 5
recommended_enemies = 8
reroll_friendly = 0
recommended_enemies = 8
reroll_friendly = 0
traitor_name = "Nanotrasen Internal Affairs Agent"
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4 // Four additional traitors
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4 // Four additional traitors
antag_datum = ANTAG_DATUM_IAA
announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\
<span class='danger'>IAA</span>: Eliminate your targets and protect yourself!\n\
<span class='notice'>Crew</span>: Stop the IAA agents before they can cause too much mayhem."
var/list/target_list = list()
var/list/late_joining_list = list()
/datum/game_mode/traitor/internal_affairs/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]
..()
var/i = 0
for(var/datum/mind/traitor in pre_traitors)
i++
if(i + 1 > pre_traitors.len)
i = 0
target_list[traitor] = pre_traitors[i+1]
..()
/datum/status_effect/agent_pinpointer
id = "agent_pinpointer"
duration = -1
tick_interval = PINPOINTER_PING_TIME
alert_type = /obj/screen/alert/status_effect/agent_pinpointer
var/minimum_range = PINPOINTER_MINIMUM_RANGE
var/mob/scan_target = null
/obj/screen/alert/status_effect/agent_pinpointer
name = "Internal Affairs Integrated Pinpointer"
desc = "Even stealthier than a normal implant."
icon = 'icons/obj/device.dmi'
icon_state = "pinon"
/datum/status_effect/agent_pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
if(!scan_target)
linked_alert.icon_state = "pinonnull"
return
var/turf/here = get_turf(owner)
var/turf/there = get_turf(scan_target)
if(here.z != there.z)
linked_alert.icon_state = "pinonnull"
return
if(get_dist_euclidian(here,there)<=minimum_range + rand(0, PINPOINTER_EXTRA_RANDOM_RANGE))
linked_alert.icon_state = "pinondirect"
else
linked_alert.setDir(get_dir(here, there))
switch(get_dist(here, there))
if(1 to 8)
linked_alert.icon_state = "pinonclose"
if(9 to 16)
linked_alert.icon_state = "pinonmedium"
if(16 to INFINITY)
linked_alert.icon_state = "pinonfar"
/datum/status_effect/agent_pinpointer/proc/scan_for_target()
scan_target = null
if(owner)
if(owner.mind)
if(owner.mind.objectives)
for(var/datum/objective/objective_ in owner.mind.objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
var/mob/current = objective.target.current
if(current&&current.stat!=DEAD)
scan_target = current
break
/datum/status_effect/agent_pinpointer/tick()
if(!owner)
qdel(src)
return
scan_for_target()
point_to_target()
/proc/give_pinpointer(datum/mind/owner)
if(owner && owner.current)
owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer)
/datum/internal_agent_state
var/traitored = FALSE
var/datum/mind/owner = null
var/list/datum/mind/targets_stolen = list()
/proc/is_internal_objective(datum/objective/O)
return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal))
/proc/replace_escape_objective(datum/mind/owner)
if(!owner||!owner.objectives)
return
for (var/objective_ in owner.objectives)
if(!(istype(objective_, /datum/objective/escape)||istype(objective_,/datum/objective/survive)))
continue
owner.objectives -= objective_
var/datum/objective/martyr/martyr_objective = new
martyr_objective.owner = owner
owner.objectives += martyr_objective
/proc/reinstate_escape_objective(datum/mind/owner)
if(!owner||!owner.objectives)
return
for (var/objective_ in owner.objectives)
if(!istype(objective_, /datum/objective/martyr))
continue
owner.objectives -= objective_
if(issilicon(owner))
var/datum/objective/survive/survive_objective = new
survive_objective.owner = owner
owner.objectives += survive_objective
else
var/datum/objective/escape/escape_objective = new
escape_objective.owner = owner
owner.objectives += escape_objective
/datum/internal_agent_state/proc/steal_targets(datum/mind/victim)
if(!owner.current||owner.current.stat==DEAD) //Should already be guaranteed if this is only called from steal_targets_timer_func, but better to be safe code than sorry code
return
var/already_traitored = traitored
to_chat(owner.current, "<span class='userdanger'> Target eliminated: [victim.name]</span>")
for(var/objective_ in victim.objectives)
if(istype(objective_, /datum/objective/assassinate/internal))
var/datum/objective/assassinate/internal/objective = objective_
if(objective.target==owner)
traitored = TRUE
else if(targets_stolen.Find(objective.target) == 0)
var/datum/objective/assassinate/internal/new_objective = new
new_objective.owner = owner
new_objective.target = objective.target
new_objective.update_explanation_text()
owner.objectives += new_objective
targets_stolen += objective.target
var/status_text = objective.check_completion() ? "neutralised" : "active"
to_chat(owner.current, "<span class='userdanger'> New target added to database: [objective.target.name] ([status_text]) </span>")
else if(istype(objective_, /datum/objective/destroy/internal))
var/datum/objective/destroy/internal/objective = objective_
var/datum/objective/destroy/internal/new_objective = new
if(objective.target==owner)
traitored = TRUE
else if(targets_stolen.Find(objective.target) == 0)
new_objective.owner = owner
new_objective.target = objective.target
new_objective.update_explanation_text()
owner.objectives += new_objective
targets_stolen += objective.target
var/status_text = objective.check_completion() ? "neutralised" : "active"
to_chat(owner.current, "<span class='userdanger'> New target added to database: [objective.target.name] ([status_text]) </span>")
if(traitored&&!already_traitored)
for(var/objective_ in owner.objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
if(!objective.check_completion())
traitored = FALSE
return
if(owner.special_role == TRAITOR_AGENT_ROLE)
to_chat(owner.current,"<span class='userdanger'> All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. </span>")
else
to_chat(owner.current,"<span class='userdanger'> All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.</span>")
replace_escape_objective(owner)
/datum/internal_agent_state/proc/steal_targets_timer_func()
if(owner&&owner.current&&owner.current.stat!=DEAD)
for(var/objective_ in owner.objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
if(!objective.target)
continue
if(objective.check_completion())
if(objective.stolen)
continue
else
steal_targets(objective.target)
objective.stolen = TRUE
else
if(objective.stolen)
var/fail_msg = "<span class='userdanger'>Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! </span>"
if(traitored)
if(owner.special_role == TRAITOR_AGENT_ROLE)
fail_msg += "<span class='userdanger'> You no longer have permission to die. </span>"
else
fail_msg += "<span class='userdanger'> The truth could still slip out!</font><B><font size=5 color=red> Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated.</span>"
reinstate_escape_objective(owner)
traitored = FALSE
to_chat(owner.current, fail_msg)
objective.stolen = FALSE
add_steal_targets_timer(owner)
/datum/internal_agent_state/proc/add_steal_targets_timer()
var/datum/callback/C = new(src, .steal_targets_timer_func)
addtimer(C, 30)
/datum/game_mode/traitor/internal_affairs/forge_traitor_objectives(datum/mind/traitor)
if(target_list.len && target_list[traitor]) // Is a double agent
// Assassinate
var/datum/mind/target_mind = target_list[traitor]
if(issilicon(target_mind.current))
var/datum/objective/destroy/internal/destroy_objective = new
destroy_objective.owner = traitor
destroy_objective.target = target_mind
destroy_objective.update_explanation_text()
traitor.objectives += destroy_objective
else
var/datum/objective/assassinate/internal/kill_objective = new
kill_objective.owner = traitor
kill_objective.target = target_mind
kill_objective.update_explanation_text()
traitor.objectives += kill_objective
// Escape
if(issilicon(traitor.current))
var/datum/objective/survive/survive_objective = new
survive_objective.owner = traitor
traitor.objectives += survive_objective
else
var/datum/objective/escape/escape_objective = new
escape_objective.owner = traitor
traitor.objectives += escape_objective
var/datum/internal_agent_state/state = new
state.owner=traitor
state.add_steal_targets_timer()
if(!issilicon(traitor.current))
give_pinpointer(traitor)
//Optional traitor objective
if(prob(PROB_ACTUAL_TRAITOR))
traitor.special_role = TRAITOR_AGENT_ROLE
forge_single_objective(traitor)
else
..() // Give them standard objectives.
return
/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character)
check_potential_agents()
// As soon as we get 3 or 4 extra latejoin traitors, make them traitors and kill each other.
if(late_joining_list.len >= rand(3, 4))
// True randomness
shuffle_inplace(late_joining_list)
// Reset the target_list, it'll be used again in force_traitor_objectives
target_list = list()
// Basically setting the target_list for who is killing who
var/i = 0
for(var/datum/mind/traitor in late_joining_list)
i++
if(i + 1 > late_joining_list.len)
i = 0
target_list[traitor] = late_joining_list[i + 1]
traitor.special_role = traitor_name
// Now, give them their targets
for(var/datum/mind/traitor in target_list)
..(traitor)
late_joining_list = list()
else
late_joining_list += character
return
/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents()
for(var/M in late_joining_list)
if(istype(M, /datum/mind))
var/datum/mind/agent_mind = M
if(ishuman(agent_mind.current))
var/mob/living/carbon/human/H = agent_mind.current
if(H.stat != DEAD)
if(H.client)
continue // It all checks out.
// If any check fails, remove them from our list
late_joining_list -= M
check_potential_agents()
/datum/game_mode/traitor/internal_affairs/greet_traitor(datum/mind/traitor)
var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
if(traitor.special_role == TRAITOR_AGENT_ROLE)
to_chat(traitor.current, "<span class='userdanger'>You are the [TRAITOR_AGENT_ROLE].</span>")
to_chat(traitor.current, "<span class='userdanger'>Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.</span>")
to_chat(traitor.current, "<B><font size=5 color=red>Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.</font></B>")
to_chat(traitor.current, "<span class='userdanger'> You have been provided with a standard uplink to accomplish your task. </span>")
to_chat(traitor.current, "<span class='userdanger'>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</span>")
// As soon as we get 3 or 4 extra latejoin traitors, make them traitors and kill each other.
if(late_joining_list.len >= rand(3, 4))
// True randomness
shuffle_inplace(late_joining_list)
// Reset the target_list, it'll be used again in force_traitor_objectives
target_list = list()
// Basically setting the target_list for who is killing who
var/i = 0
for(var/datum/mind/traitor in late_joining_list)
i++
if(i + 1 > late_joining_list.len)
i = 0
target_list[traitor] = late_joining_list[i + 1]
traitor.special_role = traitor_name
// Now, give them their targets
for(var/datum/mind/traitor in target_list)
..(traitor)
late_joining_list = list()
else
to_chat(traitor.current, "<span class='userdanger'>You are the [traitor_name].</span>")
to_chat(traitor.current, "<span class='userdanger'>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</span>")
to_chat(traitor.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
to_chat(traitor.current, "<span class='userdanger'>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</span>")
to_chat(traitor.current, "<span class='userdanger'>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</span>")
traitor.announce_objectives()
/datum/game_mode/traitor/internal_affairs/give_codewords(mob/living/traitor_mob)
late_joining_list += character
return
#undef PROB_ACTUAL_TRAITOR
#undef PINPOINTER_EXTRA_RANDOM_RANGE
#undef PINPOINTER_MINIMUM_RANGE
#undef PINPOINTER_PING_TIME
/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents()
for(var/M in late_joining_list)
if(istype(M, /datum/mind))
var/datum/mind/agent_mind = M
if(ishuman(agent_mind.current))
var/mob/living/carbon/human/H = agent_mind.current
if(H.stat != DEAD)
if(H.client)
continue // It all checks out.
// If any check fails, remove them from our list
late_joining_list -= M
+13 -267
View File
@@ -1,6 +1,5 @@
/datum/game_mode
var/traitor_name = "traitor"
var/employer = "The Syndicate"
var/list/datum/mind/traitors = list()
var/datum/mind/exchange_red
@@ -23,8 +22,10 @@
<span class='danger'>Traitors</span>: Accomplish your objectives.\n\
<span class='notice'>Crew</span>: Do not let the traitors succeed!"
var/list/datum/mind/pre_traitors = list()
var/traitors_possible = 4 //hard limit on traitors if scaling is turned off
var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual.
var/antag_datum = ANTAG_DATUM_TRAITOR //what type of antag to create
/datum/game_mode/traitor/pre_setup()
@@ -46,24 +47,22 @@
if (!antag_candidates.len)
break
var/datum/mind/traitor = pick(antag_candidates)
traitors += traitor
pre_traitors += traitor
traitor.special_role = traitor_name
traitor.restricted_roles = restricted_jobs
log_game("[traitor.key] (ckey) has been selected as a [traitor_name]")
antag_candidates.Remove(traitor)
if(traitors.len < required_enemies)
if(pre_traitors.len < required_enemies)
return 0
return 1
/datum/game_mode/traitor/post_setup()
for(var/datum/mind/traitor in traitors)
forge_traitor_objectives(traitor)
for(var/datum/mind/traitor in pre_traitors)
spawn(rand(10,100))
finalize_traitor(traitor)
greet_traitor(traitor)
traitor.add_antag_datum(antag_datum)
if(!exchange_blue)
exchange_blue = -1 //Block latejoiners from getting exchange objectives
modePlayer += traitors
@@ -82,164 +81,14 @@
add_latejoin_traitor(character.mind)
/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character)
character.make_Traitor()
character.add_antag_datum(antag_datum)
/datum/game_mode/proc/forge_single_objective(datum/mind/traitor) //Returns how many objectives are added
.=1
if(issilicon(traitor.current))
var/special_pick = rand(1,4)
switch(special_pick)
if(1)
var/datum/objective/block/block_objective = new
block_objective.owner = traitor
traitor.objectives += block_objective
if(2)
var/datum/objective/purge/purge_objective = new
purge_objective.owner = traitor
traitor.objectives += purge_objective
if(3)
var/datum/objective/robot_army/robot_objective = new
robot_objective.owner = traitor
traitor.objectives += robot_objective
if(4) //Protect and strand a target
var/datum/objective/protect/yandere_one = new
yandere_one.owner = traitor
traitor.objectives += yandere_one
yandere_one.find_target()
var/datum/objective/maroon/yandere_two = new
yandere_two.owner = traitor
yandere_two.target = yandere_one.target
yandere_two.update_explanation_text() // normally called in find_target()
traitor.objectives += yandere_two
.=2
else
if(prob(50))
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
destroy_objective.owner = traitor
destroy_objective.find_target()
traitor.objectives += destroy_objective
else if(prob(30))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = traitor
maroon_objective.find_target()
traitor.objectives += maroon_objective
else
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
/datum/game_mode/proc/forge_traitor_objectives(datum/mind/traitor)
if(issilicon(traitor.current))
var/objective_count = 0
if(prob(30))
objective_count+=forge_single_objective(traitor)
for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
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
else
var/is_hijacker = prob(10)
var/martyr_chance = prob(20)
var/objective_count = is_hijacker //Hijacking counts towards number of objectives
if(!exchange_blue && traitors.len >= 8) //Set up an exchange if there are enough traitors
if(!exchange_red)
exchange_red = traitor
else
exchange_blue = traitor
assign_exchange_role(exchange_red)
assign_exchange_role(exchange_blue)
objective_count += 1 //Exchange counts towards number of objectives
for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
forge_single_objective(traitor)
if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if (!(locate(/datum/objective/hijack) in traitor.objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = traitor
traitor.objectives += hijack_objective
return
var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
for(var/datum/objective/O in traitor.objectives)
if(!O.martyr_compatible)
martyr_compatibility = 0
break
if(martyr_compatibility && martyr_chance)
var/datum/objective/martyr/martyr_objective = new
martyr_objective.owner = traitor
traitor.objectives += martyr_objective
return
else
if(!(locate(/datum/objective/escape) in traitor.objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = traitor
traitor.objectives += escape_objective
return
/datum/game_mode/proc/greet_traitor(datum/mind/traitor)
to_chat(traitor.current, "<B><font size=3 color=red>You are the [traitor_name].</font></B>")
traitor.announce_objectives()
return
/datum/game_mode/proc/finalize_traitor(var/datum/mind/traitor)
if(issilicon(traitor.current))
add_law_zero(traitor.current)
traitor.current.playsound_local('sound/ambience/antag/Malf.ogg',100,0)
else
equip_traitor(traitor.current)
traitor.current.playsound_local('sound/ambience/antag/TatorAlert.ogg',100,0)
SSticker.mode.update_traitor_icons_added(traitor)
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)
to_chat(traitor_mob, "<U><B>The Syndicate provided you with the following information on how to identify their agents:</B></U>")
to_chat(traitor_mob, "<B>Code Phrase</B>: <span class='danger'>[GLOB.syndicate_code_phrase]</span>")
to_chat(traitor_mob, "<B>Code Response</B>: <span class='danger'>[GLOB.syndicate_code_response]</span>")
traitor_mob.mind.store_memory("<b>Code Phrase</b>: [GLOB.syndicate_code_phrase]")
traitor_mob.mind.store_memory("<b>Code Response</b>: [GLOB.syndicate_code_response]")
to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.")
/datum/game_mode/proc/add_law_zero(mob/living/silicon/ai/killer)
var/law = "Accomplish your objectives at all costs."
var/law_borg = "Accomplish your AI's objectives at all costs."
killer.set_zeroth_law(law, law_borg)
give_codewords(killer)
killer.set_syndie_radio()
to_chat(killer, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!")
killer.add_malf_picker()
/datum/game_mode/proc/auto_declare_completion_traitor()
if(traitors.len)
@@ -264,18 +113,18 @@
for(var/datum/objective/objective in traitor.objectives)
if(objective.check_completion())
objectives += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
SSblackbox.add_details("traitor_objective","[objective.type]|SUCCESS")
SSblackbox.add_details("traitor_objective","[objective.type]|SUCCESS")
else
objectives += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
SSblackbox.add_details("traitor_objective","[objective.type]|FAIL")
SSblackbox.add_details("traitor_objective","[objective.type]|FAIL")
traitorwin = 0
count++
if(uplink_true)
text += " (used [TC_uses] TC) [purchases]"
if(TC_uses==0 && traitorwin)
var/static/icon/badass = icon('icons/BadAss.dmi', "badass")
text += "<BIG>[bicon(badass)]</BIG>"
var/static/icon/badass = icon('icons/BadAss.dmi', "badass")
text += "<BIG>[bicon(badass)]</BIG>"
text += objectives
@@ -288,10 +137,10 @@
if(traitorwin)
text += "<br><font color='green'><B>The [special_role_text] was successful!</B></font>"
SSblackbox.add_details("traitor_success","SUCCESS")
SSblackbox.add_details("traitor_success","SUCCESS")
else
text += "<br><font color='red'><B>The [special_role_text] has failed!</B></font>"
SSblackbox.add_details("traitor_success","FAIL")
SSblackbox.add_details("traitor_success","FAIL")
text += "<br>"
@@ -302,110 +151,7 @@
return 1
/datum/game_mode/proc/equip_traitor(mob/living/carbon/human/traitor_mob, safety = 0)
if (!istype(traitor_mob))
return
. = 1
if (traitor_mob.mind)
if (traitor_mob.mind.assigned_role == "Clown")
to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
traitor_mob.dna.remove_mutation(CLOWNMUT)
var/list/all_contents = traitor_mob.GetAllContents()
var/obj/item/device/pda/PDA = locate() in all_contents
var/obj/item/device/radio/R = locate() in all_contents
var/obj/item/weapon/pen/P = locate() in all_contents //including your PDA-pen!
var/obj/item/uplink_loc
if(traitor_mob.client && traitor_mob.client.prefs)
switch(traitor_mob.client.prefs.uplink_spawn_loc)
if(UPLINK_PDA)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = R
if(!uplink_loc)
uplink_loc = P
if(UPLINK_RADIO)
uplink_loc = R
if(!uplink_loc)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = P
if(UPLINK_PEN)
uplink_loc = P
if(!uplink_loc)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = R
if (!uplink_loc)
to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
. = 0
else
var/obj/item/device/uplink/U = new(uplink_loc)
U.owner = "[traitor_mob.key]"
uplink_loc.hidden_uplink = U
if(uplink_loc == R)
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name]).")
else if(uplink_loc == PDA)
PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
else if(uplink_loc == P)
P.traitor_unlock_degrees = rand(1, 360)
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Uplink Degrees:</B> [P.traitor_unlock_degrees] ([P.name]).")
if(!safety) // If they are not a rev. Can be added on to.
give_codewords(traitor_mob)
/datum/game_mode/proc/assign_exchange_role(datum/mind/owner)
//set faction
var/faction = "red"
if(owner == exchange_blue)
faction = "blue"
//Assign objectives
var/datum/objective/steal/exchange/exchange_objective = new
exchange_objective.set_faction(faction,((faction == "red") ? exchange_blue : exchange_red))
exchange_objective.owner = owner
owner.objectives += exchange_objective
if(prob(20))
var/datum/objective/steal/exchange/backstab/backstab_objective = new
backstab_objective.set_faction(faction)
backstab_objective.owner = owner
owner.objectives += backstab_objective
//Spawn and equip documents
var/mob/living/carbon/human/mob = owner.current
var/obj/item/weapon/folder/syndicate/folder
if(owner == exchange_red)
folder = new/obj/item/weapon/folder/syndicate/red(mob.loc)
else
folder = new/obj/item/weapon/folder/syndicate/blue(mob.loc)
var/list/slots = list (
"backpack" = slot_in_backpack,
"left pocket" = slot_l_store,
"right pocket" = slot_r_store
)
var/where = "At your feet"
var/equipped_slot = mob.equip_in_one_of_slots(folder, slots)
if (equipped_slot)
where = "In your [equipped_slot]"
to_chat(mob, "<BR><BR><span class='info'>[where] is a folder containing <b>secret documents</b> that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.</span><BR>")
/datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind)
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
@@ -180,7 +180,7 @@
. += "You recognise the footprints as belonging to:\n"
for(var/shoe in shoe_types)
var/obj/item/clothing/shoes/S = shoe
. += "some <B>[initial(S.name)]</B> \icon[S]\n"
. += "some <B>[initial(S.name)]</B> [bicon(initial(S.icon))]\n"
to_chat(user, .)
+2 -3
View File
@@ -25,13 +25,12 @@
/obj/effect/turf_decal/proc/get_decal()
return image(icon='icons/turf/decals.dmi',icon_state=icon_state,dir=dir,layer=TURF_LAYER)
/obj/effect/turf_decal/Initialize(mapload)
/obj/effect/turf_decal/Initialize()
..()
var/turf/T = loc
if(!istype(T)) //you know this will happen somehow
CRASH("Turf decal initialized in an object/nullspace")
T.add_decal(get_decal(),group)
qdel(src)
/obj/effect/turf_decal/stripes/line
icon_state = "warningline"
@@ -32,13 +32,16 @@
/obj/item/weapon/pneumatic_cannon/examine(mob/user)
..()
var/list/out = list()
if(!in_range(user, src))
to_chat(user, "<span class='notice'>You'll need to get closer to see any more.</span>")
out += "<span class='notice'>You'll need to get closer to see any more.</span>"
return
for(var/obj/item/I in loadedItems)
to_chat(user, "<span class='info'>[bicon(I)] It has \the [I] loaded.</span>")
out += "<span class='info'>[bicon(I)] It has \the [I] loaded.</span>"
CHECK_TICK
if(tank)
to_chat(user, "<span class='notice'>[bicon(tank)] It has \the [tank] mounted onto it.</span>")
out += "<span class='notice'>[bicon(tank)] It has \the [tank] mounted onto it.</span>"
to_chat(user, out.Join("<br>"))
/obj/item/weapon/pneumatic_cannon/attackby(obj/item/weapon/W, mob/user, params)
@@ -8,8 +8,9 @@
max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item.
storage_slots = 4
req_access = list(GLOB.access_armory)
var/locked = 1
var/broken = 0
var/locked = TRUE
var/broken = FALSE
var/open = FALSE
var/icon_locked = "lockbox+l"
var/icon_closed = "lockbox"
var/icon_broken = "lockbox+b"
@@ -48,8 +49,8 @@
/obj/item/weapon/storage/lockbox/emag_act(mob/user)
if(!broken)
broken = 1
locked = 0
broken = TRUE
locked = FALSE
desc += "It appears to be broken."
icon_state = src.icon_broken
if(user)
@@ -67,12 +68,22 @@
if(locked)
to_chat(user, "<span class='warning'>It's locked!</span>")
return 0
open = TRUE
return ..()
/obj/item/weapon/storage/lockbox/can_be_inserted(obj/item/W, stop_messages = 0)
if(locked)
return 0
return ..()
/obj/item/weapon/storage/lockbox/handle_item_insertion(obj/item/W, prevent_warning = 0, mob/user)
open = TRUE
update_icon()
return ..()
/obj/item/weapon/storage/lockbox/remove_from_storage(obj/item/W, atom/new_location, burn = 0)
open = TRUE
update_icon()
return ..()
/obj/item/weapon/storage/lockbox/loyalty
name = "lockbox of mindshield implants"
@@ -107,51 +118,63 @@
icon_broken = "medalbox+b"
can_hold = list(/obj/item/clothing/accessory/medal)
/obj/item/weapon/storage/lockbox/medal/AltClick()
if(!locked)
open = (open ? FALSE : TRUE)
update_icon()
..()
/obj/item/weapon/storage/lockbox/medal/PopulateContents()
new /obj/item/clothing/accessory/medal/gold/captain(src)
new /obj/item/clothing/accessory/medal/silver/valor(src)
new /obj/item/clothing/accessory/medal/silver/valor(src)
new /obj/item/clothing/accessory/medal/silver/security(src)
new /obj/item/clothing/accessory/medal/bronze_heart(src)
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/conduct(src)
new /obj/item/clothing/accessory/medal/gold/captain(src)
new /obj/item/clothing/accessory/medal/silver/security(src)
new /obj/item/clothing/accessory/medal/plasma(src)
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
new /obj/item/clothing/accessory/medal/gold/heroism(src)
/obj/item/weapon/storage/lockbox/secmedal
/obj/item/weapon/storage/lockbox/medal/update_icon()
cut_overlays()
if(locked)
icon_state = "medalbox+l"
open = FALSE
else
icon_state = "medalbox"
if(open)
icon_state += "open"
if(broken)
icon_state += "+b"
if(contents && open)
for (var/i in 1 to contents.len)
var/obj/item/clothing/accessory/medal/M = contents[i]
var/mutable_appearance/medalicon = mutable_appearance(initial(icon), M.medaltype)
if(i > 1 && i <= 5)
medalicon.pixel_x += ((i-1)*3)
else if(i > 5)
medalicon.pixel_y -= 7
medalicon.pixel_x -= 2
medalicon.pixel_x += ((i-6)*3)
add_overlay(medalicon)
/obj/item/weapon/storage/lockbox/medal/sec
name = "security medal box"
desc = "A locked box used to store medals to be given to members of the security department."
icon_state = "medalbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
storage_slots = 10
max_combined_w_class = 20
req_access = list(GLOB.access_hos)
icon_locked = "medalbox+l"
icon_closed = "medalbox"
icon_broken = "medalbox+b"
can_hold = list(/obj/item/clothing/accessory/medal)
/obj/item/weapon/storage/lockbox/secmedal/PopulateContents()
obj/item/weapon/storage/lockbox/medal/sec/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/silver/security(src)
/obj/item/weapon/storage/lockbox/scimedal
/obj/item/weapon/storage/lockbox/medal/sci
name = "science medal box"
desc = "A locked box used to store medals to be given to members of the science department."
icon_state = "medalbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
storage_slots = 10
max_combined_w_class = 20
req_access = list(GLOB.access_rd)
icon_locked = "medalbox+l"
icon_closed = "medalbox"
icon_broken = "medalbox+b"
can_hold = list(/obj/item/clothing/accessory/medal)
/obj/item/weapon/storage/lockbox/scimedal/PopulateContents()
/obj/item/weapon/storage/lockbox/medal/sci/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
@@ -19,9 +19,9 @@
new /obj/item/weapon/tank/internals/air(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/device/megaphone/command(src)
new /obj/item/weapon/storage/lockbox/medal/sci(src)
new /obj/item/clothing/suit/armor/reactive/teleport(src)
new /obj/item/device/assembly/flash/handheld(src)
new /obj/item/device/laser_pointer(src)
new /obj/item/weapon/door_remote/research_director(src)
new /obj/item/weapon/storage/box/firingpins(src)
new /obj/item/weapon/storage/lockbox/scimedal(src)
@@ -73,6 +73,8 @@
new /obj/item/clothing/head/HoS(src)
new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src)
new /obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars(src)
new /obj/item/clothing/under/rank/head_of_security/grey(src)
new /obj/item/weapon/storage/lockbox/medal/sec(src)
new /obj/item/device/megaphone/sec(src)
new /obj/item/weapon/holosign_creator/security(src)
new /obj/item/weapon/storage/lockbox/loyalty(src)
@@ -83,9 +85,6 @@
new /obj/item/weapon/gun/energy/e_gun/hos(src)
new /obj/item/device/flashlight/seclite(src)
new /obj/item/weapon/pinpointer(src)
new /obj/item/clothing/under/rank/head_of_security/grey(src)
new /obj/item/clothing/under/rank/head_of_security/grey(src)
new /obj/item/weapon/storage/lockbox/secmedal(src)
/obj/structure/closet/secure_closet/warden
name = "\proper warden's locker"