diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 6c6269d301..3e06698904 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -51,122 +51,194 @@
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
- proc/get_manifest(monochrome, OOC)
- var/list/heads = new()
- var/list/sec = new()
- var/list/eng = new()
- var/list/med = new()
- var/list/sci = new()
- var/list/civ = new()
- var/list/bot = new()
- var/list/misc = new()
- var/list/isactive = new()
- var/dat = {"
-
- Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management."
-
- if (48) //mulebot control
- var/obj/item/radio/integrated/mule/QC = radio
- if(!QC)
- menu = "Interlink Error - Please reinsert cartridge."
- return
-
- menu = "
M.U.L.E. bot Interlink V0.8
"
-
- if(!QC.active)
- // list of bots
- if(!QC.botlist || (QC.botlist && QC.botlist.len==0))
- menu += "No bots found.
"
-
- else
- for(var/obj/machinery/bot/mulebot/B in QC.botlist)
- menu += "[B] at [get_area(B)]
"
- menu += "
Scan for active bots
"
-
- else // bot selected, control it
-
- menu += "[QC.active]
Status: (
refresh)
"
-
- if(!QC.botstatus)
- menu += "Waiting for response...
"
- else
-
- menu += "Location: [QC.botstatus["loca"] ]
"
- menu += "Mode: "
-
- switch(QC.botstatus["mode"])
- if(0)
- menu += "Ready"
- if(1)
- menu += "Loading/Unloading"
- if(2)
- menu += "Navigating to Delivery Location"
- if(3)
- menu += "Navigating to Home"
- if(4)
- menu += "Waiting for clear path"
- if(5,6)
- menu += "Calculating navigation path"
- if(7)
- menu += "Unable to locate destination"
- var/obj/structure/closet/crate/C = QC.botstatus["load"]
- menu += "
Current Load: [ !C ? "none" : "[C.name] (unload)" ]
"
- menu += "Destination: [!QC.botstatus["dest"] ? "none" : QC.botstatus["dest"] ] (set)
"
- menu += "Power: [QC.botstatus["powr"]]%
"
- menu += "Home: [!QC.botstatus["home"] ? "none" : QC.botstatus["home"] ]
"
- menu += "Auto Return Home: [QC.botstatus["retn"] ? "On Off" : "(On) Off"]
"
- menu += "Auto Pickup Crate: [QC.botstatus["pick"] ? "On Off" : "(On) Off"]
"
-
- menu += "\[Stop\] "
- menu += "\[Proceed\] "
- menu += "\[Return Home\]
"
- menu += "
Return to bot list"
-
- if (49) //janitorial locator
- menu = "
Persistent Custodial Object Locator
"
-
- var/turf/cl = get_turf(src)
- if (cl)
- menu += "Current Orbital Location: \[[cl.x],[cl.y]\]"
-
- menu += "Located Mops:
"
-
- var/ldat
- for (var/obj/item/weapon/mop/M in world)
- var/turf/ml = get_turf(M)
-
- if(ml)
- if (ml.z != cl.z)
- continue
- var/direction = get_dir(src, M)
- ldat += "Mop - \[[ml.x],[ml.y] ([uppertext(dir2text(direction))])\] - [M.reagents.total_volume ? "Wet" : "Dry"]
"
-
- if (!ldat)
- menu += "None"
- else
- menu += "[ldat]"
-
- menu += "Located Mop Buckets:
"
-
- ldat = null
- for (var/obj/structure/mopbucket/B in world)
- var/turf/bl = get_turf(B)
-
- if(bl)
- if (bl.z != cl.z)
- continue
- var/direction = get_dir(src, B)
- ldat += "Bucket - \[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\] - Water level: [B.reagents.total_volume]/100
"
-
- if (!ldat)
- menu += "None"
- else
- menu += "[ldat]"
-
- menu += "Located Cleanbots:
"
-
- ldat = null
- for (var/obj/machinery/bot/cleanbot/B in world)
- var/turf/bl = get_turf(B)
-
- if(bl)
- if (bl.z != cl.z)
- continue
- var/direction = get_dir(src, B)
- ldat += "Cleanbot - \[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\] - [B.on ? "Online" : "Offline"]
"
-
- if (!ldat)
- menu += "None"
- else
- menu += "[ldat]"
-
- else
- menu += "ERROR: Unable to determine current location."
- menu += "
Refresh GPS Locator"
+/obj/item/weapon/cartridge/signal
+ name = "generic signaler cartridge"
+ desc = "A data cartridge with an integrated radio signaler module."
+
+/obj/item/weapon/cartridge/signal/toxins
+ name = "Signal Ace 2"
+ desc = "Complete with integrated radio signaler!"
+ icon_state = "cart-tox"
+ access_reagent_scanner = 1
+ access_atmos = 1
+
+/obj/item/weapon/cartridge/signal/New()
+ ..()
+ spawn(5)
+ radio = new /obj/item/radio/integrated/signal(src)
+
+
+
+/obj/item/weapon/cartridge/quartermaster
+ name = "Space Parts & Space Vendors Cartridge"
+ desc = "Perfect for the Quartermaster on the go!"
+ icon_state = "cart-q"
+ access_quartermaster = 1
+
+/obj/item/weapon/cartridge/quartermaster/New()
+ ..()
+ spawn(5)
+ radio = new /obj/item/radio/integrated/mule(src)
+
+/obj/item/weapon/cartridge/head
+ name = "Easy-Record DELUXE"
+ icon_state = "cart-h"
+ access_status_display = 1
+
+/obj/item/weapon/cartridge/hop
+ name = "HumanResources9001"
+ icon_state = "cart-h"
+ access_status_display = 1
+ access_quartermaster = 1
+ access_janitor = 1
+ access_security = 1
+
+/obj/item/weapon/cartridge/hop/New()
+ ..()
+ spawn(5)
+ radio = new /obj/item/radio/integrated/mule(src)
+
+/obj/item/weapon/cartridge/hos
+ name = "R.O.B.U.S.T. DELUXE"
+ icon_state = "cart-hos"
+ access_status_display = 1
+ access_security = 1
+
+/obj/item/weapon/cartridge/hos/New()
+ ..()
+ spawn(5)
+ radio = new /obj/item/radio/integrated/beepsky(src)
+
+/obj/item/weapon/cartridge/ce
+ name = "Power-On DELUXE"
+ icon_state = "cart-ce"
+ access_status_display = 1
+ access_engine = 1
+ access_atmos = 1
+
+/obj/item/weapon/cartridge/cmo
+ name = "Med-U DELUXE"
+ icon_state = "cart-cmo"
+ access_status_display = 1
+ access_reagent_scanner = 1
+ access_medical = 1
+
+/obj/item/weapon/cartridge/rd
+ name = "Signal Ace DELUXE"
+ icon_state = "cart-rd"
+ access_status_display = 1
+ access_reagent_scanner = 1
+ access_atmos = 1
+
+/obj/item/weapon/cartridge/rd/New()
+ ..()
+ spawn(5)
+ radio = new /obj/item/radio/integrated/signal(src)
+
+/obj/item/weapon/cartridge/captain
+ name = "Value-PAK Cartridge"
+ desc = "Now with 200% more value!"
+ icon_state = "cart-c"
+ access_quartermaster = 1
+ access_janitor = 1
+ access_engine = 1
+ access_security = 1
+ access_medical = 1
+ access_reagent_scanner = 1
+ access_status_display = 1
+ access_atmos = 1
+
+/obj/item/weapon/cartridge/syndicate
+ name = "Detomatix Cartridge"
+ icon_state = "cart"
+ access_remote_door = 1
+ remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing.
+ charges = 4
+
+/obj/item/weapon/cartridge/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 = 1
+ status_signal.data["command"] = command
+
+ switch(command)
+ if("message")
+ status_signal.data["msg1"] = data1
+ status_signal.data["msg2"] = data2
+ if(loc)
+ var/obj/item/PDA = loc
+ var/mob/user = PDA.fingerprintslast
+ if(istype(PDA.loc,/mob/living))
+ name = PDA.loc
+ log_admin("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]")
+ message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]")
+
+ if("alert")
+ status_signal.data["picture_state"] = data1
+
+ frequency.post_signal(src, status_signal)
+
+
+/*
+ This generates the nano values of the cart menus.
+ Because we close the UI when we insert a new cart
+ we don't have to worry about null values on items
+ the user can't access. Well, unless they are href hacking.
+ But in that case their UI will just lock up.
+*/
+
+
+/obj/item/weapon/cartridge/proc/create_NanoUI_values(mob/user as mob)
+ var/obj/item/device/pda/PDA = loc
+ var/datum/nanoui/ui = nanomanager.get_open_ui(user, PDA, "main")
+ var/values[0]
+
+ /* Signaler (Mode: 40) */
+
+
+ if(istype(radio,/obj/item/radio/integrated/signal) && (mode==40 || !ui ))
+ var/obj/item/radio/integrated/signal/R = radio
+ values["signal_freq"] = format_frequency(R.frequency)
+ values["signal_code"] = R.code
+
+
+ /* Station Display (Mode: 42) */
+
+ if(mode==42 || !ui)
+ values["message1"] = message1 ? message1 : "(none)"
+ values["message2"] = message2 ? message2 : "(none)"
+
+
+
+ /* Power Monitor (Mode: 43 / 433) */
+ if(mode==43 || mode==433 || !ui)
+ var/pMonData[0]
+ for(var/obj/machinery/power/monitor/pMon in world)
+ if(!(pMon.stat & (NOPOWER|BROKEN)) )
+ pMonData[++pMonData.len] = list ("Name" = pMon.name, "ref" = "\ref[pMon]")
+ if(isnull(powmonitor)) powmonitor = pMon
+
+ values["powermonitors"] = pMonData
+
+ values["poweravail"] = powmonitor.powernet.avail
+ values["powerload"] = num2text(powmonitor.powernet.viewload,10)
+
+ var/list/L = list()
+ for(var/obj/machinery/power/terminal/term in powmonitor.powernet.nodes)
+ if(istype(term.master, /obj/machinery/power/apc))
+ var/obj/machinery/power/apc/A = term.master
+ L += A
+
+ var/list/Status = list(0,0,1,1) // Status: off, auto-off, on, auto-on
+ var/list/chg = list(0,1,1) // Charging: nope, charging, full
+ var/apcData[0]
+ for(var/obj/machinery/power/apc/A in L)
+ apcData[++apcData.len] = list("Name" = html_encode(A.area.name), "Equipment" = Status[A.equipment+1], "Lights" = Status[A.lighting+1], "Environment" = Status[A.environ+1], "CellPct" = A.cell ? round(A.cell.percent(),1) : -1, "CellStatus" = A.cell ? chg[A.charging+1] : 0)
+
+ values["apcs"] = apcData
+
+
+
+
+
+ /* General Records (Mode: 44 / 441 / 45 / 451) */
+ if(mode == 44 || mode == 441 || mode == 45 || mode ==451 || !ui)
+ if(istype(active1, /datum/data/record) && (active1 in data_core.general))
+ values["general"] = active1.fields
+ values["general_exists"] = 1
+
+ else
+
+ values["general"] = list("name" = null,\
+ "id" = null,\
+ "sex" = null,\
+ "species" = null,\
+ "age" = null,\
+ "rank" = null,\
+ "fingerprint" = null,\
+ "p_stat" = null,\
+ "m_stat" = null,\
+ )
+ values["general_exists"] = 0
+
+
+
+ /* Medical Records (Mode: 44 / 441) */
+
+ if(mode == 44 || mode == 441 || !ui)
+ var/medData[0]
+ for(var/datum/data/record/R in sortRecord(data_core.general))
+ medData[++medData.len] = list(Name = R.fields["name"],"ref" = "\ref[R]")
+ values["medical_records"] = medData
+
+ if(istype(active2, /datum/data/record) && (active2 in data_core.medical))
+ values["medical"] = active2.fields
+ values["medical_exists"] = 1
+ else
+ values["medical"] = list(\
+ "b_type" = null,\
+ "mi_dis" = null,\
+ "mi_dis_d" = null,\
+ "ma_dis" = null,\
+ "ma_dis_d" = null,\
+ "alg" = null,\
+ "alg_d" = null,\
+ "cdi" = null,\
+ "cdi_d" = null,\
+ "notes" = null,\
+ )
+ values["medical_exists"] = 0
+
+ /* Security Records (Mode:45 / 451) */
+
+ if(mode == 45 || mode == 451 || !ui)
+ var/secData[0]
+ for (var/datum/data/record/R in sortRecord(data_core.general))
+ secData[++secData.len] = list(Name = R.fields["name"], "ref" = "\ref[R]")
+ values["security_records"] = secData
+
+ if(istype(active3, /datum/data/record) && (active3 in data_core.security))
+ values["security"] = active3.fields
+ values["security_exists"] = 1
+ else
+ values["security"] = list(\
+ "criminal" = null,\
+ "mi_crim" = null,\
+ "ma_crim" = null,\
+ "ma_crim_d" = null,\
+ "notes"\
+ )
+ values["security_exists"] = 0
+
+ /* Security Bot Control (Mode: 46) */
+
+ if(mode==46 || !ui)
+ var/botsData[0]
+ var/beepskyData[0]
+ if(istype(radio,/obj/item/radio/integrated/beepsky))
+ var/obj/item/radio/integrated/beepsky/SC = radio
+ beepskyData["active"] = SC.active
+ if(SC.active && !isnull(SC.botstatus))
+ var/area/loca = SC.botstatus["loca"]
+ var/loca_name = sanitize(loca.name)
+ beepskyData["botstatus"] = list("loca" = loca_name, "mode" = SC.botstatus["mode"])
+ else
+ beepskyData["botstatus"] = list("loca" = null, "mode" = -1)
+ var/botsCount=0
+ if(SC.botlist && SC.botlist.len)
+ for(var/obj/machinery/bot/B in SC.botlist)
+ botsCount++
+ if(B.loc)
+ botsData[++botsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]")
+
+ if(!botsData.len)
+ botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
+
+ beepskyData["bots"] = botsData
+ beepskyData["count"] = botsCount
+
+ else
+ beepskyData["active"] = 0
+ botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
+ beepskyData["botstatus"] = list("loca" = null, "mode" = null)
+ beepskyData["bots"] = botsData
+ beepskyData["count"] = 0
+
+ values["beepsky"] = beepskyData
+
+
+ /* MULEBOT Control (Mode: 48) */
+
+ if(mode==48 || !ui)
+ var/muleData[0]
+ var/mulebotsData[0]
+ if(istype(radio,/obj/item/radio/integrated/mule))
+ var/obj/item/radio/integrated/mule/QC = radio
+ muleData["active"] = QC.active
+ if(QC.active && !isnull(QC.botstatus))
+ var/area/loca = QC.botstatus["loca"]
+ var/loca_name = sanitize(loca.name)
+ muleData["botstatus"] = list("loca" = loca_name, "mode" = QC.botstatus["mode"],"home"=QC.botstatus["home"],"powr" = QC.botstatus["powr"],"retn" =QC.botstatus["retn"], "pick"=QC.botstatus["pick"], "load" = QC.botstatus["load"], "dest" = sanitize(QC.botstatus["dest"]))
+
+ else
+ muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
+
+
+ var/mulebotsCount=0
+ for(var/obj/machinery/bot/B in QC.botlist)
+ mulebotsCount++
+ if(B.loc)
+ mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]")
+
+ if(!mulebotsData.len)
+ mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
+
+ muleData["bots"] = mulebotsData
+ muleData["count"] = mulebotsCount
+
+ else
+ muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
+ muleData["active"] = 0
+ mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
+ muleData["bots"] = mulebotsData
+ muleData["count"] = 0
+
+ values["mulebot"] = muleData
+
+
+
+ /* Supply Shuttle Requests Menu (Mode: 47) */
+
+ if(mode==47 || !ui)
+ var/supplyData[0]
+ supplyData["shuttle_moving"] = supply_shuttle.moving
+ supplyData["shuttle_eta"] = supply_shuttle.eta
+ supplyData["shuttle_loc"] = supply_shuttle.at_station ? "Station" : "Dock"
+ var/supplyOrderCount = 0
+ var/supplyOrderData[0]
+ for(var/S in supply_shuttle.shoppinglist)
+ var/datum/supply_order/SO = S
+
+ supplyOrderData[++supplyOrderData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "ApprovedBy" = SO.orderedby, "Comment" = html_encode(SO.comment))
+ if(!supplyOrderData.len)
+ supplyOrderData[++supplyOrderData.len] = list("Number" = null, "Name" = null, "OrderedBy"=null)
+
+ supplyData["approved"] = supplyOrderData
+ supplyData["approved_count"] = supplyOrderCount
+
+ var/requestCount = 0
+ var/requestData[0]
+ for(var/S in supply_shuttle.requestlist)
+ var/datum/supply_order/SO = S
+ requestCount++
+ requestData[++requestData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "OrderedBy" = SO.orderedby, "Comment" = html_encode(SO.comment))
+ if(!requestData.len)
+ requestData[++requestData.len] = list("Number" = null, "Name" = null, "orderedBy" = null, "Comment" = null)
+
+ supplyData["requests"] = requestData
+ supplyData["requests_count"] = requestCount
+
+
+ values["supply"] = supplyData
+
+
+
+ /* Janitor Supplies Locator (Mode: 49) */
+ if(mode==49 || !ui)
+ var/JaniData[0]
+ var/turf/cl = get_turf(src)
+
+ if(cl)
+ JaniData["user_loc"] = list("x" = cl.x, "y" = cl.y)
+ else
+ JaniData["user_loc"] = list("x" = 0, "y" = 0)
+ var/MopData[0]
+ for(var/obj/item/weapon/mop/M in world)
+ var/turf/ml = get_turf(M)
+ if(ml)
+ if(ml.z != cl.z)
+ continue
+ var/direction = get_dir(src, M)
+ MopData[++MopData.len] = list ("x" = ml.x, "y" = ml.y, "dir" = uppertext(dir2text(direction)), "status" = M.reagents.total_volume ? "Wet" : "Dry")
+
+ if(!MopData.len)
+ MopData[++MopData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
+
+
+ var/BucketData[0]
+ for(var/obj/structure/mopbucket/B in world)
+ var/turf/bl = get_turf(B)
+ if(bl)
+ if(bl.z != cl.z)
+ continue
+ var/direction = get_dir(src,B)
+ BucketData[++BucketData.len] = list ("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100)
+
+ if(!BucketData.len)
+ BucketData[++BucketData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
+
+ var/CbotData[0]
+ for(var/obj/machinery/bot/cleanbot/B in world)
+ var/turf/bl = get_turf(B)
+ if(bl)
+ if(bl.z != cl.z)
+ continue
+ var/direction = get_dir(src,B)
+ CbotData[++CbotData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.on ? "Online" : "Offline")
+
+
+ if(!CbotData.len)
+ CbotData[++CbotData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
+ var/CartData[0]
+ for(var/obj/structure/janitorialcart/B in world)
+ var/turf/bl = get_turf(B)
+ if(bl)
+ if(bl.z != cl.z)
+ continue
+ var/direction = get_dir(src,B)
+ CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100)
+ if(!CartData.len)
+ CartData[++CartData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
+
+
+
+
+ JaniData["mops"] = MopData
+ JaniData["buckets"] = BucketData
+ JaniData["cleanbots"] = CbotData
+ JaniData["carts"] = CartData
+ values["janitor"] = JaniData
+
+ return values
+
+
+
/obj/item/weapon/cartridge/Topic(href, href_list)
@@ -611,6 +555,9 @@ Code:
usr << browse(null, "window=pda")
return
+
+
+
switch(href_list["choice"])
if("Medical Records")
var/datum/data/record/R = locate(href_list["target"])
@@ -668,10 +615,9 @@ Code:
else
post_status(href_list["statdisp"])
if("Power Select")
- var/pnum = text2num(href_list["target"])
- powmonitor = powermonitors[pnum]
+ var/pref = href_list["target"]
+ powmonitor = locate(pref)
loc:mode = 433
mode = 433
- generate_menu()
- print_to_host(menu)
+ return 1
diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm
index 45bcff1c05..9dc462814e 100644
--- a/code/game/objects/items/devices/PDA/radio.dm
+++ b/code/game/objects/items/devices/PDA/radio.dm
@@ -31,15 +31,6 @@
frequency.post_signal(src, signal, filter = s_filter)
- proc/print_to_host(var/text)
- if (isnull(src.hostpda))
- return
- src.hostpda.cart = text
-
- for (var/mob/M in viewers(1, src.hostpda.loc))
- if (M.client && M.machine == src.hostpda)
- src.hostpda.cartridge.unlock()
-
return
proc/generate_menu()
@@ -107,7 +98,6 @@
if("summon")
post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(PDA) , s_filter = RADIO_SECBOT)
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT)
- PDA.cartridge.unlock()
/obj/item/radio/integrated/mule
var/list/botlist = null // list of bots
@@ -163,7 +153,6 @@
Topic(href, href_list)
..()
- var/obj/item/device/pda/PDA = src.hostpda
var/cmd = "command"
if(active) cmd = "command [active.suffix]"
@@ -208,7 +197,6 @@
if("stop", "go", "home")
post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT)
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
- PDA.cartridge.unlock()
diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm
index ebe7b751de..e04ab62671 100644
--- a/code/game/objects/items/devices/uplinks.dm
+++ b/code/game/objects/items/devices/uplinks.dm
@@ -12,6 +12,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid
var/item_data // raw item text
var/list/ItemList // Parsed list of items
var/uses // Numbers of crystals
+ var/nanoui_items[0]
// List of items not to shove in their hands.
var/list/NotInHand = list(/obj/machinery/singularity_beacon/syndicate)
@@ -23,6 +24,39 @@ A list of items and costs is stored under the datum of every game mode, alongsid
items = replacetext(item_data)
ItemList = text2list(src.items, ";") // Parsing the items text string
uses = ticker.mode.uplink_uses
+ nanoui_items = generate_nanoui_items()
+
+/*
+ Built the Items List for use with NanoUI
+*/
+
+/obj/item/device/uplink/proc/generate_nanoui_items()
+ var/items_nano[0]
+ for(var/D in ItemList)
+ var/list/O = stringsplit(D, ":")
+ if(O.len != 3) //If it is not an actual item, make a break in the menu.
+ if(O.len == 1) //If there is one item, it's probably a title
+ items_nano[++items_nano.len] = list("Category" = "[O[1]]", "items" = list())
+ continue
+
+ var/path_text = O[1]
+ var/cost = text2num(O[2])
+
+ var/path_obj = text2path(path_text)
+
+ // Because we're using strings, this comes up if item paths change.
+ // Failure to handle this error borks uplinks entirely. -Sayu
+ if(!path_obj)
+ error("Syndicate item is not a valid path: [path_text]")
+ else
+ var/itemname = O[3]
+ items_nano[items_nano.len]["items"] += list(list("Name" = itemname, "Cost" = cost, "obj_path" = path_text))
+
+ return items_nano
+
+
+
+
//Let's build a menu!
/obj/item/device/uplink/proc/generate_menu()
@@ -230,8 +264,8 @@ A list of items and costs is stored under the datum of every game mode, alongsid
feedback_add_details("traitor_uplink_items_bought","ST")
/obj/item/device/uplink/Topic(href, href_list)
-
if (href_list["buy_item"])
+
if(href_list["buy_item"] == "random")
var/boughtItem = chooseRandomItem()
if(boughtItem)
@@ -299,31 +333,48 @@ A list of items and costs is stored under the datum of every game mode, alongsid
return 1
return 0
-// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button.
-/obj/item/device/uplink/hidden/interact(mob/user as mob)
+/*
+ NANO UI FOR UPLINK WOOP WOOP
+*/
+/obj/item/device/uplink/hidden/ui_interact(mob/user, ui_key = "main")
+ var/title = "Syndicate Uplink"
+ var/data[0]
+
+ data["crystals"] = uses
+ data["nano_items"] = nanoui_items
+ data["welcome"] = welcome
- var/dat = ""
- dat += src.generate_menu()
- dat += "Lock"
- dat += ""
- user << browse(dat, "window=hidden")
- onclose(user, "hidden")
- return
+ var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key)
+ if (!ui)
+ // the ui does not exist, so we'll create a new one
+ ui = new(user, src, ui_key, "uplink.tmpl", title, 450, 600)
+ // When the UI is first opened this is the data it will use
+ ui.set_initial_data(data)
+ ui.open()
+ else
+ // The UI is already open so push the new data to it
+ ui.push_data(data)
+ return
+
+// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button.
+/obj/item/device/uplink/hidden/interact(mob/user)
+
+ ui_interact(user)
// The purchasing code.
/obj/item/device/uplink/hidden/Topic(href, href_list)
-
if (usr.stat || usr.restrained())
return
if (!( istype(usr, /mob/living/carbon/human)))
return 0
-
+ var/mob/user = usr
+ var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf))))
usr.set_machine(src)
if(href_list["lock"])
toggle()
- usr << browse(null, "window=hidden")
+ ui.close()
return 1
if(..(href, href_list) == 1)
@@ -334,7 +385,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid
A.put_in_any_hand_if_possible(I)
purchase_log += "[usr] ([usr.ckey]) bought [I]."
interact(usr)
- return
+ return 1
// I placed this here because of how relevant it is.
// You place this in your uplinkable item to check if an uplink is active or not.
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 95c5d63840..eabee2ba46 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -254,13 +254,17 @@
'nano/templates/geoscanner.tmpl',
'nano/templates/dna_modifier.tmpl',
'nano/templates/telescience_console.tmpl',
+ 'nano/templates/pda.tmpl',
+ 'nano/templates/uplink.tmpl',
'nano/images/uiBackground.png',
'nano/images/uiIcons16.png',
'nano/images/uiIcons24.png',
+ 'nano/images/uiBackground-Syndicate.png',
'nano/images/uiLinkPendingIcon.gif',
'nano/images/uiMaskBackground.png',
'nano/images/uiNoticeBackground.jpg',
'nano/images/uiTitleFluff.png',
+ 'nano/images/uiTitleFluff-Syndicate.png',
'html/search.js',
'html/panels.css',
'icons/pda_icons/pda_atmos.png',
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index 474e955f57..a6a7300469 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -136,10 +136,13 @@ nanoui is used to open and update nano browser uis
close()
return
+
if ((allowed_user_stat > -1) && (user.stat > allowed_user_stat))
set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility)
else if (user.restrained() || user.lying)
set_status(STATUS_UPDATE, push_update) // update only (orange visibility)
+ else if (istype(src_object, /obj/item/device/uplink/hidden)) // You know what if they have the uplink open let them use the UI
+ set_status(STATUS_INTERACTIVE, push_update) // Will build in distance checks on the topics for sanity.
else if (!(src_object in view(4, user))) // If the src object is not in visable, set status to 0
set_status(STATUS_DISABLED, push_update) // interactive (green visibility)
else if (dist <= 1)
diff --git a/nano/css/shared.css b/nano/css/shared.css
index 5d41a4f330..241ec579ab 100644
--- a/nano/css/shared.css
+++ b/nano/css/shared.css
@@ -23,7 +23,9 @@ hr {
padding: 0px 4px 4px 4px;
margin: 0 2px 2px 0;
cursor:default;
+ white-space: nowrap;
}
+
.hasIcon {
padding: 0px 4px 4px 0px;
}
@@ -138,6 +140,12 @@ h4 {
clear: both;
padding: 8px;
}
+
+.white {
+ color: white;
+ font-weight: bold;
+}
+
.good {
color: #4f7529;
font-weight: bold;
@@ -192,6 +200,8 @@ div.notice {
margin: 4px 0 0 0;
clear: both;
}
+
+
.itemLabel {
float: left;
width: 30%;
@@ -206,6 +216,13 @@ div.notice {
width: 20%;
color: #e9c183;
}
+.itemLabelWide {
+ float: left;
+ width: 45%;
+ color: #e9c183;
+}
+
+
.itemContentWide {
float: left;
width: 79%;
@@ -214,6 +231,11 @@ div.notice {
float: left;
width: 33%;
}
+.itemContentMedium {
+ float: left;
+ width: 55%;
+}
+
.statusDisplay {
background: #000000;
color: #ffffff;
@@ -221,6 +243,17 @@ div.notice {
padding: 4px;
margin: 3px 0;
}
+.statusDisplayRecords {
+ background: #000000;
+ color: #ffffff;
+ border: 1px solid #40628a;
+ padding: 4px;
+ margin: 3px 0;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+
.statusLabel {
width: 138px;
float: left;
@@ -307,7 +340,17 @@ div.notice {
float: left;
}
.fixedLeftWide {
- width: 150px;
+ width: 165px;
+ float: left;
+}
+
+.fixedLeftWider{
+ width: 220px;
+ float: left;
+}
+
+.fixedLeftWidest{
+ width: 250px;
float: left;
}
@@ -315,6 +358,24 @@ div.notice {
float: right;
}
+/* Used in PDA */
+
+
+.wholeScreen
+{
+ position: absolute
+ color: #517087;
+ font-size: 16px;
+ font-weight: bold;
+ text-align:center;
+}
+
+.pdalink
+{
+ float: left;
+ white-space:nowrap;
+}
+
/* DNA Modifier UI (dna_modifier.tmpl) */
.dnaBlock
@@ -363,3 +424,67 @@ div.notice {
margin: 200px 0;
text-align: center;
}
+
+/* Table stuffs for power monitor */
+table.pmon
+{
+border:2px solid RoyalBlue;
+}
+
+table.pmon td, table.pmon th
+{
+border-bottom:1px dotted black;
+padding:0px 5px 0px 5px;
+}
+
+
+
+/* Table Stuffs for manifest*/
+
+th.command
+{
+ background: #3333FF;
+ font-weight: bold;
+ color: #ffffff;
+}
+
+th.sec
+{
+ background: #8e0000;
+ font-weight: bold;
+ color: #ffffff;
+}
+th.med
+{
+ background: #006600;
+ font-weight: bold;
+ color: #ffffff;
+}
+th.eng
+{
+ background: #b27300;
+ font-weight: bold;
+ color: #ffffff;
+}
+th.sci
+{
+ background: #a65ba6;
+ font-weight: bold;
+ color: #ffffff;
+}
+th.civ
+{
+ background: #a32800;
+ font-weight: bold;
+ color: #ffffff;
+}
+th.misc
+{
+ background: #666666;
+ font-weight: bold;
+ color: #ffffff;
+}
+
+
+
+
diff --git a/nano/images/uiBackground-Syndicate.png b/nano/images/uiBackground-Syndicate.png
new file mode 100644
index 0000000000..3ca932cb83
Binary files /dev/null and b/nano/images/uiBackground-Syndicate.png differ
diff --git a/nano/images/uiBackground-Syndicate.xcf b/nano/images/uiBackground-Syndicate.xcf
new file mode 100644
index 0000000000..c86cea69d1
Binary files /dev/null and b/nano/images/uiBackground-Syndicate.xcf differ
diff --git a/nano/images/uiTitleFluff-Syndicate.png b/nano/images/uiTitleFluff-Syndicate.png
new file mode 100644
index 0000000000..b09f5ba6b2
Binary files /dev/null and b/nano/images/uiTitleFluff-Syndicate.png differ
diff --git a/nano/js/nano_base_helpers.js b/nano/js/nano_base_helpers.js
index ef34bd506a..338be42256 100644
--- a/nano/js/nano_base_helpers.js
+++ b/nano/js/nano_base_helpers.js
@@ -15,6 +15,20 @@ NanoBaseHelpers = function ()
var initHelpers = function ()
{
$.views.helpers({
+
+ syndicateMode: function() {
+ $('body').css("background-color","#8f1414");
+ $('body').css("background-image","url('uiBackground-Syndicate.png')");
+ $('body').css("background-position","50% 0");
+ $('body').css("background-repeat","repeat-x");
+
+ $('#uiTitleFluff').css("background-image","url('uiTitleFluff-Syndicate.png')");
+ $('#uiTitleFluff').css("background-position","50% 50%");
+ $('#uiTitleFluff').css("background-repeat", "no-repeat");
+
+ return '';
+ },
+
// Generate a Byond link
link: function( text, icon, parameters, status, elementClass, elementId) {
diff --git a/nano/templates/pda.tmpl b/nano/templates/pda.tmpl
new file mode 100644
index 0000000000..2494983f08
--- /dev/null
+++ b/nano/templates/pda.tmpl
@@ -0,0 +1,930 @@
+
+
+{^{if owner}}
+
+
+ Functions:
+
+
+ {^{:~link('Refresh', 'refresh', {'choice' : "Refresh"}, null, 'fixedLeft')}}
+ {^{:~link('Close', 'gear', {'choice' : "Close"}, null, 'fixedLeft')}}
+ {^{if idInserted}} {^{:~link('Update PDA Info', 'eject', {'choice' : "UpdateInfo"}, null, 'fixedLeftWide')}} {{/if}}
+ {^{if mode != 0}} {^{:~link('Return', 'arrowreturn-1-w', {'choice' : "Return"}, null, 'fixedLeft')}} {{/if}}
+
+
+
+
+
+ Station Time:
+
+
+ {^{:stationTime}}
+
+
+
+ {^{if mode == 0}}
+
+
+ Owner:
+
+
+ {^{:owner}}, {^{:ownjob}}
+
+
+
+
+
+ ID:
+
+
+ {^{:~link(idLink, 'eject', {'choice' : "Authenticate"}, idInserted ? null : 'disabled', idInserted ? 'fixedLeftWidest' : 'fixedLeft')}}
+
+
+
+
+
+ Cartridge:
+
+
+ {^{:~link(cartridge ? cartridge.name : 'no cartridge', 'eject', {'choice' : "Eject"}, cartridge ? null : 'disabled', cartridge ? 'fixedLeftWider' : 'fixedLeft')}}
+
+
+
+
Functions
+
+
+
+ General:
+
+
+ {^{:~link('Notekeeper', 'note', {'choice' : "1"},null, 'fixedLeftWide')}}
+ {^{:~link('Messenger', newMessage ? 'mail-closed' : 'mail-open', {'choice' : "2"},null, 'fixedLeftWide')}}
+ {^{:~link('Crew Manifest', 'contact', {'choice' : "41"},null, 'fixedLeftWide')}}
+
+
+
+ {^{if cartridge}}
+ {^{if cartridge.access.access_clown == 1}}
+
+
+ Clown:
+
+
+ {^{:~link('Honk Synthesizer', 'gear', {'choice' : "Honk"},null, 'fixedLeftWide')}}
+
+
+
+ {{/if}}
+ {^{if cartridge.access.access_engine == 1}}
+
+
+ Engineering:
+
+
+ {^{:~link('Power Monitor', 'alert', {'choice' : "43"},null, 'fixedLeftWide')}}
+
+
+
+ {{/if}}
+ {^{if cartridge.access.access_medical == 1}}
+
+
+ Medical:
+
+
+ {^{:~link('Medical Records', 'gear', {'choice' : "44"},null, 'fixedLeftWide')}}
+ {^{:~link(scanmode == 1 ? 'Disable Med Scanner' : 'Enable Med Scanner', 'gear', {'choice' : "Medical Scan"},null , 'fixedLeftWide')}}
+
+
+
+ {{/if}}
+ {^{if cartridge.access.access_security == 1}}
+
+
+ Security:
+
+
+ {^{:~link('Security Records', 'gear', {'choice' : "45"},null, 'fixedLeftWide')}}
+ {^{if cartridge.radio ==1}} {^{:~link('Security Bot Access', 'gear', {'choice' : "46"},null, 'fixedLeftWide')}} {{/if}}
+
+
+
+
+ {{/if}}
+ {^{if cartridge.access.access_quartermaster == 1}}
+
+
+ Quartermaster:
+
+
+ {^{:~link('Supply Records', 'gear', {'choice' : "47"},null, 'fixedLeftWide')}}
+ {^{if cartridge.radio == 3}} {^{:~link('Delivery Bot Control', 'gear', {'choice' : "48"},null, 'fixedLeftWide')}} {{/if}}
+
+
+
+
+ {{/if}}
+ {{/if}}
+
+
+
+ Utilities:
+
+
+ {^{if cartridge}}
+ {^{if cartridge.access.access_status_display == 1}} {^{:~link('Status Display', 'gear', {'choice' : "42"},null, 'fixedLeftWide')}}{{/if}}
+ {^{if cartridge.access.access_janitor==1}} {^{:~link('Custodial Locator', 'gear', {'choice' : "49"},null, 'fixedLeftWide')}} {{/if}}
+ {^{if cartridge.radio == 2}} {^{:~link('Signaler System', 'gear', {'choice' : "40"},null, 'fixedLeftWide')}} {{/if}}
+ {^{if cartridge.access.access_reagent_scanner==1}} {^{:~link(scanmode == 3 ? 'Disable Reagent Scanner' : 'Enable Reagent Scanner', 'gear', {'choice' : "Reagent Scan"},null, 'fixedLeftWider')}} {{/if}}
+ {^{if cartridge.access.access_engine==1}} {^{:~link(scanmode == 4 ? 'Disable Halogen Counter' : 'Enable Halogen Counter', 'gear', {'choice' : "Halogen Counter"}, null, 'fixedLeftWider')}} {{/if}}
+ {^{if cartridge.access.access_atmos==1}} {^{:~link(scanmode == 5 ? 'Disable Gas Scanner' : 'Enable Gas Scanner', 'gear', {'choice' : "Gas Scan"}, null, 'fixedLeftWide')}} {{/if}}
+ {^{if cartridge.access.access_remote_door==1}}{^{:~link('Toggle Door', 'gear', {'choice' : "Toggle Door"},null, 'fixedLeftWide')}} {{/if}}
+ {{/if}}
+ {^{:~link('Atmospheric Scan', 'gear', {'choice' : "3"},null, 'fixedLeftWide')}}
+ {^{:~link(fon==1 ? 'Disable Flashlight' : 'Enable Flashlight', 'lightbulb', {'choice' : "Light"}, null,'fixedLeftWide')}}
+
+
+ {^{if pai}}
+
+
+ PAI Utilities:
+
+
+ {^{:~link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"},null, 'fixedLeft')}}
+ {^{:~link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"},null, 'fixedLeft')}}
+
+
+ {{/if}}
+ {{/if}}
+ {^{if mode == 1}}
+
+
+
+
+ {^{:~link('Edit Notes', 'gear', {'choice' : "Edit"},null, 'fixedLeft')}}
+
+
+
+
+ {{else mode == 2}}
+ SpaceMessenger V4.0.1
+
+
+ Messenger Functions:
+
+
+
+ {^{:~link(silent==1 ? 'Ringer: Off' : 'Ringer: On', silent==1 ? 'volume-off' : 'volume-on', {'choice' : "Toggle Ringer"},null, 'fixedLeftWide')}}
+ {^{:~link(toff==1 ? 'Messenger: Off' : 'Messenger: On',toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"},null, 'fixedLeftWide')}}
+ {^{:~link('Set Ringtone', 'comment', {'choice' : "Ringtone"}, null, 'fixedLeftWide')}}
+ {^{:~link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"},null, 'fixedLeftWider')}}
+
+
+ {^{if toff == 0}}
+
+ {^{if cartridge}}
+ {^{if cartridge.charges}}
+
+ {^{:cartridge.charges}}
+ {^{if cartridge.type == "/obj/item/weapon/cartridge/syndicate"}} detonation charges left. {{/if}}
+ {^{if cartridge.type == "/obj/item/weapon/cartridge/clown" || cartridge.type == "/obj/item/weapon/cartridge/mime"}} viral files left. {{/if}}
+
+
+ {{/if}}
+ {{/if}}
+
+ {^{if pda_count == 0}}No other PDAS located
+ {{else}}
+ Current Conversations
+ {^{for convopdas}}
+
+ {^{:~link(Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : Reference } , null, fixedLeftWider)}}
+ {^{if ~root.cartridge}}
+ {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && Detonate == 1}} {^{:~link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
+ {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/clown"}} {^{:~link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
+ {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/mime"}} {^{:~link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
+ {{/if}}
+
+ {{/for}}
+ Other PDAs
+ {^{for pdas}}
+
+ {^{:~link(Name, 'circle-arrow-s', {'choice' : "Message", 'target' : Reference}, null, fixedLeftWider)}}
+ {^{if ~root.cartridge}}
+ {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && Detonate == 1}} {^{:~link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
+ {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/clown"}} {^{:~link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
+ {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/mime"}} {^{:~link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
+ {{/if}}
+
+ {{/for}}
+ {{/if}}
+ {{/if}}
+
+ {{else mode == 21}}
+ SpaceMessenger V4.0.1
+
+
+ Messenger Functions:
+
+
+
+ {^{:~link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"},null, 'fixedLeftWide')}}
+
+
+
+ Conversation with: {^{:convo_name}} ({^{:convo_job}})
+
+
+
+ {^{for messages}}
+ {^{if ~root.active_conversation == target}}
+ {^{if sent==0}}
+ Them: {^{:message}}
+ {{else}}
+ You: {^{:message}}
+ {{/if}}
+ {{/if}}
+ {{/for}}
+
+
+
+
+ {^{:~link('Reply', 'comment', {'choice' : "Message", 'target': active_conversation},null, 'fixedLeft')}}
+
+ {{else mode== 41}}
+
+
+ {^{if manifest.heads.length}}
+ | Command |
+ {^{for manifest["heads"]}}
+ {^{if rank == "Captain"}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{else}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {^{if manifest.sec.length}}
+ | Security |
+ {^{for manifest["sec"]}}
+ {^{if rank == "Head of Security"}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{else}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {^{if manifest.eng.length}}
+ | Engineering |
+ {^{for manifest["eng"]}}
+ {^{if rank == "Chief Engineer"}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{else}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{/if}}
+
+ {{/for}}
+ {{/if}}
+ {^{if manifest.med.length}}
+ | Medical |
+ {^{for manifest["med"]}}
+ {^{if rank == "Chief Medical Officer"}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{else}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {^{if manifest.sci.length}}
+ | Science |
+ {^{for manifest["sci"]}}
+ {^{if rank == "Research Director"}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{else}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {^{if manifest.civ.length}}
+ | Civilian |
+ {^{for manifest["civ"]}}
+ {^{if rank == "Head of Personnel"}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{else}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {^{if manifest.misc.length}}
+ | Misc |
+ {^{for manifest["misc"]}}
+ | {^{:name}} | {^{:rank}} | {^{:active}} |
+ {{/for}}
+ {{/if}}
+
+
+
+
+ {{else mode == 3}}
+
+ Atmospheric Scan
+
+
+ {^{if aircontents.reading == 1}}
+
+ Pressure:
+
+
+ {^{:~string('{1} kPa', aircontents.pressure < 80 || aircontents.pressure > 120 ? 'bad' : aircontents.pressure < 95 || aircontents.pressure > 110 ? 'average' : 'good' , aircontents.pressure)}}
+
+
+ Temperature:
+
+
+ {^{:~string('{1} °C', aircontents.temp < 5 || aircontents.temp > 35 ? 'bad' : aircontents.temp < 15 || aircontents.temp > 25 ? 'average' : 'good' , aircontents.temp)}}
+
+
+
+ Oxygen:
+
+
+ {^{:~string('{1}%', aircontents.oxygen < 17 ? 'bad' : aircontents.oxygen < 19 ? 'average' : 'good' , aircontents.oxygen)}}
+
+
+ Nitrogen:
+
+
+ {^{:~string('{1}%', aircontents.nitrogen > 82 ? 'bad' : aircontents.nitrogen > 80 ? 'average' : 'good' , aircontents.nitrogen)}}
+
+
+ Carbon Dioxide:
+
+
+ {^{:~string('{1}%', aircontents.carbon_dioxide > 5 ? 'bad' : 'good' , aircontents.carbon_dioxide)}}
+
+
+ Plasma:
+
+
+ {^{:~string('{1}%', aircontents.plasma > 0 ? 'bad' : 'good' , aircontents.plasma)}}
+
+
+ {^{if aircontents.other > 0}}
+
+ Unknown:
+
+
+ {^{:aircontents.other}}%
+
+ {{/if}}
+ {{else}}
+
+ Unable to get air reading
+
+ {{/if}}
+
+
+
+ {{else mode == 40}}
+ Remote Signaling System
+
+
+ Frequency:
+
+
+ {^{:records.signal_freq}}
+
+ {^{:~link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-10"},null, null)}}
+ {^{:~link('-.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-2"},null, null)}}
+
+ {^{:~link('+.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "2"},null, null)}}
+ {^{:~link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "10"},null, null)}}
+
+
+
+
+
+ Code:
+
+
+
+ {^{:records.signal_code}}
+
+ {^{:~link('-5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-5"},null, null)}}
+ {^{:~link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-1"},null, null)}}
+ {^{:~link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "1"},null, null)}}
+ {^{:~link('+5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "5"},null, null)}}
+
+
+
+ {^{:~link('Send Signal', 'radiation', {'cartmenu' : "1", 'choice' : "Send Signal"},null, null)}}
+
+
+ {{else mode == 42}}
+ Station Status Displays Interlink
+
+
+ Code:
+
+
+ {^{:~link('Clear', 'trash', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "blank"},null, null)}}
+ {^{:~link('Shuttle ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "shuttle"},null, null)}}
+ {^{:~link('Message', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "message"},null, null)}}
+
+
+
+
+
+ Message line 1
+
+
+ {^{:~link(records.message1 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg1"},null, null)}}
+
+
+
+
+ Message line 2
+
+
+ {^{:~link(records.message2 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg2"},null, null)}}
+
+
+
+
+
+
+ ALERT!:
+
+
+ {^{:~link('None', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'default' : "alert"},null, null)}}
+ {^{:~link('Alert', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "alert"},null, null)}}
+ {^{:~link('Lockdown', 'caution', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "alert"},null, null)}}
+ {^{:~link('Biohazard', 'radiation', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "alert"},null, null)}}
+
+
+
+ {{else mode == 43}}
+
+ Station Powermonitors
+
+ Select A power monitor:
+
+ {^{for records.powermonitors}}
+
+ {^{:~link(Name, 'radiation', {'cartmenu' : "1", 'choice' : "Power Select",'target' : ref},null, null)}}
+
+ {{/for}}
+
+ {{else mode == 433}}
+ Powernet Status
+
+
+ Current Load:
+
+
+ {^{:records.powerload}} W
+
+
+
+
+ Total Power:
+
+
+ {^{:records.poweravail}} W
+
+
+
+
+
+ {^{for records.apcs}}
+ {^{if #index % 20 === 0}}
+ | Area | Eqp. | Lgt. | Env | Cell |
+ {{/if}}
+
+ | {^{:Name}} |
+ {^{:~string(' | ', Equipment==1 ? '#4f7529' : '#8f1414' )}}
+ {^{:~string(' | ', Lights==1 ? '#4f7529' : '#8f1414' )}}
+ {^{:~string(' | ', Environment==1 ? '#4f7529' : '#8f1414' )}}
+ {^{:~string('{1} | ', CellStatus==1 ? '#4f7529' : '#8f1414', CellStatus==-1 ? 'No Cell' : CellPct + '%' )}}
+
+ {{/for}}
+
+
+
+ {{else mode == 44}}
+ Medical Record List
+
+ Select A record
+
+
+ {^{for records.medical_records}}
+
+ {^{:~link(Name, 'gear', {'cartmenu' : "1", 'choice' : "Medical Records",'target' : ref},null, null)}}
+
+ {{/for}}
+
+
+
+ {{else mode == 441}}
+ Medical Record
+
+
+
+ {^{if records.general_exists == 1}}
+ Name: {^{:records.general.name}}
+ Sex: {^{:records.general.sex}}
+ Species: {^{:records.general.species}}
+ Age: {^{:records.general.age}}
+ Rank: {^{:records.general.rank}}
+ Fingerprint: {^{:records.general.fingerprint}}
+ Physical Status: {^{:records.general.p_stat}}
+ Mental Status: {^{:records.general.m_stat}}
+ {{else}}
+
+ General Record Lost!
+
+ {{/if}}
+ {^{if records.medical_exists == 1}}
+ Medical Data:
+ Blood Type: {^{:records.medical.b_type}}
+ Minor Disabilities: {^{:records.medical.mi_dis}}
+ Details: {^{:records.medical.mi_dis_d}}
+ Major Disabilities: {^{:records.medical.ma_dis}}
+ Details: {^{:records.medical.ma_dis_d}}
+ Allergies: {^{:records.medical.alg}}
+ Details: {^{:records.medical.alg_d}}
+ Current Disease: {^{:records.medical.cdi}}
+ Details: {^{:records.medical.alg_d}}
+ Important Notes: {^{:records.medical.notes}}
+ {{else}}
+
+ Medical Record Lost!
+
+ {{/if}}
+
+
+
+
+
+ {{else mode == 45}}
+ Security Record List
+
+ Select A record
+
+
+ {^{for records.security_records}}
+
+ {^{:~link(Name, 'gear', {'cartmenu' : "1", 'choice' : "Security Records",'target' : ref},null, null)}}
+
+ {{/for}}
+
+
+
+ {{else mode == 451}}
+ Security Record
+
+
+
+ {^{if records.general_exists == 1}}
+ Name: {^{:records.general.name}}
+ Sex: {^{:records.general.sex}}
+ Species: {^{:records.general.species}}
+ Age: {^{:records.general.age}}
+ Rank: {^{:records.general.rank}}
+ Fingerprint: {^{:records.general.fingerprint}}
+ Physical Status: {^{:records.general.p_stat}}
+ Mental Status: {^{:records.general.m_stat}}
+ {{else}}
+
+ General Record Lost!
+
+ {{/if}}
+ {^{if records.security_exists == 1}}
+ Security Data:
+ Criminal Status: {^{:records.security.criminal}}
+ Minor Crimes: {^{:records.security.mi_crim}}
+ Details: {^{:records.security.mi_crim_d}}
+ Major Crimes: {^{:records.security.ma_crim}}
+ Details: {^{:records.security.ma_crim_d}}
+ Important Notes: {^{:records.security.notes}}
+ {{else}}
+
+ Security Record Lost!
+
+ {{/if}}
+
+
+
+ {{else mode == 46}}
+ Security Bot Control
+ {^{if records.beepsky.active == null || records.beepsky.active == 0}}
+ {^{if records.beepsky.count == 0}}
+ No bots found.
+ {{else}}
+
+ Select A Bot.
+
+
+ {^{for records.beepsky.bots}}
+
+ {^{:~link(Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : ref},null, null)}} (Location: {^{:Location}})
+
+ {{/for}}
+ {{/if}}
+
+ {^{:~link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"},null, null)}}
+
+ {{else}}
+ {^{:records.beepsky.active}}
+
+ {^{if records.beepsky.botstatus.mode == -1}}
+ Waiting for response...
+ {{else}}
+ Status:
+
+
+
+ Location:
+
+
+ {^{:records.beepsky.botstatus.loca}}
+
+
+
+
+ Mode:
+
+
+
+ {^{if records.beepsky.botstatus.mode ==0}} Ready
+ {{else records.beepsky.botstatus.mode == 1}}
+ Apprehending target
+ {{else records.beepsky.botstatus.mode ==2 || records.beepsky.botstatus.mode == 3}}
+ Arresting target
+ {{else records.beepsky.botstatus.mode ==4}}
+ Starting patrol
+ {{else records.beepsky.botstatus.mode ==5}}
+ On Patrol
+ {{else records.beepsky.botstatus.mode ==6}}
+ Responding to summons
+ {{/if}}
+
+
+
+
+ {^{:~link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"},null, null)}}
+ {^{:~link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"},null, null)}}
+ {^{:~link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"},null, null)}}
+
+ {{/if}}
+ {^{:~link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"},null, null)}}
+ {{/if}}
+ {{else mode == 47}}
+ Supply Record Interlink
+
+
+ Location:
+
+
+
+ {^{if records.supply.shuttle_moving}}
+ Moving to station ({^{:records.supply.shuttle_eta}})
+ {{else}}
+ Shuttle at {^{:records.supply.shuttle_loc}}
+ {{/if}}
+
+
+
+
+
+
+ Current Approved Orders
+ {^{if records.supply.approved_count == 0}}
+ No current approved orders
+ {{else}}
+ {^{for records.supply.approved}}
+ #{^{:Number}} - {^{:Name}} approved by {^{:OrderedBy}}
{^{if Comment != ""}} {^{:Comment}}
{{/if}}
+ {{/for}}
+ {{/if}}
+
+ Current Requested Orders
+ {^{if records.supply.requests_count == 0}}
+ No current requested orders
+ {{else}}
+ {^{for records.supply.requests}}
+ #{^{:Number}} - {^{:Name}} requested by {^{:OrderedBy}}
{^{if Comment != ""}} {^{:Comment}}
{{/if}}
+ {{/for}}
+ {{/if}}
+
+
+
+
+ {{else mode == 48}}
+ Mule Control
+ {^{if records.mulebot.active == null || records.mulebot.active == 0}}
+ {^{if records.mulebot.count == 0}}
+ No bots found.
+
+ {{else}}
+ Mule List
+
+ Select A Mulebot
+
+
+ {^{for records.mulebot.bots}}
+
+ {^{:~link(Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : ref},null, null)}} (Location: {^{:Location}})
+
+ {{/for}}
+ {{/if}}
+
+ {^{:~link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"},null, null)}}
+ {{else}}
+ {^{if records.mulebot.botstatus.mode == -1}}
+ Waiting for response...
+ {{else}}
+ Status:
+
+
+
+ Location:
+
+
+ {^{:records.mulebot.botstatus.loca}}
+
+
+
+
+ Mode:
+
+
+
+ {^{if records.mulebot.botstatus.mode ==0}} Ready
+ {{else records.mulebot.botstatus.mode == 1}}
+ Loading/Unloading
+ {{else records.mulebot.botstatus.mode ==2}}
+ Navigating to Delivery Location
+ {{else records.mulebot.botstatus.mode == 3}}
+ Navigating to Home
+ {{else records.mulebot.botstatus.mode ==4}}
+ Waiting for Clear Path
+ {{else records.mulebot.botstatus.mode ==5 || records.mulebot.botstatus.mode == 6}}
+ Calculating navigation Path
+
+ {{else records.mulebot.botstatus.mode ==7}}
+ Unable to locate destination
+ {{/if}}
+
+
+
+
+
+ Current Load:
+
+
+
+ {^{:~link(records.mulebot.botstatus.load == null ? 'None (Unload)' : records.mulebot.botstatus.load + ' (Unload)', 'gear', {'radiomenu' : "1", 'op' : "unload"},records.mulebot.botstatus.load == null ? 'disabled' : null, null)}}
+
+
+
+
+
+ Power:
+
+
+
+ {^{:records.mulebot.botstatus.powr}}%
+
+
+
+
+
+
+ Destination:
+
+
+ {^{:~link(records.mulebot.botstatus.dest == null || records.mulebot.botstatus.dest == "" ? 'None (Set)': records.mulebot.botstatus.dest+ ' (Set)', 'gear', {'radiomenu' : "1", 'op' : "setdest"},null, null)}}
+
+
+
+
+
+ Home:
+
+
+ {^{if records.mulebot.botstatus.home == null}} None {{else}} {^{:records.mulebot.botstatus.home}} {{/if}}
+
+
+
+
+ Auto Return:
+
+
+ {^{:~link(records.mulebot.botstatus.retn == 1 ? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : records.mulebot.botstatus.retn==1 ? "retoff" : "reton"},null, null)}}
+
+
+
+
+ Auto Pickup:
+
+
+ {^{:~link(records.mulebot.botstatus.pick==1? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : records.mulebot.botstatus.pick==1 ? "pickoff" : "pickon"},null, null)}}
+
+
+
+
+ Functions:
+
+
+ {^{:~link('Stop', 'gear', {'radiomenu' : "1", 'op' : "stop"},null, null)}}
+ {^{:~link('Proceed', 'gear', {'radiomenu' : "1", 'op' : "go"},null, null)}}
+ {^{:~link('Return Home', 'gear', {'radiomenu' : "1", 'op' : "home"},null, null)}}
+
+
+
+ {^{:~link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"},null, null)}}
+
+
+ {{/if}}
+ {{/if}}
+
+
+
+ {{else mode == 49}}
+ Janatorial Supplies Locator
+
+ Current Location:
+ {^{if records.janitor.user_loc.x == 0}}
+ Unknown
+ {{else}}
+ {^{:records.janitor.user_loc.x}} / {^{:records.janitor.user_loc.y}}
+ {{/if}}
+
+
+ {^{for records.janitor.mops}}
+ {^{if x==0}}
+ Unable to locate Mop
+ {{else}}
+ Mop Location:
+ ({^{:x}} / {^{:y}}) - {^{:dir}} - Status: {^{:status}}
+ {{/if}}
+ {{/for}}
+
+
+ {^{for records.janitor.buckets}}
+ {^{if x==0}}
+ Unable to locate Water Buckets
+ {{else}}
+ Water Buckets Location:
+ ({^{:x}} / {^{:y}}) - {^{:dir}} - Water Level: {^{:status}}
+ {{/if}}
+ {{/for}}
+
+
+ {^{for records.janitor.cleanbots}}
+ {^{if x==0}}
+ Unable to locate Clean Bots
+ {{else}}
+ Clean Bots Location:
+ ({^{:x}} / {^{:y}}) - {^{:dir}} - Status: {^{:status}}
+ {{/if}}
+
+ {{/for}}
+
+
+ {^{for records.janitor.carts}}
+ {^{if x==0}}
+ Unable to locate Janitorial Cart
+ {{else}}
+ Janitorial cart Location:
+ ({^{:x}} / {^{:y}}) - {^{:dir}} - Status: {^{:status}}
+ {{/if}}
+
+ {{/for}}
+
+
+
+
+
+ {{/if}}
+
+
+{{else}}
+
No Owner information found, please swipe ID
+
+{{/if}}
+
diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl
new file mode 100644
index 0000000000..2f47c19635
--- /dev/null
+++ b/nano/templates/uplink.tmpl
@@ -0,0 +1,46 @@
+
+
+{^{:~syndicateMode()}}
+{^{:welcome}}
+
+
+
+ Functions:
+
+
+ {^{:~link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}
+
+
+
+
+
+ Tele-Crystals:
+
+
+ {^{:crystals}}
+
+
+Request items:
+Each item costs a number of tele-crystals as indicated by the number following their name.
+
+
+{^{for nano_items}}
+
+
{^{:Category}}
+
+ {^{for items}}
+
+ {^{:~link( Name, 'gear', {'buy_item' : obj_path, 'cost' : Cost}, Cost > ~root.crystals ? 'disabled' : null, null)}} - {^{:Cost}}
+
+ {{/for}}
+
+
+{{/for}}
+
+
+ {^{:~link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, null, 'fixedLeftWidest')}}
+
+