another huge sync
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
. ++
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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?
|
||||
|
||||
|
||||
@@ -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&¤t.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
|
||||
@@ -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, .)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user