mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-28 22:48:38 +01:00
Merge remote-tracking branch 'VORE_MASTER/master' into clara-dev-pink-moo-drink
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
if(!H) return
|
||||
|
||||
log_and_message_admins("is altering the appearance of [H].")
|
||||
H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0, state = admin_state)
|
||||
H.change_appearance(APPEARANCE_ALL, usr, check_species_whitelist = 0, state = GLOB.tgui_admin_state)
|
||||
feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/change_human_appearance_self()
|
||||
@@ -29,10 +29,10 @@
|
||||
switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
|
||||
if("Yes")
|
||||
log_and_message_admins("has allowed [H] to change [T.his] appearance, without whitelisting of races.")
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
|
||||
H.change_appearance(APPEARANCE_ALL, H, check_species_whitelist = 0)
|
||||
if("No")
|
||||
log_and_message_admins("has allowed [H] to change [T.his] appearance, with whitelisting of races.")
|
||||
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
|
||||
H.change_appearance(APPEARANCE_ALL, H, check_species_whitelist = 1)
|
||||
feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/editappear()
|
||||
|
||||
@@ -31,58 +31,53 @@
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
|
||||
/obj/item/device/assembly/signaler/interact(var/mob/user)
|
||||
var/t1 = "-------"
|
||||
var/dat = {"
|
||||
<TT>
|
||||
/obj/item/device/assembly/signaler/interact(mob/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
tgui_interact(user)
|
||||
|
||||
<A href='byond://?src=\ref[src];send=1'>Send Signal</A><BR>
|
||||
<B>Frequency/Code</B> for signaler:<BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
||||
[format_frequency(src.frequency)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
/obj/item/device/assembly/signaler/tgui_state(mob/user)
|
||||
return GLOB.tgui_deep_inventory_state
|
||||
|
||||
Code:
|
||||
<A href='byond://?src=\ref[src];code=-5'>-</A>
|
||||
<A href='byond://?src=\ref[src];code=-1'>-</A>
|
||||
[src.code]
|
||||
<A href='byond://?src=\ref[src];code=1'>+</A>
|
||||
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
|
||||
[t1]
|
||||
</TT>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
/obj/item/device/assembly/signaler/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Signaler", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/assembly/signaler/Topic(href, href_list, state = deep_inventory_state)
|
||||
/obj/item/device/assembly/signaler/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["frequency"] = frequency
|
||||
data["code"] = code
|
||||
data["minFrequency"] = RADIO_LOW_FREQ
|
||||
data["maxFrequency"] = RADIO_HIGH_FREQ
|
||||
return data
|
||||
|
||||
/obj/item/device/assembly/signaler/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
|
||||
usr << browse(null, "window=radio")
|
||||
onclose(usr, "radio")
|
||||
return
|
||||
switch(action)
|
||||
if("signal")
|
||||
INVOKE_ASYNC(src, .proc/signal)
|
||||
. = TRUE
|
||||
if("freq")
|
||||
frequency = unformat_frequency(params["freq"])
|
||||
frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
|
||||
set_frequency(frequency)
|
||||
. = TRUE
|
||||
if("code")
|
||||
code = text2num(params["code"])
|
||||
code = clamp(round(code), 1, 100)
|
||||
. = TRUE
|
||||
if("reset")
|
||||
if(params["reset"] == "freq")
|
||||
set_frequency(initial(frequency))
|
||||
else
|
||||
code = initial(code)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["freq"])
|
||||
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
||||
if(new_frequency < RADIO_LOW_FREQ || new_frequency > RADIO_HIGH_FREQ)
|
||||
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
|
||||
set_frequency(new_frequency)
|
||||
|
||||
if(href_list["code"])
|
||||
src.code += text2num(href_list["code"])
|
||||
src.code = round(src.code)
|
||||
src.code = min(100, src.code)
|
||||
src.code = max(1, src.code)
|
||||
|
||||
if(href_list["send"])
|
||||
spawn( 0 )
|
||||
signal()
|
||||
|
||||
if(usr)
|
||||
attack_self(usr)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/assembly/signaler/attackby(var/obj/item/weapon/W, mob/user, params)
|
||||
if(issignaler(W))
|
||||
|
||||
@@ -115,6 +115,15 @@
|
||||
scarfs[initial(scarf_type.name)] = scarf_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(scarfs))
|
||||
|
||||
/datum/gear/accessory/scarfcolor
|
||||
display_name = "scarf (recolorable)"
|
||||
path = /obj/item/clothing/accessory/scarf/white
|
||||
cost = 1
|
||||
|
||||
/datum/gear/accessory/scarfcolor/New()
|
||||
..()
|
||||
gear_tweaks = list(gear_tweak_free_color_choice)
|
||||
|
||||
/datum/gear/accessory/jacket
|
||||
display_name = "suit jacket selection"
|
||||
path = /obj/item/clothing/accessory/jacket
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
/datum/gear/suit/mil
|
||||
display_name = "military jacket selection"
|
||||
path = /obj/item/clothing/suit/storage/miljacket
|
||||
|
||||
|
||||
/datum/gear/suit/mil/New()
|
||||
..()
|
||||
var/list/mil_jackets = list()
|
||||
|
||||
@@ -411,5 +411,15 @@
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/suit/teshcoatwhite/New()
|
||||
..()
|
||||
gear_tweaks = list(gear_tweak_free_color_choice)
|
||||
|
||||
/datum/gear/accessory/teshneckscarf
|
||||
display_name = "neckscarf, recolorable (Teshari)"
|
||||
path = /obj/item/clothing/accessory/scarf/teshari/neckscarf
|
||||
whitelisted = SPECIES_TESHARI
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/accessory/teshneckscarf/New()
|
||||
..()
|
||||
gear_tweaks = list(gear_tweak_free_color_choice)
|
||||
@@ -339,6 +339,8 @@ datum/preferences
|
||||
else if(href_list["resetslot"])
|
||||
if("No" == alert("This will reset the current slot. Continue?", "Reset current slot?", "No", "Yes"))
|
||||
return 0
|
||||
if("No" == alert("Are you completely sure that you want to reset this character slot?", "Reset current slot?", "No", "Yes"))
|
||||
return 0
|
||||
load_character(SAVE_RESET)
|
||||
sanitize_preferences()
|
||||
else if(href_list["copy"])
|
||||
|
||||
@@ -100,12 +100,12 @@
|
||||
mode = "sec"
|
||||
flash_protection = FLASH_PROTECTION_MAJOR
|
||||
action_button_name = "AR Console (Security Alerts)"
|
||||
arscreen_path = /datum/nano_module/alarm_monitor/security
|
||||
tgarscreen_path = /datum/tgui_module/alarm_monitor/security/glasses
|
||||
enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_WANTED,VIS_AUGMENTED)
|
||||
|
||||
ar_interact(var/mob/living/carbon/human/user)
|
||||
if(arscreen)
|
||||
arscreen.ui_interact(user,"main",null,1,glasses_state)
|
||||
if(tgarscreen)
|
||||
tgarscreen.tgui_interact(user)
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/glasses/omnihud/eng
|
||||
@@ -115,11 +115,11 @@
|
||||
mode = "eng"
|
||||
flash_protection = FLASH_PROTECTION_MAJOR
|
||||
action_button_name = "AR Console (Station Alerts)"
|
||||
arscreen_path = /datum/nano_module/alarm_monitor/engineering
|
||||
tgarscreen_path = /datum/tgui_module/alarm_monitor/engineering/glasses
|
||||
|
||||
ar_interact(var/mob/living/carbon/human/user)
|
||||
if(arscreen)
|
||||
arscreen.ui_interact(user,"main",null,1,glasses_state)
|
||||
if(tgarscreen)
|
||||
tgarscreen.tgui_interact(user)
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/glasses/omnihud/rnd
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
to_chat(usr, "Your module is not installed in a hardsuit.")
|
||||
return
|
||||
|
||||
module.holder.ui_interact(usr, nano_state = contained_state)
|
||||
module.holder.tgui_interact(usr, custom_state = GLOB.tgui_contained_state)
|
||||
|
||||
/obj/item/rig_module/ai_container
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
if(!target)
|
||||
if(ai_card)
|
||||
if(istype(ai_card,/obj/item/device/aicard))
|
||||
ai_card.ui_interact(H, state = deep_inventory_state)
|
||||
ai_card.tgui_interact(H, custom_state = deep_inventory_state)
|
||||
else
|
||||
eject_ai(H)
|
||||
update_verb_holder()
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
|
||||
var/suit_state //The string used for the suit's icon_state.
|
||||
|
||||
var/interface_path = "hardsuit.tmpl"
|
||||
var/ai_interface_path = "hardsuit.tmpl"
|
||||
var/interface_path = "RIGSuit"
|
||||
var/ai_interface_path = "RIGSuit"
|
||||
var/interface_title = "Hardsuit Controller"
|
||||
var/wearer_move_delay //Used for AI moving.
|
||||
var/ai_controlled_move_delay = 10
|
||||
@@ -284,6 +284,7 @@
|
||||
|
||||
if(!seal_target && !suit_is_deployed())
|
||||
M.visible_message("<span class='danger'>[M]'s suit flashes an error light.</span>","<span class='danger'>Your suit flashes an error light. It can't function properly without being fully deployed.</span>")
|
||||
playsound(src, 'sound/machines/rig/rigerror.ogg', 20, FALSE)
|
||||
failed_to_seal = 1
|
||||
|
||||
if(!failed_to_seal)
|
||||
@@ -293,6 +294,7 @@
|
||||
if(seal_delay && !do_after(M,seal_delay))
|
||||
if(M)
|
||||
to_chat(M, "<span class='warning'>You must remain still while the suit is adjusting the components.</span>")
|
||||
playsound(src, 'sound/machines/rig/rigerror.ogg', 20, FALSE)
|
||||
failed_to_seal = 1
|
||||
if(!M)
|
||||
failed_to_seal = 1
|
||||
@@ -340,6 +342,7 @@
|
||||
piece.armor["bio"] = 100
|
||||
else
|
||||
piece.armor["bio"] = src.armor["bio"]
|
||||
playsound(src, "[!seal_target ? 'sound/machines/boltsdown.ogg' : 'sound/machines/boltsup.ogg']", 10, FALSE)
|
||||
|
||||
else
|
||||
failed_to_seal = 1
|
||||
@@ -371,6 +374,7 @@
|
||||
else
|
||||
minihud = new (M.hud_used, src)
|
||||
to_chat(M, "<span class='notice'><b>Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].</b></span>")
|
||||
playsound(src, 'sound/machines/rig/rigstarted.ogg', 10, FALSE)
|
||||
M.client.screen -= booting_L
|
||||
qdel(booting_L)
|
||||
booting_R.icon_state = "boot_done"
|
||||
@@ -493,7 +497,7 @@
|
||||
wearer.wearing_rig = null
|
||||
wearer = null
|
||||
return PROCESS_KILL
|
||||
|
||||
|
||||
// Run through cooling
|
||||
coolingProcess()
|
||||
|
||||
@@ -508,6 +512,7 @@
|
||||
to_chat(wearer, "<span class='danger'>Your suit beeps stridently, and suddenly goes dead.</span>")
|
||||
else
|
||||
to_chat(wearer, "<span class='danger'>Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic composites instead of a powered suit.</span>")
|
||||
playsound(src, 'sound/machines/rig/rigdown.ogg', 60, FALSE)
|
||||
if(offline_vision_restriction == 1)
|
||||
to_chat(wearer, "<span class='danger'>The suit optics flicker and die, leaving you with restricted vision.</span>")
|
||||
else if(offline_vision_restriction == 2)
|
||||
@@ -565,6 +570,7 @@
|
||||
|
||||
if(fail_msg)
|
||||
to_chat(user, fail_msg)
|
||||
playsound(src, 'sound/machines/rig/rigerror.ogg', 20, FALSE)
|
||||
return 0
|
||||
|
||||
// This is largely for cancelling stealth and whatever.
|
||||
@@ -576,81 +582,6 @@
|
||||
cell.use(cost*10)
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/rig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/nano_state = inventory_state)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
var/list/data = list()
|
||||
|
||||
if(selected_module)
|
||||
data["primarysystem"] = "[selected_module.interface_name]"
|
||||
|
||||
if(src.loc != user)
|
||||
data["ai"] = 1
|
||||
|
||||
data["seals"] = "[src.canremove]"
|
||||
data["sealing"] = "[src.sealing]"
|
||||
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
|
||||
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
|
||||
data["boots"] = (boots ? "[boots.name]" : "None.")
|
||||
data["chest"] = (chest ? "[chest.name]" : "None.")
|
||||
|
||||
data["charge"] = cell ? round(cell.charge,1) : 0
|
||||
data["maxcharge"] = cell ? cell.maxcharge : 0
|
||||
data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0
|
||||
|
||||
data["emagged"] = subverted
|
||||
data["coverlock"] = locked
|
||||
data["interfacelock"] = interface_locked
|
||||
data["aicontrol"] = control_overridden
|
||||
data["aioverride"] = ai_override_enabled
|
||||
data["securitycheck"] = security_check_enabled
|
||||
data["malf"] = malfunction_delay
|
||||
|
||||
|
||||
var/list/module_list = list()
|
||||
var/i = 1
|
||||
for(var/obj/item/rig_module/module in installed_modules)
|
||||
var/list/module_data = list(
|
||||
"index" = i,
|
||||
"name" = "[module.interface_name]",
|
||||
"desc" = "[module.interface_desc]",
|
||||
"can_use" = "[module.usable]",
|
||||
"can_select" = "[module.selectable]",
|
||||
"can_toggle" = "[module.toggleable]",
|
||||
"is_active" = "[module.active]",
|
||||
"engagecost" = module.use_power_cost*10,
|
||||
"activecost" = module.active_power_cost*10,
|
||||
"passivecost" = module.passive_power_cost*10,
|
||||
"engagestring" = module.engage_string,
|
||||
"activatestring" = module.activate_string,
|
||||
"deactivatestring" = module.deactivate_string,
|
||||
"damage" = module.damage
|
||||
)
|
||||
|
||||
if(module.charges && module.charges.len)
|
||||
|
||||
module_data["charges"] = list()
|
||||
var/datum/rig_charge/selected = module.charges[module.charge_selected]
|
||||
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
|
||||
|
||||
for(var/chargetype in module.charges)
|
||||
var/datum/rig_charge/charge = module.charges[chargetype]
|
||||
module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]"))
|
||||
|
||||
module_list += list(module_data)
|
||||
i++
|
||||
|
||||
if(module_list.len)
|
||||
data["modules"] = module_list
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, state = nano_state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/weapon/rig/update_icon(var/update_mob_icon)
|
||||
|
||||
//TODO: Maybe consider a cache for this (use mob_icon as blank canvas, use suit icon overlay).
|
||||
@@ -698,44 +629,6 @@
|
||||
|
||||
return 1
|
||||
|
||||
//TODO: Fix Topic vulnerabilities for malfunction and AI override.
|
||||
/obj/item/weapon/rig/Topic(href,href_list)
|
||||
if(!check_suit_access(usr))
|
||||
return 0
|
||||
|
||||
if(href_list["toggle_piece"])
|
||||
if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying))
|
||||
return 0
|
||||
toggle_piece(href_list["toggle_piece"], usr)
|
||||
else if(href_list["toggle_seals"])
|
||||
toggle_seals(usr)
|
||||
else if(href_list["interact_module"])
|
||||
|
||||
var/module_index = text2num(href_list["interact_module"])
|
||||
|
||||
if(module_index > 0 && module_index <= installed_modules.len)
|
||||
var/obj/item/rig_module/module = installed_modules[module_index]
|
||||
switch(href_list["module_mode"])
|
||||
if("activate")
|
||||
module.activate()
|
||||
if("deactivate")
|
||||
module.deactivate()
|
||||
if("engage")
|
||||
module.engage()
|
||||
if("select")
|
||||
selected_module = module
|
||||
if("select_charge_type")
|
||||
module.charge_selected = href_list["charge_type"]
|
||||
else if(href_list["toggle_ai_control"])
|
||||
ai_override_enabled = !ai_override_enabled
|
||||
notify_ai("Synthetic suit control has been [ai_override_enabled ? "enabled" : "disabled"].")
|
||||
else if(href_list["toggle_suit_lock"])
|
||||
locked = !locked
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/rig/proc/notify_ai(var/message)
|
||||
for(var/obj/item/rig_module/ai_container/module in installed_modules)
|
||||
if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat)
|
||||
@@ -814,6 +707,7 @@
|
||||
if(istype(holder))
|
||||
if(use_obj && check_slot == use_obj)
|
||||
to_chat(H, "<span class='notice'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.</b></span>")
|
||||
playsound(src, 'sound/machines/boltsup.ogg', 10, FALSE)
|
||||
use_obj.canremove = 1
|
||||
holder.drop_from_inventory(use_obj)
|
||||
use_obj.forceMove(get_turf(src))
|
||||
@@ -832,6 +726,7 @@
|
||||
return
|
||||
else
|
||||
to_chat(H, "<span class='notice'>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</span>")
|
||||
playsound(src, 'sound/machines/boltsdown.ogg', 10, FALSE)
|
||||
|
||||
if(piece == "helmet" && helmet)
|
||||
helmet.update_light(H)
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* This defines the global UI for RIGSuits.
|
||||
* It has all of the relevant TGUI procs, but it's entry point is in rig_verbs.dm
|
||||
* as part of rig/proc/hardsuit_interface().
|
||||
*/
|
||||
|
||||
/*
|
||||
* tgui_interact() is the proc that opens the UI. It doesn't really do anything else, unlike NanoV1.
|
||||
* We add an extra argument, custom_state, for the things that want a custom state for their UI.
|
||||
*/
|
||||
/obj/item/weapon/rig/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, (loc != usr ? ai_interface_path : interface_path), interface_title)
|
||||
ui.open()
|
||||
if(custom_state)
|
||||
ui.set_state(custom_state)
|
||||
|
||||
/*
|
||||
* tgui_state() gives the UI the state to use by default.
|
||||
*/
|
||||
/obj/item/weapon/rig/tgui_state()
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/*
|
||||
* tgui_status() is middlewere for objects to add little exceptions or special cases to the state they use.
|
||||
* In this case, we're using it in order to make the UI refuse to let the user press any buttons if they're
|
||||
* not authorized to do so.
|
||||
* This saves us two lines of code in tgui_act().
|
||||
*/
|
||||
/obj/item/weapon/rig/tgui_status(mob/user, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(!check_suit_access(user))
|
||||
// Forces the UI to never go interactive,
|
||||
// but doesn't interfere with state saying to close.
|
||||
. = min(., STATUS_UPDATE)
|
||||
|
||||
/*
|
||||
* tgui_data() is the heavy lifter, it gives the UI it's relevant datastructure every SStgui tick.
|
||||
*/
|
||||
/obj/item/weapon/rig/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
if(selected_module)
|
||||
data["primarysystem"] = "[selected_module.interface_name]"
|
||||
else
|
||||
data["primarysystem"] = null
|
||||
|
||||
if(loc != user)
|
||||
data["ai"] = TRUE
|
||||
else
|
||||
data["ai"] = FALSE
|
||||
|
||||
data["sealed"] = !canremove
|
||||
data["sealing"] = sealing
|
||||
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
|
||||
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
|
||||
data["boots"] = (boots ? "[boots.name]" : "None.")
|
||||
data["chest"] = (chest ? "[chest.name]" : "None.")
|
||||
|
||||
data["helmetDeployed"] = (helmet && helmet.loc == loc)
|
||||
data["gauntletsDeployed"] = (gloves && gloves.loc == loc)
|
||||
data["bootsDeployed"] = (boots && boots.loc == loc)
|
||||
data["chestDeployed"] = (chest && chest.loc == loc)
|
||||
|
||||
data["charge"] = cell ? round(cell.charge,1) : 0
|
||||
data["maxcharge"] = cell ? cell.maxcharge : 0
|
||||
data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0
|
||||
|
||||
data["emagged"] = subverted
|
||||
data["coverlock"] = locked
|
||||
data["interfacelock"] = interface_locked
|
||||
data["aicontrol"] = control_overridden
|
||||
data["aioverride"] = ai_override_enabled
|
||||
data["securitycheck"] = security_check_enabled
|
||||
data["malf"] = malfunction_delay
|
||||
|
||||
var/list/module_list = list()
|
||||
if(!canremove && !sealing)
|
||||
var/i = 1
|
||||
for(var/obj/item/rig_module/module in installed_modules)
|
||||
var/list/module_data = list(
|
||||
"index" = i,
|
||||
"name" = "[module.interface_name]",
|
||||
"desc" = "[module.interface_desc]",
|
||||
"can_use" = module.usable,
|
||||
"can_select" = module.selectable,
|
||||
"can_toggle" = module.toggleable,
|
||||
"is_active" = module.active,
|
||||
"engagecost" = module.use_power_cost*10,
|
||||
"activecost" = module.active_power_cost*10,
|
||||
"passivecost" = module.passive_power_cost*10,
|
||||
"engagestring" = module.engage_string,
|
||||
"activatestring" = module.activate_string,
|
||||
"deactivatestring" = module.deactivate_string,
|
||||
"damage" = module.damage
|
||||
)
|
||||
|
||||
if(module.charges && module.charges.len)
|
||||
module_data["charges"] = list()
|
||||
var/datum/rig_charge/selected = module.charges[module.charge_selected]
|
||||
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
|
||||
|
||||
for(var/chargetype in module.charges)
|
||||
var/datum/rig_charge/charge = module.charges[chargetype]
|
||||
module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]"))
|
||||
|
||||
module_list += list(module_data)
|
||||
i++
|
||||
|
||||
if(module_list.len)
|
||||
data["modules"] = module_list
|
||||
else
|
||||
data["modules"] = list()
|
||||
|
||||
return data
|
||||
|
||||
/*
|
||||
* tgui_act() is the TGUI equivelent of Topic(). It's responsible for all of the "actions" you can take in the UI.
|
||||
*/
|
||||
/obj/item/weapon/rig/tgui_act(action, params)
|
||||
// This parent call is very important, as it's responsible for invoking tgui_status and checking our state's rules.
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
switch(action)
|
||||
if("toggle_seals")
|
||||
toggle_seals(usr)
|
||||
. = TRUE
|
||||
if("toggle_ai_control")
|
||||
ai_override_enabled = !ai_override_enabled
|
||||
notify_ai("Synthetic suit control has been [ai_override_enabled ? "enabled" : "disabled"].")
|
||||
. = TRUE
|
||||
if("toggle_suit_lock")
|
||||
locked = !locked
|
||||
. = TRUE
|
||||
if("toggle_piece")
|
||||
if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying))
|
||||
return FALSE
|
||||
toggle_piece(params["piece"], usr)
|
||||
. = TRUE
|
||||
if("interact_module")
|
||||
var/module_index = text2num(params["module"])
|
||||
|
||||
if(module_index > 0 && module_index <= installed_modules.len)
|
||||
var/obj/item/rig_module/module = installed_modules[module_index]
|
||||
switch(params["module_mode"])
|
||||
if("select")
|
||||
selected_module = module
|
||||
. = TRUE
|
||||
if("engage")
|
||||
module.engage()
|
||||
. = TRUE
|
||||
if("toggle")
|
||||
if(module.active)
|
||||
module.deactivate()
|
||||
else
|
||||
module.activate()
|
||||
. = TRUE
|
||||
if("select_charge_type")
|
||||
module.charge_selected = params["charge_type"]
|
||||
. = TRUE
|
||||
@@ -7,7 +7,7 @@
|
||||
set src = usr.contents
|
||||
|
||||
if(wearer && (wearer.back == src || wearer.belt == src))
|
||||
ui_interact(usr)
|
||||
tgui_interact(usr)
|
||||
|
||||
/obj/item/weapon/rig/verb/toggle_vision()
|
||||
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
icon = 'icons/obj/clothing/ties.dmi'
|
||||
icon_state = "bluetie"
|
||||
item_state_slots = list(slot_r_hand_str = "", slot_l_hand_str = "")
|
||||
appearance_flags = RESET_COLOR // Stops has_suit's color from being multiplied onto the accessory
|
||||
slot_flags = SLOT_TIE
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/slot = ACCESSORY_SLOT_DECOR
|
||||
var/obj/item/clothing/has_suit = null //the suit the tie may be attached to
|
||||
var/image/inv_overlay = null //overlay used when attached to clothing.
|
||||
var/obj/item/clothing/has_suit = null // The suit the tie may be attached to
|
||||
var/image/inv_overlay = null // Overlay used when attached to clothing.
|
||||
var/image/mob_overlay = null
|
||||
var/overlay_state = null
|
||||
var/concealed_holster = 0
|
||||
var/mob/living/carbon/human/wearer = null //To check if the wearer changes, so species spritesheets change properly.
|
||||
var/list/on_rolled = list() //used when jumpsuit sleevels are rolled ("rolled" entry) or it's rolled down ("down"). Set to "none" to hide in those states.
|
||||
var/mob/living/carbon/human/wearer = null // To check if the wearer changes, so species spritesheets change properly.
|
||||
var/list/on_rolled = list() // Used when jumpsuit sleevels are rolled ("rolled" entry) or it's rolled down ("down"). Set to "none" to hide in those states.
|
||||
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/ties.dmi') //Teshari can into webbing, too!
|
||||
|
||||
/obj/item/clothing/accessory/Destroy()
|
||||
@@ -29,6 +30,9 @@
|
||||
inv_overlay = image(icon = icon_override, icon_state = tmp_icon_state, dir = SOUTH)
|
||||
else
|
||||
inv_overlay = image(icon = INV_ACCESSORIES_DEF_ICON, icon_state = tmp_icon_state, dir = SOUTH)
|
||||
|
||||
inv_overlay.color = src.color
|
||||
inv_overlay.appearance_flags = appearance_flags // Stops has_suit's color from being multiplied onto the accessory
|
||||
return inv_overlay
|
||||
|
||||
/obj/item/clothing/accessory/proc/get_mob_overlay()
|
||||
@@ -65,6 +69,7 @@
|
||||
else
|
||||
mob_overlay.color = src.color
|
||||
|
||||
mob_overlay.appearance_flags = appearance_flags // Stops has_suit's color from being multiplied onto the accessory
|
||||
return mob_overlay
|
||||
|
||||
//when user attached an accessory to S
|
||||
@@ -72,8 +77,8 @@
|
||||
if(!istype(S))
|
||||
return
|
||||
has_suit = S
|
||||
loc = has_suit
|
||||
has_suit.overlays += get_inv_overlay()
|
||||
src.forceMove(S)
|
||||
has_suit.add_overlay(get_inv_overlay())
|
||||
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>You attach \the [src] to \the [has_suit].</span>")
|
||||
@@ -82,7 +87,7 @@
|
||||
/obj/item/clothing/accessory/proc/on_removed(var/mob/user)
|
||||
if(!has_suit)
|
||||
return
|
||||
has_suit.overlays -= get_inv_overlay()
|
||||
has_suit.cut_overlay(get_inv_overlay())
|
||||
has_suit = null
|
||||
if(user)
|
||||
usr.put_in_hands(src)
|
||||
@@ -325,6 +330,12 @@
|
||||
name = "striped blue scarf"
|
||||
icon_state = "stripedbluescarf"
|
||||
|
||||
/obj/item/clothing/accessory/scarf/teshari/neckscarf
|
||||
name = "small neckscarf"
|
||||
desc = "a neckscarf that is too small for a human's neck"
|
||||
icon_state = "tesh_neckscarf"
|
||||
species_restricted = list(SPECIES_TESHARI)
|
||||
|
||||
//bracelets
|
||||
|
||||
/obj/item/clothing/accessory/bracelet
|
||||
|
||||
@@ -45,6 +45,22 @@
|
||||
name = "small formal uniform"
|
||||
icon_state = "seromi_captain_formal"
|
||||
|
||||
/obj/item/clothing/under/seromi/smock/blackutilitysmock
|
||||
name = "black utility smock"
|
||||
icon_state = "teshari_blackutility_com"
|
||||
|
||||
/obj/item/clothing/under/seromi/smock/greydress
|
||||
name = "small grey dress"
|
||||
icon_state = "teshari_greydress"
|
||||
|
||||
/obj/item/clothing/under/seromi/smock/blackutility
|
||||
name = "Teshari utility uniform"
|
||||
icon_state = "teshari_blackutility"
|
||||
|
||||
/obj/item/clothing/under/seromi/smock/bluegreydress
|
||||
name = "small blue and grey dress"
|
||||
icon_state = "teshari_bluegreydress"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat
|
||||
name = "Undercoat"
|
||||
desc = "A Teshari traditional garb, with a modern twist! Made of micro and nanofibres to make it light and billowy, perfect for going fast and stylishly!"
|
||||
@@ -179,6 +195,66 @@
|
||||
icon_state = "tesh_uniform_brg"
|
||||
item_state = "tesh_uniform_brg"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/blackredworksuit
|
||||
name = "small black and red worksuit"
|
||||
icon_state = "teshari_black_red_worksuit"
|
||||
item_state = "teshari_black_red_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/blackpurpleworksuit
|
||||
name = "small black and purple worksuit"
|
||||
icon_state = "teshari_black_purple_worksuit"
|
||||
item_state = "teshari_black_purple_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/blackpurpleworksuit
|
||||
name = "small black and orange worksuit"
|
||||
icon_state = "teshari_black_orange_worksuit"
|
||||
item_state = "teshari_black_orange_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/blackblueworksuit
|
||||
name = "small black and blue worksuit"
|
||||
icon_state = "teshari_black_blue_worksuit"
|
||||
item_state = "teshari_black_blue_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/blackgreenworksuit
|
||||
name = "small black and greeen worksuit"
|
||||
icon_state = "teshari_black_green_worksuit"
|
||||
item_state = "teshari_black_green_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/whiteredworksuit
|
||||
name = "small white and red worksuit"
|
||||
icon_state = "teshari_white_red_worksuit"
|
||||
item_state = "teshari_white_red_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/whitepurpleworksuit
|
||||
name = "small white and purple worksuit"
|
||||
icon_state = "teshari_white_purple_worksuit"
|
||||
item_state = "teshari_white_purple_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/whiteorangeworksuit
|
||||
name = "small white and orange worksuit"
|
||||
icon_state = "teshari_white_orange_worksuit"
|
||||
item_state = "teshari_white_orange_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/whiteblueworksuit
|
||||
name = "small white and blue worksuit"
|
||||
icon_state = "teshari_white_blue_worksuit"
|
||||
item_state = "teshari_white_blue_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/standard/whitegreenworksuit
|
||||
name = "small white and green worksuit"
|
||||
icon_state = "teshari_white_green_worksuit"
|
||||
item_state = "teshari_white_green_worksuit"
|
||||
desc = "A small worksuit designed for a Teshari"
|
||||
|
||||
/obj/item/clothing/under/seromi/undercoat/jobs
|
||||
icon = 'icons/mob/species/seromi/deptjacket.dmi'
|
||||
icon_override = 'icons/mob/species/seromi/deptjacket.dmi'
|
||||
@@ -295,4 +371,4 @@
|
||||
name = "internal affairs undercoat"
|
||||
desc = "A traditional Teshari garb made for the Internal Affairs Agent"
|
||||
icon_state = "tesh_uniform_iaa"
|
||||
item_state = "tesh_uniform_iaa"
|
||||
item_state = "tesh_uniform_iaa"
|
||||
@@ -100,7 +100,7 @@
|
||||
src.icon_state = "mw"
|
||||
src.broken = 0 // Fix it!
|
||||
src.dirty = 0 // just to be sure
|
||||
src.flags = OPENCONTAINER
|
||||
src.flags = OPENCONTAINER | NOREACT
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It's broken!</span>")
|
||||
return 1
|
||||
@@ -119,7 +119,7 @@
|
||||
src.dirty = 0 // It's clean!
|
||||
src.broken = 0 // just to be sure
|
||||
src.icon_state = "mw"
|
||||
src.flags = OPENCONTAINER
|
||||
src.flags = OPENCONTAINER | NOREACT
|
||||
else //Otherwise bad luck!!
|
||||
to_chat(user, "<span class='warning'>It's dirty!</span>")
|
||||
return 1
|
||||
@@ -546,4 +546,4 @@
|
||||
if(istype(container, /obj/machinery/microwave))
|
||||
var/obj/machinery/microwave/M = container
|
||||
M.muck_finish()
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
@@ -243,7 +243,6 @@
|
||||
user.visible_message("[user] [panel_open ? "opens" : "closes"] the maintenance panel of \the [src].", "You [panel_open ? "open" : "close"] the maintenance panel of \the [src].")
|
||||
playsound(src, O.usesound, 50, 1)
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
if(wrenchable && default_unfasten_wrench(user, O, 20))
|
||||
@@ -263,7 +262,6 @@
|
||||
stock(O)
|
||||
user.visible_message("<span class='notice'>[user] has added \the [O] to \the [src].</span>", "<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
|
||||
|
||||
else if(istype(O, /obj/item/weapon/storage/bag))
|
||||
var/obj/item/weapon/storage/bag/P = O
|
||||
var/plants_loaded = 0
|
||||
@@ -309,11 +307,11 @@
|
||||
var/datum/stored_item/item = new/datum/stored_item(src, O.type, O.name)
|
||||
item.add_product(O)
|
||||
item_records.Add(item)
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/smartfridge/proc/vend(datum/stored_item/I)
|
||||
I.get_product(get_turf(src))
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/smartfridge/attack_ai(mob/user as mob)
|
||||
attack_hand(user)
|
||||
@@ -322,66 +320,59 @@
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
wires.Interact(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/*******************
|
||||
* SmartFridge Menu
|
||||
********************/
|
||||
/obj/machinery/smartfridge/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "SmartVend", name)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
/obj/machinery/smartfridge/tgui_data(mob/user)
|
||||
. = list()
|
||||
|
||||
var/data[0]
|
||||
data["contents"] = null
|
||||
data["electrified"] = seconds_electrified > 0
|
||||
data["shoot_inventory"] = shoot_inventory
|
||||
data["locked"] = locked
|
||||
data["secure"] = is_secure
|
||||
|
||||
var/list/items[0]
|
||||
for (var/i=1 to length(item_records))
|
||||
var/list/items = list()
|
||||
for(var/i=1 to length(item_records))
|
||||
var/datum/stored_item/I = item_records[i]
|
||||
var/count = I.get_amount()
|
||||
if(count > 0)
|
||||
items.Add(list(list("display_name" = html_encode(capitalize(I.item_name)), "vend" = i, "quantity" = count)))
|
||||
items.Add(list(list("name" = html_encode(capitalize(I.item_name)), "index" = i, "amount" = count)))
|
||||
|
||||
if(items.len > 0)
|
||||
data["contents"] = items
|
||||
.["contents"] = items
|
||||
.["name"] = name
|
||||
.["locked"] = locked
|
||||
.["secure"] = is_secure
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "smartfridge.tmpl", src.name, 400, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
/obj/machinery/smartfridge/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/smartfridge/Topic(href, href_list)
|
||||
if(..()) return 0
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("Release")
|
||||
var/amount = 0
|
||||
if(params["amount"])
|
||||
amount = params["amount"]
|
||||
else
|
||||
amount = input("How many items?", "How many items would you like to take out?", 1) as num|null
|
||||
|
||||
if(QDELETED(src) || QDELETED(usr) || !usr.Adjacent(src))
|
||||
return FALSE
|
||||
|
||||
var/index = text2num(params["index"])
|
||||
var/datum/stored_item/I = item_records[index]
|
||||
var/count = I.get_amount()
|
||||
|
||||
var/mob/user = usr
|
||||
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||
// Sanity check, there are probably ways to press the button when it shouldn't be possible.
|
||||
if(count > 0)
|
||||
if((count - amount) < 0)
|
||||
amount = count
|
||||
for(var/i = 1 to amount)
|
||||
vend(I)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if(href_list["close"])
|
||||
user.unset_machine()
|
||||
ui.close()
|
||||
return 0
|
||||
|
||||
if(href_list["vend"])
|
||||
var/index = text2num(href_list["vend"])
|
||||
var/amount = text2num(href_list["amount"])
|
||||
var/datum/stored_item/I = item_records[index]
|
||||
var/count = I.get_amount()
|
||||
|
||||
// Sanity check, there are probably ways to press the button when it shouldn't be possible.
|
||||
if(count > 0)
|
||||
if((count - amount) < 0)
|
||||
amount = count
|
||||
for(var/i = 1 to amount)
|
||||
vend(I)
|
||||
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/smartfridge/proc/throw_item()
|
||||
var/obj/throw_item = null
|
||||
@@ -400,17 +391,18 @@
|
||||
spawn(0)
|
||||
throw_item.throw_at(target,16,3,src)
|
||||
src.visible_message("<span class='warning'>[src] launches [throw_item.name] at [target.name]!</span>")
|
||||
SStgui.update_uis(src)
|
||||
return 1
|
||||
|
||||
/************************
|
||||
* Secure SmartFridges
|
||||
*************************/
|
||||
|
||||
/obj/machinery/smartfridge/secure/Topic(href, href_list)
|
||||
/obj/machinery/smartfridge/secure/tgui_act(action, params)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
return TRUE
|
||||
if(usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf)))
|
||||
if(!allowed(usr) && !emagged && locked != -1 && href_list["vend"])
|
||||
if(!allowed(usr) && !emagged && locked != -1 && action == "Release")
|
||||
to_chat(usr, "<span class='warning'>Access denied.</span>")
|
||||
return 0
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = default_state)
|
||||
var/datum/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist)
|
||||
/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR,
|
||||
var/mob/user = src,
|
||||
var/check_species_whitelist = 1,
|
||||
var/list/species_whitelist = list(),
|
||||
var/list/species_blacklist = list(),
|
||||
var/datum/tgui_state/state = GLOB.tgui_self_state)
|
||||
var/datum/tgui_module/appearance_changer/AC = new(src, src, check_species_whitelist, species_whitelist, species_blacklist)
|
||||
AC.flags = flags
|
||||
AC.ui_interact(user, state = state)
|
||||
AC.tgui_interact(user, custom_state = state)
|
||||
|
||||
/mob/living/carbon/human/proc/change_species(var/new_species)
|
||||
if(!new_species)
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
message = "does a flip!"
|
||||
m_type = 1
|
||||
if("vhelp") //Help for Virgo-specific emotes.
|
||||
to_chat(src, "vwag, vflap, mlem, blep, awoo, awoo2, growl, nya, peep, chirp, hoot, weh, merp, myarp, bark, bork, mrow, mrowl, hypno, hiss, rattle, squeak, geck, baa, baa2, mar, wurble, snort, meow, moo, croak, nsay, nme, flip")
|
||||
to_chat(src, "vwag, vflap, mlem, blep, awoo, awoo2, growl, nya, peep, chirp, hoot, weh, merp, myarp, bark, bork, mrow, mrowl, hypno, hiss, rattle, squeak, geck, baa, baa2, mar, wurble, snort, meow, moo, croak, gao, cackle, nsay, nme, flip")
|
||||
return TRUE
|
||||
|
||||
if(message)
|
||||
|
||||
@@ -14,111 +14,107 @@
|
||||
/obj/machinery/computer/drone_control/attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/drone_control/tgui_status(mob/user)
|
||||
if(!allowed(user))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/drone_control/attack_hand(var/mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat
|
||||
dat += "<B>Maintenance Units</B><BR>"
|
||||
/obj/machinery/computer/drone_control/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "DroneConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/drone_control/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["drones"] = list()
|
||||
for(var/mob/living/silicon/robot/drone/D in mob_list)
|
||||
if(D.z != src.z)
|
||||
if(D.z != z)
|
||||
continue
|
||||
if(D.foreign_droid)
|
||||
continue
|
||||
|
||||
data["drones"].Add(list(list(
|
||||
"name" = D.real_name,
|
||||
"active" = D.stat != 2,
|
||||
"charge" = D.cell.charge,
|
||||
"maxCharge" = D.cell.maxcharge,
|
||||
"loc" = "[get_area(D)]",
|
||||
"ref" = "\ref[D]",
|
||||
)))
|
||||
|
||||
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE</FONT>" : "<font color='green'>ACTIVE</FONT>"])"
|
||||
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
|
||||
dat += "<BR>Currently located in: [get_area(D)]."
|
||||
dat += "<BR><A href='?src=\ref[src];resync=\ref[D]'>Resync</A> | <A href='?src=\ref[src];shutdown=\ref[D]'>Shutdown</A></font>"
|
||||
data["fabricator"] = dronefab
|
||||
data["fabPower"] = dronefab?.produce_drones
|
||||
|
||||
dat += "<BR><BR><B>Request drone presence in area:</B> <A href='?src=\ref[src];setarea=1'>[drone_call_area]</A> (<A href='?src=\ref[src];ping=1'>Send ping</A>)"
|
||||
data["areas"] = tagger_locations
|
||||
data["selected_area"] = "[drone_call_area]"
|
||||
|
||||
dat += "<BR><BR><B>Drone fabricator</B>: "
|
||||
dat += "[dronefab ? "<A href='?src=\ref[src];toggle_fab=1'>[(dronefab.produce_drones && !(dronefab.stat & NOPOWER)) ? "ACTIVE" : "INACTIVE"]</A>" : "<font color='red'><b>FABRICATOR NOT DETECTED.</b></font> (<A href='?src=\ref[src];search_fab=1'>search</a>)"]"
|
||||
user << browse(dat, "window=computer;size=400x500")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
return data
|
||||
|
||||
|
||||
/obj/machinery/computer/drone_control/Topic(href, href_list)
|
||||
/obj/machinery/computer/drone_control/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(!allowed(usr))
|
||||
to_chat(usr, "<span class='danger'>Access denied.</span>")
|
||||
return
|
||||
switch(action)
|
||||
if("set_dcall_area")
|
||||
var/t_area = params["area"]
|
||||
if(!t_area || !(t_area in tagger_locations))
|
||||
return
|
||||
|
||||
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
usr.set_machine(src)
|
||||
drone_call_area = t_area
|
||||
to_chat(usr, "<span class='notice'>You set the area selector to [drone_call_area].</span>")
|
||||
|
||||
if (href_list["setarea"])
|
||||
if("ping")
|
||||
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
|
||||
for(var/mob/living/silicon/robot/drone/D in player_list)
|
||||
if(D.stat == 0)
|
||||
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
|
||||
|
||||
//Probably should consider using another list, but this one will do.
|
||||
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in tagger_locations
|
||||
if("resync")
|
||||
var/mob/living/silicon/robot/drone/D = locate(params["ref"])
|
||||
|
||||
if(!t_area)
|
||||
return
|
||||
if(D.stat != 2)
|
||||
to_chat(usr, "<span class='danger'>You issue a law synchronization directive for the drone.</span>")
|
||||
D.law_resync()
|
||||
|
||||
drone_call_area = t_area
|
||||
to_chat(usr, "<span class='notice'>You set the area selector to [drone_call_area].</span>")
|
||||
if("shutdown")
|
||||
var/mob/living/silicon/robot/drone/D = locate(params["ref"])
|
||||
|
||||
else if (href_list["ping"])
|
||||
if(D.stat != 2)
|
||||
to_chat(usr, "<span class='danger'>You issue a kill command for the unfortunate drone.</span>")
|
||||
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
|
||||
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
|
||||
D.shut_down()
|
||||
|
||||
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
|
||||
for(var/mob/living/silicon/robot/drone/D in player_list)
|
||||
if(D.stat == 0)
|
||||
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
|
||||
if("search_fab")
|
||||
if(dronefab)
|
||||
return
|
||||
|
||||
else if (href_list["resync"])
|
||||
for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
|
||||
if(fab.stat & NOPOWER)
|
||||
continue
|
||||
|
||||
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
|
||||
dronefab = fab
|
||||
to_chat(usr, "<span class='notice'>Drone fabricator located.</span>")
|
||||
return
|
||||
|
||||
if(D.stat != 2)
|
||||
to_chat(usr, "<span class='danger'>You issue a law synchronization directive for the drone.</span>")
|
||||
D.law_resync()
|
||||
|
||||
else if (href_list["shutdown"])
|
||||
|
||||
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
|
||||
|
||||
if(D.stat != 2)
|
||||
to_chat(usr, "<span class='danger'>You issue a kill command for the unfortunate drone.</span>")
|
||||
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
|
||||
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
|
||||
D.shut_down()
|
||||
|
||||
else if (href_list["search_fab"])
|
||||
if(dronefab)
|
||||
return
|
||||
|
||||
for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
|
||||
|
||||
if(fab.stat & NOPOWER)
|
||||
continue
|
||||
|
||||
dronefab = fab
|
||||
to_chat(usr, "<span class='notice'>Drone fabricator located.</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
|
||||
|
||||
else if (href_list["toggle_fab"])
|
||||
|
||||
if(!dronefab)
|
||||
return
|
||||
|
||||
if(get_dist(src,dronefab) > 3)
|
||||
dronefab = null
|
||||
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
|
||||
return
|
||||
|
||||
dronefab.produce_drones = !dronefab.produce_drones
|
||||
to_chat(usr, "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>")
|
||||
if("toggle_fab")
|
||||
if(!dronefab)
|
||||
return
|
||||
|
||||
src.updateUsrDialog()
|
||||
if(get_dist(src,dronefab) > 3)
|
||||
dronefab = null
|
||||
to_chat(usr, "<span class='danger'>Unable to locate drone fabricator.</span>")
|
||||
return
|
||||
|
||||
dronefab.produce_drones = !dronefab.produce_drones
|
||||
to_chat(usr, "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>")
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
drop_item()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gripper/AltClick(mob/user)
|
||||
drop_item()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gripper/omni
|
||||
name = "omni gripper"
|
||||
desc = "A strange grasping tool that can hold anything a human can, but still maintains the limitations of application its more limited cousins have."
|
||||
@@ -252,12 +256,15 @@
|
||||
return resolved
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gripper/verb/drop_item()
|
||||
/obj/item/weapon/gripper/verb/drop_gripper_item()
|
||||
|
||||
set name = "Drop Item"
|
||||
set desc = "Release an item from your magnetic gripper."
|
||||
set category = "Robot Commands"
|
||||
|
||||
drop_item()
|
||||
|
||||
obj/item/weapon/gripper/proc/drop_item()
|
||||
if(!wrapped)
|
||||
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
|
||||
for(var/obj/item/thing in src.contents)
|
||||
@@ -268,7 +275,7 @@
|
||||
wrapped = null
|
||||
return
|
||||
|
||||
to_chat(src.loc, "<span class='danger'>You drop \the [wrapped].</span>")
|
||||
to_chat(src.loc, "<span class='notice'>You drop \the [wrapped].</span>")
|
||||
wrapped.loc = get_turf(src)
|
||||
wrapped = null
|
||||
//update_icon()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/mob/living/silicon
|
||||
var/register_alarms = 1
|
||||
var/datum/nano_module/alarm_monitor/all/alarm_monitor
|
||||
var/datum/nano_module/atmos_control/atmos_control
|
||||
var/datum/tgui_module/alarm_monitor/all/robot/alarm_monitor
|
||||
var/datum/tgui_module/atmos_control/robot/atmos_control
|
||||
var/datum/tgui_module/crew_monitor/robot/crew_monitor
|
||||
var/datum/nano_module/law_manager/law_manager
|
||||
var/datum/nano_module/power_monitor/power_monitor
|
||||
var/datum/nano_module/rcon/rcon
|
||||
var/datum/tgui_module/power_monitor/robot/power_monitor
|
||||
var/datum/tgui_module/rcon/robot/rcon
|
||||
|
||||
/mob/living/silicon
|
||||
var/list/silicon_subsystems = list(
|
||||
@@ -49,7 +49,7 @@
|
||||
set name = "Alarm Monitor"
|
||||
set category = "Subystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr, state = self_state)
|
||||
alarm_monitor.tgui_interact(usr)
|
||||
|
||||
/********************
|
||||
* Atmos Control *
|
||||
@@ -58,7 +58,7 @@
|
||||
set category = "Subystems"
|
||||
set name = "Atmospherics Control"
|
||||
|
||||
atmos_control.ui_interact(usr, state = self_state)
|
||||
atmos_control.tgui_interact(usr)
|
||||
|
||||
/********************
|
||||
* Crew Monitor *
|
||||
@@ -85,7 +85,7 @@
|
||||
set category = "Subystems"
|
||||
set name = "Power Monitor"
|
||||
|
||||
power_monitor.ui_interact(usr, state = self_state)
|
||||
power_monitor.tgui_interact(usr)
|
||||
|
||||
/************
|
||||
* RCON *
|
||||
@@ -94,4 +94,4 @@
|
||||
set category = "Subystems"
|
||||
set name = "RCON"
|
||||
|
||||
rcon.ui_interact(usr, state = self_state)
|
||||
rcon.tgui_interact(usr)
|
||||
|
||||
+21
-6
@@ -343,7 +343,7 @@
|
||||
|
||||
/mob/proc/set_respawn_timer(var/time)
|
||||
// Try to figure out what time to use
|
||||
|
||||
|
||||
// Special cases, can never respawn
|
||||
if(ticker?.mode?.deny_respawn)
|
||||
time = -1
|
||||
@@ -351,22 +351,22 @@
|
||||
time = -1
|
||||
else if(!config.respawn)
|
||||
time = -1
|
||||
|
||||
|
||||
// Special case for observing before game start
|
||||
else if(ticker?.current_state <= GAME_STATE_SETTING_UP)
|
||||
time = 1 MINUTE
|
||||
|
||||
|
||||
// Wasn't given a time, use the config time
|
||||
else if(!time)
|
||||
time = config.respawn_time
|
||||
|
||||
|
||||
var/keytouse = ckey
|
||||
// Try harder to find a key to use
|
||||
if(!keytouse && key)
|
||||
keytouse = ckey(key)
|
||||
else if(!keytouse && mind?.key)
|
||||
keytouse = ckey(mind.key)
|
||||
|
||||
|
||||
GLOB.respawn_timers[keytouse] = world.time + time
|
||||
|
||||
/mob/observer/dead/set_respawn_timer()
|
||||
@@ -388,7 +388,7 @@
|
||||
var/choice = alert(usr, "Returning to the menu will prevent your character from being revived in-round. Are you sure?", "Confirmation", "No, wait", "Yes, leave")
|
||||
if(choice == "No, wait")
|
||||
return
|
||||
|
||||
|
||||
// Beyond this point, you're going to respawn
|
||||
to_chat(usr, config.respawn_message)
|
||||
|
||||
@@ -505,6 +505,11 @@
|
||||
set category = "IC"
|
||||
|
||||
if(pulling)
|
||||
if(ishuman(pulling))
|
||||
var/mob/living/carbon/human/H = pulling
|
||||
visible_message(SPAN_WARNING("\The [src] lets go of \the [H]."), SPAN_NOTICE("You let go of \the [H]."), exclude_mobs = list(H))
|
||||
if(!H.stat)
|
||||
to_chat(H, SPAN_WARNING("\The [src] lets go of you."))
|
||||
pulling.pulledby = null
|
||||
pulling = null
|
||||
if(pullin)
|
||||
@@ -576,6 +581,16 @@
|
||||
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(H.lying) // If they're on the ground we're probably dragging their arms to move them
|
||||
visible_message(SPAN_WARNING("\The [src] leans down and grips \the [H]'s arms."), SPAN_NOTICE("You lean down and grip \the [H]'s arms."), exclude_mobs = list(H))
|
||||
if(!H.stat)
|
||||
to_chat(H, SPAN_WARNING("\The [src] leans down and grips your arms."))
|
||||
else //Otherwise we're probably just holding their arm to lead them somewhere
|
||||
visible_message(SPAN_WARNING("\The [src] grips \the [H]'s arm."), SPAN_NOTICE("You grip \the [H]'s arm."), exclude_mobs = list(H))
|
||||
if(!H.stat)
|
||||
to_chat(H, SPAN_WARNING("\The [src] grips your arm."))
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 25) //Quieter than hugging/grabbing but we still want some audio feedback
|
||||
|
||||
if(H.pull_damage())
|
||||
to_chat(src, "<font color='red'><B>Pulling \the [H] in their current condition would probably be a bad idea.</B></font>")
|
||||
|
||||
|
||||
@@ -582,7 +582,6 @@
|
||||
// Do the initial caching of the player's body icons.
|
||||
new_character.force_update_limbs()
|
||||
new_character.update_icons_body()
|
||||
new_character.update_eyes()
|
||||
|
||||
new_character.key = key //Manually transfer the key to log them in
|
||||
|
||||
|
||||
@@ -1304,6 +1304,35 @@
|
||||
icon_state = "teshari_mushroom"
|
||||
species_allowed = list(SPECIES_TESHARI)
|
||||
|
||||
//Tesh things ported from Ark Station
|
||||
|
||||
teshari_twies
|
||||
name = "Teshari Twies"
|
||||
icon_state = "teshari_twies"
|
||||
species_allowed = list(SPECIES_TESHARI)
|
||||
|
||||
teshari_backstrafe
|
||||
name = "Teshari Backstrafe"
|
||||
icon_state = "teshari_backstrafe"
|
||||
species_allowed = list(SPECIES_TESHARI)
|
||||
|
||||
teshari_longway
|
||||
name = "Teshari Long way"
|
||||
icon_state = "teshari_longway"
|
||||
species_allowed = list(SPECIES_TESHARI)
|
||||
|
||||
teshari_tree
|
||||
name = "Teshari Tree"
|
||||
icon_state = "teshari_tree"
|
||||
species_allowed = list(SPECIES_TESHARI)
|
||||
|
||||
teshari_fluffymohawk
|
||||
name = "Teshari Fluffy Mohawk"
|
||||
icon_state = "teshari_fluffymohawk"
|
||||
species_allowed = list(SPECIES_TESHARI)
|
||||
|
||||
//bald tesh hair for FBP use
|
||||
|
||||
teshari_bald
|
||||
name = "Bald (use with FBP)"
|
||||
icon_state = "bald"
|
||||
|
||||
@@ -57,41 +57,43 @@
|
||||
ntnet_global.add_log("Quantum relay switched from overload recovery mode to normal operation mode.")
|
||||
..()
|
||||
|
||||
/obj/machinery/ntnet_relay/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
/obj/machinery/ntnet_relay/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "NTNetRelay", src)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/ntnet_relay/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["enabled"] = enabled
|
||||
data["dos_capacity"] = dos_capacity
|
||||
data["dos_overload"] = dos_overload
|
||||
data["dos_crashed"] = dos_failure
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "ntnet_relay.tmpl", "NTNet Quantum Relay", 500, 300, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/ntnet_relay/attack_hand(var/mob/living/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/ntnet_relay/Topic(href, href_list)
|
||||
/obj/machinery/ntnet_relay/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["restart"])
|
||||
dos_overload = 0
|
||||
dos_failure = 0
|
||||
update_icon()
|
||||
ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.")
|
||||
return 1
|
||||
else if(href_list["toggle"])
|
||||
enabled = !enabled
|
||||
ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].")
|
||||
update_icon()
|
||||
return 1
|
||||
else if(href_list["purge"])
|
||||
ntnet_global.banned_nids.Cut()
|
||||
ntnet_global.add_log("Manual override: Network blacklist cleared.")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("restart")
|
||||
dos_overload = 0
|
||||
dos_failure = 0
|
||||
update_icon()
|
||||
ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.")
|
||||
. = TRUE
|
||||
if("toggle")
|
||||
enabled = !enabled
|
||||
ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].")
|
||||
update_icon()
|
||||
. = TRUE
|
||||
if("purge")
|
||||
ntnet_global.banned_nids.Cut()
|
||||
ntnet_global.add_log("Manual override: Network blacklist cleared.")
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/ntnet_relay/New()
|
||||
..()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/computer_file/program/alarm_monitor
|
||||
filename = "alarmmonitoreng"
|
||||
filedesc = "Alarm Monitoring (Engineering)"
|
||||
nanomodule_path = /datum/nano_module/alarm_monitor/engineering
|
||||
tguimodule_path = /datum/tgui_module/alarm_monitor/engineering/ntos
|
||||
ui_header = "alarm_green.gif"
|
||||
program_icon_state = "alert-green"
|
||||
program_key_state = "atmos_key"
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/process_tick()
|
||||
..()
|
||||
var/datum/nano_module/alarm_monitor/NMA = NM
|
||||
if(istype(NMA) && NMA.has_major_alarms())
|
||||
var/datum/tgui_module/alarm_monitor/TMA = TM
|
||||
if(istype(TMA) && TMA.has_major_alarms())
|
||||
if(!has_alert)
|
||||
program_icon_state = "alert-red"
|
||||
ui_header = "alarm_red.gif"
|
||||
@@ -29,112 +29,3 @@
|
||||
update_computer_icon()
|
||||
has_alert = 0
|
||||
return 1
|
||||
|
||||
/datum/nano_module/alarm_monitor
|
||||
name = "Alarm monitor"
|
||||
var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use.
|
||||
var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user.
|
||||
//available_to_ai = FALSE
|
||||
|
||||
/datum/nano_module/alarm_monitor/New()
|
||||
..()
|
||||
alarm_handlers = list()
|
||||
|
||||
/datum/nano_module/alarm_monitor/all/New()
|
||||
..()
|
||||
alarm_handlers = SSalarm.all_handlers
|
||||
|
||||
/datum/nano_module/alarm_monitor/engineering/New()
|
||||
..()
|
||||
alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/security/New()
|
||||
..()
|
||||
alarm_handlers = list(camera_alarm, motion_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/register_alarm(var/object, var/procName)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.register_alarm(object, procName)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/unregister_alarm(var/object)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister_alarm(object)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/all_alarms()
|
||||
var/z = get_z(nano_host())
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.visible_alarms(z)
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/major_alarms()
|
||||
var/z = get_z(nano_host())
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.major_alarms(z)
|
||||
|
||||
return all_alarms
|
||||
|
||||
// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise.
|
||||
/datum/nano_module/alarm_monitor/proc/has_major_alarms()
|
||||
var/z = get_z(nano_host())
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
if(AH.has_major_alarms(z))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/minor_alarms()
|
||||
var/z = get_z(nano_host())
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.minor_alarms(z)
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/Topic(ref, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["switchTo"])
|
||||
var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras
|
||||
if(!C)
|
||||
return
|
||||
|
||||
usr.switch_to_camera(C)
|
||||
return 1
|
||||
|
||||
/datum/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
var/list/data = host.initial_data()
|
||||
|
||||
var/categories[0]
|
||||
var/z = get_z(nano_host())
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
|
||||
for(var/datum/alarm/A in AH.visible_alarms(z))
|
||||
var/cameras[0]
|
||||
var/lost_sources[0]
|
||||
|
||||
if(isAI(user))
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameras[++cameras.len] = C.nano_structure()
|
||||
for(var/datum/alarm_source/AS in A.sources)
|
||||
if(!AS.source)
|
||||
lost_sources[++lost_sources.len] = AS.source_name
|
||||
|
||||
categories[categories.len]["alarms"] += list(list(
|
||||
"name" = sanitize("[A.alarm_name()]" + "[A.max_severity() > 1 ? "(MAJOR)" : ""]"),
|
||||
"origin_lost" = A.origin == null,
|
||||
"has_cameras" = cameras.len,
|
||||
"cameras" = cameras,
|
||||
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
|
||||
data["categories"] = categories
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state)
|
||||
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
|
||||
ui.auto_update_layout = 1
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/computer_file/program/atmos_control
|
||||
filename = "atmoscontrol"
|
||||
filedesc = "Atmosphere Control"
|
||||
nanomodule_path = /datum/nano_module/atmos_control
|
||||
tguimodule_path = /datum/tgui_module/atmos_control/ntos
|
||||
program_icon_state = "atmos_control"
|
||||
program_key_state = "atmos_key"
|
||||
program_menu_icon = "shuffle"
|
||||
@@ -12,96 +12,3 @@
|
||||
requires_ntnet_feature = NTNET_SYSTEMCONTROL
|
||||
usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE
|
||||
size = 17
|
||||
|
||||
/datum/nano_module/atmos_control
|
||||
name = "Atmospherics Control"
|
||||
var/obj/access = new()
|
||||
var/emagged = 0
|
||||
var/ui_ref
|
||||
var/list/monitored_alarms = list()
|
||||
|
||||
/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids)
|
||||
..()
|
||||
access.req_access = req_access
|
||||
access.req_one_access = req_one_access
|
||||
|
||||
if(monitored_alarm_ids)
|
||||
for(var/obj/machinery/alarm/alarm in machines)
|
||||
if(alarm.alarm_id && alarm.alarm_id in monitored_alarm_ids)
|
||||
monitored_alarms += alarm
|
||||
// machines may not yet be ordered at this point
|
||||
monitored_alarms = dd_sortedObjectList(monitored_alarms)
|
||||
|
||||
/datum/nano_module/atmos_control/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["alarm"])
|
||||
if(ui_ref)
|
||||
var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines)
|
||||
if(alarm)
|
||||
var/datum/topic_state/TS = generate_state(alarm)
|
||||
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
|
||||
return 1
|
||||
|
||||
/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
var/list/data = host.initial_data()
|
||||
var/alarms[0]
|
||||
|
||||
var/z = get_z(nano_host())
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
data["map_levels"] = map_levels
|
||||
|
||||
// TODO: Move these to a cache, similar to cameras
|
||||
for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines))
|
||||
if(!monitored_alarms.len && alarm.alarms_hidden)
|
||||
continue
|
||||
if(!(alarm.z in map_levels))
|
||||
continue
|
||||
alarms[++alarms.len] = list(
|
||||
"name" = sanitize(alarm.name),
|
||||
"ref"= "\ref[alarm]",
|
||||
"danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm),
|
||||
"x" = alarm.x,
|
||||
"y" = alarm.y,
|
||||
"z" = alarm.z)
|
||||
data["alarms"] = alarms
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625, state = state)
|
||||
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
|
||||
ui.auto_update_layout = 1
|
||||
// adding a template with the key "mapContent" enables the map ui functionality
|
||||
ui.add_template("mapContent", "atmos_control_map_content.tmpl")
|
||||
// adding a template with the key "mapHeader" replaces the map header content
|
||||
ui.add_template("mapHeader", "atmos_control_map_header.tmpl")
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(0)
|
||||
ui_ref = ui
|
||||
|
||||
/datum/nano_module/atmos_control/proc/generate_state(air_alarm)
|
||||
var/datum/topic_state/air_alarm/state = new()
|
||||
state.atmos_control = src
|
||||
state.air_alarm = air_alarm
|
||||
return state
|
||||
|
||||
/datum/topic_state/air_alarm
|
||||
var/datum/nano_module/atmos_control/atmos_control = null
|
||||
var/obj/machinery/alarm/air_alarm = null
|
||||
|
||||
/datum/topic_state/air_alarm/can_use_topic(var/src_object, var/mob/user)
|
||||
if(has_access(user))
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_UPDATE
|
||||
|
||||
/datum/topic_state/air_alarm/href_list(var/mob/user)
|
||||
var/list/extra_href = list()
|
||||
extra_href["remote_connection"] = 1
|
||||
extra_href["remote_access"] = has_access(user)
|
||||
|
||||
return extra_href
|
||||
|
||||
/datum/topic_state/air_alarm/proc/has_access(var/mob/user)
|
||||
return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO) || (access_ce in user.GetAccess()))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/computer_file/program/power_monitor
|
||||
filename = "powermonitor"
|
||||
filedesc = "Power Monitoring"
|
||||
nanomodule_path = /datum/nano_module/power_monitor/
|
||||
tguimodule_path = /datum/tgui_module/power_monitor/ntos
|
||||
program_icon_state = "power_monitor"
|
||||
program_key_state = "power_key"
|
||||
program_menu_icon = "battery-3"
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
/datum/computer_file/program/power_monitor/process_tick()
|
||||
..()
|
||||
var/datum/nano_module/power_monitor/NMA = NM
|
||||
if(istype(NMA) && NMA.has_alarm())
|
||||
var/datum/tgui_module/power_monitor/TMA = TM
|
||||
if(istype(TMA) && TMA.has_alarm())
|
||||
if(!has_alert)
|
||||
program_icon_state = "power_monitor_warn"
|
||||
ui_header = "power_warn.gif"
|
||||
@@ -28,90 +28,3 @@
|
||||
ui_header = "power_norm.gif"
|
||||
update_computer_icon()
|
||||
has_alert = 0
|
||||
|
||||
/datum/nano_module/power_monitor
|
||||
name = "Power monitor"
|
||||
var/list/grid_sensors
|
||||
var/active_sensor = null //name_tag of the currently selected sensor
|
||||
|
||||
/datum/nano_module/power_monitor/New()
|
||||
..()
|
||||
refresh_sensors()
|
||||
|
||||
// Checks whether there is an active alarm, if yes, returns 1, otherwise returns 0.
|
||||
/datum/nano_module/power_monitor/proc/has_alarm()
|
||||
for(var/obj/machinery/power/sensor/S in grid_sensors)
|
||||
if(S.check_grid_warning())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// If PC is not null header template is loaded. Use PC.get_header_data() to get relevant nanoui data from it. All data entries begin with "PC_...."
|
||||
// In future it may be expanded to other modular computer devices.
|
||||
/datum/nano_module/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
var/list/data = host.initial_data()
|
||||
|
||||
var/list/sensors = list()
|
||||
// Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading.
|
||||
var/obj/machinery/power/sensor/focus = null
|
||||
|
||||
var/z = get_z(nano_host())
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
data["map_levels"] = map_levels
|
||||
|
||||
// Build list of data from sensor readings.
|
||||
for(var/obj/machinery/power/sensor/S in grid_sensors)
|
||||
if(!(S.z in map_levels))
|
||||
continue
|
||||
sensors.Add(list(list(
|
||||
"name" = S.name_tag,
|
||||
"alarm" = S.check_grid_warning()
|
||||
)))
|
||||
if(S.name_tag == active_sensor)
|
||||
focus = S
|
||||
|
||||
data["all_sensors"] = sensors
|
||||
if(focus)
|
||||
data["focus"] = focus.return_reading_data()
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500, state = state)
|
||||
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
|
||||
ui.auto_update_layout = 1
|
||||
// adding a template with the key "mapContent" enables the map ui functionality
|
||||
ui.add_template("mapContent", "power_monitor_map_content.tmpl")
|
||||
// adding a template with the key "mapHeader" replaces the map header content
|
||||
ui.add_template("mapHeader", "power_monitor_map_header.tmpl")
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
// Refreshes list of active sensors kept on this computer.
|
||||
/datum/nano_module/power_monitor/proc/refresh_sensors()
|
||||
grid_sensors = list()
|
||||
var/turf/T = get_turf(nano_host())
|
||||
var/list/levels = list()
|
||||
if(!T) // Safety check
|
||||
return
|
||||
if(T)
|
||||
levels += using_map.get_map_levels(T.z, FALSE)
|
||||
for(var/obj/machinery/power/sensor/S in machines)
|
||||
if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
|
||||
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
|
||||
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
|
||||
else
|
||||
grid_sensors += S
|
||||
|
||||
// Allows us to process UI clicks, which are relayed in form of hrefs.
|
||||
/datum/nano_module/power_monitor/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if( href_list["clear"] )
|
||||
active_sensor = null
|
||||
. = 1
|
||||
if( href_list["refresh"] )
|
||||
refresh_sensors()
|
||||
. = 1
|
||||
else if( href_list["setsensor"] )
|
||||
active_sensor = href_list["setsensor"]
|
||||
. = 1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/computer_file/program/rcon_console
|
||||
filename = "rconconsole"
|
||||
filedesc = "RCON Remote Control"
|
||||
nanomodule_path = /datum/nano_module/rcon
|
||||
tguimodule_path = /datum/tgui_module/rcon/ntos
|
||||
program_icon_state = "generic"
|
||||
program_key_state = "rd_key"
|
||||
program_menu_icon = "power"
|
||||
@@ -12,129 +12,3 @@
|
||||
requires_ntnet_feature = NTNET_SYSTEMCONTROL
|
||||
usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE
|
||||
size = 19
|
||||
|
||||
/datum/nano_module/rcon
|
||||
name = "Power RCON"
|
||||
var/list/known_SMESs = null
|
||||
var/list/known_breakers = null
|
||||
// Allows you to hide specific parts of the UI
|
||||
var/hide_SMES = 0
|
||||
var/hide_SMES_details = 0
|
||||
var/hide_breakers = 0
|
||||
|
||||
/datum/nano_module/rcon/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1, var/datum/topic_state/state = default_state)
|
||||
FindDevices() // Update our devices list
|
||||
var/list/data = host.initial_data()
|
||||
|
||||
// SMES DATA (simplified view)
|
||||
var/list/smeslist[0]
|
||||
for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs)
|
||||
smeslist.Add(list(list(
|
||||
"charge" = round(SMES.Percentage()),
|
||||
"input_set" = SMES.input_attempt,
|
||||
"input_val" = round(SMES.input_level/1000, 0.1),
|
||||
"output_set" = SMES.output_attempt,
|
||||
"output_val" = round(SMES.output_level/1000, 0.1),
|
||||
"output_load" = round(SMES.output_used/1000, 0.1),
|
||||
"RCON_tag" = SMES.RCon_tag
|
||||
)))
|
||||
|
||||
data["smes_info"] = sortByKey(smeslist, "RCON_tag")
|
||||
|
||||
// BREAKER DATA (simplified view)
|
||||
var/list/breakerlist[0]
|
||||
for(var/obj/machinery/power/breakerbox/BR in known_breakers)
|
||||
breakerlist.Add(list(list(
|
||||
"RCON_tag" = BR.RCon_tag,
|
||||
"enabled" = BR.on
|
||||
)))
|
||||
data["breaker_info"] = breakerlist
|
||||
data["hide_smes"] = hide_SMES
|
||||
data["hide_smes_details"] = hide_SMES_details
|
||||
data["hide_breakers"] = hide_breakers
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400, state = state)
|
||||
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
|
||||
ui.auto_update_layout = 1
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
// Proc: Topic()
|
||||
// Parameters: 2 (href, href_list - allows us to process UI clicks)
|
||||
// Description: Allows us to process UI clicks, which are relayed in form of hrefs.
|
||||
/datum/nano_module/rcon/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(href_list["smes_in_toggle"])
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_toggle"])
|
||||
if(SMES)
|
||||
SMES.toggle_input()
|
||||
if(href_list["smes_out_toggle"])
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_toggle"])
|
||||
if(SMES)
|
||||
SMES.toggle_output()
|
||||
if(href_list["smes_in_set"])
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_set"])
|
||||
if(SMES)
|
||||
var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000
|
||||
SMES.set_input(inputset)
|
||||
if(href_list["smes_out_set"])
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_set"])
|
||||
if(SMES)
|
||||
var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000
|
||||
SMES.set_output(outputset)
|
||||
|
||||
if(href_list["toggle_breaker"])
|
||||
var/obj/machinery/power/breakerbox/toggle = null
|
||||
for(var/obj/machinery/power/breakerbox/breaker in known_breakers)
|
||||
if(breaker.RCon_tag == href_list["toggle_breaker"])
|
||||
toggle = breaker
|
||||
if(toggle)
|
||||
if(toggle.update_locked)
|
||||
to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.")
|
||||
else
|
||||
toggle.auto_toggle()
|
||||
if(href_list["hide_smes"])
|
||||
hide_SMES = !hide_SMES
|
||||
if(href_list["hide_smes_details"])
|
||||
hide_SMES_details = !hide_SMES_details
|
||||
if(href_list["hide_breakers"])
|
||||
hide_breakers = !hide_breakers
|
||||
|
||||
|
||||
// Proc: GetSMESByTag()
|
||||
// Parameters: 1 (tag - RCON tag of SMES we want to look up)
|
||||
// Description: Looks up and returns SMES which has matching RCON tag
|
||||
/datum/nano_module/rcon/proc/GetSMESByTag(var/tag)
|
||||
if(!tag)
|
||||
return
|
||||
|
||||
for(var/obj/machinery/power/smes/buildable/S in known_SMESs)
|
||||
if(S.RCon_tag == tag)
|
||||
return S
|
||||
|
||||
// Proc: FindDevices()
|
||||
// Parameters: None
|
||||
// Description: Refreshes local list of known devices.
|
||||
/datum/nano_module/rcon/proc/FindDevices()
|
||||
known_SMESs = new /list()
|
||||
|
||||
var/z = get_z(nano_host())
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
|
||||
for(var/obj/machinery/power/smes/buildable/SMES in GLOB.smeses)
|
||||
if(!(SMES.z in map_levels))
|
||||
continue
|
||||
if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon)
|
||||
known_SMESs.Add(SMES)
|
||||
|
||||
known_breakers = new /list()
|
||||
for(var/obj/machinery/power/breakerbox/breaker in machines)
|
||||
if(!(breaker.z in map_levels))
|
||||
continue
|
||||
if(breaker.RCon_tag != "NO_TAG")
|
||||
known_breakers.Add(breaker)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/computer_file/program/shutoff_monitor
|
||||
filename = "shutoffmonitor"
|
||||
filedesc = "Shutoff Valve Monitoring"
|
||||
nanomodule_path = /datum/nano_module/shutoff_monitor
|
||||
tguimodule_path = /datum/tgui_module/shutoff_monitor/ntos
|
||||
program_icon_state = "atmos_control"
|
||||
program_key_state = "atmos_key"
|
||||
program_menu_icon = "wrench"
|
||||
@@ -11,53 +11,3 @@
|
||||
network_destination = "shutoff valve control computer"
|
||||
size = 5
|
||||
var/has_alert = 0
|
||||
|
||||
/datum/nano_module/shutoff_monitor
|
||||
name = "Shutoff Valve Monitoring"
|
||||
|
||||
/datum/nano_module/shutoff_monitor/Topic(ref, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["toggle_enable"])
|
||||
var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_enable"])
|
||||
if(!istype(S))
|
||||
return 0
|
||||
S.close_on_leaks = !S.close_on_leaks
|
||||
return 1
|
||||
|
||||
if(href_list["toggle_open"])
|
||||
var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_open"])
|
||||
if(!istype(S))
|
||||
return 0
|
||||
if(S.open)
|
||||
S.close()
|
||||
else
|
||||
S.open()
|
||||
return 1
|
||||
|
||||
/datum/nano_module/shutoff_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
var/list/data = host.initial_data()
|
||||
var/list/valves = list()
|
||||
|
||||
for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves)
|
||||
valves.Add(list(list(
|
||||
"name" = S.name,
|
||||
"enabled" = S.close_on_leaks,
|
||||
"open" = S.open,
|
||||
"x" = S.x,
|
||||
"y" = S.y,
|
||||
"z" = S.z,
|
||||
"ref" = "\ref[S]"
|
||||
)))
|
||||
|
||||
data["valves"] = valves
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "shutoff_monitor.tmpl", "Shutoff Valve Monitoring", 627, 700, state = state)
|
||||
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
|
||||
ui.auto_update_layout = 1
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
+3
-111
@@ -1,7 +1,7 @@
|
||||
/datum/computer_file/program/supermatter_monitor
|
||||
filename = "supmon"
|
||||
filedesc = "Supermatter Monitoring"
|
||||
nanomodule_path = /datum/nano_module/supermatter_monitor/
|
||||
tguimodule_path = /datum/tgui_module/supermatter_monitor/ntos
|
||||
program_icon_state = "smmon_0"
|
||||
program_key_state = "tech_key"
|
||||
program_menu_icon = "notice"
|
||||
@@ -15,119 +15,11 @@
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/process_tick()
|
||||
..()
|
||||
var/datum/nano_module/supermatter_monitor/NMS = NM
|
||||
var/new_status = istype(NMS) ? NMS.get_status() : 0
|
||||
var/datum/tgui_module/supermatter_monitor/TMS = TM
|
||||
var/new_status = istype(TMS) ? TMS.get_status() : 0
|
||||
if(last_status != new_status)
|
||||
last_status = new_status
|
||||
ui_header = "smmon_[last_status].gif"
|
||||
program_icon_state = "smmon_[last_status]"
|
||||
if(istype(computer))
|
||||
computer.update_icon()
|
||||
|
||||
/datum/nano_module/supermatter_monitor
|
||||
name = "Supermatter monitor"
|
||||
var/list/supermatters
|
||||
var/obj/machinery/power/supermatter/active = null // Currently selected supermatter crystal.
|
||||
|
||||
/datum/nano_module/supermatter_monitor/Destroy()
|
||||
. = ..()
|
||||
active = null
|
||||
supermatters = null
|
||||
|
||||
/datum/nano_module/supermatter_monitor/New()
|
||||
..()
|
||||
refresh()
|
||||
|
||||
// Refreshes list of active supermatter crystals
|
||||
/datum/nano_module/supermatter_monitor/proc/refresh()
|
||||
supermatters = list()
|
||||
var/z = get_z(nano_host())
|
||||
if(!z)
|
||||
return
|
||||
var/valid_z_levels = using_map.get_map_levels(z)
|
||||
for(var/obj/machinery/power/supermatter/S in machines)
|
||||
// Delaminating, not within coverage, not on a tile.
|
||||
if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/))
|
||||
continue
|
||||
supermatters.Add(S)
|
||||
|
||||
if(!(active in supermatters))
|
||||
active = null
|
||||
|
||||
/datum/nano_module/supermatter_monitor/proc/get_status()
|
||||
. = SUPERMATTER_INACTIVE
|
||||
for(var/obj/machinery/power/supermatter/S in supermatters)
|
||||
. = max(., S.get_status())
|
||||
|
||||
/datum/nano_module/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
var/list/data = host.initial_data()
|
||||
|
||||
if(istype(active))
|
||||
var/turf/T = get_turf(active)
|
||||
if(!T)
|
||||
active = null
|
||||
return
|
||||
var/datum/gas_mixture/air = T.return_air()
|
||||
if(!istype(air))
|
||||
active = null
|
||||
return
|
||||
|
||||
data["active"] = 1
|
||||
data["SM_integrity"] = active.get_integrity()
|
||||
data["SM_power"] = active.power
|
||||
data["SM_ambienttemp"] = air.temperature
|
||||
data["SM_ambientpressure"] = air.return_pressure()
|
||||
data["SM_EPR"] = active.get_epr()
|
||||
//data["SM_EPR"] = active.get_epr()
|
||||
if(air.total_moles)
|
||||
data["SM_gas_O2"] = round(100*air.gas["oxygen"]/air.total_moles,0.01)
|
||||
data["SM_gas_CO2"] = round(100*air.gas["carbon_dioxide"]/air.total_moles,0.01)
|
||||
data["SM_gas_N2"] = round(100*air.gas["nitrogen"]/air.total_moles,0.01)
|
||||
data["SM_gas_PH"] = round(100*air.gas["phoron"]/air.total_moles,0.01)
|
||||
data["SM_gas_N2O"] = round(100*air.gas["sleeping_agent"]/air.total_moles,0.01)
|
||||
else
|
||||
data["SM_gas_O2"] = 0
|
||||
data["SM_gas_CO2"] = 0
|
||||
data["SM_gas_N2"] = 0
|
||||
data["SM_gas_PH"] = 0
|
||||
data["SM_gas_N2O"] = 0
|
||||
else
|
||||
var/list/SMS = list()
|
||||
for(var/obj/machinery/power/supermatter/S in supermatters)
|
||||
var/area/A = get_area(S)
|
||||
if(!A)
|
||||
continue
|
||||
|
||||
SMS.Add(list(list(
|
||||
"area_name" = A.name,
|
||||
"integrity" = S.get_integrity(),
|
||||
"uid" = S.uid
|
||||
)))
|
||||
|
||||
data["active"] = 0
|
||||
data["supermatters"] = SMS
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400, state = state)
|
||||
if(host.update_layout())
|
||||
ui.auto_update_layout = 1
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/nano_module/supermatter_monitor/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if( href_list["clear"] )
|
||||
active = null
|
||||
return 1
|
||||
if( href_list["refresh"] )
|
||||
refresh()
|
||||
return 1
|
||||
if( href_list["set"] )
|
||||
var/newuid = text2num(href_list["set"])
|
||||
for(var/obj/machinery/power/supermatter/S in supermatters)
|
||||
if(S.uid == newuid)
|
||||
active = S
|
||||
return 1
|
||||
@@ -2,5 +2,5 @@
|
||||
filename = "alarmmonitorsec"
|
||||
filedesc = "Alarm Monitoring (Security)"
|
||||
extended_desc = "This program provides visual interface for the security alarm system."
|
||||
nanomodule_path = /datum/nano_module/alarm_monitor/security
|
||||
tguimodule_path = /datum/tgui_module/alarm_monitor/security/ntos
|
||||
required_access = access_security
|
||||
@@ -1,191 +0,0 @@
|
||||
/datum/nano_module/appearance_changer
|
||||
name = "Appearance Editor"
|
||||
var/flags = APPEARANCE_ALL_HAIR
|
||||
var/mob/living/carbon/human/owner = null
|
||||
var/list/valid_species = list()
|
||||
var/list/valid_hairstyles = list()
|
||||
var/list/valid_facial_hairstyles = list()
|
||||
|
||||
var/check_whitelist
|
||||
var/list/whitelist
|
||||
var/list/blacklist
|
||||
|
||||
/datum/nano_module/appearance_changer/New(var/location, var/mob/living/carbon/human/H, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list())
|
||||
..()
|
||||
owner = H
|
||||
src.check_whitelist = check_species_whitelist
|
||||
src.whitelist = species_whitelist
|
||||
src.blacklist = species_blacklist
|
||||
|
||||
/datum/nano_module/appearance_changer/Topic(ref, href_list, var/datum/topic_state/state = default_state)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["race"])
|
||||
if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species))
|
||||
if(owner.change_species(href_list["race"]))
|
||||
cut_and_generate_data()
|
||||
return 1
|
||||
if(href_list["gender"])
|
||||
if(can_change(APPEARANCE_GENDER) && (href_list["gender"] in get_genders()))
|
||||
if(owner.change_gender(href_list["gender"]))
|
||||
cut_and_generate_data()
|
||||
return 1
|
||||
if(href_list["gender_id"])
|
||||
if(can_change(APPEARANCE_GENDER) && (href_list["gender_id"] in all_genders_define_list))
|
||||
owner.identifying_gender = href_list["gender_id"]
|
||||
return 1
|
||||
if(href_list["skin_tone"])
|
||||
if(can_change_skin_tone())
|
||||
var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", -owner.s_tone + 35) as num|null
|
||||
if(isnum(new_s_tone) && can_still_topic(state))
|
||||
new_s_tone = 35 - max(min( round(new_s_tone), 220),1)
|
||||
return owner.change_skin_tone(new_s_tone)
|
||||
if(href_list["skin_color"])
|
||||
if(can_change_skin_color())
|
||||
var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(owner.r_skin, owner.g_skin, owner.b_skin)) as color|null
|
||||
if(new_skin && can_still_topic(state))
|
||||
var/r_skin = hex2num(copytext(new_skin, 2, 4))
|
||||
var/g_skin = hex2num(copytext(new_skin, 4, 6))
|
||||
var/b_skin = hex2num(copytext(new_skin, 6, 8))
|
||||
if(owner.change_skin_color(r_skin, g_skin, b_skin))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["hair"])
|
||||
if(can_change(APPEARANCE_HAIR) && (href_list["hair"] in valid_hairstyles))
|
||||
if(owner.change_hair(href_list["hair"]))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["hair_color"])
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null
|
||||
if(new_hair && can_still_topic(state))
|
||||
var/r_hair = hex2num(copytext(new_hair, 2, 4))
|
||||
var/g_hair = hex2num(copytext(new_hair, 4, 6))
|
||||
var/b_hair = hex2num(copytext(new_hair, 6, 8))
|
||||
if(owner.change_hair_color(r_hair, g_hair, b_hair))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["facial_hair"])
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR) && (href_list["facial_hair"] in valid_facial_hairstyles))
|
||||
if(owner.change_facial_hair(href_list["facial_hair"]))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["facial_hair_color"])
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR_COLOR))
|
||||
var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null
|
||||
if(new_facial && can_still_topic(state))
|
||||
var/r_facial = hex2num(copytext(new_facial, 2, 4))
|
||||
var/g_facial = hex2num(copytext(new_facial, 4, 6))
|
||||
var/b_facial = hex2num(copytext(new_facial, 6, 8))
|
||||
if(owner.change_facial_hair_color(r_facial, g_facial, b_facial))
|
||||
update_dna()
|
||||
return 1
|
||||
if(href_list["eye_color"])
|
||||
if(can_change(APPEARANCE_EYE_COLOR))
|
||||
var/new_eyes = input("Please select eye color.", "Eye Color", rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) as color|null
|
||||
if(new_eyes && can_still_topic(state))
|
||||
var/r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
var/g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
var/b_eyes = hex2num(copytext(new_eyes, 6, 8))
|
||||
if(owner.change_eye_color(r_eyes, g_eyes, b_eyes))
|
||||
update_dna()
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/datum/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
|
||||
if(!owner || !owner.species)
|
||||
return
|
||||
|
||||
generate_data(check_whitelist, whitelist, blacklist)
|
||||
var/list/data = host.initial_data()
|
||||
|
||||
data["specimen"] = owner.species.name
|
||||
data["gender"] = owner.gender
|
||||
data["gender_id"] = owner.identifying_gender
|
||||
data["change_race"] = can_change(APPEARANCE_RACE)
|
||||
if(data["change_race"])
|
||||
var/species[0]
|
||||
for(var/specimen in valid_species)
|
||||
species[++species.len] = list("specimen" = specimen)
|
||||
data["species"] = species
|
||||
|
||||
data["change_gender"] = can_change(APPEARANCE_GENDER)
|
||||
if(data["change_gender"])
|
||||
var/genders[0]
|
||||
for(var/gender in get_genders())
|
||||
genders[++genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender)
|
||||
data["genders"] = genders
|
||||
var/id_genders[0]
|
||||
for(var/gender in all_genders_define_list)
|
||||
id_genders[++id_genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender)
|
||||
data["id_genders"] = id_genders
|
||||
|
||||
|
||||
data["change_skin_tone"] = can_change_skin_tone()
|
||||
data["change_skin_color"] = can_change_skin_color()
|
||||
data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR)
|
||||
data["change_hair"] = can_change(APPEARANCE_HAIR)
|
||||
if(data["change_hair"])
|
||||
var/hair_styles[0]
|
||||
for(var/hair_style in valid_hairstyles)
|
||||
hair_styles[++hair_styles.len] = list("hairstyle" = hair_style)
|
||||
data["hair_styles"] = hair_styles
|
||||
data["hair_style"] = owner.h_style
|
||||
|
||||
data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR)
|
||||
if(data["change_facial_hair"])
|
||||
var/facial_hair_styles[0]
|
||||
for(var/facial_hair_style in valid_facial_hairstyles)
|
||||
facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style)
|
||||
data["facial_hair_styles"] = facial_hair_styles
|
||||
data["facial_hair_style"] = owner.f_style
|
||||
|
||||
data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR)
|
||||
data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src]", 800, 450, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/nano_module/appearance_changer/proc/update_dna()
|
||||
if(owner && (flags & APPEARANCE_UPDATE_DNA))
|
||||
owner.update_dna()
|
||||
|
||||
/datum/nano_module/appearance_changer/proc/can_change(var/flag)
|
||||
return owner && (flags & flag)
|
||||
|
||||
/datum/nano_module/appearance_changer/proc/can_change_skin_tone()
|
||||
return owner && (flags & APPEARANCE_SKIN) && owner.species.appearance_flags & HAS_SKIN_TONE
|
||||
|
||||
/datum/nano_module/appearance_changer/proc/can_change_skin_color()
|
||||
return owner && (flags & APPEARANCE_SKIN) && owner.species.appearance_flags & HAS_SKIN_COLOR
|
||||
|
||||
/datum/nano_module/appearance_changer/proc/cut_and_generate_data()
|
||||
// Making the assumption that the available species remain constant
|
||||
valid_facial_hairstyles.Cut()
|
||||
valid_facial_hairstyles.Cut()
|
||||
generate_data()
|
||||
|
||||
/datum/nano_module/appearance_changer/proc/generate_data()
|
||||
if(!owner)
|
||||
return
|
||||
if(!valid_species.len)
|
||||
valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist)
|
||||
if(!valid_hairstyles.len || !valid_facial_hairstyles.len)
|
||||
valid_hairstyles = owner.generate_valid_hairstyles(check_gender = 0)
|
||||
valid_facial_hairstyles = owner.generate_valid_facial_hairstyles()
|
||||
|
||||
|
||||
/datum/nano_module/appearance_changer/proc/get_genders()
|
||||
var/datum/species/S = owner.species
|
||||
var/list/possible_genders = S.genders
|
||||
if(!owner.internal_organs_by_name["cell"])
|
||||
return possible_genders
|
||||
possible_genders = possible_genders.Copy()
|
||||
possible_genders |= NEUTER
|
||||
return possible_genders
|
||||
@@ -34,19 +34,19 @@
|
||||
access = access_engine
|
||||
cost = 625
|
||||
p_drain = 0.025
|
||||
var/datum/nano_module/alarm_monitor/engineering/arscreen
|
||||
var/datum/tgui_module/alarm_monitor/engineering/nif/tgarscreen
|
||||
|
||||
New()
|
||||
..()
|
||||
arscreen = new(nif)
|
||||
tgarscreen = new(nif)
|
||||
|
||||
Destroy()
|
||||
QDEL_NULL(arscreen)
|
||||
QDEL_NULL(tgarscreen)
|
||||
return ..()
|
||||
|
||||
activate()
|
||||
if((. = ..()))
|
||||
arscreen.ui_interact(nif.human,"main",null,1,nif_state)
|
||||
tgarscreen.tgui_interact(nif.human)
|
||||
return TRUE
|
||||
|
||||
deactivate()
|
||||
|
||||
@@ -36,12 +36,8 @@
|
||||
to_chat(user, "<span class='notice'>You put [P] in [src].</span>")
|
||||
user.drop_item()
|
||||
P.loc = src
|
||||
icon_state = "[initial(icon_state)]-open"
|
||||
flick("[initial(icon_state)]-open",src)
|
||||
playsound(src, 'sound/bureaucracy/filingcabinet.ogg', 50, 1)
|
||||
sleep(40)
|
||||
icon_state = initial(icon_state)
|
||||
updateUsrDialog()
|
||||
open_animation()
|
||||
SStgui.update_uis(src)
|
||||
else if(P.is_wrench())
|
||||
playsound(src, P.usesound, 50, 1)
|
||||
anchored = !anchored
|
||||
@@ -65,20 +61,12 @@
|
||||
to_chat(user, "<span class='notice'>\The [src] is empty.</span>")
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = "<center><table>"
|
||||
for(var/obj/item/P in src)
|
||||
dat += "<tr><td><a href='?src=\ref[src];retrieve=\ref[P]'>[P.name]</a></td></tr>"
|
||||
dat += "</table></center>"
|
||||
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=filingcabinet;size=350x300")
|
||||
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/structure/filingcabinet/attack_tk(mob/user)
|
||||
if(anchored)
|
||||
attack_self_tk(user)
|
||||
else
|
||||
..()
|
||||
return attack_self_tk(user)
|
||||
return ..()
|
||||
|
||||
/obj/structure/filingcabinet/attack_self_tk(mob/user)
|
||||
if(contents.len)
|
||||
@@ -91,20 +79,46 @@
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You find nothing in [src].</span>")
|
||||
|
||||
/obj/structure/filingcabinet/Topic(href, href_list)
|
||||
if(href_list["retrieve"])
|
||||
usr << browse("", "window=filingcabinet") // Close the menu
|
||||
/obj/structure/filingcabinet/tgui_state(mob/user)
|
||||
return GLOB.tgui_physical_state
|
||||
|
||||
//var/retrieveindex = text2num(href_list["retrieve"])
|
||||
var/obj/item/P = locate(href_list["retrieve"])//contents[retrieveindex]
|
||||
if(istype(P) && (P.loc == src) && src.Adjacent(usr))
|
||||
usr.put_in_hands(P)
|
||||
updateUsrDialog()
|
||||
flick("[initial(icon_state)]-open",src)
|
||||
playsound(src, 'sound/bureaucracy/filingcabinet.ogg', 50, 1)
|
||||
spawn(0)
|
||||
sleep(20)
|
||||
icon_state = initial(icon_state)
|
||||
/obj/structure/filingcabinet/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "FileCabinet", name)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/obj/structure/filingcabinet/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["contents"] = list()
|
||||
for(var/obj/item/P in src)
|
||||
data["contents"].Add(list(list(
|
||||
"name" = P.name,
|
||||
"ref" = "\ref[P]",
|
||||
)))
|
||||
|
||||
return data
|
||||
|
||||
/obj/structure/filingcabinet/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("retrieve")
|
||||
var/obj/item/P = locate(params["ref"])
|
||||
if(istype(P) && (P.loc == src) && usr.Adjacent(src))
|
||||
usr.put_in_hands(P)
|
||||
open_animation()
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/structure/filingcabinet/proc/open_animation()
|
||||
flick("[initial(icon_state)]-open",src)
|
||||
playsound(src, 'sound/bureaucracy/filingcabinet.ogg', 50, 1)
|
||||
spawn(0)
|
||||
sleep(20)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/*
|
||||
* Security Record Cabinets
|
||||
@@ -112,7 +126,6 @@
|
||||
/obj/structure/filingcabinet/security
|
||||
var/virgin = 1
|
||||
|
||||
|
||||
/obj/structure/filingcabinet/security/proc/populate()
|
||||
if(virgin)
|
||||
for(var/datum/data/record/G in data_core.general)
|
||||
|
||||
@@ -39,10 +39,10 @@
|
||||
to_chat(user, "It reads \"[message]\".")
|
||||
|
||||
/obj/effect/decal/writing/attackby(var/obj/item/thing, var/mob/user)
|
||||
if(is_hot(thing))
|
||||
if(istype(thing, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/welder = thing
|
||||
if(welder.isOn() && welder.remove_fuel(0,user) && do_after(user, 5, src) && !QDELETED(src))
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
playsound(src.loc, welder.usesound, 50, 1)
|
||||
user.visible_message("<span class='notice'>\The [user] clears away some graffiti.</span>")
|
||||
qdel(src)
|
||||
else if(thing.sharp)
|
||||
@@ -61,4 +61,4 @@
|
||||
if(lowertext(message) == "elbereth")
|
||||
to_chat(user, "<span class='notice'>You feel much safer.</span>")
|
||||
else
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
+214
-234
@@ -27,9 +27,19 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
#define APC_UPOVERLAY_LOCKED 4096
|
||||
#define APC_UPOVERLAY_OPERATING 8192
|
||||
|
||||
|
||||
#define APC_UPDATE_ICON_COOLDOWN 100 // 10 seconds
|
||||
|
||||
// main_status var
|
||||
#define APC_EXTERNAL_POWER_NOTCONNECTED 0
|
||||
#define APC_EXTERNAL_POWER_NOENERGY 1
|
||||
#define APC_EXTERNAL_POWER_GOOD 2
|
||||
|
||||
// has_electronics var
|
||||
#define APC_HAS_ELECTRONICS_NONE 0
|
||||
#define APC_HAS_ELECTRONICS_WIRED 1
|
||||
#define APC_HAS_ELECTRONICS_SECURED 2
|
||||
|
||||
|
||||
// the Area Power Controller (APC), formerly Power Distribution Unit (PDU)
|
||||
// one per area, needs wire conection to power network through a terminal
|
||||
|
||||
@@ -101,13 +111,13 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
var/lastused_environ = 0
|
||||
var/lastused_charging = 0
|
||||
var/lastused_total = 0
|
||||
var/main_status = 0
|
||||
var/main_status = APC_EXTERNAL_POWER_NOTCONNECTED
|
||||
var/mob/living/silicon/ai/hacker = null // Malfunction var. If set AI hacked the APC and has full control.
|
||||
var/wiresexposed = 0
|
||||
powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :(
|
||||
var/debug= 0
|
||||
var/autoflag= 0 // 0 = off, 1= eqp and lights off, 2 = eqp off, 3 = all on.
|
||||
var/has_electronics = 0 // 0 - none, 1 - plugged in, 2 - secured by screwdriver
|
||||
var/has_electronics = APC_HAS_ELECTRONICS_NONE // 0 - none, 1 - plugged in, 2 - secured by screwdriver
|
||||
var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment
|
||||
var/longtermpower = 10
|
||||
var/datum/wires/apc/wires = null
|
||||
@@ -131,7 +141,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
var/last_nightshift_switch = 0
|
||||
|
||||
/obj/machinery/power/apc/updateDialog()
|
||||
if (stat & (BROKEN|MAINT))
|
||||
if(stat & (BROKEN|MAINT))
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -175,12 +185,12 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
|
||||
// offset 24 pixels in direction of dir
|
||||
// this allows the APC to be embedded in a wall, yet still inside an area
|
||||
if (building)
|
||||
if(building)
|
||||
set_dir(ndir)
|
||||
|
||||
pixel_x = (src.dir & 3)? 0 : (src.dir == 4 ? 26 : -26) //VOREStation Edit -> 24 to 26
|
||||
pixel_y = (src.dir & 3)? (src.dir ==1 ? 26 : -26) : 0 //VOREStation Edit -> 24 to 26
|
||||
if (building==0)
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? 26 : -26) //VOREStation Edit -> 24 to 26
|
||||
pixel_y = (dir & 3)? (dir ==1 ? 26 : -26) : 0 //VOREStation Edit -> 24 to 26
|
||||
if(building==0)
|
||||
init()
|
||||
else
|
||||
area = get_area(src)
|
||||
@@ -189,11 +199,11 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
operating = 0
|
||||
name = "[area.name] APC"
|
||||
stat |= MAINT
|
||||
src.update_icon()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/apc/Destroy()
|
||||
GLOB.apcs -= src
|
||||
src.update()
|
||||
update()
|
||||
area.apc = null
|
||||
area.power_light = 0
|
||||
area.power_equip = 0
|
||||
@@ -216,11 +226,11 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
// APCs are pixel-shifted, so they need to be updated.
|
||||
/obj/machinery/power/apc/set_dir(new_dir)
|
||||
..()
|
||||
pixel_x = (src.dir & 3)? 0 : (src.dir == 4 ? 24 : -24)
|
||||
pixel_y = (src.dir & 3)? (src.dir ==1 ? 24 : -24) : 0
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? 24 : -24)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? 24 : -24) : 0
|
||||
if(terminal)
|
||||
terminal.disconnect_from_network()
|
||||
terminal.set_dir(src.dir) // Terminal has same dir as master
|
||||
terminal.set_dir(dir) // Terminal has same dir as master
|
||||
terminal.connect_to_network() // Refresh the network the terminal is connected to.
|
||||
return
|
||||
|
||||
@@ -230,25 +240,25 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
/obj/machinery/power/apc/proc/make_terminal()
|
||||
// create a terminal object at the same position as original turf loc
|
||||
// wires will attach to this
|
||||
terminal = new/obj/machinery/power/terminal(src.loc)
|
||||
terminal = new/obj/machinery/power/terminal(loc)
|
||||
terminal.set_dir(dir)
|
||||
terminal.master = src
|
||||
|
||||
/obj/machinery/power/apc/proc/init()
|
||||
has_electronics = 2 //installed and secured
|
||||
has_electronics = APC_HAS_ELECTRONICS_SECURED //installed and secured
|
||||
// is starting with a power cell installed, create it and set its charge level
|
||||
if(cell_type)
|
||||
src.cell = new cell_type(src)
|
||||
cell = new cell_type(src)
|
||||
cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value)
|
||||
|
||||
var/area/A = src.loc.loc
|
||||
var/area/A = loc.loc
|
||||
|
||||
//if area isn't specified use current
|
||||
if(isarea(A) && src.areastring == null)
|
||||
src.area = A
|
||||
if(isarea(A) && !areastring)
|
||||
area = A
|
||||
name = "\improper [area.name] APC"
|
||||
else
|
||||
src.area = get_area_name(areastring)
|
||||
area = get_area_name(areastring)
|
||||
name = "\improper [area.name] APC"
|
||||
area.apc = src
|
||||
|
||||
@@ -260,7 +270,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
make_terminal()
|
||||
|
||||
spawn(5)
|
||||
src.update()
|
||||
update()
|
||||
|
||||
/obj/machinery/power/apc/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -271,17 +281,17 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
else if(opened)
|
||||
if(has_electronics && terminal)
|
||||
. += "The cover is [opened == 2 ? "removed" : "open"] and [ cell ? "a power cell is installed" : "the power cell is missing"]."
|
||||
else if (!has_electronics && terminal)
|
||||
else if(!has_electronics && terminal)
|
||||
. += "The frame is wired, but the electronics are missing."
|
||||
else if (has_electronics && !terminal)
|
||||
else if(has_electronics && !terminal)
|
||||
. += "The electronics are installed, but not wired."
|
||||
else /* if (!has_electronics && !terminal) */
|
||||
else /* if(!has_electronics && !terminal) */
|
||||
. += "It's just an empty metal frame."
|
||||
|
||||
else
|
||||
if (wiresexposed)
|
||||
if(wiresexposed)
|
||||
. += "The cover is closed and the wires are exposed."
|
||||
else if ((locked && emagged) || hacker) //Some things can cause locked && emagged. Malf AI causes hacker.
|
||||
else if((locked && emagged) || hacker) //Some things can cause locked && emagged. Malf AI causes hacker.
|
||||
. += "The cover is closed, but the panel is unresponsive."
|
||||
else if(!locked && emagged) //Normal emag does this.
|
||||
. += "The cover is closed, but the panel is flashing an error."
|
||||
@@ -292,7 +302,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
// update the APC icon to show the three base states
|
||||
// also add overlays for indicator lights
|
||||
/obj/machinery/power/apc/update_icon()
|
||||
if (!status_overlays)
|
||||
if(!status_overlays)
|
||||
status_overlays = 1
|
||||
status_overlays_lock = new
|
||||
status_overlays_charging = new
|
||||
@@ -424,7 +434,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
else if(charging == 2)
|
||||
update_overlay |= APC_UPOVERLAY_CHARGEING2
|
||||
|
||||
if (!equipment)
|
||||
if(!equipment)
|
||||
update_overlay |= APC_UPOVERLAY_EQUIPMENT0
|
||||
else if(equipment == 1)
|
||||
update_overlay |= APC_UPOVERLAY_EQUIPMENT1
|
||||
@@ -468,35 +478,34 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
//attack with an item - open/close cover, insert cell, or (un)lock interface
|
||||
|
||||
/obj/machinery/power/apc/attackby(obj/item/W, mob/user)
|
||||
|
||||
if (istype(user, /mob/living/silicon) && get_dist(src,user)>1)
|
||||
return src.attack_hand(user)
|
||||
src.add_fingerprint(user)
|
||||
if (W.is_crowbar() && opened)
|
||||
if (has_electronics==1)
|
||||
if (terminal)
|
||||
if(issilicon(user) && get_dist(src,user) > 1)
|
||||
return attack_hand(user)
|
||||
add_fingerprint(user)
|
||||
if(W.is_crowbar() && opened)
|
||||
if(has_electronics == APC_HAS_ELECTRONICS_WIRED)
|
||||
if(terminal)
|
||||
to_chat(user, "<span class='warning'>Disconnect the wires first.</span>")
|
||||
return
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
to_chat(user, "You begin to remove the power control board...") //lpeters - fixed grammar issues //Ner - grrrrrr
|
||||
if(do_after(user, 50 * W.toolspeed))
|
||||
if (has_electronics==1)
|
||||
has_electronics = 0
|
||||
if ((stat & BROKEN))
|
||||
if(has_electronics == APC_HAS_ELECTRONICS_WIRED)
|
||||
has_electronics = APC_HAS_ELECTRONICS_NONE
|
||||
if((stat & BROKEN))
|
||||
user.visible_message(\
|
||||
"<span class='warning'>[user.name] has broken the charred power control board inside [src.name]!</span>",\
|
||||
"<span class='warning'>[user.name] has broken the charred power control board inside [name]!</span>",\
|
||||
"<span class='notice'>You broke the charred power control board and remove the remains.</span>",
|
||||
"You hear a crack!")
|
||||
//ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0
|
||||
else
|
||||
user.visible_message(\
|
||||
"<span class='warning'>[user.name] has removed the power control board from [src.name]!</span>",\
|
||||
"<span class='warning'>[user.name] has removed the power control board from [name]!</span>",\
|
||||
"<span class='notice'>You remove the power control board.</span>")
|
||||
new /obj/item/weapon/module/power_control(loc)
|
||||
else if (opened!=2) //cover isn't removed
|
||||
else if(opened != 2) //cover isn't removed
|
||||
opened = 0
|
||||
update_icon()
|
||||
else if (W.is_crowbar() && !(stat & BROKEN) )
|
||||
else if(W.is_crowbar() && !(stat & BROKEN) )
|
||||
if(coverlocked && !(stat & MAINT))
|
||||
to_chat(user, "<span class='warning'>The cover is locked and cannot be opened.</span>")
|
||||
return
|
||||
@@ -505,9 +514,9 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
update_icon()
|
||||
else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside
|
||||
if(cell)
|
||||
to_chat(user, "The [src.name] already has a power cell installed.")
|
||||
to_chat(user, "The [name] already has a power cell installed.")
|
||||
return
|
||||
if (stat & MAINT)
|
||||
if(stat & MAINT)
|
||||
to_chat(user, "<span class='warning'>You need to install the wiring and electronics first.</span>")
|
||||
return
|
||||
if(W.w_class != ITEMSIZE_NORMAL)
|
||||
@@ -518,27 +527,27 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
W.forceMove(src)
|
||||
cell = W
|
||||
user.visible_message(\
|
||||
"<span class='warning'>[user.name] has inserted a power cell into [src.name]!</span>",\
|
||||
"<span class='warning'>[user.name] has inserted a power cell into [name]!</span>",\
|
||||
"<span class='notice'>You insert the power cell.</span>")
|
||||
chargecount = 0
|
||||
update_icon()
|
||||
else if (W.is_screwdriver()) // haxing
|
||||
if(opened)
|
||||
if (cell)
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>Remove the power cell first.</span>")
|
||||
return
|
||||
else
|
||||
if (has_electronics==1 && terminal)
|
||||
has_electronics = 2
|
||||
if(has_electronics == APC_HAS_ELECTRONICS_WIRED && terminal)
|
||||
has_electronics = APC_HAS_ELECTRONICS_SECURED
|
||||
stat &= ~MAINT
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
to_chat(user, "You screw the circuit electronics into place.")
|
||||
else if (has_electronics==2)
|
||||
has_electronics = 1
|
||||
else if(has_electronics == APC_HAS_ELECTRONICS_SECURED)
|
||||
has_electronics = APC_HAS_ELECTRONICS_WIRED
|
||||
stat |= MAINT
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
to_chat(user, "You unfasten the electronics.")
|
||||
else /* has_electronics==0 */
|
||||
else /* has_electronics == APC_HAS_ELECTRONICS_NONE */
|
||||
to_chat(user, "<span class='warning'>There is nothing to secure.</span>")
|
||||
return
|
||||
update_icon()
|
||||
@@ -548,10 +557,10 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
update_icon()
|
||||
|
||||
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
|
||||
togglelock()
|
||||
else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
|
||||
togglelock(user)
|
||||
|
||||
else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2)
|
||||
else if(istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
|
||||
var/turf/T = loc
|
||||
if(istype(T) && !T.is_plating())
|
||||
to_chat(user, "<span class='warning'>You must remove the floor plating in front of the APC first.</span>")
|
||||
@@ -564,9 +573,9 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
"You start adding cables to the APC frame...")
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if (C.amount >= 10 && !terminal && opened && has_electronics != 2)
|
||||
if(C.amount >= 10 && !terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
|
||||
var/obj/structure/cable/N = T.get_cable_node()
|
||||
if (prob(50) && electrocute_mob(usr, N, N))
|
||||
if(prob(50) && electrocute_mob(usr, N, N))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
@@ -578,7 +587,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
"You add cables to the APC frame.")
|
||||
make_terminal()
|
||||
terminal.connect_to_network()
|
||||
else if (W.is_wirecutter() && terminal && opened && has_electronics!=2)
|
||||
else if(W.is_wirecutter() && terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
|
||||
var/turf/T = loc
|
||||
if(istype(T) && !T.is_plating())
|
||||
to_chat(user, "<span class='warning'>You must remove the floor plating in front of the APC first.</span>")
|
||||
@@ -587,8 +596,8 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
"You begin to cut the cables...")
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(do_after(user, 50 * W.toolspeed))
|
||||
if(terminal && opened && has_electronics!=2)
|
||||
if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal))
|
||||
if(terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED)
|
||||
if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
@@ -597,22 +606,22 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
new /obj/item/stack/cable_coil(loc,10)
|
||||
to_chat(user, "<span class='notice'>You cut the cables and dismantle the power terminal.</span>")
|
||||
qdel(terminal)
|
||||
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN)))
|
||||
else if(istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && !((stat & BROKEN)))
|
||||
user.visible_message("<span class='warning'>[user.name] inserts the power control board into [src].</span>", \
|
||||
"You start to insert the power control board into the frame...")
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(do_after(user, 10))
|
||||
if(has_electronics==0)
|
||||
has_electronics = 1
|
||||
if(has_electronics == APC_HAS_ELECTRONICS_NONE)
|
||||
has_electronics = APC_HAS_ELECTRONICS_WIRED
|
||||
reboot()
|
||||
to_chat(user, "<span class='notice'>You place the power control board inside the frame.</span>")
|
||||
qdel(W)
|
||||
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && ((stat & BROKEN)))
|
||||
else if(istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && ((stat & BROKEN)))
|
||||
to_chat(user, "<span class='warning'>The [src] is too broken for that. Repair it first.</span>")
|
||||
return
|
||||
else if (istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics==0 && !terminal)
|
||||
else if(istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && !terminal)
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if (WT.get_fuel() < 3)
|
||||
if(WT.get_fuel() < 3)
|
||||
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user.name] begins cutting apart [src] with the [WT.name].</span>", \
|
||||
@@ -621,7 +630,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
playsound(src, WT.usesound, 25, 1)
|
||||
if(do_after(user, 50 * WT.toolspeed))
|
||||
if(!src || !WT.remove_fuel(3, user)) return
|
||||
if (emagged || (stat & BROKEN) || opened==2)
|
||||
if(emagged || (stat & BROKEN) || opened==2)
|
||||
new /obj/item/stack/material/steel(loc)
|
||||
user.visible_message(\
|
||||
"<span class='warning'>[src] has been cut apart by [user.name] with the [WT.name].</span>",\
|
||||
@@ -635,8 +644,8 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
"You hear welding.")
|
||||
qdel(src)
|
||||
return
|
||||
else if (opened && ((stat & BROKEN) || hacker || emagged))
|
||||
if (istype(W, /obj/item/frame/apc) && (stat & BROKEN))
|
||||
else if(opened && ((stat & BROKEN) || hacker || emagged))
|
||||
if(istype(W, /obj/item/frame/apc) && (stat & BROKEN))
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>You need to remove the power cell first.</span>")
|
||||
return
|
||||
@@ -648,10 +657,10 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
qdel(W)
|
||||
stat &= ~BROKEN
|
||||
reboot()
|
||||
if (opened==2)
|
||||
if(opened==2)
|
||||
opened = 1
|
||||
update_icon()
|
||||
else if (istype(W, /obj/item/device/multitool) && (hacker || emagged))
|
||||
else if(istype(W, /obj/item/device/multitool) && (hacker || emagged))
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>You need to remove the power cell first.</span>")
|
||||
return
|
||||
@@ -663,12 +672,12 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
playsound(src, 'sound/machines/chime.ogg', 25, 1)
|
||||
reboot()
|
||||
else
|
||||
if ((stat & BROKEN) \
|
||||
if((stat & BROKEN) \
|
||||
&& !opened \
|
||||
&& W.force >= 5 \
|
||||
&& W.w_class >= ITEMSIZE_SMALL )
|
||||
user.visible_message("<span class='danger'>The [src.name] has been hit with the [W.name] by [user.name]!</span>", \
|
||||
"<span class='danger'>You hit the [src.name] with your [W.name]!</span>", \
|
||||
user.visible_message("<span class='danger'>The [name] has been hit with the [W.name] by [user.name]!</span>", \
|
||||
"<span class='danger'>You hit the [name] with your [W.name]!</span>", \
|
||||
"You hear a bang!")
|
||||
if(prob(20))
|
||||
opened = 2
|
||||
@@ -677,12 +686,12 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
"You hear a bang!")
|
||||
update_icon()
|
||||
else
|
||||
if (istype(user, /mob/living/silicon))
|
||||
return src.attack_hand(user)
|
||||
if (!opened && wiresexposed && (istype(W, /obj/item/device/multitool) || W.is_wirecutter() || istype(W, /obj/item/device/assembly/signaler)))
|
||||
return src.attack_hand(user)
|
||||
if(istype(user, /mob/living/silicon))
|
||||
return attack_hand(user)
|
||||
if(!opened && wiresexposed && (istype(W, /obj/item/device/multitool) || W.is_wirecutter() || istype(W, /obj/item/device/assembly/signaler)))
|
||||
return attack_hand(user)
|
||||
//Placeholder until someone can do take_damage() for APCs or something.
|
||||
to_chat(user, "<span class='notice'>The [src.name] looks too sturdy to bash open with \the [W.name].</span>")
|
||||
to_chat(user, "<span class='notice'>The [name] looks too sturdy to bash open with \the [W.name].</span>")
|
||||
|
||||
// attack with hand - remove cell (if cover open) or interact with the APC
|
||||
|
||||
@@ -698,7 +707,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
else if(hacker)
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
else
|
||||
if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
|
||||
if(allowed(user) && !wires.is_cut(WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
to_chat(user, "You [ locked ? "lock" : "unlock"] the APC interface.")
|
||||
update_icon()
|
||||
@@ -707,10 +716,10 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
|
||||
/obj/machinery/power/apc/AltClick(mob/user)
|
||||
..()
|
||||
togglelock()
|
||||
togglelock(user)
|
||||
|
||||
/obj/machinery/power/apc/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (!(emagged || hacker)) // trying to unlock with an emag card
|
||||
if(!(emagged || hacker)) // trying to unlock with an emag card
|
||||
if(opened)
|
||||
to_chat(user, "You must close the cover to do that.")
|
||||
else if(wiresexposed)
|
||||
@@ -719,7 +728,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
to_chat(user, "The [src] isn't working.")
|
||||
else
|
||||
flick("apc-spark", src)
|
||||
if (do_after(user,6))
|
||||
if(do_after(user,6))
|
||||
emagged = 1
|
||||
locked = 0
|
||||
to_chat(user, "<span class='notice'>You emag the APC interface.</span>")
|
||||
@@ -733,11 +742,9 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/apc/attack_hand(mob/user)
|
||||
// if (!can_use(user)) This already gets called in interact() and in topic()
|
||||
// return
|
||||
if(!user)
|
||||
return
|
||||
src.add_fingerprint(user)
|
||||
add_fingerprint(user)
|
||||
|
||||
//Human mob special interaction goes here.
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
@@ -745,20 +752,20 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
|
||||
if(H.species.can_shred(H))
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
user.visible_message("<span call='warning'>[user.name] slashes at the [src.name]!</span>", "<span class='notice'>You slash at the [src.name]!</span>")
|
||||
user.visible_message("<span call='warning'>[user.name] slashes at the [name]!</span>", "<span class='notice'>You slash at the [name]!</span>")
|
||||
playsound(src, 'sound/weapons/slash.ogg', 100, 1)
|
||||
|
||||
var/allcut = wires.is_all_cut()
|
||||
|
||||
if(beenhit >= pick(3, 4) && wiresexposed != 1)
|
||||
wiresexposed = 1
|
||||
src.update_icon()
|
||||
src.visible_message("<span call='warning'>The [src.name]'s cover flies open, exposing the wires!</span>")
|
||||
update_icon()
|
||||
visible_message("<span call='warning'>The [name]'s cover flies open, exposing the wires!</span>")
|
||||
|
||||
else if(wiresexposed == 1 && allcut == 0)
|
||||
wires.cut_all()
|
||||
src.update_icon()
|
||||
src.visible_message("<span call='warning'>The [src.name]'s wires are shredded!</span>")
|
||||
update_icon()
|
||||
visible_message("<span call='warning'>The [name]'s wires are shredded!</span>")
|
||||
else
|
||||
beenhit += 1
|
||||
return
|
||||
@@ -769,16 +776,21 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
cell.add_fingerprint(user)
|
||||
cell.update_icon()
|
||||
|
||||
src.cell = null
|
||||
user.visible_message("<span class='warning'>[user.name] removes the power cell from [src.name]!</span>",\
|
||||
cell = null
|
||||
user.visible_message("<span class='warning'>[user.name] removes the power cell from [name]!</span>",\
|
||||
"<span class='notice'>You remove the power cell.</span>")
|
||||
charging = 0
|
||||
src.update_icon()
|
||||
update_icon()
|
||||
return
|
||||
if(stat & (BROKEN|MAINT))
|
||||
return
|
||||
// do APC interaction
|
||||
src.interact(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/apc/attack_ghost(mob/user)
|
||||
if(panel_open)
|
||||
return wires.Interact(user)
|
||||
return tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/apc/interact(mob/user)
|
||||
if(!user)
|
||||
@@ -788,15 +800,18 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
wires.Interact(user)
|
||||
return //The panel is visibly dark when the wires are exposed, so we shouldn't be able to interact with it.
|
||||
|
||||
return ui_interact(user)
|
||||
return tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/apc/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "APC", name) // 510, 460
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
/obj/machinery/power/apc/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"locked" = locked,
|
||||
"normallyLocked" = locked,
|
||||
"emagged" = emagged,
|
||||
"isOperating" = operating,
|
||||
"externalPower" = main_status,
|
||||
@@ -808,7 +823,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
"failTime" = failure_timer * 2,
|
||||
"gridCheck" = grid_check,
|
||||
"coverLocked" = coverlocked,
|
||||
"siliconUser" = issilicon(user) || isobserver(user), //I add observer here so admins can have more control, even if it makes 'siliconUser' seem inaccurate.
|
||||
"siliconUser" = issilicon(user) || (isobserver(user) && is_admin(user)), //I add observer here so admins can have more control, even if it makes 'siliconUser' seem inaccurate.
|
||||
"emergencyLights" = !emergency_lights,
|
||||
"nightshiftLights" = nightshift_lights,
|
||||
"nightshiftSetting" = nightshift_setting,
|
||||
@@ -847,18 +862,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
)
|
||||
)
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "apc.tmpl", "[area.name] - APC", 520, data["siliconUser"] ? 490 : 465)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/power/apc/proc/report()
|
||||
return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])"
|
||||
@@ -868,23 +872,23 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
area.power_light = (lighting >= POWERCHAN_ON)
|
||||
area.power_equip = (equipment >= POWERCHAN_ON)
|
||||
area.power_environ = (environ >= POWERCHAN_ON)
|
||||
// if (area.name == "AI Chamber")
|
||||
// if(area.name == "AI Chamber")
|
||||
// spawn(10)
|
||||
// to_world(" [area.name] [area.power_equip]")
|
||||
else
|
||||
area.power_light = 0
|
||||
area.power_equip = 0
|
||||
area.power_environ = 0
|
||||
// if (area.name == "AI Chamber")
|
||||
// if(area.name == "AI Chamber")
|
||||
// to_world("[area.power_equip]")
|
||||
area.power_change()
|
||||
|
||||
/obj/machinery/power/apc/proc/can_use(mob/user as mob, var/loud = 0) //used by attack_hand() and Topic()
|
||||
if(!user.client)
|
||||
return 0
|
||||
if(isobserver(user) && is_admin(user) ) //This is to allow nanoUI interaction by ghost admins.
|
||||
if(isobserver(user) && is_admin(user)) //This is to allow nanoUI interaction by ghost admins.
|
||||
return 1
|
||||
if (user.stat)
|
||||
if(user.stat)
|
||||
return 0
|
||||
if(inoperable())
|
||||
return 0
|
||||
@@ -897,7 +901,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
to_chat(user, "<span class='warning'>You must stand to use [src]!</span>")
|
||||
return 0
|
||||
autoflag = 5
|
||||
if (istype(user, /mob/living/silicon))
|
||||
if(istype(user, /mob/living/silicon))
|
||||
var/permit = 0 // Malfunction variable. If AI hacks APC it can control it even without AI control wire.
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
var/mob/living/silicon/robot/robot = user
|
||||
@@ -912,122 +916,90 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
to_chat(user, "<span class='danger'>\The AI control for [src] has been disabled!</span>")
|
||||
return 0
|
||||
else
|
||||
if (!in_range(src, user) || !istype(src.loc, /turf))
|
||||
if(!in_range(src, user) || !istype(loc, /turf))
|
||||
return 0
|
||||
var/mob/living/carbon/human/H = user
|
||||
if (istype(H) && prob(H.getBrainLoss()))
|
||||
if(istype(H) && prob(H.getBrainLoss()))
|
||||
to_chat(user, "<span class='danger'>You momentarily forget how to use [src].</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/power/apc/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
/obj/machinery/power/apc/tgui_act(action, params)
|
||||
if(..() || !can_use(usr, TRUE))
|
||||
return TRUE
|
||||
|
||||
if(!can_use(usr, 1))
|
||||
return 1
|
||||
// There's a handful of cases where we want to allow users to bypass the `locked` variable.
|
||||
// If can_admin_interact() wasn't only defined on observers, this could just be part of a single-line
|
||||
// conditional.
|
||||
var/locked_exception = FALSE
|
||||
if(issilicon(usr) || action == "nightshift")
|
||||
locked_exception = TRUE
|
||||
if(isobserver(usr))
|
||||
var/mob/observer/dead/D = usr
|
||||
if(D.can_admin_interact())
|
||||
locked_exception = TRUE
|
||||
|
||||
if(href_list["nightshift"])
|
||||
if(last_nightshift_switch > world.time - 10 SECONDS) // don't spam...
|
||||
to_chat(usr, "<span class='warning'>[src]'s night lighting circuit breaker is still cycling!</span>")
|
||||
return 0
|
||||
last_nightshift_switch = world.time
|
||||
nightshift_setting = text2num(href_list["nightshift"])
|
||||
update_nightshift()
|
||||
return 1
|
||||
if(locked && !locked_exception)
|
||||
return
|
||||
|
||||
if(locked && !issilicon(usr) )
|
||||
if(isobserver(usr) )
|
||||
var/mob/observer/dead/O = usr //Added to allow admin nanoUI interactions.
|
||||
if(!O.can_admin_interact() ) //NanoUI /should/ make this not needed, but better safe than sorry.
|
||||
to_chat(usr, "Try as you might, your ghostly fingers can't press the buttons.")
|
||||
return 1
|
||||
else
|
||||
to_chat(usr, "You must unlock the panel to use this!")
|
||||
return 1
|
||||
|
||||
if (href_list["lock"])
|
||||
coverlocked = !coverlocked
|
||||
|
||||
else if (href_list["reboot"])
|
||||
failure_timer = 0
|
||||
update_icon()
|
||||
update()
|
||||
|
||||
else if (href_list["emergency_lighting"])
|
||||
emergency_lights = !emergency_lights
|
||||
for(var/obj/machinery/light/L in area)
|
||||
if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override
|
||||
L.no_emergency = emergency_lights
|
||||
INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE)
|
||||
CHECK_TICK
|
||||
|
||||
else if (href_list["breaker"])
|
||||
toggle_breaker()
|
||||
|
||||
else if (href_list["cmode"])
|
||||
chargemode = !chargemode
|
||||
if(!chargemode)
|
||||
charging = 0
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("lock")
|
||||
if(locked_exception) // Yay code reuse
|
||||
if(emagged || (stat & (BROKEN|MAINT)))
|
||||
to_chat(usr, "The APC does not respond to the command.")
|
||||
return
|
||||
locked = !locked
|
||||
update_icon()
|
||||
if("cover")
|
||||
coverlocked = !coverlocked
|
||||
if("breaker")
|
||||
toggle_breaker()
|
||||
if("nightshift")
|
||||
if(last_nightshift_switch > world.time - 10 SECONDS) // don't spam...
|
||||
to_chat(usr, "<span class='warning'>[src]'s night lighting circuit breaker is still cycling!</span>")
|
||||
return 0
|
||||
last_nightshift_switch = world.time
|
||||
nightshift_setting = params["nightshift"]
|
||||
update_nightshift()
|
||||
if("charge")
|
||||
chargemode = !chargemode
|
||||
if(!chargemode)
|
||||
charging = 0
|
||||
update_icon()
|
||||
if("channel")
|
||||
if(params["eqp"])
|
||||
equipment = setsubsystem(text2num(params["eqp"]))
|
||||
update_icon()
|
||||
update()
|
||||
else if(params["lgt"])
|
||||
lighting = setsubsystem(text2num(params["lgt"]))
|
||||
update_icon()
|
||||
update()
|
||||
else if(params["env"])
|
||||
environ = setsubsystem(text2num(params["env"]))
|
||||
update_icon()
|
||||
update()
|
||||
if("reboot")
|
||||
failure_timer = 0
|
||||
update_icon()
|
||||
|
||||
else if (href_list["eqp"])
|
||||
var/val = text2num(href_list["eqp"])
|
||||
equipment = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
|
||||
else if (href_list["lgt"])
|
||||
var/val = text2num(href_list["lgt"])
|
||||
lighting = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
|
||||
else if (href_list["env"])
|
||||
var/val = text2num(href_list["env"])
|
||||
environ = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
|
||||
else if (href_list["overload"])
|
||||
if(istype(usr, /mob/living/silicon))
|
||||
src.overload_lighting()
|
||||
|
||||
else if (href_list["toggleaccess"])
|
||||
if(istype(usr, /mob/living/silicon))
|
||||
if(emagged || (stat & (BROKEN|MAINT)))
|
||||
to_chat(usr, "The APC does not respond to the command.")
|
||||
return
|
||||
locked = !locked
|
||||
update_icon()
|
||||
|
||||
return 0
|
||||
update()
|
||||
if("emergency_lighting")
|
||||
emergency_lights = !emergency_lights
|
||||
for(var/obj/machinery/light/L in area)
|
||||
if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override
|
||||
L.no_emergency = emergency_lights
|
||||
INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE)
|
||||
CHECK_TICK
|
||||
if("overload")
|
||||
if(locked_exception) // Reusing for simplicity!
|
||||
overload_lighting()
|
||||
|
||||
/obj/machinery/power/apc/proc/toggle_breaker()
|
||||
operating = !operating
|
||||
src.update()
|
||||
update()
|
||||
update_icon()
|
||||
|
||||
//This isn't used for now, so might as well disable it
|
||||
/*
|
||||
/obj/machinery/power/apc/proc/ion_act()
|
||||
if(prob(3))
|
||||
src.locked = 1
|
||||
if (src.cell.charge > 0)
|
||||
src.cell.charge = 0
|
||||
cell.corrupt()
|
||||
update_icon()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
|
||||
smoke.set_up(3, 0, src.loc)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
visible_message("<span class='danger'>The [src.name] suddenly lets out a blast of smoke and some sparks!</span>", \
|
||||
"<span class='danger'>You hear sizzling electronics.</span>")
|
||||
*/
|
||||
|
||||
/obj/machinery/power/apc/surplus()
|
||||
if(terminal)
|
||||
return terminal.surplus()
|
||||
@@ -1083,12 +1055,12 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
|
||||
var/excess = surplus()
|
||||
|
||||
if(!src.avail())
|
||||
main_status = 0
|
||||
if(!avail())
|
||||
main_status = APC_EXTERNAL_POWER_NOTCONNECTED
|
||||
else if(excess < 0)
|
||||
main_status = 1
|
||||
main_status = APC_EXTERNAL_POWER_NOENERGY
|
||||
else
|
||||
main_status = 2
|
||||
main_status = APC_EXTERNAL_POWER_GOOD
|
||||
|
||||
if(debug)
|
||||
log_debug("Status: [main_status] - Excess: [excess] - Last Equip: [lastused_equip] - Last Light: [lastused_light] - Longterm: [longtermpower]")
|
||||
@@ -1122,7 +1094,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
|
||||
// now trickle-charge the cell
|
||||
lastused_charging = 0 // Clear the variable for new use.
|
||||
if(src.attempt_charging())
|
||||
if(attempt_charging())
|
||||
if(excess > 0) // check to make sure we have enough to charge
|
||||
// Max charge is capped to % per second constant
|
||||
var/ch = min(excess*CELLRATE, cell.maxcharge*chargelevel)
|
||||
@@ -1170,7 +1142,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
force_update = 0
|
||||
queue_icon_update()
|
||||
update()
|
||||
else if (last_ch != charging)
|
||||
else if(last_ch != charging)
|
||||
queue_icon_update()
|
||||
|
||||
/obj/machinery/power/apc/proc/update_channels()
|
||||
@@ -1212,7 +1184,7 @@ GLOBAL_LIST_EMPTY(apcs)
|
||||
// val 0=off, 1=off(auto) 2=on 3=on(auto)
|
||||
// on 0=off, 1=on, 2=autooff
|
||||
// defines a state machine, returns the new state
|
||||
obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
|
||||
/obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
|
||||
switch(cur_state)
|
||||
//if(POWERCHAN_OFF); //autoset will never turn on a channel set to off
|
||||
if(POWERCHAN_OFF_AUTO)
|
||||
@@ -1253,24 +1225,24 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
|
||||
switch(severity)
|
||||
if(1)
|
||||
//set_broken() //now qdel() do what we need
|
||||
if (cell)
|
||||
if(cell)
|
||||
cell.ex_act(1) // more lags woohoo
|
||||
qdel(src)
|
||||
return
|
||||
if(2)
|
||||
if (prob(75))
|
||||
if(prob(75))
|
||||
set_broken()
|
||||
if (cell && prob(50))
|
||||
if(cell && prob(50))
|
||||
cell.ex_act(2)
|
||||
if(3)
|
||||
if (prob(50))
|
||||
if(prob(50))
|
||||
set_broken()
|
||||
if (cell && prob(50))
|
||||
if(cell && prob(50))
|
||||
cell.ex_act(3)
|
||||
if(4)
|
||||
if (prob(25))
|
||||
if(prob(25))
|
||||
set_broken()
|
||||
if (cell && prob(50))
|
||||
if(cell && prob(50))
|
||||
cell.ex_act(3)
|
||||
return
|
||||
|
||||
@@ -1282,7 +1254,7 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
|
||||
/obj/machinery/power/apc/proc/set_broken()
|
||||
// Aesthetically much better!
|
||||
spawn(rand(2,5))
|
||||
src.visible_message("<span class='warning'>[src]'s screen flickers suddenly, then explodes in a rain of sparks and small debris!</span>")
|
||||
visible_message("<span class='warning'>[src]'s screen flickers suddenly, then explodes in a rain of sparks and small debris!</span>")
|
||||
stat |= BROKEN
|
||||
operating = 0
|
||||
update_icon()
|
||||
@@ -1314,7 +1286,7 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
|
||||
/obj/machinery/power/apc/proc/ai_hack(var/mob/living/silicon/ai/A = null)
|
||||
if(!A || !A.hacked_apcs || hacker || aidisabled || A.stat == DEAD)
|
||||
return 0
|
||||
src.hacker = A
|
||||
hacker = A
|
||||
A.hacked_apcs += src
|
||||
locked = 1
|
||||
update_icon()
|
||||
@@ -1406,3 +1378,11 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on)
|
||||
CHECK_TICK
|
||||
|
||||
#undef APC_UPDATE_ICON_COOLDOWN
|
||||
|
||||
#undef APC_EXTERNAL_POWER_NOTCONNECTED
|
||||
#undef APC_EXTERNAL_POWER_NOENERGY
|
||||
#undef APC_EXTERNAL_POWER_GOOD
|
||||
|
||||
#undef APC_HAS_ELECTRONICS_NONE
|
||||
#undef APC_HAS_ELECTRONICS_WIRED
|
||||
#undef APC_HAS_ELECTRONICS_SECURED
|
||||
@@ -25,7 +25,7 @@
|
||||
for(var/obj/structure/cable/C in src.loc)
|
||||
qdel(C)
|
||||
. = ..()
|
||||
for(var/datum/nano_module/rcon/R in world)
|
||||
for(var/datum/tgui_module/rcon/R in world)
|
||||
R.FindDevices()
|
||||
|
||||
/obj/machinery/power/breakerbox/Initialize()
|
||||
|
||||
@@ -192,58 +192,48 @@ GLOBAL_LIST_EMPTY(all_turbines)
|
||||
if(stat & (BROKEN|NOPOWER) || !anchored) return
|
||||
if(!circ1 || !circ2) //Just incase the middle part of the TEG was not wrenched last.
|
||||
reconnect()
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/generator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/machinery/power/generator/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "TEGenerator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/generator/tgui_data(mob/user)
|
||||
// this is the data which will be sent to the ui
|
||||
var/vertical = 0
|
||||
if (dir == NORTH || dir == SOUTH)
|
||||
vertical = 1
|
||||
|
||||
var/data[0]
|
||||
data["totalOutput"] = effective_gen/1000
|
||||
data["maxTotalOutput"] = max_power/1000
|
||||
data["thermalOutput"] = last_thermal_gen/1000
|
||||
data["circConnected"] = 0
|
||||
var/list/data = list()
|
||||
data["totalOutput"] = effective_gen
|
||||
data["maxTotalOutput"] = max_power
|
||||
data["thermalOutput"] = last_thermal_gen
|
||||
|
||||
data["primary"] = list()
|
||||
if(circ1)
|
||||
//The one on the left (or top)
|
||||
data["primaryDir"] = vertical ? "top" : "left"
|
||||
data["primaryOutput"] = last_circ1_gen/1000
|
||||
data["primaryFlowCapacity"] = circ1.volume_capacity_used*100
|
||||
data["primaryInletPressure"] = circ1.air1.return_pressure()
|
||||
data["primaryInletTemperature"] = circ1.air1.temperature
|
||||
data["primaryOutletPressure"] = circ1.air2.return_pressure()
|
||||
data["primaryOutletTemperature"] = circ1.air2.temperature
|
||||
data["primary"]["dir"] = vertical ? "top" : "left"
|
||||
data["primary"]["output"] = last_circ1_gen
|
||||
data["primary"]["flowCapacity"] = circ1.volume_capacity_used*100
|
||||
data["primary"]["inletPressure"] = circ1.air1.return_pressure()
|
||||
data["primary"]["inletTemperature"] = circ1.air1.temperature
|
||||
data["primary"]["outletPressure"] = circ1.air2.return_pressure()
|
||||
data["primary"]["outletTemperature"] = circ1.air2.temperature
|
||||
|
||||
data["secondary"] = list()
|
||||
if(circ2)
|
||||
//Now for the one on the right (or bottom)
|
||||
data["secondaryDir"] = vertical ? "bottom" : "right"
|
||||
data["secondaryOutput"] = last_circ2_gen/1000
|
||||
data["secondaryFlowCapacity"] = circ2.volume_capacity_used*100
|
||||
data["secondaryInletPressure"] = circ2.air1.return_pressure()
|
||||
data["secondaryInletTemperature"] = circ2.air1.temperature
|
||||
data["secondaryOutletPressure"] = circ2.air2.return_pressure()
|
||||
data["secondaryOutletTemperature"] = circ2.air2.temperature
|
||||
data["secondary"]["dir"] = vertical ? "bottom" : "right"
|
||||
data["secondary"]["output"] = last_circ2_gen
|
||||
data["secondary"]["flowCapacity"] = circ2.volume_capacity_used*100
|
||||
data["secondary"]["inletPressure"] = circ2.air1.return_pressure()
|
||||
data["secondary"]["inletTemperature"] = circ2.air1.temperature
|
||||
data["secondary"]["outletPressure"] = circ2.air2.return_pressure()
|
||||
data["secondary"]["outletTemperature"] = circ2.air2.temperature
|
||||
|
||||
if(circ1 && circ2)
|
||||
data["circConnected"] = 1
|
||||
else
|
||||
data["circConnected"] = 0
|
||||
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "generator.tmpl", "Thermoelectric Generator", 450, 500)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/power/generator/power_change()
|
||||
..()
|
||||
|
||||
@@ -240,11 +240,16 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
/obj/machinery/gravity_generator/main/attack_hand(mob/user)
|
||||
if((. = ..()))
|
||||
return
|
||||
if(CanUseTopic(user, global.default_state) > STATUS_CLOSE)
|
||||
ui_interact(user)
|
||||
return TRUE
|
||||
tgui_interact(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/gravity_generator/main/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/machinery/gravity_generator/main/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "GravityGenerator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/gravity_generator/main/tgui_data(mob/user)
|
||||
var/data[0]
|
||||
|
||||
data["breaker"] = breaker
|
||||
@@ -253,22 +258,18 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
data["on"] = on
|
||||
data["operational"] = (stat & BROKEN) ? FALSE : TRUE
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "gravity_generator.tmpl", src.name, 500, 400)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/gravity_generator/main/Topic(href, href_list, datum/topic_state/state = default_state)
|
||||
if((. = ..()))
|
||||
return
|
||||
/obj/machinery/gravity_generator/main/tgui_act(action, params)
|
||||
if((..()))
|
||||
return TRUE
|
||||
|
||||
if(href_list["gentoggle"])
|
||||
breaker = !breaker
|
||||
investigate_log("was toggled [breaker ? "<font color='green'>ON</font>" : "<font color='red'>OFF</font>"] by [key_name(usr)].", "gravity")
|
||||
set_power()
|
||||
return TOPIC_REFRESH
|
||||
switch(action)
|
||||
if("gentoggle")
|
||||
breaker = !breaker
|
||||
investigate_log("was toggled [breaker ? "<font color='green'>ON</font>" : "<font color='red'>OFF</font>"] by [key_name(usr)].", "gravity")
|
||||
set_power()
|
||||
return TOPIC_REFRESH
|
||||
|
||||
// Power and Icon States
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
density = 1
|
||||
anchored = 0
|
||||
use_power = USE_POWER_OFF
|
||||
interact_offline = TRUE
|
||||
|
||||
var/active = 0
|
||||
var/power_gen = 5000
|
||||
@@ -28,13 +29,22 @@
|
||||
/obj/machinery/power/port_gen/proc/handleInactive()
|
||||
return
|
||||
|
||||
/obj/machinery/power/port_gen/proc/TogglePower()
|
||||
if(active)
|
||||
active = FALSE
|
||||
icon_state = "[initial(icon_state)]"
|
||||
// soundloop.stop()
|
||||
else if(HasFuel())
|
||||
active = TRUE
|
||||
icon_state = "[initial(icon_state)]on"
|
||||
// soundloop.start()
|
||||
|
||||
/obj/machinery/power/port_gen/process()
|
||||
if(active && HasFuel() && !IsBroken() && anchored && powernet)
|
||||
add_avail(power_gen * power_output)
|
||||
UseFuel()
|
||||
src.updateDialog()
|
||||
else
|
||||
active = 0
|
||||
active = FALSE
|
||||
icon_state = initial(icon_state)
|
||||
handleInactive()
|
||||
|
||||
@@ -121,7 +131,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/dismantle()
|
||||
while ( sheets > 0 )
|
||||
while( sheets > 0 )
|
||||
DropFuel()
|
||||
return ..()
|
||||
|
||||
@@ -212,16 +222,16 @@
|
||||
/obj/machinery/power/port_gen/pacman/handleInactive()
|
||||
var/cooling_temperature = 20
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if (environment)
|
||||
if(environment)
|
||||
var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1)
|
||||
var/ambient = environment.temperature - T20C
|
||||
cooling_temperature += ambient*ratio
|
||||
|
||||
if (temperature > cooling_temperature)
|
||||
if(temperature > cooling_temperature)
|
||||
var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR
|
||||
temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX)
|
||||
temperature = max(temperature - temp_loss, cooling_temperature)
|
||||
src.updateDialog()
|
||||
updateDialog()
|
||||
|
||||
if(overheating)
|
||||
overheating--
|
||||
@@ -287,97 +297,77 @@
|
||||
..()
|
||||
if (!anchored)
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/machinery/power/port_gen/tgui_status(mob/user, datum/tgui_state/state)
|
||||
if(IsBroken())
|
||||
return
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PortableGenerator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/data[0]
|
||||
data["active"] = active
|
||||
|
||||
if(istype(user, /mob/living/silicon/ai))
|
||||
data["is_ai"] = 1
|
||||
data["is_ai"] = TRUE
|
||||
else if(istype(user, /mob/living/silicon/robot) && !Adjacent(user))
|
||||
data["is_ai"] = 1
|
||||
data["is_ai"] = TRUE
|
||||
else
|
||||
data["is_ai"] = 0
|
||||
data["output_set"] = power_output
|
||||
data["output_max"] = max_power_output
|
||||
data["output_safe"] = max_safe_output
|
||||
data["output_watts"] = power_output * power_gen
|
||||
data["temperature_current"] = src.temperature
|
||||
data["temperature_max"] = src.max_temperature
|
||||
data["temperature_overheat"] = overheating
|
||||
// 1 sheet = 1000cm3?
|
||||
data["is_ai"] = FALSE
|
||||
|
||||
data["sheet_name"] = capitalize(sheet_name)
|
||||
data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000))
|
||||
data["fuel_capacity"] = round(max_sheets * 1000, 0.1)
|
||||
data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0
|
||||
data["fuel_type"] = sheet_name
|
||||
|
||||
data["anchored"] = anchored
|
||||
data["connected"] = (powernet == null ? 0 : 1)
|
||||
data["ready_to_boot"] = anchored && HasFuel()
|
||||
data["power_generated"] = DisplayPower(power_gen)
|
||||
data["power_output"] = DisplayPower(power_gen * power_output)
|
||||
data["unsafe_output"] = power_output > max_safe_output
|
||||
data["power_available"] = (powernet == null ? 0 : DisplayPower(avail()))
|
||||
data["temperature_current"] = temperature
|
||||
data["temperature_max"] = max_temperature
|
||||
data["temperature_overheat"] = overheating
|
||||
// 1 sheet = 1000cm3?
|
||||
|
||||
return data
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "pacman.tmpl", src.name, 500, 560)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
|
||||
/*
|
||||
/obj/machinery/power/port_gen/pacman/interact(mob/user)
|
||||
if (get_dist(src, user) > 1 )
|
||||
if (!istype(user, /mob/living/silicon/ai))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=port_gen"
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = text("<b>[name]</b><br>")
|
||||
if (active)
|
||||
dat += text("Generator: <A href='?src=\ref[src];action=disable'>On</A><br>")
|
||||
else
|
||||
dat += text("Generator: <A href='?src=\ref[src];action=enable'>Off</A><br>")
|
||||
dat += text("[capitalize(sheet_name)]: [sheets] - <A href='?src=\ref[src];action=eject'>Eject</A><br>")
|
||||
var/stack_percent = round(sheet_left * 100, 1)
|
||||
dat += text("Current stack: [stack_percent]% <br>")
|
||||
dat += text("Power output: <A href='?src=\ref[src];action=lower_power'>-</A> [power_gen * power_output] Watts<A href='?src=\ref[src];action=higher_power'>+</A><br>")
|
||||
dat += text("Power current: [(powernet == null ? "Unconnected" : "[avail()]")]<br>")
|
||||
|
||||
var/tempstr = "Temperature: [temperature]°C<br>"
|
||||
dat += (overheating)? "<span class='danger'>[tempstr]</span>" : tempstr
|
||||
dat += "<br><A href='?src=\ref[src];action=close'>Close</A>"
|
||||
user << browse("[dat]", "window=port_gen")
|
||||
onclose(user, "port_gen")
|
||||
*/
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/Topic(href, href_list)
|
||||
/obj/machinery/power/port_gen/pacman/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["action"])
|
||||
if(href_list["action"] == "enable")
|
||||
if(!active && HasFuel() && !IsBroken())
|
||||
active = 1
|
||||
icon_state = "[initial(icon_state)]on" //VOREStation Edit
|
||||
if(href_list["action"] == "disable")
|
||||
if (active)
|
||||
active = 0
|
||||
icon_state = initial(icon_state) //VOREStation Edit
|
||||
if(href_list["action"] == "eject")
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("toggle_power")
|
||||
TogglePower()
|
||||
. = TRUE
|
||||
|
||||
if("eject")
|
||||
if(!active)
|
||||
DropFuel()
|
||||
if(href_list["action"] == "lower_power")
|
||||
if (power_output > 1)
|
||||
. = TRUE
|
||||
|
||||
if("lower_power")
|
||||
if(power_output > 1)
|
||||
power_output--
|
||||
if (href_list["action"] == "higher_power")
|
||||
if (power_output < max_power_output || (emagged && power_output < round(max_power_output*2.5)))
|
||||
. = TRUE
|
||||
|
||||
if("higher_power")
|
||||
if(power_output < max_power_output || (emagged && power_output < round(max_power_output * 2.5)))
|
||||
power_output++
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super
|
||||
name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/load = 0 // the current load on the powernet, increased by each machine at processing
|
||||
var/newavail = 0 // what available power was gathered last tick, then becomes...
|
||||
var/avail = 0 //...the current available power in the powernet
|
||||
var/viewavail = 0 // the availability as it appears on the power console (gradually updated)
|
||||
var/viewload = 0 // the load as it appears on the power console (gradually updated)
|
||||
var/number = 0 // Unused //TODEL
|
||||
|
||||
@@ -134,7 +135,8 @@
|
||||
S.restore(perc)
|
||||
|
||||
//updates the viewed load (as seen on power computers)
|
||||
viewload = round(load)
|
||||
viewavail = round(0.8 * viewavail + 0.2 * avail)
|
||||
viewload = round(0.8 * viewload + 0.2 * load)
|
||||
|
||||
//reset the powernet
|
||||
load = 0
|
||||
|
||||
@@ -19,12 +19,22 @@
|
||||
var/name_tag = "#UNKN#" // ID tag displayed in list of powernet sensors. Each sensor should have it's own tag!
|
||||
var/long_range = 0 // If 1, sensor reading will show on all computers, regardless of Zlevel
|
||||
|
||||
var/list/history = list()
|
||||
var/record_size = 60
|
||||
var/record_interval = 50
|
||||
var/next_record = 0
|
||||
var/is_secret_monitor = FALSE
|
||||
|
||||
// Proc: New()
|
||||
// Parameters: None
|
||||
// Description: Automatically assigns name according to ID tag.
|
||||
/obj/machinery/power/sensor/New()
|
||||
..()
|
||||
auto_set_name()
|
||||
/obj/machinery/power/sensor/Initialize()
|
||||
. = ..()
|
||||
history["supply"] = list()
|
||||
history["demand"] = list()
|
||||
|
||||
// Proc: auto_set_name()
|
||||
// Parameters: None
|
||||
@@ -38,6 +48,8 @@
|
||||
for(var/obj/machinery/computer/power_monitor/PM in machines)
|
||||
if(PM.power_monitor)
|
||||
PM.power_monitor.refresh_sensors()
|
||||
history.Cut()
|
||||
history = null
|
||||
|
||||
// Proc: check_grid_warning()
|
||||
// Parameters: None
|
||||
@@ -51,10 +63,67 @@
|
||||
|
||||
// Proc: process()
|
||||
// Parameters: None
|
||||
// Description: This has to be here because we need sensors to remain in Machines list.
|
||||
// Description: This tracks historical usage, for TGUI power monitors
|
||||
/obj/machinery/power/sensor/process()
|
||||
if(!powernet)
|
||||
use_power = USE_POWER_IDLE
|
||||
connect_to_network()
|
||||
else
|
||||
use_power = USE_POWER_ACTIVE
|
||||
record()
|
||||
return 1
|
||||
|
||||
// This tracks historical usage, for TGUI power monitors
|
||||
/obj/machinery/power/sensor/proc/record()
|
||||
if(world.time >= next_record)
|
||||
next_record = world.time + record_interval
|
||||
|
||||
var/datum/powernet/connected_powernet = powernet
|
||||
|
||||
var/list/supply = history["supply"]
|
||||
if(connected_powernet)
|
||||
supply += connected_powernet.viewavail
|
||||
if(supply.len > record_size)
|
||||
supply.Cut(1, 2)
|
||||
|
||||
var/list/demand = history["demand"]
|
||||
if(connected_powernet)
|
||||
demand += connected_powernet.viewload
|
||||
if(demand.len > record_size)
|
||||
demand.Cut(1, 2)
|
||||
|
||||
/obj/machinery/power/sensor/tgui_data()
|
||||
var/list/data = list()
|
||||
|
||||
data["name"] = name_tag
|
||||
data["stored"] = record_size
|
||||
data["interval"] = record_interval / 10
|
||||
data["attached"] = !!powernet
|
||||
data["history"] = history
|
||||
|
||||
data["areas"] = list()
|
||||
if(powernet)
|
||||
for(var/obj/machinery/power/terminal/term in powernet.nodes)
|
||||
if(istype(term.master, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = term.master
|
||||
if(istype(A))
|
||||
var/cell_charge
|
||||
if(!A.cell)
|
||||
cell_charge = 0
|
||||
else
|
||||
cell_charge = A.cell.percent()
|
||||
data["areas"] += list(list(
|
||||
"name" = A.area.name,
|
||||
"charge" = cell_charge,
|
||||
"load" = DisplayPower(A.lastused_total),
|
||||
"charging" = A.charging,
|
||||
"eqp" = A.equipment,
|
||||
"lgt" = A.lighting,
|
||||
"env" = A.environ,
|
||||
))
|
||||
|
||||
return data
|
||||
|
||||
// Proc: reading_to_text()
|
||||
// Parameters: 1 (amount - Power in Watts to be converted to W, kW or MW)
|
||||
// Description: Helper proc that converts reading in Watts to kW or MW (returns string version of amount parameter)
|
||||
@@ -178,7 +247,7 @@
|
||||
APC_entry["total_load"] = reading_to_text(A.lastused_total)
|
||||
// Hopefully removes those goddamn \improper s which are screwing up the UI
|
||||
var/N = A.area.name
|
||||
if(findtext(N, "ÿ"))
|
||||
if(findtext(N, "�"))
|
||||
N = copytext(N, 3)
|
||||
APC_entry["name"] = N
|
||||
// Add data into main list of APC data.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
use_power = USE_POWER_IDLE
|
||||
idle_power_usage = 300
|
||||
active_power_usage = 300
|
||||
var/datum/nano_module/power_monitor/power_monitor
|
||||
var/datum/tgui_module/power_monitor/power_monitor
|
||||
|
||||
// Checks the sensors for alerts. If change (alerts cleared or detected) occurs, calls for icon update.
|
||||
/obj/machinery/computer/power_monitor/process()
|
||||
@@ -47,12 +47,11 @@
|
||||
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
// Uses dark magic to operate the NanoUI of this computer.
|
||||
/obj/machinery/computer/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
power_monitor.ui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
/obj/machinery/computer/power_monitor/tgui_interact(mob/user, var/datum/tgui/ui = null)
|
||||
power_monitor.tgui_interact(user, ui)
|
||||
|
||||
// Verifies if any warnings were registered by connected sensors.
|
||||
/obj/machinery/computer/power_monitor/proc/check_warnings()
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user as mob)
|
||||
if(construction_state >= 3)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
else if(construction_state == 2) // Wires exposed
|
||||
wires.Interact(user)
|
||||
|
||||
@@ -77,36 +77,6 @@
|
||||
else
|
||||
icon_state = "[reference]c"
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Topic(href, href_list)
|
||||
..()
|
||||
//Ignore input if we are broken, !silicon guy cant touch us, or nonai controlling from super far away
|
||||
if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !istype(usr, /mob/living/silicon)) || (get_dist(src, usr) > 8 && !istype(usr, /mob/living/silicon/ai)))
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=pacontrol")
|
||||
return
|
||||
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=pacontrol")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
if(href_list["togglep"])
|
||||
if(!wires.is_cut(WIRE_PARTICLE_POWER))
|
||||
toggle_power()
|
||||
else if(href_list["scan"])
|
||||
part_scan()
|
||||
|
||||
else if(href_list["strengthup"])
|
||||
if(!wires.is_cut(WIRE_PARTICLE_STRENGTH))
|
||||
add_strength()
|
||||
|
||||
else if(href_list["strengthdown"])
|
||||
if(!wires.is_cut(WIRE_PARTICLE_STRENGTH))
|
||||
remove_strength()
|
||||
|
||||
updateDialog()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
|
||||
for(var/obj/structure/particle_accelerator/part in connected_parts)
|
||||
part.strength = strength
|
||||
@@ -230,33 +200,54 @@
|
||||
part.update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/is_interactive(mob/user)
|
||||
if(!interface_control)
|
||||
to_chat(user, "<span class='alert'>ERROR: Request timed out. Check wire contacts.</span>")
|
||||
return FALSE
|
||||
if(construction_state != 3)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/interact(mob/user)
|
||||
if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER)))
|
||||
if(!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=pacontrol")
|
||||
return
|
||||
user.set_machine(src)
|
||||
/obj/machinery/particle_accelerator/control_box/tgui_status(mob/user)
|
||||
if(is_interactive(user))
|
||||
return ..()
|
||||
return STATUS_CLOSE
|
||||
|
||||
var/dat = ""
|
||||
dat += "Particle Accelerator Control Panel<BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</A><BR><BR>"
|
||||
dat += "Status:<BR>"
|
||||
if(!assembled)
|
||||
dat += "Unable to detect all parts!<BR>"
|
||||
dat += "<A href='?src=\ref[src];scan=1'>Run Scan</A><BR><BR>"
|
||||
else
|
||||
dat += "All parts in place.<BR><BR>"
|
||||
dat += "Power:"
|
||||
if(active)
|
||||
dat += "On<BR>"
|
||||
else
|
||||
dat += "Off <BR>"
|
||||
dat += "<A href='?src=\ref[src];togglep=1'>Toggle Power</A><BR><BR>"
|
||||
dat += "Particle Strength: [src.strength] "
|
||||
dat += "<A href='?src=\ref[src];strengthdown=1'>--</A>|<A href='?src=\ref[src];strengthup=1'>++</A><BR><BR>"
|
||||
/obj/machinery/particle_accelerator/control_box/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ParticleAccelerator", name)
|
||||
ui.open()
|
||||
|
||||
user << browse(dat, "window=pacontrol;size=420x500")
|
||||
onclose(user, "pacontrol")
|
||||
return
|
||||
/obj/machinery/particle_accelerator/control_box/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["assembled"] = assembled
|
||||
data["power"] = active
|
||||
data["strength"] = strength
|
||||
return data
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("power")
|
||||
if(wires.is_cut(WIRE_POWER))
|
||||
return
|
||||
toggle_power()
|
||||
. = TRUE
|
||||
if("scan")
|
||||
part_scan()
|
||||
. = TRUE
|
||||
if("add_strength")
|
||||
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
|
||||
return
|
||||
add_strength()
|
||||
. = TRUE
|
||||
if("remove_strength")
|
||||
if(wires.is_cut(WIRE_PARTICLE_STRENGTH))
|
||||
return
|
||||
remove_strength()
|
||||
. = TRUE
|
||||
|
||||
update_icon()
|
||||
|
||||
+72
-66
@@ -263,11 +263,11 @@ GLOBAL_LIST_EMPTY(smeses)
|
||||
|
||||
/obj/machinery/power/smes/attack_ai(mob/user)
|
||||
add_hiddenprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/smes/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
|
||||
/obj/machinery/power/smes/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
@@ -344,78 +344,84 @@ GLOBAL_LIST_EMPTY(smeses)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
data["nameTag"] = name_tag
|
||||
data["storedCapacity"] = round(100.0*charge/capacity, 0.1)
|
||||
data["storedCapacityAbs"] = round(charge/(1000*60), 0.1)
|
||||
data["storedCapacityMax"] = round(capacity/(1000*60))
|
||||
data["charging"] = inputting
|
||||
data["chargeMode"] = input_attempt
|
||||
data["chargeLevel"] = round(input_level/1000, 0.1)
|
||||
data["chargeMax"] = round(input_level_max/1000)
|
||||
data["chargeLoad"] = round(input_available/1000, 0.1)
|
||||
data["outputOnline"] = output_attempt
|
||||
data["outputLevel"] = round(output_level/1000, 0.1)
|
||||
data["outputMax"] = round(output_level_max/1000)
|
||||
data["outputLoad"] = round(output_used/1000, 0.1)
|
||||
data["outputting"] = outputting
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "smes.tmpl", "SMES Unit", 540, 380)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
/obj/machinery/power/smes/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Smes", name)
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/power/smes/tgui_data()
|
||||
var/list/data = list(
|
||||
"capacity" = capacity,
|
||||
"capacityPercent" = round(100*charge/capacity, 0.1),
|
||||
"charge" = charge,
|
||||
"inputAttempt" = input_attempt,
|
||||
"inputting" = inputting,
|
||||
"inputLevel" = input_level,
|
||||
"inputLevel_text" = DisplayPower(input_level),
|
||||
"inputLevelMax" = input_level_max,
|
||||
"inputAvailable" = input_available,
|
||||
"outputAttempt" = output_attempt,
|
||||
"outputting" = outputting,
|
||||
"outputLevel" = output_level,
|
||||
"outputLevel_text" = DisplayPower(output_level),
|
||||
"outputLevelMax" = output_level_max,
|
||||
"outputUsed" = output_used,
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/machinery/power/smes/proc/Percentage()
|
||||
if(!capacity)
|
||||
return 0
|
||||
return round(100.0*charge/capacity, 0.1)
|
||||
|
||||
/obj/machinery/power/smes/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if( href_list["cmode"] )
|
||||
inputting(!input_attempt)
|
||||
update_icon()
|
||||
return 1
|
||||
else if( href_list["online"] )
|
||||
outputting(!output_attempt)
|
||||
update_icon()
|
||||
return 1
|
||||
else if( href_list["input"] )
|
||||
switch( href_list["input"] )
|
||||
if("min")
|
||||
input_level = 0
|
||||
if("max")
|
||||
input_level = input_level_max
|
||||
if("set")
|
||||
input_level = (input(usr, "Enter new input level (0-[input_level_max/1000] kW)", "SMES Input Power Control", input_level/1000) as num) * 1000
|
||||
input_level = max(0, min(input_level_max, input_level)) // clamp to range
|
||||
return 1
|
||||
else if( href_list["output"] )
|
||||
switch( href_list["output"] )
|
||||
if("min")
|
||||
output_level = 0
|
||||
if("max")
|
||||
output_level = output_level_max
|
||||
if("set")
|
||||
output_level = (input(usr, "Enter new output level (0-[output_level_max/1000] kW)", "SMES Output Power Control", output_level/1000) as num) * 1000
|
||||
output_level = max(0, min(output_level_max, output_level)) // clamp to range
|
||||
return 1
|
||||
/obj/machinery/power/smes/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("tryinput")
|
||||
inputting(!input_attempt)
|
||||
update_icon()
|
||||
. = TRUE
|
||||
if("tryoutput")
|
||||
outputting(!output_attempt)
|
||||
update_icon()
|
||||
. = TRUE
|
||||
if("input")
|
||||
var/target = params["target"]
|
||||
var/adjust = text2num(params["adjust"])
|
||||
if(target == "min")
|
||||
target = 0
|
||||
. = TRUE
|
||||
else if(target == "max")
|
||||
target = input_level_max
|
||||
. = TRUE
|
||||
else if(adjust)
|
||||
target = input_level + adjust
|
||||
. = TRUE
|
||||
else if(text2num(target) != null)
|
||||
target = text2num(target)
|
||||
. = TRUE
|
||||
if(.)
|
||||
input_level = clamp(target, 0, input_level_max)
|
||||
if("output")
|
||||
var/target = params["target"]
|
||||
var/adjust = text2num(params["adjust"])
|
||||
if(target == "min")
|
||||
target = 0
|
||||
. = TRUE
|
||||
else if(target == "max")
|
||||
target = output_level_max
|
||||
. = TRUE
|
||||
else if(adjust)
|
||||
target = output_level + adjust
|
||||
. = TRUE
|
||||
else if(text2num(target) != null)
|
||||
target = text2num(target)
|
||||
. = TRUE
|
||||
if(.)
|
||||
output_level = clamp(target, 0, output_level_max)
|
||||
|
||||
/obj/machinery/power/smes/proc/inputting(var/do_input)
|
||||
input_attempt = do_input
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
/obj/machinery/power/smes/buildable/Destroy()
|
||||
qdel(wires)
|
||||
wires = null
|
||||
for(var/datum/nano_module/rcon/R in world)
|
||||
for(var/datum/tgui_module/rcon/R in world)
|
||||
R.FindDevices()
|
||||
return ..()
|
||||
|
||||
|
||||
+60
-71
@@ -399,38 +399,32 @@ GLOBAL_LIST_EMPTY(solars_list)
|
||||
return
|
||||
|
||||
/obj/machinery/power/solar_control/attack_hand(mob/user)
|
||||
if(!..())
|
||||
interact(user)
|
||||
if(..())
|
||||
return TRUE
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/solar_control/interact(mob/user)
|
||||
/obj/machinery/power/solar_control/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "SolarControl", name)
|
||||
ui.open()
|
||||
|
||||
var/t = "<B><span class='highlight'>Generated power</span></B> : [round(lastgen)] W<BR>"
|
||||
t += "<B><span class='highlight'>Star Orientation</span></B>: [SSsun.sun.angle]° ([angle2text(SSsun.sun.angle)])<BR>"
|
||||
t += "<B><span class='highlight'>Array Orientation</span></B>: [rate_control(src,"cdir","[cdir]°",1,15)] ([angle2text(cdir)])<BR>"
|
||||
t += "<B><span class='highlight'>Tracking:</span></B><div class='statusDisplay'>"
|
||||
switch(track)
|
||||
if(0)
|
||||
t += "<span class='linkOn'>Off</span> <A href='?src=\ref[src];track=1'>Timed</A> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
|
||||
if(1)
|
||||
t += "<A href='?src=\ref[src];track=0'>Off</A> <span class='linkOn'>Timed</span> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
|
||||
if(2)
|
||||
t += "<A href='?src=\ref[src];track=0'>Off</A> <A href='?src=\ref[src];track=1'>Timed</A> <span class='linkOn'>Auto</span><BR>"
|
||||
/obj/machinery/power/solar_control/tgui_data()
|
||||
var/data = list()
|
||||
|
||||
t += "Tracking Rate: [rate_control(src,"tdir","[trackrate] deg/h ([trackrate<0 ? "CCW" : "CW"])",1,30,180)]</div><BR>"
|
||||
data["generated"] = round(lastgen)
|
||||
data["generated_ratio"] = data["generated"] / round(max(connected_panels.len, 1) * GLOB.solar_gen_rate)
|
||||
|
||||
t += "<B><span class='highlight'>Connected devices:</span></B><div class='statusDisplay'>"
|
||||
data["sun_angle"] = SSsun.sun.angle
|
||||
data["array_angle"] = cdir
|
||||
data["rotation_rate"] = trackrate
|
||||
data["max_rotation_rate"] = 7200
|
||||
data["tracking_state"] = track
|
||||
|
||||
t += "<A href='?src=\ref[src];search_connected=1'>Search for devices</A><BR>"
|
||||
t += "Solar panels : [connected_panels.len] connected<BR>"
|
||||
t += "Solar tracker : [connected_tracker ? "<span class='good'>Found</span>" : "<span class='bad'>Not found</span>"]</div><BR>"
|
||||
data["connected_panels"] = connected_panels.len
|
||||
data["connected_tracker"] = (connected_tracker ? TRUE : FALSE)
|
||||
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
var/datum/browser/popup = new(user, "solar", name)
|
||||
popup.set_content(t)
|
||||
popup.open()
|
||||
|
||||
return
|
||||
return data
|
||||
|
||||
/obj/machinery/power/solar_control/attackby(obj/item/I, user as mob)
|
||||
if(I.is_screwdriver())
|
||||
@@ -481,51 +475,52 @@ GLOBAL_LIST_EMPTY(solars_list)
|
||||
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/power/solar_control/Topic(href, href_list)
|
||||
/obj/machinery/power/solar_control/tgui_act(action, params)
|
||||
if(..())
|
||||
usr << browse(null, "window=solcon")
|
||||
usr.unset_machine()
|
||||
return 0
|
||||
if(href_list["close"] )
|
||||
usr << browse(null, "window=solcon")
|
||||
usr.unset_machine()
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
if(href_list["rate control"])
|
||||
if(href_list["cdir"])
|
||||
src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360)
|
||||
src.targetdir = src.cdir
|
||||
if(track == 2) //manual update, so losing auto-tracking
|
||||
track = 0
|
||||
spawn(1)
|
||||
switch(action)
|
||||
if("azimuth")
|
||||
var/adjust = text2num(params["adjust"])
|
||||
var/value = text2num(params["value"])
|
||||
if(adjust)
|
||||
value = cdir + adjust
|
||||
if(value != null)
|
||||
cdir = value
|
||||
set_panels(cdir)
|
||||
if(href_list["tdir"])
|
||||
src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"]))
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if("azimuth_rate")
|
||||
var/adjust = text2num(params["adjust"])
|
||||
var/value = text2num(params["value"])
|
||||
if(adjust)
|
||||
value = trackrate + adjust
|
||||
if(value != null)
|
||||
trackrate = round(clamp(value, -7200, 7200), 0.01)
|
||||
if(trackrate)
|
||||
nexttime = world.time + 36000 / abs(trackrate)
|
||||
return TRUE
|
||||
return TRUE
|
||||
if("tracking")
|
||||
var/mode = text2num(params["mode"])
|
||||
track = mode
|
||||
if(track == 2)
|
||||
if(connected_tracker)
|
||||
connected_tracker.set_angle(SSsun.sun.angle)
|
||||
set_panels(cdir)
|
||||
else if(track == 1) //begin manual tracking
|
||||
targetdir = cdir
|
||||
if(trackrate)
|
||||
nexttime = world.time + 36000/abs(trackrate)
|
||||
set_panels(targetdir)
|
||||
return TRUE
|
||||
|
||||
if(href_list["track"])
|
||||
track = text2num(href_list["track"])
|
||||
if(track == 2)
|
||||
if(connected_tracker)
|
||||
connected_tracker.set_angle(SSsun.sun.angle)
|
||||
set_panels(cdir)
|
||||
else if (track == 1) //begin manual tracking
|
||||
src.targetdir = src.cdir
|
||||
if(src.trackrate) nexttime = world.time + 36000/abs(trackrate)
|
||||
set_panels(targetdir)
|
||||
|
||||
if(href_list["search_connected"])
|
||||
src.search_for_connected()
|
||||
if(connected_tracker && track == 2)
|
||||
connected_tracker.set_angle(SSsun.sun.angle)
|
||||
src.set_panels(cdir)
|
||||
|
||||
interact(usr)
|
||||
return 1
|
||||
if("refresh")
|
||||
search_for_connected()
|
||||
return TRUE
|
||||
|
||||
//rotates the panel to the passed angle
|
||||
/obj/machinery/power/solar_control/proc/set_panels(var/cdir)
|
||||
|
||||
for(var/obj/machinery/power/solar/S in connected_panels)
|
||||
S.adir = cdir //instantly rotates the panel
|
||||
S.occlusion()//and
|
||||
@@ -547,7 +542,7 @@ GLOBAL_LIST_EMPTY(solars_list)
|
||||
/obj/machinery/power/solar_control/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
//SN src = null
|
||||
//SN = null
|
||||
qdel(src)
|
||||
return
|
||||
if(2.0)
|
||||
@@ -565,9 +560,3 @@ GLOBAL_LIST_EMPTY(solars_list)
|
||||
/obj/item/weapon/paper/solar
|
||||
name = "paper- 'Going green! Setup your own solar array instructions.'"
|
||||
info = "<h1>Welcome</h1><p>At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or phoron! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.</p><p>You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!</p><p>Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the SSsun.sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the SSsun.sun's movements and to send commands to the solar panels to change direction with the SSsun.sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.</p><p>Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.</p><p>That's all to it, be safe, be green!</p>"
|
||||
|
||||
/proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null) //How not to name vars
|
||||
var/href = "<A href='?src=\ref[S];rate control=1;[V]"
|
||||
var/rate = "[href]=-[Max]'>-</A>[href]=-[Min]'>-</A> [(C?C : 0)] [href]=[Min]'>+</A>[href]=[Max]'>+</A>"
|
||||
if(Limit) return "[href]=-[Limit]'>-</A>"+rate+"[href]=[Limit]'>+</A>"
|
||||
return rate
|
||||
|
||||
@@ -390,11 +390,11 @@
|
||||
if(Adjacent(user))
|
||||
return attack_hand(user)
|
||||
else
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
return
|
||||
|
||||
/obj/machinery/power/supermatter/attack_ai(mob/user as mob)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/supermatter/attack_hand(mob/user as mob)
|
||||
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
|
||||
@@ -404,9 +404,15 @@
|
||||
|
||||
Consume(user)
|
||||
|
||||
/obj/machinery/power/supermatter/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AiSupermatter", name)
|
||||
ui.open()
|
||||
|
||||
// This is purely informational UI that may be accessed by AIs or robots
|
||||
/obj/machinery/power/supermatter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
/obj/machinery/power/supermatter/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["integrity_percentage"] = round(get_integrity())
|
||||
var/datum/gas_mixture/env = null
|
||||
@@ -421,12 +427,7 @@
|
||||
data["ambient_pressure"] = round(env.return_pressure())
|
||||
data["detonating"] = grav_pulling
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "supermatter_crystal.tmpl", "Supermatter Crystal", 500, 300)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once
|
||||
#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill
|
||||
#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch
|
||||
#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume)
|
||||
#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever
|
||||
|
||||
|
||||
@@ -245,7 +246,18 @@
|
||||
if("create_bottle")
|
||||
if(condi || !reagents.total_volume)
|
||||
return
|
||||
tgui_modal_input(src, id, "Please name your bottle:", null, arguments, reagents.get_master_reagent_name(), MAX_CUSTOM_NAME_LEN)
|
||||
var/num = round(text2num(arguments["num"] || 1))
|
||||
if(!num)
|
||||
return
|
||||
arguments["num"] = num
|
||||
var/amount_per_bottle = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_BOTTLE)
|
||||
var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_bottle]u)"
|
||||
var/bottles_text = num == 1 ? "new bottle" : "[num] new bottles"
|
||||
tgui_modal_input(src, id, "Please name your [bottles_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN)
|
||||
if("create_bottle_multiple")
|
||||
if(condi || !reagents.total_volume)
|
||||
return
|
||||
tgui_modal_input(src, id, "Please enter the amount of bottles to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5)
|
||||
if("change_bottle_style")
|
||||
var/list/choices = list()
|
||||
for(var/i = 1 to MAX_BOTTLE_SPRITE)
|
||||
@@ -357,16 +369,28 @@
|
||||
if("create_bottle")
|
||||
if(condi || !reagents.total_volume)
|
||||
return
|
||||
var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT)
|
||||
if(!count)
|
||||
return
|
||||
|
||||
if(!length(answer))
|
||||
answer = reagents.get_master_reagent_name()
|
||||
var/obj/item/weapon/reagent_containers/glass/bottle/P = new(loc)
|
||||
P.name = "[answer] bottle"
|
||||
P.pixel_x = rand(-7, 7) // random position
|
||||
P.pixel_y = rand(-7, 7)
|
||||
P.icon_state = "bottle-[bottlesprite]" || "bottle-1"
|
||||
reagents.trans_to_obj(P, 60)
|
||||
P.update_icon()
|
||||
var/amount_per_bottle = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_BOTTLE)
|
||||
while(count--)
|
||||
if(reagents.total_volume <= 0)
|
||||
to_chat(usr, "<span class='notice'>Not enough reagents to create these bottles!</span>")
|
||||
return
|
||||
var/obj/item/weapon/reagent_containers/glass/bottle/P = new(loc)
|
||||
P.name = "[answer] bottle"
|
||||
P.pixel_x = rand(-7, 7) // random position
|
||||
P.pixel_y = rand(-7, 7)
|
||||
P.icon_state = "bottle-[bottlesprite]" || "bottle-1"
|
||||
reagents.trans_to_obj(P, amount_per_bottle)
|
||||
P.update_icon()
|
||||
if("create_bottle_multiple")
|
||||
if(condi || !reagents.total_volume)
|
||||
return
|
||||
tgui_act("modal_open", list("id" = "create_bottle", "arguments" = list("num" = answer)), ui, state)
|
||||
if("change_bottle_style")
|
||||
var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE)
|
||||
if(!new_style)
|
||||
@@ -393,7 +417,9 @@
|
||||
mode = !mode
|
||||
if("ejectp")
|
||||
if(loaded_pill_bottle)
|
||||
loaded_pill_bottle.forceMove(loc)
|
||||
loaded_pill_bottle.forceMove(get_turf(src))
|
||||
if(Adjacent(usr) && !issilicon(usr))
|
||||
usr.put_in_hands(loaded_pill_bottle)
|
||||
loaded_pill_bottle = null
|
||||
if("print")
|
||||
if(printing || condi)
|
||||
@@ -842,4 +868,5 @@
|
||||
#undef MAX_MULTI_AMOUNT
|
||||
#undef MAX_UNITS_PER_PILL
|
||||
#undef MAX_UNITS_PER_PATCH
|
||||
#undef MAX_UNITS_PER_BOTTLE
|
||||
#undef MAX_CUSTOM_NAME_LEN
|
||||
|
||||
@@ -400,6 +400,49 @@
|
||||
M.heal_organ_damage(30 * removed, 30 * removed * chem_effective)
|
||||
M.adjustToxLoss(-30 * removed * chem_effective)
|
||||
|
||||
/datum/reagent/mortiferin
|
||||
name = "Mortiferin"
|
||||
id = "mortiferin"
|
||||
description = "A liquid compound based upon those used in cloning. Utilized in cases of toxic shock. May cause liver damage."
|
||||
taste_description = "meat"
|
||||
reagent_state = LIQUID
|
||||
color = "#6b4de3"
|
||||
metabolism = REM * 0.5
|
||||
mrate_static = TRUE
|
||||
scannable = 1
|
||||
|
||||
/datum/reagent/mortiferin/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location)
|
||||
if(M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse))
|
||||
affects_dead = TRUE
|
||||
else
|
||||
affects_dead = FALSE
|
||||
|
||||
. = ..(M, alien, location)
|
||||
|
||||
/datum/reagent/mortiferin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
if(M.bodytemperature < (T0C - 10) || (M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse)))
|
||||
var/chem_effective = 1 * M.species.chem_strength_heal
|
||||
if(alien == IS_SLIME)
|
||||
if(prob(10))
|
||||
to_chat(M, "<span class='danger'>It's so cold. Something causes your cellular mass to solidify sporadically, resulting in uncontrollable twitching.</span>")
|
||||
chem_effective = 0.5
|
||||
M.Weaken(10)
|
||||
M.silent = max(M.silent, 10)
|
||||
M.make_jittery(4)
|
||||
if(M.stat != DEAD)
|
||||
M.adjustCloneLoss(-5 * removed * chem_effective)
|
||||
M.adjustOxyLoss(-10 * removed * chem_effective)
|
||||
M.adjustToxLoss(-20 * removed * chem_effective)
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/internal/liver/L = H.internal_organs_by_name[O_LIVER]
|
||||
if(istype(L) && prob(5))
|
||||
if(L.robotic >= ORGAN_ROBOT)
|
||||
return
|
||||
|
||||
L.take_damage(rand(1,3) * removed)
|
||||
|
||||
/datum/reagent/necroxadone
|
||||
name = "Necroxadone"
|
||||
id = "necroxadone"
|
||||
@@ -410,18 +453,11 @@
|
||||
metabolism = REM * 0.5
|
||||
mrate_static = TRUE
|
||||
scannable = 1
|
||||
|
||||
/datum/reagent/necroxadone/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location)
|
||||
if(M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse))
|
||||
affects_dead = TRUE
|
||||
else
|
||||
affects_dead = FALSE
|
||||
|
||||
. = ..(M, alien, location)
|
||||
affects_dead = TRUE
|
||||
|
||||
/datum/reagent/necroxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
var/chem_effective = 1 * M.species.chem_strength_heal
|
||||
if(M.bodytemperature < 170 || (M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse)))
|
||||
var/chem_effective = 1 * M.species.chem_strength_heal
|
||||
if(alien == IS_SLIME)
|
||||
if(prob(10))
|
||||
to_chat(M, "<span class='danger'>It's so cold. Something causes your cellular mass to harden sporadically, resulting in seizure-like twitching.</span>")
|
||||
@@ -433,6 +469,12 @@
|
||||
M.adjustCloneLoss(-5 * removed * chem_effective)
|
||||
M.adjustOxyLoss(-20 * removed * chem_effective)
|
||||
M.adjustToxLoss(-40 * removed * chem_effective)
|
||||
M.adjustCloneLoss(-15 * removed * chem_effective)
|
||||
|
||||
else
|
||||
M.adjustToxLoss(-25 * removed * chem_effective)
|
||||
M.adjustOxyLoss(-10 * removed * chem_effective)
|
||||
M.adjustCloneLoss(-7 * removed * chem_effective)
|
||||
|
||||
/* Painkillers */
|
||||
|
||||
|
||||
@@ -428,6 +428,14 @@
|
||||
catalysts = list("phoron" = 5)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/mortiferin
|
||||
name = "Mortiferin"
|
||||
id = "mortiferin"
|
||||
result = "mortiferin"
|
||||
required_reagents = list("cryptobiolin" = 1, "clonexadone" = 1, "corophizine" = 1)
|
||||
result_amount = 2
|
||||
catalysts = list("phoron" = 5)
|
||||
|
||||
/datum/chemical_reaction/spaceacillin
|
||||
name = "Spaceacillin"
|
||||
id = "spaceacillin"
|
||||
|
||||
@@ -569,9 +569,9 @@
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 7500, "gold" = 750, "silver" = 1500, "glass" = 3750)
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/repair_droid
|
||||
|
||||
/datum/design/item/mecha/shield_drone
|
||||
name = "Shield Drone"
|
||||
desc = "Manual shield drone. Deploys a large, familiar, and rectangular shield in one direction at a time."
|
||||
/datum/design/item/mecha/combat_shield
|
||||
name = "linear combat shield"
|
||||
desc = "Linear shield projector. Deploys a large, familiar, and rectangular shield in one direction at a time."
|
||||
id = "mech_shield_droid"
|
||||
req_tech = list(TECH_PHORON = 3, TECH_MAGNET = 6, TECH_ILLEGAL = 4)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 8000, "gold" = 2000, "silver" = 3000, "phoron" = 5000, "glass" = 3750)
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
// Little define makes it cleaner to read the tripple color values out of mobs.
|
||||
#define MOB_HEX_COLOR(M, V) "#[num2hex(M.r_##V, 2)][num2hex(M.g_##V, 2)][num2hex(M.b_##V, 2)]"
|
||||
|
||||
#define MENU_MAIN "Main"
|
||||
#define MENU_BODYRECORDS "Body Records"
|
||||
#define MENU_STOCKRECORDS "Stock Records"
|
||||
#define MENU_SPECIFICRECORD "Specific Record"
|
||||
#define MENU_OOCNOTES "OOC Notes"
|
||||
|
||||
/obj/machinery/computer/transhuman/designer
|
||||
name = "body design console"
|
||||
catalogue_data = list(/datum/category_item/catalogue/information/organization/khi,
|
||||
@@ -12,16 +18,41 @@
|
||||
circuit = /obj/item/weapon/circuitboard/body_designer
|
||||
req_access = list(access_medical) // Used for loading people's designs
|
||||
var/temp = ""
|
||||
var/menu = 1 //Which menu screen to display
|
||||
var/menu = MENU_MAIN //Which menu screen to display
|
||||
var/datum/transhuman/body_record/active_br = null
|
||||
var/icon/preview_icon = null
|
||||
//Mob preview
|
||||
var/map_name
|
||||
var/obj/screen/south_preview = null
|
||||
var/obj/screen/east_preview = null
|
||||
var/obj/screen/west_preview = null
|
||||
// Mannequins are somewhat expensive to create, so cache it
|
||||
var/mob/living/carbon/human/dummy/mannequin/mannequin = null
|
||||
var/obj/item/weapon/disk/body_record/disk = null
|
||||
|
||||
/obj/machinery/computer/transhuman/designer/Initialize()
|
||||
. = ..()
|
||||
map_name = "transhuman_designer_[REF(src)]_map"
|
||||
|
||||
south_preview = new
|
||||
south_preview.name = ""
|
||||
south_preview.assigned_map = map_name
|
||||
south_preview.del_on_map_removal = FALSE
|
||||
south_preview.screen_loc = "[map_name]:1,1"
|
||||
|
||||
east_preview = new
|
||||
east_preview.name = ""
|
||||
east_preview.assigned_map = map_name
|
||||
east_preview.del_on_map_removal = FALSE
|
||||
east_preview.screen_loc = "[map_name]:2,1"
|
||||
|
||||
west_preview = new
|
||||
west_preview.name = ""
|
||||
west_preview.assigned_map = map_name
|
||||
west_preview.del_on_map_removal = FALSE
|
||||
west_preview.screen_loc = "[map_name]:0,1"
|
||||
|
||||
/obj/machinery/computer/transhuman/designer/Destroy()
|
||||
active_br = null
|
||||
preview_icon = null
|
||||
mannequin = null
|
||||
disk = null
|
||||
return ..()
|
||||
@@ -50,15 +81,24 @@
|
||||
add_fingerprint(user)
|
||||
if(inoperable())
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/transhuman/designer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
// log_debug("designer.ui_interact([user], force_open = [force_open])")
|
||||
user.set_machine(src)
|
||||
/obj/machinery/computer/transhuman/designer/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
give_client_previews(user.client)
|
||||
ui = new(user, src, "BodyDesigner", name)
|
||||
ui.open()
|
||||
|
||||
var/data[0]
|
||||
/obj/machinery/computer/transhuman/designer/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
data["mapRef"] = map_name
|
||||
return data
|
||||
|
||||
if(menu == "2")
|
||||
/obj/machinery/computer/transhuman/designer/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
if(menu == MENU_BODYRECORDS)
|
||||
var/bodyrecords_list_ui[0]
|
||||
for(var/N in SStranscore.body_scans)
|
||||
var/datum/transhuman/body_record/BR = SStranscore.body_scans[N]
|
||||
@@ -66,7 +106,7 @@
|
||||
if(bodyrecords_list_ui.len)
|
||||
data["bodyrecords"] = bodyrecords_list_ui
|
||||
|
||||
if(menu == "3")
|
||||
if(menu == MENU_STOCKRECORDS)
|
||||
var/stock_bodyrecords_list_ui[0]
|
||||
for (var/N in GLOB.all_species)
|
||||
var/datum/species/S = GLOB.all_species[N]
|
||||
@@ -86,11 +126,6 @@
|
||||
"booc" = active_br.body_oocnotes,
|
||||
"styles" = list()
|
||||
)
|
||||
if(!preview_icon)
|
||||
update_preview_icon()
|
||||
force_open = 1 // Force a refresh to send the new image
|
||||
data["previewIconUrl"] = "body_preview_icon.png"
|
||||
user << browse_rsc(preview_icon, "body_preview_icon.png")
|
||||
|
||||
var/list/styles = data["activeBodyRecord"]["styles"]
|
||||
var/list/temp
|
||||
@@ -98,6 +133,12 @@
|
||||
temp = list("styleHref" = "ear_style", "style" = "Normal")
|
||||
if(mannequin.ear_style)
|
||||
temp["style"] = mannequin.ear_style.name
|
||||
if(mannequin.ear_style.do_colouration)
|
||||
temp["color"] = MOB_HEX_COLOR(mannequin, ears)
|
||||
temp["colorHref"] = "ear_color"
|
||||
if(mannequin.ear_style.extra_overlay)
|
||||
temp["color2"] = MOB_HEX_COLOR(mannequin, ears2)
|
||||
temp["colorHref2"] = "ear_color2"
|
||||
styles["Ears"] = temp
|
||||
|
||||
temp = list("styleHref" = "tail_style", "style" = "Normal")
|
||||
@@ -106,6 +147,9 @@
|
||||
if(mannequin.tail_style.do_colouration)
|
||||
temp["color"] = MOB_HEX_COLOR(mannequin, tail)
|
||||
temp["colorHref"] = "tail_color"
|
||||
if(mannequin.tail_style.extra_overlay)
|
||||
temp["color2"] = MOB_HEX_COLOR(mannequin, tail2)
|
||||
temp["colorHref2"] = "tail_color2"
|
||||
styles["Tail"] = temp
|
||||
|
||||
temp = list("styleHref" = "wing_style", "style" = "Normal")
|
||||
@@ -114,6 +158,9 @@
|
||||
if(mannequin.wing_style.do_colouration)
|
||||
temp["color"] = MOB_HEX_COLOR(mannequin, wing)
|
||||
temp["colorHref"] = "wing_color"
|
||||
if(mannequin.wing_style.extra_overlay)
|
||||
temp["color2"] = MOB_HEX_COLOR(mannequin, wing2)
|
||||
temp["colorHref2"] = "wing_color2"
|
||||
styles["Wing"] = temp
|
||||
|
||||
temp = list("styleHref" = "hair_style", "style" = mannequin.h_style)
|
||||
@@ -143,74 +190,74 @@
|
||||
data["disk"] = disk ? 1 : 0
|
||||
data["diskStored"] = disk && disk.stored ? 1 : 0
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "body_designer.tmpl", "Body Design Console", 400, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/transhuman/designer/Topic(href, href_list)
|
||||
/obj/machinery/computer/transhuman/designer/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
else if(href_list["debug_load_my_body"])
|
||||
active_br = new /datum/transhuman/body_record(usr, FALSE, FALSE)
|
||||
preview_icon = null
|
||||
switch(action)
|
||||
if("debug_load_my_body")
|
||||
active_br = new /datum/transhuman/body_record(usr, FALSE, FALSE)
|
||||
update_preview_icon()
|
||||
menu = MENU_SPECIFICRECORD
|
||||
|
||||
else if (href_list["view_brec"])
|
||||
var/datum/transhuman/body_record/BR = locate(href_list["view_brec"])
|
||||
if(BR && istype(BR.mydna))
|
||||
if(allowed(usr) || BR.ckey == usr.ckey)
|
||||
active_br = new /datum/transhuman/body_record(BR) // Load a COPY!
|
||||
preview_icon = null
|
||||
menu = 4
|
||||
if("view_brec")
|
||||
var/datum/transhuman/body_record/BR = locate(params["view_brec"])
|
||||
if(BR && istype(BR.mydna))
|
||||
if(allowed(usr) || BR.ckey == usr.ckey)
|
||||
active_br = new /datum/transhuman/body_record(BR) // Load a COPY!
|
||||
update_preview_icon()
|
||||
menu = MENU_SPECIFICRECORD
|
||||
else
|
||||
active_br = null
|
||||
temp = "Access denied: Body records are confidential."
|
||||
else
|
||||
active_br = null
|
||||
temp = "Access denied: Body records are confidential."
|
||||
else
|
||||
active_br = null
|
||||
temp = "ERROR: Record missing."
|
||||
temp = "ERROR: Record missing."
|
||||
|
||||
else if(href_list["view_stock_brec"])
|
||||
var/datum/species/S = GLOB.all_species[href_list["view_stock_brec"]]
|
||||
if(S && (S.spawn_flags & (SPECIES_IS_WHITELISTED|SPECIES_CAN_JOIN)) == SPECIES_CAN_JOIN)
|
||||
// Generate body record from species!
|
||||
mannequin = new(null, S.name)
|
||||
mannequin.real_name = "Stock [S.name] Body"
|
||||
mannequin.name = mannequin.real_name
|
||||
mannequin.dna.real_name = mannequin.real_name
|
||||
active_br = new(mannequin, FALSE, FALSE)
|
||||
active_br.speciesname = "Custom Sleeve"
|
||||
preview_icon = null
|
||||
menu = 4
|
||||
else
|
||||
active_br = null
|
||||
temp = "ERROR: Stock Record missing."
|
||||
if("view_stock_brec")
|
||||
var/datum/species/S = GLOB.all_species[params["view_stock_brec"]]
|
||||
if(S && (S.spawn_flags & (SPECIES_IS_WHITELISTED|SPECIES_CAN_JOIN)) == SPECIES_CAN_JOIN)
|
||||
// Generate body record from species!
|
||||
mannequin = new(null, S.name)
|
||||
mannequin.real_name = "Stock [S.name] Body"
|
||||
mannequin.name = mannequin.real_name
|
||||
mannequin.dna.real_name = mannequin.real_name
|
||||
active_br = new(mannequin, FALSE, FALSE)
|
||||
active_br.speciesname = "Custom Sleeve"
|
||||
update_preview_icon()
|
||||
menu = MENU_SPECIFICRECORD
|
||||
else
|
||||
active_br = null
|
||||
temp = "ERROR: Stock Record missing."
|
||||
|
||||
else if (href_list["boocnotes"])
|
||||
menu = 6
|
||||
if("boocnotes")
|
||||
menu = MENU_OOCNOTES
|
||||
|
||||
else if (href_list["loadfromdisk"])
|
||||
if(disk && disk.stored)
|
||||
active_br = new /datum/transhuman/body_record(disk.stored) // Loads a COPY!
|
||||
preview_icon = null
|
||||
if("loadfromdisk")
|
||||
if(disk && disk.stored)
|
||||
active_br = new /datum/transhuman/body_record(disk.stored) // Loads a COPY!
|
||||
update_preview_icon()
|
||||
menu = MENU_SPECIFICRECORD
|
||||
|
||||
else if (href_list["savetodisk"])
|
||||
if(disk && active_br)
|
||||
disk.stored = new /datum/transhuman/body_record(active_br) // Saves a COPY!
|
||||
disk.name = "[initial(disk.name)] ([active_br.mydna.name])"
|
||||
if("savetodisk")
|
||||
if(disk && active_br)
|
||||
disk.stored = new /datum/transhuman/body_record(active_br) // Saves a COPY!
|
||||
disk.name = "[initial(disk.name)] ([active_br.mydna.name])"
|
||||
disk.forceMove(get_turf(src))
|
||||
disk = null
|
||||
|
||||
if("ejectdisk")
|
||||
disk.forceMove(get_turf(src))
|
||||
disk = null
|
||||
|
||||
else if (href_list["ejectdisk"])
|
||||
disk.forceMove(get_turf(src))
|
||||
disk = null
|
||||
|
||||
else if (href_list["menu"])
|
||||
menu = href_list["menu"]
|
||||
temp = ""
|
||||
else
|
||||
OnTopic(href, href_list, usr)
|
||||
if("menu")
|
||||
menu = params["menu"]
|
||||
temp = ""
|
||||
|
||||
if("href_conversion")
|
||||
PrefHrefMiddleware(params, usr)
|
||||
|
||||
add_fingerprint(usr)
|
||||
return 1 // Return 1 to refresh UI
|
||||
@@ -226,24 +273,27 @@
|
||||
|
||||
mannequin.delete_inventory(TRUE)
|
||||
update_preview_mob(mannequin)
|
||||
COMPILE_OVERLAYS(mannequin)
|
||||
|
||||
var/mutable_appearance/MA = new(mannequin)
|
||||
south_preview.appearance = MA
|
||||
south_preview.dir = SOUTH
|
||||
south_preview.screen_loc = "[map_name]:1,1"
|
||||
south_preview.name = ""
|
||||
east_preview.appearance = MA
|
||||
east_preview.dir = EAST
|
||||
east_preview.screen_loc = "[map_name]:2,1"
|
||||
east_preview.name = ""
|
||||
west_preview.appearance = MA
|
||||
west_preview.dir = WEST
|
||||
west_preview.screen_loc = "[map_name]:0,1"
|
||||
west_preview.name = ""
|
||||
|
||||
preview_icon = icon('icons/effects/effects.dmi', "nothing")
|
||||
preview_icon.Scale(48+32, 16+32)
|
||||
/obj/machinery/computer/transhuman/designer/proc/give_client_previews(client/C)
|
||||
C.register_map_obj(south_preview)
|
||||
C.register_map_obj(east_preview)
|
||||
C.register_map_obj(west_preview)
|
||||
|
||||
mannequin.dir = NORTH
|
||||
var/icon/stamp = getFlatIcon(mannequin)
|
||||
preview_icon.Blend(stamp, ICON_OVERLAY, 25, 17)
|
||||
|
||||
mannequin.dir = WEST
|
||||
stamp = getFlatIcon(mannequin)
|
||||
preview_icon.Blend(stamp, ICON_OVERLAY, 1, 9)
|
||||
|
||||
mannequin.dir = SOUTH
|
||||
stamp = getFlatIcon(mannequin)
|
||||
preview_icon.Blend(stamp, ICON_OVERLAY, 49, 1)
|
||||
|
||||
preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser.
|
||||
return preview_icon
|
||||
|
||||
/obj/machinery/computer/transhuman/designer/proc/update_preview_mob(var/mob/living/carbon/human/H)
|
||||
ASSERT(!QDELETED(H))
|
||||
@@ -306,15 +356,15 @@
|
||||
// Problem is, those procs save their data to /datum/preferences, not a body_record.
|
||||
// Luckily the procs to convert from body_record to /datum/preferences and back already exist.
|
||||
// Its ugly, but I think its still better than duplicating and maintaining all that code.
|
||||
/obj/machinery/computer/transhuman/designer/proc/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||
if(!mannequin || !preview_icon || !active_br)
|
||||
/obj/machinery/computer/transhuman/designer/proc/PrefHrefMiddleware(list/params, var/mob/user)
|
||||
if(!mannequin || !active_br)
|
||||
return
|
||||
|
||||
if(href_list["size_multiplier"])
|
||||
if(params["target_href"] == "size_multiplier")
|
||||
var/new_size = input(user, "Choose your character's size, ranging from 25% to 200%", "Character Preference") as num|null
|
||||
if(new_size && ISINRANGE(new_size,25,200))
|
||||
active_br.sizemult = (new_size/100)
|
||||
preview_icon = null
|
||||
update_preview_icon()
|
||||
return 1
|
||||
|
||||
// The black magic horror show begins
|
||||
@@ -338,26 +388,30 @@
|
||||
var/datum/category_item/player_setup_item/vore/ears/E = CG.items_by_name["Appearance"]
|
||||
ASSERT(istype(E))
|
||||
|
||||
if(href_list["bio_gender"])
|
||||
if(params["target_href"] == "bio_gender")
|
||||
var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", active_br.bodygender) as null|anything in G.get_genders()
|
||||
if(new_gender)
|
||||
active_br.bodygender = new_gender
|
||||
active_br.mydna.dna.SetUIState(DNA_UI_GENDER, new_gender!=MALE, 1)
|
||||
preview_icon = null
|
||||
update_preview_icon()
|
||||
return 1
|
||||
|
||||
var/href_list = list()
|
||||
href_list["src"] = "\ref[src]"
|
||||
href_list["[params["target_href"]]"] = params["target_value"]
|
||||
|
||||
var/action = 0
|
||||
action = B.OnTopic(href, href_list, user)
|
||||
action = B.OnTopic(list2params(href_list), href_list, user)
|
||||
if(action & TOPIC_UPDATE_PREVIEW && mannequin && active_br)
|
||||
B.copy_to_mob(mannequin)
|
||||
active_br.mydna.dna.ResetUIFrom(mannequin)
|
||||
preview_icon = null
|
||||
update_preview_icon()
|
||||
return 1
|
||||
action = E.OnTopic(href, href_list, user)
|
||||
action = E.OnTopic(list2params(href_list), href_list, user)
|
||||
if(action & TOPIC_UPDATE_PREVIEW && mannequin && active_br)
|
||||
E.copy_to_mob(mannequin)
|
||||
active_br.mydna.dna.ResetUIFrom(mannequin)
|
||||
preview_icon = null
|
||||
update_preview_icon()
|
||||
return 1
|
||||
|
||||
// Fake subtype of preferences we can use to steal code from player_setup
|
||||
|
||||
@@ -417,7 +417,7 @@ var/list/infomorph_emotions = list(
|
||||
desc = "Modify the settings on your integrated radio."
|
||||
|
||||
if(radio)
|
||||
radio.ui_interact(src,"main",null,1,conscious_state)
|
||||
radio.tgui_interact(src)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You don't have a radio!</span>")
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use_power = USE_POWER_OFF //doesn't use APC power
|
||||
var/charge_rate = 100000 //100 kW
|
||||
var/obj/machinery/shield_gen/owned_gen
|
||||
interact_offline = TRUE
|
||||
|
||||
/obj/machinery/shield_capacitor/advanced
|
||||
name = "advanced shield capacitor"
|
||||
@@ -67,36 +68,30 @@
|
||||
/obj/machinery/shield_capacitor/attack_hand(mob/user)
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/shield_capacitor/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=shield_capacitor")
|
||||
return
|
||||
var/t = "<B>Shield Capacitor Control Console</B><br><br>"
|
||||
if(locked)
|
||||
t += "<i>Swipe your ID card to begin.</i>"
|
||||
else
|
||||
t += "This capacitor is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
|
||||
t += "Capacitor Status: [time_since_fail > 2 ? "<font color=green>OK.</font>" : "<font color=red>Discharging!</font>"]<br>"
|
||||
t += "Stored Energy: [format_SI(stored_charge, "J")] ([100 * round(stored_charge/max_charge, 0.01)]%)<br>"
|
||||
t += "Charge Rate: \
|
||||
<a href='?src=\ref[src];charge_rate=-100000'>\[----\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=-10000'>\[---\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=-1000'>\[--\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=-100'>\[-\]</a>[format_SI(charge_rate, "W")]\
|
||||
<a href='?src=\ref[src];charge_rate=100'>\[+\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=1000'>\[++\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=10000'>\[+++\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=100000'>\[++++\]</a><br>"
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src]'>Refresh</A> "
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
/obj/machinery/shield_capacitor/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ShieldCapacitor", name)
|
||||
ui.open()
|
||||
|
||||
user << browse(t, "window=shield_capacitor;size=500x400")
|
||||
user.set_machine(src)
|
||||
/obj/machinery/shield_capacitor/tgui_status(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/shield_capacitor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["active"] = active
|
||||
data["time_since_fail"] = time_since_fail
|
||||
data["stored_charge"] = stored_charge
|
||||
data["max_charge"] = max_charge
|
||||
data["charge_rate"] = charge_rate
|
||||
data["max_charge_rate"] = max_charge_rate
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/shield_capacitor/process()
|
||||
if (!anchored)
|
||||
@@ -119,21 +114,20 @@
|
||||
time_since_fail = 0 //losing charge faster than we can draw from PN
|
||||
last_stored_charge = stored_charge
|
||||
|
||||
/obj/machinery/shield_capacitor/Topic(href, href_list[])
|
||||
..()
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=shield_capacitor")
|
||||
usr.unset_machine()
|
||||
return
|
||||
if( href_list["toggle"] )
|
||||
if(!active && !anchored)
|
||||
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
|
||||
return
|
||||
active = !active
|
||||
if( href_list["charge_rate"] )
|
||||
charge_rate = between(10000, charge_rate + text2num(href_list["charge_rate"]), max_charge_rate)
|
||||
/obj/machinery/shield_capacitor/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
updateDialog()
|
||||
switch(action)
|
||||
if("toggle")
|
||||
if(!active && !anchored)
|
||||
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
|
||||
return
|
||||
active = !active
|
||||
. = TRUE
|
||||
if("charge_rate")
|
||||
charge_rate = clamp(text2num(params["rate"]), 10000, max_charge_rate)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/shield_capacitor/power_change()
|
||||
if(stat & BROKEN)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
var/energy_conversion_rate = 0.0006 //how many renwicks per watt? Higher numbers equals more effiency.
|
||||
var/z_range = 0 // How far 'up and or down' to extend the shield to, in z-levels. Only works on MultiZ supported z-levels.
|
||||
use_power = USE_POWER_OFF //doesn't use APC power
|
||||
interact_offline = TRUE // don't check stat & NOPOWER|BROKEN for our UI. We check BROKEN ourselves.
|
||||
var/id //for button usage
|
||||
|
||||
/obj/machinery/shield_gen/advanced
|
||||
@@ -95,59 +96,50 @@
|
||||
/obj/machinery/shield_gen/attack_hand(mob/user)
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/shield_gen/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=shield_generator")
|
||||
return
|
||||
var/t = "<B>Shield Generator Control Console</B><BR><br>"
|
||||
if(locked)
|
||||
t += "<i>Swipe your ID card to begin.</i>"
|
||||
else
|
||||
t += "[capacitors.len ? "<font color=green>Charge capacitor(s) connected.</font>" : "<font color=red>Unable to locate charge capacitor!</font>"]<br>"
|
||||
var/i = 0
|
||||
for(var/obj/machinery/shield_capacitor/capacitor in capacitors)
|
||||
i++
|
||||
t += "Capacitor #[i]: [capacitor.active ? "<font color=green>Online.</font>" : "<font color=red>Offline.</font>"] \
|
||||
Charge: [round(capacitor.stored_charge/1000, 0.1)] kJ ([100 * round(capacitor.stored_charge/capacitor.max_charge, 0.01)]%) \
|
||||
Status: [capacitor.time_since_fail > 2 ? "<font color=green>OK.</font>" : "<font color=red>Discharging!</font>"]<br>"
|
||||
t += "This generator is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
|
||||
t += "Field Status: [time_since_fail > 2 ? "<font color=green>Stable</font>" : "<font color=red>Unstable</font>"]<br>"
|
||||
t += "Coverage Radius (restart required): \
|
||||
<a href='?src=\ref[src];change_radius=-50'>---</a> \
|
||||
<a href='?src=\ref[src];change_radius=-5'>--</a> \
|
||||
<a href='?src=\ref[src];change_radius=-1'>-</a> \
|
||||
[field_radius] m \
|
||||
<a href='?src=\ref[src];change_radius=1'>+</a> \
|
||||
<a href='?src=\ref[src];change_radius=5'>++</a> \
|
||||
<a href='?src=\ref[src];change_radius=50'>+++</a><br>"
|
||||
if(HasAbove(src.z) || HasBelow(src.z)) // Won't show up on maps lacking MultiZ support.
|
||||
t += "Vertical Shielding (restart required): \
|
||||
<a href='?src=\ref[src];z_range=-1'>-</a> \
|
||||
[z_range] Vertical Range \
|
||||
<a href='?src=\ref[src];z_range=1'>+</a><br>"
|
||||
t += "Overall Field Strength: [round(average_field_strength, 0.01)] Renwick ([target_field_strength ? round(100 * average_field_strength / target_field_strength, 0.1) : "NA"]%)<br>"
|
||||
t += "Upkeep Power: [format_SI(round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate), "W")]<br>"
|
||||
t += "Charge Rate: <a href='?src=\ref[src];strengthen_rate=-0.1'>--</a> \
|
||||
[strengthen_rate] Renwick/s \
|
||||
<a href='?src=\ref[src];strengthen_rate=0.1'>++</a><br>"
|
||||
t += "Shield Generation Power: [format_SI(round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate), "W")]<br>"
|
||||
t += "Maximum Field Strength: \
|
||||
<a href='?src=\ref[src];target_field_strength=-10'>\[min\]</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=-5'>--</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=-1'>-</a> \
|
||||
[target_field_strength] Renwick \
|
||||
<a href='?src=\ref[src];target_field_strength=1'>+</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=5'>++</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=10'>\[max\]</a><br>"
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src]'>Refresh</A> "
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
user << browse(t, "window=shield_generator;size=500x400")
|
||||
user.set_machine(src)
|
||||
/obj/machinery/shield_gen/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ShieldGenerator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/shield_gen/tgui_status(mob/user)
|
||||
if(stat & BROKEN)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/shield_gen/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["locked"] = locked
|
||||
data["lockedData"] = list()
|
||||
if(!locked)
|
||||
data["lockedData"]["capacitors"] = list()
|
||||
for(var/obj/machinery/shield_capacitor/C in capacitors)
|
||||
data["lockedData"]["capacitors"].Add(list(list(
|
||||
"active" = C.active,
|
||||
"stored_charge" = C.stored_charge,
|
||||
"max_charge" = C.max_charge,
|
||||
"failing" = (C.time_since_fail <= 2),
|
||||
)))
|
||||
|
||||
data["lockedData"]["active"] = active
|
||||
data["lockedData"]["failing"] = (time_since_fail <= 2)
|
||||
data["lockedData"]["radius"] = field_radius
|
||||
data["lockedData"]["max_radius"] = max_field_radius
|
||||
data["lockedData"]["z_range"] = z_range
|
||||
data["lockedData"]["max_z_range"] = 10
|
||||
data["lockedData"]["average_field_strength"] = average_field_strength
|
||||
data["lockedData"]["target_field_strength"] = target_field_strength
|
||||
data["lockedData"]["max_field_strength"] = max_field_strength
|
||||
data["lockedData"]["shields"] = LAZYLEN(field)
|
||||
data["lockedData"]["upkeep"] = round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate)
|
||||
data["lockedData"]["strengthen_rate"] = strengthen_rate
|
||||
data["lockedData"]["max_strengthen_rate"] = max_strengthen_rate
|
||||
data["lockedData"]["gen_power"] = round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/shield_gen/process()
|
||||
if (!anchored && active)
|
||||
@@ -206,30 +198,32 @@
|
||||
else
|
||||
average_field_strength = 0
|
||||
|
||||
/obj/machinery/shield_gen/Topic(href, href_list[])
|
||||
..()
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=shield_generator")
|
||||
usr.unset_machine()
|
||||
return
|
||||
else if( href_list["toggle"] )
|
||||
if (!active && !anchored)
|
||||
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
|
||||
return
|
||||
toggle()
|
||||
else if( href_list["change_radius"] )
|
||||
field_radius = between(0, field_radius + text2num(href_list["change_radius"]), max_field_radius)
|
||||
else if( href_list["strengthen_rate"] )
|
||||
strengthen_rate = between(0, strengthen_rate + text2num(href_list["strengthen_rate"]), max_strengthen_rate)
|
||||
else if( href_list["target_field_strength"] )
|
||||
target_field_strength = between(1, target_field_strength + text2num(href_list["target_field_strength"]), max_field_strength)
|
||||
else if( href_list["z_range"] )
|
||||
z_range = between(0, z_range + text2num(href_list["z_range"]), 10) // Max is extending ten z-levels up and down. Probably too big of a number but it shouldn't matter.
|
||||
/obj/machinery/shield_gen/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("toggle")
|
||||
if (!active && !anchored)
|
||||
to_chat(usr, "<font color='red'>The [src] needs to be firmly secured to the floor first.</font>")
|
||||
return
|
||||
toggle()
|
||||
. = TRUE
|
||||
if("change_radius")
|
||||
field_radius = clamp(text2num(params["val"]), 0, max_field_radius)
|
||||
. = TRUE
|
||||
if("strengthen_rate")
|
||||
strengthen_rate = clamp(text2num(params["val"]), 0, max_strengthen_rate)
|
||||
. = TRUE
|
||||
if("target_field_strength")
|
||||
target_field_strength = clamp(text2num(params["val"]), 1, max_field_strength)
|
||||
. = TRUE
|
||||
if("z_range")
|
||||
z_range = clamp(text2num(params["val"]), 0, 10)
|
||||
. = TRUE
|
||||
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/shield_gen/ex_act(var/severity)
|
||||
|
||||
if(active)
|
||||
toggle()
|
||||
return ..()
|
||||
|
||||
@@ -46,73 +46,58 @@
|
||||
name = "escape pod controller"
|
||||
program = /datum/computer/file/embedded_program/docking/simple
|
||||
var/datum/shuttle/autodock/ferry/escape_pod/pod
|
||||
valid_actions = list("toggle_override", "force_door")
|
||||
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/tgui_data(mob/user)
|
||||
var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type
|
||||
|
||||
data = list(
|
||||
. = list(
|
||||
"docking_status" = docking_program.get_docking_status(),
|
||||
"override_enabled" = docking_program.override_enabled,
|
||||
"door_state" = docking_program.memory["door_status"]["state"],
|
||||
"door_lock" = docking_program.memory["door_status"]["lock"],
|
||||
"exterior_status" = docking_program.memory["door_status"],
|
||||
"can_force" = pod.can_force() || (emergency_shuttle.departed && pod.can_launch()), //allow players to manually launch ahead of time if the shuttle leaves
|
||||
"is_armed" = pod.arming_controller.armed,
|
||||
"armed" = pod.arming_controller.armed,
|
||||
"internalTemplateName" = "EscapePodConsole",
|
||||
)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "escape_pod_console.tmpl", name, 470, 290)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/Topic(href, href_list)
|
||||
if((. = ..()))
|
||||
return
|
||||
|
||||
if("manual_arm")
|
||||
pod.arming_controller.arm()
|
||||
return TOPIC_REFRESH
|
||||
if("force_launch")
|
||||
if (pod.can_force())
|
||||
pod.force_launch(src)
|
||||
else if (emergency_shuttle.departed && pod.can_launch()) //allow players to manually launch ahead of time if the shuttle leaves
|
||||
pod.launch(src)
|
||||
return TOPIC_REFRESH
|
||||
return 0
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("manual_arm")
|
||||
pod.arming_controller.arm()
|
||||
. = TRUE
|
||||
if("force_launch")
|
||||
if(pod.can_force())
|
||||
pod.force_launch(src)
|
||||
else if(emergency_shuttle.departed && pod.can_launch()) //allow players to manually launch ahead of time if the shuttle leaves
|
||||
pod.launch(src)
|
||||
. = TRUE
|
||||
|
||||
|
||||
//This controller is for the escape pod berth (station side)
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth
|
||||
name = "escape pod berth controller"
|
||||
program = /datum/computer/file/embedded_program/docking/simple/escape_pod_berth
|
||||
valid_actions = list("toggle_override", "force_door")
|
||||
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/tgui_data(mob/user)
|
||||
var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type
|
||||
|
||||
var/armed = null
|
||||
if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod_berth))
|
||||
if(istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod_berth))
|
||||
var/datum/computer/file/embedded_program/docking/simple/escape_pod_berth/P = docking_program
|
||||
armed = P.armed
|
||||
|
||||
data = list(
|
||||
. = list(
|
||||
"docking_status" = docking_program.get_docking_status(),
|
||||
"override_enabled" = docking_program.override_enabled,
|
||||
"exterior_status" = docking_program.memory["door_status"],
|
||||
"armed" = armed,
|
||||
"internalTemplateName" = "EscapePodBerthConsole",
|
||||
)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "escape_pod_berth_console.tmpl", name, 470, 290)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (!emagged)
|
||||
to_chat(user, "<span class='notice'>You emag the [src], arming the escape pod!</span>")
|
||||
|
||||
@@ -26,6 +26,9 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff
|
||||
if(host)
|
||||
host.tgui_close(user)
|
||||
|
||||
/datum/tgui_module/proc/can_still_topic(mob/user, datum/tgui_state/state)
|
||||
return (tgui_status(user, state) == STATUS_INTERACTIVE)
|
||||
|
||||
/datum/tgui_module/proc/check_access(mob/user, access)
|
||||
if(!access)
|
||||
return 1
|
||||
@@ -76,4 +79,37 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, tgui_id, name)
|
||||
ui.open()
|
||||
ui.open()
|
||||
|
||||
// This is a helper for anything that wants to render the map.
|
||||
/datum/tgui_module/proc/get_plane_masters()
|
||||
. = list()
|
||||
// 'Utility' planes
|
||||
. += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects)
|
||||
. += new /obj/screen/plane_master/lighting //Lighting system (but different!)
|
||||
. += new /obj/screen/plane_master/ghosts //Ghosts!
|
||||
. += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye!
|
||||
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_STATUS} //Status is the synth/human icon left side of medhuds
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH} //Health bar
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_LIFE} //Alive-or-not icon
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_ID} //Job ID icon
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_WANTED} //Wanted status
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_IMPLOYAL} //Loyalty implants
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_IMPTRACK} //Tracking implants
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_IMPCHEM} //Chemical implants
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_SPECIAL} //"Special" role stuff
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_OOC} //OOC status HUD
|
||||
|
||||
. += new /obj/screen/plane_master{plane = PLANE_ADMIN1} //For admin use
|
||||
. += new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use
|
||||
. += new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use
|
||||
|
||||
. += new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings.
|
||||
. += new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode
|
||||
|
||||
// Real tangible stuff planes
|
||||
. += new /obj/screen/plane_master/main{plane = TURF_PLANE}
|
||||
. += new /obj/screen/plane_master/main{plane = OBJ_PLANE}
|
||||
. += new /obj/screen/plane_master/main{plane = MOB_PLANE}
|
||||
. += new /obj/screen/plane_master/cloaked //Cloaked atoms!
|
||||
@@ -0,0 +1,138 @@
|
||||
/datum/tgui_module/alarm_monitor
|
||||
name = "Alarm monitor"
|
||||
tgui_id = "StationAlertConsole"
|
||||
var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use.
|
||||
var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user.
|
||||
|
||||
/datum/tgui_module/alarm_monitor/New()
|
||||
..()
|
||||
alarm_handlers = list()
|
||||
|
||||
/datum/tgui_module/alarm_monitor/all
|
||||
/datum/tgui_module/alarm_monitor/all/New()
|
||||
..()
|
||||
alarm_handlers = SSalarm.all_handlers
|
||||
|
||||
/datum/tgui_module/alarm_monitor/all/robot
|
||||
/datum/tgui_module/alarm_monitor/all/robot/tgui_state(mob/user)
|
||||
return GLOB.tgui_self_state
|
||||
|
||||
/datum/tgui_module/alarm_monitor/engineering
|
||||
/datum/tgui_module/alarm_monitor/engineering/New()
|
||||
..()
|
||||
alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm)
|
||||
|
||||
// Subtype for glasses_state
|
||||
/datum/tgui_module/alarm_monitor/engineering/glasses
|
||||
/datum/tgui_module/alarm_monitor/engineering/glasses/tgui_state(mob/user)
|
||||
return GLOB.tgui_glasses_state
|
||||
|
||||
// Subtype for nif_state
|
||||
/datum/tgui_module/alarm_monitor/engineering/nif
|
||||
/datum/tgui_module/alarm_monitor/engineering/nif/tgui_state(mob/user)
|
||||
return GLOB.tgui_nif_state
|
||||
|
||||
// Subtype for NTOS
|
||||
/datum/tgui_module/alarm_monitor/engineering/ntos
|
||||
ntos = TRUE
|
||||
|
||||
/datum/tgui_module/alarm_monitor/security
|
||||
/datum/tgui_module/alarm_monitor/security/New()
|
||||
..()
|
||||
alarm_handlers = list(camera_alarm, motion_alarm)
|
||||
|
||||
// Subtype for glasses_state
|
||||
/datum/tgui_module/alarm_monitor/security/glasses
|
||||
/datum/tgui_module/alarm_monitor/security/glasses/tgui_state(mob/user)
|
||||
return GLOB.tgui_glasses_state
|
||||
|
||||
// Subtype for NTOS
|
||||
/datum/tgui_module/alarm_monitor/security/ntos
|
||||
ntos = TRUE
|
||||
|
||||
/datum/tgui_module/alarm_monitor/proc/register_alarm(var/object, var/procName)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.register_alarm(object, procName)
|
||||
|
||||
/datum/tgui_module/alarm_monitor/proc/unregister_alarm(var/object)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister_alarm(object)
|
||||
|
||||
/datum/tgui_module/alarm_monitor/proc/all_alarms()
|
||||
var/z = get_z(tgui_host())
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.visible_alarms(z)
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/tgui_module/alarm_monitor/proc/major_alarms()
|
||||
var/z = get_z(tgui_host())
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.major_alarms(z)
|
||||
|
||||
return all_alarms
|
||||
|
||||
// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise.
|
||||
/datum/tgui_module/alarm_monitor/proc/has_major_alarms()
|
||||
var/z = get_z(tgui_host())
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
if(AH.has_major_alarms(z))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/datum/tgui_module/alarm_monitor/proc/minor_alarms()
|
||||
var/z = get_z(tgui_host())
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.minor_alarms(z)
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/tgui_module/alarm_monitor/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
// Camera stuff is AI only.
|
||||
// If you're not an AI, this is a read-only UI.
|
||||
if(!isAI(usr))
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("switchTo")
|
||||
var/obj/machinery/camera/C = locate(params["camera"]) in cameranet.cameras
|
||||
if(!C)
|
||||
return
|
||||
|
||||
usr.switch_to_camera(C)
|
||||
return 1
|
||||
|
||||
/datum/tgui_module/alarm_monitor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/categories[0]
|
||||
var/z = get_z(tgui_host())
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
|
||||
for(var/datum/alarm/A in AH.visible_alarms(z))
|
||||
var/cameras[0]
|
||||
var/lost_sources[0]
|
||||
|
||||
if(isAI(user))
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameras[++cameras.len] = C.tgui_structure()
|
||||
for(var/datum/alarm_source/AS in A.sources)
|
||||
if(!AS.source)
|
||||
lost_sources[++lost_sources.len] = AS.source_name
|
||||
|
||||
categories[categories.len]["alarms"] += list(list(
|
||||
"name" = "[A.alarm_name()]" + "[A.max_severity() > 1 ? "(MAJOR)" : ""]",
|
||||
"origin_lost" = A.origin == null,
|
||||
"has_cameras" = cameras.len,
|
||||
"cameras" = cameras,
|
||||
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
|
||||
data["categories"] = categories
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,358 @@
|
||||
/datum/tgui_module/appearance_changer
|
||||
name = "Appearance Editor"
|
||||
tgui_id = "AppearanceChanger"
|
||||
var/flags = APPEARANCE_ALL_HAIR
|
||||
var/mob/living/carbon/human/owner = null
|
||||
var/list/valid_species = list()
|
||||
var/list/valid_hairstyles = list()
|
||||
var/list/valid_facial_hairstyles = list()
|
||||
|
||||
var/check_whitelist
|
||||
var/list/whitelist
|
||||
var/list/blacklist
|
||||
|
||||
var/customize_usr = FALSE
|
||||
|
||||
// Stuff needed to render the map
|
||||
var/map_name
|
||||
var/obj/screen/map_view/cam_screen
|
||||
var/list/cam_plane_masters
|
||||
var/obj/screen/background/cam_background
|
||||
var/obj/screen/skybox/local_skybox
|
||||
// Needed for moving camera support
|
||||
var/camera_diff_x = -1
|
||||
var/camera_diff_y = -1
|
||||
var/camera_diff_z = -1
|
||||
|
||||
/datum/tgui_module/appearance_changer/New(
|
||||
var/host,
|
||||
mob/living/carbon/human/H,
|
||||
check_species_whitelist = 1,
|
||||
list/species_whitelist = list(),
|
||||
list/species_blacklist = list())
|
||||
. = ..()
|
||||
|
||||
map_name = "appearance_changer_[REF(src)]_map"
|
||||
// Initialize map objects
|
||||
cam_screen = new
|
||||
cam_screen.name = "screen"
|
||||
cam_screen.assigned_map = map_name
|
||||
cam_screen.del_on_map_removal = FALSE
|
||||
cam_screen.screen_loc = "[map_name]:1,1"
|
||||
|
||||
cam_plane_masters = get_plane_masters()
|
||||
|
||||
for(var/plane in cam_plane_masters)
|
||||
var/obj/screen/instance = plane
|
||||
instance.assigned_map = map_name
|
||||
instance.del_on_map_removal = FALSE
|
||||
instance.screen_loc = "[map_name]:CENTER"
|
||||
|
||||
local_skybox = new()
|
||||
local_skybox.assigned_map = map_name
|
||||
local_skybox.del_on_map_removal = FALSE
|
||||
local_skybox.screen_loc = "[map_name]:CENTER,CENTER"
|
||||
cam_plane_masters += local_skybox
|
||||
|
||||
cam_background = new
|
||||
cam_background.assigned_map = map_name
|
||||
cam_background.del_on_map_removal = FALSE
|
||||
reload_cameraview()
|
||||
|
||||
owner = H
|
||||
check_whitelist = check_species_whitelist
|
||||
whitelist = species_whitelist
|
||||
blacklist = species_blacklist
|
||||
|
||||
/datum/tgui_module/appearance_changer/Destroy()
|
||||
qdel(cam_screen)
|
||||
QDEL_LIST(cam_plane_masters)
|
||||
qdel(cam_background)
|
||||
return ..()
|
||||
|
||||
/datum/tgui_module/appearance_changer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
|
||||
switch(action)
|
||||
if("race")
|
||||
if(can_change(APPEARANCE_RACE) && (params["race"] in valid_species))
|
||||
if(target.change_species(params["race"]))
|
||||
cut_and_generate_data()
|
||||
return 1
|
||||
if("gender")
|
||||
if(can_change(APPEARANCE_GENDER) && (params["gender"] in get_genders()))
|
||||
if(target.change_gender(params["gender"]))
|
||||
cut_and_generate_data()
|
||||
return 1
|
||||
if("gender_id")
|
||||
if(can_change(APPEARANCE_GENDER) && (params["gender_id"] in all_genders_define_list))
|
||||
target.identifying_gender = params["gender_id"]
|
||||
return 1
|
||||
if("skin_tone")
|
||||
if(can_change_skin_tone())
|
||||
var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", -target.s_tone + 35) as num|null
|
||||
if(isnum(new_s_tone) && can_still_topic(usr, state))
|
||||
new_s_tone = 35 - max(min( round(new_s_tone), 220),1)
|
||||
return target.change_skin_tone(new_s_tone)
|
||||
if("skin_color")
|
||||
if(can_change_skin_color())
|
||||
var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(target.r_skin, target.g_skin, target.b_skin)) as color|null
|
||||
if(new_skin && can_still_topic(usr, state))
|
||||
var/r_skin = hex2num(copytext(new_skin, 2, 4))
|
||||
var/g_skin = hex2num(copytext(new_skin, 4, 6))
|
||||
var/b_skin = hex2num(copytext(new_skin, 6, 8))
|
||||
if(target.change_skin_color(r_skin, g_skin, b_skin))
|
||||
update_dna()
|
||||
return 1
|
||||
if("hair")
|
||||
if(can_change(APPEARANCE_HAIR) && (params["hair"] in valid_hairstyles))
|
||||
if(target.change_hair(params["hair"]))
|
||||
update_dna()
|
||||
return 1
|
||||
if("hair_color")
|
||||
if(can_change(APPEARANCE_HAIR_COLOR))
|
||||
var/new_hair = input("Please select hair color.", "Hair Color", rgb(target.r_hair, target.g_hair, target.b_hair)) as color|null
|
||||
if(new_hair && can_still_topic(usr, state))
|
||||
var/r_hair = hex2num(copytext(new_hair, 2, 4))
|
||||
var/g_hair = hex2num(copytext(new_hair, 4, 6))
|
||||
var/b_hair = hex2num(copytext(new_hair, 6, 8))
|
||||
if(target.change_hair_color(r_hair, g_hair, b_hair))
|
||||
update_dna()
|
||||
return 1
|
||||
if("facial_hair")
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR) && (params["facial_hair"] in valid_facial_hairstyles))
|
||||
if(target.change_facial_hair(params["facial_hair"]))
|
||||
update_dna()
|
||||
return 1
|
||||
if("facial_hair_color")
|
||||
if(can_change(APPEARANCE_FACIAL_HAIR_COLOR))
|
||||
var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(target.r_facial, target.g_facial, target.b_facial)) as color|null
|
||||
if(new_facial && can_still_topic(usr, state))
|
||||
var/r_facial = hex2num(copytext(new_facial, 2, 4))
|
||||
var/g_facial = hex2num(copytext(new_facial, 4, 6))
|
||||
var/b_facial = hex2num(copytext(new_facial, 6, 8))
|
||||
if(target.change_facial_hair_color(r_facial, g_facial, b_facial))
|
||||
update_dna()
|
||||
return 1
|
||||
if("eye_color")
|
||||
if(can_change(APPEARANCE_EYE_COLOR))
|
||||
var/new_eyes = input("Please select eye color.", "Eye Color", rgb(target.r_eyes, target.g_eyes, target.b_eyes)) as color|null
|
||||
if(new_eyes && can_still_topic(usr, state))
|
||||
var/r_eyes = hex2num(copytext(new_eyes, 2, 4))
|
||||
var/g_eyes = hex2num(copytext(new_eyes, 4, 6))
|
||||
var/b_eyes = hex2num(copytext(new_eyes, 6, 8))
|
||||
if(target.change_eye_color(r_eyes, g_eyes, b_eyes))
|
||||
update_dna()
|
||||
return 1
|
||||
return FALSE
|
||||
|
||||
/datum/tgui_module/appearance_changer/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui/parent_ui = null, datum/tgui_state/custom_state = GLOB.tgui_default_state)
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(user))
|
||||
return TRUE
|
||||
target = user
|
||||
|
||||
if(!target || !target.species)
|
||||
return
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
reload_cameraview()
|
||||
// Register map objects
|
||||
user.client.register_map_obj(cam_screen)
|
||||
for(var/plane in cam_plane_masters)
|
||||
user.client.register_map_obj(plane)
|
||||
user.client.register_map_obj(cam_background)
|
||||
// Open UI
|
||||
ui = new(user, src, tgui_id, name)
|
||||
ui.open()
|
||||
if(custom_state)
|
||||
ui.set_state(custom_state)
|
||||
|
||||
/datum/tgui_module/appearance_changer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
generate_data(check_whitelist, whitelist, blacklist)
|
||||
differential_check()
|
||||
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
|
||||
data["name"] = target.name
|
||||
data["specimen"] = target.species.name
|
||||
data["gender"] = target.gender
|
||||
data["gender_id"] = target.identifying_gender
|
||||
data["change_race"] = can_change(APPEARANCE_RACE)
|
||||
if(data["change_race"])
|
||||
var/species[0]
|
||||
for(var/specimen in valid_species)
|
||||
species[++species.len] = list("specimen" = specimen)
|
||||
data["species"] = species
|
||||
|
||||
data["change_gender"] = can_change(APPEARANCE_GENDER)
|
||||
if(data["change_gender"])
|
||||
var/genders[0]
|
||||
for(var/gender in get_genders())
|
||||
genders[++genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender)
|
||||
data["genders"] = genders
|
||||
var/id_genders[0]
|
||||
for(var/gender in all_genders_define_list)
|
||||
id_genders[++id_genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender)
|
||||
data["id_genders"] = id_genders
|
||||
|
||||
data["change_hair"] = can_change(APPEARANCE_HAIR)
|
||||
if(data["change_hair"])
|
||||
var/hair_styles[0]
|
||||
for(var/hair_style in valid_hairstyles)
|
||||
hair_styles[++hair_styles.len] = list("hairstyle" = hair_style)
|
||||
data["hair_styles"] = hair_styles
|
||||
data["hair_style"] = target.h_style
|
||||
|
||||
data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR)
|
||||
if(data["change_facial_hair"])
|
||||
var/facial_hair_styles[0]
|
||||
for(var/facial_hair_style in valid_facial_hairstyles)
|
||||
facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style)
|
||||
data["facial_hair_styles"] = facial_hair_styles
|
||||
data["facial_hair_style"] = target.f_style
|
||||
|
||||
data["change_skin_tone"] = can_change_skin_tone()
|
||||
data["change_skin_color"] = can_change_skin_color()
|
||||
if(data["change_skin_color"])
|
||||
data["skin_color"] = rgb(target.r_skin, target.g_skin, target.b_skin)
|
||||
data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR)
|
||||
if(data["change_eye_color"])
|
||||
data["eye_color"] = rgb(target.r_eyes, target.g_eyes, target.b_eyes)
|
||||
data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR)
|
||||
if(data["change_hair_color"])
|
||||
data["hair_color"] = rgb(target.r_hair, target.g_hair, target.b_hair)
|
||||
data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR)
|
||||
if(data["change_facial_hair_color"])
|
||||
data["facial_hair_color"] = rgb(target.r_facial, target.g_facial, target.b_facial)
|
||||
return data
|
||||
|
||||
/datum/tgui_module/appearance_changer/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
data["mapRef"] = map_name
|
||||
return data
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/differential_check()
|
||||
var/turf/T = get_turf(customize_usr ? tgui_host() : owner)
|
||||
if(T)
|
||||
var/new_x = T.x
|
||||
var/new_y = T.y
|
||||
var/new_z = T.z
|
||||
if((new_x != camera_diff_x) || (new_y != camera_diff_y) || (new_z != camera_diff_z))
|
||||
reload_cameraview()
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/reload_cameraview()
|
||||
var/turf/camTurf = get_turf(customize_usr ? tgui_host() : owner)
|
||||
if(!camTurf)
|
||||
return
|
||||
|
||||
camera_diff_x = camTurf.x
|
||||
camera_diff_y = camTurf.y
|
||||
camera_diff_z = camTurf.z
|
||||
|
||||
var/list/visible_turfs = list()
|
||||
for(var/turf/T in range(1, camTurf))
|
||||
visible_turfs += T
|
||||
|
||||
cam_screen.vis_contents = visible_turfs
|
||||
cam_background.icon_state = "clear"
|
||||
cam_background.fill_rect(1, 1, 3, 3)
|
||||
|
||||
local_skybox.cut_overlays()
|
||||
local_skybox.add_overlay(SSskybox.get_skybox(get_z(camTurf)))
|
||||
local_skybox.scale_to_view(3)
|
||||
local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - camTurf.x, (world.maxy>>1) - camTurf.y)
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/update_dna()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
|
||||
if(target && (flags & APPEARANCE_UPDATE_DNA))
|
||||
target.update_dna()
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/can_change(var/flag)
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
|
||||
return target && (flags & flag)
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/can_change_skin_tone()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
|
||||
return target && (flags & APPEARANCE_SKIN) && target.species.appearance_flags & HAS_SKIN_TONE
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/can_change_skin_color()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
|
||||
return target && (flags & APPEARANCE_SKIN) && target.species.appearance_flags & HAS_SKIN_COLOR
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/cut_and_generate_data()
|
||||
// Making the assumption that the available species remain constant
|
||||
valid_facial_hairstyles.Cut()
|
||||
valid_facial_hairstyles.Cut()
|
||||
generate_data()
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/generate_data()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
if(!target)
|
||||
return
|
||||
if(!valid_species.len)
|
||||
valid_species = target.generate_valid_species(check_whitelist, whitelist, blacklist)
|
||||
if(!valid_hairstyles.len || !valid_facial_hairstyles.len)
|
||||
valid_hairstyles = target.generate_valid_hairstyles(check_gender = 0)
|
||||
valid_facial_hairstyles = target.generate_valid_facial_hairstyles()
|
||||
|
||||
/datum/tgui_module/appearance_changer/proc/get_genders()
|
||||
var/mob/living/carbon/human/target = owner
|
||||
if(customize_usr)
|
||||
if(!ishuman(usr))
|
||||
return TRUE
|
||||
target = usr
|
||||
var/datum/species/S = target.species
|
||||
var/list/possible_genders = S.genders
|
||||
if(!target.internal_organs_by_name["cell"])
|
||||
return possible_genders
|
||||
possible_genders = possible_genders.Copy()
|
||||
possible_genders |= NEUTER
|
||||
return possible_genders
|
||||
|
||||
/datum/tgui_module/appearance_changer/mirror
|
||||
name = "SalonPro Nano-Mirror™"
|
||||
flags = APPEARANCE_ALL_HAIR
|
||||
customize_usr = TRUE
|
||||
|
||||
/datum/tgui_module/appearance_changer/mirror/coskit
|
||||
name = "SalonPro Porta-Makeover Deluxe™"
|
||||
@@ -0,0 +1,110 @@
|
||||
/datum/tgui_module/atmos_control
|
||||
name = "Atmospherics Control"
|
||||
tgui_id = "AtmosControl"
|
||||
var/obj/access = new()
|
||||
var/emagged = 0
|
||||
var/ui_ref
|
||||
var/list/monitored_alarms = list()
|
||||
|
||||
/datum/tgui_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids)
|
||||
..()
|
||||
access.req_access = req_access
|
||||
access.req_one_access = req_one_access
|
||||
|
||||
if(monitored_alarm_ids)
|
||||
for(var/obj/machinery/alarm/alarm in machines)
|
||||
if(alarm.alarm_id && alarm.alarm_id in monitored_alarm_ids)
|
||||
monitored_alarms += alarm
|
||||
// machines may not yet be ordered at this point
|
||||
monitored_alarms = dd_sortedObjectList(monitored_alarms)
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("alarm")
|
||||
if(ui_ref)
|
||||
var/obj/machinery/alarm/alarm = locate(params["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines)
|
||||
if(alarm)
|
||||
var/datum/tgui_state/TS = generate_state(alarm)
|
||||
alarm.tgui_interact(usr, parent_ui = ui_ref, state = TS)
|
||||
return 1
|
||||
if("setZLevel")
|
||||
ui.set_map_z_level(params["mapZLevel"])
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, tgui_id, name)
|
||||
ui.autoupdate = TRUE
|
||||
ui.open()
|
||||
ui_ref = ui
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_static_data(mob/user)
|
||||
. = ..()
|
||||
|
||||
var/z = get_z(user)
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
|
||||
// TODO: Move these to a cache, similar to cameras
|
||||
var/alarms[0]
|
||||
for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines))
|
||||
if(!monitored_alarms.len && alarm.alarms_hidden)
|
||||
continue
|
||||
if(!(alarm.z in map_levels))
|
||||
continue
|
||||
alarms[++alarms.len] = list(
|
||||
"name" = sanitize(alarm.name),
|
||||
"ref"= "\ref[alarm]",
|
||||
"danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm),
|
||||
"x" = alarm.x,
|
||||
"y" = alarm.y,
|
||||
"z" = alarm.z)
|
||||
.["alarms"] = alarms
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/z = get_z(user)
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
data["map_levels"] = map_levels
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/atmos_control/tgui_close()
|
||||
. = ..()
|
||||
ui_ref = null
|
||||
|
||||
/datum/tgui_module/atmos_control/proc/generate_state(air_alarm)
|
||||
var/datum/tgui_state/air_alarm_remote/state = new()
|
||||
state.atmos_control = src
|
||||
state.air_alarm = air_alarm
|
||||
return state
|
||||
|
||||
/datum/tgui_state/air_alarm_remote
|
||||
var/datum/tgui_module/atmos_control/atmos_control = null
|
||||
var/obj/machinery/alarm/air_alarm = null
|
||||
|
||||
/datum/tgui_state/air_alarm_remote/can_use_topic(src_object, mob/user)
|
||||
if(!atmos_control.ui_ref)
|
||||
qdel(src)
|
||||
return STATUS_CLOSE
|
||||
if(has_access(user))
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_UPDATE
|
||||
|
||||
/datum/tgui_state/air_alarm_remote/proc/has_access(var/mob/user)
|
||||
return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO) || (access_ce in user.GetAccess()))
|
||||
|
||||
/datum/tgui_state/air_alarm_remote/Destroy()
|
||||
atmos_control = null
|
||||
air_alarm = null
|
||||
|
||||
/datum/tgui_module/atmos_control/ntos
|
||||
ntos = TRUE
|
||||
|
||||
/datum/tgui_module/atmos_control/robot
|
||||
/datum/tgui_module/atmos_control/robot/tgui_state(mob/user)
|
||||
return GLOB.tgui_self_state
|
||||
@@ -37,37 +37,7 @@
|
||||
cam_screen.del_on_map_removal = FALSE
|
||||
cam_screen.screen_loc = "[map_name]:1,1"
|
||||
|
||||
cam_plane_masters = list()
|
||||
|
||||
// 'Utility' planes
|
||||
cam_plane_masters += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects)
|
||||
cam_plane_masters += new /obj/screen/plane_master/lighting //Lighting system (but different!)
|
||||
cam_plane_masters += new /obj/screen/plane_master/ghosts //Ghosts!
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye!
|
||||
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_STATUS} //Status is the synth/human icon left side of medhuds
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH} //Health bar
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_LIFE} //Alive-or-not icon
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_ID} //Job ID icon
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_WANTED} //Wanted status
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_IMPLOYAL} //Loyalty implants
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_IMPTRACK} //Tracking implants
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_IMPCHEM} //Chemical implants
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_SPECIAL} //"Special" role stuff
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_OOC} //OOC status HUD
|
||||
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_ADMIN1} //For admin use
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use
|
||||
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings.
|
||||
cam_plane_masters += new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode
|
||||
|
||||
// Real tangible stuff planes
|
||||
cam_plane_masters += new /obj/screen/plane_master/main{plane = TURF_PLANE}
|
||||
cam_plane_masters += new /obj/screen/plane_master/main{plane = OBJ_PLANE}
|
||||
cam_plane_masters += new /obj/screen/plane_master/main{plane = MOB_PLANE}
|
||||
cam_plane_masters += new /obj/screen/plane_master/cloaked //Cloaked atoms!
|
||||
cam_plane_masters = get_plane_masters()
|
||||
|
||||
for(var/plane in cam_plane_masters)
|
||||
var/obj/screen/instance = plane
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/datum/tgui_module/power_monitor
|
||||
name = "Power monitor"
|
||||
tgui_id = "PowerMonitor"
|
||||
var/list/grid_sensors
|
||||
var/active_sensor = null //name_tag of the currently selected sensor
|
||||
|
||||
/datum/tgui_module/power_monitor/New()
|
||||
. = ..()
|
||||
refresh_sensors()
|
||||
|
||||
/datum/tgui_module/power_monitor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/sensors = list()
|
||||
// Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading.
|
||||
var/obj/machinery/power/sensor/focus = null
|
||||
|
||||
var/z = get_z(user)
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
|
||||
// Build list of data from sensor readings.
|
||||
for(var/obj/machinery/power/sensor/S in grid_sensors)
|
||||
if(!(S.z in map_levels))
|
||||
continue
|
||||
sensors.Add(list(list(
|
||||
"name" = S.name_tag,
|
||||
"alarm" = S.check_grid_warning()
|
||||
)))
|
||||
if(S.name_tag == active_sensor)
|
||||
focus = S
|
||||
|
||||
data["all_sensors"] = sensors
|
||||
if(focus)
|
||||
data["focus"] = focus.tgui_data(user)
|
||||
else
|
||||
data["focus"] = null
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/power_monitor/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("clear")
|
||||
active_sensor = null
|
||||
. = TRUE
|
||||
if("refresh")
|
||||
refresh_sensors()
|
||||
. = TRUE
|
||||
if("setsensor")
|
||||
active_sensor = params["id"]
|
||||
. = TRUE
|
||||
|
||||
/datum/tgui_module/power_monitor/proc/has_alarm()
|
||||
for(var/obj/machinery/power/sensor/S in grid_sensors)
|
||||
if(S.check_grid_warning())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/tgui_module/power_monitor/proc/refresh_sensors()
|
||||
grid_sensors = list()
|
||||
|
||||
// Handle ultranested programs
|
||||
var/turf/T = get_turf(tgui_host())
|
||||
|
||||
var/list/levels = list()
|
||||
if(!T) // Safety check
|
||||
return
|
||||
if(T)
|
||||
levels += using_map.get_map_levels(T.z, FALSE)
|
||||
for(var/obj/machinery/power/sensor/S in machines)
|
||||
if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
|
||||
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
|
||||
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
|
||||
else
|
||||
grid_sensors += S
|
||||
|
||||
/datum/tgui_module/power_monitor/ntos
|
||||
ntos = TRUE
|
||||
|
||||
// Subtype for self_state
|
||||
/datum/tgui_module/power_monitor/robot
|
||||
/datum/tgui_module/power_monitor/robot/tgui_state(mob/user)
|
||||
return GLOB.tgui_self_state
|
||||
@@ -0,0 +1,118 @@
|
||||
/datum/tgui_module/rcon
|
||||
name = "Power RCON"
|
||||
tgui_id = "RCON"
|
||||
|
||||
var/list/known_SMESs = null
|
||||
var/list/known_breakers = null
|
||||
|
||||
/datum/tgui_module/rcon/tgui_data(mob/user)
|
||||
FindDevices() // Update our devices list
|
||||
var/list/data = ..()
|
||||
|
||||
// SMES DATA (simplified view)
|
||||
var/list/smeslist[0]
|
||||
for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs)
|
||||
smeslist.Add(list(list(
|
||||
"capacity" = SMES.capacity,
|
||||
"capacityPercent" = round(100*SMES.charge/SMES.capacity, 0.1),
|
||||
"charge" = SMES.charge,
|
||||
"input_set" = SMES.input_attempt,
|
||||
"input_val" = round(SMES.input_level/1000, 0.1),
|
||||
"output_set" = SMES.output_attempt,
|
||||
"output_val" = round(SMES.output_level/1000, 0.1),
|
||||
"output_load" = round(SMES.output_used/1000, 0.1),
|
||||
"RCON_tag" = SMES.RCon_tag
|
||||
)))
|
||||
|
||||
data["smes_info"] = sortByKey(smeslist, "RCON_tag")
|
||||
|
||||
// BREAKER DATA (simplified view)
|
||||
var/list/breakerlist[0]
|
||||
for(var/obj/machinery/power/breakerbox/BR in known_breakers)
|
||||
breakerlist.Add(list(list(
|
||||
"RCON_tag" = BR.RCon_tag,
|
||||
"enabled" = BR.on
|
||||
)))
|
||||
data["breaker_info"] = breakerlist
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/rcon/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("smes_in_toggle")
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
|
||||
if(SMES)
|
||||
SMES.toggle_input()
|
||||
. = TRUE
|
||||
if("smes_out_toggle")
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
|
||||
if(SMES)
|
||||
SMES.toggle_output()
|
||||
. = TRUE
|
||||
if("smes_in_set")
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
|
||||
if(SMES)
|
||||
var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000
|
||||
SMES.set_input(inputset)
|
||||
. = TRUE
|
||||
if("smes_out_set")
|
||||
var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"])
|
||||
if(SMES)
|
||||
var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000
|
||||
SMES.set_output(outputset)
|
||||
. = TRUE
|
||||
if("toggle_breaker")
|
||||
var/obj/machinery/power/breakerbox/toggle = null
|
||||
for(var/obj/machinery/power/breakerbox/breaker in known_breakers)
|
||||
if(breaker.RCon_tag == params["breaker"])
|
||||
toggle = breaker
|
||||
if(toggle)
|
||||
if(toggle.update_locked)
|
||||
to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.")
|
||||
else
|
||||
toggle.auto_toggle()
|
||||
. = TRUE
|
||||
|
||||
|
||||
// Proc: GetSMESByTag()
|
||||
// Parameters: 1 (tag - RCON tag of SMES we want to look up)
|
||||
// Description: Looks up and returns SMES which has matching RCON tag
|
||||
/datum/tgui_module/rcon/proc/GetSMESByTag(var/tag)
|
||||
if(!tag)
|
||||
return
|
||||
|
||||
for(var/obj/machinery/power/smes/buildable/S in known_SMESs)
|
||||
if(S.RCon_tag == tag)
|
||||
return S
|
||||
|
||||
// Proc: FindDevices()
|
||||
// Parameters: None
|
||||
// Description: Refreshes local list of known devices.
|
||||
/datum/tgui_module/rcon/proc/FindDevices()
|
||||
known_SMESs = new /list()
|
||||
|
||||
var/z = get_z(tgui_host())
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
|
||||
for(var/obj/machinery/power/smes/buildable/SMES in GLOB.smeses)
|
||||
if(!(SMES.z in map_levels))
|
||||
continue
|
||||
if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon)
|
||||
known_SMESs.Add(SMES)
|
||||
|
||||
known_breakers = new /list()
|
||||
for(var/obj/machinery/power/breakerbox/breaker in machines)
|
||||
if(!(breaker.z in map_levels))
|
||||
continue
|
||||
if(breaker.RCon_tag != "NO_TAG")
|
||||
known_breakers.Add(breaker)
|
||||
|
||||
/datum/tgui_module/rcon/ntos
|
||||
ntos = TRUE
|
||||
|
||||
/datum/tgui_module/rcon/robot
|
||||
/datum/tgui_module/rcon/robot/tgui_state(mob/user)
|
||||
return GLOB.tgui_self_state
|
||||
@@ -0,0 +1,46 @@
|
||||
/datum/tgui_module/shutoff_monitor
|
||||
name = "Shutoff Valve Monitoring"
|
||||
tgui_id = "ShutoffMonitor"
|
||||
|
||||
/datum/tgui_module/shutoff_monitor/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("toggle_enable")
|
||||
var/obj/machinery/atmospherics/valve/shutoff/S = locate(params["valve"])
|
||||
if(!istype(S))
|
||||
return 0
|
||||
S.close_on_leaks = !S.close_on_leaks
|
||||
return 1
|
||||
|
||||
if("toggle_open")
|
||||
var/obj/machinery/atmospherics/valve/shutoff/S = locate(params["valve"])
|
||||
if(!istype(S))
|
||||
return 0
|
||||
if(S.open)
|
||||
S.close()
|
||||
else
|
||||
S.open()
|
||||
return 1
|
||||
|
||||
/datum/tgui_module/shutoff_monitor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/valves = list()
|
||||
|
||||
for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves)
|
||||
valves.Add(list(list(
|
||||
"name" = S.name,
|
||||
"enabled" = S.close_on_leaks,
|
||||
"open" = S.open,
|
||||
"x" = S.x,
|
||||
"y" = S.y,
|
||||
"z" = S.z,
|
||||
"ref" = "\ref[S]"
|
||||
)))
|
||||
|
||||
data["valves"] = valves
|
||||
return data
|
||||
|
||||
/datum/tgui_module/shutoff_monitor/ntos
|
||||
ntos = TRUE
|
||||
@@ -0,0 +1,108 @@
|
||||
|
||||
/datum/tgui_module/supermatter_monitor
|
||||
name = "Supermatter monitor"
|
||||
tgui_id = "SupermatterMonitor"
|
||||
var/list/supermatters
|
||||
var/obj/machinery/power/supermatter/active = null // Currently selected supermatter crystal.
|
||||
|
||||
/datum/tgui_module/supermatter_monitor/Destroy()
|
||||
. = ..()
|
||||
active = null
|
||||
supermatters = null
|
||||
|
||||
/datum/tgui_module/supermatter_monitor/New()
|
||||
..()
|
||||
refresh()
|
||||
|
||||
// Refreshes list of active supermatter crystals
|
||||
/datum/tgui_module/supermatter_monitor/proc/refresh()
|
||||
supermatters = list()
|
||||
var/z = get_z(tgui_host())
|
||||
if(!z)
|
||||
return
|
||||
var/valid_z_levels = using_map.get_map_levels(z)
|
||||
for(var/obj/machinery/power/supermatter/S in machines)
|
||||
// Delaminating, not within coverage, not on a tile.
|
||||
if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/))
|
||||
continue
|
||||
supermatters.Add(S)
|
||||
|
||||
if(!(active in supermatters))
|
||||
active = null
|
||||
|
||||
/datum/tgui_module/supermatter_monitor/proc/get_status()
|
||||
. = SUPERMATTER_INACTIVE
|
||||
for(var/obj/machinery/power/supermatter/S in supermatters)
|
||||
. = max(., S.get_status())
|
||||
|
||||
/datum/tgui_module/supermatter_monitor/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
if(istype(active))
|
||||
var/turf/T = get_turf(active)
|
||||
if(!T)
|
||||
active = null
|
||||
return
|
||||
var/datum/gas_mixture/air = T.return_air()
|
||||
if(!istype(air))
|
||||
active = null
|
||||
return
|
||||
|
||||
data["active"] = 1
|
||||
data["SM_area"] = get_area(active)
|
||||
data["SM_integrity"] = active.get_integrity()
|
||||
data["SM_power"] = active.power
|
||||
data["SM_ambienttemp"] = air.temperature
|
||||
data["SM_ambientpressure"] = air.return_pressure()
|
||||
data["SM_EPR"] = active.get_epr()
|
||||
//data["SM_EPR"] = active.get_epr()
|
||||
if(air.total_moles)
|
||||
data["SM_gas_O2"] = round(100*air.gas["oxygen"]/air.total_moles,0.01)
|
||||
data["SM_gas_CO2"] = round(100*air.gas["carbon_dioxide"]/air.total_moles,0.01)
|
||||
data["SM_gas_N2"] = round(100*air.gas["nitrogen"]/air.total_moles,0.01)
|
||||
data["SM_gas_PH"] = round(100*air.gas["phoron"]/air.total_moles,0.01)
|
||||
data["SM_gas_N2O"] = round(100*air.gas["sleeping_agent"]/air.total_moles,0.01)
|
||||
else
|
||||
data["SM_gas_O2"] = 0
|
||||
data["SM_gas_CO2"] = 0
|
||||
data["SM_gas_N2"] = 0
|
||||
data["SM_gas_PH"] = 0
|
||||
data["SM_gas_N2O"] = 0
|
||||
else
|
||||
var/list/SMS = list()
|
||||
for(var/obj/machinery/power/supermatter/S in supermatters)
|
||||
var/area/A = get_area(S)
|
||||
if(!A)
|
||||
continue
|
||||
|
||||
SMS.Add(list(list(
|
||||
"area_name" = A.name,
|
||||
"integrity" = S.get_integrity(),
|
||||
"uid" = S.uid
|
||||
)))
|
||||
|
||||
data["active"] = 0
|
||||
data["supermatters"] = SMS
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/supermatter_monitor/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("clear")
|
||||
active = null
|
||||
. = TRUE
|
||||
if("refresh")
|
||||
refresh()
|
||||
. = TRUE
|
||||
if("set")
|
||||
var/newuid = text2num(params["set"])
|
||||
for(var/obj/machinery/power/supermatter/S in supermatters)
|
||||
if(S.uid == newuid)
|
||||
active = S
|
||||
. = TRUE
|
||||
|
||||
/datum/tgui_module/supermatter_monitor/ntos
|
||||
ntos = TRUE
|
||||
@@ -143,57 +143,56 @@
|
||||
/obj/structure/lift/panel/interact(var/mob/user)
|
||||
if(!..())
|
||||
return
|
||||
|
||||
tgui_interact(user)
|
||||
|
||||
var/dat = list()
|
||||
dat += "<html><body><hr><b>Lift panel</b><hr>"
|
||||
/obj/structure/lift/panel/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Turbolift", name)
|
||||
ui.open()
|
||||
|
||||
//the floors list stores levels in order of increasing Z
|
||||
//therefore, to display upper levels at the top of the menu and
|
||||
//lower levels at the bottom, we need to go through the list in reverse
|
||||
/obj/structure/lift/panel/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["doors_open"] = lift.doors_are_open()
|
||||
data["fire_mode"] = lift.fire_mode
|
||||
|
||||
data["floors"] = list()
|
||||
for(var/i in lift.floors.len to 1 step -1)
|
||||
var/datum/turbolift_floor/floor = lift.floors[i]
|
||||
var/label = floor.label? floor.label : "Level #[i]"
|
||||
dat += "<font color = '[(floor in lift.queued_floors) ? COLOR_YELLOW : COLOR_WHITE]'>"
|
||||
dat += "<a href='?src=\ref[src];move_to_floor=["\ref[floor]"]'>[label]</a>: [floor.name]</font><br>"
|
||||
data["floors"].Add(list(list(
|
||||
"id" = i,
|
||||
"ref" = "\ref[floor]",
|
||||
"queued" = (floor in lift.queued_floors),
|
||||
"target" = (lift.target_floor == floor),
|
||||
"current" = (lift.current_floor == floor),
|
||||
"label" = floor.label,
|
||||
"name" = floor.name,
|
||||
)))
|
||||
|
||||
return data
|
||||
|
||||
dat += "<hr>"
|
||||
if(lift.doors_are_open())
|
||||
dat += "<a href='?src=\ref[src];close_doors=1'>Close Doors</a><br>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];open_doors=1'>Open Doors</a><br>"
|
||||
dat += "<a href='?src=\ref[src];emergency_stop=1'>Emergency Stop</a>"
|
||||
dat += "<hr></body></html>"
|
||||
/obj/structure/lift/panel/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
user.set_machine(src)
|
||||
var/datum/browser/popup = new(user, "turbolift_panel", "Lift Panel", 350, 320) //VOREStation Edit - Wider!
|
||||
popup.set_content(jointext(dat, null))
|
||||
popup.open()
|
||||
return
|
||||
switch(action)
|
||||
if("move_to_floor")
|
||||
. = TRUE
|
||||
lift.queue_move_to(locate(params["ref"]))
|
||||
if("toggle_doors")
|
||||
. = TRUE
|
||||
if(lift.doors_are_open())
|
||||
lift.close_doors()
|
||||
else
|
||||
lift.open_doors()
|
||||
if("emergency_stop")
|
||||
. = TRUE
|
||||
lift.emergency_stop()
|
||||
|
||||
/obj/structure/lift/panel/Topic(href, href_list)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/panel_interact
|
||||
if(href_list["move_to_floor"])
|
||||
lift.queue_move_to(locate(href_list["move_to_floor"]))
|
||||
panel_interact = 1
|
||||
if(href_list["open_doors"])
|
||||
panel_interact = 1
|
||||
lift.open_doors()
|
||||
if(href_list["close_doors"])
|
||||
panel_interact = 1
|
||||
lift.close_doors()
|
||||
if(href_list["emergency_stop"])
|
||||
panel_interact = 1
|
||||
lift.emergency_stop()
|
||||
|
||||
if(panel_interact)
|
||||
pressed(usr)
|
||||
updateDialog()
|
||||
|
||||
return 0
|
||||
|
||||
/obj/structure/lift/panel/update_icon()
|
||||
if(lift.fire_mode)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
O.loc = src
|
||||
|
||||
user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!")
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
src.attack_hand(user)
|
||||
|
||||
@@ -36,27 +36,32 @@
|
||||
icon_state = "centrifuge_moving"
|
||||
|
||||
/obj/machinery/computer/centrifuge/attack_hand(var/mob/user as mob)
|
||||
if(..()) return
|
||||
ui_interact(user)
|
||||
if(..())
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/centrifuge/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
/obj/machinery/computer/centrifuge/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "IsolationCentrifuge", name)
|
||||
ui.open()
|
||||
|
||||
var/data[0]
|
||||
/obj/machinery/computer/centrifuge/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["antibodies"] = null
|
||||
data["pathogens"] = null
|
||||
data["pathogens"] = list()
|
||||
data["is_antibody_sample"] = null
|
||||
data["busy"] = null
|
||||
data["sample_inserted"] = !!sample
|
||||
|
||||
if (curing)
|
||||
if(curing)
|
||||
data["busy"] = "Isolating antibodies..."
|
||||
else if (isolating)
|
||||
else if(isolating)
|
||||
data["busy"] = "Isolating pathogens..."
|
||||
else
|
||||
data["sample_inserted"] = !!sample
|
||||
|
||||
if (sample)
|
||||
if(sample)
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list
|
||||
if (B)
|
||||
if(B)
|
||||
data["antibodies"] = antigens2string(B.data["antibodies"], none=null)
|
||||
|
||||
var/list/pathogens[0]
|
||||
@@ -65,8 +70,7 @@
|
||||
var/datum/disease2/disease/V = virus[ID]
|
||||
pathogens.Add(list(list("name" = V.name(), "spread_type" = V.spreadtype, "reference" = "\ref[V]")))
|
||||
|
||||
if (pathogens.len > 0)
|
||||
data["pathogens"] = pathogens
|
||||
data["pathogens"] = pathogens
|
||||
|
||||
else
|
||||
var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list
|
||||
@@ -74,103 +78,90 @@
|
||||
data["antibodies"] = antigens2string(A.data["antibodies"], none=null)
|
||||
data["is_antibody_sample"] = 1
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "isolation_centrifuge.tmpl", src.name, 400, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/centrifuge/process()
|
||||
..()
|
||||
if (stat & (NOPOWER|BROKEN)) return
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
|
||||
if (curing)
|
||||
if(curing)
|
||||
curing -= 1
|
||||
if (curing == 0)
|
||||
if(curing == 0)
|
||||
cure()
|
||||
|
||||
if (isolating)
|
||||
if(isolating)
|
||||
isolating -= 1
|
||||
if(isolating == 0)
|
||||
isolate()
|
||||
|
||||
/obj/machinery/computer/centrifuge/Topic(href, href_list)
|
||||
if (..()) return 1
|
||||
/obj/machinery/computer/centrifuge/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/mob/user = usr
|
||||
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||
add_fingerprint(user)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if (href_list["close"])
|
||||
user.unset_machine()
|
||||
ui.close()
|
||||
return 0
|
||||
|
||||
if (href_list["print"])
|
||||
print(user)
|
||||
return 1
|
||||
|
||||
if(href_list["isolate"])
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list
|
||||
if (B)
|
||||
var/datum/disease2/disease/virus = locate(href_list["isolate"])
|
||||
virus2 = virus.getcopy()
|
||||
isolating = 40
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
switch(href_list["action"])
|
||||
if ("antibody")
|
||||
switch(action)
|
||||
if("print")
|
||||
print(user)
|
||||
. = TRUE
|
||||
if("isolate")
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list
|
||||
if(B)
|
||||
var/datum/disease2/disease/virus = locate(params["isolate"])
|
||||
virus2 = virus.getcopy()
|
||||
isolating = 40
|
||||
update_icon()
|
||||
. = TRUE
|
||||
if("antibody")
|
||||
var/delay = 20
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list
|
||||
if (!B)
|
||||
if(!B)
|
||||
state("\The [src] buzzes, \"No antibody carrier detected.\"", "blue")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/has_toxins = locate(/datum/reagent/toxin) in sample.reagents.reagent_list
|
||||
var/has_radium = sample.reagents.has_reagent("radium")
|
||||
if (has_toxins || has_radium)
|
||||
if(has_toxins || has_radium)
|
||||
state("\The [src] beeps, \"Pathogen purging speed above nominal.\"", "blue")
|
||||
if (has_toxins)
|
||||
if(has_toxins)
|
||||
delay = delay/2
|
||||
if (has_radium)
|
||||
if(has_radium)
|
||||
delay = delay/2
|
||||
|
||||
curing = round(delay)
|
||||
playsound(src, 'sound/machines/juicer.ogg', 50, 1)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
. = TRUE
|
||||
if("sample")
|
||||
if(sample)
|
||||
sample.loc = src.loc
|
||||
sample = null
|
||||
return 1
|
||||
. = TRUE
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/computer/centrifuge/proc/cure()
|
||||
if (!sample) return
|
||||
if(!sample) return
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list
|
||||
if (!B) return
|
||||
if(!B) return
|
||||
|
||||
var/list/data = list("antibodies" = B.data["antibodies"])
|
||||
var/amt= sample.reagents.get_reagent_amount("blood")
|
||||
sample.reagents.remove_reagent("blood", amt)
|
||||
sample.reagents.add_reagent("antibodies", amt, data)
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
update_icon()
|
||||
ping("\The [src] pings, \"Antibody isolated.\"")
|
||||
|
||||
/obj/machinery/computer/centrifuge/proc/isolate()
|
||||
if (!sample) return
|
||||
if(!sample) return
|
||||
var/obj/item/weapon/virusdish/dish = new/obj/item/weapon/virusdish(loc)
|
||||
dish.virus2 = virus2
|
||||
virus2 = null
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
update_icon()
|
||||
ping("\The [src] pings, \"Pathogen isolated.\"")
|
||||
|
||||
@@ -182,20 +173,20 @@
|
||||
<large><u>Sample:</u></large> [sample.name]<br>
|
||||
"}
|
||||
|
||||
if (user)
|
||||
if(user)
|
||||
P.info += "<u>Generated By:</u> [user.name]<br>"
|
||||
|
||||
P.info += "<hr>"
|
||||
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list
|
||||
if (B)
|
||||
if(B)
|
||||
P.info += "<u>Antibodies:</u> "
|
||||
P.info += antigens2string(B.data["antibodies"])
|
||||
P.info += "<br>"
|
||||
|
||||
var/list/virus = B.data["virus2"]
|
||||
P.info += "<u>Pathogens:</u> <br>"
|
||||
if (virus.len > 0)
|
||||
if(virus.len > 0)
|
||||
for (var/ID in virus)
|
||||
var/datum/disease2/disease/V = virus[ID]
|
||||
P.info += "[V.name()]<br>"
|
||||
@@ -204,7 +195,7 @@
|
||||
|
||||
else
|
||||
var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list
|
||||
if (A)
|
||||
if(A)
|
||||
P.info += "The following antibodies have been isolated from the blood sample: "
|
||||
P.info += antigens2string(A.data["antibodies"])
|
||||
P.info += "<br>"
|
||||
|
||||
@@ -254,6 +254,7 @@ var/global/list/virusDB = list()
|
||||
"resistance" = resistance,
|
||||
"species" = jointext(affected_species, ", "),
|
||||
"symptoms" = list(),
|
||||
"ref" = "\ref[src]",
|
||||
)
|
||||
|
||||
for(var/datum/disease2/effectholder/E in effects)
|
||||
@@ -272,6 +273,7 @@ var/global/list/virusDB = list()
|
||||
v.fields["name"] = name()
|
||||
v.fields["description"] = get_info()
|
||||
v.fields["tgui_description"] = get_tgui_info()
|
||||
v.fields["tgui_description"]["record"] = "\ref[v]"
|
||||
v.fields["antigen"] = antigens2string(antigen)
|
||||
v.fields["spread type"] = spreadtype
|
||||
virusDB["[uniqueID]"] = v
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
if(istype(I,/obj/item/weapon/virusdish))
|
||||
var/mob/living/carbon/c = user
|
||||
if (dish)
|
||||
if(dish)
|
||||
to_chat(user, "\The [src] is already loaded.")
|
||||
return
|
||||
|
||||
@@ -40,36 +40,46 @@
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/diseasesplicer/attack_hand(var/mob/user as mob)
|
||||
if(..()) return
|
||||
ui_interact(user)
|
||||
if(..())
|
||||
return TRUE
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/diseasesplicer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
/obj/machinery/computer/diseasesplicer/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "DiseaseSplicer", name)
|
||||
ui.open()
|
||||
|
||||
var/data[0]
|
||||
/obj/machinery/computer/diseasesplicer/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["dish_inserted"] = !!dish
|
||||
data["growth"] = 0
|
||||
data["affected_species"] = null
|
||||
|
||||
if (memorybank)
|
||||
data["buffer"] = null
|
||||
if(memorybank)
|
||||
data["buffer"] = list("name" = (analysed ? memorybank.effect.name : "Unknown Symptom"), "stage" = memorybank.effect.stage)
|
||||
if (species_buffer)
|
||||
data["species_buffer"] = null
|
||||
if(species_buffer)
|
||||
data["species_buffer"] = analysed ? jointext(species_buffer, ", ") : "Unknown Species"
|
||||
|
||||
if (splicing)
|
||||
data["effects"] = null
|
||||
data["info"] = null
|
||||
data["growth"] = 0
|
||||
data["affected_species"] = null
|
||||
data["busy"] = null
|
||||
if(splicing)
|
||||
data["busy"] = "Splicing..."
|
||||
else if (scanning)
|
||||
else if(scanning)
|
||||
data["busy"] = "Scanning..."
|
||||
else if (burning)
|
||||
else if(burning)
|
||||
data["busy"] = "Copying data to disk..."
|
||||
else if (dish)
|
||||
else if(dish)
|
||||
data["growth"] = min(dish.growth, 100)
|
||||
|
||||
if (dish.virus2)
|
||||
if (dish.virus2.affected_species)
|
||||
data["affected_species"] = dish.analysed ? jointext(dish.virus2.affected_species, ", ") : "Unknown"
|
||||
if(dish.virus2)
|
||||
if(dish.virus2.affected_species)
|
||||
data["affected_species"] = dish.analysed ? dish.virus2.affected_species : list()
|
||||
|
||||
if (dish.growth >= 50)
|
||||
if(dish.growth >= 50)
|
||||
var/list/effects[0]
|
||||
for (var/datum/disease2/effectholder/e in dish.virus2.effects)
|
||||
effects.Add(list(list("name" = (dish.analysed ? e.effect.name : "Unknown"), "stage" = (e.stage), "reference" = "\ref[e]")))
|
||||
@@ -81,11 +91,7 @@
|
||||
else
|
||||
data["info"] = "No dish loaded."
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "disease_splicer.tmpl", src.name, 400, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/diseasesplicer/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
@@ -95,100 +101,94 @@
|
||||
scanning -= 1
|
||||
if(!scanning)
|
||||
ping("\The [src] pings, \"Analysis complete.\"")
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
if(splicing)
|
||||
splicing -= 1
|
||||
if(!splicing)
|
||||
ping("\The [src] pings, \"Splicing operation complete.\"")
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
if(burning)
|
||||
burning -= 1
|
||||
if(!burning)
|
||||
var/obj/item/weapon/diseasedisk/d = new /obj/item/weapon/diseasedisk(src.loc)
|
||||
d.analysed = analysed
|
||||
if(analysed)
|
||||
if (memorybank)
|
||||
if(memorybank)
|
||||
d.name = "[memorybank.effect.name] GNA disk (Stage: [memorybank.effect.stage])"
|
||||
d.effect = memorybank
|
||||
else if (species_buffer)
|
||||
else if(species_buffer)
|
||||
d.name = "[jointext(species_buffer, ", ")] GNA disk"
|
||||
d.species = species_buffer
|
||||
else
|
||||
if (memorybank)
|
||||
if(memorybank)
|
||||
d.name = "Unknown GNA disk (Stage: [memorybank.effect.stage])"
|
||||
d.effect = memorybank
|
||||
else if (species_buffer)
|
||||
else if(species_buffer)
|
||||
d.name = "Unknown Species GNA disk"
|
||||
d.species = species_buffer
|
||||
|
||||
ping("\The [src] pings, \"Backup disk saved.\"")
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/computer/diseasesplicer/Topic(href, href_list)
|
||||
if(..()) return 1
|
||||
/obj/machinery/computer/diseasesplicer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/mob/user = usr
|
||||
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||
add_fingerprint(user)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
switch(action)
|
||||
if("grab")
|
||||
if(dish)
|
||||
memorybank = locate(params["grab"])
|
||||
species_buffer = null
|
||||
analysed = dish.analysed
|
||||
dish = null
|
||||
scanning = 10
|
||||
. = TRUE
|
||||
|
||||
if (href_list["close"])
|
||||
user.unset_machine()
|
||||
ui.close()
|
||||
return 0
|
||||
if("affected_species")
|
||||
if(dish)
|
||||
memorybank = null
|
||||
species_buffer = dish.virus2.affected_species
|
||||
analysed = dish.analysed
|
||||
dish = null
|
||||
scanning = 10
|
||||
. = TRUE
|
||||
|
||||
if (href_list["grab"])
|
||||
if (dish)
|
||||
memorybank = locate(href_list["grab"])
|
||||
species_buffer = null
|
||||
analysed = dish.analysed
|
||||
dish = null
|
||||
scanning = 10
|
||||
return 1
|
||||
if("eject")
|
||||
if(dish)
|
||||
dish.loc = src.loc
|
||||
dish = null
|
||||
. = TRUE
|
||||
|
||||
if (href_list["affected_species"])
|
||||
if (dish)
|
||||
memorybank = null
|
||||
species_buffer = dish.virus2.affected_species
|
||||
analysed = dish.analysed
|
||||
dish = null
|
||||
scanning = 10
|
||||
return 1
|
||||
if("splice")
|
||||
if(dish)
|
||||
var/target = text2num(params["splice"]) // target = 1 to 4 for effects, 5 for species
|
||||
if(memorybank && 0 < target && target <= 4)
|
||||
if(target < memorybank.effect.stage) return // too powerful, catching this for href exploit prevention
|
||||
|
||||
if(href_list["eject"])
|
||||
if (dish)
|
||||
dish.loc = src.loc
|
||||
dish = null
|
||||
return 1
|
||||
var/datum/disease2/effectholder/target_holder
|
||||
var/list/illegal_types = list()
|
||||
for(var/datum/disease2/effectholder/e in dish.virus2.effects)
|
||||
if(e.stage == target)
|
||||
target_holder = e
|
||||
else
|
||||
illegal_types += e.effect.type
|
||||
if(memorybank.effect.type in illegal_types) return
|
||||
target_holder.effect = memorybank.effect
|
||||
|
||||
if(href_list["splice"])
|
||||
if(dish)
|
||||
var/target = text2num(href_list["splice"]) // target = 1 to 4 for effects, 5 for species
|
||||
if(memorybank && 0 < target && target <= 4)
|
||||
if(target < memorybank.effect.stage) return // too powerful, catching this for href exploit prevention
|
||||
else if(species_buffer && target == 5)
|
||||
dish.virus2.affected_species = species_buffer
|
||||
|
||||
var/datum/disease2/effectholder/target_holder
|
||||
var/list/illegal_types = list()
|
||||
for(var/datum/disease2/effectholder/e in dish.virus2.effects)
|
||||
if(e.stage == target)
|
||||
target_holder = e
|
||||
else
|
||||
illegal_types += e.effect.type
|
||||
if(memorybank.effect.type in illegal_types) return
|
||||
target_holder.effect = memorybank.effect
|
||||
else
|
||||
return
|
||||
|
||||
else if(species_buffer && target == 5)
|
||||
dish.virus2.affected_species = species_buffer
|
||||
splicing = 10
|
||||
dish.virus2.uniqueID = rand(0,10000)
|
||||
. = TRUE
|
||||
|
||||
else
|
||||
return
|
||||
if("disk")
|
||||
burning = 10
|
||||
. = TRUE
|
||||
|
||||
splicing = 10
|
||||
dish.virus2.uniqueID = rand(0,10000)
|
||||
return 1
|
||||
|
||||
if(href_list["disk"])
|
||||
burning = 10
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
O.loc = src
|
||||
|
||||
user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!")
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
src.attack_hand(user)
|
||||
return
|
||||
@@ -46,17 +46,23 @@
|
||||
O.loc = src
|
||||
|
||||
user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!")
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
src.attack_hand(user)
|
||||
|
||||
/obj/machinery/disease2/incubator/attack_hand(mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
ui_interact(user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/disease2/incubator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
/obj/machinery/disease2/incubator/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "DishIncubator", name)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/disease2/incubator/tgui_data(mob/user)
|
||||
var/data[0]
|
||||
data["chemicals_inserted"] = !!beaker
|
||||
data["dish_inserted"] = !!dish
|
||||
@@ -74,23 +80,19 @@
|
||||
data["can_breed_virus"] = null
|
||||
data["blood_already_infected"] = null
|
||||
|
||||
if (beaker)
|
||||
if(beaker)
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list
|
||||
data["can_breed_virus"] = dish && dish.virus2 && B
|
||||
|
||||
if (B)
|
||||
if (!B.data["virus2"])
|
||||
if(B)
|
||||
if(!B.data["virus2"])
|
||||
B.data["virus2"] = list()
|
||||
|
||||
var/list/virus = B.data["virus2"]
|
||||
for (var/ID in virus)
|
||||
data["blood_already_infected"] = virus[ID]
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "dish_incubator.tmpl", src.name, 400, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
return data
|
||||
|
||||
/obj/machinery/disease2/incubator/process()
|
||||
if(dish && on && dish.virus2)
|
||||
@@ -105,7 +107,7 @@
|
||||
|
||||
foodsupply -= 1
|
||||
dish.growth += 3
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
if(radiation)
|
||||
if(radiation > 50 & prob(5))
|
||||
@@ -118,90 +120,82 @@
|
||||
else if(prob(5))
|
||||
dish.virus2.minormutate()
|
||||
radiation -= 1
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
if(toxins && prob(5))
|
||||
dish.virus2.infectionchance -= 1
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
if(toxins > 50)
|
||||
dish.growth = 0
|
||||
dish.virus2 = null
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
else if(!dish)
|
||||
on = 0
|
||||
icon_state = "incubator"
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
if(beaker)
|
||||
if(foodsupply < 100 && beaker.reagents.remove_reagent("virusfood",5))
|
||||
if(foodsupply + 10 <= 100)
|
||||
foodsupply += 10
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
if (locate(/datum/reagent/toxin) in beaker.reagents.reagent_list && toxins < 100)
|
||||
if(locate(/datum/reagent/toxin) in beaker.reagents.reagent_list && toxins < 100)
|
||||
for(var/datum/reagent/toxin/T in beaker.reagents.reagent_list)
|
||||
toxins += max(T.strength,1)
|
||||
beaker.reagents.remove_reagent(T.id,1)
|
||||
if(toxins > 100)
|
||||
toxins = 100
|
||||
break
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/disease2/incubator/Topic(href, href_list)
|
||||
if (..()) return 1
|
||||
/obj/machinery/disease2/incubator/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/mob/user = usr
|
||||
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||
add_fingerprint(user)
|
||||
switch(action)
|
||||
if("ejectchem")
|
||||
if(beaker)
|
||||
beaker.loc = src.loc
|
||||
beaker = null
|
||||
. = TRUE
|
||||
|
||||
src.add_fingerprint(user)
|
||||
if("power")
|
||||
if(dish)
|
||||
on = !on
|
||||
icon_state = on ? "incubator_on" : "incubator"
|
||||
. = TRUE
|
||||
|
||||
if (href_list["close"])
|
||||
user.unset_machine()
|
||||
ui.close()
|
||||
return 0
|
||||
if("ejectdish")
|
||||
if(dish)
|
||||
dish.loc = src.loc
|
||||
dish = null
|
||||
. = TRUE
|
||||
|
||||
if (href_list["ejectchem"])
|
||||
if(beaker)
|
||||
beaker.loc = src.loc
|
||||
beaker = null
|
||||
return 1
|
||||
if("rad")
|
||||
radiation = min(100, radiation + 10)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["power"])
|
||||
if (dish)
|
||||
on = !on
|
||||
icon_state = on ? "incubator_on" : "incubator"
|
||||
return 1
|
||||
if("flush")
|
||||
radiation = 0
|
||||
toxins = 0
|
||||
foodsupply = 0
|
||||
. = TRUE
|
||||
|
||||
if (href_list["ejectdish"])
|
||||
if(dish)
|
||||
dish.loc = src.loc
|
||||
dish = null
|
||||
return 1
|
||||
if("virus")
|
||||
if(!dish)
|
||||
return TRUE
|
||||
|
||||
if (href_list["rad"])
|
||||
radiation = min(100, radiation + 10)
|
||||
return 1
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list
|
||||
if(!B)
|
||||
return TRUE
|
||||
|
||||
if (href_list["flush"])
|
||||
radiation = 0
|
||||
toxins = 0
|
||||
foodsupply = 0
|
||||
return 1
|
||||
if(!B.data["virus2"])
|
||||
B.data["virus2"] = list()
|
||||
|
||||
if(href_list["virus"])
|
||||
if (!dish)
|
||||
return 1
|
||||
var/list/virus = list("[dish.virus2.uniqueID]" = dish.virus2.getcopy())
|
||||
B.data["virus2"] += virus
|
||||
|
||||
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list
|
||||
if (!B)
|
||||
return 1
|
||||
|
||||
if (!B.data["virus2"])
|
||||
B.data["virus2"] = list()
|
||||
|
||||
var/list/virus = list("[dish.virus2.uniqueID]" = dish.virus2.getcopy())
|
||||
B.data["virus2"] += virus
|
||||
|
||||
ping("\The [src] pings, \"Injection complete.\"")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
ping("\The [src] pings, \"Injection complete.\"")
|
||||
. = TRUE
|
||||
|
||||
+80
-106
@@ -1,8 +1,3 @@
|
||||
// UI menu navigation
|
||||
#define HOME "home"
|
||||
#define LIST "list"
|
||||
#define ENTRY "entry"
|
||||
|
||||
/obj/machinery/disease2/isolator/
|
||||
name = "pathogenic isolator"
|
||||
desc = "Used to isolate and identify diseases, allowing for comparison with a remote database."
|
||||
@@ -11,9 +6,7 @@
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "isolator"
|
||||
var/isolating = 0
|
||||
var/state = HOME
|
||||
var/datum/disease2/disease/virus2 = null
|
||||
var/datum/data/record/entry = null
|
||||
var/obj/item/weapon/reagent_containers/syringe/sample = null
|
||||
|
||||
/obj/machinery/disease2/isolator/update_icon()
|
||||
@@ -44,71 +37,57 @@
|
||||
S.loc = src
|
||||
|
||||
user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!")
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
update_icon()
|
||||
|
||||
src.attack_hand(user)
|
||||
|
||||
/obj/machinery/disease2/isolator/attack_hand(mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
ui_interact(user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/disease2/isolator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
/obj/machinery/disease2/isolator/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PathogenicIsolator", name)
|
||||
ui.open()
|
||||
|
||||
var/data[0]
|
||||
|
||||
/obj/machinery/disease2/isolator/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["syringe_inserted"] = !!sample
|
||||
data["isolating"] = isolating
|
||||
data["pathogen_pool"] = null
|
||||
data["state"] = state
|
||||
data["entry"] = entry
|
||||
data["can_print"] = (state != HOME || sample) && !isolating
|
||||
data["can_print"] = !isolating
|
||||
|
||||
switch (state)
|
||||
if (HOME)
|
||||
if (sample)
|
||||
var/list/pathogen_pool[0]
|
||||
for(var/datum/reagent/blood/B in sample.reagents.reagent_list)
|
||||
var/list/virus = B.data["virus2"]
|
||||
for (var/ID in virus)
|
||||
var/datum/disease2/disease/V = virus[ID]
|
||||
var/datum/data/record/R = null
|
||||
if (ID in virusDB)
|
||||
R = virusDB[ID]
|
||||
var/list/pathogen_pool = list()
|
||||
if(sample)
|
||||
for(var/datum/reagent/blood/B in sample.reagents.reagent_list)
|
||||
var/list/virus = B.data["virus2"]
|
||||
for (var/ID in virus)
|
||||
var/datum/disease2/disease/V = virus[ID]
|
||||
var/datum/data/record/R = null
|
||||
if (ID in virusDB)
|
||||
R = virusDB[ID]
|
||||
|
||||
var/mob/living/carbon/human/D = B.data["donor"]
|
||||
pathogen_pool.Add(list(list(\
|
||||
"name" = "[D.get_species()] [B.name]", \
|
||||
"dna" = B.data["blood_DNA"], \
|
||||
"unique_id" = V.uniqueID, \
|
||||
"reference" = "\ref[V]", \
|
||||
"is_in_database" = !!R, \
|
||||
"record" = "\ref[R]")))
|
||||
var/mob/living/carbon/human/D = B.data["donor"]
|
||||
pathogen_pool.Add(list(list(\
|
||||
"name" = "[D.get_species()] [B.name]", \
|
||||
"dna" = B.data["blood_DNA"], \
|
||||
"unique_id" = V.uniqueID, \
|
||||
"reference" = "\ref[V]", \
|
||||
"is_in_database" = !!R, \
|
||||
"record" = "\ref[R]")))
|
||||
data["pathogen_pool"] = pathogen_pool
|
||||
|
||||
if (pathogen_pool.len > 0)
|
||||
data["pathogen_pool"] = pathogen_pool
|
||||
|
||||
if (LIST)
|
||||
var/list/db[0]
|
||||
for (var/ID in virusDB)
|
||||
var/datum/data/record/r = virusDB[ID]
|
||||
db.Add(list(list("name" = r.fields["name"], "record" = "\ref[r]")))
|
||||
|
||||
if (db.len > 0)
|
||||
data["database"] = db
|
||||
|
||||
if (ENTRY)
|
||||
if (entry)
|
||||
var/desc = entry.fields["description"]
|
||||
data["entry"] = list(\
|
||||
"name" = entry.fields["name"], \
|
||||
"description" = replacetext(desc, "\n", ""))
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "pathogenic_isolator.tmpl", src.name, 400, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
var/list/db = list()
|
||||
for(var/ID in virusDB)
|
||||
var/datum/data/record/r = virusDB[ID]
|
||||
db.Add(list(list("name" = r.fields["name"], "record" = "\ref[r]")))
|
||||
data["database"] = db
|
||||
data["modal"] = tgui_modal_data(src)
|
||||
return data
|
||||
|
||||
/obj/machinery/disease2/isolator/process()
|
||||
if (isolating > 0)
|
||||
@@ -120,62 +99,54 @@
|
||||
virus2 = null
|
||||
ping("\The [src] pings, \"Viral strain isolated.\"")
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
SStgui.update_uis(src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/disease2/isolator/Topic(href, href_list)
|
||||
if (..()) return 1
|
||||
/obj/machinery/disease2/isolator/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/mob/user = usr
|
||||
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||
add_fingerprint(user)
|
||||
|
||||
. = TRUE
|
||||
switch(tgui_modal_act(src, action, params))
|
||||
if(TGUI_MODAL_ANSWER)
|
||||
return
|
||||
|
||||
src.add_fingerprint(user)
|
||||
switch(action)
|
||||
if("view_entry")
|
||||
var/datum/data/record/v = locate(params["vir"])
|
||||
if(!istype(v))
|
||||
return FALSE
|
||||
tgui_modal_message(src, "virus", "", null, v.fields["tgui_description"])
|
||||
return TRUE
|
||||
|
||||
if (href_list["close"])
|
||||
user.unset_machine()
|
||||
ui.close()
|
||||
return 0
|
||||
if("print")
|
||||
print(user, params)
|
||||
return TRUE
|
||||
|
||||
if (href_list[HOME])
|
||||
state = HOME
|
||||
return 1
|
||||
if("isolate")
|
||||
var/datum/disease2/disease/V = locate(params["isolate"])
|
||||
if (V)
|
||||
virus2 = V
|
||||
isolating = 20
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
if (href_list[LIST])
|
||||
state = LIST
|
||||
return 1
|
||||
|
||||
if (href_list[ENTRY])
|
||||
if (istype(locate(href_list["view"]), /datum/data/record))
|
||||
entry = locate(href_list["view"])
|
||||
|
||||
state = ENTRY
|
||||
return 1
|
||||
|
||||
if (href_list["print"])
|
||||
print(user)
|
||||
return 1
|
||||
|
||||
if(!sample) return 1
|
||||
|
||||
if (href_list["isolate"])
|
||||
var/datum/disease2/disease/V = locate(href_list["isolate"])
|
||||
if (V)
|
||||
virus2 = V
|
||||
isolating = 20
|
||||
if("eject")
|
||||
if(!sample)
|
||||
return FALSE
|
||||
sample.forceMove(loc)
|
||||
sample = null
|
||||
update_icon()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if (href_list["eject"])
|
||||
sample.loc = src.loc
|
||||
sample = null
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/disease2/isolator/proc/print(var/mob/user)
|
||||
/obj/machinery/disease2/isolator/proc/print(mob/user, list/params)
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc)
|
||||
|
||||
switch (state)
|
||||
if (HOME)
|
||||
switch(params["type"])
|
||||
if("patient_diagnosis")
|
||||
if (!sample) return
|
||||
P.name = "paper - Patient Diagnostic Report"
|
||||
P.info = {"
|
||||
@@ -207,7 +178,7 @@
|
||||
<u>Additional Notes:</u>
|
||||
"}
|
||||
|
||||
if (LIST)
|
||||
if("virus_list")
|
||||
P.name = "paper - Virus List"
|
||||
P.info = {"
|
||||
[virology_letterhead("Virus List")]
|
||||
@@ -225,11 +196,14 @@
|
||||
<u>Additional Notes:</u>
|
||||
"}
|
||||
|
||||
if (ENTRY)
|
||||
if("virus_record")
|
||||
var/datum/data/record/v = locate(params["vir"])
|
||||
if(!istype(v))
|
||||
return FALSE
|
||||
P.name = "paper - Viral Profile"
|
||||
P.info = {"
|
||||
[virology_letterhead("Viral Profile")]
|
||||
[entry.fields["description"]]
|
||||
[v.fields["description"]]
|
||||
<hr>
|
||||
<u>Additional Notes:</u>
|
||||
"}
|
||||
|
||||
Reference in New Issue
Block a user