mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
Fix silly stuff
This commit is contained in:
22
code/controllers/subsystems/nanoui.dm
Normal file
22
code/controllers/subsystems/nanoui.dm
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
SUBSYSTEM_DEF(nanoui)
|
||||||
|
name = "NanoUI"
|
||||||
|
wait = 5
|
||||||
|
flags = SS_NO_INIT
|
||||||
|
// a list of current open /nanoui UIs, grouped by src_object and ui_key
|
||||||
|
var/list/open_uis = list()
|
||||||
|
// a list of current open /nanoui UIs, not grouped, for use in processing
|
||||||
|
var/list/processing_uis = list()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/nanoui/Recover()
|
||||||
|
if(SSnanoui.open_uis)
|
||||||
|
open_uis |= SSnanoui.open_uis
|
||||||
|
if(SSnanoui.processing_uis)
|
||||||
|
processing_uis |= SSnanoui.processing_uis
|
||||||
|
|
||||||
|
/datum/controller/subsystem/nanoui/stat_entry()
|
||||||
|
return ..("[processing_uis.len] UIs")
|
||||||
|
|
||||||
|
/datum/controller/subsystem/nanoui/fire(resumed)
|
||||||
|
for(var/thing in processing_uis)
|
||||||
|
var/datum/nanoui/UI = thing
|
||||||
|
UI.process()
|
||||||
@@ -29,7 +29,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
|||||||
job_description = "The Site Manager manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \
|
job_description = "The Site Manager manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \
|
||||||
they do not understand everything, and are expected to delegate tasks to the appropriate crew member. The Site Manager is expected to \
|
they do not understand everything, and are expected to delegate tasks to the appropriate crew member. The Site Manager is expected to \
|
||||||
have an understanding of Standard Operating Procedure, and is subject to it, and legal action, in the same way as every other crew member."
|
have an understanding of Standard Operating Procedure, and is subject to it, and legal action, in the same way as every other crew member."
|
||||||
alt_titles = list("Overseer"= /datum/alt_title/overseer)
|
alt_titles = list("Overseer"= /datum/alt_title/overseer,"Colony Director"= /datum/alt_title/colonydirector) //CHOMPEdit
|
||||||
|
|
||||||
//YW UNCOMMENTINGSTART: REINSTATE LOYALTY IMPLANT
|
//YW UNCOMMENTINGSTART: REINSTATE LOYALTY IMPLANT
|
||||||
/datum/job/captain/equip(var/mob/living/carbon/human/H)
|
/datum/job/captain/equip(var/mob/living/carbon/human/H)
|
||||||
@@ -46,7 +46,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
|||||||
// Captain Alt Titles
|
// Captain Alt Titles
|
||||||
/datum/alt_title/overseer
|
/datum/alt_title/overseer
|
||||||
title = "Overseer"
|
title = "Overseer"
|
||||||
|
/datum/alt_title/colonydirector //CHOMPEdit
|
||||||
|
title = "Colony Director" //CHOMPEdit
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Head of Personnel
|
// Head of Personnel
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ var/list/assistant_occupations = list(
|
|||||||
|
|
||||||
|
|
||||||
var/list/command_positions = list(
|
var/list/command_positions = list(
|
||||||
"Colony Director",
|
"Site Manager",
|
||||||
"Head of Personnel",
|
"Head of Personnel",
|
||||||
"Head of Security",
|
"Head of Security",
|
||||||
"Chief Engineer",
|
"Chief Engineer",
|
||||||
@@ -136,7 +136,7 @@ var/list/nonhuman_positions = list(
|
|||||||
)
|
)
|
||||||
|
|
||||||
var/list/whitelisted_positions = list(
|
var/list/whitelisted_positions = list(
|
||||||
"Colony Director",
|
"Site Manager",
|
||||||
"Head of Personnel",
|
"Head of Personnel",
|
||||||
"Head of Security",
|
"Head of Security",
|
||||||
"Chief Engineer",
|
"Chief Engineer",
|
||||||
|
|||||||
@@ -233,10 +233,6 @@
|
|||||||
else
|
else
|
||||||
to_chat(usr, "<span class='warning'>Cannot issue pass without issuing ID.</span>")
|
to_chat(usr, "<span class='warning'>Cannot issue pass without issuing ID.</span>")
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
add_fingerprint(usr)
|
add_fingerprint(usr)
|
||||||
return TRUE
|
return TRUE
|
||||||
=======
|
|
||||||
src.add_fingerprint(usr)
|
|
||||||
SSnanoui.update_uis(src)
|
|
||||||
>>>>>>> master-holder
|
|
||||||
|
|||||||
952
code/game/objects/items/devices/communicator/cartridge.dm
Normal file
952
code/game/objects/items/devices/communicator/cartridge.dm
Normal file
@@ -0,0 +1,952 @@
|
|||||||
|
// Communicator peripheral devices
|
||||||
|
// Internal devices that attack() can be relayed to
|
||||||
|
// Additional UI menus for added functionality
|
||||||
|
/obj/item/weapon/commcard
|
||||||
|
name = "generic commcard"
|
||||||
|
desc = "A peripheral plug-in for personal communicators."
|
||||||
|
icon = 'icons/obj/pda.dmi'
|
||||||
|
icon_state = "cart"
|
||||||
|
item_state = "electronic"
|
||||||
|
w_class = ITEMSIZE_TINY
|
||||||
|
|
||||||
|
var/list/internal_devices = list() // Devices that can be toggled on to trigger on attack()
|
||||||
|
var/list/active_devices = list() // Devices that will be triggered on attack()
|
||||||
|
var/list/ui_templates = list() // List of ui templates the commcard can access
|
||||||
|
var/list/internal_data = list() // Data that shouldn't be updated every time nanoUI updates, or needs to persist between updates
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/proc/get_device_status()
|
||||||
|
var/list/L = list()
|
||||||
|
var/i = 1
|
||||||
|
for(var/obj/I in internal_devices)
|
||||||
|
if(I in active_devices)
|
||||||
|
L[++L.len] = list("name" = "\proper[I.name]", "active" = 1, "index" = i++)
|
||||||
|
else
|
||||||
|
L[++L.len] = list("name" = I.name, "active" = 0, "index" = i++)
|
||||||
|
return L
|
||||||
|
|
||||||
|
|
||||||
|
// cartridge.get_data() returns a list of tuples:
|
||||||
|
// The field element is the tag used to access the information by the template
|
||||||
|
// The value element is the actual data, and can take any form necessary for the template
|
||||||
|
/obj/item/weapon/commcard/proc/get_data()
|
||||||
|
return list()
|
||||||
|
|
||||||
|
// Handles cartridge-specific functions
|
||||||
|
// The helper.link() MUST HAVE 'cartridge_topic' passed into the href in order for cartridge functions to be processed.
|
||||||
|
// Doesn't matter what the value of it is for now, it's just a flag to say, "Hey, there's cartridge data to change!"
|
||||||
|
/obj/item/weapon/commcard/Topic(href, href_list)
|
||||||
|
|
||||||
|
// Signalers
|
||||||
|
if(href_list["signaler_target"])
|
||||||
|
|
||||||
|
var/obj/item/device/assembly/signaler/S = locate(href_list["signaler_target"]) // Should locate the correct signaler
|
||||||
|
|
||||||
|
if(!istype(S)) // Ref is no longer valid
|
||||||
|
return
|
||||||
|
|
||||||
|
if(S.loc != src) // No longer within the cartridge
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(href_list["signaler_action"])
|
||||||
|
if("Pulse")
|
||||||
|
S.activate()
|
||||||
|
|
||||||
|
if("Edit")
|
||||||
|
var/mob/user = locate(href_list["user"])
|
||||||
|
if(!istype(user)) // Ref no longer valid
|
||||||
|
return
|
||||||
|
|
||||||
|
var/newVal = input(user, "Input a new [href_list["signaler_value"]].", href_list["signaler_value"], (href_list["signaler_value"] == "Code" ? S.code : S.frequency)) as num|null
|
||||||
|
if(newVal)
|
||||||
|
switch(href_list["signaler_value"])
|
||||||
|
if("Code")
|
||||||
|
S.code = newVal
|
||||||
|
|
||||||
|
if("Frequency")
|
||||||
|
S.frequency = newVal
|
||||||
|
|
||||||
|
// Refresh list of powernet sensors
|
||||||
|
if(href_list["powernet_refresh"])
|
||||||
|
internal_data["grid_sensors"] = find_powernet_sensors()
|
||||||
|
|
||||||
|
// Load apc's on targeted powernet
|
||||||
|
if(href_list["powernet_target"])
|
||||||
|
internal_data["powernet_target"] = href_list["powernet_target"]
|
||||||
|
|
||||||
|
// GPS units
|
||||||
|
if(href_list["gps_target"])
|
||||||
|
var/obj/item/device/gps/G = locate(href_list["gps_target"])
|
||||||
|
|
||||||
|
if(!istype(G)) // Ref is no longer valid
|
||||||
|
return
|
||||||
|
|
||||||
|
if(G.loc != src) // No longer within the cartridge
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(href_list["gps_action"])
|
||||||
|
if("Power")
|
||||||
|
G.tracking = text2num(href_list["value"])
|
||||||
|
|
||||||
|
if("Long_Range")
|
||||||
|
G.local_mode = text2num(href_list["value"])
|
||||||
|
|
||||||
|
if("Hide_Signal")
|
||||||
|
G.hide_signal = text2num(href_list["value"])
|
||||||
|
|
||||||
|
if("Tag")
|
||||||
|
var/mob/user = locate(href_list["user"])
|
||||||
|
if(!istype(user)) // Ref no longer valid
|
||||||
|
return
|
||||||
|
|
||||||
|
var/newTag = input(user, "Please enter desired tag.", G.tag) as text|null
|
||||||
|
|
||||||
|
if(newTag)
|
||||||
|
G.tag = newTag
|
||||||
|
|
||||||
|
if(href_list["active_category"])
|
||||||
|
internal_data["supply_category"] = href_list["active_category"]
|
||||||
|
|
||||||
|
// Supply topic
|
||||||
|
// Copied from /obj/machinery/computer/supplycomp/Topic()
|
||||||
|
// code\game\machinery\computer\supply.dm, line 188
|
||||||
|
// Unfortunately, in order to support complete functionality, the whole thing is necessary
|
||||||
|
if(href_list["pack_ref"])
|
||||||
|
var/datum/supply_pack/S = locate(href_list["pack_ref"])
|
||||||
|
|
||||||
|
// Invalid ref
|
||||||
|
if(!istype(S))
|
||||||
|
return
|
||||||
|
|
||||||
|
// Expand the supply pack's contents
|
||||||
|
if(href_list["expand"])
|
||||||
|
internal_data["supply_pack_expanded"] ^= S
|
||||||
|
|
||||||
|
// Make a request for the pack
|
||||||
|
if(href_list["request"])
|
||||||
|
var/mob/user = locate(href_list["user"])
|
||||||
|
if(!istype(user)) // Invalid ref
|
||||||
|
return
|
||||||
|
|
||||||
|
if(world.time < internal_data["supply_reqtime"])
|
||||||
|
visible_message("<span class='warning'>[src] flashes, \"[internal_data["supply_reqtime"] - world.time] seconds remaining until another requisition form may be printed.\"</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/timeout = world.time + 600
|
||||||
|
var/reason = sanitize(input(user, "Reason:","Why do you require this item?","") as null|text)
|
||||||
|
if(world.time > timeout)
|
||||||
|
to_chat(user, "<span class='warning'>Error. Request timed out.</span>")
|
||||||
|
return
|
||||||
|
if(!reason)
|
||||||
|
return
|
||||||
|
|
||||||
|
SSsupply.create_order(S, user, reason)
|
||||||
|
internal_data["supply_reqtime"] = (world.time + 5) % 1e5
|
||||||
|
|
||||||
|
if(href_list["order_ref"])
|
||||||
|
var/datum/supply_order/O = locate(href_list["order_ref"])
|
||||||
|
|
||||||
|
// Invalid ref
|
||||||
|
if(!istype(O))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/mob/user = locate(href_list["user"])
|
||||||
|
if(!istype(user)) // Invalid ref
|
||||||
|
return
|
||||||
|
|
||||||
|
if(href_list["edit"])
|
||||||
|
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
|
||||||
|
if(!new_val)
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(href_list["edit"])
|
||||||
|
if("Supply Pack")
|
||||||
|
O.name = new_val
|
||||||
|
|
||||||
|
if("Cost")
|
||||||
|
var/num = text2num(new_val)
|
||||||
|
if(num)
|
||||||
|
O.cost = num
|
||||||
|
|
||||||
|
if("Index")
|
||||||
|
var/num = text2num(new_val)
|
||||||
|
if(num)
|
||||||
|
O.index = num
|
||||||
|
|
||||||
|
if("Reason")
|
||||||
|
O.comment = new_val
|
||||||
|
|
||||||
|
if("Ordered by")
|
||||||
|
O.ordered_by = new_val
|
||||||
|
|
||||||
|
if("Ordered at")
|
||||||
|
O.ordered_at = new_val
|
||||||
|
|
||||||
|
if("Approved by")
|
||||||
|
O.approved_by = new_val
|
||||||
|
|
||||||
|
if("Approved at")
|
||||||
|
O.approved_at = new_val
|
||||||
|
|
||||||
|
if(href_list["approve"])
|
||||||
|
SSsupply.approve_order(O, user)
|
||||||
|
|
||||||
|
if(href_list["deny"])
|
||||||
|
SSsupply.deny_order(O, user)
|
||||||
|
|
||||||
|
if(href_list["delete"])
|
||||||
|
SSsupply.delete_order(O, user)
|
||||||
|
|
||||||
|
if(href_list["clear_all_requests"])
|
||||||
|
var/mob/user = locate(href_list["user"])
|
||||||
|
if(!istype(user)) // Invalid ref
|
||||||
|
return
|
||||||
|
|
||||||
|
SSsupply.deny_all_pending(user)
|
||||||
|
|
||||||
|
if(href_list["export_ref"])
|
||||||
|
var/datum/exported_crate/E = locate(href_list["export_ref"])
|
||||||
|
|
||||||
|
// Invalid ref
|
||||||
|
if(!istype(E))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/mob/user = locate(href_list["user"])
|
||||||
|
if(!istype(user)) // Invalid ref
|
||||||
|
return
|
||||||
|
|
||||||
|
if(href_list["index"])
|
||||||
|
var/list/L = E.contents[href_list["index"]]
|
||||||
|
|
||||||
|
if(href_list["edit"])
|
||||||
|
var/field = alert(user, "Select which field to edit", , "Name", "Quantity", "Value")
|
||||||
|
|
||||||
|
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
|
||||||
|
if(!new_val)
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(field)
|
||||||
|
if("Name")
|
||||||
|
L["object"] = new_val
|
||||||
|
|
||||||
|
if("Quantity")
|
||||||
|
var/num = text2num(new_val)
|
||||||
|
if(num)
|
||||||
|
L["quantity"] = num
|
||||||
|
|
||||||
|
if("Value")
|
||||||
|
var/num = text2num(new_val)
|
||||||
|
if(num)
|
||||||
|
L["value"] = num
|
||||||
|
|
||||||
|
if(href_list["delete"])
|
||||||
|
E.contents.Cut(href_list["index"], href_list["index"] + 1)
|
||||||
|
|
||||||
|
// Else clause means they're editing/deleting the whole export report, rather than a specific item in it
|
||||||
|
else if(href_list["edit"])
|
||||||
|
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
|
||||||
|
if(!new_val)
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(href_list["edit"])
|
||||||
|
if("Name")
|
||||||
|
E.name = new_val
|
||||||
|
|
||||||
|
if("Value")
|
||||||
|
var/num = text2num(new_val)
|
||||||
|
if(num)
|
||||||
|
E.value = num
|
||||||
|
|
||||||
|
else if(href_list["delete"])
|
||||||
|
SSsupply.delete_export(E, user)
|
||||||
|
|
||||||
|
else if(href_list["add_item"])
|
||||||
|
SSsupply.add_export_item(E, user)
|
||||||
|
|
||||||
|
if(SSsupply && SSsupply.shuttle)
|
||||||
|
switch(href_list["send_shuttle"])
|
||||||
|
if("send_away")
|
||||||
|
if(SSsupply.shuttle.forbidden_atoms_check())
|
||||||
|
to_chat(usr, "<span class='warning'>For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.</span>")
|
||||||
|
else
|
||||||
|
SSsupply.shuttle.launch(src)
|
||||||
|
to_chat(usr, "<span class='notice'>Initiating launch sequence.</span>")
|
||||||
|
|
||||||
|
if("send_to_station")
|
||||||
|
SSsupply.shuttle.launch(src)
|
||||||
|
to_chat(usr, "<span class='notice'>The supply shuttle has been called and will arrive in approximately [round(SSsupply.movetime/600,1)] minutes.</span>")
|
||||||
|
|
||||||
|
if("cancel_shuttle")
|
||||||
|
SSsupply.shuttle.cancel_launch(src)
|
||||||
|
|
||||||
|
if("force_shuttle")
|
||||||
|
SSsupply.shuttle.force_launch(src)
|
||||||
|
|
||||||
|
// Status display
|
||||||
|
switch(href_list["stat_display"])
|
||||||
|
if("message")
|
||||||
|
post_status("message", internal_data["stat_display_line1"], internal_data["stat_display_line2"])
|
||||||
|
internal_data["stat_display_special"] = "message"
|
||||||
|
if("alert")
|
||||||
|
post_status("alert", href_list["alert"])
|
||||||
|
internal_data["stat_display_special"] = href_list["alert"]
|
||||||
|
if("setmsg")
|
||||||
|
internal_data["stat_display_line[href_list["line"]]"] = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", internal_data["stat_display_line[href_list["line"]]"]) as text|null, 40), 40)
|
||||||
|
else
|
||||||
|
post_status(href_list["stat_display"])
|
||||||
|
internal_data["stat_display_special"] = href_list["stat_display"]
|
||||||
|
|
||||||
|
// Merc shuttle blast door controls
|
||||||
|
switch(href_list["all_blast_doors"])
|
||||||
|
if("open")
|
||||||
|
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
|
||||||
|
B.open()
|
||||||
|
if("close")
|
||||||
|
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
|
||||||
|
B.close()
|
||||||
|
|
||||||
|
if(href_list["scan_blast_doors"])
|
||||||
|
internal_data["shuttle_doors"] = find_blast_doors()
|
||||||
|
|
||||||
|
if(href_list["toggle_blast_door"])
|
||||||
|
var/obj/machinery/door/blast/B = locate(href_list["toggle_blast_door"])
|
||||||
|
if(!B)
|
||||||
|
return
|
||||||
|
spawn(0)
|
||||||
|
if(B.density)
|
||||||
|
B.open()
|
||||||
|
else
|
||||||
|
B.close()
|
||||||
|
|
||||||
|
|
||||||
|
// Updates status displays with a new message
|
||||||
|
// Copied from /obj/item/weapon/cartridge/proc/post_status(),
|
||||||
|
// code/game/objects/items/devices/PDA/cart.dm, line 251
|
||||||
|
/obj/item/weapon/commcard/proc/post_status(var/command, var/data1, var/data2)
|
||||||
|
var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435)
|
||||||
|
if(!frequency)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/datum/signal/status_signal = new
|
||||||
|
status_signal.source = src
|
||||||
|
status_signal.transmission_method = TRANSMISSION_RADIO
|
||||||
|
status_signal.data["command"] = command
|
||||||
|
|
||||||
|
switch(command)
|
||||||
|
if("message")
|
||||||
|
status_signal.data["msg1"] = data1
|
||||||
|
status_signal.data["msg2"] = data2
|
||||||
|
internal_data["stat_display_active1"] = data1 // Update the internally stored message, we won't get receive_signal if we're the sender
|
||||||
|
internal_data["stat_display_active2"] = data2
|
||||||
|
if(loc)
|
||||||
|
var/obj/item/PDA = loc
|
||||||
|
var/mob/user = PDA.fingerprintslast
|
||||||
|
log_admin("STATUS: [user] set status screen with [src]. Message: [data1] [data2]")
|
||||||
|
message_admins("STATUS: [user] set status screen with [src]. Message: [data1] [data2]")
|
||||||
|
|
||||||
|
if("alert")
|
||||||
|
status_signal.data["picture_state"] = data1
|
||||||
|
|
||||||
|
frequency.post_signal(src, status_signal)
|
||||||
|
|
||||||
|
// Receives updates by external devices to the status displays
|
||||||
|
/obj/item/weapon/commcard/receive_signal(var/datum/signal/signal, var/receive_method, var/receive_param)
|
||||||
|
internal_data["stat_display_special"] = signal.data["command"]
|
||||||
|
switch(signal.data["command"])
|
||||||
|
if("message")
|
||||||
|
internal_data["stat_display_active1"] = signal.data["msg1"]
|
||||||
|
internal_data["stat_display_active2"] = signal.data["msg2"]
|
||||||
|
if("alert")
|
||||||
|
internal_data["stat_display_special"] = signal.data["picture_state"]
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// SUBTYPES
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
// Engineering Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Halogen Counter
|
||||||
|
// Templates
|
||||||
|
// *- Power Monitor
|
||||||
|
/obj/item/weapon/commcard/engineering
|
||||||
|
name = "\improper Power-ON cartridge"
|
||||||
|
icon_state = "cart-e"
|
||||||
|
ui_templates = list(list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl"))
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/engineering/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/halogen_counter(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/engineering/Initialize()
|
||||||
|
internal_data["grid_sensors"] = find_powernet_sensors()
|
||||||
|
internal_data["powernet_target"] = ""
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/engineering/get_data()
|
||||||
|
return list(
|
||||||
|
list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list()),
|
||||||
|
list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Atmospherics Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Gas scanner
|
||||||
|
/obj/item/weapon/commcard/atmos
|
||||||
|
name = "\improper BreatheDeep cartridge"
|
||||||
|
icon_state = "cart-a"
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/atmos/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/analyzer(src)
|
||||||
|
|
||||||
|
|
||||||
|
// Medical Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Halogen Counter
|
||||||
|
// *- Health Analyzer
|
||||||
|
// Templates
|
||||||
|
// *- Medical Records
|
||||||
|
/obj/item/weapon/commcard/medical
|
||||||
|
name = "\improper Med-U cartridge"
|
||||||
|
icon_state = "cart-m"
|
||||||
|
ui_templates = list(list("name" = "Medical Records", "template" = "med_records.tmpl"))
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/medical/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/healthanalyzer(src)
|
||||||
|
internal_devices |= new /obj/item/device/halogen_counter(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/medical/get_data()
|
||||||
|
return list(list("field" = "med_records", "value" = get_med_records()))
|
||||||
|
|
||||||
|
|
||||||
|
// Chemistry Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Halogen Counter
|
||||||
|
// *- Health Analyzer
|
||||||
|
// *- Reagent Scanner
|
||||||
|
// Templates
|
||||||
|
// *- Medical Records
|
||||||
|
/obj/item/weapon/commcard/medical/chemistry
|
||||||
|
name = "\improper ChemWhiz cartridge"
|
||||||
|
icon_state = "cart-chem"
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/medical/chemistry/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/reagent_scanner(src)
|
||||||
|
|
||||||
|
|
||||||
|
// Detective Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Halogen Counter
|
||||||
|
// *- Health Analyzer
|
||||||
|
// Templates
|
||||||
|
// *- Medical Records
|
||||||
|
// *- Security Records
|
||||||
|
/obj/item/weapon/commcard/medical/detective
|
||||||
|
name = "\improper D.E.T.E.C.T. cartridge"
|
||||||
|
icon_state = "cart-s"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Medical Records", "template" = "med_records.tmpl"),
|
||||||
|
list("name" = "Security Records", "template" = "sec_records.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/medical/detective/get_data()
|
||||||
|
var/list/data = ..()
|
||||||
|
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
// Internal Affairs Cartridge:
|
||||||
|
// Templates
|
||||||
|
// *- Security Records
|
||||||
|
// *- Employment Records
|
||||||
|
/obj/item/weapon/commcard/int_aff
|
||||||
|
name = "\improper P.R.O.V.E. cartridge"
|
||||||
|
icon_state = "cart-s"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
|
||||||
|
list("name" = "Security Records", "template" = "sec_records.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/int_aff/get_data()
|
||||||
|
return list(
|
||||||
|
list("field" = "emp_records", "value" = get_emp_records()),
|
||||||
|
list("field" = "sec_records", "value" = get_sec_records())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Security Cartridge:
|
||||||
|
// Templates
|
||||||
|
// *- Security Records
|
||||||
|
// *- Security Bot Access
|
||||||
|
/obj/item/weapon/commcard/security
|
||||||
|
name = "\improper R.O.B.U.S.T. cartridge"
|
||||||
|
icon_state = "cart-s"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Security Records", "template" = "sec_records.tmpl"),
|
||||||
|
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/security/get_data()
|
||||||
|
return list(
|
||||||
|
list("field" = "sec_records", "value" = get_sec_records()),
|
||||||
|
list("field" = "sec_bot_access", "value" = get_sec_bot_access())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Janitor Cartridge:
|
||||||
|
// Templates
|
||||||
|
// *- Janitorial Locator Magicbox
|
||||||
|
/obj/item/weapon/commcard/janitor
|
||||||
|
name = "\improper CustodiPRO cartridge"
|
||||||
|
desc = "The ultimate in clean-room design."
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/janitor/get_data()
|
||||||
|
return list(
|
||||||
|
list("field" = "janidata", "value" = get_janitorial_locations())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Signal Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Signaler
|
||||||
|
// Templates
|
||||||
|
// *- Signaler Access
|
||||||
|
/obj/item/weapon/commcard/signal
|
||||||
|
name = "generic signaler cartridge"
|
||||||
|
desc = "A data cartridge with an integrated radio signaler module."
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/signal/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/assembly/signaler(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/signal/get_data()
|
||||||
|
return list(
|
||||||
|
list("field" = "signaler_access", "value" = get_int_signalers())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Science Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Signaler
|
||||||
|
// *- Reagent Scanner
|
||||||
|
// *- Gas Scanner
|
||||||
|
// Templates
|
||||||
|
// *- Signaler Access
|
||||||
|
/obj/item/weapon/commcard/signal/science
|
||||||
|
name = "\improper Signal Ace 2 cartridge"
|
||||||
|
desc = "Complete with integrated radio signaler!"
|
||||||
|
icon_state = "cart-tox"
|
||||||
|
// UI templates inherited
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/signal/science/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/reagent_scanner(src)
|
||||||
|
internal_devices |= new /obj/item/device/analyzer(src)
|
||||||
|
|
||||||
|
|
||||||
|
// Supply Cartridge:
|
||||||
|
// Templates
|
||||||
|
// *- Supply Records
|
||||||
|
/obj/item/weapon/commcard/supply
|
||||||
|
name = "\improper Space Parts & Space Vendors cartridge"
|
||||||
|
desc = "Perfect for the Quartermaster on the go!"
|
||||||
|
icon_state = "cart-q"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Supply Records", "template" = "supply_records.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/supply/New()
|
||||||
|
..()
|
||||||
|
internal_data["supply_category"] = null
|
||||||
|
internal_data["supply_controls"] = FALSE // Cannot control the supply shuttle, cannot accept orders
|
||||||
|
internal_data["supply_pack_expanded"] = list()
|
||||||
|
internal_data["supply_reqtime"] = -1
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/supply/get_data()
|
||||||
|
// Supply records data
|
||||||
|
var/list/shuttle_status = get_supply_shuttle_status()
|
||||||
|
var/list/orders = get_supply_orders()
|
||||||
|
var/list/receipts = get_supply_receipts()
|
||||||
|
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
|
||||||
|
var/list/pack_list = list() // List of supply packs within the currently selected category
|
||||||
|
|
||||||
|
if(internal_data["supply_category"])
|
||||||
|
pack_list = get_supply_pack_list()
|
||||||
|
|
||||||
|
return list(
|
||||||
|
list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"]),
|
||||||
|
list("field" = "order_auth", "value" = misc_supply_data["order_auth"]),
|
||||||
|
list("field" = "supply_points", "value" = misc_supply_data["supply_points"]),
|
||||||
|
list("field" = "categories", "value" = misc_supply_data["supply_categories"]),
|
||||||
|
list("field" = "contraband", "value" = misc_supply_data["contraband"]),
|
||||||
|
list("field" = "active_category", "value" = internal_data["supply_category"]),
|
||||||
|
list("field" = "shuttle", "value" = shuttle_status),
|
||||||
|
list("field" = "orders", "value" = orders),
|
||||||
|
list("field" = "receipts", "value" = receipts),
|
||||||
|
list("field" = "supply_packs", "value" = pack_list)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Command Cartridge:
|
||||||
|
// Templates
|
||||||
|
// *- Status Display Access
|
||||||
|
// *- Employment Records
|
||||||
|
/obj/item/weapon/commcard/head
|
||||||
|
name = "\improper Easy-Record DELUXE"
|
||||||
|
icon_state = "cart-h"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/New()
|
||||||
|
..()
|
||||||
|
internal_data["stat_display_line1"] = null
|
||||||
|
internal_data["stat_display_line2"] = null
|
||||||
|
internal_data["stat_display_active1"] = null
|
||||||
|
internal_data["stat_display_active2"] = null
|
||||||
|
internal_data["stat_display_special"] = null
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/Initialize()
|
||||||
|
// Have to register the commcard with the Radio controller to receive updates to the status displays
|
||||||
|
radio_controller.add_object(src, 1435)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/Destroy()
|
||||||
|
// Have to unregister the commcard for proper bookkeeping
|
||||||
|
radio_controller.remove_object(src, 1435)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/get_data()
|
||||||
|
return list(
|
||||||
|
list("field" = "emp_records", "value" = get_emp_records()),
|
||||||
|
list("field" = "stat_display", "value" = get_status_display())
|
||||||
|
)
|
||||||
|
|
||||||
|
// Head of Personnel Cartridge:
|
||||||
|
// Templates
|
||||||
|
// *- Status Display Access
|
||||||
|
// *- Employment Records
|
||||||
|
// *- Security Records
|
||||||
|
// *- Supply Records
|
||||||
|
// ?- Supply Bot Access
|
||||||
|
// *- Janitorial Locator Magicbox
|
||||||
|
/obj/item/weapon/commcard/head/hop
|
||||||
|
name = "\improper HumanResources9001 cartridge"
|
||||||
|
icon_state = "cart-h"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
|
||||||
|
list("name" = "Security Records", "template" = "sec_records.tmpl"),
|
||||||
|
list("name" = "Supply Records", "template" = "supply_records.tmpl"),
|
||||||
|
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/hop/get_data()
|
||||||
|
var/list/data = ..()
|
||||||
|
|
||||||
|
// Sec records
|
||||||
|
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
|
||||||
|
|
||||||
|
// Supply records data
|
||||||
|
var/list/shuttle_status = get_supply_shuttle_status()
|
||||||
|
var/list/orders = get_supply_orders()
|
||||||
|
var/list/receipts = get_supply_receipts()
|
||||||
|
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
|
||||||
|
var/list/pack_list = list() // List of supply packs within the currently selected category
|
||||||
|
|
||||||
|
if(internal_data["supply_category"])
|
||||||
|
pack_list = get_supply_pack_list()
|
||||||
|
|
||||||
|
data[++data.len] = list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"])
|
||||||
|
data[++data.len] = list("field" = "order_auth", "value" = misc_supply_data["order_auth"])
|
||||||
|
data[++data.len] = list("field" = "supply_points", "value" = misc_supply_data["supply_points"])
|
||||||
|
data[++data.len] = list("field" = "categories", "value" = misc_supply_data["supply_categories"])
|
||||||
|
data[++data.len] = list("field" = "contraband", "value" = misc_supply_data["contraband"])
|
||||||
|
data[++data.len] = list("field" = "active_category", "value" = internal_data["supply_category"])
|
||||||
|
data[++data.len] = list("field" = "shuttle", "value" = shuttle_status)
|
||||||
|
data[++data.len] = list("field" = "orders", "value" = orders)
|
||||||
|
data[++data.len] = list("field" = "receipts", "value" = receipts)
|
||||||
|
data[++data.len] = list("field" = "supply_packs", "value" = pack_list)
|
||||||
|
|
||||||
|
// Janitorial locator magicbox
|
||||||
|
data[++data.len] = list("field" = "janidata", "value" = get_janitorial_locations())
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
// Head of Security Cartridge:
|
||||||
|
// Templates
|
||||||
|
// *- Status Display Access
|
||||||
|
// *- Employment Records
|
||||||
|
// *- Security Records
|
||||||
|
// *- Security Bot Access
|
||||||
|
/obj/item/weapon/commcard/head/hos
|
||||||
|
name = "\improper R.O.B.U.S.T. DELUXE"
|
||||||
|
icon_state = "cart-hos"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
|
||||||
|
list("name" = "Security Records", "template" = "sec_records.tmpl"),
|
||||||
|
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/hos/get_data()
|
||||||
|
var/list/data = ..()
|
||||||
|
// Sec records
|
||||||
|
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
|
||||||
|
// Sec bot access
|
||||||
|
data[++data.len] = list("field" = "sec_bot_access", "value" = get_sec_bot_access())
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
// Research Director Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Signaler
|
||||||
|
// *- Gas Scanner
|
||||||
|
// *- Reagent Scanner
|
||||||
|
// Templates
|
||||||
|
// *- Status Display Access
|
||||||
|
// *- Employment Records
|
||||||
|
// *- Signaler Access
|
||||||
|
/obj/item/weapon/commcard/head/rd
|
||||||
|
name = "\improper Signal Ace DELUXE"
|
||||||
|
icon_state = "cart-rd"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
|
||||||
|
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/rd/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/analyzer(src)
|
||||||
|
internal_devices |= new /obj/item/device/reagent_scanner(src)
|
||||||
|
internal_devices |= new /obj/item/device/assembly/signaler(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/rd/get_data()
|
||||||
|
var/list/data = ..()
|
||||||
|
// Signaler access
|
||||||
|
data[++data.len] = list("field" = "signaler_access", "value" = get_int_signalers())
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
// Chief Medical Officer Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Health Analyzer
|
||||||
|
// *- Reagent Scanner
|
||||||
|
// *- Halogen Counter
|
||||||
|
// Templates
|
||||||
|
// *- Status Display Access
|
||||||
|
// *- Employment Records
|
||||||
|
// *- Medical Records
|
||||||
|
/obj/item/weapon/commcard/head/cmo
|
||||||
|
name = "\improper Med-U DELUXE"
|
||||||
|
icon_state = "cart-cmo"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
|
||||||
|
list("name" = "Medical Records", "template" = "med_records.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/cmo/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/healthanalyzer(src)
|
||||||
|
internal_devices |= new /obj/item/device/reagent_scanner(src)
|
||||||
|
internal_devices |= new /obj/item/device/halogen_counter(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/cmo/get_data()
|
||||||
|
var/list/data = ..()
|
||||||
|
// Med records
|
||||||
|
data[++data.len] = list("field" = "med_records", "value" = get_med_records())
|
||||||
|
return data
|
||||||
|
|
||||||
|
// Chief Engineer Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Gas Scanner
|
||||||
|
// *- Halogen Counter
|
||||||
|
// Templates
|
||||||
|
// *- Status Display Access
|
||||||
|
// *- Employment Records
|
||||||
|
// *- Power Monitoring
|
||||||
|
/obj/item/weapon/commcard/head/ce
|
||||||
|
name = "\improper Power-On DELUXE"
|
||||||
|
icon_state = "cart-ce"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
|
||||||
|
list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/ce/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj.item/device/analyzer(src)
|
||||||
|
internal_devices |= new /obj/item/device/halogen_counter(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/ce/Initialize()
|
||||||
|
internal_data["grid_sensors"] = find_powernet_sensors()
|
||||||
|
internal_data["powernet_target"] = ""
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/ce/get_data()
|
||||||
|
var/list/data = ..()
|
||||||
|
// Add power monitoring data
|
||||||
|
data[++data.len] = list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list())
|
||||||
|
data[++data.len] = list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
// Captain Cartridge:
|
||||||
|
// Devices
|
||||||
|
// *- Health analyzer
|
||||||
|
// *- Gas Scanner
|
||||||
|
// *- Reagent Scanner
|
||||||
|
// *- Halogen Counter
|
||||||
|
// X- GPS - Balance
|
||||||
|
// *- Signaler
|
||||||
|
// Templates
|
||||||
|
// *- Status Display Access
|
||||||
|
// *- Employment Records
|
||||||
|
// *- Medical Records
|
||||||
|
// *- Security Records
|
||||||
|
// *- Power Monitoring
|
||||||
|
// *- Supply Records
|
||||||
|
// X- Supply Bot Access - Mulebots usually break when used
|
||||||
|
// *- Security Bot Access
|
||||||
|
// *- Janitorial Locator Magicbox
|
||||||
|
// X- GPS Access - Balance
|
||||||
|
// *- Signaler Access
|
||||||
|
/obj/item/weapon/commcard/head/captain
|
||||||
|
name = "\improper Value-PAK cartridge"
|
||||||
|
desc = "Now with 200% more value!"
|
||||||
|
icon_state = "cart-c"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
|
||||||
|
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
|
||||||
|
list("name" = "Medical Records", "template" = "med_records.tmpl"),
|
||||||
|
list("name" = "Security Records", "template" = "sec_records.tmpl"),
|
||||||
|
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl"),
|
||||||
|
list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl"),
|
||||||
|
list("name" = "Supply Records", "template" = "supply_records.tmpl"),
|
||||||
|
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl"),
|
||||||
|
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/captain/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj.item/device/analyzer(src)
|
||||||
|
internal_devices |= new /obj/item/device/healthanalyzer(src)
|
||||||
|
internal_devices |= new /obj/item/device/reagent_scanner(src)
|
||||||
|
internal_devices |= new /obj/item/device/halogen_counter(src)
|
||||||
|
internal_devices |= new /obj/item/device/assembly/signaler(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/head/captain/get_data()
|
||||||
|
var/list/data = ..()
|
||||||
|
//Med records
|
||||||
|
data[++data.len] = list("field" = "med_records", "value" = get_med_records())
|
||||||
|
|
||||||
|
// Sec records
|
||||||
|
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
|
||||||
|
|
||||||
|
// Sec bot access
|
||||||
|
data[++data.len] = list("field" = "sec_bot_access", "value" = get_sec_bot_access())
|
||||||
|
|
||||||
|
// Power Monitoring
|
||||||
|
data[++data.len] = list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list())
|
||||||
|
data[++data.len] = list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
|
||||||
|
|
||||||
|
// Supply records data
|
||||||
|
var/list/shuttle_status = get_supply_shuttle_status()
|
||||||
|
var/list/orders = get_supply_orders()
|
||||||
|
var/list/receipts = get_supply_receipts()
|
||||||
|
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
|
||||||
|
var/list/pack_list = list() // List of supply packs within the currently selected category
|
||||||
|
|
||||||
|
if(internal_data["supply_category"])
|
||||||
|
pack_list = get_supply_pack_list()
|
||||||
|
|
||||||
|
data[++data.len] = list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"])
|
||||||
|
data[++data.len] = list("field" = "order_auth", "value" = misc_supply_data["order_auth"])
|
||||||
|
data[++data.len] = list("field" = "supply_points", "value" = misc_supply_data["supply_points"])
|
||||||
|
data[++data.len] = list("field" = "categories", "value" = misc_supply_data["supply_categories"])
|
||||||
|
data[++data.len] = list("field" = "contraband", "value" = misc_supply_data["contraband"])
|
||||||
|
data[++data.len] = list("field" = "active_category", "value" = internal_data["supply_category"])
|
||||||
|
data[++data.len] = list("field" = "shuttle", "value" = shuttle_status)
|
||||||
|
data[++data.len] = list("field" = "orders", "value" = orders)
|
||||||
|
data[++data.len] = list("field" = "receipts", "value" = receipts)
|
||||||
|
data[++data.len] = list("field" = "supply_packs", "value" = pack_list)
|
||||||
|
|
||||||
|
// Janitorial locator magicbox
|
||||||
|
data[++data.len] = list("field" = "janidata", "value" = get_janitorial_locations())
|
||||||
|
|
||||||
|
// Signaler access
|
||||||
|
data[++data.len] = list("field" = "signaler_access", "value" = get_int_signalers())
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
// Mercenary Cartridge
|
||||||
|
// Templates
|
||||||
|
// *- Merc Shuttle Door Controller
|
||||||
|
/obj/item/weapon/commcard/mercenary
|
||||||
|
name = "\improper Detomatix cartridge"
|
||||||
|
icon_state = "cart"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Shuttle Blast Door Control", "template" = "merc_blast_door_control.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/mercenary/Initialize()
|
||||||
|
internal_data["shuttle_door_code"] = "smindicate" // Copied from PDA code
|
||||||
|
internal_data["shuttle_doors"] = find_blast_doors()
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/mercenary/get_data()
|
||||||
|
var/door_status[0]
|
||||||
|
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
|
||||||
|
door_status[++door_status.len] += list(
|
||||||
|
"open" = B.density,
|
||||||
|
"name" = B.name,
|
||||||
|
"ref" = "\ref[B]"
|
||||||
|
)
|
||||||
|
|
||||||
|
return list(
|
||||||
|
list("field" = "blast_door", "value" = door_status)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Explorer Cartridge
|
||||||
|
// Devices
|
||||||
|
// *- GPS
|
||||||
|
// Templates
|
||||||
|
// *- GPS Access
|
||||||
|
|
||||||
|
// IMPORTANT: NOT MAPPED IN DUE TO BALANCE CONCERNS RE: FINDING THE VICTIMS OF ANTAGS.
|
||||||
|
// See suit sensors, specifically ease of turning them off, and variable level of settings which may or may not give location
|
||||||
|
// A GPS in your phone that is either broadcasting position or totally off, and can be hidden in pockets, coats, bags, boxes, etc, is much harder to disable
|
||||||
|
/obj/item/weapon/commcard/explorer
|
||||||
|
name = "\improper Explorator cartridge"
|
||||||
|
icon_state = "cart-tox"
|
||||||
|
ui_templates = list(
|
||||||
|
list("name" = "Integrated GPS", "template" = "gps_access.tmpl")
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/explorer/New()
|
||||||
|
..()
|
||||||
|
internal_devices |= new /obj/item/device/gps/explorer(src)
|
||||||
|
|
||||||
|
/obj/item/weapon/commcard/explorer/get_data()
|
||||||
|
var/list/GPS = get_GPS_lists()
|
||||||
|
|
||||||
|
return list(
|
||||||
|
list("field" = "gps_access", "value" = GPS[1]),
|
||||||
|
list("field" = "gps_signal", "value" = GPS[2]),
|
||||||
|
list("field" = "gps_status", "value" = GPS[3])
|
||||||
|
)
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
drop_sound = 'sound/items/drop/axe.ogg'
|
drop_sound = 'sound/items/drop/axe.ogg'
|
||||||
pickup_sound = 'sound/items/pickup/axe.ogg'
|
pickup_sound = 'sound/items/pickup/axe.ogg'
|
||||||
|
|
||||||
var/material/material //CHOMPEDIT: Start, To make tiles have material variables
|
var/datum/material/material //CHOMPEDIT: Start, To make tiles have material variables
|
||||||
var/default_type = DEFAULT_WALL_MATERIAL
|
var/default_type = DEFAULT_WALL_MATERIAL
|
||||||
var/perunit = SHEET_MATERIAL_AMOUNT
|
var/perunit = SHEET_MATERIAL_AMOUNT
|
||||||
var/apply_colour //CHOMPEDIT: End
|
var/apply_colour //CHOMPEDIT: End
|
||||||
|
|||||||
@@ -17,4 +17,4 @@
|
|||||||
display_name = "AR-B glasses (CD, HoP, BSG)"
|
display_name = "AR-B glasses (CD, HoP, BSG)"
|
||||||
path = /obj/item/clothing/glasses/omnihud/all
|
path = /obj/item/clothing/glasses/omnihud/all
|
||||||
cost = 2
|
cost = 2
|
||||||
allowed_roles = list("Colony Director","Head of Personnel","Blueshield Guard")
|
allowed_roles = list("Site Manager","Head of Personnel","Blueshield Guard")
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
/datum/gear/uniform/job_nullsuit/cmd
|
/datum/gear/uniform/job_nullsuit/cmd
|
||||||
display_name = "nullsuit, cmd"
|
display_name = "nullsuit, cmd"
|
||||||
path = /obj/item/clothing/under/rank/nullsuit/cmd
|
path = /obj/item/clothing/under/rank/nullsuit/cmd
|
||||||
allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard")
|
allowed_roles = list("Head of Security","Site Manager","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer","Blueshield Guard")
|
||||||
|
|
||||||
/datum/gear/uniform/job_nullsuit/sec
|
/datum/gear/uniform/job_nullsuit/sec
|
||||||
display_name = "nullsuit, sec"
|
display_name = "nullsuit, sec"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<<<<<<< HEAD
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//Glasses
|
//Glasses
|
||||||
/*
|
/*
|
||||||
@@ -33,7 +32,9 @@ BLIND // can't see anything
|
|||||||
|
|
||||||
sprite_sheets = list(
|
sprite_sheets = list(
|
||||||
"Teshari" = 'icons/mob/species/seromi/eyes.dmi',
|
"Teshari" = 'icons/mob/species/seromi/eyes.dmi',
|
||||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||||
|
"Sergal" = 'icons/mob/species/sergal/eyes_yw.dmi',
|
||||||
|
SPECIES_GREY_YW = 'icons/mob/species/grey/eyes.dmi'/*ywedit*/
|
||||||
)
|
)
|
||||||
|
|
||||||
/obj/item/clothing/glasses/update_clothing_icon()
|
/obj/item/clothing/glasses/update_clothing_icon()
|
||||||
@@ -543,529 +544,4 @@ BLIND // can't see anything
|
|||||||
name = "optical thermal implants"
|
name = "optical thermal implants"
|
||||||
desc = "A set of implantable lenses designed to augment your vision"
|
desc = "A set of implantable lenses designed to augment your vision"
|
||||||
icon_state = "thermalimplants"
|
icon_state = "thermalimplants"
|
||||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
||||||
=======
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//Glasses
|
|
||||||
/*
|
|
||||||
SEE_SELF // can see self, no matter what
|
|
||||||
SEE_MOBS // can see all mobs, no matter what
|
|
||||||
SEE_OBJS // can see all objs, no matter what
|
|
||||||
SEE_TURFS // can see all turfs (and areas), no matter what
|
|
||||||
SEE_PIXELS// if an object is located on an unlit area, but some of its pixels are
|
|
||||||
// in a lit area (via pixel_x,y or smooth movement), can see those pixels
|
|
||||||
BLIND // can't see anything
|
|
||||||
*/
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses
|
|
||||||
name = "glasses"
|
|
||||||
icon = 'icons/obj/clothing/glasses.dmi'
|
|
||||||
w_class = ITEMSIZE_SMALL
|
|
||||||
slot_flags = SLOT_EYES
|
|
||||||
plane_slots = list(slot_glasses)
|
|
||||||
var/vision_flags = 0
|
|
||||||
var/darkness_view = 0//Base human is 2
|
|
||||||
var/see_invisible = -1
|
|
||||||
var/prescription = 0
|
|
||||||
var/toggleable = 0
|
|
||||||
var/off_state = "degoggles"
|
|
||||||
var/active = 1
|
|
||||||
var/activation_sound = 'sound/items/goggles_charge.ogg'
|
|
||||||
var/obj/screen/overlay = null
|
|
||||||
var/list/away_planes //Holder for disabled planes
|
|
||||||
drop_sound = 'sound/items/drop/accessory.ogg'
|
|
||||||
pickup_sound = 'sound/items/pickup/accessory.ogg'
|
|
||||||
|
|
||||||
sprite_sheets = list(
|
|
||||||
"Teshari" = 'icons/mob/species/seromi/eyes.dmi',
|
|
||||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
|
||||||
"Sergal" = 'icons/mob/species/sergal/eyes_yw.dmi',
|
|
||||||
SPECIES_GREY_YW = 'icons/mob/species/grey/eyes.dmi'/*ywedit*/
|
|
||||||
)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/update_clothing_icon()
|
|
||||||
if (ismob(src.loc))
|
|
||||||
var/mob/M = src.loc
|
|
||||||
M.update_inv_glasses()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/proc/can_toggle(mob/living/user)
|
|
||||||
if(!toggleable)
|
|
||||||
return FALSE
|
|
||||||
|
|
||||||
// Prevent people from just turning their goggles back on.
|
|
||||||
if(!active && (vision_flags & (SEE_TURFS|SEE_OBJS)))
|
|
||||||
var/area/A = get_area(src)
|
|
||||||
if(A.no_spoilers)
|
|
||||||
return FALSE
|
|
||||||
|
|
||||||
return TRUE
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/proc/toggle_active(mob/living/user)
|
|
||||||
if(active)
|
|
||||||
active = FALSE
|
|
||||||
icon_state = off_state
|
|
||||||
user.update_inv_glasses()
|
|
||||||
flash_protection = FLASH_PROTECTION_NONE
|
|
||||||
tint = TINT_NONE
|
|
||||||
away_planes = enables_planes
|
|
||||||
enables_planes = null
|
|
||||||
|
|
||||||
else
|
|
||||||
active = TRUE
|
|
||||||
icon_state = initial(icon_state)
|
|
||||||
user.update_inv_glasses()
|
|
||||||
flash_protection = initial(flash_protection)
|
|
||||||
tint = initial(tint)
|
|
||||||
enables_planes = away_planes
|
|
||||||
away_planes = null
|
|
||||||
user.update_action_buttons()
|
|
||||||
user.recalculate_vis()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/attack_self(mob/user)
|
|
||||||
if(toggleable)
|
|
||||||
if(!can_toggle(user))
|
|
||||||
to_chat(user, span("warning", "You don't seem to be able to toggle \the [src] here."))
|
|
||||||
else
|
|
||||||
toggle_active(user)
|
|
||||||
if(active)
|
|
||||||
to_chat(user, span("notice", "You activate the optical matrix on the [src]."))
|
|
||||||
else
|
|
||||||
to_chat(user, span("notice", "You deactivate the optical matrix on the [src]."))
|
|
||||||
..()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/meson
|
|
||||||
name = "optical meson scanner"
|
|
||||||
desc = "Used for seeing walls, floors, and stuff through anything."
|
|
||||||
icon_state = "meson"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson")
|
|
||||||
action_button_name = "Toggle Goggles"
|
|
||||||
origin_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
|
|
||||||
toggleable = 1
|
|
||||||
vision_flags = SEE_TURFS
|
|
||||||
enables_planes = list(VIS_FULLBRIGHT, VIS_MESONS)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/meson/New()
|
|
||||||
..()
|
|
||||||
overlay = global_hud.meson
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/meson/prescription
|
|
||||||
name = "prescription mesons"
|
|
||||||
desc = "Optical Meson Scanner with prescription lenses."
|
|
||||||
prescription = 1
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/meson/aviator
|
|
||||||
name = "engineering aviators"
|
|
||||||
icon_state = "aviator_eng"
|
|
||||||
off_state = "aviator"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
|
||||||
action_button_name = "Toggle HUD"
|
|
||||||
activation_sound = 'sound/effects/pop.ogg'
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/meson/aviator/prescription
|
|
||||||
name = "prescription engineering aviators"
|
|
||||||
desc = "Engineering Aviators with prescription lenses."
|
|
||||||
prescription = 1
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/hud/health/aviator
|
|
||||||
name = "medical HUD aviators"
|
|
||||||
desc = "Modified aviator glasses with a toggled health HUD."
|
|
||||||
icon_state = "aviator_med"
|
|
||||||
off_state = "aviator"
|
|
||||||
action_button_name = "Toggle Mode"
|
|
||||||
toggleable = 1
|
|
||||||
activation_sound = 'sound/effects/pop.ogg'
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/hud/health/aviator/prescription
|
|
||||||
name = "prescription medical HUD aviators"
|
|
||||||
desc = "Modified aviator glasses with a toggled health HUD. Comes with bonus prescription lenses."
|
|
||||||
prescription = 6
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/science
|
|
||||||
name = "Science Goggles"
|
|
||||||
desc = "The goggles do nothing!"
|
|
||||||
icon_state = "purple"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
toggleable = 1
|
|
||||||
action_button_name = "Toggle Goggles"
|
|
||||||
item_flags = AIRTIGHT
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/science/New()
|
|
||||||
..()
|
|
||||||
overlay = global_hud.science
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/goggles
|
|
||||||
name = "goggles"
|
|
||||||
desc = "Just some plain old goggles."
|
|
||||||
icon_state = "plaingoggles"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
item_flags = AIRTIGHT
|
|
||||||
body_parts_covered = EYES
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/night
|
|
||||||
name = "night vision goggles"
|
|
||||||
desc = "You can totally see in the dark now!"
|
|
||||||
icon_state = "night"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
origin_tech = list(TECH_MAGNET = 2)
|
|
||||||
darkness_view = 7
|
|
||||||
toggleable = 1
|
|
||||||
action_button_name = "Toggle Goggles"
|
|
||||||
off_state = "denight"
|
|
||||||
flash_protection = FLASH_PROTECTION_REDUCED
|
|
||||||
enables_planes = list(VIS_FULLBRIGHT)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/night/vox
|
|
||||||
name = "Alien Optics"
|
|
||||||
species_restricted = list("Vox")
|
|
||||||
flags = PHORONGUARD
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/night/New()
|
|
||||||
..()
|
|
||||||
overlay = global_hud.nvg
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/eyepatch
|
|
||||||
name = "eyepatch"
|
|
||||||
desc = "Yarr."
|
|
||||||
icon_state = "eyepatch"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold")
|
|
||||||
body_parts_covered = 0
|
|
||||||
var/eye = null
|
|
||||||
drop_sound = 'sound/items/drop/gloves.ogg'
|
|
||||||
pickup_sound = 'sound/items/pickup/gloves.ogg'
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/eyepatch/verb/switcheye()
|
|
||||||
set name = "Switch Eyepatch"
|
|
||||||
set category = "Object"
|
|
||||||
set src in usr
|
|
||||||
if(!istype(usr, /mob/living)) return
|
|
||||||
if(usr.stat) return
|
|
||||||
|
|
||||||
eye = !eye
|
|
||||||
if(eye)
|
|
||||||
icon_state = "[icon_state]_1"
|
|
||||||
else
|
|
||||||
icon_state = initial(icon_state)
|
|
||||||
update_clothing_icon()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/monocle
|
|
||||||
name = "monocle"
|
|
||||||
desc = "Such a dapper eyepiece!"
|
|
||||||
icon_state = "monocle"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "headset", slot_l_hand_str = "headset")
|
|
||||||
body_parts_covered = 0
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/material
|
|
||||||
name = "optical material scanner"
|
|
||||||
desc = "Very confusing glasses."
|
|
||||||
icon_state = "material"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3)
|
|
||||||
toggleable = 1
|
|
||||||
action_button_name = "Toggle Goggles"
|
|
||||||
vision_flags = SEE_OBJS
|
|
||||||
enables_planes = list(VIS_FULLBRIGHT)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/material/New()
|
|
||||||
..()
|
|
||||||
overlay = global_hud.material
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/material/prescription
|
|
||||||
name = "prescription optical material scanner"
|
|
||||||
prescription = 1
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/graviton
|
|
||||||
name = "graviton goggles"
|
|
||||||
desc = "The secrets of space travel are.. not quite yours."
|
|
||||||
icon_state = "grav"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
origin_tech = list(TECH_MAGNET = 2, TECH_BLUESPACE = 1)
|
|
||||||
darkness_view = 5
|
|
||||||
toggleable = 1
|
|
||||||
action_button_name = "Toggle Goggles"
|
|
||||||
off_state = "denight"
|
|
||||||
vision_flags = SEE_OBJS | SEE_TURFS
|
|
||||||
flash_protection = FLASH_PROTECTION_REDUCED
|
|
||||||
enables_planes = list(VIS_FULLBRIGHT, VIS_MESONS)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/graviton/New()
|
|
||||||
..()
|
|
||||||
overlay = global_hud.material
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/regular
|
|
||||||
name = "prescription glasses"
|
|
||||||
desc = "Made by Nerd. Co."
|
|
||||||
icon_state = "glasses"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
prescription = 1
|
|
||||||
body_parts_covered = 0
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/regular/scanners
|
|
||||||
name = "scanning goggles"
|
|
||||||
desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it."
|
|
||||||
icon_state = "uzenwa_sissra_1"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/regular/hipster
|
|
||||||
name = "prescription glasses"
|
|
||||||
desc = "Made by Uncool. Co."
|
|
||||||
icon_state = "hipster_glasses"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/threedglasses
|
|
||||||
desc = "A long time ago, people used these glasses to makes images from screens threedimensional."
|
|
||||||
name = "3D glasses"
|
|
||||||
icon_state = "3d"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
body_parts_covered = 0
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/gglasses
|
|
||||||
name = "green glasses"
|
|
||||||
desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme."
|
|
||||||
icon_state = "gglasses"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
body_parts_covered = 0
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/regular/rimless
|
|
||||||
name = "prescription rimless glasses"
|
|
||||||
desc = "Sleek modern glasses with a single sculpted lens."
|
|
||||||
icon_state = "glasses_rimless"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/rimless
|
|
||||||
name = "rimless glasses"
|
|
||||||
desc = "Sleek modern glasses with a single sculpted lens."
|
|
||||||
icon_state = "glasses_rimless"
|
|
||||||
prescription = 0
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/regular/thin
|
|
||||||
name = "prescription thin-rimmed glasses"
|
|
||||||
desc = "Glasses with frames are so last century."
|
|
||||||
icon_state = "glasses_thin"
|
|
||||||
prescription = 1
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thin
|
|
||||||
name = "thin-rimmed glasses"
|
|
||||||
desc = "Glasses with frames are so last century."
|
|
||||||
icon_state = "glasses_thin"
|
|
||||||
prescription = 0
|
|
||||||
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses
|
|
||||||
name = "sunglasses"
|
|
||||||
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes."
|
|
||||||
icon_state = "sun"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
|
||||||
darkness_view = -1
|
|
||||||
flash_protection = FLASH_PROTECTION_MODERATE
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/aviator
|
|
||||||
name = "aviators"
|
|
||||||
desc = "A pair of designer sunglasses."
|
|
||||||
icon_state = "aviator"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/welding
|
|
||||||
name = "welding goggles"
|
|
||||||
desc = "Protects the eyes from welders, approved by the mad scientist association."
|
|
||||||
icon_state = "welding-g"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "welding-g", slot_l_hand_str = "welding-g")
|
|
||||||
action_button_name = "Flip Welding Goggles"
|
|
||||||
matter = list(DEFAULT_WALL_MATERIAL = 1500, "glass" = 1000)
|
|
||||||
item_flags = AIRTIGHT
|
|
||||||
var/up = 0
|
|
||||||
flash_protection = FLASH_PROTECTION_MAJOR
|
|
||||||
tint = TINT_HEAVY
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/welding/attack_self()
|
|
||||||
toggle()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/welding/verb/toggle()
|
|
||||||
set category = "Object"
|
|
||||||
set name = "Adjust welding goggles"
|
|
||||||
set src in usr
|
|
||||||
|
|
||||||
if(usr.canmove && !usr.stat && !usr.restrained())
|
|
||||||
if(src.up)
|
|
||||||
src.up = !src.up
|
|
||||||
flags_inv |= HIDEEYES
|
|
||||||
body_parts_covered |= EYES
|
|
||||||
icon_state = initial(icon_state)
|
|
||||||
flash_protection = initial(flash_protection)
|
|
||||||
tint = initial(tint)
|
|
||||||
to_chat(usr, "You flip \the [src] down to protect your eyes.")
|
|
||||||
else
|
|
||||||
src.up = !src.up
|
|
||||||
flags_inv &= ~HIDEEYES
|
|
||||||
body_parts_covered &= ~EYES
|
|
||||||
icon_state = "[initial(icon_state)]up"
|
|
||||||
flash_protection = FLASH_PROTECTION_NONE
|
|
||||||
tint = TINT_NONE
|
|
||||||
to_chat(usr, "You push \the [src] up out of your face.")
|
|
||||||
update_clothing_icon()
|
|
||||||
usr.update_action_buttons()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/welding/superior
|
|
||||||
name = "superior welding goggles"
|
|
||||||
desc = "Welding goggles made from more expensive materials, strangely smells like potatoes."
|
|
||||||
icon_state = "rwelding-g"
|
|
||||||
tint = TINT_MODERATE
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/blindfold
|
|
||||||
name = "blindfold"
|
|
||||||
desc = "Covers the eyes, preventing sight."
|
|
||||||
icon_state = "blindfold"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold")
|
|
||||||
flash_protection = FLASH_PROTECTION_MAJOR
|
|
||||||
tint = BLIND
|
|
||||||
drop_sound = 'sound/items/drop/gloves.ogg'
|
|
||||||
pickup_sound = 'sound/items/pickup/gloves.ogg'
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/blindfold/tape
|
|
||||||
name = "length of tape"
|
|
||||||
desc = "It's a robust DIY blindfold!"
|
|
||||||
icon = 'icons/obj/bureaucracy.dmi'
|
|
||||||
icon_state = "tape_cross"
|
|
||||||
item_state_slots = list(slot_r_hand_str = null, slot_l_hand_str = null)
|
|
||||||
w_class = ITEMSIZE_TINY
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/prescription
|
|
||||||
name = "prescription sunglasses"
|
|
||||||
prescription = 1
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/big
|
|
||||||
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks many flashes."
|
|
||||||
icon_state = "bigsunglasses"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/fakesunglasses //Sunglasses without flash immunity
|
|
||||||
name = "stylish sunglasses"
|
|
||||||
desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes."
|
|
||||||
icon_state = "sun"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/fakesunglasses/aviator
|
|
||||||
name = "stylish aviators"
|
|
||||||
desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes."
|
|
||||||
icon_state = "aviator"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/sechud
|
|
||||||
name = "\improper HUD sunglasses"
|
|
||||||
desc = "Sunglasses with a HUD."
|
|
||||||
icon_state = "sunSecHud"
|
|
||||||
enables_planes = list(VIS_CH_ID,VIS_CH_WANTED,VIS_CH_IMPTRACK,VIS_CH_IMPLOYAL,VIS_CH_IMPCHEM)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/sechud/tactical
|
|
||||||
name = "tactical HUD"
|
|
||||||
desc = "Flash-resistant goggles with inbuilt combat and security information."
|
|
||||||
icon_state = "swatgoggles"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/sechud/aviator
|
|
||||||
name = "security HUD aviators"
|
|
||||||
desc = "Modified aviator glasses that can be switch between HUD and flash protection modes."
|
|
||||||
icon_state = "aviator_sec"
|
|
||||||
off_state = "aviator"
|
|
||||||
action_button_name = "Toggle Mode"
|
|
||||||
var/on = 1
|
|
||||||
toggleable = 1
|
|
||||||
activation_sound = 'sound/effects/pop.ogg'
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/sechud/aviator/attack_self(mob/user)
|
|
||||||
if(toggleable && !user.incapacitated())
|
|
||||||
on = !on
|
|
||||||
if(on)
|
|
||||||
flash_protection = FLASH_PROTECTION_NONE
|
|
||||||
enables_planes = away_planes
|
|
||||||
away_planes = null
|
|
||||||
to_chat(usr, "You switch the [src] to HUD mode.")
|
|
||||||
else
|
|
||||||
flash_protection = initial(flash_protection)
|
|
||||||
away_planes = enables_planes
|
|
||||||
enables_planes = null
|
|
||||||
to_chat(usr, "You switch \the [src] to flash protection mode.")
|
|
||||||
update_icon()
|
|
||||||
user << activation_sound
|
|
||||||
user.recalculate_vis()
|
|
||||||
user.update_inv_glasses()
|
|
||||||
user.update_action_buttons()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/sechud/aviator/update_icon()
|
|
||||||
if(on)
|
|
||||||
icon_state = initial(icon_state)
|
|
||||||
else
|
|
||||||
icon_state = off_state
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/sechud/aviator/prescription
|
|
||||||
name = "prescription security HUD aviators"
|
|
||||||
desc = "Modified aviator glasses that can be switch between HUD and flash protection modes. Comes with bonus prescription lenses."
|
|
||||||
prescription = 6
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/sunglasses/medhud
|
|
||||||
name = "\improper HUD sunglasses"
|
|
||||||
desc = "Sunglasses with a HUD."
|
|
||||||
icon_state = "sunMedHud"
|
|
||||||
enables_planes = list(VIS_CH_STATUS,VIS_CH_HEALTH)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thermal
|
|
||||||
name = "optical thermal scanner"
|
|
||||||
desc = "Thermals in the shape of glasses."
|
|
||||||
icon_state = "thermal"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses")
|
|
||||||
origin_tech = list(TECH_MAGNET = 3)
|
|
||||||
toggleable = 1
|
|
||||||
action_button_name = "Toggle Goggles"
|
|
||||||
vision_flags = SEE_MOBS
|
|
||||||
enables_planes = list(VIS_FULLBRIGHT, VIS_CLOAKED)
|
|
||||||
flash_protection = FLASH_PROTECTION_REDUCED
|
|
||||||
|
|
||||||
emp_act(severity)
|
|
||||||
if(istype(src.loc, /mob/living/carbon/human))
|
|
||||||
var/mob/living/carbon/human/M = src.loc
|
|
||||||
to_chat(M, "<font color='red'>The Optical Thermal Scanner overloads and blinds you!</font>")
|
|
||||||
if(M.glasses == src)
|
|
||||||
M.Blind(3)
|
|
||||||
M.eye_blurry = 5
|
|
||||||
// Don't cure being nearsighted
|
|
||||||
if(!(M.disabilities & NEARSIGHTED))
|
|
||||||
M.disabilities |= NEARSIGHTED
|
|
||||||
spawn(100)
|
|
||||||
M.disabilities &= ~NEARSIGHTED
|
|
||||||
..()
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thermal/New()
|
|
||||||
..()
|
|
||||||
overlay = global_hud.thermal
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete
|
|
||||||
name = "optical meson scanner"
|
|
||||||
desc = "Used for seeing walls, floors, and stuff through anything."
|
|
||||||
icon_state = "meson"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson")
|
|
||||||
origin_tech = list(TECH_MAGNET = 3, TECH_ILLEGAL = 4)
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thermal/plain
|
|
||||||
toggleable = 0
|
|
||||||
activation_sound = null
|
|
||||||
action_button_name = null
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thermal/plain/monocle
|
|
||||||
name = "thermonocle"
|
|
||||||
desc = "A monocle thermal."
|
|
||||||
icon_state = "thermoncle"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
|
||||||
toggleable = 1
|
|
||||||
action_button_name = "Toggle Monocle"
|
|
||||||
flags = null //doesn't protect eyes because it's a monocle, duh
|
|
||||||
|
|
||||||
body_parts_covered = 0
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thermal/plain/eyepatch
|
|
||||||
name = "optical thermal eyepatch"
|
|
||||||
desc = "An eyepatch with built-in thermal optics"
|
|
||||||
icon_state = "eyepatch"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold")
|
|
||||||
body_parts_covered = 0
|
|
||||||
toggleable = 1
|
|
||||||
action_button_name = "Toggle Eyepatch"
|
|
||||||
|
|
||||||
/obj/item/clothing/glasses/thermal/plain/jensen
|
|
||||||
name = "optical thermal implants"
|
|
||||||
desc = "A set of implantable lenses designed to augment your vision"
|
|
||||||
icon_state = "thermalimplants"
|
|
||||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
|
||||||
>>>>>>> master-holder
|
|
||||||
@@ -1,160 +1,3 @@
|
|||||||
<<<<<<< HEAD
|
|
||||||
/obj/machinery/appliance/cooker/oven
|
|
||||||
name = "oven"
|
|
||||||
desc = "Cookies are ready, dear."
|
|
||||||
icon = 'icons/obj/cooking_machines.dmi'
|
|
||||||
icon_state = "ovenopen"
|
|
||||||
cook_type = "baked"
|
|
||||||
appliancetype = OVEN
|
|
||||||
food_color = "#A34719"
|
|
||||||
can_burn_food = TRUE
|
|
||||||
var/datum/looping_sound/oven/oven_loop
|
|
||||||
circuit = /obj/item/weapon/circuitboard/oven
|
|
||||||
active_power_usage = 6 KILOWATTS
|
|
||||||
heating_power = 6 KILOWATTS
|
|
||||||
//Based on a double deck electric convection oven
|
|
||||||
|
|
||||||
resistance = 12 KILOWATTS // Approx. 12 minutes to heat up.
|
|
||||||
idle_power_usage = 2 KILOWATTS
|
|
||||||
//uses ~30% power to stay warm
|
|
||||||
optimal_power = 0.8 // Oven cooks .2 faster than the default speed.
|
|
||||||
|
|
||||||
light_x = 3
|
|
||||||
light_y = 4
|
|
||||||
max_contents = 5
|
|
||||||
container_type = /obj/item/weapon/reagent_containers/cooking_container/oven
|
|
||||||
|
|
||||||
stat = POWEROFF //Starts turned off
|
|
||||||
|
|
||||||
var/open = FALSE // Start closed just so people don't try to preheat with it open, lol.
|
|
||||||
|
|
||||||
output_options = list(
|
|
||||||
"Pizza" = /obj/item/weapon/reagent_containers/food/snacks/variable/pizza,
|
|
||||||
"Bread" = /obj/item/weapon/reagent_containers/food/snacks/variable/bread,
|
|
||||||
"Pie" = /obj/item/weapon/reagent_containers/food/snacks/variable/pie,
|
|
||||||
"Cake" = /obj/item/weapon/reagent_containers/food/snacks/variable/cake,
|
|
||||||
"Hot Pocket" = /obj/item/weapon/reagent_containers/food/snacks/variable/pocket,
|
|
||||||
"Kebab" = /obj/item/weapon/reagent_containers/food/snacks/variable/kebab,
|
|
||||||
"Waffles" = /obj/item/weapon/reagent_containers/food/snacks/variable/waffles,
|
|
||||||
"Cookie" = /obj/item/weapon/reagent_containers/food/snacks/variable/cookie,
|
|
||||||
"Donut" = /obj/item/weapon/reagent_containers/food/snacks/variable/donut,
|
|
||||||
)
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/Initialize()
|
|
||||||
. = ..()
|
|
||||||
|
|
||||||
oven_loop = new(list(src), FALSE)
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/Destroy()
|
|
||||||
QDEL_NULL(oven_loop)
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/update_icon()
|
|
||||||
if(!open)
|
|
||||||
if(!stat)
|
|
||||||
icon_state = "ovenclosed_on"
|
|
||||||
if(cooking == TRUE)
|
|
||||||
icon_state = "ovenclosed_cooking"
|
|
||||||
if(oven_loop)
|
|
||||||
oven_loop.start(src)
|
|
||||||
else
|
|
||||||
icon_state = "ovenclosed_on"
|
|
||||||
if(oven_loop)
|
|
||||||
oven_loop.stop(src)
|
|
||||||
else
|
|
||||||
icon_state = "ovenclosed_off"
|
|
||||||
if(oven_loop)
|
|
||||||
oven_loop.stop(src)
|
|
||||||
else
|
|
||||||
icon_state = "ovenopen"
|
|
||||||
if(oven_loop)
|
|
||||||
oven_loop.stop(src)
|
|
||||||
..()
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/AltClick(var/mob/user)
|
|
||||||
try_toggle_door(user)
|
|
||||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/verb/toggle_door()
|
|
||||||
set src in oview(1)
|
|
||||||
set category = "Object"
|
|
||||||
set name = "Open/close oven door"
|
|
||||||
|
|
||||||
try_toggle_door(usr)
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/proc/try_toggle_door(mob/user)
|
|
||||||
if(!isliving(usr) || isAI(user))
|
|
||||||
return
|
|
||||||
|
|
||||||
if(!usr.IsAdvancedToolUser())
|
|
||||||
to_chat(user, "<span class='notice'>You lack the dexterity to do that.</span>")
|
|
||||||
return
|
|
||||||
|
|
||||||
if(!Adjacent(usr))
|
|
||||||
to_chat(user, "<span class='notice'>You can't reach the [src] from there, get closer!</span>")
|
|
||||||
return
|
|
||||||
|
|
||||||
if(open)
|
|
||||||
open = FALSE
|
|
||||||
loss = (heating_power / resistance) * 0.5
|
|
||||||
cooking = TRUE
|
|
||||||
else
|
|
||||||
open = TRUE
|
|
||||||
loss = (heating_power / resistance) * 4
|
|
||||||
//When the oven door is opened, heat is lost MUCH faster and you stop cooking (because the door is open)
|
|
||||||
cooking = FALSE
|
|
||||||
|
|
||||||
playsound(src, 'sound/machines/hatch_open.ogg', 20, 1)
|
|
||||||
to_chat(user, "<span class='notice'>You [open ? "open" : "close"] the oven door.</span>")
|
|
||||||
update_icon()
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/proc/manip(var/obj/item/I)
|
|
||||||
// check if someone's trying to manipulate the machine
|
|
||||||
|
|
||||||
if(I.is_crowbar() || I.is_screwdriver() || istype(I, /obj/item/weapon/storage/part_replacer))
|
|
||||||
return TRUE
|
|
||||||
else
|
|
||||||
return FALSE
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/can_insert(var/obj/item/I, var/mob/user)
|
|
||||||
if(!open && !manip(I))
|
|
||||||
to_chat(user, "<span class='warning'>You can't put anything in while the door is closed!</span>")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
else
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
|
|
||||||
//If an oven's door is open it will lose heat every proc, even if it also gained it
|
|
||||||
//But dont call equalize twice in one stack. A return value of -1 from the parent indicates equalize was already called
|
|
||||||
/obj/machinery/appliance/cooker/oven/heat_up()
|
|
||||||
.=..()
|
|
||||||
if(open && . != -1)
|
|
||||||
var/turf/T = get_turf(src)
|
|
||||||
if(temperature > T.temperature)
|
|
||||||
equalize_temperature()
|
|
||||||
|
|
||||||
/obj/machinery/appliance/cooker/oven/can_remove_items(var/mob/user, show_warning = TRUE)
|
|
||||||
if(!open)
|
|
||||||
if(show_warning)
|
|
||||||
to_chat(user, "<span class='warning'>You can't take anything out while the door is closed!</span>")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
else
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
|
|
||||||
//Oven has lots of recipes and combine options. The chance for interference is high, so
|
|
||||||
//If a combine target is set the oven will do it instead of checking recipes
|
|
||||||
/obj/machinery/appliance/cooker/oven/finish_cooking(var/datum/cooking_item/CI)
|
|
||||||
if(CI.combine_target)
|
|
||||||
CI.result_type = 3//Combination type. We're making something out of our ingredients
|
|
||||||
visible_message("<span class='notice'>\The [src] pings!</span>")
|
|
||||||
combination_cook(CI)
|
|
||||||
return
|
|
||||||
else
|
|
||||||
..()
|
|
||||||
=======
|
|
||||||
/obj/machinery/appliance/cooker/oven
|
/obj/machinery/appliance/cooker/oven
|
||||||
name = "oven"
|
name = "oven"
|
||||||
desc = "Cookies are ready, dear."
|
desc = "Cookies are ready, dear."
|
||||||
@@ -309,5 +152,4 @@
|
|||||||
combination_cook(CI)
|
combination_cook(CI)
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
..()
|
..()
|
||||||
>>>>>>> master-holder
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//In future consider cleaning up often used recipes by adding them to the general recipe list with material criteria
|
//In future consider cleaning up often used recipes by adding them to the general recipe list with material criteria
|
||||||
|
|
||||||
/material/plasteel/generate_recipes()
|
/datum/material/plasteel/generate_recipes()
|
||||||
. = ..()
|
. = ..()
|
||||||
// recipes += new/datum/stack_recipe("Hammer Head", /obj/item/weapon/hammer_head, 2) //CHOMPEdit - Disabled because I had to disable code/game/objects/items/weapons/material/sledgehammer_construction_ch.dm due to lots of errors
|
// recipes += new/datum/stack_recipe("Hammer Head", /obj/item/weapon/hammer_head, 2) //CHOMPEdit - Disabled because I had to disable code/game/objects/items/weapons/material/sledgehammer_construction_ch.dm due to lots of errors
|
||||||
recipes += new/datum/stack_recipe_list("sofas", list( \
|
recipes += new/datum/stack_recipe_list("sofas", list( \
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
new/datum/stack_recipe("sofa corner", /obj/structure/bed/chair/sofa/corner, 1, one_per_turf = 1, on_floor = 1), \
|
new/datum/stack_recipe("sofa corner", /obj/structure/bed/chair/sofa/corner, 1, one_per_turf = 1, on_floor = 1), \
|
||||||
))
|
))
|
||||||
|
|
||||||
/material/plastic/generate_recipes()
|
/datum/material/plastic/generate_recipes()
|
||||||
. = ..()
|
. = ..()
|
||||||
recipes += new/datum/stack_recipe_list("sofas", list( \
|
recipes += new/datum/stack_recipe_list("sofas", list( \
|
||||||
new/datum/stack_recipe("sofa middle", /obj/structure/bed/chair/sofa, 1, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), \
|
new/datum/stack_recipe("sofa middle", /obj/structure/bed/chair/sofa, 1, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), \
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
new/datum/stack_recipe("sofa corner", /obj/structure/bed/chair/sofa/corner, 1, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), \
|
new/datum/stack_recipe("sofa corner", /obj/structure/bed/chair/sofa/corner, 1, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), \
|
||||||
))
|
))
|
||||||
|
|
||||||
/material/wood/generate_recipes() //Is a little sad we cant have lovely wooden sofa
|
/datum/material/wood/generate_recipes() //Is a little sad we cant have lovely wooden sofa
|
||||||
. = ..()
|
. = ..()
|
||||||
recipes += new/datum/stack_recipe_list("sofas", list( \
|
recipes += new/datum/stack_recipe_list("sofas", list( \
|
||||||
new/datum/stack_recipe("sofa middle", /obj/structure/bed/chair/sofa, 1, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), \
|
new/datum/stack_recipe("sofa middle", /obj/structure/bed/chair/sofa, 1, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), \
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//CARPET materials
|
//CARPET materials
|
||||||
|
|
||||||
/material/carpet
|
/datum/material/carpet
|
||||||
name = MAT_CARPET
|
name = MAT_CARPET
|
||||||
display_name = "comfy"
|
display_name = "comfy"
|
||||||
use_name = "upholstery"
|
use_name = "upholstery"
|
||||||
@@ -14,42 +14,42 @@
|
|||||||
protectiveness = 1 // 4%
|
protectiveness = 1 // 4%
|
||||||
conductive = 0
|
conductive = 0
|
||||||
|
|
||||||
/material/carpet/teal
|
/datum/material/carpet/teal
|
||||||
name = MAT_CARPET_TEAL
|
name = MAT_CARPET_TEAL
|
||||||
icon_colour = "#007575"
|
icon_colour = "#007575"
|
||||||
stack_type = /obj/item/stack/tile/carpet/teal
|
stack_type = /obj/item/stack/tile/carpet/teal
|
||||||
|
|
||||||
/material/carpet/bcarpet
|
/datum/material/carpet/bcarpet
|
||||||
name = MAT_CARPET_BLACK
|
name = MAT_CARPET_BLACK
|
||||||
icon_colour = "#1B171E"
|
icon_colour = "#1B171E"
|
||||||
stack_type = /obj/item/stack/tile/carpet/bcarpet
|
stack_type = /obj/item/stack/tile/carpet/bcarpet
|
||||||
|
|
||||||
/material/carpet/blucarpet
|
/datum/material/carpet/blucarpet
|
||||||
name = MAT_CARPET_BLUE
|
name = MAT_CARPET_BLUE
|
||||||
icon_colour = "#122CDF"
|
icon_colour = "#122CDF"
|
||||||
stack_type = /obj/item/stack/tile/carpet/blucarpet
|
stack_type = /obj/item/stack/tile/carpet/blucarpet
|
||||||
|
|
||||||
/material/carpet/turcarpet
|
/datum/material/carpet/turcarpet
|
||||||
name = MAT_CARPET_TURQUOISE
|
name = MAT_CARPET_TURQUOISE
|
||||||
icon_colour = "#41A997"
|
icon_colour = "#41A997"
|
||||||
stack_type = /obj/item/stack/tile/carpet/turcarpet
|
stack_type = /obj/item/stack/tile/carpet/turcarpet
|
||||||
|
|
||||||
/material/carpet/sblucarpet
|
/datum/material/carpet/sblucarpet
|
||||||
name = MAT_CARPET_SILVERBLUE
|
name = MAT_CARPET_SILVERBLUE
|
||||||
icon_colour = "#547EC6"
|
icon_colour = "#547EC6"
|
||||||
stack_type = /obj/item/stack/tile/carpet/sblucarpet
|
stack_type = /obj/item/stack/tile/carpet/sblucarpet
|
||||||
|
|
||||||
/material/carpet/gaycarpet
|
/datum/material/carpet/gaycarpet
|
||||||
name = MAT_CARPET_PINK
|
name = MAT_CARPET_PINK
|
||||||
icon_colour = "#E12C87"
|
icon_colour = "#E12C87"
|
||||||
stack_type = /obj/item/stack/tile/carpet/gaycarpet
|
stack_type = /obj/item/stack/tile/carpet/gaycarpet
|
||||||
|
|
||||||
/material/carpet/purcarpet
|
/datum/material/carpet/purcarpet
|
||||||
name = MAT_CARPET_PURPLE
|
name = MAT_CARPET_PURPLE
|
||||||
icon_colour = "#B500A6"
|
icon_colour = "#B500A6"
|
||||||
stack_type = /obj/item/stack/tile/carpet/purcarpet
|
stack_type = /obj/item/stack/tile/carpet/purcarpet
|
||||||
|
|
||||||
/material/carpet/oracarpet
|
/datum/material/carpet/oracarpet
|
||||||
name = MAT_CARPET_ORANGE
|
name = MAT_CARPET_ORANGE
|
||||||
icon_colour = "#D1D000"
|
icon_colour = "#D1D000"
|
||||||
stack_type = /obj/item/stack/tile/carpet/oracarpet
|
stack_type = /obj/item/stack/tile/carpet/oracarpet
|
||||||
7
code/modules/nano/interaction/admin.dm
Normal file
7
code/modules/nano/interaction/admin.dm
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
This state checks that the user is an admin, end of story
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/admin_state/admin_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/admin_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
return check_rights(R_ADMIN|R_EVENT, 0, user) ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||||
37
code/modules/nano/interaction/base.dm
Normal file
37
code/modules/nano/interaction/base.dm
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/datum/proc/nano_host()
|
||||||
|
return src
|
||||||
|
|
||||||
|
/datum/proc/nano_container()
|
||||||
|
return src
|
||||||
|
|
||||||
|
/datum/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state)
|
||||||
|
var/src_object = nano_host()
|
||||||
|
return state.can_use_topic(src_object, user)
|
||||||
|
|
||||||
|
/datum/topic_state/proc/href_list(var/mob/user)
|
||||||
|
return list()
|
||||||
|
|
||||||
|
/datum/topic_state/proc/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
/mob/proc/shared_nano_interaction()
|
||||||
|
if (src.stat || !client)
|
||||||
|
return STATUS_CLOSE // no updates, close the interface
|
||||||
|
else if (incapacitated())
|
||||||
|
return STATUS_UPDATE // update only (orange visibility)
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
|
||||||
|
/mob/living/silicon/ai/shared_nano_interaction()
|
||||||
|
if(lacks_power())
|
||||||
|
return STATUS_CLOSE
|
||||||
|
if (check_unable(1, 0))
|
||||||
|
return STATUS_CLOSE
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/shared_nano_interaction()
|
||||||
|
. = STATUS_INTERACTIVE
|
||||||
|
if(!has_power)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
if(lockdown)
|
||||||
|
. = STATUS_DISABLED
|
||||||
|
return min(., ..())
|
||||||
7
code/modules/nano/interaction/conscious.dm
Normal file
7
code/modules/nano/interaction/conscious.dm
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
This state only checks if user is conscious.
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/conscious_state/conscious_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/conscious_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
return user.stat == CONSCIOUS ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||||
18
code/modules/nano/interaction/contained.dm
Normal file
18
code/modules/nano/interaction/contained.dm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
This state checks if user is somewhere within src_object, as well as the default NanoUI interaction.
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/contained_state/contained_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/contained_state/can_use_topic(var/atom/src_object, var/mob/user)
|
||||||
|
if(!src_object.contains(user))
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
return user.shared_nano_interaction()
|
||||||
|
|
||||||
|
/atom/proc/contains(var/atom/location)
|
||||||
|
if(!location)
|
||||||
|
return 0
|
||||||
|
if(location == src)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return contains(location.loc)
|
||||||
91
code/modules/nano/interaction/default.dm
Normal file
91
code/modules/nano/interaction/default.dm
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/var/global/datum/topic_state/default/default_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/default/href_list(var/mob/user)
|
||||||
|
return list()
|
||||||
|
|
||||||
|
/datum/topic_state/default/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
return user.default_can_use_topic(src_object)
|
||||||
|
|
||||||
|
/mob/proc/default_can_use_topic(var/src_object)
|
||||||
|
return STATUS_CLOSE // By default no mob can do anything with NanoUI
|
||||||
|
|
||||||
|
/mob/observer/dead/default_can_use_topic(var/src_object)
|
||||||
|
if(can_admin_interact())
|
||||||
|
return STATUS_INTERACTIVE // Admins are more equal
|
||||||
|
if(!client || get_dist(src_object, src) > client.view) // Preventing ghosts from having a million windows open by limiting to objects in range
|
||||||
|
return STATUS_CLOSE
|
||||||
|
return STATUS_UPDATE // Ghosts can view updates
|
||||||
|
|
||||||
|
/mob/living/silicon/pai/default_can_use_topic(var/src_object)
|
||||||
|
if((src_object == src || src_object == radio || src_object == communicator) && !stat)
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
else
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/default_can_use_topic(var/src_object)
|
||||||
|
. = shared_nano_interaction()
|
||||||
|
if(. <= STATUS_DISABLED)
|
||||||
|
return
|
||||||
|
|
||||||
|
// robots can interact with things they can see within their view range
|
||||||
|
if((src_object in view(src)) && get_dist(src_object, src) <= src.client.view)
|
||||||
|
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||||
|
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||||
|
|
||||||
|
/mob/living/silicon/ai/default_can_use_topic(var/src_object)
|
||||||
|
. = shared_nano_interaction()
|
||||||
|
if(. != STATUS_INTERACTIVE)
|
||||||
|
return
|
||||||
|
|
||||||
|
// Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras)
|
||||||
|
// unless it's on the same level as the object it's interacting with.
|
||||||
|
var/turf/T = get_turf(src_object)
|
||||||
|
if(!T || !(z == T.z || (T.z in using_map.player_levels)))
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
// If an object is in view then we can interact with it
|
||||||
|
if(src_object in view(client.view, src))
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
|
||||||
|
// If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view
|
||||||
|
if(is_in_chassis())
|
||||||
|
//stop AIs from leaving windows open and using then after they lose vision
|
||||||
|
if(cameranet && !cameranet.checkTurfVis(get_turf(src_object)))
|
||||||
|
return STATUS_CLOSE
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
else if(get_dist(src_object, src) <= client.view) // View does not return what one would expect while installed in an inteliCard
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI.
|
||||||
|
/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user)
|
||||||
|
return user.shared_living_nano_distance(src_object)
|
||||||
|
|
||||||
|
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
|
||||||
|
if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
var/dist = get_dist(src_object, src)
|
||||||
|
if (dist <= 1)
|
||||||
|
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||||
|
else if (dist <= 2)
|
||||||
|
return STATUS_UPDATE // update only (orange visibility)
|
||||||
|
else if (dist <= 4)
|
||||||
|
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
/mob/living/default_can_use_topic(var/src_object)
|
||||||
|
. = shared_nano_interaction(src_object)
|
||||||
|
if(. != STATUS_CLOSE)
|
||||||
|
if(loc)
|
||||||
|
. = min(., loc.contents_nano_distance(src_object, src))
|
||||||
|
if(STATUS_INTERACTIVE)
|
||||||
|
return STATUS_UPDATE
|
||||||
|
|
||||||
|
/mob/living/carbon/human/default_can_use_topic(var/src_object)
|
||||||
|
. = shared_nano_interaction(src_object)
|
||||||
|
if(. != STATUS_CLOSE)
|
||||||
|
. = min(., shared_living_nano_distance(src_object))
|
||||||
|
if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction.
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
6
code/modules/nano/interaction/default_vr.dm
Normal file
6
code/modules/nano/interaction/default_vr.dm
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/mob/living/simple_mob/default_can_use_topic(var/src_object)
|
||||||
|
. = shared_nano_interaction(src_object)
|
||||||
|
if(. != STATUS_CLOSE)
|
||||||
|
. = min(., shared_living_nano_distance(src_object))
|
||||||
|
|
||||||
|
//Allows simple mobs to interact with nanoui as long as they have "has_hands = TRUE"
|
||||||
7
code/modules/nano/interaction/interactive.dm
Normal file
7
code/modules/nano/interaction/interactive.dm
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
This state always returns STATUS_INTERACTIVE
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/interactive/interactive_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/interactive/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
11
code/modules/nano/interaction/inventory.dm
Normal file
11
code/modules/nano/interaction/inventory.dm
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
This state checks that the src_object is somewhere in the user's first-level inventory (in hands, on ear, etc.), but not further down (such as in bags).
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/inventory_state/inventory_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/inventory_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
if(!(src_object in user))
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
|
||||||
|
return user.shared_nano_interaction()
|
||||||
10
code/modules/nano/interaction/inventory_deep.dm
Normal file
10
code/modules/nano/interaction/inventory_deep.dm
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
This state checks if src_object is contained anywhere in the user's inventory, including bags, etc.
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/deep_inventory_state/deep_inventory_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/deep_inventory_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
if(!user.contains(src_object))
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
return user.shared_nano_interaction()
|
||||||
32
code/modules/nano/interaction/inventory_vr.dm
Normal file
32
code/modules/nano/interaction/inventory_vr.dm
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
This state checks that the src_object is on the user's glasses slot.
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/glasses_state/glasses_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/glasses_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
if(ishuman(user))
|
||||||
|
var/mob/living/carbon/human/H = user
|
||||||
|
if(H.glasses == src_object)
|
||||||
|
return user.shared_nano_interaction()
|
||||||
|
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
/var/global/datum/topic_state/nif_state/nif_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/nif_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
if(ishuman(user))
|
||||||
|
var/mob/living/carbon/human/H = user
|
||||||
|
if(H.nif && H.nif.stat == NIF_WORKING && src_object == H.nif)
|
||||||
|
return user.shared_nano_interaction()
|
||||||
|
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
/var/global/datum/topic_state/commlink_state/commlink_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/commlink_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
if(ishuman(user))
|
||||||
|
var/mob/living/carbon/human/H = user
|
||||||
|
if(H.nif && H.nif.stat == NIF_WORKING && H.nif.comm == src_object)
|
||||||
|
return user.shared_nano_interaction()
|
||||||
|
|
||||||
|
return STATUS_CLOSE
|
||||||
6
code/modules/nano/interaction/outside.dm
Normal file
6
code/modules/nano/interaction/outside.dm
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/var/global/datum/topic_state/default/outside/outside_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/default/outside/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
if(user in src_object)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
return ..()
|
||||||
18
code/modules/nano/interaction/physical.dm
Normal file
18
code/modules/nano/interaction/physical.dm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/var/global/datum/topic_state/physical/physical_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/physical/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
. = user.shared_nano_interaction(src_object)
|
||||||
|
if(. > STATUS_CLOSE)
|
||||||
|
return min(., user.check_physical_distance(src_object))
|
||||||
|
|
||||||
|
/mob/proc/check_physical_distance(var/src_object)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
/mob/observer/dead/check_physical_distance(var/src_object)
|
||||||
|
return default_can_use_topic(src_object)
|
||||||
|
|
||||||
|
/mob/living/check_physical_distance(var/src_object)
|
||||||
|
return shared_living_nano_distance(src_object)
|
||||||
|
|
||||||
|
/mob/living/silicon/check_physical_distance(var/src_object)
|
||||||
|
return max(STATUS_UPDATE, shared_living_nano_distance(src_object))
|
||||||
39
code/modules/nano/interaction/remote.dm
Normal file
39
code/modules/nano/interaction/remote.dm
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
This state checks that user is capable, within range of the remoter, etc. and that src_object meets the basic requirements for interaction (being powered, non-broken, etc.
|
||||||
|
Whoever initializes this state is also responsible for deleting it properly.
|
||||||
|
*/
|
||||||
|
/datum/topic_state/remote
|
||||||
|
var/datum/remoter
|
||||||
|
var/datum/remote_target
|
||||||
|
var/datum/topic_state/remoter_state
|
||||||
|
|
||||||
|
/datum/topic_state/remote/New(var/remoter, var/remote_target, var/datum/topic_state/remoter_state = default_state)
|
||||||
|
src.remoter = remoter
|
||||||
|
src.remote_target = remote_target
|
||||||
|
src.remoter_state = remoter_state
|
||||||
|
..()
|
||||||
|
|
||||||
|
/datum/topic_state/remote/Destroy()
|
||||||
|
src.remoter = null
|
||||||
|
src.remoter_state = null
|
||||||
|
|
||||||
|
// Force an UI update before we go, ensuring that any windows we may have opened for the remote target closes.
|
||||||
|
SSnanoui.update_uis(remote_target.nano_container())
|
||||||
|
remote_target = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/topic_state/remote/can_use_topic(var/datum/src_object, var/mob/user)
|
||||||
|
if(!(remoter && remoter_state)) // The remoter is gone, let us leave
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
if(src_object != remote_target)
|
||||||
|
error("remote - Unexpected src_object: Expected '[remote_target]'/[remote_target.type], was '[src_object]'/[src_object.type]")
|
||||||
|
|
||||||
|
// This checks if src_object is powered, etc.
|
||||||
|
// The interactive state is otherwise simplistic and only returns STATUS_INTERACTIVE and never checks distances, etc.
|
||||||
|
. = src_object.CanUseTopic(user, interactive_state)
|
||||||
|
if(. == STATUS_CLOSE)
|
||||||
|
return
|
||||||
|
|
||||||
|
// This is the (generally) heavy checking, making sure the user is capable, within range of the remoter source, etc.
|
||||||
|
return min(., remoter.CanUseTopic(user, remoter_state))
|
||||||
9
code/modules/nano/interaction/self.dm
Normal file
9
code/modules/nano/interaction/self.dm
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
This state checks that the src_object is the same the as user
|
||||||
|
*/
|
||||||
|
/var/global/datum/topic_state/self_state/self_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/self_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
if(src_object != user)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
return user.shared_nano_interaction()
|
||||||
13
code/modules/nano/interaction/zlevel.dm
Normal file
13
code/modules/nano/interaction/zlevel.dm
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
This state checks that the user is on the same Z-level as src_object
|
||||||
|
*/
|
||||||
|
|
||||||
|
/var/global/datum/topic_state/z_state/z_state = new()
|
||||||
|
|
||||||
|
/datum/topic_state/z_state/can_use_topic(var/src_object, var/mob/user)
|
||||||
|
var/turf/turf_obj = get_turf(src_object)
|
||||||
|
var/turf/turf_usr = get_turf(user)
|
||||||
|
if(!turf_obj || !turf_usr)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
return turf_obj.z == turf_usr.z ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||||
44
code/modules/nano/nanoexternal.dm
Normal file
44
code/modules/nano/nanoexternal.dm
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// This file contains all Nano procs/definitions for external classes/objects
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a Nano UI window is closed
|
||||||
|
* This is how Nano handles closed windows
|
||||||
|
* It must be a verb so that it can be called using winset
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/client/verb/nanoclose(var/uiref as text)
|
||||||
|
set hidden = 1 // hide this verb from the user's panel
|
||||||
|
set name = "nanoclose"
|
||||||
|
|
||||||
|
var/datum/nanoui/ui = locate(uiref)
|
||||||
|
|
||||||
|
if (istype(ui))
|
||||||
|
ui.close()
|
||||||
|
|
||||||
|
if(ui.ref)
|
||||||
|
var/href = "close=1"
|
||||||
|
src.Topic(href, params2list(href), ui.ref) // this will direct to the atom's Topic() proc via client.Topic()
|
||||||
|
else if (ui.on_close_logic)
|
||||||
|
// no atomref specified (or not found)
|
||||||
|
// so just reset the user mob's machine var
|
||||||
|
if(src && src.mob)
|
||||||
|
src.mob.unset_machine()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ui_interact proc is used to open and update Nano UIs
|
||||||
|
* If ui_interact is not used then the UI will not update correctly
|
||||||
|
* ui_interact is currently defined for /atom/movable
|
||||||
|
*
|
||||||
|
* @param user /mob The mob who is interacting with this ui
|
||||||
|
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
||||||
|
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
|
||||||
|
* @param force_open boolean Force the UI to (re)open, even if it's already open
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state)
|
||||||
|
return
|
||||||
|
|
||||||
|
// Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob
|
||||||
|
/mob/var/list/open_uis = list()
|
||||||
224
code/modules/nano/nanomanager.dm
Normal file
224
code/modules/nano/nanomanager.dm
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data
|
||||||
|
*
|
||||||
|
* @param user /mob The mob who opened/owns the ui
|
||||||
|
* @param src_object /obj|/mob The obj or mob which the ui belongs to
|
||||||
|
* @param ui_key string A string key used for the ui
|
||||||
|
* @param ui /datum/nanoui An existing instance of the ui (can be null)
|
||||||
|
* @param data list The data to be passed to the ui, if it exists
|
||||||
|
* @param force_open boolean The ui is being forced to (re)open, so close ui if it exists (instead of updating)
|
||||||
|
*
|
||||||
|
* @return /nanoui Returns the found ui, for null if none exists
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data, var/force_open = 0)
|
||||||
|
if (isnull(ui)) // no ui has been passed, so we'll search for one
|
||||||
|
{
|
||||||
|
ui = get_open_ui(user, src_object, ui_key)
|
||||||
|
}
|
||||||
|
if (!isnull(ui))
|
||||||
|
// The UI is already open
|
||||||
|
if (!force_open)
|
||||||
|
ui.push_data(data)
|
||||||
|
return ui
|
||||||
|
else
|
||||||
|
ui.reinitialise(new_initial_data=data)
|
||||||
|
return ui
|
||||||
|
|
||||||
|
return null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an open /nanoui ui for the current user, src_object and ui_key
|
||||||
|
*
|
||||||
|
* @param user /mob The mob who opened/owns the ui
|
||||||
|
* @param src_object /obj|/mob The obj or mob which the ui belongs to
|
||||||
|
* @param ui_key string A string key used for the ui
|
||||||
|
*
|
||||||
|
* @return /nanoui Returns the found ui, or null if none exists
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/get_open_ui(var/mob/user, src_object, ui_key)
|
||||||
|
var/src_object_key = "\ref[src_object]"
|
||||||
|
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||||
|
//testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open")
|
||||||
|
return null
|
||||||
|
else if (isnull(open_uis[src_object_key][ui_key]) || !istype(open_uis[src_object_key][ui_key], /list))
|
||||||
|
//testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - there are no uis open for this object")
|
||||||
|
return null
|
||||||
|
|
||||||
|
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||||
|
if (ui.user == user)
|
||||||
|
return ui
|
||||||
|
|
||||||
|
//testing("nanomanager/get_open_ui mob [user.name] [src_object:name] [ui_key] - ui not found")
|
||||||
|
return null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all /nanoui uis attached to src_object
|
||||||
|
*
|
||||||
|
* @param src_object /obj|/mob The obj or mob which the uis are attached to
|
||||||
|
*
|
||||||
|
* @return int The number of uis updated
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/update_uis(src_object)
|
||||||
|
var/src_object_key = "\ref[src_object]"
|
||||||
|
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
var/update_count = 0
|
||||||
|
for (var/ui_key in open_uis[src_object_key])
|
||||||
|
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||||
|
if(ui && ui.src_object && ui.user && ui.src_object.nano_host())
|
||||||
|
ui.process(1)
|
||||||
|
update_count++
|
||||||
|
return update_count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close all /nanoui uis attached to src_object
|
||||||
|
*
|
||||||
|
* @param src_object /obj|/mob The obj or mob which the uis are attached to
|
||||||
|
*
|
||||||
|
* @return int The number of uis close
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/close_uis(src_object)
|
||||||
|
var/src_object_key = "\ref[src_object]"
|
||||||
|
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
var/close_count = 0
|
||||||
|
for (var/ui_key in open_uis[src_object_key])
|
||||||
|
for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||||
|
if(ui && ui.src_object && ui.user && ui.src_object.nano_host())
|
||||||
|
ui.close()
|
||||||
|
close_count++
|
||||||
|
return close_count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update /nanoui uis belonging to user
|
||||||
|
*
|
||||||
|
* @param user /mob The mob who owns the uis
|
||||||
|
* @param src_object /obj|/mob If src_object is provided, only update uis which are attached to src_object (optional)
|
||||||
|
* @param ui_key string If ui_key is provided, only update uis with a matching ui_key (optional)
|
||||||
|
*
|
||||||
|
* @return int The number of uis updated
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/update_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||||
|
if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||||
|
return 0 // has no open uis
|
||||||
|
|
||||||
|
var/update_count = 0
|
||||||
|
for (var/datum/nanoui/ui in user.open_uis)
|
||||||
|
if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||||
|
ui.process(1)
|
||||||
|
update_count++
|
||||||
|
|
||||||
|
return update_count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close /nanoui uis belonging to user
|
||||||
|
*
|
||||||
|
* @param user /mob The mob who owns the uis
|
||||||
|
* @param src_object /obj|/mob If src_object is provided, only close uis which are attached to src_object (optional)
|
||||||
|
* @param ui_key string If ui_key is provided, only close uis with a matching ui_key (optional)
|
||||||
|
*
|
||||||
|
* @return int The number of uis closed
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/close_user_uis(var/mob/user, src_object = null, ui_key = null)
|
||||||
|
if (isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||||
|
//testing("nanomanager/close_user_uis mob [user.name] has no open uis")
|
||||||
|
return 0 // has no open uis
|
||||||
|
|
||||||
|
var/close_count = 0
|
||||||
|
for (var/datum/nanoui/ui in user.open_uis)
|
||||||
|
if ((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||||
|
ui.close()
|
||||||
|
close_count++
|
||||||
|
|
||||||
|
//testing("nanomanager/close_user_uis mob [user.name] closed [open_uis.len] of [close_count] uis")
|
||||||
|
|
||||||
|
return close_count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a /nanoui ui to the list of open uis
|
||||||
|
* This is called by the /nanoui open() proc
|
||||||
|
*
|
||||||
|
* @param ui /nanoui The ui to add
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/ui_opened(var/datum/nanoui/ui)
|
||||||
|
var/src_object_key = "\ref[ui.src_object]"
|
||||||
|
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||||
|
open_uis[src_object_key] = list(ui.ui_key = list())
|
||||||
|
else if (isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||||
|
open_uis[src_object_key][ui.ui_key] = list();
|
||||||
|
|
||||||
|
ui.user.open_uis |= ui
|
||||||
|
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||||
|
uis |= ui
|
||||||
|
processing_uis |= ui
|
||||||
|
//testing("nanomanager/ui_opened mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a /nanoui ui from the list of open uis
|
||||||
|
* This is called by the /nanoui close() proc
|
||||||
|
*
|
||||||
|
* @param ui /nanoui The ui to remove
|
||||||
|
*
|
||||||
|
* @return int 0 if no ui was removed, 1 if removed successfully
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/ui_closed(var/datum/nanoui/ui)
|
||||||
|
var/src_object_key = "\ref[ui.src_object]"
|
||||||
|
if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||||
|
return 0 // wasn't open
|
||||||
|
else if (isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||||
|
return 0 // wasn't open
|
||||||
|
|
||||||
|
processing_uis.Remove(ui)
|
||||||
|
if(ui.user) // Sanity check in case a user has been deleted (say a blown up borg watching the alarm interface)
|
||||||
|
ui.user.open_uis.Remove(ui)
|
||||||
|
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||||
|
uis.Remove(ui)
|
||||||
|
|
||||||
|
//testing("nanomanager/ui_closed mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]")
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called on user logout
|
||||||
|
* Closes/clears all uis attached to the user's /mob
|
||||||
|
*
|
||||||
|
* @param user /mob The user's mob
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
/datum/controller/subsystem/nanoui/proc/user_logout(var/mob/user)
|
||||||
|
//testing("nanomanager/user_logout user [user.name]")
|
||||||
|
return close_user_uis(user)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called when a player transfers from one mob to another
|
||||||
|
* Transfers all open UIs to the new mob
|
||||||
|
*
|
||||||
|
* @param oldMob /mob The user's old mob
|
||||||
|
* @param newMob /mob The user's new mob
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/nanoui/proc/user_transferred(var/mob/oldMob, var/mob/newMob)
|
||||||
|
//testing("nanomanager/user_transferred from mob [oldMob.name] to mob [newMob.name]")
|
||||||
|
if (!oldMob || isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0)
|
||||||
|
//testing("nanomanager/user_transferred mob [oldMob.name] has no open uis")
|
||||||
|
return 0 // has no open uis
|
||||||
|
|
||||||
|
if (isnull(newMob.open_uis) || !istype(newMob.open_uis, /list))
|
||||||
|
newMob.open_uis = list()
|
||||||
|
|
||||||
|
for (var/datum/nanoui/ui in oldMob.open_uis)
|
||||||
|
ui.user = newMob
|
||||||
|
newMob.open_uis.Add(ui)
|
||||||
|
|
||||||
|
oldMob.open_uis.Cut()
|
||||||
|
|
||||||
|
return 1 // success
|
||||||
92
code/modules/nano/nanomapgen.dm
Normal file
92
code/modules/nano/nanomapgen.dm
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// This file is a modified version of https://raw2.github.com/Baystation12/OldCode-BS12/master/code/TakePicture.dm
|
||||||
|
|
||||||
|
#define NANOMAP_ICON_SIZE 4
|
||||||
|
#define NANOMAP_MAX_ICON_DIMENSION 1200
|
||||||
|
|
||||||
|
#define NANOMAP_TILES_PER_IMAGE (NANOMAP_MAX_ICON_DIMENSION / NANOMAP_ICON_SIZE)
|
||||||
|
|
||||||
|
#define NANOMAP_TERMINALERR 5
|
||||||
|
#define NANOMAP_INPROGRESS 2
|
||||||
|
#define NANOMAP_BADOUTPUT 2
|
||||||
|
#define NANOMAP_SUCCESS 1
|
||||||
|
#define NANOMAP_WATCHDOGSUCCESS 4
|
||||||
|
#define NANOMAP_WATCHDOGTERMINATE 3
|
||||||
|
|
||||||
|
|
||||||
|
//Call these procs to dump your world to a series of image files (!!)
|
||||||
|
//NOTE: Does not explicitly support non 32x32 icons or stuff with large pixel_* values, so don't blame me if it doesn't work perfectly
|
||||||
|
|
||||||
|
/client/proc/nanomapgen_DumpImage()
|
||||||
|
set name = "Generate NanoUI Map"
|
||||||
|
set category = "Server"
|
||||||
|
|
||||||
|
if(holder)
|
||||||
|
nanomapgen_DumpTile(1, 1, text2num(input(usr,"Enter the Z level to generate")))
|
||||||
|
|
||||||
|
/client/proc/nanomapgen_DumpTile(var/startX = 1, var/startY = 1, var/currentZ = 1, var/endX = -1, var/endY = -1)
|
||||||
|
|
||||||
|
if (endX < 0 || endX > world.maxx)
|
||||||
|
endX = world.maxx
|
||||||
|
|
||||||
|
if (endY < 0 || endY > world.maxy)
|
||||||
|
endY = world.maxy
|
||||||
|
|
||||||
|
if (currentZ < 0 || currentZ > world.maxz)
|
||||||
|
to_chat(usr, "NanoMapGen: <B>ERROR: currentZ ([currentZ]) must be between 1 and [world.maxz]</B>")
|
||||||
|
|
||||||
|
sleep(3)
|
||||||
|
return NANOMAP_TERMINALERR
|
||||||
|
|
||||||
|
if (startX > endX)
|
||||||
|
to_chat(usr, "NanoMapGen: <B>ERROR: startX ([startX]) cannot be greater than endX ([endX])</B>")
|
||||||
|
|
||||||
|
sleep(3)
|
||||||
|
return NANOMAP_TERMINALERR
|
||||||
|
|
||||||
|
if (startY > endX)
|
||||||
|
to_chat(usr, "NanoMapGen: <B>ERROR: startY ([startY]) cannot be greater than endY ([endY])</B>")
|
||||||
|
sleep(3)
|
||||||
|
return NANOMAP_TERMINALERR
|
||||||
|
|
||||||
|
var/icon/Tile = icon(file("nano/mapbase1200.png"))
|
||||||
|
if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION)
|
||||||
|
to_world_log("NanoMapGen: <B>ERROR: BASE IMAGE DIMENSIONS ARE NOT [NANOMAP_MAX_ICON_DIMENSION]x[NANOMAP_MAX_ICON_DIMENSION]</B>")
|
||||||
|
sleep(3)
|
||||||
|
return NANOMAP_TERMINALERR
|
||||||
|
|
||||||
|
Tile.Scale((endX - startX + 1) * NANOMAP_ICON_SIZE, (endY - startY + 1) * NANOMAP_ICON_SIZE) // VOREStation Edit - Scale image to actual size mapped.
|
||||||
|
|
||||||
|
to_world_log("NanoMapGen: <B>GENERATE MAP ([startX],[startY],[currentZ]) to ([endX],[endY],[currentZ])</B>")
|
||||||
|
to_chat(usr, "NanoMapGen: <B>GENERATE MAP ([startX],[startY],[currentZ]) to ([endX],[endY],[currentZ])</B>")
|
||||||
|
|
||||||
|
var/count = 0;
|
||||||
|
for(var/WorldX = startX, WorldX <= endX, WorldX++)
|
||||||
|
for(var/WorldY = startY, WorldY <= endY, WorldY++)
|
||||||
|
|
||||||
|
var/atom/Turf = locate(WorldX, WorldY, currentZ)
|
||||||
|
|
||||||
|
var/icon/TurfIcon = new(Turf.icon, Turf.icon_state)
|
||||||
|
TurfIcon.Scale(NANOMAP_ICON_SIZE, NANOMAP_ICON_SIZE)
|
||||||
|
|
||||||
|
Tile.Blend(TurfIcon, ICON_OVERLAY, ((WorldX - 1) * NANOMAP_ICON_SIZE), ((WorldY - 1) * NANOMAP_ICON_SIZE))
|
||||||
|
|
||||||
|
count++
|
||||||
|
|
||||||
|
if (count % 8000 == 0)
|
||||||
|
to_world_log("NanoMapGen: <B>[count] tiles done</B>")
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
var/mapFilename = "nanomap_z[currentZ]-new.png"
|
||||||
|
|
||||||
|
to_world_log("NanoMapGen: <B>sending [mapFilename] to client</B>")
|
||||||
|
|
||||||
|
usr << browse(Tile, "window=picture;file=[mapFilename];display=0")
|
||||||
|
|
||||||
|
to_world_log("NanoMapGen: <B>Done.</B>")
|
||||||
|
|
||||||
|
to_chat(usr, "NanoMapGen: <B>Done. File [mapFilename] uploaded to your cache.</B>")
|
||||||
|
|
||||||
|
if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION)
|
||||||
|
return NANOMAP_BADOUTPUT
|
||||||
|
|
||||||
|
return NANOMAP_SUCCESS
|
||||||
528
code/modules/nano/nanoui.dm
Normal file
528
code/modules/nano/nanoui.dm
Normal file
@@ -0,0 +1,528 @@
|
|||||||
|
/**********************************************************
|
||||||
|
NANO UI FRAMEWORK
|
||||||
|
|
||||||
|
nanoui class (or whatever Byond calls classes)
|
||||||
|
|
||||||
|
nanoui is used to open and update nano browser uis
|
||||||
|
**********************************************************/
|
||||||
|
|
||||||
|
/datum/nanoui
|
||||||
|
// the user who opened this ui
|
||||||
|
var/mob/user
|
||||||
|
// the object this ui "belongs" to
|
||||||
|
var/datum/src_object
|
||||||
|
// the title of this ui
|
||||||
|
var/title
|
||||||
|
// the key of this ui, this is to allow multiple (different) uis for each src_object
|
||||||
|
var/ui_key
|
||||||
|
// window_id is used as the window name/identifier for browse and onclose
|
||||||
|
var/window_id
|
||||||
|
// the browser window width
|
||||||
|
var/width = 0
|
||||||
|
// the browser window height
|
||||||
|
var/height = 0
|
||||||
|
// whether to use extra logic when window closes
|
||||||
|
var/on_close_logic = 1
|
||||||
|
// an extra ref to use when the window is closed, usually null
|
||||||
|
var/atom/ref = null
|
||||||
|
// options for modifying window behaviour
|
||||||
|
var/window_options = "focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
|
||||||
|
// the list of stylesheets to apply to this ui
|
||||||
|
var/list/stylesheets = list()
|
||||||
|
// the list of javascript scripts to use for this ui
|
||||||
|
var/list/scripts = list()
|
||||||
|
// a list of templates which can be used with this ui
|
||||||
|
var/templates[0]
|
||||||
|
// the layout key for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing)
|
||||||
|
var/layout_key = "default"
|
||||||
|
// this sets whether to re-render the ui layout with each update (default 0, turning on will break the map ui if it's in use)
|
||||||
|
var/auto_update_layout = 0
|
||||||
|
// this sets whether to re-render the ui content with each update (default 1)
|
||||||
|
var/auto_update_content = 1
|
||||||
|
// the default state to use for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing)
|
||||||
|
var/state_key = "default"
|
||||||
|
// show the map ui, this is used by the default layout
|
||||||
|
var/show_map = 0
|
||||||
|
// the map z level to display
|
||||||
|
var/map_z_level = 1
|
||||||
|
// initial data, containing the full data structure, must be sent to the ui (the data structure cannot be extended later on)
|
||||||
|
var/list/initial_data[0]
|
||||||
|
// set to 1 to update the ui automatically every master_controller tick
|
||||||
|
var/is_auto_updating = 0
|
||||||
|
// the current status/visibility of the ui
|
||||||
|
var/status = STATUS_INTERACTIVE
|
||||||
|
|
||||||
|
// Relationship between a master interface and its children. Used in update_status
|
||||||
|
var/datum/nanoui/master_ui
|
||||||
|
var/list/datum/nanoui/children = list()
|
||||||
|
var/datum/topic_state/state = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new nanoui instance.
|
||||||
|
*
|
||||||
|
* @param nuser /mob The mob who has opened/owns this ui
|
||||||
|
* @param nsrc_object /obj|/mob The obj or mob which this ui belongs to
|
||||||
|
* @param nui_key string A string key to use for this ui. Allows for multiple unique uis on one src_oject
|
||||||
|
* @param ntemplate string The filename of the template file from /nano/templates (e.g. "my_template.tmpl")
|
||||||
|
* @param ntitle string The title of this ui
|
||||||
|
* @param nwidth int the width of the ui window
|
||||||
|
* @param nheight int the height of the ui window
|
||||||
|
* @param nref /atom A custom ref to use if "on_close_logic" is set to 1
|
||||||
|
*
|
||||||
|
* @return /nanoui new nanoui object
|
||||||
|
*/
|
||||||
|
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/state = default_state)
|
||||||
|
user = nuser
|
||||||
|
src_object = nsrc_object
|
||||||
|
ui_key = nui_key
|
||||||
|
window_id = "[ui_key]\ref[src_object]"
|
||||||
|
|
||||||
|
src.master_ui = master_ui
|
||||||
|
if(master_ui)
|
||||||
|
master_ui.children += src
|
||||||
|
src.state = state
|
||||||
|
|
||||||
|
// add the passed template filename as the "main" template, this is required
|
||||||
|
add_template("main", ntemplate_filename)
|
||||||
|
|
||||||
|
if (ntitle)
|
||||||
|
title = sanitize(ntitle)
|
||||||
|
if (nwidth)
|
||||||
|
width = nwidth
|
||||||
|
if (nheight)
|
||||||
|
height = nheight
|
||||||
|
if (nref)
|
||||||
|
ref = nref
|
||||||
|
|
||||||
|
add_common_assets()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this proc to add assets which are common to (and required by) all nano uis
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/add_common_assets()
|
||||||
|
add_script("libraries.min.js") // A JS file comprising of jQuery, doT.js and jQuery Timer libraries (compressed together)
|
||||||
|
add_script("nano_utility.js") // The NanoUtility JS, this is used to store utility functions.
|
||||||
|
add_script("nano_templates_bundle.js") // Contains all templates, generated by asset cache system at server start.
|
||||||
|
add_script("nano_template.js") // The NanoTemplate JS, this is used to render templates.
|
||||||
|
add_script("nano_state_manager.js") // The NanoStateManager JS, it handles updates from the server and passes data to the current state
|
||||||
|
add_script("nano_state.js") // The NanoState JS, this is the base state which all states must inherit from
|
||||||
|
add_script("nano_state_default.js") // The NanoStateDefault JS, this is the "default" state (used by all UIs by default), which inherits from NanoState
|
||||||
|
add_script("nano_base_callbacks.js") // The NanoBaseCallbacks JS, this is used to set up (before and after update) callbacks which are common to all UIs
|
||||||
|
add_script("nano_base_helpers.js") // The NanoBaseHelpers JS, this is used to set up template helpers which are common to all UIs
|
||||||
|
add_stylesheet("shared.css") // this CSS sheet is common to all UIs
|
||||||
|
add_stylesheet("shared_vr.css") // VOREStation Add
|
||||||
|
add_stylesheet("icons.css") // this CSS sheet is common to all UIs
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current status (also known as visibility) of this ui.
|
||||||
|
*
|
||||||
|
* @param state int The status to set, see the defines at the top of this file
|
||||||
|
* @param push_update int (bool) Push an update to the ui to update it's status (an update is always sent if the status has changed to red (0))
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_status(state, push_update)
|
||||||
|
if (state != status) // Only update if it is different
|
||||||
|
if (status == STATUS_DISABLED)
|
||||||
|
status = state
|
||||||
|
if (push_update)
|
||||||
|
update()
|
||||||
|
else
|
||||||
|
status = state
|
||||||
|
if (push_update || status == 0)
|
||||||
|
push_data(null, 1) // Update the UI, force the update in case the status is 0, data is null so that previous data is used
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the status (visibility) of this ui based on the user's status
|
||||||
|
*
|
||||||
|
* @param push_update int (bool) Push an update to the ui to update it's status. This is set to 0/false if an update is going to be pushed anyway (to avoid unnessary updates)
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/update_status(var/push_update = 0)
|
||||||
|
var/obj/host = src_object.nano_host()
|
||||||
|
var/new_status = host.CanUseTopic(user, state)
|
||||||
|
if(master_ui)
|
||||||
|
new_status = min(new_status, master_ui.status)
|
||||||
|
|
||||||
|
set_status(new_status, push_update)
|
||||||
|
if(new_status == STATUS_CLOSE)
|
||||||
|
close()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the ui to auto update (every master_controller tick)
|
||||||
|
*
|
||||||
|
* @param state int (bool) Set auto update to 1 or 0 (true/false)
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_auto_update(nstate = 1)
|
||||||
|
is_auto_updating = nstate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the initial data for the ui. This is vital as the data structure set here cannot be changed when pushing new updates.
|
||||||
|
*
|
||||||
|
* @param data /list The list of data for this ui
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_initial_data(list/data)
|
||||||
|
initial_data = data
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get config data to sent to the ui.
|
||||||
|
*
|
||||||
|
* @return /list config data
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/get_config_data()
|
||||||
|
var/name = "[src_object]"
|
||||||
|
name = sanitize(name)
|
||||||
|
var/list/config_data = list(
|
||||||
|
"title" = title,
|
||||||
|
"srcObject" = list("name" = name),
|
||||||
|
"stateKey" = state_key,
|
||||||
|
"status" = status,
|
||||||
|
"autoUpdateLayout" = auto_update_layout,
|
||||||
|
"autoUpdateContent" = auto_update_content,
|
||||||
|
"showMap" = show_map,
|
||||||
|
"mapZLevel" = map_z_level,
|
||||||
|
"user" = list("name" = user.name)
|
||||||
|
)
|
||||||
|
return config_data
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get data to sent to the ui.
|
||||||
|
*
|
||||||
|
* @param data /list The list of general data for this ui (can be null to use previous data sent)
|
||||||
|
*
|
||||||
|
* @return /list data to send to the ui
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/get_send_data(var/list/data)
|
||||||
|
var/list/config_data = get_config_data()
|
||||||
|
|
||||||
|
var/list/send_data = list("config" = config_data)
|
||||||
|
|
||||||
|
if (!isnull(data))
|
||||||
|
send_data["data"] = data
|
||||||
|
|
||||||
|
return send_data
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the browser window options for this ui
|
||||||
|
*
|
||||||
|
* @param nwindow_options string The new window options
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_window_options(nwindow_options)
|
||||||
|
window_options = nwindow_options
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a CSS stylesheet to this UI
|
||||||
|
* These must be added before the UI has been opened, adding after that will have no effect
|
||||||
|
*
|
||||||
|
* @param file string The name of the CSS file from /nano/css (e.g. "my_style.css")
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/add_stylesheet(file)
|
||||||
|
stylesheets.Add(file)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a JavsScript script to this UI
|
||||||
|
* These must be added before the UI has been opened, adding after that will have no effect
|
||||||
|
*
|
||||||
|
* @param file string The name of the JavaScript file from /nano/js (e.g. "my_script.js")
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/add_script(file)
|
||||||
|
scripts.Add(file)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a template for this UI
|
||||||
|
* Templates are combined with the data sent to the UI to create the rendered view
|
||||||
|
* These must be added before the UI has been opened, adding after that will have no effect
|
||||||
|
*
|
||||||
|
* @param key string The key which is used to reference this template in the frontend
|
||||||
|
* @param filename string The name of the template file from /nano/templates (e.g. "my_template.tmpl")
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/add_template(key, filename)
|
||||||
|
templates[key] = filename
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the layout key for use in the frontend Javascript
|
||||||
|
* The layout key is the basic layout key for the page
|
||||||
|
* Two files are loaded on the client based on the layout key varable:
|
||||||
|
* -> a template in /nano/templates with the filename "layout_<layout_key>.tmpl
|
||||||
|
* -> a CSS stylesheet in /nano/css with the filename "layout_<layout_key>.css
|
||||||
|
*
|
||||||
|
* @param nlayout string The layout key to use
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_layout_key(nlayout_key)
|
||||||
|
layout_key = lowertext(nlayout_key)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the ui to update the layout (re-render it) on each update, turning this on will break the map ui (if it's being used)
|
||||||
|
*
|
||||||
|
* @param state int (bool) Set update to 1 or 0 (true/false) (default 0)
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_auto_update_layout(nstate)
|
||||||
|
auto_update_layout = nstate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the ui to update the main content (re-render it) on each update
|
||||||
|
*
|
||||||
|
* @param state int (bool) Set update to 1 or 0 (true/false) (default 1)
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_auto_update_content(nstate)
|
||||||
|
auto_update_content = nstate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the state key for use in the frontend Javascript
|
||||||
|
*
|
||||||
|
* @param nstate_key string The key of the state to use
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_state_key(nstate_key)
|
||||||
|
state_key = nstate_key
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle showing the map ui
|
||||||
|
*
|
||||||
|
* @param nstate_key boolean 1 to show map, 0 to hide (default is 0)
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_show_map(nstate)
|
||||||
|
show_map = nstate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle showing the map ui
|
||||||
|
*
|
||||||
|
* @param nstate_key boolean 1 to show map, 0 to hide (default is 0)
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/set_map_z_level(nz)
|
||||||
|
map_z_level = nz
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not to use the "old" on close logic (mainly unset_machine())
|
||||||
|
*
|
||||||
|
* @param state int (bool) Set on_close_logic to 1 or 0 (true/false)
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/use_on_close_logic(state)
|
||||||
|
on_close_logic = state
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the HTML for this UI
|
||||||
|
*
|
||||||
|
* @return string HTML for the UI
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/get_html()
|
||||||
|
|
||||||
|
// before the UI opens, add the layout files based on the layout key
|
||||||
|
add_stylesheet("layout_[layout_key].css")
|
||||||
|
add_template("layout", "layout_[layout_key].tmpl")
|
||||||
|
|
||||||
|
var/head_content = ""
|
||||||
|
|
||||||
|
for (var/filename in scripts)
|
||||||
|
head_content += "<script type='text/javascript' src='[filename]'></script> "
|
||||||
|
|
||||||
|
for (var/filename in stylesheets)
|
||||||
|
head_content += "<link rel='stylesheet' type='text/css' href='[filename]'> "
|
||||||
|
|
||||||
|
var/template_data_json = "{}" // An empty JSON object
|
||||||
|
if (templates.len > 0)
|
||||||
|
template_data_json = strip_improper(json_encode(templates))
|
||||||
|
|
||||||
|
var/list/send_data = get_send_data(initial_data)
|
||||||
|
var/initial_data_json = replacetext(replacetext(json_encode(send_data), """, "&#34;"), "'", "'")
|
||||||
|
initial_data_json = strip_improper(initial_data_json);
|
||||||
|
|
||||||
|
var/url_parameters_json = json_encode(list("src" = "\ref[src]"))
|
||||||
|
|
||||||
|
return {"
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<script type='text/javascript'>
|
||||||
|
function receiveUpdateData(jsonString)
|
||||||
|
{
|
||||||
|
// We need both jQuery and NanoStateManager to be able to recieve data
|
||||||
|
// At the moment any data received before those libraries are loaded will be lost
|
||||||
|
if (typeof NanoStateManager != 'undefined' && typeof jQuery != 'undefined')
|
||||||
|
{
|
||||||
|
NanoStateManager.receiveUpdateData(jsonString);
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// alert('browser.recieveUpdateData failed due to jQuery or NanoStateManager being unavailiable.');
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
[head_content]
|
||||||
|
</head>
|
||||||
|
<body scroll=auto data-template-data='[template_data_json]' data-url-parameters='[url_parameters_json]' data-initial-data='[initial_data_json]'>
|
||||||
|
<div id='uiLayout'>
|
||||||
|
</div>
|
||||||
|
<noscript>
|
||||||
|
<div id='uiNoScript'>
|
||||||
|
<h2>JAVASCRIPT REQUIRED</h2>
|
||||||
|
<p>Your Internet Explorer's Javascript is disabled (or broken).<br/>
|
||||||
|
Enable Javascript and then open this UI again.</p>
|
||||||
|
</div>
|
||||||
|
</noscript>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open this UI
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/open()
|
||||||
|
if(!user.client)
|
||||||
|
return
|
||||||
|
|
||||||
|
// An attempted fix to UIs sometimes locking up spamming runtime errors due to src_object being null for whatever reason.
|
||||||
|
// This hard-deletes the UI, preventing the device that uses the UI from being locked up permanently.
|
||||||
|
if(!src_object)
|
||||||
|
del(src)
|
||||||
|
|
||||||
|
var/window_size = ""
|
||||||
|
if (width && height)
|
||||||
|
window_size = "size=[width]x[height];"
|
||||||
|
update_status(0)
|
||||||
|
if(status == STATUS_CLOSE)
|
||||||
|
return
|
||||||
|
|
||||||
|
user << browse(get_html(), "window=[window_id];[window_size][window_options]")
|
||||||
|
winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map
|
||||||
|
on_close_winset()
|
||||||
|
//onclose(user, window_id)
|
||||||
|
SSnanoui.ui_opened(src)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reinitialise this UI, potentially with a different template and/or initial data
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/reinitialise(template, new_initial_data)
|
||||||
|
if(template)
|
||||||
|
add_template("main", template)
|
||||||
|
if(new_initial_data)
|
||||||
|
set_initial_data(new_initial_data)
|
||||||
|
open()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close this UI
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/close()
|
||||||
|
is_auto_updating = 0
|
||||||
|
SSnanoui.ui_closed(src)
|
||||||
|
user << browse(null, "window=[window_id]")
|
||||||
|
for(var/datum/nanoui/child in children)
|
||||||
|
child.close()
|
||||||
|
children.Cut()
|
||||||
|
state = null
|
||||||
|
master_ui = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the UI window to call the nanoclose verb when the window is closed
|
||||||
|
* This allows Nano to handle closed windows
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/on_close_winset()
|
||||||
|
if(!user.client)
|
||||||
|
return
|
||||||
|
var/params = "\ref[src]"
|
||||||
|
|
||||||
|
winset(user, window_id, "on-close=\"nanoclose [params]\"")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push data to an already open UI window
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/push_data(data, force_push = 0)
|
||||||
|
update_status(0)
|
||||||
|
if (status == STATUS_DISABLED && !force_push)
|
||||||
|
return // Cannot update UI, no visibility
|
||||||
|
|
||||||
|
var/list/send_data = get_send_data(data)
|
||||||
|
|
||||||
|
//to_chat(user,list2json_usecache(send_data)) // used for debugging //NANO DEBUG HOOK
|
||||||
|
user << output(list2params(list(strip_improper(json_encode(send_data)))),"[window_id].browser:receiveUpdateData")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Topic() proc is called whenever a user clicks on a link within a Nano UI
|
||||||
|
* If the UI status is currently STATUS_INTERACTIVE then call the src_object Topic()
|
||||||
|
* If the src_object Topic() returns 1 (true) then update all UIs attached to src_object
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/Topic(href, href_list)
|
||||||
|
update_status(0) // update the status
|
||||||
|
if (status != STATUS_INTERACTIVE || user != usr) // If UI is not interactive or usr calling Topic is not the UI user
|
||||||
|
return
|
||||||
|
|
||||||
|
// This is used to toggle the nano map ui
|
||||||
|
var/map_update = 0
|
||||||
|
if(href_list["showMap"])
|
||||||
|
set_show_map(text2num(href_list["showMap"]))
|
||||||
|
map_update = 1
|
||||||
|
|
||||||
|
if(href_list["mapZLevel"])
|
||||||
|
set_map_z_level(text2num(href_list["mapZLevel"]))
|
||||||
|
map_update = 1
|
||||||
|
|
||||||
|
if ((src_object && src_object.Topic(href, href_list, state)) || map_update)
|
||||||
|
SSnanoui.update_uis(src_object) // update all UIs attached to src_object
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process this UI, updating the entire UI or just the status (aka visibility)
|
||||||
|
* This process proc is called by the master_controller
|
||||||
|
*
|
||||||
|
* @param update string For this UI to update
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/process(update = 0)
|
||||||
|
if (!src_object || !user)
|
||||||
|
close()
|
||||||
|
return
|
||||||
|
|
||||||
|
if (status && (update || is_auto_updating))
|
||||||
|
update() // Update the UI (update_status() is called whenever a UI is updated)
|
||||||
|
else
|
||||||
|
update_status(1) // Not updating UI, so lets check here if status has changed
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the UI
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
/datum/nanoui/proc/update(var/force_open = 0)
|
||||||
|
src_object.ui_interact(user, ui_key, src, force_open, master_ui, state)
|
||||||
@@ -269,7 +269,7 @@
|
|||||||
JaniData["user_loc"] = list("x" = 0, "y" = 0)
|
JaniData["user_loc"] = list("x" = 0, "y" = 0)
|
||||||
|
|
||||||
var/MopData[0]
|
var/MopData[0]
|
||||||
for(var/obj/item/weapon/mop/M in all_mops)//GLOB.janitorial_equipment)
|
for(var/obj/item/weapon/mop/M in GLOB.all_mops)//GLOB.janitorial_equipment)
|
||||||
var/turf/ml = get_turf(M)
|
var/turf/ml = get_turf(M)
|
||||||
if(ml)
|
if(ml)
|
||||||
if(ml.z != cl.z)
|
if(ml.z != cl.z)
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
MopData[++MopData.len] = list ("x" = ml.x, "y" = ml.y, "dir" = uppertext(dir2text(direction)), "status" = M.reagents.total_volume ? "Wet" : "Dry")
|
MopData[++MopData.len] = list ("x" = ml.x, "y" = ml.y, "dir" = uppertext(dir2text(direction)), "status" = M.reagents.total_volume ? "Wet" : "Dry")
|
||||||
|
|
||||||
var/BucketData[0]
|
var/BucketData[0]
|
||||||
for(var/obj/structure/mopbucket/B in all_mopbuckets)//GLOB.janitorial_equipment)
|
for(var/obj/structure/mopbucket/B in GLOB.all_mopbuckets)//GLOB.janitorial_equipment)
|
||||||
var/turf/bl = get_turf(B)
|
var/turf/bl = get_turf(B)
|
||||||
if(bl)
|
if(bl)
|
||||||
if(bl.z != cl.z)
|
if(bl.z != cl.z)
|
||||||
@@ -296,7 +296,7 @@
|
|||||||
CbotData[++CbotData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.on ? "Online" : "Offline")
|
CbotData[++CbotData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.on ? "Online" : "Offline")
|
||||||
|
|
||||||
var/CartData[0]
|
var/CartData[0]
|
||||||
for(var/obj/structure/janitorialcart/B in all_janitorial_carts)//GLOB.janitorial_equipment)
|
for(var/obj/structure/janitorialcart/B in GLOB.all_janitorial_carts)//GLOB.janitorial_equipment)
|
||||||
var/turf/bl = get_turf(B)
|
var/turf/bl = get_turf(B)
|
||||||
if(bl)
|
if(bl)
|
||||||
if(bl.z != cl.z)
|
if(bl.z != cl.z)
|
||||||
|
|||||||
@@ -1,500 +1,3 @@
|
|||||||
<<<<<<< HEAD
|
|
||||||
#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times
|
|
||||||
|
|
||||||
/datum/reagents
|
|
||||||
var/list/datum/reagent/reagent_list = list()
|
|
||||||
var/total_volume = 0
|
|
||||||
var/maximum_volume = 100
|
|
||||||
var/atom/my_atom = null
|
|
||||||
|
|
||||||
/datum/reagents/New(var/max = 100, atom/A = null)
|
|
||||||
..()
|
|
||||||
maximum_volume = max
|
|
||||||
my_atom = A
|
|
||||||
|
|
||||||
//I dislike having these here but map-objects are initialised before world/New() is called. >_>
|
|
||||||
if(!SSchemistry.chemical_reagents)
|
|
||||||
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
|
|
||||||
var/paths = typesof(/datum/reagent) - /datum/reagent
|
|
||||||
SSchemistry.chemical_reagents = list()
|
|
||||||
for(var/path in paths)
|
|
||||||
var/datum/reagent/D = new path()
|
|
||||||
if(!D.name)
|
|
||||||
continue
|
|
||||||
SSchemistry.chemical_reagents[D.id] = D
|
|
||||||
|
|
||||||
/datum/reagents/Destroy()
|
|
||||||
STOP_PROCESSING(SSchemistry, src)
|
|
||||||
for(var/datum/reagent/R in reagent_list)
|
|
||||||
qdel(R)
|
|
||||||
reagent_list = null
|
|
||||||
if(my_atom && my_atom.reagents == src)
|
|
||||||
my_atom.reagents = null
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
/* Internal procs */
|
|
||||||
|
|
||||||
/datum/reagents/proc/get_free_space() // Returns free space.
|
|
||||||
return maximum_volume - total_volume
|
|
||||||
|
|
||||||
/datum/reagents/proc/get_master_reagent() // Returns reference to the reagent with the biggest volume.
|
|
||||||
var/the_reagent = null
|
|
||||||
var/the_volume = 0
|
|
||||||
|
|
||||||
for(var/datum/reagent/A in reagent_list)
|
|
||||||
if(A.volume > the_volume)
|
|
||||||
the_volume = A.volume
|
|
||||||
the_reagent = A
|
|
||||||
|
|
||||||
return the_reagent
|
|
||||||
|
|
||||||
/datum/reagents/proc/get_master_reagent_name() // Returns the name of the reagent with the biggest volume.
|
|
||||||
var/the_name = null
|
|
||||||
var/the_volume = 0
|
|
||||||
for(var/datum/reagent/A in reagent_list)
|
|
||||||
if(A.volume > the_volume)
|
|
||||||
the_volume = A.volume
|
|
||||||
the_name = A.name
|
|
||||||
|
|
||||||
return the_name
|
|
||||||
|
|
||||||
/datum/reagents/proc/get_master_reagent_id() // Returns the id of the reagent with the biggest volume.
|
|
||||||
var/the_id = null
|
|
||||||
var/the_volume = 0
|
|
||||||
for(var/datum/reagent/A in reagent_list)
|
|
||||||
if(A.volume > the_volume)
|
|
||||||
the_volume = A.volume
|
|
||||||
the_id = A.id
|
|
||||||
|
|
||||||
return the_id
|
|
||||||
|
|
||||||
/datum/reagents/proc/update_total() // Updates volume.
|
|
||||||
total_volume = 0
|
|
||||||
for(var/datum/reagent/R in reagent_list)
|
|
||||||
if(R.volume < MINIMUM_CHEMICAL_VOLUME)
|
|
||||||
del_reagent(R.id)
|
|
||||||
else
|
|
||||||
total_volume += R.volume
|
|
||||||
return
|
|
||||||
|
|
||||||
/datum/reagents/proc/handle_reactions()
|
|
||||||
if(QDELETED(my_atom))
|
|
||||||
return FALSE
|
|
||||||
if(my_atom.flags & NOREACT)
|
|
||||||
return FALSE
|
|
||||||
var/reaction_occurred
|
|
||||||
var/list/eligible_reactions = list()
|
|
||||||
var/list/effect_reactions = list()
|
|
||||||
do
|
|
||||||
reaction_occurred = FALSE
|
|
||||||
for(var/i in reagent_list)
|
|
||||||
var/datum/reagent/R = i
|
|
||||||
if(SSchemistry.chemical_reactions_by_reagent[R.id])
|
|
||||||
eligible_reactions |= SSchemistry.chemical_reactions_by_reagent[R.id]
|
|
||||||
|
|
||||||
for(var/i in eligible_reactions)
|
|
||||||
var/datum/chemical_reaction/C = i
|
|
||||||
if(C.can_happen(src) && C.process(src))
|
|
||||||
effect_reactions |= C
|
|
||||||
reaction_occurred = TRUE
|
|
||||||
eligible_reactions.len = 0
|
|
||||||
while(reaction_occurred)
|
|
||||||
for(var/i in effect_reactions)
|
|
||||||
var/datum/chemical_reaction/C = i
|
|
||||||
C.post_reaction(src)
|
|
||||||
update_total()
|
|
||||||
|
|
||||||
/* Holder-to-chemical */
|
|
||||||
|
|
||||||
/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0)
|
|
||||||
if(!isnum(amount) || amount <= 0)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
update_total()
|
|
||||||
amount = min(amount, get_free_space())
|
|
||||||
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if(current.id == id)
|
|
||||||
if(current.id == "blood")
|
|
||||||
if(LAZYLEN(data) && !isnull(data["species"]) && !isnull(current.data["species"]) && data["species"] != current.data["species"]) // Species bloodtypes are already incompatible, this just stops it from mixing into the one already in a container.
|
|
||||||
continue
|
|
||||||
|
|
||||||
current.volume += amount
|
|
||||||
if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful
|
|
||||||
current.mix_data(data, amount)
|
|
||||||
update_total()
|
|
||||||
if(!safety)
|
|
||||||
handle_reactions()
|
|
||||||
if(my_atom)
|
|
||||||
my_atom.on_reagent_change()
|
|
||||||
return 1
|
|
||||||
var/datum/reagent/D = SSchemistry.chemical_reagents[id]
|
|
||||||
if(D)
|
|
||||||
var/datum/reagent/R = new D.type()
|
|
||||||
reagent_list += R
|
|
||||||
R.holder = src
|
|
||||||
R.volume = amount
|
|
||||||
R.initialize_data(data)
|
|
||||||
update_total()
|
|
||||||
if(!safety)
|
|
||||||
handle_reactions()
|
|
||||||
if(my_atom)
|
|
||||||
my_atom.on_reagent_change()
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagents/proc/isolate_reagent(reagent)
|
|
||||||
for(var/A in reagent_list)
|
|
||||||
var/datum/reagent/R = A
|
|
||||||
if(R.id != reagent)
|
|
||||||
del_reagent(R.id)
|
|
||||||
update_total()
|
|
||||||
|
|
||||||
/datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0)
|
|
||||||
if(!isnum(amount))
|
|
||||||
return 0
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if(current.id == id)
|
|
||||||
current.volume -= amount // It can go negative, but it doesn't matter
|
|
||||||
update_total() // Because this proc will delete it then
|
|
||||||
if(!safety)
|
|
||||||
handle_reactions()
|
|
||||||
if(my_atom)
|
|
||||||
my_atom.on_reagent_change()
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagents/proc/del_reagent(var/id)
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if (current.id == id)
|
|
||||||
reagent_list -= current
|
|
||||||
qdel(current)
|
|
||||||
update_total()
|
|
||||||
if(my_atom)
|
|
||||||
my_atom.on_reagent_change()
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagents/proc/has_reagent(var/id, var/amount = 0)
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if(current.id == id)
|
|
||||||
if(current.volume >= amount)
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagents/proc/has_any_reagent(var/list/check_reagents)
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if(current.id in check_reagents)
|
|
||||||
if(current.volume >= check_reagents[current.id])
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagents/proc/has_all_reagents(var/list/check_reagents)
|
|
||||||
//this only works if check_reagents has no duplicate entries... hopefully okay since it expects an associative list
|
|
||||||
var/missing = check_reagents.len
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if(current.id in check_reagents)
|
|
||||||
if(current.volume >= check_reagents[current.id])
|
|
||||||
missing--
|
|
||||||
return !missing
|
|
||||||
|
|
||||||
/datum/reagents/proc/clear_reagents()
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
del_reagent(current.id)
|
|
||||||
return
|
|
||||||
|
|
||||||
/datum/reagents/proc/get_reagent_amount(var/id)
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if(current.id == id)
|
|
||||||
return current.volume
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagents/proc/get_data(var/id)
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
if(current.id == id)
|
|
||||||
return current.get_data()
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagents/proc/get_reagents()
|
|
||||||
. = list()
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
. += "[current.id] ([current.volume])"
|
|
||||||
return english_list(., "EMPTY", "", ", ", ", ")
|
|
||||||
|
|
||||||
/* Holder-to-holder and similar procs */
|
|
||||||
|
|
||||||
/datum/reagents/proc/remove_any(var/amount = 1) // Removes up to [amount] of reagents from [src]. Returns actual amount removed.
|
|
||||||
amount = min(amount, total_volume)
|
|
||||||
|
|
||||||
if(!amount)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/part = amount / total_volume
|
|
||||||
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
var/amount_to_remove = current.volume * part
|
|
||||||
remove_reagent(current.id, amount_to_remove, 1)
|
|
||||||
|
|
||||||
update_total()
|
|
||||||
handle_reactions()
|
|
||||||
return amount
|
|
||||||
|
|
||||||
/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]).
|
|
||||||
if(!target || !istype(target))
|
|
||||||
return
|
|
||||||
|
|
||||||
amount = max(0, min(amount, total_volume, target.get_free_space() / multiplier))
|
|
||||||
|
|
||||||
if(!amount)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/part = amount / total_volume
|
|
||||||
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
var/amount_to_transfer = current.volume * part
|
|
||||||
target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1) // We don't react until everything is in place
|
|
||||||
if(!copy)
|
|
||||||
remove_reagent(current.id, amount_to_transfer, 1)
|
|
||||||
|
|
||||||
if(!copy)
|
|
||||||
handle_reactions()
|
|
||||||
target.handle_reactions()
|
|
||||||
return amount
|
|
||||||
|
|
||||||
/* Holder-to-atom and similar procs */
|
|
||||||
|
|
||||||
//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally,
|
|
||||||
//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob().
|
|
||||||
//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person),
|
|
||||||
//call the appropriate trans_to_*() proc.
|
|
||||||
/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
|
|
||||||
touch(target) //First, handle mere touch effects
|
|
||||||
|
|
||||||
if(ismob(target))
|
|
||||||
return splash_mob(target, amount, copy)
|
|
||||||
if(isturf(target))
|
|
||||||
return trans_to_turf(target, amount, multiplier, copy)
|
|
||||||
if(isobj(target) && target.is_open_container())
|
|
||||||
return trans_to_obj(target, amount, multiplier, copy)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
//Splashing reagents is messier than trans_to, the target's loc gets some of the reagents as well.
|
|
||||||
/datum/reagents/proc/splash(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/min_spill=0, var/max_spill=60)
|
|
||||||
var/spill = 0
|
|
||||||
if(!isturf(target) && target.loc)
|
|
||||||
spill = amount*(rand(min_spill, max_spill)/100)
|
|
||||||
amount -= spill
|
|
||||||
if(spill)
|
|
||||||
splash(target.loc, spill, multiplier, copy, min_spill, max_spill)
|
|
||||||
|
|
||||||
trans_to(target, amount, multiplier, copy)
|
|
||||||
|
|
||||||
/datum/reagents/proc/trans_type_to(var/target, var/rtype, var/amount = 1)
|
|
||||||
if (!target)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/datum/reagent/transfering_reagent = get_reagent(rtype)
|
|
||||||
|
|
||||||
if (istype(target, /atom))
|
|
||||||
var/atom/A = target
|
|
||||||
if (!A.reagents || !A.simulated)
|
|
||||||
return
|
|
||||||
|
|
||||||
amount = min(amount, transfering_reagent.volume)
|
|
||||||
|
|
||||||
if(!amount)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
var/datum/reagents/F = new /datum/reagents(amount)
|
|
||||||
var/tmpdata = get_data(rtype)
|
|
||||||
F.add_reagent(rtype, amount, tmpdata)
|
|
||||||
remove_reagent(rtype, amount)
|
|
||||||
|
|
||||||
|
|
||||||
if (istype(target, /atom))
|
|
||||||
return F.trans_to(target, amount) // Let this proc check the atom's type
|
|
||||||
else if (istype(target, /datum/reagents))
|
|
||||||
return F.trans_to_holder(target, amount)
|
|
||||||
|
|
||||||
/datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1)
|
|
||||||
if (!target || !target.reagents)
|
|
||||||
return
|
|
||||||
|
|
||||||
amount = min(amount, get_reagent_amount(id))
|
|
||||||
|
|
||||||
if(!amount)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/datum/reagents/F = new /datum/reagents(amount)
|
|
||||||
var/tmpdata = get_data(id)
|
|
||||||
F.add_reagent(id, amount, tmpdata)
|
|
||||||
remove_reagent(id, amount)
|
|
||||||
|
|
||||||
return F.trans_to(target, amount) // Let this proc check the atom's type
|
|
||||||
|
|
||||||
// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent.
|
|
||||||
// This does not handle transferring reagents to things.
|
|
||||||
// For example, splashing someone with water will get them wet and extinguish them if they are on fire,
|
|
||||||
// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin.
|
|
||||||
/datum/reagents/proc/touch(var/atom/target, var/amount)
|
|
||||||
if(ismob(target))
|
|
||||||
touch_mob(target, amount)
|
|
||||||
if(isturf(target))
|
|
||||||
touch_turf(target, amount)
|
|
||||||
if(isobj(target))
|
|
||||||
touch_obj(target, amount)
|
|
||||||
return
|
|
||||||
|
|
||||||
/datum/reagents/proc/touch_mob(var/mob/target)
|
|
||||||
if(!target || !istype(target))
|
|
||||||
return
|
|
||||||
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
current.touch_mob(target, current.volume)
|
|
||||||
|
|
||||||
update_total()
|
|
||||||
|
|
||||||
/datum/reagents/proc/touch_turf(var/turf/target, var/amount)
|
|
||||||
if(!target || !istype(target))
|
|
||||||
return
|
|
||||||
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
current.touch_turf(target, amount)
|
|
||||||
|
|
||||||
update_total()
|
|
||||||
|
|
||||||
/datum/reagents/proc/touch_obj(var/obj/target, var/amount)
|
|
||||||
if(!target || !istype(target))
|
|
||||||
return
|
|
||||||
|
|
||||||
for(var/datum/reagent/current in reagent_list)
|
|
||||||
current.touch_obj(target, amount)
|
|
||||||
|
|
||||||
update_total()
|
|
||||||
|
|
||||||
// Attempts to place a reagent on the mob's skin.
|
|
||||||
// Reagents are not guaranteed to transfer to the target.
|
|
||||||
// Do not call this directly, call trans_to() instead.
|
|
||||||
/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/copy = 0)
|
|
||||||
var/perm = 1
|
|
||||||
if(isliving(target)) //will we ever even need to tranfer reagents to non-living mobs?
|
|
||||||
var/mob/living/L = target
|
|
||||||
if(ishuman(L))
|
|
||||||
var/mob/living/carbon/human/H = L
|
|
||||||
if(H.check_shields(0, null, null, null, "the spray") == 1) //If they block the spray, it does nothing.
|
|
||||||
amount = 0
|
|
||||||
perm = L.reagent_permeability()
|
|
||||||
return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy)
|
|
||||||
|
|
||||||
/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder...
|
|
||||||
if(!target || !istype(target))
|
|
||||||
return
|
|
||||||
if(iscarbon(target))
|
|
||||||
var/mob/living/carbon/C = target
|
|
||||||
if(type == CHEM_BLOOD)
|
|
||||||
var/datum/reagents/R = C.reagents
|
|
||||||
return trans_to_holder(R, amount, multiplier, copy)
|
|
||||||
if(type == CHEM_INGEST)
|
|
||||||
var/datum/reagents/R = C.ingested
|
|
||||||
return C.ingest(src, R, amount, multiplier, copy)
|
|
||||||
if(type == CHEM_TOUCH)
|
|
||||||
var/datum/reagents/R = C.touching
|
|
||||||
return trans_to_holder(R, amount, multiplier, copy)
|
|
||||||
else
|
|
||||||
var/datum/reagents/R = new /datum/reagents(amount)
|
|
||||||
. = trans_to_holder(R, amount, multiplier, copy)
|
|
||||||
R.touch_mob(target)
|
|
||||||
|
|
||||||
/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it.
|
|
||||||
if(!target)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/datum/reagents/R = new /datum/reagents(amount * multiplier)
|
|
||||||
. = trans_to_holder(R, amount, multiplier, copy)
|
|
||||||
R.touch_turf(target, amount)
|
|
||||||
return
|
|
||||||
|
|
||||||
/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch.
|
|
||||||
if(!target)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(!target.reagents)
|
|
||||||
var/datum/reagents/R = new /datum/reagents(amount * multiplier)
|
|
||||||
. = trans_to_holder(R, amount, multiplier, copy)
|
|
||||||
R.touch_obj(target, amount)
|
|
||||||
return
|
|
||||||
|
|
||||||
return trans_to_holder(target.reagents, amount, multiplier, copy)
|
|
||||||
|
|
||||||
/* Atom reagent creation - use it all the time */
|
|
||||||
|
|
||||||
/atom/proc/create_reagents(var/max_vol)
|
|
||||||
reagents = new/datum/reagents(max_vol, src)
|
|
||||||
|
|
||||||
// Aurora Cooking Port
|
|
||||||
/datum/reagents/proc/get_reagent(var/id) // Returns reference to reagent matching passed ID
|
|
||||||
for(var/datum/reagent/A in reagent_list)
|
|
||||||
if (A.id == id)
|
|
||||||
return A
|
|
||||||
|
|
||||||
return null
|
|
||||||
|
|
||||||
//Spreads the contents of this reagent holder all over the vicinity of the target turf.
|
|
||||||
/datum/reagents/proc/splash_area(var/turf/epicentre, var/range = 3, var/portion = 1.0, var/multiplier = 1, var/copy = 0)
|
|
||||||
var/list/things = dview(range, epicentre, INVISIBILITY_LIGHTING)
|
|
||||||
var/list/turfs = list()
|
|
||||||
for (var/turf/T in things)
|
|
||||||
turfs += T
|
|
||||||
if (!turfs.len)
|
|
||||||
return//Nowhere to splash to, somehow
|
|
||||||
//Create a temporary holder to hold all the amount that will be spread
|
|
||||||
var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier)
|
|
||||||
trans_to_holder(R, total_volume * portion, multiplier, copy)
|
|
||||||
//The exact amount that will be given to each turf
|
|
||||||
var/turfportion = R.total_volume / turfs.len
|
|
||||||
for (var/turf/T in turfs)
|
|
||||||
var/datum/reagents/TR = new /datum/reagents(turfportion)
|
|
||||||
R.trans_to_holder(TR, turfportion, 1, 0)
|
|
||||||
TR.splash_turf(T)
|
|
||||||
qdel(R)
|
|
||||||
|
|
||||||
|
|
||||||
//Spreads the contents of this reagent holder all over the target turf, dividing among things in it.
|
|
||||||
//50% is divided between mobs, 20% between objects, and whatever is left on the turf itself
|
|
||||||
/datum/reagents/proc/splash_turf(var/turf/T, var/amount = null, var/multiplier = 1, var/copy = 0)
|
|
||||||
if (isnull(amount))
|
|
||||||
amount = total_volume
|
|
||||||
else
|
|
||||||
amount = min(amount, total_volume)
|
|
||||||
if (amount <= 0)
|
|
||||||
return
|
|
||||||
var/list/mobs = list()
|
|
||||||
for (var/mob/M in T)
|
|
||||||
mobs += M
|
|
||||||
var/list/objs = list()
|
|
||||||
for (var/obj/O in T)
|
|
||||||
objs += O
|
|
||||||
if (objs.len)
|
|
||||||
var/objportion = (amount * 0.2) / objs.len
|
|
||||||
for (var/o in objs)
|
|
||||||
var/obj/O = o
|
|
||||||
trans_to(O, objportion, multiplier, copy)
|
|
||||||
amount = min(amount, total_volume)
|
|
||||||
if (mobs.len)
|
|
||||||
var/mobportion = (amount * 0.5) / mobs.len
|
|
||||||
for (var/m in mobs)
|
|
||||||
var/mob/M = m
|
|
||||||
trans_to(M, mobportion, multiplier, copy)
|
|
||||||
trans_to(T, total_volume, multiplier, copy)
|
|
||||||
if (total_volume <= 0)
|
|
||||||
qdel(src)
|
|
||||||
=======
|
|
||||||
#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times
|
#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times
|
||||||
|
|
||||||
/datum/reagents
|
/datum/reagents
|
||||||
@@ -990,5 +493,4 @@
|
|||||||
trans_to(M, mobportion, multiplier, copy)
|
trans_to(M, mobportion, multiplier, copy)
|
||||||
trans_to(T, total_volume, multiplier, copy)
|
trans_to(T, total_volume, multiplier, copy)
|
||||||
if (total_volume <= 0)
|
if (total_volume <= 0)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
>>>>>>> master-holder
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
var/list/L = list()
|
var/list/L = list()
|
||||||
var/list/areaindex = list()
|
var/list/areaindex = list()
|
||||||
|
|
||||||
for(var/obj/item/device/radio/beacon/R in all_beacons)
|
for(var/obj/item/device/radio/beacon/R in GLOB.all_beacons)
|
||||||
var/turf/T = get_turf(R)
|
var/turf/T = get_turf(R)
|
||||||
if(!T)
|
if(!T)
|
||||||
continue
|
continue
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
areaindex[tmpname] = 1
|
areaindex[tmpname] = 1
|
||||||
L[tmpname] = R
|
L[tmpname] = R
|
||||||
|
|
||||||
for(var/obj/item/weapon/implant/tracking/I in all_tracking_implants)
|
for(var/obj/item/weapon/implant/tracking/I in GLOB.all_tracking_implants)
|
||||||
if(!I.implanted || !ismob(I.loc))
|
if(!I.implanted || !ismob(I.loc))
|
||||||
continue
|
continue
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -122,8 +122,4 @@
|
|||||||
/mob/living/carbon/human/shared_living_tgui_distance(atom/movable/src_object)
|
/mob/living/carbon/human/shared_living_tgui_distance(atom/movable/src_object)
|
||||||
if((TK in mutations) && (get_dist(src, src_object) <= 2))
|
if((TK in mutations) && (get_dist(src, src_object) <= 2))
|
||||||
return STATUS_INTERACTIVE
|
return STATUS_INTERACTIVE
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
// Topic Extensions for old UIs
|
|
||||||
/datum/proc/CanUseTopic(var/mob/user, var/datum/tgui_state/state)
|
|
||||||
return tgui_status(user, state)
|
|
||||||
@@ -9,12 +9,4 @@ GLOBAL_DATUM_INIT(tgui_deep_inventory_state, /datum/tgui_state/deep_inventory_st
|
|||||||
/datum/tgui_state/deep_inventory_state/can_use_topic(src_object, mob/user)
|
/datum/tgui_state/deep_inventory_state/can_use_topic(src_object, mob/user)
|
||||||
if(!user.contains(src_object))
|
if(!user.contains(src_object))
|
||||||
return STATUS_CLOSE
|
return STATUS_CLOSE
|
||||||
return user.shared_tgui_interaction(src_object)
|
return user.shared_tgui_interaction(src_object)
|
||||||
|
|
||||||
/atom/proc/contains(var/atom/location)
|
|
||||||
if(!location)
|
|
||||||
return 0
|
|
||||||
if(location == src)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
return contains(location.loc)
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -109,6 +109,7 @@
|
|||||||
#include "code\_global_vars\bitfields.dm"
|
#include "code\_global_vars\bitfields.dm"
|
||||||
#include "code\_global_vars\misc.dm"
|
#include "code\_global_vars\misc.dm"
|
||||||
#include "code\_global_vars\mobs.dm"
|
#include "code\_global_vars\mobs.dm"
|
||||||
|
#include "code\_global_vars\religion.dm"
|
||||||
#include "code\_global_vars\roundstats.dm"
|
#include "code\_global_vars\roundstats.dm"
|
||||||
#include "code\_global_vars\sensitive.dm"
|
#include "code\_global_vars\sensitive.dm"
|
||||||
#include "code\_global_vars\lists\mapping.dm"
|
#include "code\_global_vars\lists\mapping.dm"
|
||||||
@@ -268,6 +269,7 @@
|
|||||||
#include "code\controllers\subsystems\machines.dm"
|
#include "code\controllers\subsystems\machines.dm"
|
||||||
#include "code\controllers\subsystems\mapping.dm"
|
#include "code\controllers\subsystems\mapping.dm"
|
||||||
#include "code\controllers\subsystems\mobs.dm"
|
#include "code\controllers\subsystems\mobs.dm"
|
||||||
|
#include "code\controllers\subsystems\nanoui.dm"
|
||||||
#include "code\controllers\subsystems\nightshift.dm"
|
#include "code\controllers\subsystems\nightshift.dm"
|
||||||
#include "code\controllers\subsystems\open_space.dm"
|
#include "code\controllers\subsystems\open_space.dm"
|
||||||
#include "code\controllers\subsystems\orbits.dm"
|
#include "code\controllers\subsystems\orbits.dm"
|
||||||
@@ -1193,6 +1195,7 @@
|
|||||||
#include "code\game\objects\items\devices\uplink_random_lists.dm"
|
#include "code\game\objects\items\devices\uplink_random_lists.dm"
|
||||||
#include "code\game\objects\items\devices\violin.dm"
|
#include "code\game\objects\items\devices\violin.dm"
|
||||||
#include "code\game\objects\items\devices\whistle.dm"
|
#include "code\game\objects\items\devices\whistle.dm"
|
||||||
|
#include "code\game\objects\items\devices\communicator\cartridge.dm"
|
||||||
#include "code\game\objects\items\devices\communicator\communicator.dm"
|
#include "code\game\objects\items\devices\communicator\communicator.dm"
|
||||||
#include "code\game\objects\items\devices\communicator\helper.dm"
|
#include "code\game\objects\items\devices\communicator\helper.dm"
|
||||||
#include "code\game\objects\items\devices\communicator\integrated.dm"
|
#include "code\game\objects\items\devices\communicator\integrated.dm"
|
||||||
@@ -3150,6 +3153,25 @@
|
|||||||
#include "code\modules\multiz\turf.dm"
|
#include "code\modules\multiz\turf.dm"
|
||||||
#include "code\modules\multiz\turf_yw.dm"
|
#include "code\modules\multiz\turf_yw.dm"
|
||||||
#include "code\modules\multiz\zshadow.dm"
|
#include "code\modules\multiz\zshadow.dm"
|
||||||
|
#include "code\modules\nano\nanoexternal.dm"
|
||||||
|
#include "code\modules\nano\nanomanager.dm"
|
||||||
|
#include "code\modules\nano\nanomapgen.dm"
|
||||||
|
#include "code\modules\nano\nanoui.dm"
|
||||||
|
#include "code\modules\nano\interaction\admin.dm"
|
||||||
|
#include "code\modules\nano\interaction\base.dm"
|
||||||
|
#include "code\modules\nano\interaction\conscious.dm"
|
||||||
|
#include "code\modules\nano\interaction\contained.dm"
|
||||||
|
#include "code\modules\nano\interaction\default.dm"
|
||||||
|
#include "code\modules\nano\interaction\default_vr.dm"
|
||||||
|
#include "code\modules\nano\interaction\interactive.dm"
|
||||||
|
#include "code\modules\nano\interaction\inventory.dm"
|
||||||
|
#include "code\modules\nano\interaction\inventory_deep.dm"
|
||||||
|
#include "code\modules\nano\interaction\inventory_vr.dm"
|
||||||
|
#include "code\modules\nano\interaction\outside.dm"
|
||||||
|
#include "code\modules\nano\interaction\physical.dm"
|
||||||
|
#include "code\modules\nano\interaction\remote.dm"
|
||||||
|
#include "code\modules\nano\interaction\self.dm"
|
||||||
|
#include "code\modules\nano\interaction\zlevel.dm"
|
||||||
#include "code\modules\nifsoft\nif.dm"
|
#include "code\modules\nifsoft\nif.dm"
|
||||||
#include "code\modules\nifsoft\nif_softshop.dm"
|
#include "code\modules\nifsoft\nif_softshop.dm"
|
||||||
#include "code\modules\nifsoft\nif_statpanel.dm"
|
#include "code\modules\nifsoft\nif_statpanel.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user