mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-09 16:12:17 +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, \
|
||||
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."
|
||||
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
|
||||
/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
|
||||
/datum/alt_title/overseer
|
||||
title = "Overseer"
|
||||
|
||||
/datum/alt_title/colonydirector //CHOMPEdit
|
||||
title = "Colony Director" //CHOMPEdit
|
||||
//////////////////////////////////
|
||||
// Head of Personnel
|
||||
//////////////////////////////////
|
||||
|
||||
@@ -54,7 +54,7 @@ var/list/assistant_occupations = list(
|
||||
|
||||
|
||||
var/list/command_positions = list(
|
||||
"Colony Director",
|
||||
"Site Manager",
|
||||
"Head of Personnel",
|
||||
"Head of Security",
|
||||
"Chief Engineer",
|
||||
@@ -136,7 +136,7 @@ var/list/nonhuman_positions = list(
|
||||
)
|
||||
|
||||
var/list/whitelisted_positions = list(
|
||||
"Colony Director",
|
||||
"Site Manager",
|
||||
"Head of Personnel",
|
||||
"Head of Security",
|
||||
"Chief Engineer",
|
||||
|
||||
@@ -233,10 +233,6 @@
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Cannot issue pass without issuing ID.</span>")
|
||||
|
||||
<<<<<<< HEAD
|
||||
add_fingerprint(usr)
|
||||
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'
|
||||
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/perunit = SHEET_MATERIAL_AMOUNT
|
||||
var/apply_colour //CHOMPEDIT: End
|
||||
|
||||
@@ -17,4 +17,4 @@
|
||||
display_name = "AR-B glasses (CD, HoP, BSG)"
|
||||
path = /obj/item/clothing/glasses/omnihud/all
|
||||
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
|
||||
display_name = "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
|
||||
display_name = "nullsuit, sec"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<<<<<<< HEAD
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//Glasses
|
||||
/*
|
||||
@@ -33,7 +32,9 @@ BLIND // can't see anything
|
||||
|
||||
sprite_sheets = list(
|
||||
"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()
|
||||
@@ -544,528 +545,3 @@ BLIND // can't see anything
|
||||
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")
|
||||
=======
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//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
|
||||
name = "oven"
|
||||
desc = "Cookies are ready, dear."
|
||||
@@ -310,4 +153,3 @@
|
||||
return
|
||||
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
|
||||
|
||||
/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_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), \
|
||||
))
|
||||
|
||||
/material/plastic/generate_recipes()
|
||||
/datum/material/plastic/generate_recipes()
|
||||
. = ..()
|
||||
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]"), \
|
||||
@@ -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]"), \
|
||||
))
|
||||
|
||||
/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( \
|
||||
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
|
||||
|
||||
/material/carpet
|
||||
/datum/material/carpet
|
||||
name = MAT_CARPET
|
||||
display_name = "comfy"
|
||||
use_name = "upholstery"
|
||||
@@ -14,42 +14,42 @@
|
||||
protectiveness = 1 // 4%
|
||||
conductive = 0
|
||||
|
||||
/material/carpet/teal
|
||||
/datum/material/carpet/teal
|
||||
name = MAT_CARPET_TEAL
|
||||
icon_colour = "#007575"
|
||||
stack_type = /obj/item/stack/tile/carpet/teal
|
||||
|
||||
/material/carpet/bcarpet
|
||||
/datum/material/carpet/bcarpet
|
||||
name = MAT_CARPET_BLACK
|
||||
icon_colour = "#1B171E"
|
||||
stack_type = /obj/item/stack/tile/carpet/bcarpet
|
||||
|
||||
/material/carpet/blucarpet
|
||||
/datum/material/carpet/blucarpet
|
||||
name = MAT_CARPET_BLUE
|
||||
icon_colour = "#122CDF"
|
||||
stack_type = /obj/item/stack/tile/carpet/blucarpet
|
||||
|
||||
/material/carpet/turcarpet
|
||||
/datum/material/carpet/turcarpet
|
||||
name = MAT_CARPET_TURQUOISE
|
||||
icon_colour = "#41A997"
|
||||
stack_type = /obj/item/stack/tile/carpet/turcarpet
|
||||
|
||||
/material/carpet/sblucarpet
|
||||
/datum/material/carpet/sblucarpet
|
||||
name = MAT_CARPET_SILVERBLUE
|
||||
icon_colour = "#547EC6"
|
||||
stack_type = /obj/item/stack/tile/carpet/sblucarpet
|
||||
|
||||
/material/carpet/gaycarpet
|
||||
/datum/material/carpet/gaycarpet
|
||||
name = MAT_CARPET_PINK
|
||||
icon_colour = "#E12C87"
|
||||
stack_type = /obj/item/stack/tile/carpet/gaycarpet
|
||||
|
||||
/material/carpet/purcarpet
|
||||
/datum/material/carpet/purcarpet
|
||||
name = MAT_CARPET_PURPLE
|
||||
icon_colour = "#B500A6"
|
||||
stack_type = /obj/item/stack/tile/carpet/purcarpet
|
||||
|
||||
/material/carpet/oracarpet
|
||||
/datum/material/carpet/oracarpet
|
||||
name = MAT_CARPET_ORANGE
|
||||
icon_colour = "#D1D000"
|
||||
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)
|
||||
|
||||
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)
|
||||
if(ml)
|
||||
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")
|
||||
|
||||
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)
|
||||
if(bl)
|
||||
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")
|
||||
|
||||
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)
|
||||
if(bl)
|
||||
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
|
||||
|
||||
/datum/reagents
|
||||
@@ -991,4 +494,3 @@
|
||||
trans_to(T, total_volume, multiplier, copy)
|
||||
if (total_volume <= 0)
|
||||
qdel(src)
|
||||
>>>>>>> master-holder
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
var/list/L = 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)
|
||||
if(!T)
|
||||
continue
|
||||
@@ -39,7 +39,7 @@
|
||||
areaindex[tmpname] = 1
|
||||
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))
|
||||
continue
|
||||
else
|
||||
|
||||
@@ -123,7 +123,3 @@
|
||||
if((TK in mutations) && (get_dist(src, src_object) <= 2))
|
||||
return STATUS_INTERACTIVE
|
||||
return ..()
|
||||
|
||||
// Topic Extensions for old UIs
|
||||
/datum/proc/CanUseTopic(var/mob/user, var/datum/tgui_state/state)
|
||||
return tgui_status(user, state)
|
||||
@@ -10,11 +10,3 @@ GLOBAL_DATUM_INIT(tgui_deep_inventory_state, /datum/tgui_state/deep_inventory_st
|
||||
if(!user.contains(src_object))
|
||||
return STATUS_CLOSE
|
||||
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\misc.dm"
|
||||
#include "code\_global_vars\mobs.dm"
|
||||
#include "code\_global_vars\religion.dm"
|
||||
#include "code\_global_vars\roundstats.dm"
|
||||
#include "code\_global_vars\sensitive.dm"
|
||||
#include "code\_global_vars\lists\mapping.dm"
|
||||
@@ -268,6 +269,7 @@
|
||||
#include "code\controllers\subsystems\machines.dm"
|
||||
#include "code\controllers\subsystems\mapping.dm"
|
||||
#include "code\controllers\subsystems\mobs.dm"
|
||||
#include "code\controllers\subsystems\nanoui.dm"
|
||||
#include "code\controllers\subsystems\nightshift.dm"
|
||||
#include "code\controllers\subsystems\open_space.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\violin.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\helper.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_yw.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_softshop.dm"
|
||||
#include "code\modules\nifsoft\nif_statpanel.dm"
|
||||
|
||||
Reference in New Issue
Block a user