mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 19:47:22 +01:00
Merge branch 'master' into my-nanomaps-cant-be-this-cute
This commit is contained in:
+16
-16
@@ -190,9 +190,6 @@
|
||||
/datum/action/item_action/toggle_mister
|
||||
name = "Toggle Mister"
|
||||
|
||||
/datum/action/item_action/toggle_headphones
|
||||
name = "Toggle Headphones"
|
||||
|
||||
/datum/action/item_action/toggle_helmet_light
|
||||
name = "Toggle Helmet Light"
|
||||
|
||||
@@ -232,19 +229,6 @@
|
||||
button.name = name
|
||||
..()
|
||||
|
||||
/datum/action/item_action/synthswitch
|
||||
name = "Change Synthesizer Instrument"
|
||||
desc = "Change the type of instrument your synthesizer is playing as."
|
||||
|
||||
/datum/action/item_action/synthswitch/Trigger()
|
||||
if(istype(target, /obj/item/instrument/piano_synth))
|
||||
var/obj/item/instrument/piano_synth/synth = target
|
||||
var/chosen = input("Choose the type of instrument you want to use", "Instrument Selection", "piano") as null|anything in synth.insTypes
|
||||
if(!synth.insTypes[chosen])
|
||||
return
|
||||
return synth.changeInstrument(chosen)
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/vortex_recall
|
||||
name = "Vortex Recall"
|
||||
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
|
||||
@@ -257,6 +241,9 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/change_headphones_song
|
||||
name = "Change Headphones Song"
|
||||
|
||||
/datum/action/item_action/toggle
|
||||
|
||||
/datum/action/item_action/toggle/New(Target)
|
||||
@@ -463,6 +450,7 @@
|
||||
/datum/action/spell_action
|
||||
check_flags = 0
|
||||
background_icon_state = "bg_spell"
|
||||
var/recharge_text_color = "#FFFFFF"
|
||||
|
||||
/datum/action/spell_action/New(Target)
|
||||
..()
|
||||
@@ -500,6 +488,18 @@
|
||||
return spell.can_cast(owner)
|
||||
return 0
|
||||
|
||||
/datum/action/spell_action/UpdateButtonIcon()
|
||||
if(button && !(. = ..()))
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
if(!istype(S))
|
||||
return
|
||||
var/progress = S.get_availability_percentage()
|
||||
var/col_val_high = 72 * progress + 128
|
||||
var/col_val_low = 200 * progress
|
||||
button.maptext = "<div style=\"font-size:6pt;color:[recharge_text_color];font:'Small Fonts';text-align:center;\" valign=\"bottom\">[round_down(progress * 100)]%</div>"
|
||||
button.color = rgb(col_val_high, col_val_low, col_val_low, col_val_high)
|
||||
else
|
||||
button.maptext = null
|
||||
/*
|
||||
/datum/action/spell_action/alien
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover))
|
||||
return
|
||||
|
||||
if((H.flying) || H.buckled)
|
||||
if(H.flying || H.floating || H.buckled)
|
||||
return
|
||||
|
||||
var/damage = rand(min_damage, max_damage)
|
||||
|
||||
@@ -47,23 +47,30 @@
|
||||
return
|
||||
if(!isturf(target))
|
||||
return
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
var/turf/source_turf = get_turf(I)
|
||||
var/turf/target_turf = target
|
||||
var/list/clickparams = params2list(params)
|
||||
var/x_offset = text2num(clickparams["icon-x"]) - 16
|
||||
var/y_offset = text2num(clickparams["icon-y"]) - 16
|
||||
var/x_offset
|
||||
var/y_offset
|
||||
if(target_turf != get_turf(I)) //Trying to stick it on a wall, don't move it to the actual wall or you can move the item through it. Instead set the pixels as appropriate
|
||||
var/target_direction = get_dir(source_turf, target_turf)//The direction we clicked
|
||||
// Snowflake diagonal handling
|
||||
if(target_direction in GLOB.diagonals)
|
||||
to_chat(user, "<span class='warning'>You cant reach [target_turf].</span>")
|
||||
return
|
||||
if(target_direction & EAST)
|
||||
x_offset += 32
|
||||
x_offset = 16
|
||||
y_offset = rand(-12, 12)
|
||||
else if(target_direction & WEST)
|
||||
x_offset -= 32
|
||||
if(target_direction & NORTH)
|
||||
y_offset += 32
|
||||
x_offset = -16
|
||||
y_offset = rand(-12, 12)
|
||||
else if(target_direction & NORTH)
|
||||
x_offset = rand(-12, 12)
|
||||
y_offset = 16
|
||||
else if(target_direction & SOUTH)
|
||||
y_offset -= 32
|
||||
x_offset = rand(-12, 12)
|
||||
y_offset = -16
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You stick [I] to [target_turf].</span>")
|
||||
I.pixel_x = x_offset
|
||||
I.pixel_y = y_offset
|
||||
|
||||
@@ -51,6 +51,6 @@
|
||||
Additionally calls the parent's `after_slip()` proc on the `victim`.
|
||||
*/
|
||||
/datum/component/slippery/proc/Slip(datum/source, mob/living/carbon/human/victim)
|
||||
if(istype(victim) && prob(slip_chance) && victim.slip(description, stun, weaken, slip_tiles, walking_is_safe, slip_always, slip_verb))
|
||||
if(istype(victim) && !victim.flying && prob(slip_chance) && victim.slip(description, stun, weaken, slip_tiles, walking_is_safe, slip_always, slip_verb))
|
||||
var/atom/movable/owner = parent
|
||||
owner.after_slip(victim)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/datum/component/spooky
|
||||
var/too_spooky = TRUE //will it spawn a new instrument?
|
||||
|
||||
/datum/component/spooky/Initialize()
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
|
||||
|
||||
/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user)
|
||||
if(ishuman(user)) //this weapon wasn't meant for mortals.
|
||||
var/mob/living/carbon/human/U = user
|
||||
if(!istype(U.dna.species, /datum/species/skeleton))
|
||||
U.adjustStaminaLoss(35) //Extra Damage
|
||||
U.Jitter(35)
|
||||
U.stuttering = 20
|
||||
if(U.getStaminaLoss() > 95)
|
||||
to_chat(U, "<font color='red' size='4'><b>Your ears weren't meant for this spectral sound.</b></font>")
|
||||
spectral_change(U)
|
||||
return
|
||||
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(istype(H.dna.species, /datum/species/skeleton))
|
||||
return //undeads are unaffected by the spook-pocalypse.
|
||||
C.Jitter(35)
|
||||
C.stuttering = 20
|
||||
if(!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman))
|
||||
C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live
|
||||
to_chat(C, "<font color='red' size='4'><B>DOOT</B></font>")
|
||||
spectral_change(H)
|
||||
|
||||
else //the sound will spook monkeys.
|
||||
C.Jitter(15)
|
||||
C.stuttering = 20
|
||||
|
||||
/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user)
|
||||
if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/diona) && !istype(H.dna.species, /datum/species/machine) && !istype(H.dna.species, /datum/species/slime) && !istype(H.dna.species, /datum/species/golem) && !istype(H.dna.species, /datum/species/plasmaman) && !istype(H.dna.species, /datum/species/skeleton)))
|
||||
H.Stun(20)
|
||||
H.set_species(/datum/species/skeleton)
|
||||
H.visible_message("<span class='warning'>[H] has given up on life as a mortal.</span>")
|
||||
var/T = get_turf(H)
|
||||
if(too_spooky)
|
||||
if(prob(30))
|
||||
new/obj/item/instrument/saxophone/spectral(T)
|
||||
else if(prob(30))
|
||||
new/obj/item/instrument/trumpet/spectral(T)
|
||||
else if(prob(30))
|
||||
new/obj/item/instrument/trombone/spectral(T)
|
||||
else
|
||||
to_chat(H, "<span class='boldwarning'>The spooky gods forgot to ship your instrument. Better luck next unlife.</span>")
|
||||
to_chat(H, "<span class='boldnotice'>You are the spooky skeleton!</span>")
|
||||
to_chat(H, "<span class='boldnotice'>A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.</span>")
|
||||
change_name(H) //time for a new name!
|
||||
|
||||
/datum/component/spooky/proc/change_name(mob/living/carbon/human/H)
|
||||
var/t = stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN)
|
||||
if(!t)
|
||||
t = "spooky skeleton"
|
||||
H.real_name = t
|
||||
H.name = t
|
||||
@@ -67,6 +67,14 @@
|
||||
var/obj/item/projectile/P = AM
|
||||
if(P.original != parent)
|
||||
return
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.flying)
|
||||
return
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = M
|
||||
if(L.floating)
|
||||
return
|
||||
var/atom/current_parent = parent
|
||||
if(isturf(current_parent.loc))
|
||||
play_squeak()
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
W.plane = initial(W.plane)
|
||||
W.loc = affected_mob.loc
|
||||
W.dropped(affected_mob)
|
||||
if(isobj(affected_mob.loc))
|
||||
var/obj/O = affected_mob.loc
|
||||
O.force_eject_occupant()
|
||||
var/mob/living/new_mob = new new_form(affected_mob.loc)
|
||||
if(istype(new_mob))
|
||||
new_mob.a_intent = "harm"
|
||||
|
||||
@@ -191,6 +191,10 @@
|
||||
..()
|
||||
desc = "That's Definitely Not [M.real_name]."
|
||||
|
||||
/datum/dog_fashion/head/cone
|
||||
name = "REAL_NAME"
|
||||
desc = "Omnicone's Chosen Champion"
|
||||
|
||||
/datum/dog_fashion/back/hardsuit
|
||||
name = "Space Explorer REAL_NAME"
|
||||
desc = "That's one small step for a corgi. One giant yap for corgikind."
|
||||
@@ -200,3 +204,7 @@
|
||||
D.mutations.Add(BREATHLESS)
|
||||
D.atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
D.minbodytemp = 0
|
||||
|
||||
/datum/dog_fashion/head/fried_vox_empty
|
||||
name = "Colonel REAL_NAME"
|
||||
desc = "Keep away from live vox."
|
||||
|
||||
@@ -152,13 +152,11 @@
|
||||
return doTeleport()
|
||||
return 0
|
||||
|
||||
/datum/teleport/instant //teleports when datum is created
|
||||
|
||||
start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
|
||||
if(..())
|
||||
if(teleport())
|
||||
return 1
|
||||
return 0
|
||||
/datum/teleport/instant/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
|
||||
if(..())
|
||||
if(teleport())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/teleport/instant/science
|
||||
|
||||
+32
-13
@@ -3,32 +3,51 @@
|
||||
var/raw_time // When did this happen?
|
||||
var/what // What happened
|
||||
var/who // Who did it
|
||||
var/target // Who/what was targeted (can be a string)
|
||||
var/turf/where // Where did it happen
|
||||
var/target // Who/what was targeted
|
||||
var/where // Where did it happen
|
||||
|
||||
/datum/log_record/New(_log_type, _who, _what, _target, _where, _raw_time)
|
||||
log_type = _log_type
|
||||
|
||||
who = get_subject_text(_who)
|
||||
|
||||
who = get_subject_text(_who, _log_type)
|
||||
what = _what
|
||||
target = get_subject_text(_target)
|
||||
if(!_where)
|
||||
target = get_subject_text(_target, _log_type)
|
||||
if(!istext(_where) && !isturf(_where))
|
||||
_where = get_turf(_who)
|
||||
where = _where
|
||||
if(isturf(_where))
|
||||
var/turf/T = _where
|
||||
where = ADMIN_COORDJMP(T)
|
||||
else
|
||||
where = _where
|
||||
if(!_raw_time)
|
||||
_raw_time = world.time
|
||||
raw_time = _raw_time
|
||||
|
||||
/datum/log_record/proc/get_subject_text(subject)
|
||||
/datum/log_record/proc/get_subject_text(subject, log_type)
|
||||
if(ismob(subject) || isclient(subject) || istype(subject, /datum/mind))
|
||||
return key_name_admin(subject)
|
||||
if(isatom(subject))
|
||||
. = key_name_admin(subject)
|
||||
if(should_log_health(log_type) && isliving(subject))
|
||||
. += get_health_string(subject)
|
||||
else if(isatom(subject))
|
||||
var/atom/A = subject
|
||||
return A.name
|
||||
if(istype(subject, /datum))
|
||||
. = A.name
|
||||
else if(istype(subject, /datum))
|
||||
var/datum/D = subject
|
||||
return D.type
|
||||
return subject
|
||||
else
|
||||
. = subject
|
||||
|
||||
/datum/log_record/proc/get_health_string(var/mob/living/L)
|
||||
var/OX = L.getOxyLoss() > 50 ? "<b>[L.getOxyLoss()]</b>" : L.getOxyLoss()
|
||||
var/TX = L.getToxLoss() > 50 ? "<b>[L.getToxLoss()]</b>" : L.getToxLoss()
|
||||
var/BU = L.getFireLoss() > 50 ? "<b>[L.getFireLoss()]</b>" : L.getFireLoss()
|
||||
var/BR = L.getBruteLoss() > 50 ? "<b>[L.getBruteLoss()]</b>" : L.getBruteLoss()
|
||||
return " ([L.health]: <font color='deepskyblue'>[OX]</font> - <font color='green'>[TX]</font> - <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>)"
|
||||
|
||||
/datum/log_record/proc/should_log_health(log_type)
|
||||
if(log_type == ATTACK_LOG || log_type == DEFENSE_LOG)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/proc/compare_log_record(datum/log_record/A, datum/log_record/B)
|
||||
var/time_diff = A.raw_time - B.raw_time
|
||||
|
||||
+108
-24
@@ -1,31 +1,45 @@
|
||||
#define ALL_LOGS list(ATTACK_LOG, DEFENSE_LOG, CONVERSION_LOG, SAY_LOG, EMOTE_LOG, MISC_LOG)
|
||||
#define UPDATE_CKEY_MOB(__ckey) var/mob/result = selected_ckeys_mobs[__ckey];\
|
||||
if(!result || result.ckey != __ckey){\
|
||||
result = get_mob_by_ckey(__ckey);\
|
||||
selected_ckeys_mobs[__ckey] = result;\
|
||||
}
|
||||
|
||||
#define RECORD_WARN_LIMIT 1000
|
||||
#define RECORD_HARD_LIMIT 2500
|
||||
|
||||
/datum/log_viewer
|
||||
var/time_from = 0
|
||||
var/time_to = 4 HOURS // 4 Hours should be enough. INFINITY would screw the UI up
|
||||
var/list/selected_mobs = list() // The mobs in question
|
||||
var/list/selected_log_types = list() // The log types being searched for
|
||||
|
||||
var/list/selected_mobs = list() // The mobs in question.
|
||||
var/list/selected_ckeys = list() // The ckeys selected to search for. Will show all mobs the ckey is attached to
|
||||
var/list/mob/selected_ckeys_mobs = list()
|
||||
var/list/selected_log_types = ALL_LOGS // The log types being searched for
|
||||
var/list/log_records = list() // Found and sorted records
|
||||
|
||||
/datum/log_viewer/proc/clear_all()
|
||||
selected_mobs.Cut()
|
||||
selected_log_types.Cut()
|
||||
selected_log_types = ALL_LOGS
|
||||
selected_ckeys.Cut()
|
||||
selected_ckeys_mobs.Cut()
|
||||
time_from = initial(time_from)
|
||||
time_to = initial(time_to)
|
||||
log_records.Cut()
|
||||
return
|
||||
|
||||
/datum/log_viewer/proc/search()
|
||||
/datum/log_viewer/proc/search(user)
|
||||
log_records.Cut() // Empty the old results
|
||||
var/list/invalid_mobs = list()
|
||||
var/list/ckeys = selected_ckeys.Copy()
|
||||
for(var/i in selected_mobs)
|
||||
var/mob/M = i
|
||||
if(!M || QDELETED(M))
|
||||
if(!M || QDELETED(M) || !M.last_known_ckey)
|
||||
invalid_mobs |= M
|
||||
continue
|
||||
ckeys |= M.last_known_ckey
|
||||
|
||||
for(var/ckey in ckeys)
|
||||
for(var/log_type in selected_log_types)
|
||||
var/list/logs = M.logs[log_type]
|
||||
var/list/logs = GLOB.logging.get_logs_by_type(ckey, log_type)
|
||||
var/len_logs = length(logs)
|
||||
if(len_logs)
|
||||
var/start_index = get_earliest_log_index(logs)
|
||||
@@ -36,8 +50,8 @@
|
||||
continue
|
||||
log_records.Add(logs.Copy(start_index, end_index + 1))
|
||||
|
||||
if(invalid_mobs.len)
|
||||
to_chat(usr, "<span class='warning'>The search criteria contained invalid mobs. They have been removed from the criteria.</span>")
|
||||
if(length(invalid_mobs))
|
||||
to_chat(user, "<span class='warning'>The search criteria contained invalid mobs. They have been removed from the criteria.</span>")
|
||||
for(var/i in invalid_mobs)
|
||||
selected_mobs -= i // Cleanup
|
||||
|
||||
@@ -91,9 +105,23 @@
|
||||
return start
|
||||
return 0
|
||||
|
||||
/datum/log_viewer/proc/add_mob(mob/user, mob/M)
|
||||
/datum/log_viewer/proc/add_mobs(list/mob/mobs)
|
||||
if(!length(mobs))
|
||||
return
|
||||
for(var/i in mobs)
|
||||
add_mob(usr, i, FALSE)
|
||||
|
||||
/datum/log_viewer/proc/add_ckey(mob/user, ckey)
|
||||
if(!user || !ckey)
|
||||
return
|
||||
selected_ckeys |= ckey
|
||||
UPDATE_CKEY_MOB(ckey)
|
||||
show_ui(user)
|
||||
|
||||
/datum/log_viewer/proc/add_mob(mob/user, mob/M, show_the_ui = TRUE)
|
||||
if(!M || !user)
|
||||
return
|
||||
|
||||
selected_mobs |= M
|
||||
|
||||
show_ui(user)
|
||||
@@ -102,9 +130,9 @@
|
||||
var/all_log_types = ALL_LOGS
|
||||
var/trStyleTop = "border-top:2px solid; border-bottom:2px solid; padding-top: 5px; padding-bottom: 5px;"
|
||||
var/trStyle = "border-top:1px solid; border-bottom:1px solid; padding-top: 5px; padding-bottom: 5px;"
|
||||
var/dat
|
||||
dat += "<head><style>.adminticket{border:2px solid} td{border:1px solid grey;} th{border:1px solid grey;} span{float:left;width:150px;}</style></head>"
|
||||
dat += "<div style='height:15vh'>"
|
||||
var/list/dat = list()
|
||||
dat += "<head><meta http-equiv='X-UA-Compatible' content='IE=edge'><style>.adminticket{border:2px solid} td{border:1px solid grey;} th{border:1px solid grey;} span{float:left;width:150px;}</style></head>"
|
||||
dat += "<div style='min-height:100px'>"
|
||||
dat += "<span>Time Search Range:</span> <a href='?src=[UID()];start_time=1'>[gameTimestamp(wtime = time_from)]</a>"
|
||||
dat += " To: <a href='?src=[UID()];end_time=1'>[gameTimestamp(wtime = time_to)]</a>"
|
||||
dat += "<BR>"
|
||||
@@ -115,20 +143,26 @@
|
||||
if(QDELETED(M))
|
||||
selected_mobs -= i
|
||||
continue
|
||||
dat += "<a href='?src=[UID()];remove_mob=\ref[M]'>[M.name]</a>"
|
||||
dat += "<a href='?src=[UID()];remove_mob=\ref[M]'>[get_display_name(M)]</a>"
|
||||
dat += "<a href='?src=[UID()];add_mob=1'>Add Mob</a>"
|
||||
dat += "<a href='?src=[UID()];clear_mobs=1'>Clear All Mobs</a>"
|
||||
dat += "<BR>"
|
||||
|
||||
dat += "<span>Ckeys being used:</span>"
|
||||
for(var/ckey in selected_ckeys)
|
||||
dat += "<a href='?src=[UID()];remove_ckey=[ckey]'>[get_ckey_name(ckey)]</a>"
|
||||
dat += "<a href='?src=[UID()];add_ckey=1'>Add ckey</a>"
|
||||
dat += "<a href='?src=[UID()];clear_ckeys=1'>Clear All ckeys</a>"
|
||||
dat += "<BR>"
|
||||
|
||||
dat += "<span>Log Types:</span>"
|
||||
for(var/i in all_log_types)
|
||||
var/log_type = i
|
||||
for(var/log_type in all_log_types)
|
||||
var/enabled = (log_type in selected_log_types)
|
||||
var/text
|
||||
var/style
|
||||
if(enabled)
|
||||
text = "<b>[log_type]</b>"
|
||||
style = "background: [get_logtype_color(i)]"
|
||||
style = "background: [get_logtype_color(log_type)]"
|
||||
else
|
||||
text = log_type
|
||||
|
||||
@@ -142,9 +176,9 @@
|
||||
// Search results
|
||||
var/tdStyleTime = "width:80px; text-align:center;"
|
||||
var/tdStyleType = "width:80px; text-align:center;"
|
||||
var/tdStyleWho = "width:300px; text-align:center;"
|
||||
var/tdStyleWho = "width:400px; text-align:center;"
|
||||
var/tdStyleWhere = "width:150px; text-align:center;"
|
||||
dat += "<div style='overflow-y: auto; max-height:76vh;'>"
|
||||
dat += "<div style='overflow-y: auto; max-height:calc(100vh - 150px);'>"
|
||||
dat += "<table style='width:100%; border: 1px solid;'>"
|
||||
dat += "<tr style='[trStyleTop]'><th style='[tdStyleTime]'>When</th><th style='[tdStyleType]'>Type</th><th style='[tdStyleWho]'>Who</th><th>What</th><th>Target</th><th style='[tdStyleWhere]'>Where</th></tr>"
|
||||
for(var/i in log_records)
|
||||
@@ -153,13 +187,12 @@
|
||||
|
||||
dat +="<tr style='[trStyle]'><td style='[tdStyleTime]'>[time]</td><td style='[tdStyleType]background: [get_logtype_color(L.log_type)]'>[L.log_type]</td>\
|
||||
<td style='[tdStyleWho]'>[L.who]</td><td style='background: [get_logtype_color(L.log_type)];'>[L.what]</td>\
|
||||
<td style='[tdStyleWho]'>[L.target]</td><td style='[tdStyleWhere]'>[ADMIN_COORDJMP(L.where)]</td></tr>"
|
||||
|
||||
<td style='[tdStyleWho]'>[L.target]</td><td style='[tdStyleWhere]'>[L.where]</td></tr>"
|
||||
dat += "</table>"
|
||||
dat += "</div>"
|
||||
|
||||
var/datum/browser/popup = new(user, "Log viewer", "Log viewer", 1400, 600)
|
||||
popup.set_content(dat)
|
||||
var/datum/browser/popup = new(user, "Log Viewer", "Log Viewer", 1500, 600)
|
||||
popup.set_content(dat.Join())
|
||||
popup.open()
|
||||
|
||||
/datum/log_viewer/Topic(href, href_list)
|
||||
@@ -188,6 +221,19 @@
|
||||
return
|
||||
if(href_list["search"])
|
||||
search(usr)
|
||||
var/records_len = length(log_records)
|
||||
if(records_len > RECORD_WARN_LIMIT)
|
||||
var/datum/log_record/last_record = log_records[RECORD_WARN_LIMIT]
|
||||
var/last_time = gameTimestamp(wtime = last_record.raw_time - 9.99)
|
||||
var/answer = alert(usr, "More than [RECORD_WARN_LIMIT] records were found. continuing will take a long time. This won't cause much lag for the server. Time at the [RECORD_WARN_LIMIT]th record '[last_time]'", "Warning", "Continue", "Limit to [RECORD_WARN_LIMIT]", "Cancel")
|
||||
if(answer == "Limit to [RECORD_WARN_LIMIT]")
|
||||
log_records.Cut(RECORD_WARN_LIMIT)
|
||||
else if(answer == "Cancel")
|
||||
log_records.Cut()
|
||||
else
|
||||
if(records_len > RECORD_HARD_LIMIT)
|
||||
to_chat(usr, "<span class='warning'>Record limit reached. Limiting to [RECORD_HARD_LIMIT].</span>")
|
||||
log_records.Cut(RECORD_HARD_LIMIT)
|
||||
show_ui(usr)
|
||||
return
|
||||
if(href_list["clear_all"])
|
||||
@@ -198,17 +244,31 @@
|
||||
selected_mobs.Cut()
|
||||
show_ui(usr)
|
||||
return
|
||||
if(href_list["clear_ckeys"])
|
||||
selected_ckeys.Cut()
|
||||
selected_ckeys_mobs.Cut()
|
||||
show_ui(usr)
|
||||
return
|
||||
if(href_list["add_mob"])
|
||||
var/list/mobs = getpois(TRUE, TRUE)
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a mob: ", mobs)
|
||||
A.on_close(CALLBACK(src, .proc/add_mob, usr))
|
||||
return
|
||||
if(href_list["add_ckey"])
|
||||
var/list/ckeys = GLOB.logging.get_ckeys_logged()
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a ckey: ", ckeys)
|
||||
A.on_close(CALLBACK(src, .proc/add_ckey, usr))
|
||||
return
|
||||
if(href_list["remove_mob"])
|
||||
var/mob/M = locate(href_list["remove_mob"])
|
||||
if(M)
|
||||
selected_mobs -= M
|
||||
show_ui(usr)
|
||||
return
|
||||
if(href_list["remove_ckey"])
|
||||
selected_ckeys -= href_list["remove_ckey"]
|
||||
show_ui(usr)
|
||||
return
|
||||
if(href_list["toggle_log_type"])
|
||||
var/log_type = href_list["toggle_log_type"]
|
||||
if(log_type in selected_log_types)
|
||||
@@ -232,4 +292,28 @@
|
||||
return "deepskyblue"
|
||||
if(MISC_LOG)
|
||||
return "gray"
|
||||
if(DEADCHAT_LOG)
|
||||
return "#cc00c6"
|
||||
if(OOC_LOG)
|
||||
return "#002eb8"
|
||||
if(LOOC_LOG)
|
||||
return "#6699CC"
|
||||
return "slategray"
|
||||
|
||||
/datum/log_viewer/proc/get_display_name(mob/M)
|
||||
var/name = M.name
|
||||
if(M.name != M.real_name)
|
||||
name = "[name] ([M.real_name])"
|
||||
if(isobserver(M))
|
||||
name = "[name] (DEAD)"
|
||||
return "\[[M.last_known_ckey]\] [name]"
|
||||
|
||||
/datum/log_viewer/proc/get_ckey_name(ckey)
|
||||
UPDATE_CKEY_MOB(ckey)
|
||||
var/mob/M = selected_ckeys_mobs[ckey]
|
||||
|
||||
return get_display_name(M)
|
||||
|
||||
#undef UPDATE_CKEY_MOB
|
||||
#undef RECORD_WARN_LIMIT
|
||||
#undef RECORD_HARD_LIMIT
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/datum/logging
|
||||
var/list/datum/log_record/logs = list() // Assoc list of assoc lists (ckey, (log_type, list/logs))
|
||||
|
||||
/datum/logging/proc/add_log(ckey, datum/log_record/log)
|
||||
if(!ckey)
|
||||
log_debug("GLOB.logging.add_log called with an invalid ckey")
|
||||
return
|
||||
|
||||
if(!logs[ckey])
|
||||
logs[ckey] = list()
|
||||
|
||||
var/list/log_types_list = logs[ckey]
|
||||
|
||||
if(!log_types_list[log.log_type])
|
||||
log_types_list[log.log_type] = list()
|
||||
|
||||
var/list/datum/log_record/log_records = log_types_list[log.log_type]
|
||||
log_records.Add(log)
|
||||
|
||||
/datum/logging/proc/get_ckeys_logged()
|
||||
var/list/ckeys = list()
|
||||
for(var/ckey in logs)
|
||||
ckeys.Add(ckey)
|
||||
return ckeys
|
||||
|
||||
/* Returns the logs of a given ckey and log_type
|
||||
* If no logs exist it will return an empty list
|
||||
*/
|
||||
/datum/logging/proc/get_logs_by_type(ckey, log_type)
|
||||
if(!ckey)
|
||||
log_debug("GLOB.logging.get_logs_by_type called with an invalid ckey")
|
||||
return
|
||||
if(!log_type || !(log_type in ALL_LOGS))
|
||||
log_debug("GLOB.logging.get_logs_by_type called with an invalid log_type '[log_type]'")
|
||||
return
|
||||
|
||||
var/list/log_types_list = logs[ckey]
|
||||
// Check if logs exist for the ckey
|
||||
if(!length(log_types_list))
|
||||
return list()
|
||||
|
||||
var/list/datum/log_record/log_records = log_types_list[log_type]
|
||||
|
||||
// Check if logs exist for this type
|
||||
if(!log_records)
|
||||
return list()
|
||||
return log_records
|
||||
@@ -71,7 +71,7 @@
|
||||
var/list/atoms_cache = output_atoms
|
||||
var/sound/S = sound(soundfile)
|
||||
if(direct)
|
||||
S.channel = open_sound_channel()
|
||||
S.channel = SSsounds.random_available_channel()
|
||||
S.volume = volume
|
||||
for(var/i in 1 to atoms_cache.len)
|
||||
var/atom/thing = atoms_cache[i]
|
||||
|
||||
+6
-13
@@ -100,14 +100,6 @@
|
||||
current.mind = null
|
||||
leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it
|
||||
|
||||
for(var/log_type in current.logs) // Copy the old logs
|
||||
var/list/logs = current.logs[log_type]
|
||||
if(new_character.logs[log_type])
|
||||
new_character.logs[log_type] += logs.Copy() // Append the old ones
|
||||
new_character.logs[log_type] = sortTim(new_character.logs[log_type], /proc/compare_log_record) // Sort them on time
|
||||
else
|
||||
new_character.logs[log_type] = logs.Copy() // Just copy them
|
||||
|
||||
SSnanoui.user_transferred(current, new_character)
|
||||
|
||||
if(new_character.mind) //remove any mind currently in our new body's mind variable
|
||||
@@ -922,7 +914,7 @@
|
||||
log_admin("[key_name(usr)] has equipped [key_name(current)] as a wizard")
|
||||
message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a wizard")
|
||||
if("name")
|
||||
SSticker.mode.name_wizard(current)
|
||||
INVOKE_ASYNC(SSticker.mode, /datum/game_mode/wizard.proc/name_wizard, current)
|
||||
log_admin("[key_name(usr)] has allowed wizard [key_name(current)] to name themselves")
|
||||
message_admins("[key_name_admin(usr)] has allowed wizard [key_name_admin(current)] to name themselves")
|
||||
if("autoobjectives")
|
||||
@@ -1419,9 +1411,10 @@
|
||||
return A
|
||||
|
||||
/datum/mind/proc/announce_objectives()
|
||||
to_chat(current, "<span class='notice'>Your current objectives:</span>")
|
||||
for(var/line in splittext(gen_objective_text(), "<br>"))
|
||||
to_chat(current, line)
|
||||
if(current)
|
||||
to_chat(current, "<span class='notice'>Your current objectives:</span>")
|
||||
for(var/line in splittext(gen_objective_text(), "<br>"))
|
||||
to_chat(current, line)
|
||||
|
||||
/datum/mind/proc/find_syndicate_uplink()
|
||||
var/list/L = current.get_contents()
|
||||
@@ -1508,7 +1501,7 @@
|
||||
SSticker.mode.equip_wizard(current)
|
||||
for(var/obj/item/spellbook/S in current.contents)
|
||||
S.op = 0
|
||||
SSticker.mode.name_wizard(current)
|
||||
INVOKE_ASYNC(SSticker.mode, /datum/game_mode/wizard.proc/name_wizard, current)
|
||||
SSticker.mode.forge_wizard_objectives(src)
|
||||
SSticker.mode.greet_wizard(src)
|
||||
SSticker.mode.update_wiz_icons_added(src)
|
||||
|
||||
@@ -222,10 +222,10 @@
|
||||
name = "NT Undercover Operative"
|
||||
// Disguised NT special forces, sent to quietly eliminate or keep tabs on people in high positions (e.g: captain)
|
||||
|
||||
uniform = /obj/item/clothing/under/color/black
|
||||
uniform = /obj/item/clothing/under/color/random
|
||||
back = /obj/item/storage/backpack
|
||||
belt = /obj/item/storage/belt/utility/full/multitool
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
gloves = /obj/item/clothing/gloves/color/yellow
|
||||
shoes = /obj/item/clothing/shoes/chameleon/noslip
|
||||
l_ear = /obj/item/radio/headset/centcom
|
||||
id = /obj/item/card/id
|
||||
|
||||
@@ -351,16 +351,6 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable
|
||||
pipe_id = PIPE_CIRCULATOR
|
||||
pipe_icon = "circ"
|
||||
|
||||
/datum/pipes/atmospheric/omni_filter
|
||||
pipe_name = "omni filter"
|
||||
pipe_id = PIPE_OMNI_FILTER
|
||||
pipe_icon = "omni_filter"
|
||||
|
||||
/datum/pipes/atmospheric/omni_mixer
|
||||
pipe_name = "omni mixer"
|
||||
pipe_id = PIPE_OMNI_MIXER
|
||||
pipe_icon = "omni_mixer"
|
||||
|
||||
/datum/pipes/atmospheric/insulated
|
||||
pipe_name = "insulated pipe"
|
||||
pipe_id = PIPE_INSULATED_STRAIGHT
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
name = "Biodome Winter"
|
||||
id = "biodome-winter"
|
||||
description = "For those getaways where you want to get back to nature, but you don't want to leave the fortified military compound where you spend your days. \
|
||||
Includes a unique(*) laser pistol display case, and the recently introduced I.C.E(tm)."
|
||||
Includes the recently introduced I.C.E(tm)."
|
||||
suffix = "lavaland_biodome_winter.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/biodome/clown
|
||||
@@ -42,7 +42,7 @@
|
||||
cost = 10
|
||||
allow_duplicates = FALSE
|
||||
|
||||
datum/map_template/ruin/lavaland/ash_walker
|
||||
/datum/map_template/ruin/lavaland/ash_walker
|
||||
name = "Ash Walker Nest"
|
||||
id = "ash-walker"
|
||||
description = "A race of unbreathing lizards live here, that run faster than a human can, worship a broken dead city, and are capable of reproducing by something involving tentacles? \
|
||||
|
||||
@@ -248,3 +248,29 @@
|
||||
allow_duplicates = FALSE // I dont even want to think about what happens if you have 2 shuttles with the same ID. Likely scary stuff.
|
||||
always_place = TRUE // Its designed to make exploring other space ruins more accessible
|
||||
cost = 0 // Force spawned so shouldnt have a cost
|
||||
|
||||
/datum/map_template/ruin/space/syndiecakesfactory
|
||||
id = "Syndiecakes Factory"
|
||||
suffix = "syndiecakesfactory.dmm"
|
||||
name = "Syndicakes Factory"
|
||||
description = "Syndicate used to get funds selling corgi cakes produced here. Was it hit by meteors or by a Nanotrasen comando?"
|
||||
allow_duplicates = FALSE
|
||||
cost = 2 //telecomms + multiple mobs
|
||||
|
||||
/datum/map_template/ruin/space/debris1
|
||||
id = "debris1"
|
||||
suffix = "debris1.dmm"
|
||||
name = "Debris field 1"
|
||||
description = "A bunch of metal chunks, wires and space waste"
|
||||
|
||||
/datum/map_template/ruin/space/debris2
|
||||
id = "debris2"
|
||||
suffix = "debris2.dmm"
|
||||
name = "Debris field 2"
|
||||
description = "A bunch of metal chunks, wires and space waste that used to be some kind of secure storage facility"
|
||||
|
||||
/datum/map_template/ruin/space/debris3
|
||||
id = "debris3"
|
||||
suffix = "debris3.dmm"
|
||||
name = "Debris field 3"
|
||||
description = "A bunch of metal chunks, wires and space waste. It used to be an arcade."
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
var/admin_notes
|
||||
|
||||
/datum/map_template/shuttle/New()
|
||||
shuttle_id = "[port_id]_[suffix]"
|
||||
mappath = "[prefix][shuttle_id].dmm"
|
||||
if(port_id && suffix)
|
||||
shuttle_id = "[port_id]_[suffix]"
|
||||
mappath = "[prefix][shuttle_id].dmm"
|
||||
. = ..()
|
||||
|
||||
/datum/map_template/shuttle/emergency
|
||||
@@ -132,3 +133,8 @@
|
||||
suffix = "admin"
|
||||
name = "NTV Argos"
|
||||
description = "Default Admin ship. An older ship used for special operations."
|
||||
|
||||
/datum/map_template/shuttle/admin/armory
|
||||
suffix = "armory"
|
||||
name = "NRV Sparta"
|
||||
description = "Armory Shuttle, with plenty of guns to hand out and some general supplies."
|
||||
|
||||
@@ -6,44 +6,47 @@
|
||||
qdel(src)
|
||||
owner = new_owner
|
||||
|
||||
/datum/spawners_menu/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = FALSE, datum/topic_state/state = GLOB.ghost_state, datum/nanoui/master_ui = null)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/spawners_menu/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui_state/state = GLOB.tgui_observer_state, datum/tgui/master_ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "spawners_menu.tmpl", "Spawners Menu", 700, 600, master_ui, state = state)
|
||||
ui = new(user, src, ui_key, "SpawnersMenu", "Spawners Menu", 700, 600, master_ui, state = state)
|
||||
ui.open()
|
||||
|
||||
/datum/spawners_menu/ui_data(mob/user)
|
||||
/datum/spawners_menu/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["spawners"] = list()
|
||||
for(var/spawner in GLOB.mob_spawners)
|
||||
var/list/this = list()
|
||||
this["name"] = spawner
|
||||
this["desc"] = ""
|
||||
this["important_info"] = ""
|
||||
this["fluff"] = ""
|
||||
this["uids"] = list()
|
||||
for(var/spawner_obj in GLOB.mob_spawners[spawner])
|
||||
for(var/spawner_obj in GLOB.mob_spawners[spawner])//each spawner can contain multiple actual spawners, we use only one desc/info
|
||||
this["uids"] += "\ref[spawner_obj]"
|
||||
if(!this["desc"])
|
||||
if(!this["desc"]) //haven't set descriptions yet
|
||||
if(istype(spawner_obj, /obj/effect/mob_spawn))
|
||||
var/obj/effect/mob_spawn/MS = spawner_obj
|
||||
this["desc"] = MS.flavour_text
|
||||
this["desc"] = MS.description
|
||||
this["important_info"] = MS.important_info
|
||||
this["fluff"] = MS.flavour_text
|
||||
else
|
||||
var/obj/O = spawner_obj
|
||||
this["desc"] = O.desc
|
||||
this["amount_left"] = LAZYLEN(GLOB.mob_spawners[spawner])
|
||||
data["spawners"] += list(this)
|
||||
|
||||
return data
|
||||
|
||||
/datum/spawners_menu/Topic(href, href_list)
|
||||
/datum/spawners_menu/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
var/spawners = replacetext(href_list["uid"], ",", ";")
|
||||
return
|
||||
var/spawners = replacetext(params["ID"], ",", ";")
|
||||
var/list/possible_spawners = params2list(spawners)
|
||||
var/obj/effect/mob_spawn/MS = locate(pick(possible_spawners))
|
||||
if(!MS || !istype(MS))
|
||||
log_runtime(EXCEPTION("A ghost tried to interact with an invalid spawner, or the spawner didn't exist."))
|
||||
return
|
||||
switch(href_list["action"])
|
||||
switch(action)
|
||||
if("jump")
|
||||
owner.forceMove(get_turf(MS))
|
||||
. = TRUE
|
||||
|
||||
+20
-2
@@ -230,12 +230,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
/obj/effect/proc_holder/spell/process()
|
||||
charge_counter += 2
|
||||
if(action)
|
||||
action.UpdateButtonIcon()
|
||||
if(charge_counter < charge_max)
|
||||
return
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
charge_counter = charge_max
|
||||
if(action)
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1, mob/user = usr, make_attack_logs = TRUE) //if recharge is started is important for the trigger spells
|
||||
before_cast(targets)
|
||||
@@ -339,6 +339,19 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
target.vars[type] += amount //I bear no responsibility for the runtimes that'll happen if you try to adjust non-numeric or even non-existant vars
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/get_availability_percentage()
|
||||
switch(charge_type)
|
||||
if("recharge")
|
||||
if(charge_counter == 0)
|
||||
return 0
|
||||
return charge_counter / charge_max
|
||||
if("charges")
|
||||
if(charge_counter)
|
||||
return 1
|
||||
return 0
|
||||
if("holdervar")
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob
|
||||
var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
|
||||
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
|
||||
@@ -444,6 +457,11 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
|
||||
return
|
||||
|
||||
// Normally, AoE spells will generate an attack log for every turf they loop over, while searching for targets.
|
||||
// With this override, all /aoe_turf type spells will only generate 1 log, saying that the user has cast the spell.
|
||||
/obj/effect/proc_holder/spell/aoe_turf/perform(list/targets, recharge, mob/user, make_attack_logs)
|
||||
add_attack_logs(user, null, "Cast the AoE spell [name]", ATKLOG_ALL)
|
||||
return ..(targets, recharge, user, FALSE)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/proc/los_check(mob/A,mob/B)
|
||||
//Checks for obstacles from A to B
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
action_background_icon_state = "bg_demon"
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/hellish/cast(list/targets, mob/living/user = usr)
|
||||
msg_admin_attack("[key_name_admin(usr)] has fired a fireball.", ATKLOG_FEW)
|
||||
add_attack_logs(user, targets, "has fired a Hellfire ball", ATKLOG_FEW)
|
||||
.=..()
|
||||
|
||||
|
||||
|
||||
@@ -13,11 +13,6 @@
|
||||
action_icon_state = "knock"
|
||||
sound = 'sound/magic/knock.ogg'
|
||||
|
||||
// Knock doesn't need to generate an attack log for every turf, set `make_attack_logs` to FALSE and just create a custom one.
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/perform(list/targets, recharge, mob/user)
|
||||
add_attack_logs(user, user, "cast the spell [name]", ATKLOG_ALL)
|
||||
return ..(targets, recharge, user, make_attack_logs = FALSE)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets, mob/user = usr)
|
||||
for(var/turf/T in targets)
|
||||
for(var/obj/machinery/door/door in T.contents)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
if(ready)
|
||||
Discharge()
|
||||
|
||||
obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
|
||||
/obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
|
||||
ready = 0
|
||||
start_time = 0
|
||||
if(halo)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
if(ready)
|
||||
Discharge()
|
||||
|
||||
obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr)
|
||||
/obj/effect/proc_holder/spell/targeted/magnet/proc/Reset(mob/user = usr)
|
||||
ready = 0
|
||||
energy = 0
|
||||
start_time = 0
|
||||
|
||||
@@ -1173,11 +1173,10 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
containername = "fox crate"
|
||||
|
||||
/datum/supply_packs/organic/butterfly
|
||||
name = "Butterflies Crate"
|
||||
name = "Butterfly Crate"
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/critter/butterfly
|
||||
containername = "butterflies crate"
|
||||
contraband = 1
|
||||
containername = "butterfly crate"
|
||||
|
||||
/datum/supply_packs/organic/deer
|
||||
name = "Deer Crate"
|
||||
|
||||
@@ -412,9 +412,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/jobspecific/energizedfireaxe
|
||||
name = "Energized Fire Axe"
|
||||
desc = "A fire axe with a massive electrical charge built into it. It can release this charge on its first victim and will be rather plain after that."
|
||||
desc = "A fire axe with a massive energy charge built into it. Upon striking someone while charged it will throw them backwards while stunning them briefly, but will take some time to charge up again. It is also much sharper than a regular axe and can pierce light armor."
|
||||
reference = "EFA"
|
||||
item = /obj/item/twohanded/energizedfireaxe
|
||||
item = /obj/item/twohanded/fireaxe/energized
|
||||
cost = 10
|
||||
job = list("Life Support Specialist")
|
||||
|
||||
@@ -736,6 +736,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 12 // normally 18
|
||||
gamemodes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/bulldog_XLmagsbag
|
||||
name = "Bulldog - 12g XL Magazine Duffel Bag"
|
||||
desc = "A duffel bag containing three 16 round drum magazines(Slug, Buckshot, Dragon's Breath)."
|
||||
reference = "12XLDB"
|
||||
item = /obj/item/storage/backpack/duffel/syndie/ammo/shotgunXLmags
|
||||
cost = 12 // normally 18
|
||||
gamemodes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/smg
|
||||
name = "C-20r - .45 Magazine"
|
||||
desc = "An additional 20-round .45 magazine for use in the C-20r submachine gun. These bullets pack a lot of punch that can knock most targets down, but do limited overall damage."
|
||||
@@ -1725,8 +1733,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
U.purchase_log += "<BIG>[bicon(C)]</BIG>"
|
||||
for(var/item in bought_items)
|
||||
new item(C)
|
||||
U.purchase_log += "<BIG>[bicon(item)]</BIG>"
|
||||
var/obj/purchased = new item(C)
|
||||
U.purchase_log += "<BIG>[bicon(purchased)]</BIG>"
|
||||
log_game("[key_name(usr)] purchased a surplus crate with [jointext(itemlog, ", ")]")
|
||||
|
||||
/datum/uplink_item/bundles_TC/telecrystal
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
return
|
||||
if(!L.client) //Only sentient people are going along with it!
|
||||
return
|
||||
if(L.flying)
|
||||
return
|
||||
L.adjustFireLoss(3)
|
||||
|
||||
/datum/weather/floor_is_lava/fake
|
||||
|
||||
+76
-119
@@ -1,67 +1,29 @@
|
||||
// Wires for airlocks
|
||||
|
||||
/datum/wires/airlock/secure
|
||||
random = 1
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/airlock
|
||||
holder_type = /obj/machinery/door/airlock
|
||||
wire_count = 12
|
||||
window_x = 410
|
||||
window_y = 570
|
||||
wire_count = 12 // 10 actual, 2 duds.
|
||||
proper_name = "Airlock"
|
||||
window_x = 400
|
||||
window_y = 101
|
||||
|
||||
#define AIRLOCK_WIRE_IDSCAN 1
|
||||
#define AIRLOCK_WIRE_MAIN_POWER1 2
|
||||
#define AIRLOCK_WIRE_DOOR_BOLTS 4
|
||||
#define AIRLOCK_WIRE_BACKUP_POWER1 8
|
||||
#define AIRLOCK_WIRE_OPEN_DOOR 16
|
||||
#define AIRLOCK_WIRE_AI_CONTROL 32
|
||||
#define AIRLOCK_WIRE_ELECTRIFY 64
|
||||
#define AIRLOCK_WIRE_SAFETY 128
|
||||
#define AIRLOCK_WIRE_SPEED 256
|
||||
#define AIRLOCK_WIRE_LIGHT 512
|
||||
/datum/wires/airlock/New(atom/_holder)
|
||||
wires = list(
|
||||
WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_DOOR_BOLTS, WIRE_BACKUP_POWER1, WIRE_OPEN_DOOR,
|
||||
WIRE_AI_CONTROL, WIRE_ELECTRIFY, WIRE_SAFETY, WIRE_SPEED, WIRE_BOLT_LIGHT
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/wires/airlock/GetWireName(index)
|
||||
switch(index)
|
||||
if(AIRLOCK_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
if(AIRLOCK_WIRE_MAIN_POWER1)
|
||||
return "Primary Power"
|
||||
|
||||
if(AIRLOCK_WIRE_DOOR_BOLTS)
|
||||
return "Door Bolts"
|
||||
|
||||
if(AIRLOCK_WIRE_BACKUP_POWER1)
|
||||
return "Primary Backup Power"
|
||||
|
||||
if(AIRLOCK_WIRE_OPEN_DOOR)
|
||||
return "Door State"
|
||||
|
||||
if(AIRLOCK_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Electrification"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Door Safeties"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Door Timing"
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
return "Bolt Lights"
|
||||
|
||||
/datum/wires/airlock/CanUse(mob/living/L)
|
||||
/datum/wires/airlock/interactable(mob/user)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
if(iscarbon(L))
|
||||
if(A.Adjacent(L))
|
||||
if(A.isElectrified())
|
||||
if(A.shock(L, 100))
|
||||
return 0
|
||||
if(iscarbon(user) && A.Adjacent(user) && A.isElectrified() && A.shock(user, 100))
|
||||
return FALSE
|
||||
if(A.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/airlock/get_status()
|
||||
. = ..()
|
||||
@@ -70,21 +32,20 @@
|
||||
|
||||
. += "The door bolts [A.locked ? "have fallen!" : "look up."]"
|
||||
. += "The door bolt lights are [(A.lights && haspower) ? "on." : "off!"]"
|
||||
. += "The test light is [haspower ? "on." : "off!"]"
|
||||
. += "The 'AI control allowed' light is [(A.aiControlDisabled == 0 && !A.emagged && haspower) ? "on" : "off"]."
|
||||
. += "The test light is [haspower ? "on." : "off!"]"
|
||||
. += "The 'AI control allowed' light is [(A.aiControlDisabled == AICONTROLDISABLED_OFF && !A.emagged && haspower) ? "on" : "off"]."
|
||||
. += "The 'Check Wiring' light is [(A.safe == 0 && haspower) ? "on" : "off"]."
|
||||
. += "The 'Check Timing Mechanism' light is [(A.normalspeed == 0 && haspower) ? "on" : "off"]."
|
||||
. += "The emergency lights are [(A.emergency && haspower) ? "on" : "off"]."
|
||||
|
||||
/datum/wires/airlock/UpdateCut(index, mended)
|
||||
|
||||
/datum/wires/airlock/on_cut(wire, mend)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(index)
|
||||
if(AIRLOCK_WIRE_IDSCAN)
|
||||
A.aiDisabledIdScanner = !mended
|
||||
if(AIRLOCK_WIRE_MAIN_POWER1)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.aiDisabledIdScanner = !mend
|
||||
if(WIRE_MAIN_POWER1)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user.
|
||||
A.loseMainPower()
|
||||
A.shock(usr, 50)
|
||||
@@ -92,9 +53,9 @@
|
||||
A.regainMainPower()
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(AIRLOCK_WIRE_BACKUP_POWER1)
|
||||
if(WIRE_BACKUP_POWER1)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user.
|
||||
A.loseBackupPower()
|
||||
A.shock(usr, 50)
|
||||
@@ -102,66 +63,66 @@
|
||||
A.regainBackupPower()
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(AIRLOCK_WIRE_DOOR_BOLTS)
|
||||
if(WIRE_DOOR_BOLTS)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present)
|
||||
A.lock(1)
|
||||
A.update_icon()
|
||||
|
||||
if(AIRLOCK_WIRE_AI_CONTROL)
|
||||
if(WIRE_AI_CONTROL)
|
||||
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
//one wire for AI control. Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all.
|
||||
//aiControlDisabled: If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in.
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
//aiControlDisabled: see explanation in code\__DEFINES\construction.dm#32
|
||||
if(A.aiControlDisabled == AICONTROLDISABLED_OFF)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_ON
|
||||
else if(A.aiControlDisabled == AICONTROLDISABLED_PERMA)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_BYPASS
|
||||
else
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
if(A.aiControlDisabled == AICONTROLDISABLED_ON)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_OFF
|
||||
else if(A.aiControlDisabled == AICONTROLDISABLED_BYPASS)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_PERMA
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
if(!mended)
|
||||
if(WIRE_ELECTRIFY)
|
||||
if(!mend)
|
||||
//Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted.
|
||||
A.electrify(-1)
|
||||
else
|
||||
A.electrify(0)
|
||||
return // Don't update the dialog.
|
||||
|
||||
if(AIRLOCK_WIRE_SAFETY)
|
||||
A.safe = mended
|
||||
if(WIRE_SAFETY)
|
||||
A.safe = mend
|
||||
|
||||
if(AIRLOCK_WIRE_SPEED)
|
||||
A.autoclose = mended
|
||||
if(mended)
|
||||
if(WIRE_SPEED)
|
||||
A.autoclose = mend
|
||||
if(mend)
|
||||
if(!A.density)
|
||||
spawn(0)
|
||||
A.close()
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/close)
|
||||
|
||||
if(AIRLOCK_WIRE_LIGHT)
|
||||
A.lights = mended
|
||||
if(WIRE_BOLT_LIGHT)
|
||||
A.lights = mend
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
/datum/wires/airlock/UpdatePulsed(index)
|
||||
|
||||
/datum/wires/airlock/on_pulse(wire)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(index)
|
||||
if(AIRLOCK_WIRE_IDSCAN)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
//Sending a pulse through flashes the red light on the door (if the door has power).
|
||||
if(A.arePowerSystemsOn() && A.density)
|
||||
A.do_animate("deny")
|
||||
if(A.emergency)
|
||||
A.emergency = 0
|
||||
A.update_icon()
|
||||
if(AIRLOCK_WIRE_MAIN_POWER1)
|
||||
|
||||
if(WIRE_MAIN_POWER1)
|
||||
//Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter).
|
||||
A.loseMainPower()
|
||||
if(AIRLOCK_WIRE_DOOR_BOLTS)
|
||||
|
||||
if(WIRE_DOOR_BOLTS)
|
||||
//one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not),
|
||||
//raises them if they are down (only if power's on)
|
||||
if(!A.locked)
|
||||
@@ -170,45 +131,41 @@
|
||||
else if(A.unlock())
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", hearing_distance = 1)
|
||||
|
||||
if(AIRLOCK_WIRE_BACKUP_POWER1)
|
||||
if(WIRE_BACKUP_POWER1)
|
||||
//two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter).
|
||||
A.loseBackupPower()
|
||||
if(AIRLOCK_WIRE_AI_CONTROL)
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
|
||||
spawn(10)
|
||||
if(A)
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(A.aiControlDisabled == AICONTROLDISABLED_OFF)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_ON
|
||||
else if(A.aiControlDisabled == AICONTROLDISABLED_PERMA)
|
||||
A.aiControlDisabled = AICONTROLDISABLED_BYPASS
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
addtimer(CALLBACK(A, /obj/machinery/door/airlock/.proc/ai_control_callback), 1 SECONDS)
|
||||
|
||||
if(WIRE_ELECTRIFY)
|
||||
//one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds.
|
||||
A.electrify(30)
|
||||
if(AIRLOCK_WIRE_OPEN_DOOR)
|
||||
|
||||
if(WIRE_OPEN_DOOR)
|
||||
//tries to open the door without ID
|
||||
//will succeed only if the ID wire is cut or the door requires no access and it's not emagged
|
||||
if(A.emagged) return
|
||||
if(!A.requiresID() || A.check_access(null))
|
||||
spawn(0)
|
||||
if(A.density)
|
||||
A.open()
|
||||
else
|
||||
A.close()
|
||||
if(AIRLOCK_WIRE_SAFETY)
|
||||
if(A.density)
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/open)
|
||||
else
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/close)
|
||||
|
||||
if(WIRE_SAFETY)
|
||||
A.safe = !A.safe
|
||||
if(!A.density)
|
||||
spawn(0)
|
||||
A.close()
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/airlock/.proc/close)
|
||||
|
||||
if(AIRLOCK_WIRE_SPEED)
|
||||
if(WIRE_SPEED)
|
||||
A.normalspeed = !A.normalspeed
|
||||
|
||||
if(AIRLOCK_WIRE_LIGHT)
|
||||
if(WIRE_BOLT_LIGHT)
|
||||
A.lights = !A.lights
|
||||
A.update_icon()
|
||||
|
||||
|
||||
+41
-69
@@ -2,35 +2,22 @@
|
||||
/datum/wires/alarm
|
||||
holder_type = /obj/machinery/alarm
|
||||
wire_count = 5
|
||||
window_x = 385
|
||||
window_y = 90
|
||||
proper_name = "Air alarm"
|
||||
|
||||
#define AALARM_WIRE_IDSCAN 1
|
||||
#define AALARM_WIRE_POWER 2
|
||||
#define AALARM_WIRE_SYPHON 4
|
||||
#define AALARM_WIRE_AI_CONTROL 8
|
||||
#define AALARM_WIRE_AALARM 16
|
||||
/datum/wires/alarm/New(atom/_holder)
|
||||
wires = list(
|
||||
WIRE_IDSCAN , WIRE_MAIN_POWER1 , WIRE_SYPHON,
|
||||
WIRE_AI_CONTROL, WIRE_AALARM
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/wires/alarm/GetWireName(index)
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
return "Power"
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
return "Syphon"
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
return "Atmospherics Alarm"
|
||||
|
||||
/datum/wires/alarm/CanUse(mob/living/L)
|
||||
/datum/wires/alarm/interactable(mob/user)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
if(A.wiresexposed)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/alarm/get_status()
|
||||
. = ..()
|
||||
@@ -39,75 +26,60 @@
|
||||
. += "The Air Alarm is [(A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "offline." : "working properly!"]"
|
||||
. += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]."
|
||||
|
||||
/datum/wires/alarm/UpdateCut(index, mended)
|
||||
/datum/wires/alarm/on_cut(wire, mend)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
if(!mended)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
if(!mend)
|
||||
A.locked = 1
|
||||
// to_chat(world, "Idscan wire cut")
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
if(WIRE_MAIN_POWER1)
|
||||
A.shock(usr, 50)
|
||||
A.shorted = !mended
|
||||
A.shorted = !mend
|
||||
A.update_icon()
|
||||
// to_chat(world, "Power wire cut")
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
A.aidisabled = !mended
|
||||
// to_chat(world, "AI Control Wire Cut")
|
||||
if(WIRE_AI_CONTROL)
|
||||
A.aidisabled = !mend
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
if(!mended)
|
||||
if(WIRE_SYPHON)
|
||||
if(!mend)
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
A.apply_mode()
|
||||
// to_chat(world, "Syphon Wire Cut")
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
if(A.alarm_area.atmosalert(2, A))
|
||||
A.post_alert(2)
|
||||
if(WIRE_AALARM)
|
||||
if(A.alarm_area.atmosalert(ATMOS_ALARM_DANGER, A))
|
||||
A.post_alert(ATMOS_ALARM_DANGER)
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
/datum/wires/alarm/UpdatePulsed(index)
|
||||
/datum/wires/alarm/on_pulse(wire)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.locked = !A.locked
|
||||
// to_chat(world, "Idscan wire pulsed")
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
// to_chat(world, "Power wire pulsed")
|
||||
if(A.shorted == 0)
|
||||
A.shorted = 1
|
||||
if(WIRE_MAIN_POWER1)
|
||||
if(!A.shorted)
|
||||
A.shorted = TRUE
|
||||
A.update_icon()
|
||||
addtimer(CALLBACK(A, /obj/machinery/alarm/.proc/unshort_callback), 120 SECONDS)
|
||||
|
||||
spawn(12000)
|
||||
if(A.shorted == 1)
|
||||
A.shorted = 0
|
||||
A.update_icon()
|
||||
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
// to_chat(world, "AI Control wire pulsed")
|
||||
if(A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
A.updateDialog()
|
||||
spawn(100)
|
||||
if(A.aidisabled == 1)
|
||||
A.aidisabled = 0
|
||||
addtimer(CALLBACK(A, /obj/machinery/alarm/.proc/enable_ai_control_callback), 10 SECONDS)
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
// to_chat(world, "Syphon wire pulsed")
|
||||
|
||||
if(WIRE_SYPHON)
|
||||
if(A.mode == 1) // AALARM_MODE_SCRUB
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
else
|
||||
A.mode = 1 // AALARM_MODE_SCRUB
|
||||
A.apply_mode()
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
// to_chat(world, "Aalarm wire pulsed")
|
||||
if(A.alarm_area.atmosalert(0, A))
|
||||
A.post_alert(0)
|
||||
if(WIRE_AALARM)
|
||||
if(A.alarm_area.atmosalert(ATMOS_ALARM_NONE, A))
|
||||
A.post_alert(ATMOS_ALARM_NONE)
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
+33
-58
@@ -1,25 +1,13 @@
|
||||
/datum/wires/apc
|
||||
holder_type = /obj/machinery/power/apc
|
||||
wire_count = 4
|
||||
proper_name = "APC"
|
||||
window_x = 355
|
||||
window_y = 97
|
||||
|
||||
#define APC_WIRE_IDSCAN 1
|
||||
#define APC_WIRE_MAIN_POWER1 2
|
||||
#define APC_WIRE_MAIN_POWER2 4
|
||||
#define APC_WIRE_AI_CONTROL 8
|
||||
|
||||
/datum/wires/apc/GetWireName(index)
|
||||
switch(index)
|
||||
if(APC_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
if(APC_WIRE_MAIN_POWER1)
|
||||
return "Primary Power"
|
||||
|
||||
if(APC_WIRE_MAIN_POWER2)
|
||||
return "Secondary Power"
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
/datum/wires/apc/New(atom/_holder)
|
||||
wires = list(WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_MAIN_POWER2, WIRE_AI_CONTROL)
|
||||
return ..()
|
||||
|
||||
/datum/wires/apc/get_status()
|
||||
. = ..()
|
||||
@@ -29,66 +17,53 @@
|
||||
. += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]."
|
||||
|
||||
|
||||
/datum/wires/apc/CanUse(mob/living/L)
|
||||
/datum/wires/apc/interactable(mob/user)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
if(A.panel_open && !A.opened)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/apc/UpdatePulsed(index)
|
||||
/datum/wires/apc/on_pulse(wire)
|
||||
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
|
||||
switch(index)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.locked = FALSE
|
||||
addtimer(CALLBACK(A, /obj/machinery/power/apc/.proc/relock_callback), 30 SECONDS)
|
||||
|
||||
if(APC_WIRE_IDSCAN)
|
||||
A.locked = 0
|
||||
|
||||
spawn(300)
|
||||
if(A)
|
||||
A.locked = 1
|
||||
A.updateDialog()
|
||||
if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2)
|
||||
if(!A.shorted)
|
||||
A.shorted = TRUE
|
||||
addtimer(CALLBACK(A, /obj/machinery/power/apc/.proc/check_main_power_callback), 120 SECONDS)
|
||||
|
||||
if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
|
||||
if(A.shorted == 0)
|
||||
A.shorted = 1
|
||||
|
||||
spawn(1200)
|
||||
if(A && !IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
|
||||
A.shorted = 0
|
||||
A.updateDialog()
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
if(A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
|
||||
spawn(10)
|
||||
if(A && !IsIndexCut(APC_WIRE_AI_CONTROL))
|
||||
A.aidisabled = 0
|
||||
A.updateDialog()
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
addtimer(CALLBACK(A, /obj/machinery/power/apc/.proc/check_ai_control_callback), 1 SECONDS)
|
||||
|
||||
..()
|
||||
|
||||
/datum/wires/apc/UpdateCut(index, mended)
|
||||
/datum/wires/apc/on_cut(wire, mend)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
|
||||
switch(index)
|
||||
if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
|
||||
|
||||
if(!mended)
|
||||
switch(wire)
|
||||
if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2)
|
||||
if(!mend)
|
||||
A.shock(usr, 50)
|
||||
A.shorted = 1
|
||||
A.shorted = TRUE
|
||||
|
||||
else if(!IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
|
||||
A.shorted = 0
|
||||
else if(!is_cut(WIRE_MAIN_POWER1) && !is_cut(WIRE_MAIN_POWER2))
|
||||
A.shorted = FALSE
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
|
||||
if(!mended)
|
||||
if(A.aidisabled == 0)
|
||||
A.aidisabled = 1
|
||||
if(WIRE_AI_CONTROL)
|
||||
if(!mend)
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
else
|
||||
if(A.aidisabled == 1)
|
||||
A.aidisabled = 0
|
||||
if(A.aidisabled)
|
||||
A.aidisabled = FALSE
|
||||
..()
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
/datum/wires/autolathe
|
||||
holder_type = /obj/machinery/autolathe
|
||||
wire_count = 10
|
||||
proper_name = "Autolathe"
|
||||
window_x = 340
|
||||
window_y = 55
|
||||
|
||||
#define AUTOLATHE_HACK_WIRE 1
|
||||
#define AUTOLATHE_SHOCK_WIRE 2
|
||||
#define AUTOLATHE_DISABLE_WIRE 4
|
||||
|
||||
/datum/wires/autolathe/GetWireName(index)
|
||||
switch(index)
|
||||
if(AUTOLATHE_HACK_WIRE)
|
||||
return "Hack"
|
||||
|
||||
if(AUTOLATHE_SHOCK_WIRE)
|
||||
return "Shock"
|
||||
|
||||
if(AUTOLATHE_DISABLE_WIRE)
|
||||
return "Disable"
|
||||
/datum/wires/autolathe/New(atom/_holder)
|
||||
wires = list(WIRE_AUTOLATHE_HACK, WIRE_ELECTRIFY, WIRE_AUTOLATHE_DISABLE)
|
||||
return ..()
|
||||
|
||||
/datum/wires/autolathe/get_status()
|
||||
. = ..()
|
||||
@@ -24,51 +16,38 @@
|
||||
. += "The green light is [A.shocked ? "off" : "on"]."
|
||||
. += "The blue light is [A.hacked ? "off" : "on"]."
|
||||
|
||||
/datum/wires/autolathe/CanUse()
|
||||
/datum/wires/autolathe/interactable(mob/user)
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
if(iscarbon(user) && A.Adjacent(user) && A.shocked && A.shock(user, 100))
|
||||
return FALSE
|
||||
if(A.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/autolathe/UpdateCut(index, mended)
|
||||
/datum/wires/autolathe/on_cut(wire, mend)
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
switch(index)
|
||||
if(AUTOLATHE_HACK_WIRE)
|
||||
A.adjust_hacked(!mended)
|
||||
if(AUTOLATHE_SHOCK_WIRE)
|
||||
A.shocked = !mended
|
||||
if(AUTOLATHE_DISABLE_WIRE)
|
||||
A.disabled = !mended
|
||||
switch(wire)
|
||||
if(WIRE_AUTOLATHE_HACK)
|
||||
A.adjust_hacked(!mend)
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !mend
|
||||
if(WIRE_AUTOLATHE_DISABLE)
|
||||
A.disabled = !mend
|
||||
..()
|
||||
|
||||
/datum/wires/autolathe/UpdatePulsed(index)
|
||||
if(IsIndexCut(index))
|
||||
/datum/wires/autolathe/on_pulse(wire)
|
||||
if(is_cut(wire))
|
||||
return
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
switch(index)
|
||||
if(AUTOLATHE_HACK_WIRE)
|
||||
switch(wire)
|
||||
if(WIRE_AUTOLATHE_HACK)
|
||||
A.adjust_hacked(!A.hacked)
|
||||
updateUIs()
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.adjust_hacked(0)
|
||||
updateUIs()
|
||||
if(AUTOLATHE_SHOCK_WIRE)
|
||||
A.shocked = !A.shocked
|
||||
updateUIs()
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.shocked = 0
|
||||
updateUIs()
|
||||
if(AUTOLATHE_DISABLE_WIRE)
|
||||
A.disabled = !A.disabled
|
||||
updateUIs()
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.disabled = 0
|
||||
updateUIs()
|
||||
addtimer(CALLBACK(A, /obj/machinery/autolathe/.proc/check_hacked_callback), 5 SECONDS)
|
||||
|
||||
/datum/wires/autolathe/proc/updateUIs()
|
||||
SSnanoui.update_uis(src)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !A.shocked
|
||||
addtimer(CALLBACK(A, /obj/machinery/autolathe/.proc/check_electrified_callback), 5 SECONDS)
|
||||
|
||||
if(WIRE_AUTOLATHE_DISABLE)
|
||||
A.disabled = !A.disabled
|
||||
addtimer(CALLBACK(A, /obj/machinery/autolathe/.proc/check_disabled_callback), 5 SECONDS)
|
||||
|
||||
+20
-25
@@ -1,9 +1,15 @@
|
||||
// Wires for cameras.
|
||||
|
||||
/datum/wires/camera
|
||||
random = 0
|
||||
holder_type = /obj/machinery/camera
|
||||
wire_count = 2
|
||||
proper_name = "Camera"
|
||||
window_x = 350
|
||||
window_y = 95
|
||||
|
||||
/datum/wires/camera/New(atom/_holder)
|
||||
wires = list(WIRE_FOCUS, WIRE_MAIN_POWER1)
|
||||
return ..()
|
||||
|
||||
/datum/wires/camera/get_status()
|
||||
. = ..()
|
||||
@@ -11,51 +17,40 @@
|
||||
. += "The focus light is [(C.view_range == initial(C.view_range)) ? "on" : "off"]."
|
||||
. += "The power link light is [C.can_use() ? "on" : "off"]."
|
||||
|
||||
/datum/wires/camera/CanUse(mob/living/L)
|
||||
/datum/wires/camera/interactable(mob/user)
|
||||
var/obj/machinery/camera/C = holder
|
||||
if(!C.panel_open)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
#define CAMERA_WIRE_FOCUS 1
|
||||
#define CAMERA_WIRE_POWER 2
|
||||
|
||||
/datum/wires/camera/GetWireName(index)
|
||||
switch(index)
|
||||
if(CAMERA_WIRE_FOCUS)
|
||||
return "Focus"
|
||||
|
||||
if(CAMERA_WIRE_POWER)
|
||||
return "Power"
|
||||
|
||||
/datum/wires/camera/UpdateCut(index, mended)
|
||||
/datum/wires/camera/on_cut(wire, mend)
|
||||
var/obj/machinery/camera/C = holder
|
||||
switch(index)
|
||||
if(CAMERA_WIRE_FOCUS)
|
||||
var/range = (mended ? initial(C.view_range) : C.short_range)
|
||||
switch(wire)
|
||||
if(WIRE_FOCUS)
|
||||
var/range = (mend ? initial(C.view_range) : C.short_range)
|
||||
C.setViewRange(range)
|
||||
|
||||
if(CAMERA_WIRE_POWER)
|
||||
if(C.status && !mended || !C.status && mended)
|
||||
if(WIRE_MAIN_POWER1)
|
||||
if(C.status && !mend || !C.status && mend)
|
||||
C.toggle_cam(usr, TRUE)
|
||||
C.obj_integrity = C.max_integrity //this is a pretty simplistic way to heal the camera, but there's no reason for this to be complex.
|
||||
..()
|
||||
|
||||
/datum/wires/camera/UpdatePulsed(index)
|
||||
/datum/wires/camera/on_pulse(wire)
|
||||
var/obj/machinery/camera/C = holder
|
||||
if(IsIndexCut(index))
|
||||
if(is_cut(wire))
|
||||
return
|
||||
switch(index)
|
||||
if(CAMERA_WIRE_FOCUS)
|
||||
switch(wire)
|
||||
if(WIRE_FOCUS)
|
||||
var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range))
|
||||
C.setViewRange(new_range)
|
||||
|
||||
if(CAMERA_WIRE_POWER)
|
||||
if(WIRE_MAIN_POWER1)
|
||||
C.toggle_cam(null) // Deactivate the camera
|
||||
..()
|
||||
|
||||
/datum/wires/camera/proc/CanDeconstruct()
|
||||
if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS))
|
||||
if(is_cut(WIRE_MAIN_POWER1) && is_cut(WIRE_FOCUS))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
/datum/wires/explosive
|
||||
wire_count = 1
|
||||
proper_name = "Explosive"
|
||||
window_x = 320
|
||||
window_y = 50
|
||||
|
||||
#define WIRE_EXPLODE 1
|
||||
|
||||
/datum/wires/explosive/GetWireName(index)
|
||||
switch(index)
|
||||
if(WIRE_EXPLODE)
|
||||
return "Explode"
|
||||
/datum/wires/explosive/New(atom/_holder)
|
||||
wires = list(WIRE_EXPLODE)
|
||||
return ..()
|
||||
|
||||
/datum/wires/explosive/proc/explode()
|
||||
return
|
||||
|
||||
/datum/wires/explosive/UpdatePulsed(index)
|
||||
switch(index)
|
||||
/datum/wires/explosive/on_pulse(wire)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
explode()
|
||||
..()
|
||||
|
||||
/datum/wires/explosive/UpdateCut(index, mended)
|
||||
switch(index)
|
||||
/datum/wires/explosive/on_cut(wire, mend)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
if(!mended)
|
||||
if(!mend)
|
||||
explode()
|
||||
..()
|
||||
|
||||
/datum/wires/explosive/gibtonite
|
||||
holder_type = /obj/item/twohanded/required/gibtonite
|
||||
|
||||
/datum/wires/explosive/gibtonite/CanUse(mob/L)
|
||||
return 1
|
||||
/datum/wires/explosive/gibtonite/interactable(mob/user)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/explosive/gibtonite/UpdateCut(index, mended)
|
||||
/datum/wires/explosive/gibtonite/on_cut(wire, mend)
|
||||
return
|
||||
|
||||
/datum/wires/explosive/gibtonite/explode()
|
||||
|
||||
@@ -1,90 +1,35 @@
|
||||
/datum/wires/mulebot
|
||||
random = 1
|
||||
randomize = TRUE
|
||||
holder_type = /mob/living/simple_animal/bot/mulebot
|
||||
wire_count = 10
|
||||
window_x = 410
|
||||
proper_name = "Mulebot"
|
||||
window_x = 370
|
||||
window_y = -12
|
||||
|
||||
#define MULEBOT_WIRE_POWER1 1 // power connections
|
||||
#define MULEBOT_WIRE_POWER2 2
|
||||
#define MULEBOT_WIRE_AVOIDANCE 4 // mob avoidance
|
||||
#define MULEBOT_WIRE_LOADCHECK 8 // load checking (non-crate)
|
||||
#define MULEBOT_WIRE_MOTOR1 16 // motor wires
|
||||
#define MULEBOT_WIRE_MOTOR2 32 //
|
||||
#define MULEBOT_WIRE_REMOTE_RX 64 // remote recv functions
|
||||
#define MULEBOT_WIRE_REMOTE_TX 128 // remote trans status
|
||||
#define MULEBOT_WIRE_BEACON_RX 256 // beacon ping recv
|
||||
/datum/wires/mulebot/New(atom/_holder)
|
||||
wires = list(
|
||||
WIRE_MAIN_POWER1, WIRE_MAIN_POWER2, WIRE_MOB_AVOIDANCE,
|
||||
WIRE_LOADCHECK, WIRE_MOTOR1, WIRE_MOTOR2,
|
||||
WIRE_REMOTE_RX, WIRE_REMOTE_TX, WIRE_BEACON_RX
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/wires/mulebot/GetWireName(index)
|
||||
switch(index)
|
||||
if(MULEBOT_WIRE_POWER1)
|
||||
return "Primary Power"
|
||||
|
||||
if(MULEBOT_WIRE_POWER2)
|
||||
return "Secondary Power"
|
||||
|
||||
if(MULEBOT_WIRE_AVOIDANCE)
|
||||
return "Mob Avoidance"
|
||||
|
||||
if(MULEBOT_WIRE_LOADCHECK)
|
||||
return "Load Checking"
|
||||
|
||||
if(MULEBOT_WIRE_MOTOR1)
|
||||
return "Primary Motor"
|
||||
|
||||
if(MULEBOT_WIRE_MOTOR2)
|
||||
return "Secondary Motor"
|
||||
|
||||
if(MULEBOT_WIRE_REMOTE_RX)
|
||||
return "Remote Signal Receiver"
|
||||
|
||||
if(MULEBOT_WIRE_REMOTE_TX)
|
||||
return "Remote Signal Sender"
|
||||
|
||||
if(MULEBOT_WIRE_BEACON_RX)
|
||||
return "Navigation Beacon Receiver"
|
||||
|
||||
/datum/wires/mulebot/CanUse(mob/living/L)
|
||||
/datum/wires/mulebot/interactable(mob/user)
|
||||
var/mob/living/simple_animal/bot/mulebot/M = holder
|
||||
if(M.open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/mulebot/UpdatePulsed(index)
|
||||
switch(index)
|
||||
if(MULEBOT_WIRE_POWER1, MULEBOT_WIRE_POWER2)
|
||||
/datum/wires/mulebot/on_pulse(wire)
|
||||
switch(wire)
|
||||
if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The charge light flickers.</span>")
|
||||
if(MULEBOT_WIRE_AVOIDANCE)
|
||||
if(WIRE_MOB_AVOIDANCE)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The external warning lights flash briefly.</span>")
|
||||
if(MULEBOT_WIRE_LOADCHECK)
|
||||
if(WIRE_LOADCHECK)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The load platform clunks.</span>")
|
||||
if(MULEBOT_WIRE_MOTOR1, MULEBOT_WIRE_MOTOR2)
|
||||
if(WIRE_MOTOR1, WIRE_MOTOR2)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The drive motor whines briefly.</span>")
|
||||
else
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] You hear a radio crackle.</span>")
|
||||
..()
|
||||
|
||||
// HELPER PROCS
|
||||
|
||||
/datum/wires/mulebot/proc/Motor1()
|
||||
return !(wires_status & MULEBOT_WIRE_MOTOR1)
|
||||
|
||||
/datum/wires/mulebot/proc/Motor2()
|
||||
return !(wires_status & MULEBOT_WIRE_MOTOR2)
|
||||
|
||||
/datum/wires/mulebot/proc/HasPower()
|
||||
return !(wires_status & MULEBOT_WIRE_POWER1) && !(wires_status & MULEBOT_WIRE_POWER2)
|
||||
|
||||
/datum/wires/mulebot/proc/LoadCheck()
|
||||
return !(wires_status & MULEBOT_WIRE_LOADCHECK)
|
||||
|
||||
/datum/wires/mulebot/proc/MobAvoid()
|
||||
return !(wires_status & MULEBOT_WIRE_AVOIDANCE)
|
||||
|
||||
/datum/wires/mulebot/proc/RemoteTX()
|
||||
return !(wires_status & MULEBOT_WIRE_REMOTE_TX)
|
||||
|
||||
/datum/wires/mulebot/proc/RemoteRX()
|
||||
return !(wires_status & MULEBOT_WIRE_REMOTE_RX)
|
||||
|
||||
/datum/wires/mulebot/proc/BeaconRX()
|
||||
return !(wires_status & MULEBOT_WIRE_BEACON_RX)
|
||||
|
||||
@@ -1,28 +1,20 @@
|
||||
/datum/wires/nuclearbomb
|
||||
holder_type = /obj/machinery/nuclearbomb
|
||||
random = 1
|
||||
wire_count = 7
|
||||
randomize = TRUE
|
||||
wire_count = 7 // 3 actual, 4 duds.
|
||||
proper_name = "Nuclear bomb"
|
||||
window_x = 345
|
||||
window_y = 75
|
||||
|
||||
#define NUCLEARBOMB_WIRE_LIGHT 1
|
||||
#define NUCLEARBOMB_WIRE_TIMING 2
|
||||
#define NUCLEARBOMB_WIRE_SAFETY 4
|
||||
/datum/wires/nuclearbomb/New(atom/_holder)
|
||||
wires = list(WIRE_BOMB_LIGHT, WIRE_BOMB_TIMING, WIRE_BOMB_SAFETY)
|
||||
return ..()
|
||||
|
||||
/datum/wires/nuclearbomb/GetWireName(index)
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
return "Bomb Light"
|
||||
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
return "Bomb Timing"
|
||||
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
return "Bomb Safety"
|
||||
|
||||
/datum/wires/nuclearbomb/CanUse(mob/living/L)
|
||||
/datum/wires/nuclearbomb/interactable(mob/user)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
if(N.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/nuclearbomb/get_status()
|
||||
. = ..()
|
||||
@@ -31,52 +23,36 @@
|
||||
. += "The device is is [N.safety ? "quiet" : "whirring"]."
|
||||
. += "The lights are [N.lighthack ? "static" : "functional"]."
|
||||
|
||||
/datum/wires/nuclearbomb/UpdatePulsed(index)
|
||||
/datum/wires/nuclearbomb/on_pulse(wire)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
switch(wire)
|
||||
if(WIRE_BOMB_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
updateUIs()
|
||||
spawn(100)
|
||||
N.lighthack = !N.lighthack
|
||||
updateUIs()
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
addtimer(CALLBACK(N, /obj/machinery/nuclearbomb/.proc/reset_lighthack_callback), 10 SECONDS)
|
||||
|
||||
if(WIRE_BOMB_TIMING)
|
||||
if(N.timing)
|
||||
message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
N.safety = !N.safety
|
||||
updateUIs()
|
||||
spawn(100)
|
||||
N.safety = !N.safety
|
||||
if(N.safety == 1)
|
||||
if(!N.is_syndicate)
|
||||
set_security_level(N.previous_level)
|
||||
N.visible_message("<span class='notice'>The [N] quiets down.</span>")
|
||||
if(!N.lighthack)
|
||||
if(N.icon_state == "nuclearbomb2")
|
||||
N.icon_state = "nuclearbomb1"
|
||||
else
|
||||
N.visible_message("<span class='notice'>The [N] emits a quiet whirling noise!</span>")
|
||||
updateUIs()
|
||||
|
||||
/datum/wires/nuclearbomb/UpdateCut(index, mended)
|
||||
if(WIRE_BOMB_SAFETY)
|
||||
N.safety = !N.safety
|
||||
addtimer(CALLBACK(N, /obj/machinery/nuclearbomb/.proc/reset_safety_callback), 10 SECONDS)
|
||||
|
||||
/datum/wires/nuclearbomb/on_cut(wire, mend)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
switch(wire)
|
||||
if(WIRE_BOMB_SAFETY)
|
||||
if(N.timing)
|
||||
message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
|
||||
if(WIRE_BOMB_TIMING)
|
||||
if(!N.lighthack)
|
||||
if(N.icon_state == "nuclearbomb2")
|
||||
N.icon_state = "nuclearbomb1"
|
||||
N.timing = 0
|
||||
GLOB.bomb_set = 0
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
GLOB.bomb_set = FALSE
|
||||
|
||||
/datum/wires/nuclearbomb/proc/updateUIs()
|
||||
SSnanoui.update_uis(src)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
if(WIRE_BOMB_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
|
||||
@@ -1,67 +1,52 @@
|
||||
/datum/wires/particle_acc/control_box
|
||||
wire_count = 5
|
||||
holder_type = /obj/machinery/particle_accelerator/control_box
|
||||
proper_name = "Particle accelerator control"
|
||||
window_x = 361
|
||||
window_y = 22
|
||||
|
||||
#define PARTICLE_TOGGLE_WIRE 1 // Toggles whether the PA is on or not.
|
||||
#define PARTICLE_STRENGTH_WIRE 2 // Determines the strength of the PA.
|
||||
#define PARTICLE_INTERFACE_WIRE 4 // Determines the interface showing up.
|
||||
#define PARTICLE_LIMIT_POWER_WIRE 8 // Determines how strong the PA can be.
|
||||
/datum/wires/particle_acc/control_box/New(atom/_holder)
|
||||
wires = list(WIRE_PARTICLE_POWER, WIRE_PARTICLE_STRENGTH, WIRE_PARTICLE_INTERFACE, WIRE_PARTICLE_POWER_LIMIT)
|
||||
return ..()
|
||||
|
||||
/datum/wires/particle_acc/control_box/GetWireName(index)
|
||||
switch(index)
|
||||
if(PARTICLE_TOGGLE_WIRE)
|
||||
return "Power Toggle"
|
||||
|
||||
if(PARTICLE_STRENGTH_WIRE)
|
||||
return "Strength"
|
||||
|
||||
if(PARTICLE_INTERFACE_WIRE)
|
||||
return "Interface"
|
||||
|
||||
if(PARTICLE_LIMIT_POWER_WIRE)
|
||||
return "Maximum Power"
|
||||
|
||||
/datum/wires/particle_acc/control_box/CanUse(mob/living/L)
|
||||
/datum/wires/particle_acc/control_box/interactable(mob/user)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
if(C.construction_state == 2)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/particle_acc/control_box/UpdatePulsed(index)
|
||||
/datum/wires/particle_acc/control_box/on_pulse(wire)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
switch(index)
|
||||
|
||||
if(PARTICLE_TOGGLE_WIRE)
|
||||
switch(wire)
|
||||
if(WIRE_PARTICLE_POWER)
|
||||
C.toggle_power()
|
||||
|
||||
if(PARTICLE_STRENGTH_WIRE)
|
||||
if(WIRE_PARTICLE_STRENGTH)
|
||||
C.add_strength()
|
||||
|
||||
if(PARTICLE_INTERFACE_WIRE)
|
||||
if(WIRE_PARTICLE_INTERFACE)
|
||||
C.interface_control = !C.interface_control
|
||||
|
||||
if(PARTICLE_LIMIT_POWER_WIRE)
|
||||
if(WIRE_PARTICLE_POWER_LIMIT)
|
||||
C.visible_message("[bicon(C)]<b>[C]</b> makes a large whirring noise.")
|
||||
..()
|
||||
|
||||
/datum/wires/particle_acc/control_box/UpdateCut(index, mended)
|
||||
/datum/wires/particle_acc/control_box/on_cut(wire, mend)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
switch(index)
|
||||
|
||||
if(PARTICLE_TOGGLE_WIRE)
|
||||
if(C.active == !mended)
|
||||
switch(wire)
|
||||
if(WIRE_PARTICLE_POWER)
|
||||
if(C.active == !mend)
|
||||
C.toggle_power()
|
||||
|
||||
if(PARTICLE_STRENGTH_WIRE)
|
||||
|
||||
for(var/i = 1; i < 3; i++)
|
||||
if(WIRE_PARTICLE_STRENGTH)
|
||||
for(var/i in 1 to 2)
|
||||
C.remove_strength()
|
||||
|
||||
if(PARTICLE_INTERFACE_WIRE)
|
||||
C.interface_control = mended
|
||||
if(WIRE_PARTICLE_INTERFACE)
|
||||
C.interface_control = mend
|
||||
|
||||
if(PARTICLE_LIMIT_POWER_WIRE)
|
||||
C.strength_upper_limit = (mended ? 2 : 3)
|
||||
if(WIRE_PARTICLE_POWER_LIMIT)
|
||||
C.strength_upper_limit = (mend ? 2 : 3)
|
||||
if(C.strength_upper_limit < C.strength)
|
||||
C.remove_strength()
|
||||
..()
|
||||
|
||||
+27
-35
@@ -1,52 +1,44 @@
|
||||
/datum/wires/radio
|
||||
holder_type = /obj/item/radio
|
||||
wire_count = 3
|
||||
proper_name = "Radio"
|
||||
window_x = 330
|
||||
window_y = 37
|
||||
|
||||
#define RADIO_WIRE_SIGNAL 1
|
||||
#define RADIO_WIRE_RECEIVE 2
|
||||
#define RADIO_WIRE_TRANSMIT 4
|
||||
/datum/wires/radio/New(atom/_holder)
|
||||
wires = list(WIRE_RADIO_SIGNAL, WIRE_RADIO_RECEIVER, WIRE_RADIO_TRANSMIT)
|
||||
return ..()
|
||||
|
||||
/datum/wires/radio/GetWireName(index)
|
||||
switch(index)
|
||||
if(RADIO_WIRE_SIGNAL)
|
||||
return "Signal"
|
||||
|
||||
if(RADIO_WIRE_RECEIVE)
|
||||
return "Receiver"
|
||||
|
||||
if(RADIO_WIRE_TRANSMIT)
|
||||
return "Transmitter"
|
||||
|
||||
/datum/wires/radio/CanUse(mob/living/L)
|
||||
/datum/wires/radio/interactable(mob/user)
|
||||
var/obj/item/radio/R = holder
|
||||
if(R.b_stat)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/radio/UpdatePulsed(index)
|
||||
/datum/wires/radio/on_pulse(wire)
|
||||
var/obj/item/radio/R = holder
|
||||
switch(index)
|
||||
if(RADIO_WIRE_SIGNAL)
|
||||
R.listening = !R.listening && !IsIndexCut(RADIO_WIRE_RECEIVE)
|
||||
R.broadcasting = R.listening && !IsIndexCut(RADIO_WIRE_TRANSMIT)
|
||||
switch(wire)
|
||||
if(WIRE_RADIO_SIGNAL)
|
||||
R.listening = !R.listening && !is_cut(WIRE_RADIO_RECEIVER)
|
||||
R.broadcasting = R.listening && !is_cut(WIRE_RADIO_TRANSMIT)
|
||||
|
||||
if(RADIO_WIRE_RECEIVE)
|
||||
R.listening = !R.listening && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_RECEIVER)
|
||||
R.listening = !R.listening && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
|
||||
if(RADIO_WIRE_TRANSMIT)
|
||||
R.broadcasting = !R.broadcasting && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_TRANSMIT)
|
||||
R.broadcasting = !R.broadcasting && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
..()
|
||||
|
||||
/datum/wires/radio/UpdateCut(index, mended)
|
||||
/datum/wires/radio/on_cut(wire, mend)
|
||||
var/obj/item/radio/R = holder
|
||||
switch(index)
|
||||
if(RADIO_WIRE_SIGNAL)
|
||||
R.listening = mended && !IsIndexCut(RADIO_WIRE_RECEIVE)
|
||||
R.broadcasting = mended && !IsIndexCut(RADIO_WIRE_TRANSMIT)
|
||||
switch(wire)
|
||||
if(WIRE_RADIO_SIGNAL)
|
||||
R.listening = mend && !is_cut(WIRE_RADIO_RECEIVER)
|
||||
R.broadcasting = mend && !is_cut(WIRE_RADIO_TRANSMIT)
|
||||
|
||||
if(RADIO_WIRE_RECEIVE)
|
||||
R.listening = mended && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_RECEIVER)
|
||||
R.listening = mend && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
|
||||
if(RADIO_WIRE_TRANSMIT)
|
||||
R.broadcasting = mended && !IsIndexCut(RADIO_WIRE_SIGNAL)
|
||||
if(WIRE_RADIO_TRANSMIT)
|
||||
R.broadcasting = mend && !is_cut(WIRE_RADIO_SIGNAL)
|
||||
..()
|
||||
|
||||
+29
-64
@@ -1,32 +1,14 @@
|
||||
/datum/wires/robot
|
||||
random = 1
|
||||
randomize = TRUE
|
||||
holder_type = /mob/living/silicon/robot
|
||||
wire_count = 5
|
||||
window_x = 340
|
||||
window_y = 106
|
||||
proper_name = "Cyborg"
|
||||
|
||||
// /vg/ ordering
|
||||
|
||||
#define BORG_WIRE_MAIN_POWER 1 // The power wires do nothing whyyyyyyyyyyyyy
|
||||
#define BORG_WIRE_LOCKED_DOWN 2
|
||||
#define BORG_WIRE_CAMERA 4
|
||||
#define BORG_WIRE_AI_CONTROL 8 // Not used on MoMMIs
|
||||
#define BORG_WIRE_LAWCHECK 16 // Not used on MoMMIs
|
||||
|
||||
/datum/wires/robot/GetWireName(index)
|
||||
switch(index)
|
||||
if(BORG_WIRE_MAIN_POWER)
|
||||
return "Main Power"
|
||||
|
||||
if(BORG_WIRE_LOCKED_DOWN)
|
||||
return "Lockdown"
|
||||
|
||||
if(BORG_WIRE_CAMERA)
|
||||
return "Camera"
|
||||
|
||||
if(BORG_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
|
||||
if(BORG_WIRE_LAWCHECK)
|
||||
return "Law Check"
|
||||
/datum/wires/robot/New(atom/_holder)
|
||||
wires = list(WIRE_AI_CONTROL, WIRE_BORG_CAMERA, WIRE_BORG_LAWCHECK, WIRE_BORG_LOCKED)
|
||||
return ..()
|
||||
|
||||
/datum/wires/robot/get_status()
|
||||
. = ..()
|
||||
@@ -36,70 +18,53 @@
|
||||
. += "The Camera light is [(R.camera && R.camera.status == 1) ? "on" : "off"]."
|
||||
. += "The lockdown light is [R.lockcharge ? "on" : "off"]."
|
||||
|
||||
/datum/wires/robot/UpdateCut(index, mended)
|
||||
|
||||
/datum/wires/robot/on_cut(wire, mend)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
switch(index)
|
||||
if(BORG_WIRE_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI
|
||||
if(!mended)
|
||||
if(R.lawupdate == 1)
|
||||
switch(wire)
|
||||
if(WIRE_BORG_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI
|
||||
if(!mend)
|
||||
if(R.lawupdate)
|
||||
to_chat(R, "LawSync protocol engaged.")
|
||||
R.lawsync()
|
||||
R.show_laws()
|
||||
else
|
||||
if(R.lawupdate == 0 && !R.emagged)
|
||||
R.lawupdate = 1
|
||||
if(!R.lawupdate && !R.emagged)
|
||||
R.lawupdate = TRUE
|
||||
|
||||
if(BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control
|
||||
if(!mended)
|
||||
if(WIRE_AI_CONTROL) //Cut the AI wire to reset AI control
|
||||
if(!mend)
|
||||
if(R.connected_ai)
|
||||
R.disconnect_from_ai()
|
||||
|
||||
if(BORG_WIRE_CAMERA)
|
||||
if(WIRE_BORG_CAMERA)
|
||||
if(!isnull(R.camera) && !R.scrambledcodes)
|
||||
R.camera.status = mended
|
||||
R.camera.status = mend
|
||||
R.camera.toggle_cam(usr, 0) // Will kick anyone who is watching the Cyborg's camera.
|
||||
|
||||
if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh
|
||||
if(R.lawupdate)
|
||||
R.lawsync()
|
||||
|
||||
if(BORG_WIRE_LOCKED_DOWN)
|
||||
R.SetLockdown(!mended)
|
||||
if(WIRE_BORG_LOCKED)
|
||||
R.SetLockdown(!mend)
|
||||
..()
|
||||
|
||||
|
||||
/datum/wires/robot/UpdatePulsed(index)
|
||||
|
||||
/datum/wires/robot/on_pulse(wire)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
switch(index)
|
||||
if(BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI
|
||||
switch(wire)
|
||||
if(WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI
|
||||
if(!R.emagged)
|
||||
R.connect_to_ai(select_active_ai())
|
||||
|
||||
if(BORG_WIRE_CAMERA)
|
||||
if(WIRE_BORG_CAMERA)
|
||||
if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes)
|
||||
R.camera.toggle_cam(usr, 0) // Kick anyone watching the Cyborg's camera, doesn't display you disconnecting the camera.
|
||||
R.visible_message("[R]'s camera lense focuses loudly.")
|
||||
to_chat(R, "Your camera lense focuses loudly.")
|
||||
|
||||
if(BORG_WIRE_LOCKED_DOWN)
|
||||
if(WIRE_BORG_LOCKED)
|
||||
R.SetLockdown(!R.lockcharge) // Toggle
|
||||
..()
|
||||
|
||||
/datum/wires/robot/CanUse(mob/living/L)
|
||||
/datum/wires/robot/interactable(mob/user)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
if(R.wiresexposed)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/robot/proc/IsCameraCut()
|
||||
return wires_status & BORG_WIRE_CAMERA
|
||||
|
||||
/datum/wires/robot/proc/LockedCut()
|
||||
return wires_status & BORG_WIRE_LOCKED_DOWN
|
||||
|
||||
/datum/wires/robot/proc/CanLawCheck()
|
||||
return wires_status & BORG_WIRE_LAWCHECK
|
||||
|
||||
/datum/wires/robot/proc/AIHasControl()
|
||||
return wires_status & BORG_WIRE_AI_CONTROL
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
/datum/wires/smartfridge
|
||||
holder_type = /obj/machinery/smartfridge
|
||||
wire_count = 3
|
||||
proper_name = "Smartfridge"
|
||||
window_x = 340
|
||||
window_y = 103
|
||||
|
||||
/datum/wires/smartfridge/New(atom/_holder)
|
||||
wires = list(WIRE_ELECTRIFY, WIRE_IDSCAN, WIRE_THROW_ITEM)
|
||||
return ..()
|
||||
|
||||
/datum/wires/smartfridge/secure
|
||||
random = 1
|
||||
wire_count = 4
|
||||
randomize = TRUE
|
||||
wire_count = 4 // 3 actual, 1 dud.
|
||||
window_y = 97
|
||||
|
||||
#define SMARTFRIDGE_WIRE_ELECTRIFY 1
|
||||
#define SMARTFRIDGE_WIRE_THROW 2
|
||||
#define SMARTFRIDGE_WIRE_IDSCAN 4
|
||||
|
||||
/datum/wires/smartfridge/GetWireName(index)
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
return "Electrification"
|
||||
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
return "Item Throw"
|
||||
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
/datum/wires/smartfridge/CanUse(mob/living/L)
|
||||
/datum/wires/smartfridge/interactable(mob/user)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
if(!issilicon(L))
|
||||
if(S.seconds_electrified)
|
||||
if(S.shock(L, 100))
|
||||
return 0
|
||||
if(iscarbon(user) && S.Adjacent(user) && S.seconds_electrified && S.shock(user, 100))
|
||||
return FALSE
|
||||
if(S.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/smartfridge/get_status()
|
||||
. = ..()
|
||||
@@ -38,27 +29,27 @@
|
||||
. += "The red light is [S.shoot_inventory ? "off" : "blinking"]."
|
||||
. += "A [S.scan_id ? "purple" : "yellow"] light is on."
|
||||
|
||||
/datum/wires/smartfridge/UpdatePulsed(index)
|
||||
/datum/wires/smartfridge/on_pulse(wire)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
S.shoot_inventory = !S.shoot_inventory
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
if(WIRE_ELECTRIFY)
|
||||
S.seconds_electrified = 30
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
if(WIRE_IDSCAN)
|
||||
S.scan_id = !S.scan_id
|
||||
..()
|
||||
|
||||
/datum/wires/smartfridge/UpdateCut(index, mended)
|
||||
/datum/wires/smartfridge/on_cut(wire, mend)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
switch(index)
|
||||
if(SMARTFRIDGE_WIRE_THROW)
|
||||
S.shoot_inventory = !mended
|
||||
if(SMARTFRIDGE_WIRE_ELECTRIFY)
|
||||
if(mended)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
S.shoot_inventory = !mend
|
||||
if(WIRE_ELECTRIFY)
|
||||
if(mend)
|
||||
S.seconds_electrified = 0
|
||||
else
|
||||
S.seconds_electrified = -1
|
||||
if(SMARTFRIDGE_WIRE_IDSCAN)
|
||||
S.scan_id = 1
|
||||
if(WIRE_IDSCAN)
|
||||
S.scan_id = TRUE
|
||||
..()
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
/datum/wires/suitstorage
|
||||
holder_type = /obj/machinery/suit_storage_unit
|
||||
wire_count = 8
|
||||
proper_name = "Suit storage unit"
|
||||
window_x = 350
|
||||
window_y = 85
|
||||
|
||||
#define SSU_WIRE_ID 1
|
||||
#define SSU_WIRE_SHOCK 2
|
||||
#define SSU_WIRE_SAFETY 4
|
||||
#define SSU_WIRE_UV 8
|
||||
|
||||
|
||||
/datum/wires/suitstorage/GetWireName(index)
|
||||
switch(index)
|
||||
if(SSU_WIRE_ID)
|
||||
return "ID lock"
|
||||
if(SSU_WIRE_SHOCK)
|
||||
return "Shock wire"
|
||||
if(SSU_WIRE_SAFETY)
|
||||
return "Safety wire"
|
||||
if(SSU_WIRE_UV)
|
||||
return "UV wire"
|
||||
|
||||
/datum/wires/suitstorage/New(atom/_holder)
|
||||
wires = list(WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_SAFETY, WIRE_SSU_UV)
|
||||
return ..()
|
||||
|
||||
/datum/wires/suitstorage/get_status()
|
||||
. = ..()
|
||||
@@ -28,42 +17,48 @@
|
||||
. += "The green light is [A.shocked ? "on" : "off"]."
|
||||
. += "The UV display shows [A.uv_super ? "15 nm" : "185 nm"]."
|
||||
|
||||
datum/wires/suitstorage/CanUse()
|
||||
/datum/wires/suitstorage/interactable(mob/user)
|
||||
var/obj/machinery/suit_storage_unit/A = holder
|
||||
if(iscarbon(user) && A.Adjacent(user) && A.shocked)
|
||||
return A.shock(user, 100)
|
||||
if(A.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/suitstorage/UpdateCut(index, mended)
|
||||
/datum/wires/suitstorage/on_cut(wire, mend)
|
||||
var/obj/machinery/suit_storage_unit/A = holder
|
||||
switch(index)
|
||||
if(SSU_WIRE_ID)
|
||||
A.secure = mended
|
||||
if(SSU_WIRE_SAFETY)
|
||||
A.safeties = mended
|
||||
if(SSU_WIRE_SHOCK)
|
||||
A.shocked = !mended
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.secure = mend
|
||||
|
||||
if(WIRE_SAFETY)
|
||||
A.safeties = mend
|
||||
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !mend
|
||||
A.shock(usr, 50)
|
||||
if(SSU_WIRE_UV)
|
||||
A.uv_super = !mended
|
||||
|
||||
if(WIRE_SSU_UV)
|
||||
A.uv_super = !mend
|
||||
..()
|
||||
|
||||
datum/wires/suitstorage/UpdatePulsed(index)
|
||||
/datum/wires/suitstorage/on_pulse(wire)
|
||||
var/obj/machinery/suit_storage_unit/A = holder
|
||||
if(IsIndexCut(index))
|
||||
if(is_cut(wire))
|
||||
return
|
||||
switch(index)
|
||||
if(SSU_WIRE_ID)
|
||||
switch(wire)
|
||||
if(WIRE_IDSCAN)
|
||||
A.secure = !A.secure
|
||||
if(SSU_WIRE_SAFETY)
|
||||
|
||||
if(WIRE_SAFETY)
|
||||
A.safeties = !A.safeties
|
||||
if(SSU_WIRE_SHOCK)
|
||||
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !A.shocked
|
||||
if(A.shocked)
|
||||
A.shock(usr, 100)
|
||||
spawn(50)
|
||||
if(A && !IsIndexCut(index))
|
||||
A.shocked = FALSE
|
||||
if(SSU_WIRE_UV)
|
||||
addtimer(CALLBACK(A, /obj/machinery/suit_storage_unit/.proc/check_electrified_callback), 5 SECONDS)
|
||||
|
||||
if(WIRE_SSU_UV)
|
||||
A.uv_super = !A.uv_super
|
||||
..()
|
||||
|
||||
@@ -1,47 +1,31 @@
|
||||
/datum/wires/syndicatebomb
|
||||
random = TRUE
|
||||
randomize = TRUE
|
||||
holder_type = /obj/machinery/syndicatebomb
|
||||
wire_count = 5
|
||||
proper_name = "Syndicate bomb"
|
||||
window_x = 320
|
||||
window_y = 22
|
||||
|
||||
#define BOMB_WIRE_BOOM 1 // Explodes if pulsed or cut while active, defuses a bomb that isn't active on cut
|
||||
#define BOMB_WIRE_UNBOLT 2 // Unbolts the bomb if cut, hint on pulsed
|
||||
#define BOMB_WIRE_DELAY 4 // Raises the timer on pulse, does nothing on cut
|
||||
#define BOMB_WIRE_PROCEED 8 // Lowers the timer, explodes if cut while the bomb is active
|
||||
#define BOMB_WIRE_ACTIVATE 16 // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut
|
||||
/datum/wires/syndicatebomb/New(atom/_holder)
|
||||
wires = list(WIRE_BOMB_DELAY, WIRE_EXPLODE, WIRE_BOMB_UNBOLT,WIRE_BOMB_PROCEED, WIRE_BOMB_ACTIVATE)
|
||||
return ..()
|
||||
|
||||
/datum/wires/syndicatebomb/GetWireName(index)
|
||||
switch(index)
|
||||
if(BOMB_WIRE_BOOM)
|
||||
return "Explode"
|
||||
|
||||
if(BOMB_WIRE_UNBOLT)
|
||||
return "Unbolt"
|
||||
|
||||
if(BOMB_WIRE_DELAY)
|
||||
return "Delay"
|
||||
|
||||
if(BOMB_WIRE_PROCEED)
|
||||
return "Proceed"
|
||||
|
||||
if(BOMB_WIRE_ACTIVATE)
|
||||
return "Activate"
|
||||
|
||||
/datum/wires/syndicatebomb/CanUse(mob/living/L)
|
||||
/datum/wires/syndicatebomb/interactable(mob/user)
|
||||
var/obj/machinery/syndicatebomb/P = holder
|
||||
if(P.open_panel)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/syndicatebomb/UpdatePulsed(index)
|
||||
/datum/wires/syndicatebomb/on_pulse(wire)
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(index)
|
||||
if(BOMB_WIRE_BOOM)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
if(B.active)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] An alarm sounds! It's go-</span>")
|
||||
B.explode_now = TRUE
|
||||
if(BOMB_WIRE_UNBOLT)
|
||||
if(WIRE_BOMB_UNBOLT)
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The bolts spin in place for a moment.</span>")
|
||||
if(BOMB_WIRE_DELAY)
|
||||
if(WIRE_BOMB_DELAY)
|
||||
if(B.delayedbig)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bomb has already been delayed.</span>")
|
||||
else
|
||||
@@ -49,7 +33,7 @@
|
||||
playsound(B, 'sound/machines/chime.ogg', 30, 1)
|
||||
B.detonation_timer += 300
|
||||
B.delayedbig = TRUE
|
||||
if(BOMB_WIRE_PROCEED)
|
||||
if(WIRE_BOMB_PROCEED)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] The bomb buzzes ominously!</span>")
|
||||
playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1)
|
||||
var/seconds = B.seconds_remaining()
|
||||
@@ -59,7 +43,7 @@
|
||||
B.detonation_timer -= 100
|
||||
else if(seconds >= 11) // Both to prevent negative timers and to have a little mercy.
|
||||
B.detonation_timer = world.time + 100
|
||||
if(BOMB_WIRE_ACTIVATE)
|
||||
if(WIRE_BOMB_ACTIVATE)
|
||||
if(!B.active && !B.defused)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] You hear the bomb start ticking!</span>")
|
||||
B.activate()
|
||||
@@ -72,11 +56,11 @@
|
||||
B.delayedlittle = TRUE
|
||||
..()
|
||||
|
||||
/datum/wires/syndicatebomb/UpdateCut(index, mended)
|
||||
/datum/wires/syndicatebomb/on_cut(wire, mend)
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(index)
|
||||
if(BOMB_WIRE_BOOM)
|
||||
if(mended)
|
||||
switch(wire)
|
||||
if(WIRE_EXPLODE)
|
||||
if(mend)
|
||||
B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage.
|
||||
else
|
||||
if(B.active)
|
||||
@@ -84,17 +68,17 @@
|
||||
B.explode_now = TRUE
|
||||
else
|
||||
B.defused = TRUE
|
||||
if(BOMB_WIRE_UNBOLT)
|
||||
if(!mended && B.anchored)
|
||||
if(WIRE_BOMB_UNBOLT)
|
||||
if(!mend && B.anchored)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bolts lift out of the ground!</span>")
|
||||
playsound(B, 'sound/effects/stealthoff.ogg', 30, 1)
|
||||
B.anchored = FALSE
|
||||
if(BOMB_WIRE_PROCEED)
|
||||
if(!mended && B.active)
|
||||
if(WIRE_BOMB_PROCEED)
|
||||
if(!mend && B.active)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] An alarm sounds! It's go-</span>")
|
||||
B.explode_now = TRUE
|
||||
if(BOMB_WIRE_ACTIVATE)
|
||||
if(!mended && B.active)
|
||||
if(WIRE_BOMB_ACTIVATE)
|
||||
if(!mend && B.active)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The timer stops! The bomb has been defused!</span>")
|
||||
B.defused = TRUE
|
||||
B.update_icon()
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/datum/wires/tesla_coil
|
||||
wire_count = 1
|
||||
holder_type = /obj/machinery/power/tesla_coil
|
||||
proper_name = "Tesla coil"
|
||||
window_x = 320
|
||||
window_y = 50
|
||||
|
||||
#define TESLACOIL_WIRE_ZAP 1
|
||||
/datum/wires/tesla_coil/New(atom/_holder)
|
||||
wires = list(WIRE_TESLACOIL_ZAP)
|
||||
return ..()
|
||||
|
||||
/datum/wires/tesla_coil/GetWireName(index)
|
||||
switch(index)
|
||||
if(TESLACOIL_WIRE_ZAP)
|
||||
return "Zap"
|
||||
|
||||
/datum/wires/tesla_coil/CanUse(mob/living/L)
|
||||
/datum/wires/tesla_coil/interactable(mob/user)
|
||||
var/obj/machinery/power/tesla_coil/T = holder
|
||||
if(T && T.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/tesla_coil/UpdatePulsed(index)
|
||||
/datum/wires/tesla_coil/on_pulse(wire)
|
||||
var/obj/machinery/power/tesla_coil/T = holder
|
||||
switch(index)
|
||||
if(TESLACOIL_WIRE_ZAP)
|
||||
switch(wire)
|
||||
if(WIRE_TESLACOIL_ZAP)
|
||||
T.zap()
|
||||
..()
|
||||
|
||||
@@ -1,35 +1,21 @@
|
||||
/datum/wires/vending
|
||||
holder_type = /obj/machinery/vending
|
||||
wire_count = 4
|
||||
window_y = 112
|
||||
window_x = 350
|
||||
proper_name = "Vending machine"
|
||||
|
||||
#define VENDING_WIRE_THROW 1
|
||||
#define VENDING_WIRE_CONTRABAND 2
|
||||
#define VENDING_WIRE_ELECTRIFY 4
|
||||
#define VENDING_WIRE_IDSCAN 8
|
||||
/datum/wires/vending/New(atom/_holder)
|
||||
wires = list(WIRE_THROW_ITEM, WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_CONTRABAND)
|
||||
return ..()
|
||||
|
||||
/datum/wires/vending/GetWireName(index)
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
return "Item Throw"
|
||||
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
return "Contraband"
|
||||
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
return "Electrification"
|
||||
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
/datum/wires/vending/CanUse(mob/living/L)
|
||||
/datum/wires/vending/interactable(mob/user)
|
||||
var/obj/machinery/vending/V = holder
|
||||
if(!istype(L, /mob/living/silicon))
|
||||
if(V.seconds_electrified)
|
||||
if(V.shock(L, 100))
|
||||
return 0
|
||||
if(!istype(user, /mob/living/silicon) && V.seconds_electrified && V.shock(user, 100))
|
||||
return FALSE
|
||||
if(V.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/vending/get_status()
|
||||
. = ..()
|
||||
@@ -39,31 +25,31 @@
|
||||
. += "The green light is [V.extended_inventory ? "on" : "off"]."
|
||||
. += "A [V.scan_id ? "purple" : "yellow"] light is on."
|
||||
|
||||
/datum/wires/vending/UpdatePulsed(index)
|
||||
/datum/wires/vending/on_pulse(wire)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
V.shoot_inventory = !V.shoot_inventory
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
if(WIRE_CONTRABAND)
|
||||
V.extended_inventory = !V.extended_inventory
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
if(WIRE_ELECTRIFY)
|
||||
V.seconds_electrified = 30
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
if(WIRE_IDSCAN)
|
||||
V.scan_id = !V.scan_id
|
||||
..()
|
||||
|
||||
/datum/wires/vending/UpdateCut(index, mended)
|
||||
/datum/wires/vending/on_cut(wire, mend)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(index)
|
||||
if(VENDING_WIRE_THROW)
|
||||
V.shoot_inventory = !mended
|
||||
if(VENDING_WIRE_CONTRABAND)
|
||||
switch(wire)
|
||||
if(WIRE_THROW_ITEM)
|
||||
V.shoot_inventory = !mend
|
||||
if(WIRE_CONTRABAND)
|
||||
V.extended_inventory = FALSE
|
||||
if(VENDING_WIRE_ELECTRIFY)
|
||||
if(mended)
|
||||
if(WIRE_ELECTRIFY)
|
||||
if(mend)
|
||||
V.seconds_electrified = 0
|
||||
else
|
||||
V.seconds_electrified = -1
|
||||
if(VENDING_WIRE_IDSCAN)
|
||||
V.scan_id = 1
|
||||
if(WIRE_IDSCAN)
|
||||
V.scan_id = TRUE
|
||||
..()
|
||||
|
||||
+395
-270
@@ -1,331 +1,456 @@
|
||||
// Wire datums. Created by Giacomand.
|
||||
// Was created to replace a horrible case of copy and pasted code with no care for maintability.
|
||||
// Goodbye Door wires, Cyborg wires, Vending Machine wires, Autolathe wires
|
||||
// Protolathe wires, APC wires and Camera wires!
|
||||
|
||||
#define MAX_FLAG 65535
|
||||
|
||||
GLOBAL_LIST_EMPTY(same_wires)
|
||||
// 12 colours, if you're adding more than 12 wires then add more colours here
|
||||
GLOBAL_LIST_INIT(wireColours, list("red", "blue", "green", "black", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink"))
|
||||
|
||||
/datum/wires
|
||||
/// TRUE if the wires will be different every time a new wire datum is created.
|
||||
var/randomize = FALSE
|
||||
/// The atom the wires belong too. For example: an airlock.
|
||||
var/atom/holder
|
||||
/// The holder type; used to make sure that the holder is the correct type.
|
||||
var/holder_type
|
||||
/// The display name for the TGUI window. For example, given the var is "APC"...
|
||||
/// When the TGUI window is opened, "wires" will be appended to it's title, and it would become "APC wires".
|
||||
var/proper_name = "Unknown"
|
||||
/// The total number of wires that our holder atom has.
|
||||
var/wire_count = NONE
|
||||
/// A list of all wires. For a list of valid wires defines that can go here, see `code/__DEFINES/wires.dm`
|
||||
var/list/wires
|
||||
/// A list of all cut wires. The same values that can go into `wires` will get added and removed from this list.
|
||||
var/list/cut_wires
|
||||
/// An associative list with the wire color as the key, and the wire define as the value.
|
||||
var/list/colors
|
||||
/// An associative list of signalers attached to the wires. The wire color is the key, and the signaler object reference is the value.
|
||||
var/list/assemblies
|
||||
/// The width of the wire TGUI window.
|
||||
var/window_x = 300
|
||||
/// The height of the wire TGUI window. Will get longer as needed, based on the `wire_count`.
|
||||
var/window_y = 100
|
||||
|
||||
var/random = 0 // Will the wires be different for every single instance.
|
||||
var/atom/holder = null // The holder
|
||||
var/holder_type = null // The holder type; used to make sure that the holder is the correct type.
|
||||
var/wire_count = 0 // Max is 16
|
||||
var/wires_status = 0 // BITFLAG OF WIRES
|
||||
|
||||
var/list/wires = list()
|
||||
var/list/signallers = list()
|
||||
|
||||
var/table_options = " align='center'"
|
||||
var/row_options1 = " width='80px'"
|
||||
var/row_options2 = " width='260px'"
|
||||
var/window_x = 370
|
||||
var/window_y = 470
|
||||
|
||||
/datum/wires/New(atom/holder)
|
||||
/datum/wires/New(atom/_holder)
|
||||
..()
|
||||
src.holder = holder
|
||||
if(!istype(holder, holder_type))
|
||||
if(!istype(_holder, holder_type))
|
||||
CRASH("Our holder is null/the wrong type!")
|
||||
|
||||
// Generate new wires
|
||||
if(random)
|
||||
GenerateWires()
|
||||
// Get the same wires
|
||||
holder = _holder
|
||||
cut_wires = list()
|
||||
colors = list()
|
||||
assemblies = list()
|
||||
|
||||
// Add in the appropriate amount of dud wires.
|
||||
var/wire_len = length(wires)
|
||||
if(wire_len < wire_count) // If the amount of "real" wires is less than the total we're suppose to have...
|
||||
add_duds(wire_count - wire_len) // Add in the appropriate amount of duds to reach `wire_count`.
|
||||
|
||||
// If the randomize is true, we need to generate a new set of wires and ignore any wire color directories.
|
||||
if(randomize)
|
||||
randomize()
|
||||
return
|
||||
|
||||
if(!GLOB.wire_color_directory[holder_type])
|
||||
randomize()
|
||||
GLOB.wire_color_directory[holder_type] = colors
|
||||
else
|
||||
// We don't have any wires to copy yet, generate some and then copy it.
|
||||
if(!GLOB.same_wires[holder_type])
|
||||
GenerateWires()
|
||||
GLOB.same_wires[holder_type] = src.wires.Copy()
|
||||
else
|
||||
var/list/wires = GLOB.same_wires[holder_type]
|
||||
src.wires = wires // Reference the wires list.
|
||||
colors = GLOB.wire_color_directory[holder_type]
|
||||
|
||||
/datum/wires/Destroy()
|
||||
holder = null
|
||||
for(var/color in colors)
|
||||
detach_assembly(color)
|
||||
return ..()
|
||||
|
||||
/datum/wires/proc/GenerateWires()
|
||||
var/list/colours_to_pick = GLOB.wireColours.Copy() // Get a copy, not a reference.
|
||||
var/list/indexes_to_pick = list()
|
||||
//Generate our indexes
|
||||
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
||||
indexes_to_pick += i
|
||||
colours_to_pick.len = wire_count // Downsize it to our specifications.
|
||||
/**
|
||||
* Randomly generates a new set of wires. and corresponding colors from the given pool. Assigns the information as an associative list, to `colors`.
|
||||
*
|
||||
* In the `colors` list, the name of the color is the key, and the wire is the value.
|
||||
* For example: `colors["red"] = WIRE_ELECTRIFY`. This will look like `list("red" = WIRE_ELECTRIFY)` internally.
|
||||
*/
|
||||
/datum/wires/proc/randomize()
|
||||
var/static/list/possible_colors = list("red", "blue", "green", "silver", "orange", "brown", "gold", "white", "cyan", "magenta", "purple", "pink")
|
||||
var/list/my_possible_colors = possible_colors.Copy()
|
||||
|
||||
while(colours_to_pick.len && indexes_to_pick.len)
|
||||
// Pick and remove a colour
|
||||
var/colour = pick_n_take(colours_to_pick)
|
||||
|
||||
// Pick and remove an index
|
||||
var/index = pick_n_take(indexes_to_pick)
|
||||
|
||||
src.wires[colour] = index
|
||||
//wires = shuffle(wires)
|
||||
|
||||
/datum/wires/proc/get_status()
|
||||
return list()
|
||||
for(var/wire in shuffle(wires))
|
||||
colors[pick_n_take(my_possible_colors)] = wire
|
||||
|
||||
/**
|
||||
* Proc called when the user attempts to interact with wires UI.
|
||||
*
|
||||
* Checks if the user exists, is a mob, the wires are attached to something (`holder`) and makes sure `interactable(user)` returns TRUE.
|
||||
* If all the checks succeed, open the TGUI interface for the user.
|
||||
*
|
||||
* Arugments:
|
||||
* * user - the mob trying to interact with the wires.
|
||||
*/
|
||||
/datum/wires/proc/Interact(mob/user)
|
||||
if(user && istype(user) && holder && CanUse(user))
|
||||
ui_interact(user)
|
||||
if(user && istype(user) && holder && interactable(user))
|
||||
tgui_interact(user)
|
||||
|
||||
/datum/wires/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/**
|
||||
* Base proc, intended to be overriden. Wire datum specific checks you want to run before the TGUI is shown to the user should go here.
|
||||
*/
|
||||
/datum/wires/proc/interactable(mob/user)
|
||||
return TRUE
|
||||
|
||||
/// Users will be interacting with our holder object and not the wire datum directly, therefore we need to return the holder.
|
||||
/datum/wires/tgui_host()
|
||||
return holder
|
||||
|
||||
/datum/wires/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "wires.tmpl", holder.name, window_x, window_y)
|
||||
ui = new(user, src, ui_key, "Wires", "[proper_name] wires", window_x, window_y + wire_count * 30, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/datum/wires/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.physical_state)
|
||||
var/data[0]
|
||||
var/list/replace_colours = null
|
||||
/datum/wires/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/replace_colors
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(eyes && (COLOURBLIND in H.mutations))
|
||||
replace_colours = eyes.replace_colours
|
||||
if(eyes && (COLOURBLIND in H.mutations)) // Check if the human has colorblindness.
|
||||
replace_colors = eyes.replace_colours // Get the colorblind replacement colors list.
|
||||
|
||||
var/list/wires_list = list()
|
||||
|
||||
var/list/W[0]
|
||||
for(var/colour in wires)
|
||||
var/new_colour = colour
|
||||
var/colour_name = colour
|
||||
if(colour in replace_colours)
|
||||
new_colour = replace_colours[colour]
|
||||
if(new_colour in LIST_REPLACE_RENAME)
|
||||
colour_name = LIST_REPLACE_RENAME[new_colour]
|
||||
for(var/color in colors)
|
||||
var/replaced_color = color
|
||||
var/color_name = color
|
||||
|
||||
if(color in replace_colors) // If this color is one that needs to be replaced using the colorblindness list.
|
||||
replaced_color = replace_colors[color]
|
||||
if(replaced_color in LIST_COLOR_RENAME) // If its an ugly written color name like "darkolivegreen", rename it to something like "dark green".
|
||||
color_name = LIST_COLOR_RENAME[replaced_color]
|
||||
else
|
||||
colour_name = new_colour
|
||||
else
|
||||
new_colour = colour
|
||||
colour_name = new_colour
|
||||
W[++W.len] = list("colour_name" = capitalize(colour_name), "seen_colour" = capitalize(new_colour),"colour" = capitalize(colour), "cut" = IsColourCut(colour), "index" = can_see_wire_index(user) ? GetWireName(GetIndex(colour)) : null, "attached" = IsAttached(colour))
|
||||
color_name = replaced_color // Else just keep the normal color name
|
||||
|
||||
if(W.len > 0)
|
||||
data["wires"] = W
|
||||
wires_list += list(list(
|
||||
"seen_color" = replaced_color, // The color of the wire that the mob will see. This will be the same as `color` if the user is NOT colorblind.
|
||||
"color_name" = color_name, // The wire's name. This will be the same as `color` if the user is NOT colorblind.
|
||||
"color" = color, // The "real" color of the wire. No replacements.
|
||||
"wire" = can_see_wire_info(user) && !is_dud_color(color) ? get_wire(color) : null, // Wire define information like "Contraband" or "Door Bolts".
|
||||
"cut" = is_color_cut(color), // Whether the wire is cut or not. Used to display "cut" or "mend".
|
||||
"attached" = is_attached(color) // Whether or not a signaler is attached to this wire.
|
||||
))
|
||||
data["wires"] = wires_list
|
||||
|
||||
// Get the information shown at the bottom of wire TGUI window, such as "The red light is blinking", etc.
|
||||
// If the user is colorblind, we need to replace these colors as well.
|
||||
var/list/status = get_status()
|
||||
if(replace_colours)
|
||||
var/i
|
||||
for(i=1, i<=status.len, i++)
|
||||
for(var/colour in replace_colours)
|
||||
var/new_colour = replace_colours[colour]
|
||||
if(new_colour in LIST_REPLACE_RENAME)
|
||||
new_colour = LIST_REPLACE_RENAME[new_colour]
|
||||
if(findtext(status[i],colour))
|
||||
status[i] = replacetext(status[i],colour,new_colour)
|
||||
break
|
||||
data["status_len"] = status.len
|
||||
data["status"] = status
|
||||
|
||||
if(replace_colors)
|
||||
var/i
|
||||
for(i in 1 to length(status))
|
||||
for(var/color in replace_colors)
|
||||
var/new_color = replace_colors[color]
|
||||
if(new_color in LIST_COLOR_RENAME)
|
||||
new_color = LIST_COLOR_RENAME[new_color]
|
||||
if(findtext(status[i], color))
|
||||
status[i] = replacetext(status[i], color, new_color)
|
||||
break
|
||||
|
||||
data["status"] = status
|
||||
return data
|
||||
|
||||
/datum/wires/nano_host()
|
||||
return holder
|
||||
/datum/wires/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
/datum/wires/proc/can_see_wire_index(mob/user)
|
||||
var/mob/user = usr
|
||||
if(!interactable(user))
|
||||
return
|
||||
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
var/color = lowertext(params["wire"])
|
||||
holder.add_hiddenprint(user)
|
||||
|
||||
switch(action)
|
||||
// Toggles the cut/mend status.
|
||||
if("cut")
|
||||
if(!istype(I, /obj/item/wirecutters) && !user.can_admin_interact())
|
||||
to_chat(user, "<span class='error'>You need wirecutters!</span>")
|
||||
return
|
||||
|
||||
if(istype(I))
|
||||
playsound(holder, I.usesound, 20, 1)
|
||||
cut_color(color)
|
||||
return TRUE
|
||||
|
||||
// Pulse a wire.
|
||||
if("pulse")
|
||||
if(!istype(I, /obj/item/multitool) && !user.can_admin_interact())
|
||||
to_chat(user, "<span class='error'>You need a multitool!</span>")
|
||||
return
|
||||
|
||||
playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
|
||||
pulse_color(color)
|
||||
|
||||
// If they pulse the electrify wire, call interactable() and try to shock them.
|
||||
if(get_wire(color) == WIRE_ELECTRIFY)
|
||||
interactable(user)
|
||||
|
||||
return TRUE
|
||||
|
||||
// Attach a signaler to a wire.
|
||||
if("attach")
|
||||
if(is_attached(color))
|
||||
var/obj/item/O = detach_assembly(color)
|
||||
if(O)
|
||||
user.put_in_hands(O)
|
||||
return TRUE
|
||||
|
||||
if(!istype(I, /obj/item/assembly/signaler))
|
||||
to_chat(user, "<span class='error'>You need a remote signaller!</span>")
|
||||
return
|
||||
|
||||
if(user.drop_item())
|
||||
attach_assembly(color, I)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[user.get_active_hand()] is stuck to your hand!</span>")
|
||||
|
||||
/**
|
||||
* Proc called to determine if the user can see wire define information, such as "Contraband", "Door Bolts", etc.
|
||||
*
|
||||
* If the user is an admin, or has a multitool which reveals wire information in their active hand, the proc returns TRUE.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - the mob who is interacting with the wires.
|
||||
*/
|
||||
/datum/wires/proc/can_see_wire_info(mob/user)
|
||||
if(user.can_admin_interact())
|
||||
return TRUE
|
||||
else if(istype(user.get_active_hand(), /obj/item/multitool))
|
||||
var/obj/item/multitool/M = user.get_active_hand()
|
||||
if(M.shows_wire_information)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/wires/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
var/mob/L = usr
|
||||
if(CanUse(L) && href_list["action"])
|
||||
var/obj/item/I = L.get_active_hand()
|
||||
var/colour = lowertext(href_list["wire"])
|
||||
holder.add_hiddenprint(L)
|
||||
switch(href_list["action"])
|
||||
if("cut") // Toggles the cut/mend status
|
||||
if(istype(I, /obj/item/wirecutters) || L.can_admin_interact())
|
||||
if(istype(I))
|
||||
playsound(holder, I.usesound, 20, 1)
|
||||
CutWireColour(colour)
|
||||
else
|
||||
to_chat(L, "<span class='error'>You need wirecutters!</span>")
|
||||
if("pulse")
|
||||
if(istype(I, /obj/item/multitool) || L.can_admin_interact())
|
||||
playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
|
||||
PulseColour(colour)
|
||||
else
|
||||
to_chat(L, "<span class='error'>You need a multitool!</span>")
|
||||
if("attach")
|
||||
if(IsAttached(colour))
|
||||
var/obj/item/O = Detach(colour)
|
||||
if(O)
|
||||
L.put_in_hands(O)
|
||||
else
|
||||
if(istype(I, /obj/item/assembly/signaler))
|
||||
if(L.drop_item())
|
||||
Attach(colour, I)
|
||||
else
|
||||
to_chat(L, "<span class='warning'>[L.get_active_hand()] is stuck to your hand!</span>")
|
||||
else
|
||||
to_chat(L, "<span class='error'>You need a remote signaller!</span>")
|
||||
/**
|
||||
* Base proc, intended to be overwritten. Put wire information you'll see at the botton of the TGUI window here, such as "The red light is blinking".
|
||||
*/
|
||||
/datum/wires/proc/get_status()
|
||||
return list()
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
return 1
|
||||
/**
|
||||
* Clears the `colors` list, and randomizes it to a new set of color-to-wire relations.
|
||||
*/
|
||||
/datum/wires/proc/shuffle_wires()
|
||||
colors.Cut()
|
||||
randomize()
|
||||
|
||||
//
|
||||
// Overridable Procs
|
||||
//
|
||||
/**
|
||||
* Repairs all cut wires.
|
||||
*/
|
||||
/datum/wires/proc/repair()
|
||||
cut_wires.Cut()
|
||||
|
||||
// Called when wires cut/mended.
|
||||
/datum/wires/proc/UpdateCut(index, mended)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
/**
|
||||
* Adds in dud wires, which do nothing when cut/pulsed.
|
||||
*
|
||||
* Arguments:
|
||||
* * duds - the amount of dud wires to generate.
|
||||
*/
|
||||
/datum/wires/proc/add_duds(duds)
|
||||
while(duds)
|
||||
var/dud = WIRE_DUD_PREFIX + "[--duds]"
|
||||
if(dud in wires)
|
||||
continue
|
||||
wires += dud
|
||||
|
||||
// Called when wire pulsed. Add code here.
|
||||
/datum/wires/proc/UpdatePulsed(index)
|
||||
if(holder)
|
||||
SSnanoui.update_uis(holder)
|
||||
/**
|
||||
* Determines if the passed in wire is a dud or not. Returns TRUE if the wire is a dud, FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/is_dud(wire)
|
||||
return findtext(wire, WIRE_DUD_PREFIX, 1, length(WIRE_DUD_PREFIX) + 1)
|
||||
|
||||
/datum/wires/proc/CanUse(mob/L)
|
||||
return 1
|
||||
/**
|
||||
* Returns TRUE if the wire that corresponds to the passed in color is a dud. FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * color - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/is_dud_color(color)
|
||||
return is_dud(get_wire(color))
|
||||
|
||||
/datum/wires/CanUseTopic(mob/user, datum/topic_state/state)
|
||||
if(!CanUse(user))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
/**
|
||||
* Gets the wire associated with the color passed in.
|
||||
*
|
||||
* Arugments:
|
||||
* * color - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/get_wire(color)
|
||||
return colors[color]
|
||||
|
||||
// Example of use:
|
||||
/*
|
||||
/**
|
||||
* Determines if the passed in wire is cut or not. Returns TRUE if it's cut, FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/is_cut(wire)
|
||||
return (wire in cut_wires)
|
||||
|
||||
#define NAME_WIRE_BOLTED 1
|
||||
#define NAME_WIRE_SHOCKED 2
|
||||
#define NAME_WIRE_SAFETY 4
|
||||
#define NAME_WIRE_POWER 8
|
||||
/**
|
||||
* Determines if the wire associated with the passed in color, is cut or not. Returns TRUE if it's cut, FALSE otherwise.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/is_color_cut(color)
|
||||
return is_cut(get_wire(color))
|
||||
|
||||
/datum/wires/door/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(index)
|
||||
if(NAME_WIRE_BOLTED)
|
||||
if(!mended)
|
||||
A.bolt()
|
||||
if(NAME_WIRE_SHOCKED)
|
||||
A.shock()
|
||||
if(NAME_WIRE_SAFETY)
|
||||
A.safety()
|
||||
/**
|
||||
* Determines if all of the wires are cut. Returns TRUE they're all cut, FALSE otherwise.
|
||||
*/
|
||||
/datum/wires/proc/is_all_cut()
|
||||
return (length(cut_wires) == length(wires))
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Helper Procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/PulseColour(colour)
|
||||
PulseIndex(GetIndex(colour))
|
||||
|
||||
/datum/wires/proc/PulseIndex(index)
|
||||
if(IsIndexCut(index))
|
||||
return
|
||||
UpdatePulsed(index)
|
||||
|
||||
/datum/wires/proc/GetIndex(colour)
|
||||
if(wires[colour])
|
||||
var/index = wires[colour]
|
||||
return index
|
||||
/**
|
||||
* Cut or mend a wire. Calls `on_cut()`.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/cut(wire)
|
||||
if(is_cut(wire))
|
||||
cut_wires -= wire
|
||||
on_cut(wire, mend = TRUE)
|
||||
else
|
||||
CRASH("[colour] is not a key in wires.")
|
||||
cut_wires += wire
|
||||
on_cut(wire, mend = FALSE)
|
||||
|
||||
/datum/wires/proc/GetWireName(index)
|
||||
/**
|
||||
* Cut the wire which corresponds with the passed in color.
|
||||
*
|
||||
* Arugments:
|
||||
* * color - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/cut_color(color)
|
||||
cut(get_wire(color))
|
||||
|
||||
/**
|
||||
* Cuts a random wire.
|
||||
*/
|
||||
/datum/wires/proc/cut_random()
|
||||
cut(wires[rand(1, length(wires))])
|
||||
|
||||
/**
|
||||
* Cuts all wires.
|
||||
*/
|
||||
/datum/wires/proc/cut_all()
|
||||
for(var/wire in wires)
|
||||
cut(wire)
|
||||
|
||||
/**
|
||||
* Proc called when any wire is cut.
|
||||
*
|
||||
* Base proc, intended to be overriden.
|
||||
* Place an behavior you want to happen when certain wires are cut, into this proc.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT color. For example 'WIRE_ELECTRIFY'.
|
||||
* * mend - TRUE if we're mending the wire. FALSE if we're cutting.
|
||||
*/
|
||||
/datum/wires/proc/on_cut(wire, mend = FALSE)
|
||||
return
|
||||
|
||||
//
|
||||
// Is Index/Colour Cut procs
|
||||
//
|
||||
/**
|
||||
* Pulses the given wire. Calls `on_pulse()`.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`.
|
||||
*/
|
||||
/datum/wires/proc/pulse(wire)
|
||||
if(is_cut(wire))
|
||||
return
|
||||
on_pulse(wire)
|
||||
|
||||
/datum/wires/proc/IsColourCut(colour)
|
||||
var/index = GetIndex(colour)
|
||||
return IsIndexCut(index)
|
||||
/**
|
||||
* Pulses the wire associated with the given color.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire color.
|
||||
*/
|
||||
/datum/wires/proc/pulse_color(color)
|
||||
pulse(get_wire(color))
|
||||
|
||||
/datum/wires/proc/IsIndexCut(index)
|
||||
return (index & wires_status)
|
||||
/**
|
||||
* Proc called when any wire is pulsed.
|
||||
*
|
||||
* Base proc, intended to be overriden.
|
||||
* Place behavior you want to happen when certain wires are pulsed, into this proc.
|
||||
*
|
||||
* Arugments:
|
||||
* * wire - a wire define, NOT color. For example 'WIRE_ELECTRIFY'.
|
||||
*/
|
||||
/datum/wires/proc/on_pulse(wire)
|
||||
return
|
||||
|
||||
//
|
||||
// Signaller Procs
|
||||
//
|
||||
/**
|
||||
* Proc called when an attached signaler receives a signal.
|
||||
*
|
||||
* Searches through the `assemblies` list for the wire that the signaler is attached to. Pulses the wire when it's found.
|
||||
*
|
||||
* Arugments:
|
||||
* * S - the attached signaler receiving the signal.
|
||||
*/
|
||||
/datum/wires/proc/pulse_assembly(obj/item/assembly/signaler/S)
|
||||
for(var/color in assemblies)
|
||||
if(S == assemblies[color])
|
||||
pulse_color(color)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/proc/IsAttached(colour)
|
||||
if(signallers[colour])
|
||||
return 1
|
||||
return 0
|
||||
/**
|
||||
* Proc called when a mob tries to attach a signaler to a wire.
|
||||
*
|
||||
* Makes sure that `S` is actually a signaler and that something is not already attached to the wire.
|
||||
* Adds the signaler to the `assemblies` list as a value, with the `color` as a the key.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
* * S - the signaler that a mob is trying to attach.
|
||||
*/
|
||||
/datum/wires/proc/attach_assembly(color, obj/item/assembly/signaler/S)
|
||||
if(S && istype(S) && !is_attached(color))
|
||||
assemblies[color] = S
|
||||
S.forceMove(holder)
|
||||
S.connected = src
|
||||
return S
|
||||
|
||||
/datum/wires/proc/GetAttached(colour)
|
||||
if(signallers[colour])
|
||||
return signallers[colour]
|
||||
/**
|
||||
* Proc called when a mob tries to detach a signaler from a wire.
|
||||
*
|
||||
* First checks if there is a signaler on the wire. If so, removes the signaler, and clears it from `assemblies` list.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
*/
|
||||
/datum/wires/proc/detach_assembly(color)
|
||||
var/obj/item/assembly/signaler/S = get_attached(color)
|
||||
if(S && istype(S))
|
||||
assemblies -= color
|
||||
S.connected = null
|
||||
S.forceMove(holder.drop_location())
|
||||
return S
|
||||
|
||||
/**
|
||||
* Gets the signaler attached to the given wire color, if there is one.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
*/
|
||||
/datum/wires/proc/get_attached(color)
|
||||
if(assemblies[color])
|
||||
return assemblies[color]
|
||||
return null
|
||||
|
||||
/datum/wires/proc/Attach(colour, obj/item/assembly/signaler/S)
|
||||
if(colour && S)
|
||||
if(!IsAttached(colour))
|
||||
signallers[colour] = S
|
||||
S.loc = holder
|
||||
S.connected = src
|
||||
return S
|
||||
|
||||
/datum/wires/proc/Detach(colour)
|
||||
if(colour)
|
||||
var/obj/item/assembly/signaler/S = GetAttached(colour)
|
||||
if(S)
|
||||
signallers -= colour
|
||||
S.connected = null
|
||||
S.loc = holder.loc
|
||||
return S
|
||||
|
||||
|
||||
/datum/wires/proc/Pulse(obj/item/assembly/signaler/S)
|
||||
|
||||
for(var/colour in signallers)
|
||||
if(S == signallers[colour])
|
||||
PulseColour(colour)
|
||||
break
|
||||
|
||||
|
||||
//
|
||||
// Cut Wire Colour/Index procs
|
||||
//
|
||||
|
||||
/datum/wires/proc/CutWireColour(colour)
|
||||
var/index = GetIndex(colour)
|
||||
CutWireIndex(index)
|
||||
|
||||
/datum/wires/proc/CutWireIndex(index)
|
||||
if(IsIndexCut(index))
|
||||
wires_status &= ~index
|
||||
UpdateCut(index, 1)
|
||||
else
|
||||
wires_status |= index
|
||||
UpdateCut(index, 0)
|
||||
|
||||
/datum/wires/proc/RandomCut()
|
||||
var/r = rand(1, wires.len)
|
||||
CutWireIndex(r)
|
||||
|
||||
/datum/wires/proc/CutAll()
|
||||
for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
|
||||
CutWireIndex(i)
|
||||
|
||||
/datum/wires/proc/IsAllCut()
|
||||
if(wires_status == (1 << wire_count) - 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//
|
||||
//Shuffle and Mend
|
||||
//
|
||||
|
||||
/datum/wires/proc/Shuffle()
|
||||
wires_status = 0
|
||||
GenerateWires()
|
||||
/**
|
||||
* Checks if the given wire has a signaler on it.
|
||||
*
|
||||
* Arguments:
|
||||
* * color - the wire color.
|
||||
*/
|
||||
/datum/wires/proc/is_attached(color)
|
||||
if(assemblies[color])
|
||||
return TRUE
|
||||
|
||||
Reference in New Issue
Block a user