mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
NanoUI PDAs made Modular (lazy commit)
This commit is contained in:
3
code/__defines/pda.dm
Normal file
3
code/__defines/pda.dm
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#define PDA_APP_UPDATE 0
|
||||||
|
#define PDA_APP_NOUPDATE 1
|
||||||
|
#define PDA_APP_UPDATE_SLOW 2
|
||||||
@@ -21,6 +21,27 @@
|
|||||||
/*
|
/*
|
||||||
* Text sanitization
|
* Text sanitization
|
||||||
*/
|
*/
|
||||||
|
// Can be used almost the same way as normal input for text
|
||||||
|
/proc/clean_input(Message, Title, Default, mob/user=usr)
|
||||||
|
var/txt = input(user, Message, Title, Default) as text | null
|
||||||
|
if(txt)
|
||||||
|
return html_encode(txt)
|
||||||
|
|
||||||
|
//Simply removes < and > and limits the length of the message
|
||||||
|
/proc/strip_html_simple(var/t,var/limit=MAX_MESSAGE_LEN)
|
||||||
|
var/list/strip_chars = list("<",">")
|
||||||
|
t = copytext(t,1,limit)
|
||||||
|
for(var/char in strip_chars)
|
||||||
|
var/index = findtext(t, char)
|
||||||
|
while(index)
|
||||||
|
t = copytext(t, 1, index) + copytext(t, index+1)
|
||||||
|
index = findtext(t, char)
|
||||||
|
return t
|
||||||
|
|
||||||
|
//Runs byond's sanitization proc along-side strip_html_simple
|
||||||
|
//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' that html_encode() would cause
|
||||||
|
/proc/adminscrub(var/t,var/limit=MAX_MESSAGE_LEN)
|
||||||
|
return copytext((html_encode(strip_html_simple(t))),1,limit)
|
||||||
|
|
||||||
//Used for preprocessing entered text
|
//Used for preprocessing entered text
|
||||||
/proc/sanitize(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1)
|
/proc/sanitize(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1)
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ nanoui is used to open and update nano browser uis
|
|||||||
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_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.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_state_default.js") // The NanoStateDefault JS, this is the "default" state (used by all UIs by default), which inherits from NanoState
|
||||||
|
add_script("nano_state_pda.js") // The NanoStatePDA JS, this is the state used for PDAs.
|
||||||
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_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_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.css") // this CSS sheet is common to all UIs
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
var/notify_silent = 0
|
var/notify_silent = 0
|
||||||
var/hidden = 0 // program not displayed in main menu
|
var/hidden = 0 // program not displayed in main menu
|
||||||
var/category = "General" // the category to list it in on the main menu
|
var/category = "General" // the category to list it in on the main menu
|
||||||
var/obj/item/pda/pda // if this is null, and the app is running code, something's gone wrong
|
var/obj/item/device/pda/pda // if this is null, and the app is running code, something's gone wrong
|
||||||
|
|
||||||
/datum/data/pda/Destroy()
|
/datum/data/pda/Destroy()
|
||||||
pda = null
|
pda = null
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
var/base_name
|
var/base_name
|
||||||
category = "Scanners"
|
category = "Scanners"
|
||||||
|
|
||||||
/datum/data/pda/utility/scanmode/New(obj/item/cartridge/C)
|
/datum/data/pda/utility/scanmode/New(obj/item/weapon/cartridge/C)
|
||||||
..(C)
|
..(C)
|
||||||
name = "Enable [base_name]"
|
name = "Enable [base_name]"
|
||||||
|
|
||||||
|
|||||||
@@ -80,9 +80,13 @@ var/list/civilian_cartridges = list(
|
|||||||
var/message1 // used for status_displays
|
var/message1 // used for status_displays
|
||||||
var/message2
|
var/message2
|
||||||
var/list/stored_data = list()
|
var/list/stored_data = list()
|
||||||
|
var/list/programs = list()
|
||||||
|
var/list/messenger_plugins = list()
|
||||||
|
|
||||||
/obj/item/weapon/cartridge/Destroy()
|
/obj/item/weapon/cartridge/Destroy()
|
||||||
QDEL_NULL(radio)
|
QDEL_NULL(radio)
|
||||||
|
QDEL_LIST(programs)
|
||||||
|
QDEL_LIST(messenger_plugins)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/obj/item/weapon/cartridge/engineering
|
/obj/item/weapon/cartridge/engineering
|
||||||
@@ -234,14 +238,25 @@ var/list/civilian_cartridges = list(
|
|||||||
name = "\improper Value-PAK cartridge"
|
name = "\improper Value-PAK cartridge"
|
||||||
desc = "Now with 200% more value!"
|
desc = "Now with 200% more value!"
|
||||||
icon_state = "cart-c"
|
icon_state = "cart-c"
|
||||||
access_quartermaster = 1
|
programs = list(
|
||||||
access_janitor = 1
|
new/datum/data/pda/app/power,
|
||||||
access_engine = 1
|
new/datum/data/pda/utility/scanmode/halogen,
|
||||||
access_security = 1
|
|
||||||
access_medical = 1
|
new/datum/data/pda/utility/scanmode/gas,
|
||||||
access_reagent_scanner = 1
|
|
||||||
access_status_display = 1
|
new/datum/data/pda/app/crew_records/medical,
|
||||||
access_atmos = 1
|
new/datum/data/pda/utility/scanmode/medical,
|
||||||
|
|
||||||
|
new/datum/data/pda/utility/scanmode/reagent,
|
||||||
|
|
||||||
|
new/datum/data/pda/app/crew_records/security,
|
||||||
|
new/datum/data/pda/app/secbot_control,
|
||||||
|
|
||||||
|
new/datum/data/pda/app/janitor,
|
||||||
|
|
||||||
|
new/datum/data/pda/app/supply,
|
||||||
|
|
||||||
|
new/datum/data/pda/app/status_display)
|
||||||
|
|
||||||
/obj/item/weapon/cartridge/syndicate
|
/obj/item/weapon/cartridge/syndicate
|
||||||
name = "\improper Detomatix cartridge"
|
name = "\improper Detomatix cartridge"
|
||||||
@@ -276,6 +291,13 @@ var/list/civilian_cartridges = list(
|
|||||||
|
|
||||||
frequency.post_signal(src, status_signal)
|
frequency.post_signal(src, status_signal)
|
||||||
|
|
||||||
|
/obj/item/weapon/cartridge/frame
|
||||||
|
name = "F.R.A.M.E. cartridge"
|
||||||
|
icon_state = "cart"
|
||||||
|
charges = 5
|
||||||
|
var/telecrystals = 0
|
||||||
|
messenger_plugins = list(new/datum/data/pda/messenger_plugin/virus/frame)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This generates the nano values of the cart menus.
|
This generates the nano values of the cart menus.
|
||||||
|
|||||||
410
code/modules/pda/cart_apps.dm
Normal file
410
code/modules/pda/cart_apps.dm
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
/datum/data/pda/app/status_display
|
||||||
|
name = "Status Display"
|
||||||
|
icon = "list-alt"
|
||||||
|
template = "pda_status_display"
|
||||||
|
category = "Utilities"
|
||||||
|
|
||||||
|
var/message1 // used for status_displays
|
||||||
|
var/message2
|
||||||
|
|
||||||
|
/datum/data/pda/app/status_display/update_ui(mob/user as mob, list/data)
|
||||||
|
data["records"] = list(
|
||||||
|
"message1" = message1 ? message1 : "(none)",
|
||||||
|
"message2" = message2 ? message2 : "(none)")
|
||||||
|
|
||||||
|
/datum/data/pda/app/status_display/Topic(href, list/href_list)
|
||||||
|
switch(href_list["choice"])
|
||||||
|
if("Status")
|
||||||
|
switch(href_list["statdisp"])
|
||||||
|
if("message")
|
||||||
|
post_status("message", message1, message2)
|
||||||
|
if("alert")
|
||||||
|
post_status("alert", href_list["alert"])
|
||||||
|
if("setmsg1")
|
||||||
|
message1 = clean_input("Line 1", "Enter Message Text", message1)
|
||||||
|
if("setmsg2")
|
||||||
|
message2 = clean_input("Line 2", "Enter Message Text", message2)
|
||||||
|
else
|
||||||
|
post_status(href_list["statdisp"])
|
||||||
|
|
||||||
|
/datum/data/pda/app/status_display/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
|
||||||
|
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
|
||||||
|
|
||||||
|
spawn(0)
|
||||||
|
frequency.post_signal(src, status_signal)
|
||||||
|
|
||||||
|
|
||||||
|
/datum/data/pda/app/signaller
|
||||||
|
name = "Signaler System"
|
||||||
|
icon = "rss"
|
||||||
|
template = "pda_signaller"
|
||||||
|
category = "Utilities"
|
||||||
|
|
||||||
|
/datum/data/pda/app/signaller/update_ui(mob/user as mob, list/data)
|
||||||
|
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/signal))
|
||||||
|
var/obj/item/radio/integrated/signal/R = pda.cartridge.radio
|
||||||
|
data["signal_freq"] = format_frequency(R.frequency)
|
||||||
|
data["signal_code"] = R.code
|
||||||
|
|
||||||
|
/datum/data/pda/app/signaller/Topic(href, list/href_list)
|
||||||
|
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/signal))
|
||||||
|
var/obj/item/radio/integrated/signal/R = pda.cartridge.radio
|
||||||
|
|
||||||
|
switch(href_list["choice"])
|
||||||
|
if("Send Signal")
|
||||||
|
spawn(0)
|
||||||
|
R.send_signal("ACTIVATE")
|
||||||
|
|
||||||
|
if("Signal Frequency")
|
||||||
|
var/new_frequency = sanitize_frequency(R.frequency + text2num(href_list["sfreq"]))
|
||||||
|
R.set_frequency(new_frequency)
|
||||||
|
|
||||||
|
if("Signal Code")
|
||||||
|
R.code += text2num(href_list["scode"])
|
||||||
|
R.code = round(R.code)
|
||||||
|
R.code = min(100, R.code)
|
||||||
|
R.code = max(1, R.code)
|
||||||
|
|
||||||
|
/datum/data/pda/app/power
|
||||||
|
name = "Power Monitor"
|
||||||
|
icon = "exclamation-triangle"
|
||||||
|
template = "pda_power"
|
||||||
|
category = "Engineering"
|
||||||
|
update = PDA_APP_UPDATE_SLOW
|
||||||
|
|
||||||
|
// var/obj/machinery/computer/monitor/powmonitor = null
|
||||||
|
|
||||||
|
// /datum/data/pda/app/power/update_ui(mob/user as mob, list/data)
|
||||||
|
// update = PDA_APP_UPDATE_SLOW
|
||||||
|
|
||||||
|
// if(powmonitor && !isnull(powmonitor.powernet))
|
||||||
|
// data["records"] = list(
|
||||||
|
// "powerconnected" = 1,
|
||||||
|
// "poweravail" = powmonitor.powernet.avail,
|
||||||
|
// "powerload" = num2text(powmonitor.powernet.viewload, 10),
|
||||||
|
// "powerdemand" = powmonitor.powernet.load,
|
||||||
|
// "apcs" = GLOB.apc_repository.apc_data(powmonitor.powernet))
|
||||||
|
// has_back = 1
|
||||||
|
// else
|
||||||
|
// data["records"] = list(
|
||||||
|
// "powerconnected" = 0,
|
||||||
|
// "powermonitors" = GLOB.powermonitor_repository.powermonitor_data())
|
||||||
|
// has_back = 0
|
||||||
|
|
||||||
|
// /datum/data/pda/app/power/Topic(href, list/href_list)
|
||||||
|
// switch(href_list["choice"])
|
||||||
|
// if("Power Select")
|
||||||
|
// var/pref = href_list["target"]
|
||||||
|
// powmonitor = locate(pref)
|
||||||
|
// update = PDA_APP_UPDATE
|
||||||
|
// if("Back")
|
||||||
|
// powmonitor = null
|
||||||
|
// update = PDA_APP_UPDATE
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records
|
||||||
|
var/datum/data/record/general_records = null
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/update_ui(mob/user as mob, list/data)
|
||||||
|
var/list/records[0]
|
||||||
|
|
||||||
|
if(general_records && (general_records in data_core.general))
|
||||||
|
data["records"] = records
|
||||||
|
records["general"] = general_records.fields
|
||||||
|
return records
|
||||||
|
else
|
||||||
|
for(var/A in sortRecord(data_core.general))
|
||||||
|
var/datum/data/record/R = A
|
||||||
|
if(R)
|
||||||
|
records += list(list(Name = R.fields["name"], "ref" = "\ref[R]"))
|
||||||
|
data["recordsList"] = records
|
||||||
|
return null
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/Topic(href, list/href_list)
|
||||||
|
switch(href_list["choice"])
|
||||||
|
if("Records")
|
||||||
|
var/datum/data/record/R = locate(href_list["target"])
|
||||||
|
if(R && (R in data_core.general))
|
||||||
|
load_records(R)
|
||||||
|
if("Back")
|
||||||
|
general_records = null
|
||||||
|
has_back = 0
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/proc/load_records(datum/data/record/R)
|
||||||
|
general_records = R
|
||||||
|
has_back = 1
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/medical
|
||||||
|
name = "Medical Records"
|
||||||
|
icon = "heartbeat"
|
||||||
|
template = "pda_medical"
|
||||||
|
category = "Medical"
|
||||||
|
|
||||||
|
var/datum/data/record/medical_records = null
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/medical/update_ui(mob/user as mob, list/data)
|
||||||
|
var/list/records = ..()
|
||||||
|
if(!records)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(medical_records && (medical_records in data_core.medical))
|
||||||
|
records["medical"] = medical_records.fields
|
||||||
|
|
||||||
|
return records
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/medical/load_records(datum/data/record/R)
|
||||||
|
..(R)
|
||||||
|
for(var/A in data_core.medical)
|
||||||
|
var/datum/data/record/E = A
|
||||||
|
if(E && (E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
|
||||||
|
medical_records = E
|
||||||
|
break
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/security
|
||||||
|
name = "Security Records"
|
||||||
|
icon = "tags"
|
||||||
|
template = "pda_security"
|
||||||
|
category = "Security"
|
||||||
|
|
||||||
|
var/datum/data/record/security_records = null
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/security/update_ui(mob/user as mob, list/data)
|
||||||
|
var/list/records = ..()
|
||||||
|
if(!records)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(security_records && (security_records in data_core.security))
|
||||||
|
records["security"] = security_records.fields
|
||||||
|
|
||||||
|
return records
|
||||||
|
|
||||||
|
/datum/data/pda/app/crew_records/security/load_records(datum/data/record/R)
|
||||||
|
..(R)
|
||||||
|
for(var/A in data_core.security)
|
||||||
|
var/datum/data/record/E = A
|
||||||
|
if(E && (E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
|
||||||
|
security_records = E
|
||||||
|
break
|
||||||
|
|
||||||
|
/datum/data/pda/app/secbot_control
|
||||||
|
name = "Security Bot Access"
|
||||||
|
icon = "rss"
|
||||||
|
template = "pda_secbot"
|
||||||
|
category = "Security"
|
||||||
|
|
||||||
|
/datum/data/pda/app/secbot_control/update_ui(mob/user as mob, list/data)
|
||||||
|
var/botsData[0]
|
||||||
|
var/beepskyData[0]
|
||||||
|
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/beepsky))
|
||||||
|
var/obj/item/radio/integrated/beepsky/SC = pda.cartridge.radio
|
||||||
|
beepskyData["active"] = SC.active ? sanitize(SC.active.name) : null
|
||||||
|
has_back = SC.active ? 1 : 0
|
||||||
|
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/mob/living/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
|
||||||
|
has_back = 0
|
||||||
|
|
||||||
|
data["beepsky"] = beepskyData
|
||||||
|
|
||||||
|
/datum/data/pda/app/secbot_control/Topic(href, list/href_list)
|
||||||
|
switch(href_list["choice"])
|
||||||
|
if("Back")
|
||||||
|
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/beepsky))
|
||||||
|
pda.cartridge.radio.Topic(null, list(radiomenu = "1", op = "botlist"))
|
||||||
|
|
||||||
|
/datum/data/pda/app/mule_control
|
||||||
|
name = "Delivery Bot Control"
|
||||||
|
icon = "truck"
|
||||||
|
template = "pda_mule"
|
||||||
|
category = "Quartermaster"
|
||||||
|
|
||||||
|
// /datum/data/pda/app/mule_control/update_ui(mob/user as mob, list/data)
|
||||||
|
// var/muleData[0]
|
||||||
|
// var/mulebotsData[0]
|
||||||
|
// if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/mule))
|
||||||
|
// var/obj/item/radio/integrated/mule/QC = pda.cartridge.radio
|
||||||
|
// muleData["active"] = QC.active ? sanitize(QC.active.name) : null
|
||||||
|
// has_back = QC.active ? 1 : 0
|
||||||
|
// 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/mob/living/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
|
||||||
|
// has_back = 0
|
||||||
|
|
||||||
|
// data["mulebot"] = muleData
|
||||||
|
|
||||||
|
// /datum/data/pda/app/mule_control/Topic(href, list/href_list)
|
||||||
|
// switch(href_list["choice"])
|
||||||
|
// if("Back")
|
||||||
|
// if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/radio/integrated/mule))
|
||||||
|
// pda.cartridge.radio.Topic(null, list(radiomenu = "1", op = "botlist"))
|
||||||
|
|
||||||
|
/datum/data/pda/app/supply
|
||||||
|
name = "Supply Records"
|
||||||
|
icon = "file-text-o"
|
||||||
|
template = "pda_supply"
|
||||||
|
category = "Quartermaster"
|
||||||
|
update = PDA_APP_UPDATE_SLOW
|
||||||
|
|
||||||
|
// /datum/data/pda/app/supply/update_ui(mob/user as mob, list/data)
|
||||||
|
// var/supplyData[0]
|
||||||
|
|
||||||
|
// if(SSshuttle.supply.mode == SHUTTLE_CALL)
|
||||||
|
// supplyData["shuttle_moving"] = 1
|
||||||
|
|
||||||
|
// if(is_station_level(SSshuttle.supply.z))
|
||||||
|
// supplyData["shuttle_loc"] = "Station"
|
||||||
|
// else
|
||||||
|
// supplyData["shuttle_loc"] = "CentCom"
|
||||||
|
|
||||||
|
// supplyData["shuttle_time"] = "([SSshuttle.supply.timeLeft(600)] Mins)"
|
||||||
|
|
||||||
|
// var/supplyOrderCount = 0
|
||||||
|
// var/supplyOrderData[0]
|
||||||
|
// for(var/S in SSshuttle.shoppinglist)
|
||||||
|
// var/datum/supply_order/SO = S
|
||||||
|
// supplyOrderCount++
|
||||||
|
// 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 SSshuttle.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
|
||||||
|
|
||||||
|
// data["supply"] = supplyData
|
||||||
|
|
||||||
|
/datum/data/pda/app/janitor
|
||||||
|
name = "Custodial Locator"
|
||||||
|
icon = "trash-o"
|
||||||
|
template = "pda_janitor"
|
||||||
|
category = "Utilities"
|
||||||
|
update = PDA_APP_UPDATE_SLOW
|
||||||
|
|
||||||
|
/datum/data/pda/app/janitor/update_ui(mob/user as mob, list/data)
|
||||||
|
var/JaniData[0]
|
||||||
|
var/turf/cl = get_turf(pda)
|
||||||
|
|
||||||
|
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 all_mops)//GLOB.janitorial_equipment)
|
||||||
|
var/turf/ml = get_turf(M)
|
||||||
|
if(ml)
|
||||||
|
if(ml.z != cl.z)
|
||||||
|
continue
|
||||||
|
var/direction = get_dir(pda, M)
|
||||||
|
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)
|
||||||
|
var/turf/bl = get_turf(B)
|
||||||
|
if(bl)
|
||||||
|
if(bl.z != cl.z)
|
||||||
|
continue
|
||||||
|
var/direction = get_dir(pda,B)
|
||||||
|
BucketData[++BucketData.len] = list ("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "volume" = B.reagents.total_volume, "max_volume" = B.reagents.maximum_volume)
|
||||||
|
|
||||||
|
var/CbotData[0]
|
||||||
|
for(var/mob/living/bot/cleanbot/B in mob_list)
|
||||||
|
var/turf/bl = get_turf(B)
|
||||||
|
if(bl)
|
||||||
|
if(bl.z != cl.z)
|
||||||
|
continue
|
||||||
|
var/direction = get_dir(pda,B)
|
||||||
|
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)
|
||||||
|
var/turf/bl = get_turf(B)
|
||||||
|
if(bl)
|
||||||
|
if(bl.z != cl.z)
|
||||||
|
continue
|
||||||
|
var/direction = get_dir(pda,B)
|
||||||
|
CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "volume" = B.reagents.total_volume, "max_volume" = B.reagents.maximum_volume)
|
||||||
|
|
||||||
|
JaniData["mops"] = MopData.len ? MopData : null
|
||||||
|
JaniData["buckets"] = BucketData.len ? BucketData : null
|
||||||
|
JaniData["cleanbots"] = CbotData.len ? CbotData : null
|
||||||
|
JaniData["carts"] = CartData.len ? CartData : null
|
||||||
|
data["janitor"] = JaniData
|
||||||
111
code/modules/pda/core_apps.dm
Normal file
111
code/modules/pda/core_apps.dm
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/datum/data/pda/app/main_menu
|
||||||
|
icon = "home"
|
||||||
|
template = "pda_main_menu"
|
||||||
|
hidden = 1
|
||||||
|
|
||||||
|
/datum/data/pda/app/main_menu/update_ui(mob/user as mob, list/data)
|
||||||
|
title = pda.name
|
||||||
|
|
||||||
|
data["app"]["is_home"] = 1
|
||||||
|
|
||||||
|
data["apps"] = pda.shortcut_cache
|
||||||
|
data["categories"] = pda.shortcut_cat_order
|
||||||
|
data["pai"] = !isnull(pda.pai) // pAI inserted?
|
||||||
|
|
||||||
|
var/list/notifying[0]
|
||||||
|
for(var/P in pda.notifying_programs)
|
||||||
|
notifying["\ref[P]"] = 1
|
||||||
|
data["notifying"] = notifying
|
||||||
|
|
||||||
|
/datum/data/pda/app/main_menu/Topic(href, list/href_list)
|
||||||
|
switch(href_list["choice"])
|
||||||
|
if("UpdateInfo")
|
||||||
|
pda.ownjob = pda.id.assignment
|
||||||
|
pda.ownrank = pda.id.rank
|
||||||
|
pda.name = "PDA-[pda.owner] ([pda.ownjob])"
|
||||||
|
if("pai")
|
||||||
|
if(pda.pai)
|
||||||
|
if(pda.pai.loc != pda)
|
||||||
|
pda.pai = null
|
||||||
|
else
|
||||||
|
switch(href_list["option"])
|
||||||
|
if("1") // Configure pAI device
|
||||||
|
pda.pai.attack_self(usr)
|
||||||
|
if("2") // Eject pAI device
|
||||||
|
var/turf/T = get_turf_or_move(pda.loc)
|
||||||
|
if(T)
|
||||||
|
pda.pai.loc = T
|
||||||
|
pda.pai = null
|
||||||
|
|
||||||
|
/datum/data/pda/app/notekeeper
|
||||||
|
name = "Notekeeper"
|
||||||
|
icon = "sticky-note-o"
|
||||||
|
template = "pda_notekeeper"
|
||||||
|
|
||||||
|
var/note = null
|
||||||
|
var/notehtml = ""
|
||||||
|
|
||||||
|
/datum/data/pda/app/notekeeper/start()
|
||||||
|
. = ..()
|
||||||
|
if(!note)
|
||||||
|
note = "Congratulations, your station has chosen the [pda.model_name]!"
|
||||||
|
|
||||||
|
/datum/data/pda/app/notekeeper/update_ui(mob/user as mob, list/data)
|
||||||
|
data["note"] = note // current pda notes
|
||||||
|
|
||||||
|
/datum/data/pda/app/notekeeper/Topic(href, list/href_list)
|
||||||
|
switch(href_list["choice"])
|
||||||
|
if("Edit")
|
||||||
|
var/n = input("Please enter message", name, notehtml) as message
|
||||||
|
if(pda.loc == usr)
|
||||||
|
note = adminscrub(n)
|
||||||
|
notehtml = html_decode(note)
|
||||||
|
note = replacetext(note, "\n", "<br>")
|
||||||
|
else
|
||||||
|
pda.close(usr)
|
||||||
|
|
||||||
|
/datum/data/pda/app/manifest
|
||||||
|
name = "Crew Manifest"
|
||||||
|
icon = "user"
|
||||||
|
template = "pda_manifest"
|
||||||
|
update = PDA_APP_UPDATE_SLOW
|
||||||
|
|
||||||
|
// /datum/data/pda/app/manifest/update_ui(mob/user as mob, list/data)
|
||||||
|
// data_core.get_manifest_json()
|
||||||
|
// data["manifest"] = PDA_Manifest
|
||||||
|
|
||||||
|
/datum/data/pda/app/manifest/Topic(href, list/href_list)
|
||||||
|
|
||||||
|
/datum/data/pda/app/atmos_scanner
|
||||||
|
name = "Atmospheric Scan"
|
||||||
|
icon = "fire"
|
||||||
|
template = "pda_atmos_scan"
|
||||||
|
category = "Utilities"
|
||||||
|
update = PDA_APP_UPDATE_SLOW
|
||||||
|
|
||||||
|
// /datum/data/pda/app/atmos_scanner/update_ui(mob/user as mob, list/data)
|
||||||
|
// var/turf/T = get_turf(user.loc)
|
||||||
|
// if(!isnull(T))
|
||||||
|
// var/datum/gas_mixture/environment = T.return_air()
|
||||||
|
|
||||||
|
// var/pressure = environment.return_pressure()
|
||||||
|
// var/total_moles = environment.total_moles
|
||||||
|
|
||||||
|
// if(total_moles)
|
||||||
|
// var/o2_level = environment.oxygen/total_moles
|
||||||
|
// var/n2_level = environment.nitrogen/total_moles
|
||||||
|
// var/co2_level = environment.carbon_dioxide/total_moles
|
||||||
|
// var/plasma_level = environment.toxins/total_moles
|
||||||
|
// var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level)
|
||||||
|
// data["aircontents"] = list(
|
||||||
|
// "pressure" = pressure,
|
||||||
|
// "nitrogen" = n2_level*100,
|
||||||
|
// "oxygen" = o2_level*100,
|
||||||
|
// "carbon_dioxide" = co2_level*100,
|
||||||
|
// "plasma" = plasma_level*100,
|
||||||
|
// "other" = unknown_level,
|
||||||
|
// "temp" = environment.temperature-T0C,
|
||||||
|
// "reading" = 1
|
||||||
|
// )
|
||||||
|
// if(isnull(data["aircontents"]))
|
||||||
|
// data["aircontents"] = list("reading" = 0)
|
||||||
215
code/modules/pda/messenger.dm
Normal file
215
code/modules/pda/messenger.dm
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/datum/data/pda/app/messenger
|
||||||
|
name = "Messenger"
|
||||||
|
icon = "comments-o"
|
||||||
|
notify_icon = "comments"
|
||||||
|
title = "SpaceMessenger V4.1.0"
|
||||||
|
template = "pda_messenger"
|
||||||
|
|
||||||
|
var/toff = 0 //If 1, messenger disabled
|
||||||
|
var/list/tnote[0] //Current Texts
|
||||||
|
var/last_text //No text spamming
|
||||||
|
|
||||||
|
var/m_hidden = 0 // Is the PDA hidden from the PDA list?
|
||||||
|
var/active_conversation = null // New variable that allows us to only view a single conversation.
|
||||||
|
var/list/conversations = list() // For keeping up with who we have PDA messsages from.
|
||||||
|
var/latest_post = 0
|
||||||
|
var/auto_scroll = 1
|
||||||
|
|
||||||
|
/datum/data/pda/app/messenger/start()
|
||||||
|
. = ..()
|
||||||
|
unnotify()
|
||||||
|
latest_post = 0
|
||||||
|
|
||||||
|
/datum/data/pda/app/messenger/update_ui(mob/user as mob, list/data)
|
||||||
|
data["silent"] = notify_silent // does the pda make noise when it receives a message?
|
||||||
|
data["toff"] = toff // is the messenger function turned off?
|
||||||
|
data["active_conversation"] = active_conversation // Which conversation are we following right now?
|
||||||
|
|
||||||
|
has_back = active_conversation
|
||||||
|
if(active_conversation)
|
||||||
|
data["messages"] = tnote
|
||||||
|
for(var/c in tnote)
|
||||||
|
if(c["target"] == active_conversation)
|
||||||
|
data["convo_name"] = sanitize(c["owner"])
|
||||||
|
data["convo_job"] = sanitize(c["job"])
|
||||||
|
break
|
||||||
|
data["auto_scroll"] = auto_scroll
|
||||||
|
data["latest_post"] = latest_post
|
||||||
|
latest_post = tnote.len
|
||||||
|
else
|
||||||
|
var/convopdas[0]
|
||||||
|
var/pdas[0]
|
||||||
|
for(var/A in PDAs)
|
||||||
|
var/obj/item/device/pda/P = A
|
||||||
|
var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger)
|
||||||
|
|
||||||
|
if(!P.owner || PM.toff || P == pda || PM.m_hidden)
|
||||||
|
continue
|
||||||
|
if(conversations.Find("\ref[P]"))
|
||||||
|
convopdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "1")))
|
||||||
|
else
|
||||||
|
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
|
||||||
|
|
||||||
|
data["convopdas"] = convopdas
|
||||||
|
data["pdas"] = pdas
|
||||||
|
|
||||||
|
var/list/plugins = list()
|
||||||
|
if(pda.cartridge)
|
||||||
|
for(var/A in pda.cartridge.messenger_plugins)
|
||||||
|
var/datum/data/pda/messenger_plugin/P = A
|
||||||
|
plugins += list(list(name = P.name, icon = P.icon, ref = "\ref[P]"))
|
||||||
|
data["plugins"] = plugins
|
||||||
|
|
||||||
|
if(pda.cartridge)
|
||||||
|
data["charges"] = pda.cartridge.charges ? pda.cartridge.charges : 0
|
||||||
|
|
||||||
|
/datum/data/pda/app/messenger/Topic(href, list/href_list)
|
||||||
|
if(!pda.can_use())
|
||||||
|
return
|
||||||
|
unnotify()
|
||||||
|
|
||||||
|
switch(href_list["choice"])
|
||||||
|
if("Toggle Messenger")
|
||||||
|
toff = !toff
|
||||||
|
if("Toggle Ringer")//If viewing texts then erase them, if not then toggle silent status
|
||||||
|
notify_silent = !notify_silent
|
||||||
|
if("Clear")//Clears messages
|
||||||
|
if(href_list["option"] == "All")
|
||||||
|
tnote.Cut()
|
||||||
|
conversations.Cut()
|
||||||
|
if(href_list["option"] == "Convo")
|
||||||
|
var/new_tnote[0]
|
||||||
|
for(var/i in tnote)
|
||||||
|
if(i["target"] != active_conversation)
|
||||||
|
new_tnote[++new_tnote.len] = i
|
||||||
|
tnote = new_tnote
|
||||||
|
conversations.Remove(active_conversation)
|
||||||
|
|
||||||
|
active_conversation = null
|
||||||
|
latest_post = 0
|
||||||
|
if("Message")
|
||||||
|
var/obj/item/device/pda/P = locate(href_list["target"])
|
||||||
|
create_message(usr, P)
|
||||||
|
if(href_list["target"] in conversations) // Need to make sure the message went through, if not welp.
|
||||||
|
active_conversation = href_list["target"]
|
||||||
|
latest_post = 0
|
||||||
|
if("Select Conversation")
|
||||||
|
var/P = href_list["convo"]
|
||||||
|
for(var/n in conversations)
|
||||||
|
if(P == n)
|
||||||
|
active_conversation = P
|
||||||
|
latest_post = 0
|
||||||
|
if("Messenger Plugin")
|
||||||
|
if(!href_list["target"] || !href_list["plugin"])
|
||||||
|
return
|
||||||
|
|
||||||
|
var/obj/item/device/pda/P = locate(href_list["target"])
|
||||||
|
if(!P)
|
||||||
|
to_chat(usr, "PDA not found.")
|
||||||
|
|
||||||
|
var/datum/data/pda/messenger_plugin/plugin = locate(href_list["plugin"])
|
||||||
|
if(plugin && (plugin in pda.cartridge.messenger_plugins))
|
||||||
|
plugin.messenger = src
|
||||||
|
plugin.user_act(usr, P)
|
||||||
|
if("Back")
|
||||||
|
active_conversation = null
|
||||||
|
latest_post = 0
|
||||||
|
if("Autoscroll")
|
||||||
|
auto_scroll = !auto_scroll
|
||||||
|
|
||||||
|
/datum/data/pda/app/messenger/proc/create_message(var/mob/living/U, var/obj/item/device/pda/P)
|
||||||
|
var/t = input(U, "Please enter message", name, null) as text|null
|
||||||
|
if(!t)
|
||||||
|
return
|
||||||
|
t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN))
|
||||||
|
t = readd_quotes(t)
|
||||||
|
if(!t || !istype(P))
|
||||||
|
return
|
||||||
|
if(!in_range(pda, U) && pda.loc != U)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger)
|
||||||
|
|
||||||
|
if(!PM || PM.toff || toff)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(last_text && world.time < last_text + 5)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!pda.can_use())
|
||||||
|
return
|
||||||
|
|
||||||
|
last_text = world.time
|
||||||
|
// check if telecomms I/O route 1459 is stable
|
||||||
|
//var/telecomms_intact = telecomms_process(P.owner, owner, t)
|
||||||
|
var/obj/machinery/message_server/useMS = null
|
||||||
|
if(message_servers)
|
||||||
|
for(var/A in message_servers)
|
||||||
|
var/obj/machinery/message_server/MS = A
|
||||||
|
//PDAs are now dependent on the Message Server.
|
||||||
|
if(MS.active)
|
||||||
|
useMS = MS
|
||||||
|
break
|
||||||
|
|
||||||
|
var/datum/signal/signal = pda.telecomms_process()
|
||||||
|
|
||||||
|
var/useTC = 0
|
||||||
|
if(signal)
|
||||||
|
if(signal.data["done"])
|
||||||
|
useTC = 1
|
||||||
|
var/turf/pos = get_turf(P)
|
||||||
|
// TODO: Make the radio system cooperate with the space manager
|
||||||
|
if(pos.z in signal.data["level"])
|
||||||
|
useTC = 2
|
||||||
|
//Let's make this barely readable
|
||||||
|
if(signal.data["compression"] > 0)
|
||||||
|
t = Gibberish(t, signal.data["compression"] + 50)
|
||||||
|
|
||||||
|
if(useMS && useTC) // only send the message if it's stable
|
||||||
|
if(useTC != 2) // Does our recipient have a broadcaster on their level?
|
||||||
|
to_chat(U, "ERROR: Cannot reach recipient.")
|
||||||
|
return
|
||||||
|
useMS.send_pda_message("[P.owner]","[pda.owner]","[t]")
|
||||||
|
tnote.Add(list(list("sent" = 1, "owner" = "[P.owner]", "job" = "[P.ownjob]", "message" = "[t]", "target" = "\ref[P]")))
|
||||||
|
PM.tnote.Add(list(list("sent" = 0, "owner" = "[pda.owner]", "job" = "[pda.ownjob]", "message" = "[t]", "target" = "\ref[pda]")))
|
||||||
|
pda.investigate_log("<span class='game say'>PDA Message - <span class='name'>[U.key] - [pda.owner]</span> -> <span class='name'>[P.owner]</span>: <span class='message'>[t]</span></span>", "pda")
|
||||||
|
if(!conversations.Find("\ref[P]"))
|
||||||
|
conversations.Add("\ref[P]")
|
||||||
|
if(!PM.conversations.Find("\ref[pda]"))
|
||||||
|
PM.conversations.Add("\ref[pda]")
|
||||||
|
|
||||||
|
SSnanoui.update_user_uis(U, P) // Update the sending user's PDA UI so that they can see the new message
|
||||||
|
PM.notify("<b>Message from [pda.owner] ([pda.ownjob]), </b>\"[t]\" (<a href='?src=[REF(PM)];choice=Message;target=\ref[pda]'>Reply</a>)")
|
||||||
|
log_pda("(PDA: [src.name]) sent \"[t]\" to [P.name]", usr)
|
||||||
|
else
|
||||||
|
to_chat(U, "<span class='notice'>ERROR: Messaging server is not responding.</span>")
|
||||||
|
|
||||||
|
/datum/data/pda/app/messenger/proc/available_pdas()
|
||||||
|
var/list/names = list()
|
||||||
|
var/list/plist = list()
|
||||||
|
var/list/namecounts = list()
|
||||||
|
|
||||||
|
if(toff)
|
||||||
|
to_chat(usr, "Turn on your receiver in order to send messages.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for(var/A in PDAs)
|
||||||
|
var/obj/item/device/pda/P = A
|
||||||
|
var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger)
|
||||||
|
|
||||||
|
if(!P.owner || !PM || PM.hidden || P == pda || PM.toff)
|
||||||
|
continue
|
||||||
|
|
||||||
|
var/name = P.owner
|
||||||
|
if(name in names)
|
||||||
|
namecounts[name]++
|
||||||
|
name = text("[name] ([namecounts[name]])")
|
||||||
|
else
|
||||||
|
names.Add(name)
|
||||||
|
namecounts[name] = 1
|
||||||
|
|
||||||
|
plist[text("[name]")] = P
|
||||||
|
return plist
|
||||||
|
|
||||||
|
/datum/data/pda/app/messenger/proc/can_receive()
|
||||||
|
return pda.owner && !toff && !hidden
|
||||||
91
code/modules/pda/messenger_plugins.dm
Normal file
91
code/modules/pda/messenger_plugins.dm
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/datum/data/pda/messenger_plugin
|
||||||
|
var/datum/data/pda/app/messenger/messenger
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/proc/user_act(mob/user as mob, obj/item/device/pda/P)
|
||||||
|
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus
|
||||||
|
name = "*Send Virus*"
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/user_act(mob/user as mob, obj/item/device/pda/P)
|
||||||
|
var/datum/data/pda/app/messenger/M = P.find_program(/datum/data/pda/app/messenger)
|
||||||
|
|
||||||
|
if(M && !M.toff && pda.cartridge.charges > 0)
|
||||||
|
pda.cartridge.charges--
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/clown
|
||||||
|
icon = "star"
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/clown/user_act(mob/user as mob, obj/item/device/pda/P)
|
||||||
|
. = ..(user, P)
|
||||||
|
if(.)
|
||||||
|
user.show_message("<span class='notice'>Virus sent!</span>", 1)
|
||||||
|
P.honkamt = (rand(15,20))
|
||||||
|
P.ttone = "honk"
|
||||||
|
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/mime
|
||||||
|
icon = "arrow-circle-down"
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/mime/user_act(mob/user as mob, obj/item/device/pda/P)
|
||||||
|
. = ..(user, P)
|
||||||
|
if(.)
|
||||||
|
user.show_message("<span class='notice'>Virus sent!</span>", 1)
|
||||||
|
var/datum/data/pda/app/M = P.find_program(/datum/data/pda/app/messenger)
|
||||||
|
if(M)
|
||||||
|
M.notify_silent = 1
|
||||||
|
P.ttone = "silence"
|
||||||
|
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/detonate
|
||||||
|
name = "*Detonate*"
|
||||||
|
icon = "exclamation-circle"
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/detonate/user_act(mob/user as mob, obj/item/device/pda/P)
|
||||||
|
. = ..(user, P)
|
||||||
|
if(.)
|
||||||
|
var/difficulty = 0
|
||||||
|
|
||||||
|
if(pda.cartridge)
|
||||||
|
difficulty += pda.cartridge.programs.len / 2
|
||||||
|
else
|
||||||
|
difficulty += 2
|
||||||
|
|
||||||
|
if(!P.detonate || P.hidden_uplink)
|
||||||
|
user.show_message("<span class='warning'>The target PDA does not seem to respond to the detonation command.</span>", 1)
|
||||||
|
pda.cartridge.charges++
|
||||||
|
else if(prob(difficulty * 12))
|
||||||
|
user.show_message("<span class='warning'>An error flashes on your [pda].</span>", 1)
|
||||||
|
else if(prob(difficulty * 3))
|
||||||
|
user.show_message("<span class='danger'>Energy feeds back into your [pda]!</span>", 1)
|
||||||
|
pda.close(user)
|
||||||
|
pda.explode()
|
||||||
|
log_admin("[key_name(user)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up")
|
||||||
|
message_admins("[key_name_admin(user)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up", 1)
|
||||||
|
else
|
||||||
|
user.show_message("<span class='notice'>Success!</span>", 1)
|
||||||
|
log_admin("[key_name(user)] just attempted to blow up [P] with the Detomatix cartridge and succeded")
|
||||||
|
message_admins("[key_name_admin(user)] just attempted to blow up [P] with the Detomatix cartridge and succeded", 1)
|
||||||
|
P.explode()
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/frame
|
||||||
|
icon = "exclamation-circle"
|
||||||
|
|
||||||
|
/datum/data/pda/messenger_plugin/virus/frame/user_act(mob/user, obj/item/device/pda/P)
|
||||||
|
. = ..(user, P)
|
||||||
|
if(.)
|
||||||
|
var/lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
|
||||||
|
user.show_message("<span class='notice'>Virus Sent! The unlock code to the target is: [lock_code]</span>")
|
||||||
|
if(!P.hidden_uplink)
|
||||||
|
var/obj/item/device/uplink/hidden/uplink = new(P)
|
||||||
|
P.hidden_uplink = uplink
|
||||||
|
P.lock_code = lock_code
|
||||||
|
// else
|
||||||
|
// P.hidden_uplink.hidden_crystals += P.hidden_uplink.uses //Temporarially hide the PDA's crystals, so you can't steal telecrystals.
|
||||||
|
var/obj/item/weapon/cartridge/frame/parent_cart = pda.cartridge
|
||||||
|
P.hidden_uplink.uses = parent_cart.telecrystals
|
||||||
|
parent_cart.telecrystals = 0
|
||||||
|
P.hidden_uplink.active = TRUE
|
||||||
@@ -18,14 +18,10 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
var/owner = null
|
var/owner = null
|
||||||
var/default_cartridge = 0 // Access level defined by cartridge
|
var/default_cartridge = 0 // Access level defined by cartridge
|
||||||
var/obj/item/weapon/cartridge/cartridge = null //current cartridge
|
var/obj/item/weapon/cartridge/cartridge = null //current cartridge
|
||||||
var/mode = 0 //Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge.
|
|
||||||
|
|
||||||
var/lastmode = 0
|
|
||||||
var/ui_tick = 0
|
var/ui_tick = 0
|
||||||
var/nanoUI[0]
|
|
||||||
|
|
||||||
//Secondary variables
|
//Secondary variables
|
||||||
var/scanmode = 0 //1 is medical scanner, 2 is forensics, 3 is reagent scanner.
|
// var/scanmode = 0 //1 is medical scanner, 2 is forensics, 3 is reagent scanner.
|
||||||
var/fon = 0 //Is the flashlight function on?
|
var/fon = 0 //Is the flashlight function on?
|
||||||
var/f_lum = 2 //Luminosity for the flashlight function
|
var/f_lum = 2 //Luminosity for the flashlight function
|
||||||
var/message_silent = 0 //To beep or not to beep, that is the question
|
var/message_silent = 0 //To beep or not to beep, that is the question
|
||||||
@@ -34,7 +30,14 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
var/tnote[0] //Current Texts
|
var/tnote[0] //Current Texts
|
||||||
var/last_text //No text spamming
|
var/last_text //No text spamming
|
||||||
var/last_honk //Also no honk spamming that's bad too
|
var/last_honk //Also no honk spamming that's bad too
|
||||||
var/ttone = "beep" //The PDA ringtone!
|
var/ttone = "beep" //The ringtone!
|
||||||
|
var/list/ttone_sound = list("beep" = 'sound/machines/twobeep.ogg',
|
||||||
|
"boom" = 'sound/effects/explosionfar.ogg',
|
||||||
|
"slip" = 'sound/misc/slip.ogg',
|
||||||
|
"honk" = 'sound/items/bikehorn.ogg',
|
||||||
|
"SKREE" = 'sound/voice/shriek1.ogg',
|
||||||
|
// "holy" = 'sound/items/PDA/ambicha4-short.ogg',
|
||||||
|
"xeno" = 'sound/voice/hiss1.ogg')
|
||||||
var/newstone = "beep, beep" //The news ringtone!
|
var/newstone = "beep, beep" //The news ringtone!
|
||||||
var/lock_code = "" // Lockcode to unlock uplink
|
var/lock_code = "" // Lockcode to unlock uplink
|
||||||
var/honkamt = 0 //How many honks left when infected with honk.exe
|
var/honkamt = 0 //How many honks left when infected with honk.exe
|
||||||
@@ -67,6 +70,24 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
|
|
||||||
var/spam_proof = FALSE // If true, it can't be spammed by random events.
|
var/spam_proof = FALSE // If true, it can't be spammed by random events.
|
||||||
|
|
||||||
|
// App-based PDAs
|
||||||
|
var/model_name = "Thinktronic 5230 Personal Data Assistant"
|
||||||
|
var/datum/data/pda/utility/scanmode/scanmode = null
|
||||||
|
var/datum/data/pda/app/current_app = null
|
||||||
|
var/datum/data/pda/app/lastapp = null
|
||||||
|
var/list/programs = list(
|
||||||
|
new/datum/data/pda/app/main_menu,
|
||||||
|
new/datum/data/pda/app/notekeeper,
|
||||||
|
new/datum/data/pda/app/messenger,
|
||||||
|
new/datum/data/pda/app/manifest,
|
||||||
|
new/datum/data/pda/app/atmos_scanner,
|
||||||
|
new/datum/data/pda/utility/scanmode/notes,
|
||||||
|
new/datum/data/pda/utility/flashlight)
|
||||||
|
var/list/shortcut_cache = list()
|
||||||
|
var/list/shortcut_cat_order = list()
|
||||||
|
var/list/notifying_programs = list()
|
||||||
|
var/retro_mode = 0
|
||||||
|
|
||||||
/obj/item/device/pda/examine(mob/user)
|
/obj/item/device/pda/examine(mob/user)
|
||||||
. = ..()
|
. = ..()
|
||||||
if(Adjacent(user))
|
if(Adjacent(user))
|
||||||
@@ -97,6 +118,32 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
if(iscarbon(user) && !touch_silent)
|
if(iscarbon(user) && !touch_silent)
|
||||||
playsound(src, 'sound/machines/pda_click.ogg', 20)
|
playsound(src, 'sound/machines/pda_click.ogg', 20)
|
||||||
|
|
||||||
|
/obj/item/device/pda/proc/play_ringtone()
|
||||||
|
var/S
|
||||||
|
|
||||||
|
if(ttone in ttone_sound)
|
||||||
|
S = ttone_sound[ttone]
|
||||||
|
else
|
||||||
|
S = 'sound/machines/twobeep.ogg'
|
||||||
|
playsound(loc, S, 50, 1)
|
||||||
|
for(var/mob/O in hearers(3, loc))
|
||||||
|
O.show_message(text("[bicon(src)] *[ttone]*"))
|
||||||
|
|
||||||
|
/obj/item/device/pda/proc/set_ringtone()
|
||||||
|
var/t = input("Please enter new ringtone", name, ttone) as text
|
||||||
|
if(in_range(src, usr) && loc == usr)
|
||||||
|
if(t)
|
||||||
|
if(hidden_uplink && hidden_uplink.check_trigger(usr, lowertext(t), lowertext(lock_code)))
|
||||||
|
to_chat(usr, "The PDA softly beeps.")
|
||||||
|
close(usr)
|
||||||
|
else
|
||||||
|
t = sanitize(copytext(t, 1, 20))
|
||||||
|
ttone = t
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
close(usr)
|
||||||
|
return 0
|
||||||
|
|
||||||
/obj/item/device/pda/medical
|
/obj/item/device/pda/medical
|
||||||
default_cartridge = /obj/item/weapon/cartridge/medical
|
default_cartridge = /obj/item/weapon/cartridge/medical
|
||||||
icon_state = "pda-m"
|
icon_state = "pda-m"
|
||||||
@@ -442,6 +489,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
..()
|
..()
|
||||||
PDAs += src
|
PDAs += src
|
||||||
PDAs = sortAtom(PDAs)
|
PDAs = sortAtom(PDAs)
|
||||||
|
update_programs()
|
||||||
if(default_cartridge)
|
if(default_cartridge)
|
||||||
cartridge = new default_cartridge(src)
|
cartridge = new default_cartridge(src)
|
||||||
new /obj/item/weapon/pen(src)
|
new /obj/item/weapon/pen(src)
|
||||||
@@ -469,6 +517,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
else
|
else
|
||||||
icon = 'icons/obj/pda_old.dmi'
|
icon = 'icons/obj/pda_old.dmi'
|
||||||
log_debug("Invalid switch for PDA, defaulting to old PDA icons. [pdachoice] chosen.")
|
log_debug("Invalid switch for PDA, defaulting to old PDA icons. [pdachoice] chosen.")
|
||||||
|
start_program(find_program(/datum/data/pda/app/main_menu))
|
||||||
|
|
||||||
|
|
||||||
/obj/item/device/pda/proc/can_use()
|
/obj/item/device/pda/proc/can_use()
|
||||||
@@ -499,17 +548,25 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
return attack_self(M)
|
return attack_self(M)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/item/device/pda/proc/close(mob/user)
|
||||||
|
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||||
|
ui.close()
|
||||||
|
|
||||||
|
SStgui.close_uis(src)
|
||||||
|
|
||||||
/obj/item/device/pda/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
/obj/item/device/pda/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||||
ui_tick++
|
ui_tick++
|
||||||
var/datum/nanoui/old_ui = SSnanoui.get_open_ui(user, src, "main")
|
var/datum/nanoui/old_ui = SSnanoui.get_open_ui(user, src, "main")
|
||||||
var/auto_update = 1
|
var/auto_update = 1
|
||||||
if(mode in no_auto_update)
|
if(!current_app)
|
||||||
auto_update = 0
|
|
||||||
if(old_ui && (mode == lastmode && ui_tick % 5 && mode in update_every_five))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
lastmode = mode
|
if(current_app.update == PDA_APP_NOUPDATE && current_app == lastapp)
|
||||||
|
auto_update = 0
|
||||||
|
if(old_ui && (current_app == lastapp && ui_tick % 5 && current_app.update == PDA_APP_UPDATE_SLOW))
|
||||||
|
return
|
||||||
|
|
||||||
|
lastapp = current_app
|
||||||
|
|
||||||
var/title = "Personal Data Assistant"
|
var/title = "Personal Data Assistant"
|
||||||
|
|
||||||
@@ -518,156 +575,57 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
data["owner"] = owner // Who is your daddy...
|
data["owner"] = owner // Who is your daddy...
|
||||||
data["ownjob"] = ownjob // ...and what does he do?
|
data["ownjob"] = ownjob // ...and what does he do?
|
||||||
|
|
||||||
data["mode"] = mode // The current view
|
// update list of shortcuts, only if they changed
|
||||||
data["scanmode"] = scanmode // Scanners
|
if(!shortcut_cache.len)
|
||||||
data["fon"] = fon // Flashlight on?
|
shortcut_cache = list()
|
||||||
data["pai"] = (isnull(pai) ? 0 : 1) // pAI inserted?
|
shortcut_cat_order = list()
|
||||||
data["note"] = note // current pda notes
|
var/prog_list = programs.Copy()
|
||||||
data["message_silent"] = message_silent // does the pda make noise when it receives a message?
|
if(cartridge)
|
||||||
data["news_silent"] = news_silent // does the pda make noise when it receives news?
|
prog_list |= cartridge.programs
|
||||||
data["touch_silent"] = touch_silent // does the pda make noise when it receives news?
|
|
||||||
data["toff"] = toff // is the messenger function turned off?
|
|
||||||
data["active_conversation"] = active_conversation // Which conversation are we following right now?
|
|
||||||
|
|
||||||
|
for(var/A in prog_list)
|
||||||
|
var/datum/data/pda/P = A
|
||||||
|
|
||||||
|
if(P.hidden)
|
||||||
|
continue
|
||||||
|
var/list/cat
|
||||||
|
if(P.category in shortcut_cache)
|
||||||
|
cat = shortcut_cache[P.category]
|
||||||
|
else
|
||||||
|
cat = list()
|
||||||
|
shortcut_cache[P.category] = cat
|
||||||
|
shortcut_cat_order += P.category
|
||||||
|
cat |= list(list(name = P.name, icon = P.icon, notify_icon = P.notify_icon, ref = "\ref[P]"))
|
||||||
|
|
||||||
|
// force the order of a few core categories
|
||||||
|
shortcut_cat_order = list("General") \
|
||||||
|
+ sortList(shortcut_cat_order - list("General", "Scanners", "Utilities")) \
|
||||||
|
+ list("Scanners", "Utilities")
|
||||||
|
|
||||||
data["idInserted"] = (id ? 1 : 0)
|
data["idInserted"] = (id ? 1 : 0)
|
||||||
data["idLink"] = (id ? text("[id.registered_name], [id.assignment]") : "--------")
|
data["idLink"] = (id ? text("[id.registered_name], [id.assignment]") : "--------")
|
||||||
|
|
||||||
data["cart_loaded"] = cartridge ? 1:0
|
data["useRetro"] = retro_mode
|
||||||
if(cartridge)
|
|
||||||
var/cartdata[0]
|
|
||||||
cartdata["access"] = list(\
|
|
||||||
"access_security" = cartridge.access_security,\
|
|
||||||
"access_engine" = cartridge.access_engine,\
|
|
||||||
"access_atmos" = cartridge.access_atmos,\
|
|
||||||
"access_medical" = cartridge.access_medical,\
|
|
||||||
"access_clown" = cartridge.access_clown,\
|
|
||||||
"access_mime" = cartridge.access_mime,\
|
|
||||||
"access_janitor" = cartridge.access_janitor,\
|
|
||||||
"access_quartermaster" = cartridge.access_quartermaster,\
|
|
||||||
"access_hydroponics" = cartridge.access_hydroponics,\
|
|
||||||
"access_reagent_scanner" = cartridge.access_reagent_scanner,\
|
|
||||||
"access_remote_door" = cartridge.access_remote_door,\
|
|
||||||
"access_status_display" = cartridge.access_status_display,\
|
|
||||||
"access_detonate_pda" = cartridge.access_detonate_pda\
|
|
||||||
)
|
|
||||||
|
|
||||||
if(mode in cartmodes)
|
data["cartridge_name"] = cartridge ? cartridge.name : ""
|
||||||
data["records"] = cartridge.create_NanoUI_values()
|
data["stationTime"] = worldtime2stationtime(world.time)
|
||||||
|
|
||||||
if(mode == 0)
|
data["app"] = list()
|
||||||
cartdata["name"] = cartridge.name
|
current_app.update_ui(user, data)
|
||||||
if(isnull(cartridge.radio))
|
data["app"] |= list(
|
||||||
cartdata["radio"] = 0
|
"name" = current_app.title,
|
||||||
else
|
"icon" = current_app.icon,
|
||||||
if(istype(cartridge.radio, /obj/item/radio/integrated/beepsky))
|
"template" = current_app.template,
|
||||||
cartdata["radio"] = 1
|
"has_back" = current_app.has_back)
|
||||||
if(istype(cartridge.radio, /obj/item/radio/integrated/signal))
|
|
||||||
cartdata["radio"] = 2
|
|
||||||
//if(istype(cartridge.radio, /obj/item/radio/integrated/mule))
|
|
||||||
// cartdata["radio"] = 3
|
|
||||||
|
|
||||||
if(mode == 2)
|
|
||||||
cartdata["charges"] = cartridge.charges ? cartridge.charges : 0
|
|
||||||
data["cartridge"] = cartdata
|
|
||||||
|
|
||||||
data["stationTime"] = stationtime2text()
|
|
||||||
data["new_Message"] = new_message
|
|
||||||
data["new_News"] = new_news
|
|
||||||
|
|
||||||
var/datum/reception/reception = get_reception(src, do_sleep = 0)
|
|
||||||
var/has_reception = reception.telecomms_reception & TELECOMMS_RECEPTION_SENDER
|
|
||||||
data["reception"] = has_reception
|
|
||||||
|
|
||||||
if(mode==2)
|
|
||||||
var/convopdas[0]
|
|
||||||
var/pdas[0]
|
|
||||||
var/count = 0
|
|
||||||
for (var/obj/item/device/pda/P in PDAs)
|
|
||||||
if (!P.owner||P.toff||P == src||P.hidden) continue
|
|
||||||
if(conversations.Find("\ref[P]"))
|
|
||||||
convopdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "1")))
|
|
||||||
else
|
|
||||||
pdas.Add(list(list("Name" = "[P]", "Reference" = "\ref[P]", "Detonate" = "[P.detonate]", "inconvo" = "0")))
|
|
||||||
count++
|
|
||||||
|
|
||||||
data["convopdas"] = convopdas
|
|
||||||
data["pdas"] = pdas
|
|
||||||
data["pda_count"] = count
|
|
||||||
|
|
||||||
if(mode==21)
|
|
||||||
data["messagescount"] = tnote.len
|
|
||||||
data["messages"] = tnote
|
|
||||||
else
|
|
||||||
data["messagescount"] = null
|
|
||||||
data["messages"] = null
|
|
||||||
|
|
||||||
if(active_conversation)
|
|
||||||
for(var/c in tnote)
|
|
||||||
if(c["target"] == active_conversation)
|
|
||||||
data["convo_name"] = sanitize(c["owner"])
|
|
||||||
data["convo_job"] = sanitize(c["job"])
|
|
||||||
break
|
|
||||||
if(mode==41)
|
|
||||||
data_core.get_manifest_list()
|
|
||||||
|
|
||||||
|
|
||||||
if(mode==3)
|
|
||||||
data["aircontents"] = src.analyze_air()
|
|
||||||
if(mode==6)
|
|
||||||
if(has_reception)
|
|
||||||
feeds.Cut()
|
|
||||||
for(var/datum/feed_channel/channel in news_network.network_channels)
|
|
||||||
feeds[++feeds.len] = list("name" = channel.channel_name, "censored" = channel.censored)
|
|
||||||
data["feedChannels"] = feeds
|
|
||||||
if(mode==61)
|
|
||||||
var/datum/feed_channel/FC
|
|
||||||
for(FC in news_network.network_channels)
|
|
||||||
if(FC.channel_name == active_feed["name"])
|
|
||||||
break
|
|
||||||
|
|
||||||
var/list/feed = feed_info[active_feed]
|
|
||||||
if(!feed)
|
|
||||||
feed = list()
|
|
||||||
feed["channel"] = FC.channel_name
|
|
||||||
feed["author"] = "Unknown"
|
|
||||||
feed["censored"]= 0
|
|
||||||
feed["updated"] = -1
|
|
||||||
feed_info[active_feed] = feed
|
|
||||||
|
|
||||||
if(FC.updated > feed["updated"] && has_reception)
|
|
||||||
feed["author"] = FC.author
|
|
||||||
feed["updated"] = FC.updated
|
|
||||||
feed["censored"] = FC.censored
|
|
||||||
|
|
||||||
var/list/messages = list()
|
|
||||||
if(!FC.censored)
|
|
||||||
var/index = 0
|
|
||||||
for(var/datum/feed_message/FM in FC.messages)
|
|
||||||
index++
|
|
||||||
if(FM.img)
|
|
||||||
usr << browse_rsc(FM.img, "pda_news_tmp_photo_[feed["channel"]]_[index].png")
|
|
||||||
// News stories are HTML-stripped but require newline replacement to be properly displayed in NanoUI
|
|
||||||
var/body = replacetext(FM.body, "\n", "<br>")
|
|
||||||
messages[++messages.len] = list("author" = FM.author, "body" = body, "message_type" = FM.message_type, "time_stamp" = FM.time_stamp, "has_image" = (FM.img != null), "caption" = FM.caption, "index" = index)
|
|
||||||
feed["messages"] = messages
|
|
||||||
|
|
||||||
data["feed"] = feed
|
|
||||||
|
|
||||||
data["manifest"] = PDA_Manifest
|
|
||||||
|
|
||||||
nanoUI = data
|
|
||||||
// update the ui if it exists, returns null if no ui is passed/found
|
// update the ui if it exists, returns null if no ui is passed/found
|
||||||
|
|
||||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||||
|
|
||||||
if (!ui)
|
if(!ui)
|
||||||
// the ui does not exist, so we'll create a new() one
|
// the ui does not exist, so we'll create a new() one
|
||||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||||
ui = new(user, src, ui_key, "pda.tmpl", title, 520, 400, state = inventory_state)
|
ui = new(user, src, ui_key, "pda.tmpl", title, 520, 400, state = inventory_state)
|
||||||
// add templates for screens in common with communicator.
|
ui.set_state_key("pda")
|
||||||
ui.add_template("atmosphericScan", "atmospheric_scan.tmpl")
|
|
||||||
ui.add_template("crewManifest", "crew_manifest.tmpl")
|
|
||||||
// when the ui is first opened this is the data it will use
|
// when the ui is first opened this is the data it will use
|
||||||
ui.set_initial_data(data)
|
ui.set_initial_data(data)
|
||||||
// open the new ui window
|
// open the new ui window
|
||||||
@@ -682,24 +640,42 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
return
|
return
|
||||||
|
|
||||||
ui_interact(user) //NanoUI requires this proc
|
ui_interact(user) //NanoUI requires this proc
|
||||||
|
tgui_interact(user)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/item/device/pda/proc/start_program(datum/data/pda/P)
|
||||||
|
if(P && ((P in programs) || (cartridge && (P in cartridge.programs))))
|
||||||
|
return P.start()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
/obj/item/device/pda/proc/find_program(type)
|
||||||
|
var/datum/data/pda/A = locate(type) in programs
|
||||||
|
if(A)
|
||||||
|
return A
|
||||||
|
if(cartridge)
|
||||||
|
A = locate(type) in cartridge.programs
|
||||||
|
if(A)
|
||||||
|
return A
|
||||||
|
return null
|
||||||
|
|
||||||
|
// force the cache to rebuild on update_ui
|
||||||
|
/obj/item/device/pda/proc/update_shortcuts()
|
||||||
|
shortcut_cache.Cut()
|
||||||
|
|
||||||
|
/obj/item/device/pda/proc/update_programs()
|
||||||
|
for(var/A in programs)
|
||||||
|
var/datum/data/pda/P = A
|
||||||
|
P.pda = src
|
||||||
|
|
||||||
/obj/item/device/pda/Topic(href, href_list)
|
/obj/item/device/pda/Topic(href, href_list)
|
||||||
if(href_list["cartmenu"] && !isnull(cartridge))
|
. = ..()
|
||||||
cartridge.Topic(href, href_list)
|
if(.)
|
||||||
return 1
|
return
|
||||||
if(href_list["radiomenu"] && !isnull(cartridge) && !isnull(cartridge.radio))
|
|
||||||
cartridge.radio.Topic(href, href_list)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
..()
|
|
||||||
var/mob/user = usr
|
var/mob/user = usr
|
||||||
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||||
var/mob/living/U = usr
|
var/mob/living/U = usr
|
||||||
//Looking for master was kind of pointless since PDAs don't appear to have one.
|
if(usr.stat == DEAD)
|
||||||
//if ((src in U.contents) || ( istype(loc, /turf) && in_range(src, U) ) )
|
|
||||||
if (usr.stat == DEAD)
|
|
||||||
return 0
|
return 0
|
||||||
if(!can_use()) //Why reinvent the wheel? There's a proc that does exactly that.
|
if(!can_use()) //Why reinvent the wheel? There's a proc that does exactly that.
|
||||||
U.unset_machine()
|
U.unset_machine()
|
||||||
@@ -710,293 +686,56 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
add_fingerprint(U)
|
add_fingerprint(U)
|
||||||
U.set_machine(src)
|
U.set_machine(src)
|
||||||
|
|
||||||
|
if(href_list["radiomenu"] && !isnull(cartridge) && !isnull(cartridge.radio))
|
||||||
|
cartridge.radio.Topic(href, href_list)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
. = 1
|
||||||
|
|
||||||
switch(href_list["choice"])
|
switch(href_list["choice"])
|
||||||
|
if("Home")//Go home, largely replaces the old Return
|
||||||
//BASIC FUNCTIONS===================================
|
var/datum/data/pda/app/main_menu/A = find_program(/datum/data/pda/app/main_menu)
|
||||||
|
if(A)
|
||||||
if("Close")//Self explanatory
|
start_program(A)
|
||||||
U.unset_machine()
|
if("StartProgram")
|
||||||
ui.close()
|
if(href_list["program"])
|
||||||
return 0
|
var/datum/data/pda/app/A = locate(href_list["program"])
|
||||||
if("Refresh")//Refresh, goes to the end of the proc.
|
if(A)
|
||||||
if("Return")//Return
|
start_program(A)
|
||||||
if(mode<=9)
|
|
||||||
mode = 0
|
|
||||||
else
|
|
||||||
mode = round(mode/10)
|
|
||||||
if(mode==2)
|
|
||||||
active_conversation = null
|
|
||||||
if(mode==4)//Fix for cartridges. Redirects to hub.
|
|
||||||
mode = 0
|
|
||||||
else if(mode >= 40 && mode <= 49)//Fix for cartridges. Redirects to refresh the menu.
|
|
||||||
cartridge.mode = mode
|
|
||||||
if ("Authenticate")//Checks for ID
|
|
||||||
id_check(U, 1)
|
|
||||||
if("UpdateInfo")
|
|
||||||
ownjob = id.assignment
|
|
||||||
ownrank = id.rank
|
|
||||||
name = "PDA-[owner] ([ownjob])"
|
|
||||||
if("Eject")//Ejects the cart, only done from hub.
|
if("Eject")//Ejects the cart, only done from hub.
|
||||||
verb_remove_cartridge()
|
if(!isnull(cartridge))
|
||||||
|
var/turf/T = loc
|
||||||
//MENU FUNCTIONS===================================
|
if(ismob(T))
|
||||||
|
T = T.loc
|
||||||
if("0")//Hub
|
var/obj/item/weapon/cartridge/C = cartridge
|
||||||
mode = 0
|
C.forceMove(T)
|
||||||
if("1")//Notes
|
if(scanmode in C.programs)
|
||||||
mode = 1
|
scanmode = null
|
||||||
if("2")//Messenger
|
if(current_app in C.programs)
|
||||||
mode = 2
|
start_program(find_program(/datum/data/pda/app/main_menu))
|
||||||
if("21")//Read messages
|
if(C.radio)
|
||||||
mode = 21
|
C.radio.hostpda = null
|
||||||
if("3")//Atmos scan
|
for(var/datum/data/pda/P in notifying_programs)
|
||||||
mode = 3
|
if(P in C.programs)
|
||||||
if("4")//Redirects to hub
|
P.unnotify()
|
||||||
mode = 0
|
cartridge = null
|
||||||
if("chatroom") // chatroom hub
|
update_shortcuts()
|
||||||
mode = 5
|
if("Authenticate")//Checks for ID
|
||||||
if("41") //Manifest
|
id_check(usr, 1)
|
||||||
mode = 41
|
if("Retro")
|
||||||
|
retro_mode = !retro_mode
|
||||||
|
|
||||||
//MAIN FUNCTIONS===================================
|
|
||||||
|
|
||||||
if("Light")
|
|
||||||
if(fon)
|
|
||||||
fon = 0
|
|
||||||
set_light(0)
|
|
||||||
else
|
|
||||||
fon = 1
|
|
||||||
set_light(f_lum)
|
|
||||||
if("Medical Scan")
|
|
||||||
if(scanmode == 1)
|
|
||||||
scanmode = 0
|
|
||||||
else if((!isnull(cartridge)) && (cartridge.access_medical))
|
|
||||||
scanmode = 1
|
|
||||||
if("Reagent Scan")
|
|
||||||
if(scanmode == 3)
|
|
||||||
scanmode = 0
|
|
||||||
else if((!isnull(cartridge)) && (cartridge.access_reagent_scanner))
|
|
||||||
scanmode = 3
|
|
||||||
if("Halogen Counter")
|
|
||||||
if(scanmode == 4)
|
|
||||||
scanmode = 0
|
|
||||||
else if((!isnull(cartridge)) && (cartridge.access_engine))
|
|
||||||
scanmode = 4
|
|
||||||
if("Honk")
|
|
||||||
if ( !(last_honk && world.time < last_honk + 20) )
|
|
||||||
playsound(src, 'sound/items/bikehorn.ogg', 50, 1)
|
|
||||||
last_honk = world.time
|
|
||||||
if("Gas Scan")
|
|
||||||
if(scanmode == 5)
|
|
||||||
scanmode = 0
|
|
||||||
else if((!isnull(cartridge)) && (cartridge.access_atmos))
|
|
||||||
scanmode = 5
|
|
||||||
if("Toggle Beeping")
|
|
||||||
touch_silent = !touch_silent
|
|
||||||
|
|
||||||
//MESSENGER/NOTE FUNCTIONS===================================
|
|
||||||
|
|
||||||
if ("Edit")
|
|
||||||
var/n = input(U, "Please enter message", name, notehtml) as message
|
|
||||||
if (in_range(src, U) && loc == U)
|
|
||||||
n = sanitizeSafe(n, extra = 0)
|
|
||||||
if (mode == 1)
|
|
||||||
note = html_decode(n)
|
|
||||||
notehtml = note
|
|
||||||
note = replacetext(note, "\n", "<br>")
|
|
||||||
else
|
|
||||||
ui.close()
|
|
||||||
if("Toggle Messenger")
|
|
||||||
toff = !toff
|
|
||||||
if("Toggle Ringer")//If viewing texts then erase them, if not then toggle silent status
|
|
||||||
message_silent = !message_silent
|
|
||||||
if("Toggle News")
|
|
||||||
news_silent = !news_silent
|
|
||||||
if("Clear")//Clears messages
|
|
||||||
if(href_list["option"] == "All")
|
|
||||||
tnote.Cut()
|
|
||||||
conversations.Cut()
|
|
||||||
if(href_list["option"] == "Convo")
|
|
||||||
var/new_tnote[0]
|
|
||||||
for(var/i in tnote)
|
|
||||||
if(i["target"] != active_conversation)
|
|
||||||
new_tnote[++new_tnote.len] = i
|
|
||||||
tnote = new_tnote
|
|
||||||
conversations.Remove(active_conversation)
|
|
||||||
|
|
||||||
active_conversation = null
|
|
||||||
if(mode==21)
|
|
||||||
mode=2
|
|
||||||
|
|
||||||
if("Ringtone")
|
if("Ringtone")
|
||||||
var/t = input(U, "Please enter new ringtone", name, ttone) as text
|
return set_ringtone()
|
||||||
if (in_range(src, U) && loc == U)
|
|
||||||
if (t)
|
|
||||||
if(src.hidden_uplink && hidden_uplink.check_trigger(U, lowertext(t), lowertext(lock_code)))
|
|
||||||
to_chat(U, "The PDA softly beeps.")
|
|
||||||
ui.close()
|
|
||||||
else
|
|
||||||
t = sanitize(t, 20)
|
|
||||||
ttone = t
|
|
||||||
else
|
|
||||||
ui.close()
|
|
||||||
return 0
|
|
||||||
if("Newstone")
|
|
||||||
var/t = input(U, "Please enter new news tone", name, newstone) as text
|
|
||||||
if (in_range(src, U) && loc == U)
|
|
||||||
if (t)
|
|
||||||
t = sanitize(t, 20)
|
|
||||||
newstone = t
|
|
||||||
else
|
|
||||||
ui.close()
|
|
||||||
return 0
|
|
||||||
if("Message")
|
|
||||||
|
|
||||||
var/obj/item/device/pda/P = locate(href_list["target"])
|
|
||||||
src.create_message(U, P, !href_list["notap"])
|
|
||||||
if(mode == 2)
|
|
||||||
if(href_list["target"] in conversations) // Need to make sure the message went through, if not welp.
|
|
||||||
active_conversation = href_list["target"]
|
|
||||||
mode = 21
|
|
||||||
|
|
||||||
if("Select Conversation")
|
|
||||||
var/P = href_list["convo"]
|
|
||||||
for(var/n in conversations)
|
|
||||||
if(P == n)
|
|
||||||
active_conversation=P
|
|
||||||
mode=21
|
|
||||||
if("Select Feed")
|
|
||||||
var/n = href_list["name"]
|
|
||||||
for(var/f in feeds)
|
|
||||||
if(f["name"] == n)
|
|
||||||
active_feed = f
|
|
||||||
mode=61
|
|
||||||
if("Send Honk")//Honk virus
|
|
||||||
if(cartridge && cartridge.access_clown)//Cartridge checks are kind of unnecessary since everything is done through switch.
|
|
||||||
var/obj/item/device/pda/P = locate(href_list["target"])//Leaving it alone in case it may do something useful, I guess.
|
|
||||||
if(!isnull(P))
|
|
||||||
if (!P.toff && cartridge.charges > 0)
|
|
||||||
cartridge.charges--
|
|
||||||
U.show_message("<span class='notice'>Virus sent!</span>", 1)
|
|
||||||
P.honkamt = (rand(15,20))
|
|
||||||
else
|
|
||||||
to_chat(U, "PDA not found.")
|
|
||||||
else
|
|
||||||
ui.close()
|
|
||||||
return 0
|
|
||||||
if("Send Silence")//Silent virus
|
|
||||||
if(cartridge && cartridge.access_mime)
|
|
||||||
var/obj/item/device/pda/P = locate(href_list["target"])
|
|
||||||
if(!isnull(P))
|
|
||||||
if (!P.toff && cartridge.charges > 0)
|
|
||||||
cartridge.charges--
|
|
||||||
U.show_message("<span class='notice'>Virus sent!</span>", 1)
|
|
||||||
P.message_silent = 1
|
|
||||||
P.news_silent = 1
|
|
||||||
P.ttone = "silence"
|
|
||||||
P.newstone = "silence"
|
|
||||||
else
|
|
||||||
to_chat(U, "PDA not found.")
|
|
||||||
else
|
|
||||||
ui.close()
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
//SYNDICATE FUNCTIONS===================================
|
|
||||||
|
|
||||||
if("Toggle Door")
|
|
||||||
if(cartridge && cartridge.access_remote_door)
|
|
||||||
for(var/obj/machinery/door/blast/M in machines)
|
|
||||||
if(M.id == cartridge.remote_door_id)
|
|
||||||
if(M.density)
|
|
||||||
M.open()
|
|
||||||
else
|
|
||||||
M.close()
|
|
||||||
|
|
||||||
if("Detonate")//Detonate PDA... maybe
|
|
||||||
if(cartridge && cartridge.access_detonate_pda)
|
|
||||||
var/obj/item/device/pda/P = locate(href_list["target"])
|
|
||||||
var/datum/reception/reception = get_reception(src, P, "", do_sleep = 0)
|
|
||||||
if(!(reception.message_server && reception.telecomms_reception & TELECOMMS_RECEPTION_SENDER))
|
|
||||||
U.show_message("<span class='warning'>An error flashes on your [src]: Connection unavailable</span>", 1)
|
|
||||||
return
|
|
||||||
if(reception.telecomms_reception & TELECOMMS_RECEPTION_RECEIVER == 0) // Does our recepient have a broadcaster on their level?
|
|
||||||
U.show_message("<span class='warning'>An error flashes on your [src]: Recipient unavailable</span>", 1)
|
|
||||||
return
|
|
||||||
if(!isnull(P))
|
|
||||||
if (!P.toff && cartridge.charges > 0)
|
|
||||||
cartridge.charges--
|
|
||||||
|
|
||||||
var/difficulty = 2
|
|
||||||
|
|
||||||
if(P.cartridge)
|
|
||||||
difficulty += P.cartridge.access_medical
|
|
||||||
difficulty += P.cartridge.access_security
|
|
||||||
difficulty += P.cartridge.access_engine
|
|
||||||
difficulty += P.cartridge.access_clown
|
|
||||||
difficulty += P.cartridge.access_janitor
|
|
||||||
if(P.hidden_uplink)
|
|
||||||
difficulty += 3
|
|
||||||
|
|
||||||
if(prob(difficulty))
|
|
||||||
U.show_message("<span class='warning'>An error flashes on your [src].</span>", 1)
|
|
||||||
else if (prob(difficulty * 7))
|
|
||||||
U.show_message("<span class='warning'>Energy feeds back into your [src]!</span>", 1)
|
|
||||||
ui.close()
|
|
||||||
detonate_act(src)
|
|
||||||
log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up")
|
|
||||||
message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge but failed.", 1)
|
|
||||||
else
|
|
||||||
U.show_message("<span class='notice'>Success!</span>", 1)
|
|
||||||
log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge and succeeded")
|
|
||||||
message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge and succeeded.", 1)
|
|
||||||
detonate_act(P)
|
|
||||||
else
|
|
||||||
to_chat(U, "No charges left.")
|
|
||||||
|
|
||||||
else
|
|
||||||
to_chat(U, "PDA not found.")
|
|
||||||
else
|
|
||||||
U.unset_machine()
|
|
||||||
ui.close()
|
|
||||||
return 0
|
|
||||||
|
|
||||||
//pAI FUNCTIONS===================================
|
|
||||||
if("pai")
|
|
||||||
if(pai)
|
|
||||||
if(pai.loc != src)
|
|
||||||
pai = null
|
|
||||||
else
|
|
||||||
switch(href_list["option"])
|
|
||||||
if("1") // Configure pAI device
|
|
||||||
pai.attack_self(U)
|
|
||||||
if("2") // Eject pAI device
|
|
||||||
var/turf/T = get_turf_or_move(src.loc)
|
|
||||||
if(T)
|
|
||||||
pai.loc = T
|
|
||||||
pai = null
|
|
||||||
|
|
||||||
else
|
else
|
||||||
mode = text2num(href_list["choice"])
|
if(current_app)
|
||||||
if(cartridge)
|
. = current_app.Topic(href, href_list)
|
||||||
cartridge.mode = mode
|
|
||||||
|
|
||||||
//EXTRA FUNCTIONS===================================
|
//EXTRA FUNCTIONS===================================
|
||||||
|
if((honkamt > 0) && (prob(60)))//For clown virus.
|
||||||
if (mode == 2||mode == 21)//To clear message overlays.
|
|
||||||
new_message = 0
|
|
||||||
update_icon()
|
|
||||||
|
|
||||||
if (mode == 6||mode == 61)//To clear news overlays.
|
|
||||||
new_news = 0
|
|
||||||
update_icon()
|
|
||||||
|
|
||||||
if ((honkamt > 0) && (prob(60)))//For clown virus.
|
|
||||||
honkamt--
|
honkamt--
|
||||||
playsound(src, 'sound/items/bikehorn.ogg', 30, 1)
|
playsound(loc, 'sound/items/bikehorn.ogg', 30, 1)
|
||||||
|
|
||||||
return 1 // return 1 tells it to refresh the UI in NanoUI
|
return // return 1 tells it to refresh the UI in NanoUI
|
||||||
|
|
||||||
/obj/item/device/pda/update_icon()
|
/obj/item/device/pda/update_icon()
|
||||||
..()
|
..()
|
||||||
@@ -1230,8 +969,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
return
|
return
|
||||||
|
|
||||||
if(can_use(usr))
|
if(can_use(usr))
|
||||||
mode = 0
|
start_program(find_program(/datum/data/pda/app/main_menu))
|
||||||
SSnanoui.update_uis(src)
|
notifying_programs.Cut()
|
||||||
|
overlays -= image('icons/obj/pda.dmi', "pda-r")
|
||||||
to_chat(usr, "<span class='notice'>You press the reset button on \the [src].</span>")
|
to_chat(usr, "<span class='notice'>You press the reset button on \the [src].</span>")
|
||||||
else
|
else
|
||||||
to_chat(usr, "<span class='notice'>You cannot do this while restrained.</span>")
|
to_chat(usr, "<span class='notice'>You cannot do this while restrained.</span>")
|
||||||
@@ -1286,8 +1026,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
if(ismob(loc))
|
if(ismob(loc))
|
||||||
var/mob/M = loc
|
var/mob/M = loc
|
||||||
M.put_in_hands(cartridge)
|
M.put_in_hands(cartridge)
|
||||||
mode = 0
|
// mode = 0
|
||||||
scanmode = 0
|
// scanmode = 0
|
||||||
if (cartridge.radio)
|
if (cartridge.radio)
|
||||||
cartridge.radio.hostpda = null
|
cartridge.radio.hostpda = null
|
||||||
to_chat(usr, "<span class='notice'>You remove \the [cartridge] from the [name].</span>")
|
to_chat(usr, "<span class='notice'>You remove \the [cartridge] from the [name].</span>")
|
||||||
@@ -1363,128 +1103,132 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
return
|
return
|
||||||
|
|
||||||
/obj/item/device/pda/attack(mob/living/C as mob, mob/living/user as mob)
|
/obj/item/device/pda/attack(mob/living/C as mob, mob/living/user as mob)
|
||||||
if (istype(C, /mob/living/carbon))
|
if (istype(C, /mob/living/carbon) && scanmode)
|
||||||
switch(scanmode)
|
scanmode.scan_mob(C, user)
|
||||||
if(1)
|
|
||||||
|
|
||||||
for (var/mob/O in viewers(C, null))
|
// switch(scanmode)
|
||||||
O.show_message("<span class='warning'>\The [user] has analyzed [C]'s vitals!</span>", 1)
|
// if(1)
|
||||||
|
|
||||||
user.show_message("<span class='notice'>Analyzing Results for [C]:</span>")
|
// for (var/mob/O in viewers(C, null))
|
||||||
user.show_message("<span class='notice'> Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]</span>", 1)
|
// O.show_message("<span class='warning'>\The [user] has analyzed [C]'s vitals!</span>", 1)
|
||||||
user.show_message(text("<span class='notice'> Damage Specifics:</span> <span class='[]'>[]</span>-<span class='[]'>[]</span>-<span class='[]'>[]</span>-<span class='[]'>[]</span>",
|
|
||||||
(C.getOxyLoss() > 50) ? "warning" : "", C.getOxyLoss(),
|
|
||||||
(C.getToxLoss() > 50) ? "warning" : "", C.getToxLoss(),
|
|
||||||
(C.getFireLoss() > 50) ? "warning" : "", C.getFireLoss(),
|
|
||||||
(C.getBruteLoss() > 50) ? "warning" : "", C.getBruteLoss()
|
|
||||||
), 1)
|
|
||||||
user.show_message("<span class='notice'> Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
|
||||||
user.show_message("<span class='notice'> Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)</span>", 1)
|
|
||||||
if(C.tod && (C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
|
||||||
user.show_message("<span class='notice'> Time of Death: [C.tod]</span>")
|
|
||||||
if(istype(C, /mob/living/carbon/human))
|
|
||||||
var/mob/living/carbon/human/H = C
|
|
||||||
var/list/damaged = H.get_damaged_organs(1,1)
|
|
||||||
user.show_message("<span class='notice'>Localized Damage, Brute/Burn:</span>",1)
|
|
||||||
if(length(damaged)>0)
|
|
||||||
for(var/obj/item/organ/external/org in damaged)
|
|
||||||
user.show_message(text("<span class='notice'> []: <span class='[]'>[]</span>-<span class='[]'>[]</span></span>",
|
|
||||||
capitalize(org.name), (org.brute_dam > 0) ? "warning" : "notice", org.brute_dam, (org.burn_dam > 0) ? "warning" : "notice", org.burn_dam),1)
|
|
||||||
else
|
|
||||||
user.show_message("<span class='notice'> Limbs are OK.</span>",1)
|
|
||||||
|
|
||||||
if(2)
|
// user.show_message("<span class='notice'>Analyzing Results for [C]:</span>")
|
||||||
if (!istype(C:dna, /datum/dna))
|
// user.show_message("<span class='notice'> Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]</span>", 1)
|
||||||
to_chat(user, "<span class='notice'>No fingerprints found on [C]</span>")
|
// user.show_message(text("<span class='notice'> Damage Specifics:</span> <span class='[]'>[]</span>-<span class='[]'>[]</span>-<span class='[]'>[]</span>-<span class='[]'>[]</span>",
|
||||||
else
|
// (C.getOxyLoss() > 50) ? "warning" : "", C.getOxyLoss(),
|
||||||
to_chat(user, text("<span class='notice'>\The [C]'s Fingerprints: [md5(C:dna.uni_identity)]</span>"))
|
// (C.getToxLoss() > 50) ? "warning" : "", C.getToxLoss(),
|
||||||
if ( !(C:blood_DNA) )
|
// (C.getFireLoss() > 50) ? "warning" : "", C.getFireLoss(),
|
||||||
to_chat(user, "<span class='notice'>No blood found on [C]</span>")
|
// (C.getBruteLoss() > 50) ? "warning" : "", C.getBruteLoss()
|
||||||
if(C:blood_DNA)
|
// ), 1)
|
||||||
qdel(C:blood_DNA)
|
// user.show_message("<span class='notice'> Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
||||||
else
|
// user.show_message("<span class='notice'> Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)</span>", 1)
|
||||||
to_chat(user, "<span class='notice'>Blood found on [C]. Analysing...</span>")
|
// if(C.tod && (C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
||||||
spawn(15)
|
// user.show_message("<span class='notice'> Time of Death: [C.tod]</span>")
|
||||||
for(var/blood in C:blood_DNA)
|
// if(istype(C, /mob/living/carbon/human))
|
||||||
to_chat(user, "<span class='notice'>Blood type: [C:blood_DNA[blood]]\nDNA: [blood]</span>")
|
// var/mob/living/carbon/human/H = C
|
||||||
|
// var/list/damaged = H.get_damaged_organs(1,1)
|
||||||
|
// user.show_message("<span class='notice'>Localized Damage, Brute/Burn:</span>",1)
|
||||||
|
// if(length(damaged)>0)
|
||||||
|
// for(var/obj/item/organ/external/org in damaged)
|
||||||
|
// user.show_message(text("<span class='notice'> []: <span class='[]'>[]</span>-<span class='[]'>[]</span></span>",
|
||||||
|
// capitalize(org.name), (org.brute_dam > 0) ? "warning" : "notice", org.brute_dam, (org.burn_dam > 0) ? "warning" : "notice", org.burn_dam),1)
|
||||||
|
// else
|
||||||
|
// user.show_message("<span class='notice'> Limbs are OK.</span>",1)
|
||||||
|
|
||||||
if(4)
|
// if(2)
|
||||||
user.visible_message("<span class='warning'>\The [user] has analyzed [C]'s radiation levels!</span>", "<span class='notice'>You have analyzed [C]'s radiation levels!</span>")
|
// if (!istype(C:dna, /datum/dna))
|
||||||
to_chat(user, "<span class='notice'>Analyzing Results for [C]:</span>")
|
// to_chat(user, "<span class='notice'>No fingerprints found on [C]</span>")
|
||||||
if(C.radiation)
|
// else
|
||||||
to_chat(user, "<span class='notice'>Radiation Level: [C.radiation]</span>")
|
// to_chat(user, text("<span class='notice'>\The [C]'s Fingerprints: [md5(C:dna.uni_identity)]</span>"))
|
||||||
else
|
// if ( !(C:blood_DNA) )
|
||||||
to_chat(user, "<span class='notice'>No radiation detected.</span>")
|
// to_chat(user, "<span class='notice'>No blood found on [C]</span>")
|
||||||
|
// if(C:blood_DNA)
|
||||||
|
// qdel(C:blood_DNA)
|
||||||
|
// else
|
||||||
|
// to_chat(user, "<span class='notice'>Blood found on [C]. Analysing...</span>")
|
||||||
|
// spawn(15)
|
||||||
|
// for(var/blood in C:blood_DNA)
|
||||||
|
// to_chat(user, "<span class='notice'>Blood type: [C:blood_DNA[blood]]\nDNA: [blood]</span>")
|
||||||
|
|
||||||
|
// if(4)
|
||||||
|
// user.visible_message("<span class='warning'>\The [user] has analyzed [C]'s radiation levels!</span>", "<span class='notice'>You have analyzed [C]'s radiation levels!</span>")
|
||||||
|
// to_chat(user, "<span class='notice'>Analyzing Results for [C]:</span>")
|
||||||
|
// if(C.radiation)
|
||||||
|
// to_chat(user, "<span class='notice'>Radiation Level: [C.radiation]</span>")
|
||||||
|
// else
|
||||||
|
// to_chat(user, "<span class='notice'>No radiation detected.</span>")
|
||||||
|
|
||||||
/obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
|
/obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
|
||||||
if(!proximity) return
|
if(proximity && scanmode)
|
||||||
switch(scanmode)
|
scanmode.scan_atom(A, user)
|
||||||
|
// if(!proximity) return
|
||||||
|
// switch(scanmode)
|
||||||
|
|
||||||
if(3)
|
// if(3)
|
||||||
if(!isobj(A))
|
// if(!isobj(A))
|
||||||
return
|
// return
|
||||||
if(!isnull(A.reagents))
|
// if(!isnull(A.reagents))
|
||||||
if(A.reagents.reagent_list.len > 0)
|
// if(A.reagents.reagent_list.len > 0)
|
||||||
var/reagents_length = A.reagents.reagent_list.len
|
// var/reagents_length = A.reagents.reagent_list.len
|
||||||
to_chat(user, "<span class='notice'>[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.</span>")
|
// to_chat(user, "<span class='notice'>[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.</span>")
|
||||||
for (var/re in A.reagents.reagent_list)
|
// for (var/re in A.reagents.reagent_list)
|
||||||
to_chat(user, "<span class='notice'> [re]</span>")
|
// to_chat(user, "<span class='notice'> [re]</span>")
|
||||||
else
|
// else
|
||||||
to_chat(user, "<span class='notice'>No active chemical agents found in [A].</span>")
|
// to_chat(user, "<span class='notice'>No active chemical agents found in [A].</span>")
|
||||||
else
|
// else
|
||||||
to_chat(user, "<span class='notice'>No significantchemical agents found in [A].</span>")
|
// to_chat(user, "<span class='notice'>No significantchemical agents found in [A].</span>")
|
||||||
|
|
||||||
if(5)
|
// if(5)
|
||||||
analyze_gases(A, user)
|
// analyze_gases(A, user)
|
||||||
|
|
||||||
if (!scanmode && istype(A, /obj/item/weapon/paper) && owner)
|
// if (!scanmode && istype(A, /obj/item/weapon/paper) && owner)
|
||||||
// JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents,
|
// // JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents,
|
||||||
// as this will clobber the HTML, but at least it lets you scan a document. You can restore the original
|
// // as this will clobber the HTML, but at least it lets you scan a document. You can restore the original
|
||||||
// notes by editing the note again. (Was going to allow you to edit, but scanned documents are too long.)
|
// // notes by editing the note again. (Was going to allow you to edit, but scanned documents are too long.)
|
||||||
var/raw_scan = (A:info)
|
// var/raw_scan = (A:info)
|
||||||
var/formatted_scan = ""
|
// var/formatted_scan = ""
|
||||||
// Scrub out the tags (replacing a few formatting ones along the way)
|
// // Scrub out the tags (replacing a few formatting ones along the way)
|
||||||
|
|
||||||
// Find the beginning and end of the first tag.
|
// // Find the beginning and end of the first tag.
|
||||||
var/tag_start = findtext(raw_scan,"<")
|
// var/tag_start = findtext(raw_scan,"<")
|
||||||
var/tag_stop = findtext(raw_scan,">")
|
// var/tag_stop = findtext(raw_scan,">")
|
||||||
|
|
||||||
// Until we run out of complete tags...
|
// // Until we run out of complete tags...
|
||||||
while(tag_start&&tag_stop)
|
// while(tag_start&&tag_stop)
|
||||||
var/pre = copytext(raw_scan,1,tag_start) // Get the stuff that comes before the tag
|
// var/pre = copytext(raw_scan,1,tag_start) // Get the stuff that comes before the tag
|
||||||
var/tag = lowertext(copytext(raw_scan,tag_start+1,tag_stop)) // Get the tag so we can do intellegent replacement
|
// var/tag = lowertext(copytext(raw_scan,tag_start+1,tag_stop)) // Get the tag so we can do intellegent replacement
|
||||||
var/tagend = findtext(tag," ") // Find the first space in the tag if there is one.
|
// var/tagend = findtext(tag," ") // Find the first space in the tag if there is one.
|
||||||
|
|
||||||
// Anything that's before the tag can just be added as is.
|
// // Anything that's before the tag can just be added as is.
|
||||||
formatted_scan = formatted_scan+pre
|
// formatted_scan = formatted_scan+pre
|
||||||
|
|
||||||
// If we have a space after the tag (and presumably attributes) just crop that off.
|
// // If we have a space after the tag (and presumably attributes) just crop that off.
|
||||||
if (tagend)
|
// if (tagend)
|
||||||
tag=copytext(tag,1,tagend)
|
// tag=copytext(tag,1,tagend)
|
||||||
|
|
||||||
if (tag=="p"||tag=="/p"||tag=="br") // Check if it's I vertical space tag.
|
// if (tag=="p"||tag=="/p"||tag=="br") // Check if it's I vertical space tag.
|
||||||
formatted_scan=formatted_scan+"<br>" // If so, add some padding in.
|
// formatted_scan=formatted_scan+"<br>" // If so, add some padding in.
|
||||||
|
|
||||||
raw_scan = copytext(raw_scan,tag_stop+1) // continue on with the stuff after the tag
|
// raw_scan = copytext(raw_scan,tag_stop+1) // continue on with the stuff after the tag
|
||||||
|
|
||||||
// Look for the next tag in what's left
|
// // Look for the next tag in what's left
|
||||||
tag_start = findtext(raw_scan,"<")
|
// tag_start = findtext(raw_scan,"<")
|
||||||
tag_stop = findtext(raw_scan,">")
|
// tag_stop = findtext(raw_scan,">")
|
||||||
|
|
||||||
// Anything that is left in the page. just tack it on to the end as is
|
// // Anything that is left in the page. just tack it on to the end as is
|
||||||
formatted_scan=formatted_scan+raw_scan
|
// formatted_scan=formatted_scan+raw_scan
|
||||||
|
|
||||||
// If there is something in there already, pad it out.
|
// // If there is something in there already, pad it out.
|
||||||
if (length(note)>0)
|
// if (length(note)>0)
|
||||||
note = note + "<br><br>"
|
// note = note + "<br><br>"
|
||||||
|
|
||||||
// Store the scanned document to the notes
|
// // Store the scanned document to the notes
|
||||||
note = "Scanned Document. Edit to restore previous notes/delete scan.<br>----------<br>" + formatted_scan + "<br>"
|
// note = "Scanned Document. Edit to restore previous notes/delete scan.<br>----------<br>" + formatted_scan + "<br>"
|
||||||
// notehtml ISN'T set to allow user to get their old notes back. A better implementation would add a "scanned documents"
|
// // notehtml ISN'T set to allow user to get their old notes back. A better implementation would add a "scanned documents"
|
||||||
// feature to the PDA, which would better convey the availability of the feature, but this will work for now.
|
// // feature to the PDA, which would better convey the availability of the feature, but this will work for now.
|
||||||
|
|
||||||
// Inform the user
|
// // Inform the user
|
||||||
to_chat(user, "<span class='notice'>Paper scanned and OCRed to notekeeper.</span>") //concept of scanning paper copyright brainoblivion 2009
|
// to_chat(user, "<span class='notice'>Paper scanned and OCRed to notekeeper.</span>") //concept of scanning paper copyright brainoblivion 2009
|
||||||
|
|
||||||
|
|
||||||
/obj/item/device/pda/proc/explode() //This needs tuning. //Sure did.
|
/obj/item/device/pda/proc/explode() //This needs tuning. //Sure did.
|
||||||
@@ -1501,8 +1245,12 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
src.id.forceMove(get_turf(src.loc))
|
src.id.forceMove(get_turf(src.loc))
|
||||||
else
|
else
|
||||||
QDEL_NULL(src.id)
|
QDEL_NULL(src.id)
|
||||||
QDEL_NULL(src.cartridge)
|
|
||||||
QDEL_NULL(src.pai)
|
current_app = null
|
||||||
|
scanmode = null
|
||||||
|
QDEL_NULL(pai)
|
||||||
|
QDEL_LIST(programs)
|
||||||
|
QDEL_NULL(cartridge)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/obj/item/device/pda/clown/Crossed(atom/movable/AM as mob|obj) //Clown PDA is slippery.
|
/obj/item/device/pda/clown/Crossed(atom/movable/AM as mob|obj) //Clown PDA is slippery.
|
||||||
|
|||||||
59
code/modules/pda/pda_tgui.dm
Normal file
59
code/modules/pda/pda_tgui.dm
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// Self contained file for all things TGUI
|
||||||
|
/obj/item/device/pda/tgui_state(mob/user)
|
||||||
|
return GLOB.tgui_inventory_state
|
||||||
|
|
||||||
|
/obj/item/device/pda/tgui_interact(mob/user, datum/tgui/ui)
|
||||||
|
ui = SStgui.try_update_ui(user, src, ui)
|
||||||
|
if(!ui)
|
||||||
|
ui = new(user, src, "Pda", "Personal Data Assistant")
|
||||||
|
ui.open()
|
||||||
|
|
||||||
|
/obj/item/device/pda/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||||
|
var/list/data = ..()
|
||||||
|
|
||||||
|
data["owner"] = owner // Who is your daddy...
|
||||||
|
data["ownjob"] = ownjob // ...and what does he do?
|
||||||
|
|
||||||
|
// update list of shortcuts, only if they changed
|
||||||
|
if(!shortcut_cache.len)
|
||||||
|
shortcut_cache = list()
|
||||||
|
shortcut_cat_order = list()
|
||||||
|
var/prog_list = programs.Copy()
|
||||||
|
if(cartridge)
|
||||||
|
prog_list |= cartridge.programs
|
||||||
|
|
||||||
|
for(var/A in prog_list)
|
||||||
|
var/datum/data/pda/P = A
|
||||||
|
|
||||||
|
if(P.hidden)
|
||||||
|
continue
|
||||||
|
var/list/cat
|
||||||
|
if(P.category in shortcut_cache)
|
||||||
|
cat = shortcut_cache[P.category]
|
||||||
|
else
|
||||||
|
cat = list()
|
||||||
|
shortcut_cache[P.category] = cat
|
||||||
|
shortcut_cat_order += P.category
|
||||||
|
cat |= list(list(name = P.name, icon = P.icon, notify_icon = P.notify_icon, ref = "\ref[P]"))
|
||||||
|
|
||||||
|
// force the order of a few core categories
|
||||||
|
shortcut_cat_order = list("General") \
|
||||||
|
+ sortList(shortcut_cat_order - list("General", "Scanners", "Utilities")) \
|
||||||
|
+ list("Scanners", "Utilities")
|
||||||
|
|
||||||
|
data["idInserted"] = (id ? 1 : 0)
|
||||||
|
data["idLink"] = (id ? text("[id.registered_name], [id.assignment]") : "--------")
|
||||||
|
|
||||||
|
data["useRetro"] = retro_mode
|
||||||
|
|
||||||
|
data["cartridge_name"] = cartridge ? cartridge.name : ""
|
||||||
|
data["stationTime"] = worldtime2stationtime(world.time)
|
||||||
|
|
||||||
|
data["app"] = list(
|
||||||
|
"name" = current_app.title,
|
||||||
|
"icon" = current_app.icon,
|
||||||
|
"template" = current_app.template,
|
||||||
|
"has_back" = current_app.has_back)
|
||||||
|
current_app.update_ui(user, data)
|
||||||
|
|
||||||
|
return data
|
||||||
200
code/modules/pda/utilities.dm
Normal file
200
code/modules/pda/utilities.dm
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/datum/data/pda/utility/flashlight
|
||||||
|
name = "Enable Flashlight"
|
||||||
|
icon = "lightbulb-o"
|
||||||
|
|
||||||
|
var/fon = 0 //Is the flashlight function on?
|
||||||
|
var/f_lum = 2 //Luminosity for the flashlight function
|
||||||
|
|
||||||
|
/datum/data/pda/utility/flashlight/start()
|
||||||
|
fon = !fon
|
||||||
|
name = fon ? "Disable Flashlight" : "Enable Flashlight"
|
||||||
|
pda.update_shortcuts()
|
||||||
|
pda.set_light(fon ? f_lum : 0)
|
||||||
|
|
||||||
|
/datum/data/pda/utility/honk
|
||||||
|
name = "Honk Synthesizer"
|
||||||
|
icon = "smile-o"
|
||||||
|
category = "Clown"
|
||||||
|
|
||||||
|
var/last_honk //Also no honk spamming that's bad too
|
||||||
|
|
||||||
|
/datum/data/pda/utility/honk/start()
|
||||||
|
if(!(last_honk && world.time < last_honk + 20))
|
||||||
|
playsound(pda.loc, 'sound/items/bikehorn.ogg', 50, 1)
|
||||||
|
last_honk = world.time
|
||||||
|
|
||||||
|
/datum/data/pda/utility/toggle_door
|
||||||
|
name = "Toggle Door"
|
||||||
|
icon = "external-link"
|
||||||
|
var/remote_door_id = ""
|
||||||
|
|
||||||
|
// /datum/data/pda/utility/toggle_door/start()
|
||||||
|
// for(var/obj/machinery/door/poddoor/M in airlocks)
|
||||||
|
// if(M.id_tag == remote_door_id)
|
||||||
|
// if(M.density)
|
||||||
|
// M.open()
|
||||||
|
// else
|
||||||
|
// M.close()
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/medical
|
||||||
|
base_name = "Med Scanner"
|
||||||
|
icon = "heart-o"
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/medical/scan_mob(mob/living/C as mob, mob/living/user as mob)
|
||||||
|
C.visible_message("<span class=warning>[user] has analyzed [C]'s vitals!</span>")
|
||||||
|
|
||||||
|
user.show_message("<span class=notice>Analyzing Results for [C]:</span>")
|
||||||
|
user.show_message("<span class=notice>\t Overall Status: [C.stat > 1 ? "dead" : "[C.health]% healthy"]</span>", 1)
|
||||||
|
user.show_message("<span class=notice>\t Damage Specifics: [C.getOxyLoss() > 50 ? "</span><span class=warning>" : ""][C.getOxyLoss()]-[C.getToxLoss() > 50 ? "</span><span class=warning>" : "</span><span class=notice>"][C.getToxLoss()]-[C.getFireLoss() > 50 ? "</span><span class=warning>" : "</span><span class=notice>"][C.getFireLoss()]-[C.getBruteLoss() > 50 ? "</span><span class=warning>" : "</span><span class=notice>"][C.getBruteLoss()]</span>", 1)
|
||||||
|
user.show_message("<span class=notice>\t Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
||||||
|
user.show_message("<span class=notice>\t Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)</span>", 1)
|
||||||
|
if(C.tod && (C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
||||||
|
user.show_message("<span class=notice>\t Time of Death: [C.tod]</span>")
|
||||||
|
if(istype(C, /mob/living/carbon/human))
|
||||||
|
var/mob/living/carbon/human/H = C
|
||||||
|
var/list/damaged = H.get_damaged_organs(1,1)
|
||||||
|
user.show_message("<span class=notice>Localized Damage, Brute/Burn:</span>",1)
|
||||||
|
if(length(damaged)>0)
|
||||||
|
for(var/obj/item/organ/external/org in damaged)
|
||||||
|
user.show_message("<span class=notice>\t [capitalize(org.name)]: [org.brute_dam > 0 ? "<span class=warning>[org.brute_dam]</span>" : "0"]-[org.burn_dam > 0 ? "<span class=warning>[org.burn_dam]</span>" : "0"]", 1)
|
||||||
|
else
|
||||||
|
user.show_message("<span class=notice>\t Limbs are OK.",1)
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/dna
|
||||||
|
base_name = "DNA Scanner"
|
||||||
|
icon = "link"
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/dna/scan_mob(mob/living/C as mob, mob/living/user as mob)
|
||||||
|
if(istype(C, /mob/living/carbon/human))
|
||||||
|
var/mob/living/carbon/human/H = C
|
||||||
|
if(!istype(H.dna, /datum/dna))
|
||||||
|
to_chat(user, "<span class=notice>No fingerprints found on [H]</span>")
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class=notice>[H]'s Fingerprints: [md5(H.dna.uni_identity)]</span>")
|
||||||
|
scan_blood(C, user)
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/dna/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob)
|
||||||
|
scan_blood(A, user)
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/dna/proc/scan_blood(atom/A, mob/user)
|
||||||
|
if(!A.blood_DNA)
|
||||||
|
to_chat(user, "<span class=notice>No blood found on [A]</span>")
|
||||||
|
if(A.blood_DNA)
|
||||||
|
qdel(A.blood_DNA)
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class=notice>Blood found on [A]. Analysing...</span>")
|
||||||
|
spawn(15)
|
||||||
|
for(var/blood in A.blood_DNA)
|
||||||
|
to_chat(user, "<span class=notice>Blood type: [A.blood_DNA[blood]]\nDNA: [blood]</span>")
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/halogen
|
||||||
|
base_name = "Halogen Counter"
|
||||||
|
icon = "exclamation-circle"
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/halogen/scan_mob(mob/living/C as mob, mob/living/user as mob)
|
||||||
|
C.visible_message("<span class=warning>[user] has analyzed [C]'s radiation levels!</span>")
|
||||||
|
|
||||||
|
user.show_message("<span class=notice>Analyzing Results for [C]:</span>")
|
||||||
|
if(C.radiation)
|
||||||
|
user.show_message("<span class=notice>Radiation Level: [C.radiation > 0 ? "</span><span class=danger>[C.radiation]" : "0"]</span>")
|
||||||
|
else
|
||||||
|
user.show_message("<span class=notice>No radiation detected.</span>")
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/reagent
|
||||||
|
base_name = "Reagent Scanner"
|
||||||
|
icon = "flask"
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/reagent/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob)
|
||||||
|
if(!isnull(A.reagents))
|
||||||
|
if(A.reagents.reagent_list.len > 0)
|
||||||
|
var/reagents_length = A.reagents.reagent_list.len
|
||||||
|
to_chat(user, "<span class='notice'>[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.</span>")
|
||||||
|
for(var/re in A.reagents.reagent_list)
|
||||||
|
to_chat(user, "<span class='notice'>\t [re]</span>")
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>No active chemical agents found in [A].</span>")
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>No significant chemical agents found in [A].</span>")
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/gas
|
||||||
|
base_name = "Gas Scanner"
|
||||||
|
icon = "tachometer"
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/gas/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob)
|
||||||
|
// if(istype(A, /obj/item/tank))
|
||||||
|
// var/obj/item/tank/T = A
|
||||||
|
// pda.atmosanalyzer_scan(T.air_contents, user, T)
|
||||||
|
// else if(istype(A, /obj/machinery/portable_atmospherics))
|
||||||
|
// var/obj/machinery/portable_atmospherics/T = A
|
||||||
|
// pda.atmosanalyzer_scan(T.air_contents, user, T)
|
||||||
|
// else if(istype(A, /obj/machinery/atmospherics/pipe))
|
||||||
|
// var/obj/machinery/atmospherics/pipe/T = A
|
||||||
|
// pda.atmosanalyzer_scan(T.parent.air, user, T)
|
||||||
|
// else if(istype(A, /obj/machinery/power/rad_collector))
|
||||||
|
// var/obj/machinery/power/rad_collector/T = A
|
||||||
|
// if(T.P)
|
||||||
|
// pda.atmosanalyzer_scan(T.P.air_contents, user, T)
|
||||||
|
// else if(istype(A, /obj/item/flamethrower))
|
||||||
|
// var/obj/item/flamethrower/T = A
|
||||||
|
// if(T.ptank)
|
||||||
|
// pda.atmosanalyzer_scan(T.ptank.air_contents, user, T)
|
||||||
|
// else if(istype(A, /obj/machinery/portable_atmospherics/scrubber/huge))
|
||||||
|
// var/obj/machinery/portable_atmospherics/scrubber/huge/T = A
|
||||||
|
// pda.atmosanalyzer_scan(T.air_contents, user, T)
|
||||||
|
// else if(istype(A, /obj/machinery/atmospherics/unary/tank))
|
||||||
|
// var/obj/machinery/atmospherics/unary/tank/T = A
|
||||||
|
// pda.atmosanalyzer_scan(T.air_contents, user, T)
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/notes
|
||||||
|
base_name = "Note Scanner"
|
||||||
|
icon = "clipboard"
|
||||||
|
var/datum/data/pda/app/notekeeper/notes
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/notes/start()
|
||||||
|
. = ..()
|
||||||
|
notes = pda.find_program(/datum/data/pda/app/notekeeper)
|
||||||
|
|
||||||
|
/datum/data/pda/utility/scanmode/notes/scan_atom(atom/A as mob|obj|turf|area, mob/user as mob)
|
||||||
|
if(notes && istype(A, /obj/item/weapon/paper))
|
||||||
|
var/obj/item/weapon/paper/P = A
|
||||||
|
var/list/brlist = list("p", "/p", "br", "hr", "h1", "h2", "h3", "h4", "/h1", "/h2", "/h3", "/h4")
|
||||||
|
|
||||||
|
// JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents,
|
||||||
|
// as this will clobber the HTML, but at least it lets you scan a document. You can restore the original
|
||||||
|
// notes by editing the note again. (Was going to allow you to edit, but scanned documents are too long.)
|
||||||
|
var/raw_scan = sanitize_simple(P.info, list("\t" = "", "ÿ" = ""))
|
||||||
|
var/formatted_scan = ""
|
||||||
|
// Scrub out the tags (replacing a few formatting ones along the way)
|
||||||
|
// Find the beginning and end of the first tag.
|
||||||
|
var/tag_start = findtext(raw_scan, "<")
|
||||||
|
var/tag_stop = findtext(raw_scan, ">")
|
||||||
|
// Until we run out of complete tags...
|
||||||
|
while(tag_start && tag_stop)
|
||||||
|
var/pre = copytext(raw_scan, 1, tag_start) // Get the stuff that comes before the tag
|
||||||
|
var/tag = lowertext(copytext(raw_scan, tag_start + 1, tag_stop)) // Get the tag so we can do intellegent replacement
|
||||||
|
var/tagend = findtext(tag, " ") // Find the first space in the tag if there is one.
|
||||||
|
// Anything that's before the tag can just be added as is.
|
||||||
|
formatted_scan = formatted_scan + pre
|
||||||
|
// If we have a space after the tag (and presumably attributes) just crop that off.
|
||||||
|
if(tagend)
|
||||||
|
tag = copytext(tag, 1, tagend)
|
||||||
|
if(tag in brlist) // Check if it's I vertical space tag.
|
||||||
|
formatted_scan = formatted_scan + "<br>" // If so, add some padding in.
|
||||||
|
raw_scan = copytext(raw_scan, tag_stop + 1) // continue on with the stuff after the tag
|
||||||
|
// Look for the next tag in what's left
|
||||||
|
tag_start = findtext(raw_scan, "<")
|
||||||
|
tag_stop = findtext(raw_scan, ">")
|
||||||
|
// Anything that is left in the page. just tack it on to the end as is
|
||||||
|
formatted_scan = formatted_scan + raw_scan
|
||||||
|
// If there is something in there already, pad it out.
|
||||||
|
if(length(notes.note) > 0)
|
||||||
|
notes.note += "<br><br>"
|
||||||
|
// Store the scanned document to the notes
|
||||||
|
notes.note += "Scanned Document. Edit to restore previous notes/delete scan.<br>----------<br>" + formatted_scan + "<br>"
|
||||||
|
// notehtml ISN'T set to allow user to get their old notes back. A better implementation would add a "scanned documents"
|
||||||
|
// feature to the PDA, which would better convey the availability of the feature, but this will work for now.
|
||||||
|
// Inform the user
|
||||||
|
to_chat(user, "<span class=notice>Paper scanned and OCRed to notekeeper.</span>")//concept of scanning paper copyright brainoblivion 2009
|
||||||
|
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class=warning>Error scanning [A].</span>")
|
||||||
@@ -48,13 +48,13 @@ hr {
|
|||||||
.link32 {
|
.link32 {
|
||||||
float: left;
|
float: left;
|
||||||
min-width: 15px;
|
min-width: 15px;
|
||||||
max-width: 31px;
|
max-width: 31px;
|
||||||
height: 31px;
|
height: 31px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background: #40628a;
|
background: #40628a;
|
||||||
border: 1px solid #161616;
|
border: 1px solid #161616;
|
||||||
margin: 0 2px 2px 0;
|
margin: 0 2px 2px 0;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ h4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.greenButton {
|
.greenButton {
|
||||||
background: #00aa00;
|
background: #00aa00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yellowButton {
|
.yellowButton {
|
||||||
@@ -209,11 +209,11 @@ h4 {
|
|||||||
.caption {
|
.caption {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.multiLine {
|
.multiLine {
|
||||||
@@ -267,7 +267,7 @@ div.notice {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 4px 0 0 0;
|
margin: 4px 0 0 0;
|
||||||
clear: both;
|
clear: both;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemContentNarrow, .itemContent, .itemContentWide, .itemContentSmall, .itemContentMedium {
|
.itemContentNarrow, .itemContent, .itemContentWide, .itemContentSmall, .itemContentMedium {
|
||||||
@@ -325,7 +325,7 @@ div.notice {
|
|||||||
border: 1px solid #40628a;
|
border: 1px solid #40628a;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
margin: 3px 0;
|
margin: 3px 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statusDisplayRecords {
|
.statusDisplayRecords {
|
||||||
@@ -339,16 +339,16 @@ div.notice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.statusDisplayComm {
|
.statusDisplayComm {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
border-top: 0 none;
|
border-top: 0 none;
|
||||||
border-left: 0 none;
|
border-left: 0 none;
|
||||||
border-right: 0 none;
|
border-right: 0 none;
|
||||||
border-bottom: 2px inset #40628a;
|
border-bottom: 2px inset #40628a;
|
||||||
margin: 3px 0;
|
margin: 3px 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statusLabel {
|
.statusLabel {
|
||||||
@@ -410,7 +410,7 @@ div.notice {
|
|||||||
float: left;
|
float: left;
|
||||||
margin: 0 5px 0 0;
|
margin: 0 5px 0 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #40628a;
|
background: #40628a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.displayBarVerticalFill {
|
.displayBarVerticalFill {
|
||||||
@@ -418,7 +418,7 @@ div.notice {
|
|||||||
height: 0%;
|
height: 0%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
float: left;
|
float: left;
|
||||||
background: #000000;
|
background: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*used in xenobio2 computer*/
|
/*used in xenobio2 computer*/
|
||||||
@@ -428,12 +428,12 @@ div.notice {
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
height: 110px;
|
height: 110px;
|
||||||
border-right: 2px solid rgb(102, 179, 255);
|
border-right: 2px solid rgb(102, 179, 255);
|
||||||
border-left: 2px solid rgb(102, 179, 255);
|
border-left: 2px solid rgb(102, 179, 255);
|
||||||
border-bottom: 2px solid rgb(102, 179, 255);
|
border-bottom: 2px solid rgb(102, 179, 255);
|
||||||
float: left;
|
float: left;
|
||||||
margin: 0 5px 0 0;
|
margin: 0 5px 0 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #40628a;
|
background: #40628a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.displayBarBeakerFill {
|
.displayBarBeakerFill {
|
||||||
@@ -441,7 +441,7 @@ div.notice {
|
|||||||
height: 0%;
|
height: 0%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
float: left;
|
float: left;
|
||||||
background: rgba(153, 204, 255, 0.3);
|
background: rgba(153, 204, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.displayBarFill.alignRight {
|
.displayBarFill.alignRight {
|
||||||
@@ -514,7 +514,7 @@ div.notice {
|
|||||||
.fixedLeftWiderRed {
|
.fixedLeftWiderRed {
|
||||||
width: 220px;
|
width: 220px;
|
||||||
float: left;
|
float: left;
|
||||||
background: #ee0000;
|
background: #ee0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floatRight {
|
.floatRight {
|
||||||
@@ -522,7 +522,7 @@ div.notice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.floatLeft {
|
.floatLeft {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used in PDA */
|
/* Used in PDA */
|
||||||
@@ -538,6 +538,14 @@ div.notice {
|
|||||||
.pdalink {
|
.pdalink {
|
||||||
float: left;
|
float: left;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdalink.disabled {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #999;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DNA Modifier UI (dna_modifier.tmpl) */
|
/* DNA Modifier UI (dna_modifier.tmpl) */
|
||||||
@@ -585,11 +593,11 @@ div.notice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table.fixed {
|
table.fixed {
|
||||||
table-layout:fixed;
|
table-layout:fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.fixed td {
|
table.fixed td {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Table stuffs for power monitor */
|
/* Table stuffs for power monitor */
|
||||||
@@ -641,9 +649,9 @@ th.Cargo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th.Planetside{
|
th.Planetside{
|
||||||
background: #555555;
|
background: #555555;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
th.Civilian {
|
th.Civilian {
|
||||||
@@ -659,9 +667,9 @@ th.Miscellaneous {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th.Silicon {
|
th.Silicon {
|
||||||
background: #222222;
|
background: #222222;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
/* Damage/health colors for crew monitoring computer */
|
/* Damage/health colors for crew monitoring computer */
|
||||||
|
|
||||||
@@ -696,20 +704,20 @@ th.Silicon {
|
|||||||
|
|
||||||
/*Communicator Homescreen*/
|
/*Communicator Homescreen*/
|
||||||
div.homeContainer {
|
div.homeContainer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.homeScreen {
|
div.homeScreen {
|
||||||
padding: 0 20px 0 20px;
|
padding: 0 20px 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link64 {
|
.link64 {
|
||||||
float: left;
|
float: left;
|
||||||
min-width: 15px;
|
min-width: 15px;
|
||||||
max-width: 68px;
|
max-width: 68px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
@@ -717,43 +725,43 @@ div.homeScreen {
|
|||||||
background: rgba(64, 98, 138, 0.6);
|
background: rgba(64, 98, 138, 0.6);
|
||||||
border: 1px solid #161616;
|
border: 1px solid #161616;
|
||||||
padding: 0 0 4px 0;
|
padding: 0 0 4px 0;
|
||||||
margin: 0 0 30px 5.5%;
|
margin: 0 0 30px 5.5%;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link64:hover {
|
.link64:hover {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Communicator Dialing*/
|
/*Communicator Dialing*/
|
||||||
.dialPad {
|
.dialPad {
|
||||||
clear: both;
|
clear: both;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadKeys {
|
.dialPadKeys {
|
||||||
float: left;
|
float: left;
|
||||||
width: 47px;
|
width: 47px;
|
||||||
height: 47px;
|
height: 47px;
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background: rgba(64, 98, 138, 0.15);
|
background: rgba(64, 98, 138, 0.15);
|
||||||
border: 1px inset rgba(100, 100, 100, 0.25);
|
border: 1px inset rgba(100, 100, 100, 0.25);
|
||||||
cursor: default;
|
cursor: default;
|
||||||
line-height: 47px;
|
line-height: 47px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadKeys:hover {
|
.dialPadKeys:hover {
|
||||||
background: rgba(80, 122, 172, 0.5);
|
background: rgba(80, 122, 172, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadButtons {
|
.dialPadButtons {
|
||||||
float: left;
|
float: left;
|
||||||
width: 63.2px;
|
width: 63.2px;
|
||||||
height: 63.2px;
|
height: 63.2px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
@@ -762,42 +770,88 @@ div.homeScreen {
|
|||||||
border: 1px inset rgba(100, 100, 100, 0.25);
|
border: 1px inset rgba(100, 100, 100, 0.25);
|
||||||
padding: 0 0 4px 0;
|
padding: 0 0 4px 0;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadButtons:hover {
|
.dialPadButtons:hover {
|
||||||
background: rgba(80, 122, 172, 0.5);
|
background: rgba(80, 122, 172, 0.5);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadAddress {
|
.dialPadAddress {
|
||||||
float: left;
|
float: left;
|
||||||
width: 192px;
|
width: 192px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
background: rgba(64, 98, 138, 0.15);
|
background: rgba(64, 98, 138, 0.15);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
border-left: 1px inset #40628a;
|
border-left: 1px inset #40628a;
|
||||||
border-top: 1px inset #40628a;
|
border-top: 1px inset #40628a;
|
||||||
border-bottom: 1px inset #40628a;
|
border-bottom: 1px inset #40628a;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadAddress:hover{
|
.dialPadAddress:hover{
|
||||||
background: rgba(80, 122, 172, 0.5);
|
background: rgba(80, 122, 172, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadClear {
|
.dialPadClear {
|
||||||
float: left;
|
float: left;
|
||||||
width: 19%;
|
width: 19%;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
background: rgba(64, 98, 138, 0.15);
|
background: rgba(64, 98, 138, 0.15);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
border-right: 1px inset #40628a;
|
border-right: 1px inset #40628a;
|
||||||
border-top: 1px inset #40628a;
|
border-top: 1px inset #40628a;
|
||||||
border-bottom: 1px inset #40628a;
|
border-bottom: 1px inset #40628a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialPadClear:hover{
|
.dialPadClear:hover{
|
||||||
background: rgba(80, 122, 172, 0.5);
|
background: rgba(80, 122, 172, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.item.mainmenu {
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.clock {
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
float: right;
|
||||||
|
padding-right: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pdaFooter {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: #2c2c2c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdaFooterButton {
|
||||||
|
width: 33%;
|
||||||
|
padding: 0.5em 0;
|
||||||
|
font-size: 200%;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdaFooterButton:hover {
|
||||||
|
background: #507aac;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdaFooterButton.disabled {
|
||||||
|
background: none !important;
|
||||||
|
color: #555 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdaFooterButton.uiLinkPendingIcon {
|
||||||
|
position: absolute;
|
||||||
|
width: 33%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
51
nano/js/nano_state_pda.js
Normal file
51
nano/js/nano_state_pda.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
NanoStatePDAClass.inheritsFrom(NanoStateClass);
|
||||||
|
var NanoStatePDA = new NanoStatePDAClass();
|
||||||
|
|
||||||
|
function NanoStatePDAClass() {
|
||||||
|
this.key = 'pda';
|
||||||
|
this.key = this.key.toLowerCase();
|
||||||
|
this.current_template = "";
|
||||||
|
|
||||||
|
NanoStateManager.addState(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NanoStatePDAClass.prototype.onUpdate = function(data) {
|
||||||
|
NanoStateClass.prototype.onUpdate.call(this, data);
|
||||||
|
var state = this;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if(data['data']['app'] != null) {
|
||||||
|
var template = data['data']['app']['template'];
|
||||||
|
if(template != null && template != state.current_template) {
|
||||||
|
var templateMarkup = nanouiTemplateBundle()[template + ".tmpl"];
|
||||||
|
if (templateMarkup) {
|
||||||
|
templateMarkup += '<div class="clearBoth"></div>';
|
||||||
|
|
||||||
|
try {
|
||||||
|
NanoTemplate.addTemplate('app', templateMarkup);
|
||||||
|
NanoTemplate.resetTemplate('app');
|
||||||
|
$("#uiApp").html(NanoTemplate.parse('app', data));
|
||||||
|
state.current_template = template;
|
||||||
|
|
||||||
|
if(data['config']['status'] == 2) {
|
||||||
|
$('#uiApp .linkActive').addClass('linkPending');
|
||||||
|
$('#uiApp .linkActive').oneTime(400, 'linkPending', function () {
|
||||||
|
$('#uiApp .linkActive').removeClass('linkPending inactive');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch(error) {
|
||||||
|
reportError('ERROR: An error occurred while loading the PDA App UI: ' + error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (NanoTemplate.templateExists('app')) {
|
||||||
|
$("#uiApp").html(NanoTemplate.parse('app', data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(error) {
|
||||||
|
reportError('ERROR: An error occurred while rendering the PDA App UI: ' + error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -76,6 +76,9 @@ var NanoTemplate = function () {
|
|||||||
templateExists: function (key) {
|
templateExists: function (key) {
|
||||||
return _templates.hasOwnProperty(key);
|
return _templates.hasOwnProperty(key);
|
||||||
},
|
},
|
||||||
|
resetTemplate: function (key) {
|
||||||
|
_compiledTemplates[key] = null;
|
||||||
|
},
|
||||||
parse: function (templateKey, data) {
|
parse: function (templateKey, data) {
|
||||||
if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) {
|
if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) {
|
||||||
if (!_templates.hasOwnProperty(templateKey)) {
|
if (!_templates.hasOwnProperty(templateKey)) {
|
||||||
|
|||||||
@@ -166,4 +166,9 @@ if (!String.prototype.ckey) {
|
|||||||
String.prototype.ckey = function () {
|
String.prototype.ckey = function () {
|
||||||
return this.replace(/\W/g, '').toLowerCase();
|
return this.replace(/\W/g, '').toLowerCase();
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var reportError = function (str) {
|
||||||
|
window.location = "byond://?nano_err=" + encodeURIComponent(str);
|
||||||
|
alert(str);
|
||||||
}
|
}
|
||||||
@@ -1,784 +1,156 @@
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Title: PDA UI
|
Title: PDA UI
|
||||||
Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm
|
Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm
|
||||||
-->
|
-->
|
||||||
|
{{if data.useRetro}}
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainBG {
|
||||||
|
background: #6F7961;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemLabelNarrow, .itemLabel, .itemLabelWide, .itemLabelWider, .itemLabelWidest {
|
||||||
|
color: #000000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.good {
|
||||||
|
color: #444444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.average {
|
||||||
|
color: #222222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bad {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdanote {
|
||||||
|
color: #777777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link, .linkOn, .linkOff, .selected, .disabled, .yellowButton, .redButton {
|
||||||
|
color: #000000;
|
||||||
|
background: #565D4B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdalink, .pdalink.disabled {
|
||||||
|
min-width: 15px;
|
||||||
|
height: 16px;
|
||||||
|
text-align: center;
|
||||||
|
color: #000000;
|
||||||
|
text-decoration: none;
|
||||||
|
background: #565D4B;
|
||||||
|
border: 1px solid #161616;
|
||||||
|
padding: 0px 4px 4px 4px;
|
||||||
|
margin: 0 2px 2px 0;
|
||||||
|
cursor: default;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdalink.disabled {
|
||||||
|
color: #333;
|
||||||
|
background: #565D4B;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pdaFooter {
|
||||||
|
background: #6F7961;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdaFooterButton {
|
||||||
|
background: none;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.pdaFooterButton.disabled {
|
||||||
|
color: #444 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.clock {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixedLeft, .fixedLeftWide, .fixedLeftWider, .fixedLeftWidest, .floatRight {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatRight {
|
||||||
|
min-width: 15px;
|
||||||
|
height: 16px;
|
||||||
|
text-align: center;
|
||||||
|
background: #565D4B;
|
||||||
|
border: 1px solid #161616;
|
||||||
|
padding: 0px 4px 4px 4px;
|
||||||
|
margin: 0 2px 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uiIcon16 {
|
||||||
|
background-image: none;
|
||||||
|
float: left;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#uiTitleText, #pdaFooter {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pmon {
|
||||||
|
background: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemLabel {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statusDisplayRecords .good, .statusDisplay .good {
|
||||||
|
color: #020;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statusDisplayRecords .average, .statusDisplay .average {
|
||||||
|
color: #110;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
{{/if}}
|
||||||
{{if data.owner}}
|
{{if data.owner}}
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="itemLabelNarrow">
|
<div class="floatLeft">
|
||||||
<b>Functions</b>:
|
{{if data.idInserted}}
|
||||||
</div>
|
{{:helper.link(data.idLink, 'eject', {'choice' : "Authenticate"}, null, 'pdalink fixedLeftWide')}}
|
||||||
<div class="itemContent">
|
{{/if}}
|
||||||
<!--{{:helper.link('Refresh', 'refresh', {'choice' : "Refresh"}, null, 'fixedLeft')}}-->
|
{{if data.cartridge_name}}
|
||||||
{{:helper.link('Close', 'gear', {'choice' : "Close"}, null, 'fixedLeft')}}
|
{{:helper.link(data.cartridge_name, 'eject', {'choice' : "Eject"}, null, 'pdalink fixedLeftWidest')}}
|
||||||
{{if data.idInserted}} {{:helper.link('Update PDA Info', 'eject', {'choice' : "UpdateInfo"}, null, 'fixedLeftWide')}} {{/if}}
|
{{/if}}
|
||||||
{{if data.mode != 0}} {{:helper.link('Return', 'arrowreturn-1-w', {'choice' : "Return"}, null, 'fixedLeft')}} {{/if}}
|
{{:helper.link('Toggle R.E.T.R.O. mode', 'gear', {'choice': "Retro"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
<div class="clock">
|
||||||
|
{{:data.stationTime}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
|
||||||
<div class="item">
|
{{if data.app}}
|
||||||
<div class="itemLabelNarrow">
|
<h2><i class="fa fa-{{:data.app.icon}}"></i> {{:data.app.name}}</h2>
|
||||||
<b>Station Time</b>:
|
<div id="uiApp"></div>
|
||||||
</div>
|
<div class="pdaFooterButton disabled"> </div>
|
||||||
<div class="itemContent">
|
{{/if}}
|
||||||
<span class="average">{{:data.stationTime}}</span>
|
|
||||||
</div>
|
<div id="pdaFooter">
|
||||||
|
{{:helper.link("", 'back', {'choice' : "Back"}, data.app.has_back ? null : 'disabled', 'link pdaFooterButton')}}
|
||||||
|
{{:helper.link("", 'home', {'choice' : "Home"}, data.app.is_home ? 'disabled' : null, 'link pdaFooterButton')}}
|
||||||
</div>
|
</div>
|
||||||
<br>
|
|
||||||
|
|
||||||
|
|
||||||
{{if data.mode == 0}} <!-- Main Menu -->
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
Owner:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
<span class="average">{{:data.owner}}, {{:data.ownjob}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
ID:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link(data.idLink, 'eject', {'choice' : "Authenticate"}, data.idInserted ? null : 'disabled', data.idInserted ? 'floatright' : 'fixedLeft')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Cartridge</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{if data.cart_loaded==1}}
|
|
||||||
{{:helper.link(data.cartridge.name, 'eject', {'choice' : "Eject"},null,null)}}
|
|
||||||
{{else}}
|
|
||||||
{{:helper.link('None', 'eject', {'choice' : "Eject"},'disabled',null)}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<H2>Functions</H2>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>General</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('Notekeeper', 'note', {'choice' : "1"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link('Messenger', data.new_Message ? 'mail-closed' : 'mail-open', {'choice' : "2"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link('Crew Manifest', 'contact', {'choice' : "41"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link('News', data.new_News ? 'mail-closed' : 'mail-open', {'choice' : "6"}, null, 'fixedLeftWide')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{if data.cartridge}}
|
|
||||||
{{if data.cartridge.access.access_clown == 1}}
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Clown</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('Honk Synthesizer', 'gear', {'choice' : "Honk"}, null, 'fixedLeftWide')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_engine == 1}}
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Engineering</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('Power Monitor', 'alert', {'choice' : "43"}, null, 'fixedLeftWide')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_medical == 1}}
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Medical</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('Medical Records', 'gear', {'choice' : "44"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link(data.scanmode == 1 ? 'Disable Med Scanner' : 'Enable Med Scanner', 'gear', {'choice' : "Medical Scan"}, null , 'fixedLeftWide')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_security == 1}}
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Security</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('Security Records', 'gear', {'choice' : "45"}, null, 'fixedLeftWide')}}
|
|
||||||
{{if data.cartridge.radio ==1}} {{:helper.link('Security Bot Access', 'gear', {'choice' : "46"}, null, 'fixedLeftWide')}} {{/if}}
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_quartermaster == 1}}
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Quartermaster</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('Supply Records', 'gear', {'choice' : "47"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link('Delivery Bot Control', 'gear', {'choice' : "48"}, null, 'fixedLeftWide')}}
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
<br>
|
|
||||||
<div class="item">
|
|
||||||
<div class = "itemLabelNarrow">
|
|
||||||
<b>Utilities</b>:
|
|
||||||
</div>
|
|
||||||
<div class = "itemContent">
|
|
||||||
{{if data.cartridge}}
|
|
||||||
{{if data.cartridge.access.access_status_display == 1}}
|
|
||||||
{{:helper.link('Status Display', 'gear', {'choice' : "42"}, null, 'fixedLeftWide')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_janitor==1}}
|
|
||||||
{{:helper.link('Custodial Locator', 'gear', {'choice' : "49"}, null, 'fixedLeftWide')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.radio == 2}}
|
|
||||||
{{:helper.link('Signaler System', 'gear', {'choice' : "40"}, null, 'fixedLeftWide')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_reagent_scanner==1}}
|
|
||||||
{{:helper.link(data.scanmode == 3 ? 'Disable Reagent Scanner' : 'Enable Reagent Scanner', 'gear', {'choice' : "Reagent Scan"}, null, 'fixedLeftWider')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_engine==1}}
|
|
||||||
{{:helper.link(data.scanmode == 4 ? 'Disable Halogen Counter' : 'Enable Halogen Counter', 'gear', {'choice' : "Halogen Counter"}, null, 'fixedLeftWider')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_atmos==1}}
|
|
||||||
{{:helper.link(data.scanmode == 5 ? 'Disable Gas Scanner' : 'Enable Gas Scanner', 'gear', {'choice' : "Gas Scan"}, null, 'fixedLeftWide')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_remote_door==1}}
|
|
||||||
{{:helper.link('Toggle Door', 'gear', {'choice' : "Toggle Door"}, null, 'fixedLeftWide')}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{:helper.link('Atmospheric Scan', 'gear', {'choice' : "3"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link(data.touch_silent==1 ? 'Enable Beeping' : 'Disable Beeping', 'gear', {'choice' : "Toggle Beeping"}, null,'fixedLeftWide')}}
|
|
||||||
{{:helper.link(data.fon==1 ? 'Disable Flashlight' : 'Enable Flashlight', 'lightbulb', {'choice' : "Light"}, null,'fixedLeftWide')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{if data.pai}}
|
|
||||||
<div class="item">
|
|
||||||
<div class = "itemLabelNarrow">
|
|
||||||
<b>PAI Utilities</b>:
|
|
||||||
</div>
|
|
||||||
<div class = "itemContent">
|
|
||||||
{{:helper.link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"}, null, 'fixedLeft')}}
|
|
||||||
{{:helper.link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"}, null, 'fixedLeft')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 1}} <!-- Notekeeper -->
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b>Notes</b>:
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="statusDisplayRecords">
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemContent" style="width: 100%;">
|
|
||||||
<span class="average">{{:data.note}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
{{:helper.link('Edit Notes', 'gear', {'choice' : "Edit"}, null, 'fixedLeft')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 2}} <!-- Messenger -->
|
|
||||||
<H2>SpaceMessenger V4.0.1</H2>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Messenger Functions</b>:
|
|
||||||
</div>
|
|
||||||
<div class ="itemContent">
|
|
||||||
{{:helper.link(data.message_silent==1 ? 'Ringer: Off' : 'Ringer: On', data.message_silent==1 ? 'volume-off' : 'volume-on', {'choice' : "Toggle Ringer"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link(data.toff==1 ? 'Messenger: Off' : 'Messenger: On',data.toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link('Set Ringtone', 'comment', {'choice' : "Ringtone"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"}, null, 'fixedLeftWider')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{if data.toff == 0}}
|
|
||||||
<br><br>
|
|
||||||
{{if data.cartridge}}
|
|
||||||
{{if data.cartridge.charges}}
|
|
||||||
<div class="item">
|
|
||||||
<b>{{:data.cartridge.charges}}
|
|
||||||
{{if data.cartridge.access.access_detonate_pda}} detonation charges left. {{/if}}
|
|
||||||
{{if data.cartridge.access.access_clown || data.cartridge.access.access_mime}} viral files left. {{/if}}
|
|
||||||
</b>
|
|
||||||
<br><br>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{if data.pda_count == 0}}
|
|
||||||
<b>No other PDAS located</b>
|
|
||||||
{{else}}
|
|
||||||
<H3>Current Conversations</H3>
|
|
||||||
{{for data.convopdas}}
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, value.fixedLeftWider)}}
|
|
||||||
{{if data.cartridge}}
|
|
||||||
{{if data.cartridge.access.access_detonate_pda && value.Detonate}}
|
|
||||||
{{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'fixedLeft')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_clown}}
|
|
||||||
{{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'fixedLeft')}}
|
|
||||||
{{/if}}
|
|
||||||
{{if data.cartridge.access.access_mime}}
|
|
||||||
{{:helper.link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : value.Reference}, null, 'fixedLeft')}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/for}}
|
|
||||||
<H3>Other PDAs</H3>
|
|
||||||
{{for data.pdas}}
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Message", 'target' : value.Reference}, null, value.fixedLeftWider)}}
|
|
||||||
{{if data.cartridge}}
|
|
||||||
{{if data.cartridge.access.access_detonate_pda && value.Detonate}} {{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}
|
|
||||||
{{if data.cartridge.access.access_clown}} {{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}
|
|
||||||
{{if data.cartridge.access.access_mime}} {{:helper.link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/for}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 21}} <!-- Messenger -->
|
|
||||||
<H2>SpaceMessenger V4.0.1</H2>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b>Messenger Functions</b>:
|
|
||||||
</div>
|
|
||||||
<div class ="itemContent">
|
|
||||||
{{:helper.link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"}, null, 'fixedLeftWide')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<H3>Conversation with: <span class="average">{{:data.convo_name}} ({{:data.convo_job}})</span></H3>
|
|
||||||
<div class="statusDisplay" style="overflow: auto;">
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemContent" style="width: 100%;">
|
|
||||||
{{for data.messages}}
|
|
||||||
{{if data.active_conversation == value.target}}
|
|
||||||
{{if value.sent==0}}
|
|
||||||
<span class="average"><B>Them</B>: {{:value.message}}</span><br>
|
|
||||||
{{else}}
|
|
||||||
<span class="good"><B>You</B>: {{:value.message}}</span><br>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/for}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{:helper.link('Reply', 'comment', {'choice' : "Message", 'target': data.active_conversation}, null, 'fixedLeft')}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode== 41}} <!-- Manifest uses cached data so we only use nanowriter when shit changes.-->
|
|
||||||
{{#def.crewManifest}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 3}}
|
|
||||||
<H2>Atmospheric Scan</H2>
|
|
||||||
{{#def.atmosphericScan}}
|
|
||||||
|
|
||||||
{{else data.mode == 40}} <!-- Cartridge: Signaler -->
|
|
||||||
<H2>Remote Signaling System</H2>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b>Frequency</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:data.records.signal_freq}}
|
|
||||||
<br>
|
|
||||||
|
|
||||||
{{:helper.link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-10"}, null, null)}}
|
|
||||||
{{:helper.link('-.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-2"}, null, null)}}
|
|
||||||
|
|
||||||
{{:helper.link('+.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "2"}, null, null)}}
|
|
||||||
{{:helper.link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "10"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b>Code</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
<span class="average">
|
|
||||||
{{:data.records.signal_code}}<br>
|
|
||||||
</span>
|
|
||||||
{{:helper.link('-5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-5"}, null, null)}}
|
|
||||||
{{:helper.link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-1"}, null, null)}}
|
|
||||||
{{:helper.link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "1"}, null, null)}}
|
|
||||||
{{:helper.link('+5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "5"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link('Send Signal', 'radiation', {'cartmenu' : "1", 'choice' : "Send Signal"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 42}}
|
|
||||||
<H2>Station Status Displays Interlink</H2>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b>Code</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('Clear', 'trash', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "blank"}, null, null)}}
|
|
||||||
<!-- VOREStation Edit TFF 21/12/19 - Virgo = Tram. Not shuttle -->
|
|
||||||
{{:helper.link('Tram ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "shuttle"}, null, null)}}
|
|
||||||
{{:helper.link('Message', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "message"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b>Message line 1</b>
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link(data.records.message1 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg1"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b>Message line 2</b>
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link(data.records.message2 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg2"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<b> ALERT!</b>:
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{:helper.link('None', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "default"}, null, null)}}
|
|
||||||
{{:helper.link('Red Alert', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "redalert"}, null, null)}}
|
|
||||||
{{:helper.link('Lockdown', 'caution', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "lockdown"}, null, null)}}
|
|
||||||
{{:helper.link('Biohazard', 'radiation', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "biohazard"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{else data.mode == 43}}
|
|
||||||
<H2>Sensor Selection</H2>
|
|
||||||
<div class="item">
|
|
||||||
Available Sensors:
|
|
||||||
</div>
|
|
||||||
{{for data.records.power_sensors}}
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link(value.name_tag, 'plus', {'cartmenu' : "1", 'choice' : "Power Select",'target' : value.name_tag})}}<br>
|
|
||||||
</div>
|
|
||||||
{{/for}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 433}}
|
|
||||||
<H2>Sensor Reading(Simplified View)</H2>
|
|
||||||
{{if data.records.sensor_reading}}
|
|
||||||
<table><tr><th>Area<th>Cell %<th>Load
|
|
||||||
{{for data.records.sensor_reading.apc_data}}
|
|
||||||
<tr><td>{{:value.name}}
|
|
||||||
<td>{{:value.cell_charge}}%
|
|
||||||
<td>{{:value.total_load}}
|
|
||||||
{{empty}}
|
|
||||||
<tr><td>No APCs found!
|
|
||||||
{{/for}}
|
|
||||||
</table>
|
|
||||||
<br><b>Available: {{:data.records.sensor_reading.total_avail}}</b>
|
|
||||||
<br><b>Load: {{:data.records.sensor_reading.total_used_all}}</b>
|
|
||||||
{{else}}
|
|
||||||
Unable to contact sensor controller! Please retry and contact tech support if problem persists.
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{else data.mode == 44}}
|
|
||||||
<H2>Medical Record List</H2>
|
|
||||||
<div class="item">
|
|
||||||
Select A record
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{for data.records.medical_records}}
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link(value.Name, 'gear', {'cartmenu' : "1", 'choice' : "Medical Records",'target' : value.ref}, null, null)}}
|
|
||||||
</div>
|
|
||||||
{{/for}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 441}}
|
|
||||||
<H2>Medical Record</H2>
|
|
||||||
<div class="statusDisplayRecords">
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemContent" style="width: 100%;">
|
|
||||||
{{if data.records.general_exists == 1}}
|
|
||||||
<span class="good">Name: </span> <span class="average">{{:data.records.general.name}} </span><br>
|
|
||||||
<span class="good">Entity Class: </span> <span class="average">{{:data.records.general.brain_type}} </span><br>
|
|
||||||
<span class="good">Sex: </span> <span class="average">{{:data.records.general.sex}} </span><br>
|
|
||||||
<span class="good">Species: </span> <span class="average">{{:data.records.general.species}} </span><br>
|
|
||||||
<span class="good">Age: </span> <span class="average">{{:data.records.general.age}} </span><br>
|
|
||||||
<span class="good">Rank: </span> <span class="average">{{:data.records.general.rank}} </span><br>
|
|
||||||
<span class="good">Fingerprint: </span> <span class="average">{{:data.records.general.fingerprint}} </span><br>
|
|
||||||
<span class="good">Physical Status: </span> <span class="average">{{:data.records.general.p_stat}} </span><br>
|
|
||||||
<span class="good">Mental Status: </span> <span class="average">{{:data.records.general.m_stat}} </span><br><br>
|
|
||||||
{{else}}
|
|
||||||
<span class="bad">
|
|
||||||
General Record Lost!<br><br>
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
|
||||||
{{if data.records.medical_exists == 1}}
|
|
||||||
Medical Data:<br>
|
|
||||||
<span class="good">Blood Type: </span> <span class="average">{{:data.records.medical.b_type}} </span><br><br>
|
|
||||||
<span class="good">Minor Disabilities: </span> <span class="average">{{:data.records.medical.mi_dis}} </span><br>
|
|
||||||
<span class="good">Details: </span> <span class="average">{{:data.records.medical.mi_dis_d}} </span><br><br>
|
|
||||||
<span class="good">Major Disabilities: </span> <span class="average">{{:data.records.medical.ma_dis}} </span><br>
|
|
||||||
<span class="good">Details: </span> <span class="average">{{:data.records.medical.ma_dis_d}} </span><br><br>
|
|
||||||
<span class="good">Allergies: </span> <span class="average">{{:data.records.medical.alg}} </span><br>
|
|
||||||
<span class="good">Details: </span> <span class="average">{{:data.records.medical.alg_d}} </span><br><br>
|
|
||||||
<span class="good">Current Disease: </span> <span class="average">{{:data.records.medical.cdi}} </span><br>
|
|
||||||
<span class="good">Details: </span> <span class="average">{{:data.records.medical.alg_d}} </span><br><br>
|
|
||||||
<span class="good">Important Notes: </span> <span class="average multiLine">{{:data.records.medical.notes}} </span>
|
|
||||||
{{else}}
|
|
||||||
<span class="bad">
|
|
||||||
Medical Record Lost!
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 45}}
|
|
||||||
<H2>Security Record List</H2>
|
|
||||||
<div class="item">
|
|
||||||
Select A record
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{for data.records.security_records}}
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link(value.Name, 'gear', {'cartmenu' : "1", 'choice' : "Security Records",'target' : value.ref}, null, null)}}
|
|
||||||
</div>
|
|
||||||
{{/for}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 451}}
|
|
||||||
<H2>Security Record</H2>
|
|
||||||
<div class="statusDisplayRecords">
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemContent" style="width: 100%;">
|
|
||||||
{{if data.records.general_exists == 1}}
|
|
||||||
<span class="good">Name: </span> <span class="average"> {{:data.records.general.name}}</span><br>
|
|
||||||
<span class="good">Sex: </span> <span class="average">{{:data.records.general.sex}} </span><br>
|
|
||||||
<span class="good">Species: </span> <span class="average">{{:data.records.general.species}} </span><br>
|
|
||||||
<span class="good">Age: </span> <span class="average">{{:data.records.general.age}} </span><br>
|
|
||||||
<span class="good">Rank: </span> <span class="average">{{:data.records.general.rank}} </span><br>
|
|
||||||
<span class="good">Fingerprint: </span> <span class="average">{{:data.records.general.fingerprint}} </span><br>
|
|
||||||
<span class="good">Physical Status: </span> <span class="average">{{:data.records.general.p_stat}} </span><br>
|
|
||||||
<span class="good">Mental Status: </span> <span class="average">{{:data.records.general.m_stat}} </span><br><br>
|
|
||||||
{{else}}
|
|
||||||
<span class="bad">
|
|
||||||
General Record Lost!<br><br>
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
|
||||||
{{if data.records.security_exists == 1}}
|
|
||||||
Security Data:<br>
|
|
||||||
<span class="good">Criminal Status: </span><span class="average">{{:data.records.security.criminal}} </span><br><br>
|
|
||||||
<span class="good">Minor Crimes: </span><span class="average">{{:data.records.security.mi_crim}} </span><br>
|
|
||||||
<span class="good">Details: </span><span class="average">{{:data.records.security.mi_crim_d}} </span><br><br>
|
|
||||||
<span class="good">Major Crimes: </span><span class="average">{{:data.records.security.ma_crim}} </span><br>
|
|
||||||
<span class="good">Details: </span><span class="average">{{:data.records.security.ma_crim_d}} </span><br><br>
|
|
||||||
<span class="good">Important Notes: </span><span class="average multiLine">{{:data.records.security.notes}} </span>
|
|
||||||
{{else}}
|
|
||||||
<span class="bad">
|
|
||||||
Security Record Lost!<br><br>
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 46}}
|
|
||||||
<H2>Security Bot Control </H2>
|
|
||||||
{{if data.records.beepsky.active == null || data.records.beepsky.active == 0}}
|
|
||||||
{{if data.records.beepsky.count == 0}}
|
|
||||||
<H1><span class="bad">No bots found.</span></H1>
|
|
||||||
{{else}}
|
|
||||||
<div class="item">
|
|
||||||
Select A Bot.
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
{{for data.records.beepsky.bots}}
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, null)}} (Location: {{:value.Location}})
|
|
||||||
</div>
|
|
||||||
{{/for}}
|
|
||||||
{{/if}}
|
|
||||||
<br>
|
|
||||||
{{:helper.link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"}, null, null)}}
|
|
||||||
{{else}}
|
|
||||||
<H1><span class="average">{{:data.records.beepsky.active}}</span></H1>
|
|
||||||
<br><br>
|
|
||||||
{{if data.records.beepsky.botstatus.mode == -1}}
|
|
||||||
<H1><span class="bad">Waiting for response...</span></H1>
|
|
||||||
{{else}}
|
|
||||||
<H1><span class="good">Status:</span></H1>
|
|
||||||
<br>
|
|
||||||
<div class = "item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<span class="good">Location:</span>
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
<span class="average">{{:data.records.beepsky.botstatus.loca}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class = "item">
|
|
||||||
<div class="itemLabel">
|
|
||||||
<span class="good">Mode:</span>
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
<span class="average">
|
|
||||||
{{if data.records.beepsky.botstatus.mode ==0}}
|
|
||||||
Ready
|
|
||||||
{{else data.records.beepsky.botstatus.mode == 1}}
|
|
||||||
Apprehending target
|
|
||||||
{{else data.records.beepsky.botstatus.mode ==2 || data.records.beepsky.botstatus.mode == 3}}
|
|
||||||
Arresting target
|
|
||||||
{{else data.records.beepsky.botstatus.mode ==4}}
|
|
||||||
Starting patrol
|
|
||||||
{{else data.records.beepsky.botstatus.mode ==5}}
|
|
||||||
On Patrol
|
|
||||||
{{else data.records.beepsky.botstatus.mode ==6}}
|
|
||||||
Responding to summons
|
|
||||||
{{/if}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, null)}}
|
|
||||||
{{:helper.link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, null)}}
|
|
||||||
{{:helper.link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"}, null, null)}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{:helper.link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"}, null, null)}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 47}}
|
|
||||||
<H1><span class="average">Supply Record Interlink</span></H1>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<span class="good">Location:</span>
|
|
||||||
</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
<span class="average">
|
|
||||||
{{if data.records.supply.shuttle_moving}}
|
|
||||||
Moving to station ({{:data.records.supply.shuttle_eta}})
|
|
||||||
{{else}}
|
|
||||||
Shuttle at {{:data.records.supply.shuttle_loc}}
|
|
||||||
{{/if}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="statusDisplayRecords">
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemContent" style="width: 100%;">
|
|
||||||
<span class="good"><B>Current Approved Orders</B></span><br>
|
|
||||||
{{if data.records.supply.approved_count == 0}}
|
|
||||||
<span class="average"> No current approved orders </span><br><br>
|
|
||||||
{{else}}
|
|
||||||
{{for data.records.supply.approved}}
|
|
||||||
<span class="average">#{{:value.Number}} - {{:value.Name}} approved by {{:value.OrderedBy}}<br>{{if value.Comment != ""}} {{:value.Comment}} <br>{{/if}}<br></span>
|
|
||||||
{{/for}}
|
|
||||||
{{/if}}
|
|
||||||
<br><br>
|
|
||||||
<span class="good"><B>Current Requested Orders</B></span><br>
|
|
||||||
{{if data.records.supply.requests_count == 0}}
|
|
||||||
<span class="average">No current requested orders</span><br><br>
|
|
||||||
{{else}}
|
|
||||||
{{for data.records.supply.requests}}
|
|
||||||
<span class="average">#{{:value.Number}} - {{:value.Name}} requested by {{:value.OrderedBy}}<br>{{if value.Comment != ""}} {{:value.Comment}} <br>{{/if}}<br></span>
|
|
||||||
{{/for}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 48}}
|
|
||||||
<H2>Mule Control</H2>
|
|
||||||
{{if data.records.mulebotcount == 0}}
|
|
||||||
<H1><span class="bad">No bots found.</span></H1>
|
|
||||||
{{else}}
|
|
||||||
<H2>Mule List</H2>
|
|
||||||
{{for data.records.mulebots}}
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">Mulebot #{{:value.name}}</div>
|
|
||||||
<div class="itemContent">Location: {{:value.location}}<br>Home: {{:value.home}}<br>Target: {{:value.target}}<br>Load: {{:value.load}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabel">Status:</div>
|
|
||||||
<div class="itemContent">
|
|
||||||
{{if value.paused == 0}}
|
|
||||||
Nominal
|
|
||||||
{{else value.paused == 1}}
|
|
||||||
Paused
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
{{:helper.link('Go home', null, {'cartmenu' : "1", 'choice' : "MULEbot", 'ref' : value.ref, 'command' : "Home"})}}
|
|
||||||
{{:helper.link('Set destination', null, {'cartmenu' : "1", 'choice' : "MULEbot", 'ref' : value.ref, 'command' : "SetD"})}}
|
|
||||||
{{:helper.link('Go', null, {'cartmenu' : "1", 'choice' : "MULEbot", 'ref' : value.ref, 'command' : "GoTD"})}}
|
|
||||||
{{:helper.link('Stop', null, {'cartmenu' : "1", 'choice' : "MULEbot", 'ref' : value.ref, 'command' : "Stop"})}}
|
|
||||||
</div>
|
|
||||||
{{/for}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
{{else data.mode == 49}}
|
|
||||||
<H2>Janatorial Supplies Locator</H2>
|
|
||||||
<div class="item">
|
|
||||||
<span class="good">Current Location:</span>
|
|
||||||
{{if data.records.janitor.user_loc.x == 0}}
|
|
||||||
<span class="bad">Unknown</span>
|
|
||||||
{{else}}
|
|
||||||
<span class="average"> {{:data.records.janitor.user_loc.x}} / {{:data.records.janitor.user_loc.y}}</span>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
{{for data.records.janitor.mops}}
|
|
||||||
{{if value.x==0}}
|
|
||||||
<span class="bad">Unable to locate Mop</span>
|
|
||||||
{{else}}
|
|
||||||
<span class="good">Mop Location:</span>
|
|
||||||
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}</span><br>
|
|
||||||
{{/if}}
|
|
||||||
{{/for}}
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
{{for data.records.janitor.buckets}}
|
|
||||||
{{if value.x==0}}
|
|
||||||
<span class="bad">Unable to locate Water Buckets</span>
|
|
||||||
{{else}}
|
|
||||||
<span class="good">Water Buckets Location:</span>
|
|
||||||
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Water Level: {{:value.status}}</span><br>
|
|
||||||
{{/if}}
|
|
||||||
{{/for}}
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
{{for data.records.janitor.cleanbots}}
|
|
||||||
{{if value.x==0}}
|
|
||||||
<span class="bad">Unable to locate Clean Bots</span>
|
|
||||||
{{else}}
|
|
||||||
<span class="good">Clean Bots Location:</span>
|
|
||||||
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}</span><br>
|
|
||||||
{{/if}}
|
|
||||||
{{/for}}
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
{{for data.records.janitor.carts}}
|
|
||||||
{{if value.x==0}}
|
|
||||||
<span class="bad">Unable to locate Janitorial Cart</span>
|
|
||||||
{{else}}
|
|
||||||
<span class="good">Janitorial cart Location:</span>
|
|
||||||
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}</span><br>
|
|
||||||
{{/if}}
|
|
||||||
{{/for}}
|
|
||||||
|
|
||||||
{{else data.mode == 6}}
|
|
||||||
<H2><span class="white">InstaNews ED 2.0.9</span></H2>
|
|
||||||
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemLabelNarrow">
|
|
||||||
<b>Functions</b>:
|
|
||||||
</div>
|
|
||||||
<div class ="itemContent">
|
|
||||||
{{:helper.link(data.news_silent==1 ? 'Ringer: Off' : 'Ringer: On', data.news_silent==1 ? 'volume-off' : 'volume-on', {'choice' : "Toggle News"}, null, 'fixedLeftWide')}}
|
|
||||||
{{:helper.link('Set news tone', 'comment', {'choice' : "Newstone"}, null, 'fixedLeftWide')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{if data.reception != 1}}
|
|
||||||
<span class="bad">No reception with newscaster network.</span>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemContent">
|
|
||||||
{{for data.feedChannels}}
|
|
||||||
{{if value.censored}}
|
|
||||||
{{:helper.link(value.name, 'circle-arrow-s', {'choice' : "Select Feed", 'feed' : value.feed, 'name' : value.name } , null, 'fixedLeftWiderRed')}}
|
|
||||||
{{else}}
|
|
||||||
{{:helper.link(value.name, 'circle-arrow-s', {'choice' : "Select Feed", 'feed' : value.feed, 'name' : value.name } , null, 'fixedLeftWider')}}
|
|
||||||
{{/if}}
|
|
||||||
{{empty}}
|
|
||||||
<I>No active channels found...</I>
|
|
||||||
{{/for}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{else data.mode == 61}}
|
|
||||||
<H2><span class="white">{{:data.feed.channel}}</span></H2>
|
|
||||||
<span class="white">Created by: </span><span class="average">{{:data.feed.author}}<br></span>
|
|
||||||
|
|
||||||
{{if data.reception != 1}}
|
|
||||||
<span class="bad">No reception with newscaster network.</span>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="statusDisplay" style="overflow: auto;">
|
|
||||||
<div class="item">
|
|
||||||
<div class="itemContent" style="width: 100%;">
|
|
||||||
{{if data.feed.censored}}
|
|
||||||
<H3><span class="bad">Attention</span></H3>
|
|
||||||
This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<br>
|
|
||||||
No further feed story additions are allowed while the D-Notice is in effect.<br>
|
|
||||||
{{else}}
|
|
||||||
{{for data.feed.messages}}
|
|
||||||
-{{:value.body}}<br>
|
|
||||||
{{if value.has_image}}
|
|
||||||
<img src='pda_news_tmp_photo_{{:data.feed.channel}}_{{:value.index}}.png' width = '180'><br>
|
|
||||||
{{if value.caption}}
|
|
||||||
<span class="caption">{{:value.caption}}</span><br>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
<span class="footer">[{{:value.message_type}} by <span class="average">{{:value.author}}</span> - {{:value.time_stamp}}]</span><br>
|
|
||||||
<br>
|
|
||||||
{{empty}}
|
|
||||||
<I>No feed messages found in channel...</I>
|
|
||||||
{{/for}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="wholeScreen">
|
<div class="wholeScreen">
|
||||||
<br><br><br><br><br><br><br>No Owner information found, please swipe ID
|
<br><br><br><br><br><br><br>No Owner information found, please swipe ID
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
60
nano/templates/pda_atmos_scan.tmpl
Normal file
60
nano/templates/pda_atmos_scan.tmpl
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<!--
|
||||||
|
Title: PDA Atmospheric Scanner UI
|
||||||
|
Used In File(s): \code\game\objects\items\devices\PDA\cart_apps.dm
|
||||||
|
-->
|
||||||
|
<div class="statusDisplay" style="height: 250px; overflow: auto;">
|
||||||
|
<div class="item">
|
||||||
|
{{if data.aircontents.reading == 1}}
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="pdanote">Pressure:</span>
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
{{:helper.string('<span class="{0}">{1} kPa</span>', data.aircontents.pressure < 80 || data.aircontents.pressure > 120 ? 'bad' : data.aircontents.pressure < 95 || data.aircontents.pressure > 110 ? 'average' : 'good', helper.smoothRound(data.aircontents.pressure, 1))}}
|
||||||
|
</div>
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="pdanote">Temperature:</span>
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
{{:helper.string('<span class="{0}">{1} °C</span>', data.aircontents.temp < 5 || data.aircontents.temp > 35 ? 'bad' : data.aircontents.temp < 15 || data.aircontents.temp > 25 ? 'average' : 'good' , helper.smoothRound(data.aircontents.temp, 1))}}
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="pdanote">Oxygen:</span>
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
{{:helper.string('<span class="{0}">{1}%</span>', data.aircontents.oxygen < 17 ? 'bad' : data.aircontents.oxygen < 19 ? 'average' : 'good', helper.smoothRound(data.aircontents.oxygen, 1))}}
|
||||||
|
</div>
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="pdanote">Nitrogen:</span>
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
{{:helper.string('<span class="{0}">{1}%</span>', data.aircontents.nitrogen > 82 ? 'bad' : data.aircontents.nitrogen > 80 ? 'average' : 'good', helper.smoothRound(data.aircontents.nitrogen, 1))}}
|
||||||
|
</div>
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="pdanote">Carbon Dioxide:</span>
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
{{:helper.string('<span class="{0}">{1}%</span>', data.aircontents.carbon_dioxide > 5 ? 'bad' : 'good', helper.smoothRound(data.aircontents.carbon_dioxide, 1))}}
|
||||||
|
</div>
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="pdanote">Plasma:</span>
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
{{:helper.string('<span class="{0}">{1}%</span>', data.aircontents.plasma > 0 ? 'bad' : 'good', helper.smoothRound(data.aircontents.plasma, 1))}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{if data.aircontents.other > 0}}
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="pdanote">Unknown:</span>
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
<span class="bad">{{:helper.smoothRound(data.aircontents.other, 1)}}%</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<div class="itemContent" style="width: 100%;">
|
||||||
|
<span class="average"><b>Unable to get air reading</b></span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
66
nano/templates/pda_janitor.tmpl
Normal file
66
nano/templates/pda_janitor.tmpl
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<div class="statusDisplay">
|
||||||
|
<div class="item">
|
||||||
|
<span class="good">Current Location:</span>
|
||||||
|
{{if data.janitor.user_loc.x == 0}}
|
||||||
|
<span class="bad">Unknown</span>
|
||||||
|
{{else}}
|
||||||
|
<span class="average"> {{:data.janitor.user_loc.x}} / {{:data.janitor.user_loc.y}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
{{if data.janitor.mops}}
|
||||||
|
<span class="good">Mop Locations:</span>
|
||||||
|
<ul>
|
||||||
|
{{for data.janitor.mops}}
|
||||||
|
<li>
|
||||||
|
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}</span>
|
||||||
|
</li>
|
||||||
|
{{/for}}
|
||||||
|
</ul>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">Unable to locate Mops</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
{{if data.janitor.buckets}}
|
||||||
|
<span class="good">Mop Bucket Locations:</span>
|
||||||
|
<ul>
|
||||||
|
{{for data.janitor.buckets}}
|
||||||
|
<li>
|
||||||
|
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Capacity: {{:value.volume}}/{{:value.max_volume}}</span>
|
||||||
|
</li>
|
||||||
|
{{/for}}
|
||||||
|
</ul>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">Unable to locate Mop Buckets</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
{{if data.janitor.cleanbots}}
|
||||||
|
<span class="good">Cleanbot Locations:</span>
|
||||||
|
<ul>
|
||||||
|
{{for data.janitor.cleanbots}}
|
||||||
|
<li>
|
||||||
|
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}</span>
|
||||||
|
</li>
|
||||||
|
{{/for}}
|
||||||
|
</ul>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">Unable to locate Cleanbots</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
{{if data.janitor.carts}}
|
||||||
|
<span class="good">Janitorial Cart Locations:</span>
|
||||||
|
<ul>
|
||||||
|
{{for data.janitor.carts}}
|
||||||
|
<li>
|
||||||
|
<span class="average">({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Water Level: {{:value.volume}}/{{:value.max_volume}}</span>
|
||||||
|
</li>
|
||||||
|
{{/for}}
|
||||||
|
</ul>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">Unable to locate Janitorial Carts</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
76
nano/templates/pda_main_menu.tmpl
Normal file
76
nano/templates/pda_main_menu.tmpl
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<!--
|
||||||
|
Title: PDA Home UI
|
||||||
|
Used In File(s): \code\game\objects\items\devices\PDA\core_apps.dm
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/* flash notify icons */
|
||||||
|
var notifications = [];
|
||||||
|
var noteTimer;
|
||||||
|
function mm_flashNotify() {
|
||||||
|
notifications.forEach(function(n) {
|
||||||
|
if(n.item.hasClass("fa-"+n.icon)) {
|
||||||
|
n.item.removeClass("fa-"+n.icon).addClass("fa-"+n.notifyIcon);
|
||||||
|
} else {
|
||||||
|
n.item.removeClass("fa-"+n.notifyIcon).addClass("fa-"+n.icon);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(!noteTimer) {
|
||||||
|
noteTimer = window.setInterval(mm_flashNotify, 1000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
Owner:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">{{:data.owner}}, {{:data.ownjob}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
ID:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link('Update PDA Info', 'refresh', {'choice' : "UpdateInfo"}, data.idInserted ? null : 'disabled', 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<H2>Functions</H2>
|
||||||
|
</div>
|
||||||
|
{{for data.categories : cat : i}}
|
||||||
|
<div class="item mainmenu">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
<b>{{:cat}}</b>:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{for data.apps[cat]}}
|
||||||
|
{{if value.ref in data.notifying}}
|
||||||
|
<div data-notify="{{:value.ref}}">
|
||||||
|
{{:helper.link(value.name, value.notify_icon, {'choice' : "StartProgram", 'program' : value.ref}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
notifications.push({item: $("[data-notify='{{:value.ref}}'] i"), icon: '{{:value.icon}}', notifyIcon: '{{:value.notify_icon}}'});
|
||||||
|
</script>
|
||||||
|
{{else}}
|
||||||
|
{{:helper.link(value.name, value.icon, {'choice' : "StartProgram", 'program' : value.ref}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
|
||||||
|
{{if data.pai}}
|
||||||
|
<div class="item">
|
||||||
|
<div class = "itemLabelNarrow">
|
||||||
|
<b>PAI Utilities</b>:
|
||||||
|
</div>
|
||||||
|
<div class = "itemContent">
|
||||||
|
{{:helper.link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"}, null, 'pdalink fixedLeft')}}
|
||||||
|
{{:helper.link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"}, null, 'pdalink fixedLeft')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
96
nano/templates/pda_manifest.tmpl
Normal file
96
nano/templates/pda_manifest.tmpl
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<!--
|
||||||
|
Title: PDA Crew Manifest UI
|
||||||
|
Used In File(s): \code\game\objects\items\devices\PDA\core_apps.dm
|
||||||
|
-->
|
||||||
|
<div class="item">
|
||||||
|
<center><table class="pmon"><tbody>
|
||||||
|
{{if data.manifest.heads}}
|
||||||
|
<tr><th colspan="3" class="command">Command</th></tr>
|
||||||
|
{{for data.manifest["heads"]}}
|
||||||
|
{{if value.rank == "Captain"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.sec}}
|
||||||
|
<tr><th colspan="3" class="sec">Security</th></tr>
|
||||||
|
{{for data.manifest["sec"]}}
|
||||||
|
{{if value.rank == "Head of Security"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.eng}}
|
||||||
|
<tr><th colspan="3" class="eng">Engineering</th></tr>
|
||||||
|
{{for data.manifest["eng"]}}
|
||||||
|
{{if value.rank == "Chief Engineer"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.med}}
|
||||||
|
<tr><th colspan="3" class="med">Medical</th></tr>
|
||||||
|
{{for data.manifest["med"]}}
|
||||||
|
{{if value.rank == "Chief Medical Officer"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.sci}}
|
||||||
|
<tr><th colspan="3" class="sci">Science</th></tr>
|
||||||
|
{{for data.manifest["sci"]}}
|
||||||
|
{{if value.rank == "Research Director"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.ser}}
|
||||||
|
<tr><th colspan="3" class="ser">Service</th></tr>
|
||||||
|
{{for data.manifest["ser"]}}
|
||||||
|
{{if value.rank == "Head of Personnel"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.sup}}
|
||||||
|
<tr><th colspan="3" class="sup">Supply</th></tr>
|
||||||
|
{{for data.manifest["sup"]}}
|
||||||
|
{{if value.rank == "Head of Personnel"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else value.rank == "Quartermaster"}}
|
||||||
|
<tr><td><span class="qm-job">{{:value.name}}</span></td><td><span class="qm-job">{{:value.rank}}</span></td><td><span class="qm-job">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.civ}}
|
||||||
|
<tr><th colspan="3" class="civ">Civilian</th></tr>
|
||||||
|
{{for data.manifest["civ"]}}
|
||||||
|
{{if value.rank == "Head of Personnel"}}
|
||||||
|
<tr><td><span class="good">{{:value.name}}</span></td><td><span class="good">{{:value.rank}}</span></td><td><span class="good">{{:value.active}}</span></td></tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{if data.manifest.misc}}
|
||||||
|
<tr><th colspan="3" class="misc">Misc</th></tr>
|
||||||
|
{{for data.manifest["misc"]}}
|
||||||
|
<tr><td><span class="average">{{:value.name}}</span></td><td><span class="average">{{:value.rank}}</span></td><td><span class="average">{{:value.active}}</span></td></tr>
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
</tbody></table></center>
|
||||||
|
</div>
|
||||||
54
nano/templates/pda_medical.tmpl
Normal file
54
nano/templates/pda_medical.tmpl
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{{if !data.records}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">Select a record:</div>
|
||||||
|
</div>
|
||||||
|
{{for data.recordsList}}
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link(value.Name, 'user', {'choice' : "Records", 'target' : value.ref}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
</div>
|
||||||
|
{{empty}}
|
||||||
|
<div class="item">
|
||||||
|
<span class="average">No records found.</span>
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
{{else}}
|
||||||
|
<div class="statusDisplayRecords">
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemContent" style="width: 100%;">
|
||||||
|
{{if data.records.general}}
|
||||||
|
<span class="good">Name: </span> <span class="average">{{:data.records.general.name}} </span><br>
|
||||||
|
<span class="good">Sex: </span> <span class="average">{{:data.records.general.sex}} </span><br>
|
||||||
|
<span class="good">Species: </span> <span class="average">{{:data.records.general.species}} </span><br>
|
||||||
|
<span class="good">Age: </span> <span class="average">{{:data.records.general.age}} </span><br>
|
||||||
|
<span class="good">Rank: </span> <span class="average">{{:data.records.general.rank}} </span><br>
|
||||||
|
<span class="good">Fingerprint: </span> <span class="average">{{:data.records.general.fingerprint}} </span><br>
|
||||||
|
<span class="good">Physical Status: </span> <span class="average">{{:data.records.general.p_stat}} </span><br>
|
||||||
|
<span class="good">Mental Status: </span> <span class="average">{{:data.records.general.m_stat}} </span><br><br>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">
|
||||||
|
General Record Lost!<br><br>
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
{{if data.records.medical}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">Medical Data:</div>
|
||||||
|
</div>
|
||||||
|
<span class="good">Blood Type: </span> <span class="average">{{:data.records.medical.b_type}} </span><br><br>
|
||||||
|
<span class="good">Minor Disabilities: </span> <span class="average">{{:data.records.medical.mi_dis}} </span><br>
|
||||||
|
<span class="good">Details: </span> <span class="average">{{:data.records.medical.mi_dis_d}} </span><br><br>
|
||||||
|
<span class="good">Major Disabilities: </span> <span class="average">{{:data.records.medical.ma_dis}} </span><br>
|
||||||
|
<span class="good">Details: </span> <span class="average">{{:data.records.medical.ma_dis_d}} </span><br><br>
|
||||||
|
<span class="good">Allergies: </span> <span class="average">{{:data.records.medical.alg}} </span><br>
|
||||||
|
<span class="good">Details: </span> <span class="average">{{:data.records.medical.alg_d}} </span><br><br>
|
||||||
|
<span class="good">Current Disease: </span> <span class="average">{{:data.records.medical.cdi}} </span><br>
|
||||||
|
<span class="good">Details: </span> <span class="average">{{:data.records.medical.alg_d}} </span><br><br>
|
||||||
|
<span class="good">Important Notes: </span> <span class="average">{{:data.records.medical.notes}} </span>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">
|
||||||
|
Medical Record Lost!
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
90
nano/templates/pda_messenger.tmpl
Normal file
90
nano/templates/pda_messenger.tmpl
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<!--
|
||||||
|
Title: PDA Messenger UI
|
||||||
|
Used In File(s): \code\game\objects\items\devices\PDA\core_apps.dm
|
||||||
|
-->
|
||||||
|
{{if data.active_conversation}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b>Messenger Functions</b>:
|
||||||
|
</div>
|
||||||
|
<div class ="itemContent">
|
||||||
|
{{:helper.link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link(data.auto_scroll ? 'Autoscroll: On' : 'Autoscroll: Off', 'level-down', {'choice' : "Autoscroll"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<H3>Conversation with: <span class="average">{{:data.convo_name}} ({{:data.convo_job}})</span></H3>
|
||||||
|
<div class="statusDisplay" style="overflow: auto;">
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemContent" style="width: 100%;">
|
||||||
|
{{for data.messages}}
|
||||||
|
{{if data.active_conversation == value.target}}
|
||||||
|
{{if value.sent==0}}
|
||||||
|
<span class="average"><B>Them</B>: {{:value.message}}</span><br>
|
||||||
|
{{else}}
|
||||||
|
<span class="good"><B>You</B>: {{:value.message}}</span><br>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{/for}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{:helper.link('Reply', 'comment', {'choice' : "Message", 'target': data.active_conversation}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
{{if data.auto_scroll && data.latest_post != data.messages.length}}
|
||||||
|
var body = document.body;
|
||||||
|
$('html,body').animate({scrollTop: body.scrollHeight}, "fast");
|
||||||
|
{{/if}}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{{else}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
<b>Messenger Functions</b>:
|
||||||
|
</div>
|
||||||
|
<div class ="itemContent">
|
||||||
|
{{:helper.link(data.silent==1 ? 'Ringer: Off' : 'Ringer: On', data.silent==1 ? 'volume-off' : 'volume-up', {'choice' : "Toggle Ringer"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link(data.toff==1 ? 'Messenger: Off' : 'Messenger: On',data.toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Set Ringtone', 'bell-o', {'choice' : "Ringtone"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"}, null, 'pdalink fixedLeftWider')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{if data.toff == 0}}
|
||||||
|
<br>
|
||||||
|
{{if data.charges}}
|
||||||
|
<div class="item">
|
||||||
|
<b>{{:data.charges}} charges left.</b>
|
||||||
|
<br><br>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{if !data.convopdas.length && !data.pdas.length}}
|
||||||
|
<b>No other PDAS located</b>
|
||||||
|
{{else}}
|
||||||
|
<H3>Current Conversations</H3>
|
||||||
|
{{for data.convopdas}}
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link(value.Name, 'arrow-circle-down', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, 'pdalink')}}
|
||||||
|
{{if data.charges}}
|
||||||
|
{{for data.plugins : plugin : i}}
|
||||||
|
{{:helper.link(plugin.name, plugin.icon, {'choice' : "Messenger Plugin", 'plugin' : plugin.ref, 'target' : value.Reference}, null, 'pdalink fixedLeft')}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
<H3>Other PDAs</H3>
|
||||||
|
{{for data.pdas}}
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link(value.Name, 'arrow-circle-down', {'choice' : "Message", 'target' : value.Reference}, null, 'pdalink')}}
|
||||||
|
{{if data.charges}}
|
||||||
|
{{for data.plugins : plugin : i}}
|
||||||
|
{{:helper.link(plugin.name, plugin.icon, {'choice' : "Messenger Plugin", 'plugin' : plugin.ref, 'target' : value.Reference}, null, 'pdalink fixedLeft')}}
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
91
nano/templates/pda_mob_hunt.tmpl
Normal file
91
nano/templates/pda_mob_hunt.tmpl
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Connection Status:
|
||||||
|
</td>
|
||||||
|
{{if data.connected}}
|
||||||
|
<td>
|
||||||
|
<span class="good">Connected</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{:helper.link('Disconnect', 'sign-out', {'choice': 'Disconnect'})}}
|
||||||
|
</td>
|
||||||
|
{{else}}
|
||||||
|
<td>
|
||||||
|
<span class="bad">No Connection</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{:helper.link('Connect', 'sign-in', {'choice': 'Reconnect'})}}
|
||||||
|
</td>
|
||||||
|
{{/if}}
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="itemLabel">My Collection:</div>
|
||||||
|
{{if data.no_collection}}
|
||||||
|
<div class="statusDisplayRecords">
|
||||||
|
<div class="item">
|
||||||
|
<span class="average">Your collection is empty! Go capture some Nano-Mobs!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
Wild mobs captured: {{:data.wild_captures}}
|
||||||
|
{{else}}
|
||||||
|
<div class="statusDisplayRecords">
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemContent" style="width: 100%;">
|
||||||
|
{{if data.entry}}
|
||||||
|
{{if data.entry.nickname}}
|
||||||
|
<span class="good">Name: </span> <span class="average"> {{:data.entry.nickname}}</span><br>
|
||||||
|
{{/if}}
|
||||||
|
<span class="good">Species: </span> <span class="average">{{:data.entry.real_name}} </span><br>
|
||||||
|
<span class="good">Level: </span> <span class="average">{{:data.entry.level}} </span><br>
|
||||||
|
<span class="good">Primary Type: </span> <span class="average">{{:data.entry.type1}} </span><br>
|
||||||
|
{{if data.entry.type2}}
|
||||||
|
<span class="good">Secondary Type: </span> <span class="average">{{:data.entry.type2}} </span><br>
|
||||||
|
{{/if}}
|
||||||
|
{{if data.entry.sprite}}
|
||||||
|
<img src='{{:data.entry.sprite}}'>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">Mob Image Missing!</span>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">
|
||||||
|
Mob Data Missing!<br><br>
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
Wild mobs captured: {{:data.wild_captures}}
|
||||||
|
<div class="item">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{:helper.link('Previous Mob', 'arrow-left', {'choice': 'Prev'})}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{:helper.link('Transfer Mob', 'exchange', {'choice': 'Transfer'})}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{:helper.link('Rename Mob', 'pencil', {'choice': 'Rename'})}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{:helper.link('Release Mob', 'tree', {'choice': 'Release'})}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{:helper.link('Next Mob', 'arrow-right', {'choice': 'Next'})}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{{if data.entry.is_hacked}}
|
||||||
|
<br>
|
||||||
|
{{:helper.link('Set Trap', 'bolt', {'choice': 'Set_Trap'})}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
118
nano/templates/pda_mule.tmpl
Normal file
118
nano/templates/pda_mule.tmpl
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
{{if !data.mulebot.active}}
|
||||||
|
{{if data.mulebot.count == 0}}
|
||||||
|
<H1><span class="bad">No bots found.</span></H1>
|
||||||
|
{{else}}
|
||||||
|
<div class="item">
|
||||||
|
Select a MULE:
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
{{for data.mulebot.bots}}
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, 'pdalink fixedLeftWidest')}} (Location: {{:value.Location}})
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
<br>
|
||||||
|
{{:helper.link('Scan for Bots','rss', {'radiomenu' : "1", 'op' : "scanbots"}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
{{else}}
|
||||||
|
<H1><span class="average">{{:data.mulebot.active}}</span></H1>
|
||||||
|
{{if data.mulebot.botstatus.mode == -1}}
|
||||||
|
<H1><span class="bad">Waiting for response...</span></H1>
|
||||||
|
{{else}}
|
||||||
|
<H1><span class="good">Status:</span></H1>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Location:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">{{:data.mulebot.botstatus.loca}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Mode:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">
|
||||||
|
{{if data.mulebot.botstatus.mode == 0}}
|
||||||
|
Ready
|
||||||
|
{{else data.mulebot.botstatus.mode == 1}}
|
||||||
|
Loading/Unloading
|
||||||
|
{{else data.mulebot.botstatus.mode == 2}}
|
||||||
|
Navigating to Delivery Location
|
||||||
|
{{else data.mulebot.botstatus.mode == 3}}
|
||||||
|
Navigating to Home
|
||||||
|
{{else data.mulebot.botstatus.mode == 4}}
|
||||||
|
Waiting for Clear Path
|
||||||
|
{{else data.mulebot.botstatus.mode == 5 || data.mulebot.botstatus.mode == 6}}
|
||||||
|
Calculating navigation Path
|
||||||
|
{{else data.mulebot.botstatus.mode == 7}}
|
||||||
|
Unable to locate destination
|
||||||
|
{{/if}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Current Load:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">
|
||||||
|
{{:helper.link(data.mulebot.botstatus.load == null ? 'None (Unload)' : data.mulebot.botstatus.load + ' (Unload)', 'archive', {'radiomenu' : "1", 'op' : "unload"},data.mulebot.botstatus.load == null ? 'disabled' : null, 'pdalink fixedLeftWidest')}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Power:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">
|
||||||
|
{{:data.mulebot.botstatus.powr}}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Destination:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link(data.mulebot.botstatus.dest == null || data.mulebot.botstatus.dest == "" ? 'None (Set)' : data.mulebot.botstatus.dest + ' (Set)', 'gear', {'radiomenu' : "1", 'op' : "setdest"}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Home:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{if data.mulebot.botstatus.home == null}} None {{else}} {{:data.mulebot.botstatus.home}} {{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Auto Return:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link(data.mulebot.botstatus.retn == 1 ? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : (data.mulebot.botstatus.retn==1 ? "retoff" : "reton")}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Auto Pickup:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link(data.mulebot.botstatus.pick==1? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : (data.mulebot.botstatus.pick==1 ? "pickoff" : "pickon")}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Functions:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link('Stop', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, 'pdalink fixedLeft')}}
|
||||||
|
{{:helper.link('Proceed', 'gear', {'radiomenu' : "1", 'op' : "start"}, null, 'pdalink fixedLeft')}}
|
||||||
|
{{:helper.link('Return Home', 'gear', {'radiomenu' : "1", 'op' : "home"}, null, 'pdalink fixedLeft')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
21
nano/templates/pda_notekeeper.tmpl
Normal file
21
nano/templates/pda_notekeeper.tmpl
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
Title: PDA Notekeeper UI
|
||||||
|
Used In File(s): \code\game\objects\items\devices\PDA\apps.dm
|
||||||
|
-->
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b>Notes</b>:
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="statusDisplayRecords">
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemContent" style="width: 100%;">
|
||||||
|
<span class="pdanote">{{:data.note}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
{{:helper.link('Edit Notes', 'pencil-square-o', {'choice': "Edit"}, null, 'pdalink')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
49
nano/templates/pda_power.tmpl
Normal file
49
nano/templates/pda_power.tmpl
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{{if !data.records.powerconnected}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">Select a power monitor:</div>
|
||||||
|
</div>
|
||||||
|
{{for data.records.powermonitors}}
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link(value.Name, 'exclamation-circle', {'choice' : "Power Select", 'target' : value.ref}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
{{else}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
<b>Total Power:</b>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">{{:data.records.poweravail}} W</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
<b>Total Load:</b>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">{{:data.records.powerload}} W</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
<b>Total Demand:</b>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">{{:data.records.powerdemand}} W</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<table class="curvedEdges" style="text-align: center;"><tbody>
|
||||||
|
<tr><th>Area</th><th>Equip.</th><th>Lighting</th><th>Environ.</th><th>Cell</th><th>Load</th></tr>
|
||||||
|
{{for data.records.apcs}}
|
||||||
|
<tr><td style="text-align: left; font-weight: bold;">{{:value.Name}}</td>
|
||||||
|
{{:helper.string('<td width="55px" bgcolor="{0}">{1}</td>', value.Equipment == "On" || value.Equipment == "AOn" ? '#4f7529' : '#8f1414', value.Equipment)}}
|
||||||
|
{{:helper.string('<td width="55px" bgcolor="{0}">{1}</td>', value.Lights == "On" || value.Lights == "AOn" ? '#4f7529' : '#8f1414', value.Lights)}}
|
||||||
|
{{:helper.string('<td width="55px" bgcolor="{0}">{1}</td>', value.Environment == "On" || value.Environment == "AOn" ? '#4f7529' : '#8f1414', value.Environment)}}
|
||||||
|
{{:helper.string('<td style="text-align: center;" width="65px" bgcolor="{0}">{1}{2}</td>', value.CellStatus == "F" ? '#4f7529' : value.CellStatus == "C" ? '#cd6500' : '#8f1414', value.CellStatus == "M" ? 'No Cell' : value.CellPct + '%', value.CellStatus == "M" ? '' : ' (' + value.CellStatus + ')')}}
|
||||||
|
<td width="55px">{{:value.Load}}W</td>
|
||||||
|
</tr>
|
||||||
|
{{/for}}
|
||||||
|
</tbody></table>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
59
nano/templates/pda_secbot.tmpl
Normal file
59
nano/templates/pda_secbot.tmpl
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
{{if !data.beepsky.active}}
|
||||||
|
{{if data.beepsky.count == 0}}
|
||||||
|
<H1><span class="bad">No bots found.</span></H1>
|
||||||
|
{{else}}
|
||||||
|
<div class="item">
|
||||||
|
Select a bot:
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
{{for data.beepsky.bots}}
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, 'pdalink fixedLeftWidest')}} (Location: {{:value.Location}})
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
<br>
|
||||||
|
{{:helper.link('Scan for Bots','rss', {'radiomenu' : "1", 'op' : "scanbots"}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
{{else}}
|
||||||
|
<H1><span class="average">{{:data.beepsky.active}}</span></H1>
|
||||||
|
{{if data.beepsky.botstatus.mode == -1}}
|
||||||
|
<H1><span class="bad">Waiting for response...</span></H1>
|
||||||
|
{{else}}
|
||||||
|
<H1><span class="good">Status:</span></H1>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Location:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">{{:data.beepsky.botstatus.loca}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<span class="good">Mode:</span>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">
|
||||||
|
{{if data.beepsky.botstatus.mode ==0}}
|
||||||
|
Ready
|
||||||
|
{{else data.beepsky.botstatus.mode == 1}}
|
||||||
|
Apprehending target
|
||||||
|
{{else data.beepsky.botstatus.mode ==2 || data.beepsky.botstatus.mode == 3}}
|
||||||
|
Arresting target
|
||||||
|
{{else data.beepsky.botstatus.mode ==4}}
|
||||||
|
Starting patrol
|
||||||
|
{{else data.beepsky.botstatus.mode ==5}}
|
||||||
|
On Patrol
|
||||||
|
{{else data.beepsky.botstatus.mode ==6}}
|
||||||
|
Responding to summons
|
||||||
|
{{/if}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
50
nano/templates/pda_security.tmpl
Normal file
50
nano/templates/pda_security.tmpl
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{{if !data.records}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">Select a record:</div>
|
||||||
|
</div>
|
||||||
|
{{for data.recordsList}}
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link(value.Name, 'user', {'choice' : "Records", 'target' : value.ref}, null, 'pdalink fixedLeftWidest')}}
|
||||||
|
</div>
|
||||||
|
{{empty}}
|
||||||
|
<div class="item">
|
||||||
|
<span class="average">No records found.</span>
|
||||||
|
</div>
|
||||||
|
{{/for}}
|
||||||
|
{{else}}
|
||||||
|
<div class="statusDisplayRecords">
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemContent" style="width: 100%;">
|
||||||
|
{{if data.records.general}}
|
||||||
|
<span class="good">Name: </span> <span class="average"> {{:data.records.general.name}}</span><br>
|
||||||
|
<span class="good">Sex: </span> <span class="average">{{:data.records.general.sex}} </span><br>
|
||||||
|
<span class="good">Species: </span> <span class="average">{{:data.records.general.species}} </span><br>
|
||||||
|
<span class="good">Age: </span> <span class="average">{{:data.records.general.age}} </span><br>
|
||||||
|
<span class="good">Rank: </span> <span class="average">{{:data.records.general.rank}} </span><br>
|
||||||
|
<span class="good">Fingerprint: </span> <span class="average">{{:data.records.general.fingerprint}} </span><br>
|
||||||
|
<span class="good">Physical Status: </span> <span class="average">{{:data.records.general.p_stat}} </span><br>
|
||||||
|
<span class="good">Mental Status: </span> <span class="average">{{:data.records.general.m_stat}} </span><br><br>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">
|
||||||
|
General Record Lost!<br><br>
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
{{if data.records.security}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">Security Data:</div>
|
||||||
|
</div>
|
||||||
|
<span class="good">Criminal Status: </span><span class="average">{{:data.records.security.criminal}} </span><br><br>
|
||||||
|
<span class="good">Minor Crimes: </span><span class="average">{{:data.records.security.mi_crim}} </span><br>
|
||||||
|
<span class="good">Details: </span><span class="average">{{:data.records.security.mi_crim_d}} </span><br><br>
|
||||||
|
<span class="good">Major Crimes: </span><span class="average">{{:data.records.security.ma_crim}} </span><br>
|
||||||
|
<span class="good">Details: </span><span class="average">{{:data.records.security.ma_crim_d}} </span><br><br>
|
||||||
|
<span class="good">Important Notes: </span><span class="average">{{:data.records.security.notes}} </span>
|
||||||
|
{{else}}
|
||||||
|
<span class="bad">
|
||||||
|
Security Record Lost!<br><br>
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
38
nano/templates/pda_signaller.tmpl
Normal file
38
nano/templates/pda_signaller.tmpl
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<!--
|
||||||
|
Title: PDA Remote Signaller UI
|
||||||
|
Used In File(s): \code\game\objects\items\devices\PDA\cart_apps.dm
|
||||||
|
-->
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b>Frequency</b>:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:data.signal_freq}}
|
||||||
|
<br>
|
||||||
|
|
||||||
|
{{:helper.link('-1', null, {'choice' : "Signal Frequency", 'sfreq' : "-10"}, null, null)}}
|
||||||
|
{{:helper.link('-.2', null, {'choice' : "Signal Frequency", 'sfreq' : "-2"}, null, null)}}
|
||||||
|
|
||||||
|
{{:helper.link('+.2', null, {'choice' : "Signal Frequency", 'sfreq' : "2"}, null, null)}}
|
||||||
|
{{:helper.link('+1', null, {'choice' : "Signal Frequency", 'sfreq' : "10"}, null, null)}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b>Code</b>:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">
|
||||||
|
{{:data.signal_code}}<br>
|
||||||
|
</span>
|
||||||
|
{{:helper.link('-5', null, {'choice' : "Signal Code", 'scode' : "-5"}, null, null)}}
|
||||||
|
{{:helper.link('-1', null, {'choice' : "Signal Code", 'scode' : "-1"}, null, null)}}
|
||||||
|
{{:helper.link('+1', null, {'choice' : "Signal Code", 'scode' : "1"}, null, null)}}
|
||||||
|
{{:helper.link('+5', null, {'choice' : "Signal Code", 'scode' : "5"}, null, null)}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
{{:helper.link('Send Signal', 'exclamation-circle', {'choice' : "Send Signal"}, null, null)}}
|
||||||
|
</div>
|
||||||
44
nano/templates/pda_status_display.tmpl
Normal file
44
nano/templates/pda_status_display.tmpl
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<!--
|
||||||
|
Title: PDA Status Display UI
|
||||||
|
Used In File(s): \code\game\objects\items\devices\PDA\cart_apps.dm
|
||||||
|
-->
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b>Code</b>:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link('Clear', 'trash', {'choice' : "Status", 'statdisp' : "blank"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Shuttle ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "shuttle"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Message', 'gear', {'choice' : "Status", 'statdisp' : "message"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b>Message line 1</b>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link(data.records.message1 + ' (set)', 'pencil', {'choice' : "Status", 'statdisp' : "setmsg1"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b>Message line 2</b>
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link(data.records.message2 + ' (set)', 'pencil', {'choice' : "Status", 'statdisp' : "setmsg2"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
<b> ALERT!</b>:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
{{:helper.link('None', 'bell', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "default"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Red Alert', 'bell', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "redalert"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Lockdown', 'exclamation-circle', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "lockdown"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
{{:helper.link('Biohazard', 'exclamation-circle', {'choice' : "Status", 'statdisp' : "alert", 'alert' : "biohazard"}, null, 'pdalink fixedLeftWide')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
39
nano/templates/pda_supply.tmpl
Normal file
39
nano/templates/pda_supply.tmpl
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelNarrow">
|
||||||
|
Location:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
<span class="average">
|
||||||
|
{{if data.supply.shuttle_moving}}
|
||||||
|
Moving to {{:data.supply.shuttle_loc}}
|
||||||
|
{{else}}
|
||||||
|
Shuttle at {{:data.supply.shuttle_loc}}
|
||||||
|
{{/if}}
|
||||||
|
<br>
|
||||||
|
{{:data.supply.shuttle_time}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="statusDisplayRecords">
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemContent" style="width: 100%;">
|
||||||
|
<span class="good"><B>Current Approved Orders</B></span><br>
|
||||||
|
{{if data.supply.approved_count == 0}}
|
||||||
|
<span class="average pdanote">No current approved orders </span><br><br>
|
||||||
|
{{else}}
|
||||||
|
{{for data.supply.approved}}
|
||||||
|
<span class="average">#{{:value.Number}} - {{:value.Name}} approved by {{:value.OrderedBy}}<br>{{if value.Comment != ""}} {{:value.Comment}} <br>{{/if}}<br></span>
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
<br><br>
|
||||||
|
<span class="good"><B>Current Requested Orders</B></span><br>
|
||||||
|
{{if data.supply.requests_count == 0}}
|
||||||
|
<span class="average pdanote">No current requested orders</span><br><br>
|
||||||
|
{{else}}
|
||||||
|
{{for data.supply.requests}}
|
||||||
|
<span class="average">#{{:value.Number}} - {{:value.Name}} requested by {{:value.OrderedBy}}<br>{{if value.Comment != ""}} {{:value.Comment}} <br>{{/if}}<br></span>
|
||||||
|
{{/for}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
17
tgui/packages/tgui/interfaces/Pda.js
Normal file
17
tgui/packages/tgui/interfaces/Pda.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { round } from 'common/math';
|
||||||
|
import { Fragment } from 'inferno';
|
||||||
|
import { useBackend } from "../backend";
|
||||||
|
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from "../components";
|
||||||
|
import { Window } from "../layouts";
|
||||||
|
|
||||||
|
export const Pda = (props, context) => {
|
||||||
|
const { act, data } = useBackend(context);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Window width={580} height={670}>
|
||||||
|
<Window.Content scrollable>
|
||||||
|
PDA!
|
||||||
|
</Window.Content>
|
||||||
|
</Window>
|
||||||
|
);
|
||||||
|
};
|
||||||
14
tgui/packages/tgui/interfaces/pda/pda_main_menu.js
Normal file
14
tgui/packages/tgui/interfaces/pda/pda_main_menu.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { round } from 'common/math';
|
||||||
|
import { Fragment } from 'inferno';
|
||||||
|
import { useBackend } from "../backend";
|
||||||
|
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from "../components";
|
||||||
|
|
||||||
|
export const pda_main_menu = (props, context) => {
|
||||||
|
const { act, data } = useBackend(context);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Section>
|
||||||
|
Main Menu
|
||||||
|
</Section>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
<script type='text/javascript' src='nano_state_manager.js'></script>
|
<script type='text/javascript' src='nano_state_manager.js'></script>
|
||||||
<script type='text/javascript' src='nano_state.js'></script>
|
<script type='text/javascript' src='nano_state.js'></script>
|
||||||
<script type='text/javascript' src='nano_state_default.js'></script>
|
<script type='text/javascript' src='nano_state_default.js'></script>
|
||||||
|
<script type='text/javascript' src='nano_state_pda.js'></script>
|
||||||
<script type='text/javascript' src='nano_base_callbacks.js'></script>
|
<script type='text/javascript' src='nano_base_callbacks.js'></script>
|
||||||
<script type='text/javascript' src='nano_base_helpers.js'></script>
|
<script type='text/javascript' src='nano_base_helpers.js'></script>
|
||||||
<link rel='stylesheet' type='text/css' href='shared.css'>
|
<link rel='stylesheet' type='text/css' href='shared.css'>
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
#include "code\__defines\nifsoft.dm"
|
#include "code\__defines\nifsoft.dm"
|
||||||
#include "code\__defines\objects.dm"
|
#include "code\__defines\objects.dm"
|
||||||
#include "code\__defines\overmap.dm"
|
#include "code\__defines\overmap.dm"
|
||||||
|
#include "code\__defines\pda.dm"
|
||||||
#include "code\__defines\planets.dm"
|
#include "code\__defines\planets.dm"
|
||||||
#include "code\__defines\plants.dm"
|
#include "code\__defines\plants.dm"
|
||||||
#include "code\__defines\preferences.dm"
|
#include "code\__defines\preferences.dm"
|
||||||
@@ -3067,11 +3068,17 @@
|
|||||||
#include "code\modules\paperwork\stamps.dm"
|
#include "code\modules\paperwork\stamps.dm"
|
||||||
#include "code\modules\pda\app.dm"
|
#include "code\modules\pda\app.dm"
|
||||||
#include "code\modules\pda\cart.dm"
|
#include "code\modules\pda\cart.dm"
|
||||||
|
#include "code\modules\pda\cart_apps.dm"
|
||||||
#include "code\modules\pda\cart_vr.dm"
|
#include "code\modules\pda\cart_vr.dm"
|
||||||
#include "code\modules\pda\chatroom.dm"
|
#include "code\modules\pda\chatroom.dm"
|
||||||
|
#include "code\modules\pda\core_apps.dm"
|
||||||
|
#include "code\modules\pda\messenger.dm"
|
||||||
|
#include "code\modules\pda\messenger_plugins.dm"
|
||||||
#include "code\modules\pda\pda.dm"
|
#include "code\modules\pda\pda.dm"
|
||||||
|
#include "code\modules\pda\pda_tgui.dm"
|
||||||
#include "code\modules\pda\pda_vr.dm"
|
#include "code\modules\pda\pda_vr.dm"
|
||||||
#include "code\modules\pda\radio.dm"
|
#include "code\modules\pda\radio.dm"
|
||||||
|
#include "code\modules\pda\utilities.dm"
|
||||||
#include "code\modules\persistence\filth.dm"
|
#include "code\modules\persistence\filth.dm"
|
||||||
#include "code\modules\persistence\graffiti.dm"
|
#include "code\modules\persistence\graffiti.dm"
|
||||||
#include "code\modules\persistence\noticeboard.dm"
|
#include "code\modules\persistence\noticeboard.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user