Merge branch 'master' into upstream-merge-31737

This commit is contained in:
Poojawa
2017-10-21 07:18:14 -05:00
committed by GitHub
591 changed files with 181531 additions and 178280 deletions
@@ -1,5 +1,6 @@
/datum/antagonist/abductor
name = "Abductor"
job_rank = ROLE_ABDUCTOR
var/datum/objective_team/abductor_team/team
var/sub_role
var/outfit
@@ -18,9 +19,15 @@
landmark_type = /obj/effect/landmark/abductor/scientist
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
/datum/antagonist/abductor/New(datum/mind/new_owner, datum/objective_team/abductor_team/T)
team = T
return ..()
/datum/antagonist/abductor/create_team(datum/objective_team/abductor_team/new_team)
if(!new_team)
return
if(!istype(new_team))
stack_trace("Wrong team type passed to [type] initialization.")
team = new_team
/datum/antagonist/abductor/get_team()
return team
/datum/antagonist/abductor/on_gain()
SSticker.mode.abductors += owner
@@ -31,7 +38,6 @@
/datum/antagonist/abductor/on_removal()
SSticker.mode.abductors -= owner
team.members -= owner
owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"<span class='userdanger'>You are no longer the [owner.special_role]!</span>")
+42 -2
View File
@@ -7,6 +7,8 @@ GLOBAL_LIST_EMPTY(antagonists)
var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum
var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with
var/delete_on_mind_deletion = TRUE
var/job_rank
var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted.
/datum/antagonist/New(datum/mind/new_owner)
GLOB.antagonists += src
@@ -23,9 +25,10 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/can_be_owned(datum/mind/new_owner)
. = TRUE
if(owner.has_antag_datum(type))
var/datum/mind/tested = new_owner || owner
if(tested.has_antag_datum(type))
return FALSE
for(var/i in owner.antag_datums)
for(var/i in tested.antag_datums)
var/datum/antagonist/A = i
if(is_type_in_typecache(src, A.typecache_datum_blacklist))
return FALSE
@@ -42,12 +45,35 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override)
return
//Assign default team and creates one for one of a kind team antagonists
/datum/antagonist/proc/create_team(datum/objective_team/team)
return
//Proc called when the datum is given to a mind.
/datum/antagonist/proc/on_gain()
if(owner && owner.current)
if(!silent)
greet()
apply_innate_effects()
if(is_banned(owner.current) && replace_banned)
replace_banned_player()
/datum/antagonist/proc/is_banned(mob/M)
if(!M)
return FALSE
. = (jobban_isbanned(M,"Syndicate") || (job_rank && jobban_isbanned(M,job_rank)))
/datum/antagonist/proc/replace_banned_player()
set waitfor = FALSE
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", null, job_rank, 50, owner.current)
var/mob/dead/observer/theghost = null
if(candidates.len)
theghost = pick(candidates)
to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.")
owner.current.ghostize(0)
owner.current.key = theghost.key
/datum/antagonist/proc/on_removal()
remove_innate_effects()
@@ -55,6 +81,9 @@ GLOBAL_LIST_EMPTY(antagonists)
LAZYREMOVE(owner.antag_datums, src)
if(!silent && owner.current)
farewell()
var/datum/objective_team/team = get_team()
if(team)
team.remove_member(owner)
qdel(src)
/datum/antagonist/proc/greet()
@@ -62,3 +91,14 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/farewell()
return
//Returns the team antagonist belongs to if any.
/datum/antagonist/proc/get_team()
return
//Should probably be on ticker or job ss ?
/proc/get_antagonists(antag_type,specific = FALSE)
. = list()
for(var/datum/antagonist/A in GLOB.antagonists)
if(!specific && istype(A,antag_type) || specific && A.type == antag_type)
. += A.owner
@@ -1,22 +1,30 @@
/datum/antagonist/brother
name = "Brother"
job_rank = ROLE_BROTHER
var/special_role = "blood brother"
var/datum/objective_team/brother_team/team
/datum/antagonist/brother/New(datum/mind/new_owner, datum/objective_team/brother_team/T)
team = T
/datum/antagonist/brother/New(datum/mind/new_owner)
return ..()
/datum/antagonist/brother/create_team(datum/objective_team/brother_team/new_team)
if(!new_team)
return
if(!istype(new_team))
stack_trace("Wrong team type passed to [type] initialization.")
team = new_team
/datum/antagonist/brother/get_team()
return team
/datum/antagonist/brother/on_gain()
SSticker.mode.brothers += owner
owner.special_role = special_role
owner.objectives += team.objectives
finalize_brother()
return ..()
/datum/antagonist/brother/on_removal()
SSticker.mode.brothers -= owner
team.members -= owner
owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"<span class='userdanger'>You are no longer the [special_role]!</span>")
@@ -1,6 +1,8 @@
//CLOCKCULT PROOF OF CONCEPT
/datum/antagonist/clockcult
name = "Clock Cultist"
var/datum/action/innate/hierophant/hierophant_network = new()
job_rank = ROLE_SERVANT_OF_RATVAR
/datum/antagonist/clockcult/silent
silent = TRUE
@@ -47,8 +49,6 @@
var/mob/living/current = owner.current
SSticker.mode.servants_of_ratvar += owner
SSticker.mode.update_servant_icons_added(owner)
if(jobban_isbanned(current, ROLE_SERVANT_OF_RATVAR))
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR), 0)
owner.special_role = "Servant of Ratvar"
owner.current.log_message("<font color=#BE8700>Has been converted to the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
if(issilicon(current))
@@ -1,8 +1,10 @@
#define SUMMON_POSSIBILITIES 3
/datum/antagonist/cult
name = "Cultist"
var/datum/action/innate/cult/comm/communion = new
var/datum/action/innate/cult/mastervote/vote = new
job_rank = ROLE_CULTIST
/datum/antagonist/cult/Destroy()
QDEL_NULL(communion)
@@ -73,8 +75,6 @@
add_objectives()
SSticker.mode.cult += owner // Only add after they've been given objectives
cult_memorization(owner)
if(jobban_isbanned(current, ROLE_CULTIST))
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_CULTIST, ROLE_CULTIST), 0)
SSticker.mode.update_cult_icons_added(owner)
current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
if(GLOB.blood_target && GLOB.blood_target_image && current.client)
+1
View File
@@ -1,5 +1,6 @@
/datum/antagonist/traitor
name = "Traitor"
job_rank = ROLE_TRAITOR
var/should_specialise = TRUE //do we split into AI and human
var/base_datum_custom = ANTAG_DATUM_TRAITOR_CUSTOM //used for body transfer
var/ai_datum = ANTAG_DATUM_TRAITOR_AI
+2 -1
View File
@@ -85,6 +85,8 @@ GLOBAL_LIST_INIT(devil_title, list("Lord ", "Prelate ", "Count ", "Viscount ", "
GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", "mya", "folth", "wren", "geyr", "hil", "niet", "twou", "phi", "coa"))
GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr."))
/datum/antagonist/devil
name = "Devil"
job_rank = ROLE_DEVIL
//Don't delete upon mind destruction, otherwise soul re-selling will break.
delete_on_mind_deletion = FALSE
var/obligation
@@ -107,7 +109,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/obj/effect/proc_holder/spell/targeted/conjure_item/violin,
/obj/effect/proc_holder/spell/targeted/summon_dancefloor))
var/ascendable = FALSE
name = "Devil"
/datum/antagonist/devil/New()
+1
View File
@@ -1,5 +1,6 @@
/datum/antagonist/ninja
name = "Ninja"
job_rank = ROLE_NINJA
var/helping_station = 0
var/give_objectives = TRUE
+229
View File
@@ -0,0 +1,229 @@
//How often to check for promotion possibility
#define HEAD_UPDATE_PERIOD 300
/datum/antagonist/rev
name = "Revolutionary"
job_rank = ROLE_REV
var/hud_type = "rev"
var/datum/objective_team/revolution/rev_team
/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
. = ..()
if(new_owner.assigned_role in GLOB.command_positions)
return FALSE
if(new_owner.unconvertable)
return FALSE
/datum/antagonist/rev/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_rev_icons_added(M)
/datum/antagonist/rev/remove_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_rev_icons_removed(M)
/datum/antagonist/rev/proc/equip_rev()
return
/datum/antagonist/rev/New()
. = ..()
/datum/antagonist/rev/on_gain()
. = ..()
create_objectives()
equip_rev()
owner.current.log_message("<font color='red'>Has been converted to the revolution!</font>", INDIVIDUAL_ATTACK_LOG)
/datum/antagonist/rev/on_removal()
remove_objectives()
. = ..()
/datum/antagonist/rev/greet()
to_chat(owner, "<span class='danger'><FONT size = 3> You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!</FONT></span>")
owner.announce_objectives()
/datum/antagonist/rev/create_team(datum/objective_team/revolution/new_team)
if(!new_team)
//For now only one revolution at a time
for(var/datum/antagonist/rev/head/H in GLOB.antagonists)
if(H.rev_team)
rev_team = H.rev_team
return
rev_team = new /datum/objective_team/revolution
rev_team.update_objectives()
rev_team.update_heads()
return
if(!istype(new_team))
stack_trace("Wrong team type passed to [type] initialization.")
rev_team = new_team
/datum/antagonist/rev/get_team()
return rev_team
/datum/antagonist/rev/proc/create_objectives()
owner.objectives |= rev_team.objectives
/datum/antagonist/rev/proc/remove_objectives()
owner.objectives -= rev_team.objectives
//Bump up to head_rev
/datum/antagonist/rev/proc/promote()
var/old_team = rev_team
var/datum/mind/old_owner = owner
silent = TRUE
owner.remove_antag_datum(/datum/antagonist/rev)
var/datum/antagonist/rev/head/new_revhead = new(old_owner)
new_revhead.silent = TRUE
old_owner.add_antag_datum(new_revhead,old_team)
new_revhead.silent = FALSE
to_chat(old_owner, "<span class='userdanger'>You have proved your devotion to revolution! You are a head revolutionary now!</span>")
/datum/antagonist/rev/head
name = "Head Revolutionary"
hud_type = "rev_head"
var/remove_clumsy = FALSE
var/give_flash = FALSE
var/give_hud = FALSE
/datum/antagonist/rev/proc/update_rev_icons_added(mob/living/M)
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
revhud.join_hud(M)
set_antag_hud(M,hud_type)
/datum/antagonist/rev/proc/update_rev_icons_removed(mob/living/M)
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
revhud.leave_hud(M)
set_antag_hud(M, null)
/datum/antagonist/rev/proc/can_be_converted(mob/living/candidate)
if(!candidate.mind)
return FALSE
if(!can_be_owned(candidate.mind))
return FALSE
var/mob/living/carbon/C = candidate //Check to see if the potential rev is implanted
if(!istype(C)) //Can't convert simple animals
return FALSE
if(C.isloyal())
return FALSE
return TRUE
/datum/antagonist/rev/proc/add_revolutionary(datum/mind/rev_mind,stun = TRUE)
if(!can_be_converted(rev_mind.current))
return FALSE
if(stun)
if(iscarbon(rev_mind.current))
var/mob/living/carbon/carbon_mob = rev_mind.current
carbon_mob.silent = max(carbon_mob.silent, 5)
carbon_mob.flash_act(1, 1)
rev_mind.current.Stun(100)
rev_mind.add_antag_datum(/datum/antagonist/rev,rev_team)
rev_mind.special_role = "Revolutionary"
return TRUE
/datum/antagonist/rev/head/proc/demote()
var/datum/mind/old_owner = owner
var/old_team = rev_team
silent = TRUE
owner.remove_antag_datum(/datum/antagonist/rev/head)
var/datum/antagonist/rev/new_rev = new /datum/antagonist/rev(old_owner)
new_rev.silent = TRUE
old_owner.add_antag_datum(new_rev,old_team)
new_rev.silent = FALSE
to_chat(old_owner, "<span class='userdanger'>Revolution has been disappointed of your leader traits! You are a regular revolutionary now!</span>")
/datum/antagonist/rev/farewell()
if(ishuman(owner.current))
owner.current.visible_message("[owner.current] looks like they just remembered their real allegiance!", \
"<span class='userdanger'><FONT size = 3>You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</FONT></span>")
else if(issilicon(owner.current))
owner.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.", \
"<span class='userdanger'><FONT size = 3>The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.</FONT></span>")
/datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter)
log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!")
if(borged)
message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]")
owner.special_role = null
if(iscarbon(owner.current))
var/mob/living/carbon/C = owner.current
C.Unconscious(100)
owner.remove_antag_datum(type)
/datum/antagonist/rev/head/remove_revolutionary(borged,deconverter)
if(!borged)
return
. = ..()
/datum/antagonist/rev/head/equip_rev()
var/mob/living/carbon/human/H = owner.current
if(!istype(H))
return
if(remove_clumsy && owner.assigned_role == "Clown")
to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
H.dna.remove_mutation(CLOWNMUT)
if(give_flash)
var/obj/item/device/assembly/flash/T = new(H)
var/list/slots = list (
"backpack" = slot_in_backpack,
"left pocket" = slot_l_store,
"right pocket" = slot_r_store
)
var/where = H.equip_in_one_of_slots(T, slots)
if (!where)
to_chat(H, "The Syndicate were unfortunately unable to get you a flash.")
else
to_chat(H, "The flash in your [where] will help you to persuade the crew to join your cause.")
if(give_hud)
var/obj/item/organ/cyberimp/eyes/hud/security/syndicate/S = new(H)
S.Insert(H, special = FALSE, drop_if_replaced = FALSE)
to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.")
/datum/objective_team/revolution
name = "Revolution"
var/list/objectives = list()
var/max_headrevs = 3
/datum/objective_team/revolution/proc/update_objectives(initial = FALSE)
var/untracked_heads = SSjob.get_all_heads()
for(var/datum/objective/mutiny/O in objectives)
untracked_heads -= O.target
for(var/datum/mind/M in untracked_heads)
var/datum/objective/mutiny/new_target = new()
new_target.team = src
new_target.target = M
new_target.update_explanation_text()
objectives += new_target
for(var/datum/mind/M in members)
M.objectives |= objectives
addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
/datum/objective_team/revolution/proc/head_revolutionaries()
. = list()
for(var/datum/mind/M in members)
if(M.has_antag_datum(/datum/antagonist/rev/head))
. += M
/datum/objective_team/revolution/proc/update_heads()
if(SSticker.HasRoundStarted())
var/list/datum/mind/head_revolutionaries = head_revolutionaries()
var/list/datum/mind/heads = SSjob.get_all_heads()
var/list/sec = SSjob.get_all_sec()
if(head_revolutionaries.len < max_headrevs && head_revolutionaries.len < round(heads.len - ((8 - sec.len) / 3)))
var/list/datum/mind/non_heads = members - head_revolutionaries
var/list/datum/mind/promotable = list()
for(var/datum/mind/khrushchev in non_heads)
if(khrushchev.current && !khrushchev.current.incapacitated() && !khrushchev.current.restrained() && khrushchev.current.client && khrushchev.current.stat != DEAD)
if(ROLE_REV in khrushchev.current.client.prefs.be_special)
promotable += khrushchev
if(promotable.len)
var/datum/mind/new_leader = pick(promotable)
var/datum/antagonist/rev/rev = new_leader.has_antag_datum(/datum/antagonist/rev)
rev.promote()
addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
+17 -5
View File
@@ -5,6 +5,7 @@
/datum/antagonist/wizard
name = "Space Wizard"
job_rank = ROLE_WIZARD
var/give_objectives = TRUE
var/strip = TRUE //strip before equipping
var/allow_rename = TRUE
@@ -32,6 +33,16 @@
/datum/antagonist/wizard/proc/unregister()
SSticker.mode.wizards -= src
/datum/antagonist/wizard/create_team(datum/objective_team/wizard/new_team)
if(!new_team)
return
if(!istype(new_team))
stack_trace("Wrong team type passed to [type] initialization.")
wiz_team = new_team
/datum/antagonist/wizard/get_team()
return wiz_team
/datum/objective_team/wizard
name = "wizard team"
@@ -99,6 +110,8 @@
/datum/antagonist/wizard/on_removal()
unregister()
for(var/objective in objectives)
owner.objectives -= objective
owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff
return ..()
@@ -144,8 +157,7 @@
/datum/antagonist/wizard/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
if(wiz_team) //Don't bother with the icon if you're solo wizard
update_wiz_icons_added(M)
update_wiz_icons_added(M, wiz_team ? TRUE : FALSE) //Don't bother showing the icon if you're solo wizard
M.faction |= "wizard"
/datum/antagonist/wizard/remove_innate_effects(mob/living/mob_override)
@@ -166,10 +178,10 @@
owner.announce_objectives()
/datum/antagonist/wizard/apprentice/register()
SSticker.mode.apprentices |= src
SSticker.mode.apprentices |= owner
/datum/antagonist/wizard/apprentice/unregister()
SSticker.mode.apprentices -= src
SSticker.mode.apprentices -= owner
/datum/antagonist/wizard/apprentice/equip_wizard()
. = ..()
@@ -237,7 +249,7 @@
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz)
/datum/antagonist/wizard/proc/update_wiz_icons_added(mob/living/wiz,join = TRUE)
var/datum/atom_hud/antag/wizhud = GLOB.huds[ANTAG_HUD_WIZ]
wizhud.join_hud(wiz)
set_antag_hud(wiz, hud_version)
+2 -1
View File
@@ -249,7 +249,8 @@
// Otherwise, the user mob's machine var will be reset directly.
//
/proc/onclose(mob/user, windowid, atom/ref=null)
if(!user.client) return
if(!user.client)
return
var/param = "null"
if(ref)
param = "\ref[ref]"
+2
View File
@@ -77,6 +77,8 @@
/datum/datacore/proc/manifest()
for(var/mob/dead/new_player/N in GLOB.player_list)
if(N.new_character)
log_manifest(N.ckey,N.new_character.mind,N.new_character)
if(ishuman(N.new_character))
manifest_inject(N.new_character, N.client)
CHECK_TICK
+3 -2
View File
@@ -18,10 +18,11 @@
if(!parrot || parrot.loc != affected_mob)
cure()
else if(prob(parrot.speak_chance))
affected_mob.say(pick(parrot.speech_buffer))
if(parrot.speech_buffer.len)
affected_mob.say(pick(parrot.speech_buffer))
/datum/disease/parrot_possession/cure()
if(parrot && parrot.loc == affected_mob)
parrot.forceMove(affected_mob.drop_location())
affected_mob.visible_message("<span class='danger'>[parrot] is violently driven out of [affected_mob]!</span>", "<span class='userdanger'>[parrot] bursts out of your chest!</span>")
..()
..()
+4 -2
View File
@@ -95,8 +95,10 @@ STI KALY - blind
var/list/L = list()
for(var/turf/T in get_area_turfs(thearea.type))
if(T.z != affected_mob.z) continue
if(T.name == "space") continue
if(T.z != affected_mob.z)
continue
if(T.name == "space")
continue
if(!T.density)
var/clear = 1
for(var/obj/O in T)
+1 -1
View File
@@ -50,7 +50,7 @@
for(var/mob/M in GLOB.dead_mob_list)
if(!M.client || isnewplayer(M))
continue
var/T = get_turf(src)
var/T = get_turf(user)
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null)))
M.show_message(msg)
+10
View File
@@ -1,4 +1,5 @@
#define EXPLOSION_THROW_SPEED 4
#define REEBE_HUGBOX_COEFFICIENT 0.5
GLOBAL_LIST_EMPTY(explosions)
//Against my better judgement, I will return the explosion datum
@@ -60,6 +61,13 @@ GLOBAL_LIST_EMPTY(explosions)
light_impact_range = min(GLOB.MAX_EX_LIGHT_RANGE, light_impact_range)
flash_range = min(GLOB.MAX_EX_FLASH_RANGE, flash_range)
flame_range = min(GLOB.MAX_EX_FLAME_RANGE, flame_range)
if(!ignorecap && epicenter.z == ZLEVEL_CITYOFCOGS)
devastation_range = min(GLOB.MAX_EX_DEVESTATION_RANGE * REEBE_HUGBOX_COEFFICIENT, devastation_range)
heavy_impact_range = min(GLOB.MAX_EX_HEAVY_RANGE * REEBE_HUGBOX_COEFFICIENT, heavy_impact_range)
light_impact_range = min(GLOB.MAX_EX_LIGHT_RANGE * REEBE_HUGBOX_COEFFICIENT, light_impact_range)
flash_range = min(GLOB.MAX_EX_FLASH_RANGE * REEBE_HUGBOX_COEFFICIENT, flash_range)
flame_range = min(GLOB.MAX_EX_FLAME_RANGE * REEBE_HUGBOX_COEFFICIENT, flame_range)
//DO NOT REMOVE THIS STOPLAG, IT BREAKS THINGS
//not sleeping causes us to ex_act() the thing that triggered the explosion
@@ -388,3 +396,5 @@ GLOBAL_LIST_EMPTY(explosions)
// 10 explosion power is a (1, 3, 6) explosion.
// 5 explosion power is a (0, 1, 3) explosion.
// 1 explosion power is a (0, 0, 1) explosion.
#undef REEBE_HUGBOX_COEFFICIENT
+1 -1
View File
@@ -206,7 +206,7 @@
continue
if(extended_safety_checks)
if(istype(F, /turf/open/lava)) //chasms aren't /floor, and so are pre-filtered
if(islava(F)) //chasms aren't /floor, and so are pre-filtered
var/turf/open/lava/L = F
if(!L.is_safe())
continue
@@ -0,0 +1,89 @@
/*
list/atom/output_atoms
mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
mid_length (num) The length to wait between playing mid_sounds
start_sound (soundfile) Played before starting the mid_sounds loop
start_length (num) How long to wait before starting the main loop after playing start_sound
end_sound (soundfile) The sound played after the main loop has concluded
chance (num) Chance per loop to play a mid_sound
volume (num) Sound output volume
muted (bool) Private. Used to stop the sound loop.
max_loops (num) The max amount of loops to run for.
*/
/datum/looping_sound
var/list/atom/output_atoms
var/mid_sounds
var/mid_length
var/start_sound
var/start_length
var/end_sound
var/chance
var/volume
var/muted = TRUE
var/max_loops
/datum/looping_sound/New(list/_output_atoms, start_immediately=FALSE)
if(!mid_sounds)
WARNING("A looping sound datum was created without sounds to play.")
return
if(_output_atoms)
output_atoms = _output_atoms
else
output_atoms = list()
if(start_immediately)
start()
/datum/looping_sound/Destroy()
stop()
output_atoms = null
return ..()
/datum/looping_sound/proc/start()
if(!muted)
return
muted = FALSE
on_start()
/datum/looping_sound/proc/stop()
if(muted)
return
muted = TRUE
/datum/looping_sound/proc/sound_loop(looped=0)
if(muted || (max_loops && looped > max_loops))
on_stop(looped)
return
if(!chance || prob(chance))
play(get_sound(looped))
addtimer(CALLBACK(src, .proc/sound_loop, ++looped), mid_length)
/datum/looping_sound/proc/play(soundfile)
var/list/atoms_cache = output_atoms
for(var/i in 1 to atoms_cache.len)
var/atom/thing = atoms_cache[i]
playsound(thing, soundfile, volume)
/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
if(!_mid_sounds)
. = mid_sounds
else
. = _mid_sounds
while(!isfile(.) && !isnull(.))
. = pickweight(.)
/datum/looping_sound/proc/on_start()
var/start_wait = 0
if(start_sound)
play(start_sound)
start_wait = start_length
addtimer(CALLBACK(src, .proc/sound_loop), start_wait)
/datum/looping_sound/proc/on_stop(looped)
if(end_sound)
play(end_sound)
@@ -0,0 +1,9 @@
/datum/looping_sound/showering
start_sound = 'sound/machines/shower/shower_start.ogg'
start_length = 2
mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1)
mid_length = 10
end_sound = 'sound/machines/shower/shower_end.ogg'
volume = 25
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+6 -3
View File
@@ -358,9 +358,12 @@
for (var/obj/O in oview(1, A))
if (O.density == 1)
if (O == A) continue
if (O == D) continue
if (O.opacity) continue
if (O == A)
continue
if (O == D)
continue
if (O.opacity)
continue
else
surface = O
ST = get_turf(O)
+47 -80
View File
@@ -147,6 +147,10 @@
qdel(A)
return
LAZYADD(antag_datums, A)
A.create_team(team)
var/datum/objective_team/antag_team = A.get_team()
if(antag_team)
antag_team.add_member(src)
A.on_gain()
return A
@@ -227,15 +231,9 @@
remove_antag_equip()
/datum/mind/proc/remove_rev()
if(src in SSticker.mode.revolutionaries)
SSticker.mode.revolutionaries -= src
SSticker.mode.update_rev_icons_removed(src)
if(src in SSticker.mode.head_revolutionaries)
SSticker.mode.head_revolutionaries -= src
SSticker.mode.update_rev_icons_removed(src)
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
remove_antag_datum(rev.type)
special_role = null
remove_objectives()
remove_antag_equip()
/datum/mind/proc/remove_antag_equip()
var/list/Mob_Contents = current.get_contents()
@@ -258,7 +256,6 @@
SSticker.mode.update_changeling_icons_removed(src)
SSticker.mode.update_traitor_icons_removed(src)
SSticker.mode.update_cult_icons_removed(src)
SSticker.mode.update_rev_icons_removed(src)
/datum/mind/proc/equip_traitor(var/employer = "The Syndicate", var/silent = FALSE)
if(!current)
@@ -302,7 +299,8 @@
uplink_loc = R
if (!uplink_loc)
if(!silent) to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
if(!silent)
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)
@@ -312,19 +310,22 @@
if(uplink_loc == R)
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
if(!silent) 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.")
if(!silent)
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(GLOB.phonetic_alphabet)]"
if(!silent) 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.")
if(!silent)
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)
if(!silent) 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.")
if(!silent)
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]).")
//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does.
@@ -333,8 +334,9 @@
if(iscultist(creator))
SSticker.mode.add_cultist(src)
else if(is_revolutionary_in_general(creator))
SSticker.mode.add_revolutionary(src)
else if(is_revolutionary(creator))
var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev)
converter.add_revolutionary(src,FALSE)
else if(is_servant_of_ratvar(creator))
add_servant_of_ratvar(current)
@@ -549,9 +551,10 @@
text = "<i><b>[text]</b></i>: "
if (assigned_role in GLOB.command_positions)
text += "<b>HEAD</b> | not mindshielded | employee | headrev | rev"
else if (src in SSticker.mode.head_revolutionaries)
else if (has_antag_datum(/datum/antagonist/rev/head))
var/datum/antagonist/rev/head = has_antag_datum(/datum/antagonist/rev/head)
var/last_healthy_headrev = TRUE
for(var/datum/mind/I in SSticker.mode.head_revolutionaries)
for(var/datum/mind/I in head.rev_team.head_revolutionaries())
if(I == src)
continue
var/mob/M = I.current
@@ -576,7 +579,7 @@
text += "<br>Objectives are empty! <a href='?src=\ref[src];revolution=autoobjectives'>Set to kill all heads</a>."
else if(current.isloyal())
text += "head | <b>MINDSHIELDED</b> | employee | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | rev"
else if (src in SSticker.mode.revolutionaries)
else if (has_antag_datum(/datum/antagonist/rev))
text += "head | not mindshielded | <a href='?src=\ref[src];revolution=clear'>employee</a> | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | <b>REV</b>"
else
text += "head | not mindshielded | <b>EMPLOYEE</b> | <a href='?src=\ref[src];revolution=headrev'>headrev</a> | <a href='?src=\ref[src];revolution=rev'>rev</a>"
@@ -721,8 +724,7 @@
out += sections[i]+"<br>"
if(((src in SSticker.mode.head_revolutionaries) || (src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current))
if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current))
text = "Uplink: <a href='?src=\ref[src];common=uplink'>give</a>"
var/obj/item/device/uplink/U = find_syndicate_uplink()
if(U)
@@ -938,57 +940,41 @@
switch(href_list["revolution"])
if("clear")
remove_rev()
to_chat(current, "<span class='userdanger'>You have been brainwashed! You are no longer a revolutionary!</span>")
message_admins("[key_name_admin(usr)] has de-rev'ed [current].")
log_admin("[key_name(usr)] has de-rev'ed [current].")
if("rev")
if(src in SSticker.mode.head_revolutionaries)
SSticker.mode.head_revolutionaries -= src
SSticker.mode.update_rev_icons_removed(src)
to_chat(current, "<span class='userdanger'>Revolution has been disappointed of your leader traits! You are a regular revolutionary now!</span>")
else if(!(src in SSticker.mode.revolutionaries))
to_chat(current, "<span class='danger'><FONT size = 3> You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!</FONT></span>")
if(has_antag_datum(/datum/antagonist/rev/head))
var/datum/antagonist/rev/head/head = has_antag_datum(/datum/antagonist/rev/head)
head.demote()
else if(!has_antag_datum(/datum/antagonist/rev))
add_antag_datum(/datum/antagonist/rev)
special_role = "Revolutionary"
message_admins("[key_name_admin(usr)] has rev'ed [current].")
log_admin("[key_name(usr)] has rev'ed [current].")
else
return
SSticker.mode.revolutionaries += src
SSticker.mode.update_rev_icons_added(src)
special_role = "Revolutionary"
message_admins("[key_name_admin(usr)] has rev'ed [current].")
log_admin("[key_name(usr)] has rev'ed [current].")
if("headrev")
if(src in SSticker.mode.revolutionaries)
SSticker.mode.revolutionaries -= src
SSticker.mode.update_rev_icons_removed(src)
to_chat(current, "<span class='userdanger'>You have proved your devotion to revoltion! Yea are a head revolutionary now!</span>")
else if(!(src in SSticker.mode.head_revolutionaries))
if(has_antag_datum(/datum/antagonist/rev))
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
rev.promote()
else if(!has_antag_datum(/datum/antagonist/rev/head))
//what about the team here.
var/datum/antagonist/rev/head/new_head = new /datum/antagonist/rev/head(src)
new_head.give_flash = TRUE
new_head.give_hud = TRUE
new_head.remove_clumsy = TRUE
add_antag_datum(new_head)
to_chat(current, "<span class='userdanger'>You are a member of the revolutionaries' leadership now!</span>")
else
return
if (SSticker.mode.head_revolutionaries.len>0)
// copy targets
var/datum/mind/valid_head = locate() in SSticker.mode.head_revolutionaries
if (valid_head)
for (var/datum/objective/mutiny/O in valid_head.objectives)
var/datum/objective/mutiny/rev_obj = new
rev_obj.owner = src
rev_obj.target = O.target
rev_obj.explanation_text = "Assassinate [O.target.name], the [O.target.assigned_role]."
objectives += rev_obj
SSticker.mode.greet_revolutionary(src,0)
SSticker.mode.head_revolutionaries += src
SSticker.mode.update_rev_icons_added(src)
special_role = "Head Revolutionary"
message_admins("[key_name_admin(usr)] has head-rev'ed [current].")
log_admin("[key_name(usr)] has head-rev'ed [current].")
if("autoobjectives")
SSticker.mode.forge_revolutionary_objectives(src)
SSticker.mode.greet_revolutionary(src,0)
to_chat(usr, "<span class='notice'>The objectives for revolution have been generated and shown to [key]</span>")
if("flash")
if (!SSticker.mode.equip_revolutionary(current))
var/datum/antagonist/rev/head/head = has_antag_datum(/datum/antagonist/rev/head)
if(!head.equip_rev())
to_chat(usr, "<span class='danger'>Spawning flash failed!</span>")
if("takeflash")
@@ -1447,31 +1433,12 @@
to_chat(H, "Spawning an amulet from your Master failed.")
/datum/mind/proc/make_Rev()
if (SSticker.mode.head_revolutionaries.len>0)
// copy targets
var/datum/mind/valid_head = locate() in SSticker.mode.head_revolutionaries
if (valid_head)
for (var/datum/objective/mutiny/O in valid_head.objectives)
var/datum/objective/mutiny/rev_obj = new
rev_obj.owner = src
rev_obj.target = O.target
rev_obj.explanation_text = "Assassinate [O.target.current.real_name], the [O.target.assigned_role]."
objectives += rev_obj
SSticker.mode.greet_revolutionary(src,0)
SSticker.mode.head_revolutionaries += src
SSticker.mode.update_rev_icons_added(src)
var/datum/antagonist/rev/head/head = new(src)
head.give_flash = TRUE
head.give_hud = TRUE
add_antag_datum(head)
special_role = "Head Revolutionary"
SSticker.mode.forge_revolutionary_objectives(src)
SSticker.mode.greet_revolutionary(src,0)
var/list/L = current.get_contents()
var/obj/item/device/assembly/flash/flash = locate() in L
qdel(flash)
take_uplink()
var/fail = 0
fail |= !SSticker.mode.equip_revolutionary(current)
/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S)
spell_list += S
S.action.Grant(current)
+2 -2
View File
@@ -645,9 +645,9 @@ GLOBAL_LIST_EMPTY(mutations_list)
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
return visual_indicators[1]
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target, mouseparams)
if(owner.a_intent == INTENT_HARM)
owner.LaserEyes(target)
owner.LaserEyes(target, mouseparams)
/mob/living/carbon/proc/update_mutations_overlay()
+1 -1
View File
@@ -89,7 +89,7 @@
continue
thing.rad_act(strength)
var/static/list/blacklisted = typecacheof(list(/turf, /obj/structure/cable, /obj/machinery/atmospherics))
var/static/list/blacklisted = typecacheof(list(/turf, /mob, /obj/structure/cable, /obj/machinery/atmospherics))
if(!can_contaminate || blacklisted[thing.type])
continue
if(prob((strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1/(steps*range_modifier), 1))) // Only stronk rads get to have little baby rads
+1 -1
View File
@@ -261,7 +261,7 @@
var/turf/next = get_step(ridden, direction)
var/turf/current = get_turf(ridden)
if(istype(next, /turf/open/lava) || istype(current, /turf/open/lava)) //We can move from land to lava, or lava to land, but not from land to land
if(islava(next) || islava(current)) //We can move from land to lava, or lava to land, but not from land to land
..()
else
to_chat(user, "Boats don't go on land!")
+7
View File
@@ -255,3 +255,10 @@
suffix = "gondolaasteroid.dmm"
name = "Gondoland"
description = "Just an ordinary rock- wait, what's that thing?"
/datum/map_template/ruin/space/whiteshipruin_box
id = "whiteshipruin_box"
suffix = "whiteshipruin_box.dmm"
name = "NT Medical Ship"
description = "An ancient ship, said to be among the first discovered derelicts near Space Station 13 that was still in working order. \
Aged and deprecated by time, this relic of a vessel is now broken beyond repair."
+1 -5
View File
@@ -433,11 +433,7 @@
playsound(spawn_turf, 'sound/effects/curse2.ogg', 80, 1, -1)
var/turf/ownerloc = get_turf(owner)
var/obj/item/projectile/curse_hand/C = new (spawn_turf)
C.current = spawn_turf
C.starting = spawn_turf
C.yo = ownerloc.y - spawn_turf.y
C.xo = ownerloc.x - spawn_turf.x
C.original = owner
C.preparePixelProjectile(ownerloc, spawn_turf)
C.fire()
/obj/effect/temp_visual/curse
+159 -158
View File
@@ -1,158 +1,159 @@
/datum/wires/airlock
holder_type = /obj/machinery/door/airlock
proper_name = "Airlock"
/datum/wires/airlock/secure
randomize = TRUE
/datum/wires/airlock/New(atom/holder)
wires = list(
WIRE_POWER1, WIRE_POWER2,
WIRE_BACKUP1, WIRE_BACKUP2,
WIRE_OPEN, WIRE_BOLTS, WIRE_IDSCAN, WIRE_AI,
WIRE_SHOCK, WIRE_SAFETY, WIRE_TIMING, WIRE_LIGHT,
WIRE_ZAP1, WIRE_ZAP2
)
add_duds(2)
..()
/datum/wires/airlock/interactable(mob/user)
var/obj/machinery/door/airlock/A = holder
if(!issilicon(user) && A.isElectrified() && A.shock(user, 100))
return FALSE
if(A.panel_open)
return TRUE
/datum/wires/airlock/get_status()
var/obj/machinery/door/airlock/A = holder
var/list/status = list()
status += "The door bolts [A.locked ? "have fallen!" : "look up."]"
status += "The test light is [A.hasPower() ? "on" : "off"]."
status += "The AI connection light is [A.aiControlDisabled || A.emagged ? "off" : "on"]."
status += "The check wiring light is [A.safe ? "off" : "on"]."
status += "The timer is powered [A.autoclose ? "on" : "off"]."
status += "The speed light is [A.normalspeed ? "on" : "off"]."
status += "The emergency light is [A.emergency ? "on" : "off"]."
return status
/datum/wires/airlock/on_pulse(wire)
set waitfor = FALSE
var/obj/machinery/door/airlock/A = holder
switch(wire)
if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power.
A.loseMainPower()
if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power.
A.loseBackupPower()
if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required).
if(A.emagged)
return
if(!A.requiresID() || A.check_access(null))
if(A.density)
A.open()
else
A.close()
if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on).
if(!A.locked)
A.bolt()
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
else
if(A.hasPower())
A.unbolt()
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
A.update_icon()
if(WIRE_IDSCAN) // Pulse to disable emergency access and flash red lights.
if(A.hasPower() && A.density)
A.do_animate("deny")
if(A.emergency)
A.emergency = FALSE
A.update_icon()
if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting).
if(A.aiControlDisabled == 0)
A.aiControlDisabled = 1
else if(A.aiControlDisabled == -1)
A.aiControlDisabled = 2
sleep(10)
if(A)
if(A.aiControlDisabled == 1)
A.aiControlDisabled = 0
else if(A.aiControlDisabled == 2)
A.aiControlDisabled = -1
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
if(!A.secondsElectrified)
A.set_electrified(30)
if(usr)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
add_logs(usr, A, "electrified")
sleep(10)
if(A)
while (A.secondsElectrified > 0)
A.secondsElectrified -= 1
if(A.secondsElectrified < 0)
A.set_electrified(0)
sleep(10)
if(WIRE_SAFETY)
A.safe = !A.safe
if(!A.density)
A.close()
if(WIRE_TIMING)
A.normalspeed = !A.normalspeed
if(WIRE_LIGHT)
A.lights = !A.lights
A.update_icon()
/datum/wires/airlock/on_cut(wire, mend)
var/obj/machinery/door/airlock/A = holder
switch(wire)
if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power.
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
A.regainMainPower()
if(usr)
A.shock(usr, 50)
else
A.loseMainPower()
if(usr)
A.shock(usr, 50)
if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power.
if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2))
A.regainBackupPower()
if(usr)
A.shock(usr, 50)
else
A.loseBackupPower()
if(usr)
A.shock(usr, 50)
if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing.
if(!mend)
A.bolt()
if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable.
if(mend)
if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI
A.aiControlDisabled = 0
else if(A.aiControlDisabled == 2)
A.aiControlDisabled = -1
else
if(A.aiControlDisabled == 0)
A.aiControlDisabled = 1
else if(A.aiControlDisabled == -1)
A.aiControlDisabled = 2
if(WIRE_SHOCK) // Cut to shock the door, mend to unshock.
if(mend)
if(A.secondsElectrified)
A.set_electrified(0)
else
if(A.secondsElectrified != -1)
A.set_electrified(-1)
if(usr)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
add_logs(usr, A, "electrified")
if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable.
A.safe = mend
if(WIRE_TIMING) // Cut to disable auto-close, mend to re-enable.
A.autoclose = mend
if(A.autoclose && !A.density)
A.close()
if(WIRE_LIGHT) // Cut to disable lights, mend to re-enable.
A.lights = mend
A.update_icon()
if(WIRE_ZAP1, WIRE_ZAP2) // Ouch.
A.shock(usr, 50)
/datum/wires/airlock
holder_type = /obj/machinery/door/airlock
proper_name = "Airlock"
/datum/wires/airlock/secure
randomize = TRUE
/datum/wires/airlock/New(atom/holder)
wires = list(
WIRE_POWER1, WIRE_POWER2,
WIRE_BACKUP1, WIRE_BACKUP2,
WIRE_OPEN, WIRE_BOLTS, WIRE_IDSCAN, WIRE_AI,
WIRE_SHOCK, WIRE_SAFETY, WIRE_TIMING, WIRE_LIGHT,
WIRE_ZAP1, WIRE_ZAP2
)
add_duds(2)
..()
/datum/wires/airlock/interactable(mob/user)
var/obj/machinery/door/airlock/A = holder
if(!issilicon(user) && A.isElectrified() && A.shock(user, 100))
return FALSE
if(A.panel_open)
return TRUE
/datum/wires/airlock/get_status()
var/obj/machinery/door/airlock/A = holder
var/list/status = list()
status += "The door bolts [A.locked ? "have fallen!" : "look up."]"
status += "The test light is [A.hasPower() ? "on" : "off"]."
status += "The AI connection light is [A.aiControlDisabled || A.emagged ? "off" : "on"]."
status += "The check wiring light is [A.safe ? "off" : "on"]."
status += "The timer is powered [A.autoclose ? "on" : "off"]."
status += "The speed light is [A.normalspeed ? "on" : "off"]."
status += "The emergency light is [A.emergency ? "on" : "off"]."
return status
/datum/wires/airlock/on_pulse(wire)
set waitfor = FALSE
var/obj/machinery/door/airlock/A = holder
switch(wire)
if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power.
A.loseMainPower()
if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power.
A.loseBackupPower()
if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required).
if(A.emagged)
return
if(!A.requiresID() || A.check_access(null))
if(A.density)
A.open()
else
A.close()
if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on).
if(!A.locked)
A.bolt()
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
else
if(A.hasPower())
A.unbolt()
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
A.update_icon()
if(WIRE_IDSCAN) // Pulse to disable emergency access and flash red lights.
if(A.hasPower() && A.density)
A.do_animate("deny")
if(A.emergency)
A.emergency = FALSE
A.update_icon()
if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting).
if(A.aiControlDisabled == 0)
A.aiControlDisabled = 1
else if(A.aiControlDisabled == -1)
A.aiControlDisabled = 2
sleep(10)
if(A)
if(A.aiControlDisabled == 1)
A.aiControlDisabled = 0
else if(A.aiControlDisabled == 2)
A.aiControlDisabled = -1
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
if(!A.secondsElectrified)
A.set_electrified(30)
if(usr)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
add_logs(usr, A, "electrified")
sleep(10)
if(A)
while (A.secondsElectrified > 0)
A.secondsElectrified -= 1
if(A.secondsElectrified < 0)
A.set_electrified(0)
sleep(10)
if(WIRE_SAFETY)
A.safe = !A.safe
if(!A.density)
A.close()
if(WIRE_TIMING)
A.normalspeed = !A.normalspeed
if(WIRE_LIGHT)
A.lights = !A.lights
A.update_icon()
/datum/wires/airlock/on_cut(wire, mend)
var/obj/machinery/door/airlock/A = holder
switch(wire)
if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power.
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
A.regainMainPower()
if(usr)
A.shock(usr, 50)
else
A.loseMainPower()
if(usr)
A.shock(usr, 50)
if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power.
if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2))
A.regainBackupPower()
if(usr)
A.shock(usr, 50)
else
A.loseBackupPower()
if(usr)
A.shock(usr, 50)
if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing.
if(!mend)
A.bolt()
if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable.
if(mend)
if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI
A.aiControlDisabled = 0
else if(A.aiControlDisabled == 2)
A.aiControlDisabled = -1
else
if(A.aiControlDisabled == 0)
A.aiControlDisabled = 1
else if(A.aiControlDisabled == -1)
A.aiControlDisabled = 2
if(WIRE_SHOCK) // Cut to shock the door, mend to unshock.
if(mend)
if(A.secondsElectrified)
A.set_electrified(0)
else
if(A.secondsElectrified != -1)
A.set_electrified(-1)
if(usr)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
add_logs(usr, A, "electrified")
if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable.
A.safe = mend
if(WIRE_TIMING) // Cut to disable auto-close, mend to re-enable.
A.autoclose = mend
if(A.autoclose && !A.density)
A.close()
if(WIRE_LIGHT) // Cut to disable lights, mend to re-enable.
A.lights = mend
A.update_icon()
if(WIRE_ZAP1, WIRE_ZAP2) // Ouch.
if(usr)
A.shock(usr, 50)