Fix silly stuff

This commit is contained in:
Cadyn
2020-10-05 19:46:50 -07:00
parent 07775449d7
commit 1d0e69633f
38 changed files with 2229 additions and 1229 deletions

View 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()

View File

@@ -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
//////////////////////////////////

View File

@@ -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",

View File

@@ -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

View 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])
)

View File

@@ -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

View File

@@ -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")

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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]"), \

View File

@@ -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

View 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

View 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(., ..())

View 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

View 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)

View 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

View 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"

View 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

View 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()

View 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()

View 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

View 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 ..()

View 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))

View 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))

View 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()

View 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

View 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()

View 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

View 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
View 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;", "&amp;#34;"), "'", "&#39;")
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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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"