mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-25 04:57:12 +01:00
Merge branch 'master' into instrument-tgui-n-optimization
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
+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
|
||||
+4
-11
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -444,6 +444,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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -633,7 +633,6 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
contains = list(/obj/machinery/power/emitter,
|
||||
/obj/machinery/power/emitter)
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "emitter crate"
|
||||
access = ACCESS_CE
|
||||
containertype = /obj/structure/closet/crate/secure/engineering
|
||||
@@ -717,7 +716,7 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
name = "Supermatter Shard Crate"
|
||||
contains = list(/obj/machinery/power/supermatter_shard)
|
||||
cost = 50 //So cargo thinks twice before killing themselves with it
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containertype = /obj/structure/closet/crate/secure/engineering
|
||||
containername = "supermatter shard crate"
|
||||
access = ACCESS_CE
|
||||
|
||||
@@ -728,7 +727,7 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
/obj/item/pipe/circulator,
|
||||
/obj/item/pipe/circulator)
|
||||
cost = 25
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containertype = /obj/structure/closet/crate/secure/engineering
|
||||
containername = "thermo-electric generator crate"
|
||||
access = ACCESS_CE
|
||||
announce_beacons = list("Engineering" = list("Chief Engineer's Desk", "Atmospherics"))
|
||||
@@ -1174,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"
|
||||
|
||||
@@ -1725,8 +1725,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
|
||||
|
||||
+62
-106
@@ -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 test light is [haspower ? "on." : "off!"]"
|
||||
. += "The 'AI control allowed' light is [(A.aiControlDisabled == 0 && !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,16 +63,16 @@
|
||||
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)
|
||||
@@ -124,44 +85,44 @@
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
|
||||
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,40 @@
|
||||
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(WIRE_AI_CONTROL)
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
addtimer(CALLBACK(A, /obj/machinery/door/airlock/.proc/ai_control_callback), 1 SECONDS)
|
||||
|
||||
spawn(10)
|
||||
if(A)
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
|
||||
if(AIRLOCK_WIRE_ELECTRIFY)
|
||||
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