diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 6c6269d301e..3e066989043 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -51,122 +51,194 @@ //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). var/locked[] = list() - proc/get_manifest(monochrome, OOC) - var/list/heads = new() - var/list/sec = new() - var/list/eng = new() - var/list/med = new() - var/list/sci = new() - var/list/civ = new() - var/list/bot = new() - var/list/misc = new() - var/list/isactive = new() - var/dat = {" - - - - "} - var/even = 0 - - // sort mobs - for(var/datum/data/record/t in data_core.general) - var/name = t.fields["name"] - var/rank = t.fields["rank"] - var/real_rank = t.fields["real_rank"] - if(OOC) - var/active = 0 - for(var/mob/M in player_list) - if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10) - active = 1 - break - isactive[name] = active ? "Active" : "Inactive" - else - isactive[name] = t.fields["p_stat"] - +/obj/effect/datacore/proc/get_manifest(monochrome, OOC) + var/list/heads = new() + var/list/sec = new() + var/list/eng = new() + var/list/med = new() + var/list/sci = new() + var/list/civ = new() + var/list/bot = new() + var/list/misc = new() + var/list/isactive = new() + var/dat = {" + +
NameRankActivity
+ + "} + var/even = 0 + // sort mobs + for(var/datum/data/record/t in data_core.general) + var/name = t.fields["name"] + var/rank = t.fields["rank"] + var/real_rank = t.fields["real_rank"] + if(OOC) + var/active = 0 + for(var/mob/M in player_list) + if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10) + active = 1 + break + isactive[name] = active ? "Active" : "Inactive" + else + isactive[name] = t.fields["p_stat"] //world << "[name]: [rank]" - //cael - to prevent multiple appearances of a player/job combination, add a continue after each line - var/department = 0 - if(real_rank in command_positions) - heads[name] = rank - department = 1 - if(real_rank in security_positions) - sec[name] = rank - department = 1 - if(real_rank in engineering_positions) - eng[name] = rank - department = 1 - if(real_rank in medical_positions) - med[name] = rank - department = 1 - if(real_rank in science_positions) - sci[name] = rank - department = 1 - if(real_rank in civilian_positions) - civ[name] = rank - department = 1 - if(real_rank in nonhuman_positions) - bot[name] = rank - department = 1 + var/department = 0 + if(real_rank in command_positions) + heads[name] = rank + department = 1 + if(real_rank in security_positions) + sec[name] = rank + department = 1 + if(real_rank in engineering_positions) + eng[name] = rank + department = 1 + if(real_rank in medical_positions) + med[name] = rank + department = 1 + if(real_rank in science_positions) + sci[name] = rank + department = 1 + if(real_rank in civilian_positions) + civ[name] = rank + department = 1 + if(real_rank in nonhuman_positions) + bot[name] = rank + department = 1 + if(!department && !(name in heads)) + misc[name] = rank + if(heads.len > 0) + dat += "" + for(name in heads) + dat += "" + even = !even + if(sec.len > 0) + dat += "" + for(name in sec) + dat += "" + even = !even + if(eng.len > 0) + dat += "" + for(name in eng) + dat += "" + even = !even + if(med.len > 0) + dat += "" + for(name in med) + dat += "" + even = !even + if(sci.len > 0) + dat += "" + for(name in sci) + dat += "" + even = !even + if(civ.len > 0) + dat += "" + for(name in civ) + dat += "" + even = !even + // in case somebody is insane and added them to the manifest, why not + if(bot.len > 0) + dat += "" + for(name in bot) + dat += "" + even = !even + // misc guys + if(misc.len > 0) + dat += "" + for(name in misc) + dat += "" + even = !even - if(!department && !(name in heads)) - misc[name] = rank - - if(heads.len > 0) - dat += "" - for(name in heads) - dat += "" - even = !even - if(sec.len > 0) - dat += "" - for(name in sec) - dat += "" - even = !even - if(eng.len > 0) - dat += "" - for(name in eng) - dat += "" - even = !even - if(med.len > 0) - dat += "" - for(name in med) - dat += "" - even = !even - if(sci.len > 0) - dat += "" - for(name in sci) - dat += "" - even = !even - if(civ.len > 0) - dat += "" - for(name in civ) - dat += "" - even = !even - // in case somebody is insane and added them to the manifest, why not - if(bot.len > 0) - dat += "" - for(name in bot) - dat += "" - even = !even - // misc guys - if(misc.len > 0) - dat += "" - for(name in misc) - dat += "" - even = !even + dat += "
NameRankActivity
Heads
[name][heads[name]][isactive[name]]
Security
[name][sec[name]][isactive[name]]
Engineering
[name][eng[name]][isactive[name]]
Medical
[name][med[name]][isactive[name]]
Science
[name][sci[name]][isactive[name]]
Civilian
[name][civ[name]][isactive[name]]
Silicon
[name][bot[name]][isactive[name]]
Miscellaneous
[name][misc[name]][isactive[name]]
Heads
[name][heads[name]][isactive[name]]
Security
[name][sec[name]][isactive[name]]
Engineering
[name][eng[name]][isactive[name]]
Medical
[name][med[name]][isactive[name]]
Science
[name][sci[name]][isactive[name]]
Civilian
[name][civ[name]][isactive[name]]
Silicon
[name][bot[name]][isactive[name]]
Miscellaneous
[name][misc[name]][isactive[name]]
" + dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly + dat = replacetext(dat, "\t", "") + return dat + + +/* +We can't just insert in HTML into the nanoUI so we need the raw data to play with. +*/ + +/obj/effect/datacore/proc/get_manifest_json() + var/heads[0] + var/sec[0] + var/eng[0] + var/med[0] + var/sci[0] + var/civ[0] + var/bot[0] + var/misc[0] + for(var/datum/data/record/t in data_core.general) + var/name = t.fields["name"] + var/rank = t.fields["rank"] + var/real_rank = t.fields["real_rank"] + var/isactive = t.fields["p_stat"] + var/department = 0 + var/depthead = 0 // Department Heads will be placed at the top of their lists. + if(real_rank in command_positions) + heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + depthead = 1 + if(rank=="Captain" && heads.len != 1) + heads.Swap(1,heads.len) + + if(real_rank in security_positions) + sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && sec.len != 1) + sec.Swap(1,sec.len) + + if(real_rank in engineering_positions) + eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && eng.len != 1) + eng.Swap(1,eng.len) + + if(real_rank in medical_positions) + med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && med.len != 1) + med.Swap(1,med.len) + + if(real_rank in science_positions) + sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && sci.len != 1) + sci.Swap(1,sci.len) + + if(real_rank in civilian_positions) + civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + if(depthead && civ.len != 1) + civ.Swap(1,civ.len) + + if(real_rank in nonhuman_positions) + bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive) + department = 1 + + if(!department && !(name in heads)) + misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive) + + return list(\ + "heads" = heads,\ + "sec" = sec,\ + "eng" = eng,\ + "med" = med,\ + "sci" = sci,\ + "civ" = civ,\ + "bot" = bot,\ + "misc" = misc\ + ) - dat += "" - dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly - dat = replacetext(dat, "\t", "") - return dat /obj/effect/laser name = "laser" diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index ed164896369..71a545cd556 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -443,7 +443,6 @@ //Sender isn't faking as someone who exists if(isnull(PDARec)) src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]") - customrecepient.tnote += "← From [customsender] ([customjob]):
[custommessage]
" if (!customrecepient.silent) playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, customrecepient.loc)) @@ -456,8 +455,13 @@ customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r") //Sender is faking as someone who exists else + src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]") - customrecepient.tnote += "← From [PDARec.owner] ([customjob]):
[custommessage]
" + customrecepient.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]"))) + + if(!customrecepient.conversations.Find("\ref[PDARec]")) + customrecepient.conversations.Add("\ref[PDARec]") + if (!customrecepient.silent) playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, customrecepient.loc)) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index f4f79f37476..4631577172e 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1,3 +1,4 @@ + //The advanced pea-green monochrome lcd of tomorrow. var/global/list/obj/item/device/pda/PDAs = list() @@ -25,7 +26,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/f_lum = 2 //Luminosity for the flashlight function var/silent = 0 //To beep or not to beep, that is the question var/toff = 0 //If 1, messenger disabled - var/tnote = null //Current Texts + var/tnote[0] //Current Texts var/last_text //No text spamming var/last_honk //Also no honk spamming that's bad too var/ttone = "beep" //The ringtone! @@ -37,7 +38,10 @@ var/global/list/obj/item/device/pda/PDAs = list() var/cart = "" //A place to stick cartridge menu information var/detonate = 1 // Can the PDA be blown up? var/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/newmessage = 0 //To remove hackish overlay check + var/obj/item/weapon/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. var/ownjob = null //related to above @@ -242,7 +246,13 @@ var/global/list/obj/item/device/pda/PDAs = list() if(usr.stat == 2) usr << "You can't do that because you are dead!" return - var/HTML = "AI PDA Message Log[tnote]" + var/HTML = "AI PDA Message Log" + for(var/index in tnote) + if(index["sent"]) + HTML += addtext("→ To ", index["owner"],":
", index["message"], "
") + else + HTML += addtext("← From ", index["owner"],":
", index["message"], "
") + HTML +="" usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") @@ -309,6 +319,172 @@ var/global/list/obj/item/device/pda/PDAs = list() return attack_self(M) return + + + +/* Notes for those wanting to modify this code or even understand it. + There are two modes: New UI and a UI already existing. + If the UI is new, you define your variables, if the ui already exists if it didn't have variables in data for what you want to add + then it won't add it even if you make a data["blahblah"] for it. That's the reason for the = null all over the place, so that. + ui.push_data(data) proc has to have the var structure already setup otherwise it can't push the update. + + The exception to the "YOU HAVE TO DEFINE IT" rule is cartridges, we later force + the ui to close if a cartridge is inserted so that never will be a problem. + So there will never be a time a UI creation causes that to be a problem. +*/ + +/obj/item/device/pda/ui_interact(mob/user, ui_key = "main") + var/title = "Personal Data Assistant" + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key) + + var/data[0] // This is the data that will be sent to the PDA + + + data["owner"] = owner // Who is your daddy... + data["ownjob"] = ownjob // ...and what does he do? + + data["mode"] = mode // The current view + data["scanmode"] = scanmode // Scanners + data["fon"] = fon // Flashlight on? + data["pai"] = (isnull(pai) ? 0 : 1) // pAI inserted? + data["note"] = note // current pda notes + data["silent"] = 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? + + + data["idInserted"] = (id ? 1 : 0) + data["idLink"] = (id ? text("[id.registered_name], [id.assignment]") : "--------") + + + if(cartridge) + var/cartdata[0] + + + data["records"] = cartridge.create_NanoUI_values() + + + cartdata["name"] = cartridge.name + 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\ + ) + if(isnull(cartridge.radio)) + cartdata["radio"] = 0 + else + if(istype(cartridge.radio, /obj/item/radio/integrated/beepsky)) + cartdata["radio"] = 1 + if(istype(cartridge.radio, /obj/item/radio/integrated/signal)) + cartdata["radio"] = 2 + if(istype(cartridge.radio, /obj/item/radio/integrated/mule)) + cartdata["radio"] = 3 + + cartdata["type"] = cartridge.type + cartdata["charges"] = cartridge.charges ? cartridge.charges : 0 + data["cartridge"] = cartdata + + + + + + data["stationTime"] = worldtime2text() + data["newMessage"] = newmessage + + + + var/convopdas[0] + var/pdas[0] + var/count = 0 + for (var/obj/item/device/pda/P in sortAtom(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 + data["messagescount"] = tnote.len + data["messages"] = tnote + var/found = 0 + if(active_conversation) + for(var/c in tnote) + if(c["target"] == active_conversation) + data["convo_name"] = c["owner"] + data["convo_job"] = c["job"] + found = 1 + break + if(!found) + data["convo_name"] = null + data["convo_job"] = null + + if(!ui || mode==41) + data["manifest"] = data_core.get_manifest_json() + + + if(!ui || mode==3) + var/turf/T = get_turf_or_move(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" = "[round(pressure,0.1)]",\ + "nitrogen" = "[round(n2_level*100,0.1)]",\ + "oxygen" = "[round(o2_level*100,0.1)]",\ + "carbon_dioxide" = "[round(co2_level*100,0.1)]",\ + "plasma" = "[round(plasma_level*100,0.01)]",\ + "other" = "[round(unknown_level, 0.01)]",\ + "temp" = "[round(environment.temperature-T0C,0.1)]",\ + "reading" = 1\ + ) + if(isnull(data["aircontents"])) + data["aircontents"] = list(\ + "pressure" = null,\ + "nitrogen" = null,\ + "oxygen" = null,\ + "carbon_dioxide" = null,\ + "plasma" = null,\ + "other" = null,\ + "temp" = null,\ + "reading" = 0\ + ) + + + + + if (!ui) + // the ui does not exist, so we'll create a new one + ui = new(user, src, ui_key, "pda.tmpl", title, 630, 600) + // When the UI is first opened this is the data it will use + ui.set_initial_data(data) + ui.open() + else + // The UI is already open so push the new data to it + ui.push_data(data) + return + + + //NOTE: graphic resources are loaded on client login /obj/item/device/pda/attack_self(mob/user as mob) @@ -317,203 +493,21 @@ var/global/list/obj/item/device/pda/PDAs = list() if(active_uplink_check(user)) return - var/dat = "Personal Data Assistant" - - dat += " Close" - - if ((!isnull(cartridge)) && (mode == 0)) - dat += " | Eject [cartridge]" - if (mode) - dat += " | Return" - dat += " | Refresh" - - dat += "
" - - if (!owner) - dat += "Warning: No owner information entered. Please swipe card.

" - dat += " Retry" - else - switch (mode) - if (0) - dat += "

PERSONAL DATA ASSISTANT v.1.2

" - dat += "Owner: [owner], [ownjob]
" - dat += text("ID: [id ? "[id.registered_name], [id.assignment]" : "----------"]") - dat += text("
[id ? "Update PDA Info" : ""]
") - - dat += "Station Time: [worldtime2text()]"//:[world.time / 100 % 6][world.time / 100 % 10]" - - dat += "

" - - dat += "

General Functions

" - dat += "" - if (cartridge.access_engine) - dat += "

Engineering Functions

" - dat += "" - if (cartridge.access_medical) - dat += "

Medical Functions

" - dat += "" - if (cartridge.access_security) - dat += "

Security Functions

" - dat += "" - else dat += "" - if(cartridge.access_quartermaster) - dat += "

Quartermaster Functions:

" - dat += "" - dat += "" - - dat += "

Utilities

" - dat += "" - - if (1) - dat += "

Notekeeper V2.1

" - dat += " Edit
" - dat += note - - if (2) - dat += "

SpaceMessenger V3.9.4

" - dat += " Ringer: [silent == 1 ? "Off" : "On"] | " - dat += " Send / Receive: [toff == 1 ? "Off" : "On"] | " - dat += " Set Ringtone | " - dat += " Messages
" - - if (istype(cartridge, /obj/item/weapon/cartridge/syndicate)) - dat += "[cartridge:shock_charges] detonation charges left.
" - if (istype(cartridge, /obj/item/weapon/cartridge/clown)) - dat += "[cartridge:honk_charges] viral files left.
" - if (istype(cartridge, /obj/item/weapon/cartridge/mime)) - dat += "[cartridge:mime_charges] viral files left.
" - - dat += "

Detected PDAs

" - - dat += "" - if (count == 0) - dat += "None detected.
" - - if(21) - dat += "

SpaceMessenger V3.9.4

" - dat += " Clear Messages" - - dat += "

Messages

" - - dat += tnote - dat += "
" - - if (3) - dat += "

Atmospheric Readings

" - - var/turf/T = get_turf_or_move(user.loc) - if (isnull(T)) - dat += "Unable to obtain a reading.
" - else - var/datum/gas_mixture/environment = T.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - dat += "Air Pressure: [round(pressure,0.1)] kPa
" - - 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) - dat += "Nitrogen: [round(n2_level*100)]%
" - dat += "Oxygen: [round(o2_level*100)]%
" - dat += "Carbon Dioxide: [round(co2_level*100)]%
" - dat += "Plasma: [round(plasma_level*100)]%
" - if(unknown_level > 0.01) - dat += "OTHER: [round(unknown_level)]%
" - dat += "Temperature: [round(environment.temperature-T0C)]°C
" - dat += "
" - - if (5) - dat += "

Nanotrasen Relay Chat

" - - dat += "

Detected Channels

:
  • " - for(var/datum/chatroom/C in chatrooms) - dat += "#[html_encode(lowertext(C.name))]" - if(C.password != "") - dat += " " - dat += "
  • " - - if (41) //crew manifest - dat += "

    Crew Manifest

    " - dat += "Entries cannot be modified from this terminal.

    " - if(data_core) - dat += data_core.get_manifest(1) // make it monochrome - dat += "
    " - - else//Else it links to the cart menu proc. Although, it really uses menu hub 4--menu 4 doesn't really exist as it simply redirects to hub. - dat += cart - - dat += "" - user << browse(dat, "window=pda;size=400x444;border=1;can_resize=1;can_close=0;can_minimize=0") - onclose(user, "pda", src) + ui_interact(user) //NanoUI requires this proc + return /obj/item/device/pda/Topic(href, href_list) + if(href_list["cartmenu"] && !isnull(cartridge)) + cartridge.Topic(href, href_list) + return 1 + if(href_list["radiomenu"] && !isnull(cartridge) && !isnull(cartridge.radio)) + cartridge.radio.Topic(href, href_list) + return 1 + + ..() + var/mob/user = usr + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") var/mob/living/U = usr //Looking for master was kind of pointless since PDAs don't appear to have one. //if ((src in U.contents) || ( istype(loc, /turf) && in_range(src, U) ) ) @@ -530,7 +524,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if("Close")//Self explanatory U.unset_machine() - U << browse(null, "window=pda") + ui.close() return if("Refresh")//Refresh, goes to the end of the proc. if("Return")//Return @@ -538,11 +532,12 @@ var/global/list/obj/item/device/pda/PDAs = list() 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 - cartridge.unlock() if ("Authenticate")//Checks for ID id_check(U, 1) if("UpdateInfo") @@ -554,6 +549,8 @@ var/global/list/obj/item/device/pda/PDAs = list() if(ismob(T)) T = T.loc cartridge.loc = T + ui.close() + mode = 0 scanmode = 0 if (cartridge.radio) cartridge.radio.hostpda = null @@ -625,57 +622,80 @@ var/global/list/obj/item/device/pda/PDAs = list() note = replacetext(n, "\n", "
    ") notehtml = n else - U << browse(null, "window=pda") - return + ui.close() if("Toggle Messenger") toff = !toff if("Toggle Ringer")//If viewing texts then erase them, if not then toggle silent status silent = !silent if("Clear")//Clears messages - tnote = null + 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") var/t = input(U, "Please enter new ringtone", name, ttone) as text if (in_range(src, U) && loc == U) if (t) if(src.hidden_uplink && hidden_uplink.check_trigger(U, lowertext(t), lowertext(lock_code))) U << "The PDA softly beeps." - U << browse(null, "window=pda") + ui.close() else t = copytext(sanitize(t), 1, 20) ttone = t else - U << browse(null, "window=pda") + ui.close() return if("Message") + var/obj/item/device/pda/P = locate(href_list["target"]) src.create_message(U, P) + if(mode == 2) + 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("Send Honk")//Honk virus if(istype(cartridge, /obj/item/weapon/cartridge/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:honk_charges > 0) - cartridge:honk_charges-- + if (!P.toff && cartridge.charges > 0) + cartridge.charges-- U.show_message("\blue Virus sent!", 1) P.honkamt = (rand(15,20)) else U << "PDA not found." else - U << browse(null, "window=pda") + ui.close() return if("Send Silence")//Silent virus if(istype(cartridge, /obj/item/weapon/cartridge/mime)) var/obj/item/device/pda/P = locate(href_list["target"]) if(!isnull(P)) - if (!P.toff && cartridge:mime_charges > 0) - cartridge:mime_charges-- + if (!P.toff && cartridge.charges > 0) + cartridge.charges-- U.show_message("\blue Virus sent!", 1) P.silent = 1 P.ttone = "silence" else U << "PDA not found." else - U << browse(null, "window=pda") + ui.close() return @@ -694,8 +714,8 @@ var/global/list/obj/item/device/pda/PDAs = list() if(istype(cartridge, /obj/item/weapon/cartridge/syndicate)) var/obj/item/device/pda/P = locate(href_list["target"]) if(!isnull(P)) - if (!P.toff && cartridge:shock_charges > 0) - cartridge:shock_charges-- + if (!P.toff && cartridge.charges > 0) + cartridge.charges-- var/difficulty = 0 @@ -712,7 +732,7 @@ var/global/list/obj/item/device/pda/PDAs = list() U.show_message("\red An error flashes on your [src].", 1) else if (prob(difficulty * 3)) U.show_message("\red Energy feeds back into your [src]!", 1) - U << browse(null, "window=pda") + ui.close() explode() 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, blowing themselves up", 1) @@ -725,7 +745,7 @@ var/global/list/obj/item/device/pda/PDAs = list() U << "PDA not found." else U.unset_machine() - U << browse(null, "window=pda") + ui.close() return //pAI FUNCTIONS=================================== @@ -737,33 +757,31 @@ var/global/list/obj/item/device/pda/PDAs = list() var/turf/T = get_turf_or_move(src.loc) if(T) pai.loc = T + pai = null -//LINK FUNCTIONS=================================== - - else//Cartridge menu linking + else mode = text2num(href_list["choice"]) - cartridge.mode = mode - cartridge.unlock() + if(cartridge) + cartridge.mode = mode + + else//If not in range or not using the pda. U.unset_machine() - U << browse(null, "window=pda") + ui.close() return //EXTRA FUNCTIONS=================================== if (mode == 2||mode == 21)//To clear message overlays. overlays.Cut() + newmessage = 0 if ((honkamt > 0) && (prob(60)))//For clown virus. honkamt-- playsound(loc, 'sound/items/bikehorn.ogg', 30, 1) - if(U.machine == src && href_list["skiprefresh"]!="1")//Final safety. - attack_self(U)//It auto-closes the menu prior if the user is not in range and so on. - else - U.unset_machine() - U << browse(null, "window=pda") - return + src.updateUsrDialog() + return 1 // return 1 tells it to refresh the UI in NanoUI /obj/item/device/pda/proc/remove_id() if (id) @@ -792,7 +810,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if(!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) @@ -822,23 +840,24 @@ var/global/list/obj/item/device/pda/PDAs = list() U << "ERROR: Cannot reach recepient." return useMS.send_pda_message("[P.owner]","[owner]","[t]") - - tnote += "→ To [P.owner]:
    [t]
    " - P.tnote += "← From
    [owner] ([ownjob]):
    [t]
    " - for(var/mob/M in player_list) - if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS)) // src.client is so that ghosts don't have to listen to mice - M.show_message("PDA Message - [owner] -> [P.owner]: [t]") + tnote.Add(list(list("sent" = 1, "owner" = "[P.owner]", "job" = "[P.ownjob]", "message" = "[t]", "target" = "\ref[P]"))) + P.tnote.Add(list(list("sent" = 0, "owner" = "[owner]", "job" = "[ownjob]", "message" = "[t]", "target" = "\ref[src]"))) + if(!conversations.Find("\ref[P]")) + conversations.Add("\ref[P]") + if(!P.conversations.Find("\ref[src]")) + P.conversations.Add("\ref[src]") if (prob(15)) //Give the AI a chance of intercepting the message var/who = src.owner if(prob(50)) - who = P:owner + who = P.owner for(var/mob/living/silicon/ai/ai in mob_list) // Allows other AIs to intercept the message but the AI won't intercept their own message. if(ai.aiPDA != P && ai.aiPDA != src) ai.show_message("Intercepted message from [who]: [t]") + if (!P.silent) playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, P.loc)) @@ -851,12 +870,14 @@ var/global/list/obj/item/device/pda/PDAs = list() else L = get(P, /mob/living/silicon) + if(L) L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)" log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]") P.overlays.Cut() P.overlays += image('icons/obj/pda.dmi', "pda-r") + P.newmessage = 1 else U << "ERROR: Messaging server is not responding." @@ -926,12 +947,15 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/attackby(obj/item/C as obj, mob/user as mob) ..() if(istype(C, /obj/item/weapon/cartridge) && !cartridge) + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") cartridge = C user.drop_item() cartridge.loc = src user << "You insert [cartridge] into [src]." if(cartridge.radio) cartridge.radio.hostpda = src + if(ui) + ui.close() else if(istype(C, /obj/item/weapon/card/id)) var/obj/item/weapon/card/id/idcard = C @@ -1045,9 +1069,6 @@ var/global/list/obj/item/device/pda/PDAs = list() if(5) if((istype(A, /obj/item/weapon/tank)) || (istype(A, /obj/machinery/portable_atmospherics))) - if(istype(A, /obj/item/weapon/tank)) - var/obj/item/weapon/tank/t = A - t.manipulated_by = user.real_name var/obj/icon = A for (var/mob/O in viewers(user, null)) O << "\red [user] has used [src] on \icon[icon] [A]" @@ -1138,8 +1159,8 @@ var/global/list/obj/item/device/pda/PDAs = list() return if ((istype(M, /mob/living/carbon/human) && (M.real_name != src.owner) && (istype(src.cartridge, /obj/item/weapon/cartridge/clown)))) - if (src.cartridge:honk_charges < 5) - src.cartridge:honk_charges++ + if (src.cartridge.charges < 5) + src.cartridge.charges++ M.stop_pulling() M << "\blue You slipped on the PDA!" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index f0e3ee98f17..02dbf86b921 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -21,6 +21,7 @@ var/access_status_display = 0 var/access_quartermaster = 0 var/access_hydroponics = 0 + var/charges = 0 var/mode = null var/menu var/datum/data/record/active1 = null //General @@ -32,575 +33,518 @@ var/message2 var/list/stored_data = list() - engineering - name = "Power-ON Cartridge" - icon_state = "cart-e" - access_engine = 1 +/obj/item/weapon/cartridge/engineering + name = "Power-ON Cartridge" + icon_state = "cart-e" + access_engine = 1 - atmos - name = "BreatheDeep Cartridge" - icon_state = "cart-a" - access_atmos = 1 +/obj/item/weapon/cartridge/atmos + name = "BreatheDeep Cartridge" + icon_state = "cart-a" + access_atmos = 1 - medical - name = "Med-U Cartridge" - icon_state = "cart-m" - access_medical = 1 +/obj/item/weapon/cartridge/medical + name = "Med-U Cartridge" + icon_state = "cart-m" + access_medical = 1 - chemistry - name = "ChemWhiz Cartridge" - icon_state = "cart-chem" - access_reagent_scanner = 1 +/obj/item/weapon/cartridge/chemistry + name = "ChemWhiz Cartridge" + icon_state = "cart-chem" + access_reagent_scanner = 1 - security - name = "R.O.B.U.S.T. Cartridge" - icon_state = "cart-s" - access_security = 1 +/obj/item/weapon/cartridge/security + name = "R.O.B.U.S.T. Cartridge" + icon_state = "cart-s" + access_security = 1 - New() - ..() - spawn(5) - radio = new /obj/item/radio/integrated/beepsky(src) +/obj/item/weapon/cartridge/security/New() + ..() + spawn(5) + radio = new /obj/item/radio/integrated/beepsky(src) - detective - name = "D.E.T.E.C.T. Cartridge" - icon_state = "cart-s" - access_security = 1 - access_medical = 1 +/obj/item/weapon/cartridge/detective + name = "D.E.T.E.C.T. Cartridge" + icon_state = "cart-s" + access_security = 1 + access_medical = 1 - janitor - name = "CustodiPRO Cartridge" - desc = "The ultimate in clean-room design." - icon_state = "cart-j" - access_janitor = 1 +/obj/item/weapon/cartridge/janitor + name = "CustodiPRO Cartridge" + desc = "The ultimate in clean-room design." + icon_state = "cart-j" + access_janitor = 1 - lawyer - name = "P.R.O.V.E. Cartridge" - icon_state = "cart-s" - access_security = 1 +/obj/item/weapon/cartridge/lawyer + name = "P.R.O.V.E. Cartridge" + icon_state = "cart-s" + access_security = 1 - clown - name = "Honkworks 5.0" - icon_state = "cart-clown" - access_clown = 1 - var/honk_charges = 5 +/obj/item/weapon/cartridge/clown + name = "Honkworks 5.0" + icon_state = "cart-clown" + access_clown = 1 + charges = 5 - mime - name = "Gestur-O 1000" - icon_state = "cart-mi" - access_mime = 1 - var/mime_charges = 5 +/obj/item/weapon/cartridge/mime + name = "Gestur-O 1000" + icon_state = "cart-mi" + access_mime = 1 + charges = 5 /* - botanist - name = "Green Thumb v4.20" - icon_state = "cart-b" - access_flora = 1 +/obj/item/weapon/cartridge/botanist + name = "Green Thumb v4.20" + icon_state = "cart-b" + access_flora = 1 */ - signal - name = "generic signaler cartridge" - desc = "A data cartridge with an integrated radio signaler module." - - toxins - name = "Signal Ace 2" - desc = "Complete with integrated radio signaler!" - icon_state = "cart-tox" - access_reagent_scanner = 1 - access_atmos = 1 - - New() - ..() - spawn(5) - radio = new /obj/item/radio/integrated/signal(src) - - - - quartermaster - name = "Space Parts & Space Vendors Cartridge" - desc = "Perfect for the Quartermaster on the go!" - icon_state = "cart-q" - access_quartermaster = 1 - - New() - ..() - spawn(5) - radio = new /obj/item/radio/integrated/mule(src) - - head - name = "Easy-Record DELUXE" - icon_state = "cart-h" - access_status_display = 1 - - hop - name = "HumanResources9001" - icon_state = "cart-h" - access_status_display = 1 - access_quartermaster = 1 - access_janitor = 1 - access_security = 1 - - New() - ..() - spawn(5) - radio = new /obj/item/radio/integrated/mule(src) - - hos - name = "R.O.B.U.S.T. DELUXE" - icon_state = "cart-hos" - access_status_display = 1 - access_security = 1 - - New() - ..() - spawn(5) - radio = new /obj/item/radio/integrated/beepsky(src) - - ce - name = "Power-On DELUXE" - icon_state = "cart-ce" - access_status_display = 1 - access_engine = 1 - access_atmos = 1 - - cmo - name = "Med-U DELUXE" - icon_state = "cart-cmo" - access_status_display = 1 - access_reagent_scanner = 1 - access_medical = 1 - - rd - name = "Signal Ace DELUXE" - icon_state = "cart-rd" - access_status_display = 1 - access_reagent_scanner = 1 - access_atmos = 1 - - New() - ..() - spawn(5) - radio = new /obj/item/radio/integrated/signal(src) - - captain - name = "Value-PAK Cartridge" - desc = "Now with 200% more value!" - icon_state = "cart-c" - access_engine = 1 - access_security = 1 - access_medical = 1 - access_reagent_scanner = 1 - access_status_display = 1 - access_atmos = 1 - - syndicate - name = "Detomatix Cartridge" - icon_state = "cart" - access_remote_door = 1 - remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing. - var/shock_charges = 4 - - proc/unlock() - if (!istype(loc, /obj/item/device/pda)) - return - - generate_menu() - print_to_host(menu) - return - - proc/print_to_host(var/text) - if (!istype(loc, /obj/item/device/pda)) - return - loc:cart = text - - for (var/mob/M in viewers(1, loc.loc)) - if (M.client && M.machine == loc) - loc:attack_self(M) - - return - - proc/post_status(var/command, var/data1, var/data2) - - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) - - if(!frequency) return - - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - - switch(command) - if("message") - status_signal.data["msg1"] = data1 - status_signal.data["msg2"] = data2 - if(loc) - var/obj/item/PDA = loc - var/mob/user = PDA.fingerprintslast - if(istype(PDA.loc,/mob/living)) - name = PDA.loc - log_admin("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") - message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") - - if("alert") - status_signal.data["picture_state"] = data1 - - frequency.post_signal(src, status_signal) - - proc/generate_menu() - switch(mode) - if(40) //signaller - menu = "

    Remote Signaling System

    " - - menu += {" -Send Signal
    -Frequency: -- -- -[format_frequency(radio:frequency)] -+ -+
    -
    -Code: -- -- -[radio:code] -+ -+
    "} - - if (42) //status displays - menu = "

    Station Status Display Interlink

    " - - menu += "\[ Clear \]
    " - menu += "\[ Shuttle ETA \]
    " - menu += "\[ Message \]" - menu += "
    " - menu += "\[ Alert: None |" - menu += " Red Alert |" - menu += " Lockdown |" - menu += " Biohazard \]
    " - - if (43) //Muskets' and Rockdtben's power monitor :D - menu = "

    Power Monitors - Please select one


    " - powmonitor = null - powermonitors = list() - var/powercount = 0 - - - - for(var/obj/machinery/power/monitor/pMon in world) - if(!(pMon.stat & (NOPOWER|BROKEN)) ) - powercount++ - powermonitors += pMon - - - if(!powercount) - menu += "\red No connection
    " - else - - menu += "" - var/count = 0 - for(var/obj/machinery/power/monitor/pMon in powermonitors) - count++ - menu += " [pMon]
    " - - menu += "
    " - - if (433) //Muskets' and Rockdtben's power monitor :D - menu = "

    Power Monitor


    " - if(!powmonitor) - menu += "\red No connection
    " - else - var/list/L = list() - for(var/obj/machinery/power/terminal/term in powmonitor.powernet.nodes) - if(istype(term.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/A = term.master - L += A - - menu += "
    Total power: [powmonitor.powernet.avail] W
    Total load: [num2text(powmonitor.powernet.viewload,10)] W
    " - - menu += "" - - if(L.len > 0) - menu += "Area Eqp./Lgt./Env. Load Cell
    " - - var/list/S = list(" Off","AOff"," On", " AOn") - var/list/chg = list("N","C","F") - - for(var/obj/machinery/power/apc/A in L) - menu += copytext(add_tspace(A.area.name, 30), 1, 30) - menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]
    " - - menu += "
    " - - if (44) //medical records //This thing only displays a single screen so it's hard to really get the sub-menu stuff working. - menu = "

    Medical Record List

    " - if(!isnull(data_core.general)) - for (var/datum/data/record/R in sortRecord(data_core.general)) - menu += "[R.fields["id"]]: [R.fields["name"]]
    " - menu += "
    " - if(441) - menu = "

    Medical Record

    " - - if (istype(active1, /datum/data/record) && (active1 in data_core.general)) - menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
    " - menu += "Sex: [active1.fields["sex"]]
    " - menu += "Age: [active1.fields["age"]]
    " - menu += "Rank: [active1.fields["rank"]]
    " - menu += "Fingerprint: [active1.fields["fingerprint"]]
    " - menu += "Physical Status: [active1.fields["p_stat"]]
    " - menu += "Mental Status: [active1.fields["m_stat"]]
    " - else - menu += "Record Lost!
    " - - menu += "
    " - - menu += "

    Medical Data

    " - if (istype(active2, /datum/data/record) && (active2 in data_core.medical)) - menu += "Blood Type: [active2.fields["b_type"]]

    " - - menu += "Minor Disabilities: [active2.fields["mi_dis"]]
    " - menu += "Details: [active2.fields["mi_dis_d"]]

    " - - menu += "Major Disabilities: [active2.fields["ma_dis"]]
    " - menu += "Details: [active2.fields["ma_dis_d"]]

    " - - menu += "Allergies: [active2.fields["alg"]]
    " - menu += "Details: [active2.fields["alg_d"]]

    " - - menu += "Current Diseases: [active2.fields["cdi"]]
    " - menu += "Details: [active2.fields["cdi_d"]]

    " - - menu += "Important Notes: [active2.fields["notes"]]
    " - else - menu += "Record Lost!
    " - - menu += "
    " - if (45) //security records - menu = "

    Security Record List

    " - if(!isnull(data_core.general)) - for (var/datum/data/record/R in sortRecord(data_core.general)) - menu += "
    [R.fields["id"]]: [R.fields["name"]]
    " - - menu += "
    " - if(451) - menu = "

    Security Record

    " - - if (istype(active1, /datum/data/record) && (active1 in data_core.general)) - menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
    " - menu += "Sex: [active1.fields["sex"]]
    " - menu += "Age: [active1.fields["age"]]
    " - menu += "Rank: [active1.fields["rank"]]
    " - menu += "Fingerprint: [active1.fields["fingerprint"]]
    " - menu += "Physical Status: [active1.fields["p_stat"]]
    " - menu += "Mental Status: [active1.fields["m_stat"]]
    " - else - menu += "Record Lost!
    " - - menu += "
    " - - menu += "

    Security Data

    " - if (istype(active3, /datum/data/record) && (active3 in data_core.security)) - menu += "Criminal Status: [active3.fields["criminal"]]
    " - - menu += "Minor Crimes: [active3.fields["mi_crim"]]
    " - menu += "Details: [active3.fields["mi_crim"]]

    " - - menu += "Major Crimes: [active3.fields["ma_crim"]]
    " - menu += "Details: [active3.fields["ma_crim_d"]]

    " - - menu += "Important Notes:
    " - menu += "[active3.fields["notes"]]" - else - menu += "Record Lost!
    " - - menu += "
    " - if (46) //beepsky control - var/obj/item/radio/integrated/beepsky/SC = radio - if(!SC) - menu = "Interlink Error - Please reinsert cartridge." - return - - menu = "

    Securitron Interlink

    " - - if(!SC.active) - // list of bots - if(!SC.botlist || (SC.botlist && SC.botlist.len==0)) - menu += "No bots found.
    " - - else - for(var/obj/machinery/bot/B in SC.botlist) - if (B) - menu += "
    [B] at [B.loc.loc]
    " - - menu += "
    Scan for active bots
    " - - else // bot selected, control it - - menu += "[SC.active]
    Status: (refresh)
    " - - if(!SC.botstatus) - menu += "Waiting for response...
    " - else - - menu += "Location: [SC.botstatus["loca"] ]
    " - menu += "Mode: " - - switch(SC.botstatus["mode"]) - if(0) - menu += "Ready" - if(1) - menu += "Apprehending target" - if(2,3) - menu += "Arresting target" - if(4) - menu += "Starting patrol" - if(5) - menu += "On patrol" - if(6) - menu += "Responding to summons" - - menu += "
    \[Stop Patrol\] " - menu += "\[Start Patrol\] " - menu += "\[Summon Bot\]
    " - menu += "
    Return to bot list" - - if (47) //quartermaster order records - menu = "

    Supply Record Interlink

    " - - menu += "
    Supply shuttle
    " - menu += "Location: [supply_shuttle.moving ? "Moving to station ([supply_shuttle.eta] Mins.)":supply_shuttle.at_station ? "Station":"Dock"]
    " - menu += "Current approved orders:
      " - for(var/S in supply_shuttle.shoppinglist) - var/datum/supply_order/SO = S - menu += "
    1. #[SO.ordernum] - [SO.object.name] approved by [SO.orderedby] [SO.comment ? "([SO.comment])":""]
    2. " - menu += "
    " - - menu += "Current requests:
      " - for(var/S in supply_shuttle.requestlist) - var/datum/supply_order/SO = S - menu += "
    1. #[SO.ordernum] - [SO.object.name] requested by [SO.orderedby]
    2. " - menu += "
    Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management." - - if (48) //mulebot control - var/obj/item/radio/integrated/mule/QC = radio - if(!QC) - menu = "Interlink Error - Please reinsert cartridge." - return - - menu = "

    M.U.L.E. bot Interlink V0.8

    " - - if(!QC.active) - // list of bots - if(!QC.botlist || (QC.botlist && QC.botlist.len==0)) - menu += "No bots found.
    " - - else - for(var/obj/machinery/bot/mulebot/B in QC.botlist) - menu += "[B] at [get_area(B)]
    " - menu += "
    Scan for active bots
    " - - else // bot selected, control it - - menu += "[QC.active]
    Status: (refresh)
    " - - if(!QC.botstatus) - menu += "Waiting for response...
    " - else - - menu += "Location: [QC.botstatus["loca"] ]
    " - menu += "Mode: " - - switch(QC.botstatus["mode"]) - if(0) - menu += "Ready" - if(1) - menu += "Loading/Unloading" - if(2) - menu += "Navigating to Delivery Location" - if(3) - menu += "Navigating to Home" - if(4) - menu += "Waiting for clear path" - if(5,6) - menu += "Calculating navigation path" - if(7) - menu += "Unable to locate destination" - var/obj/structure/closet/crate/C = QC.botstatus["load"] - menu += "
    Current Load: [ !C ? "none" : "[C.name] (unload)" ]
    " - menu += "Destination: [!QC.botstatus["dest"] ? "none" : QC.botstatus["dest"] ] (set)
    " - menu += "Power: [QC.botstatus["powr"]]%
    " - menu += "Home: [!QC.botstatus["home"] ? "none" : QC.botstatus["home"] ]
    " - menu += "Auto Return Home: [QC.botstatus["retn"] ? "On Off" : "(On) Off"]
    " - menu += "Auto Pickup Crate: [QC.botstatus["pick"] ? "On Off" : "(On) Off"]

    " - - menu += "\[Stop\] " - menu += "\[Proceed\] " - menu += "\[Return Home\]
    " - menu += "
    Return to bot list" - - if (49) //janitorial locator - menu = "

    Persistent Custodial Object Locator

    " - - var/turf/cl = get_turf(src) - if (cl) - menu += "Current Orbital Location: \[[cl.x],[cl.y]\]" - - menu += "

    Located Mops:

    " - - var/ldat - for (var/obj/item/weapon/mop/M in world) - var/turf/ml = get_turf(M) - - if(ml) - if (ml.z != cl.z) - continue - var/direction = get_dir(src, M) - ldat += "Mop - \[[ml.x],[ml.y] ([uppertext(dir2text(direction))])\] - [M.reagents.total_volume ? "Wet" : "Dry"]
    " - - if (!ldat) - menu += "None" - else - menu += "[ldat]" - - menu += "

    Located Mop Buckets:

    " - - ldat = null - for (var/obj/structure/mopbucket/B in world) - var/turf/bl = get_turf(B) - - if(bl) - if (bl.z != cl.z) - continue - var/direction = get_dir(src, B) - ldat += "Bucket - \[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\] - Water level: [B.reagents.total_volume]/100
    " - - if (!ldat) - menu += "None" - else - menu += "[ldat]" - - menu += "

    Located Cleanbots:

    " - - ldat = null - for (var/obj/machinery/bot/cleanbot/B in world) - var/turf/bl = get_turf(B) - - if(bl) - if (bl.z != cl.z) - continue - var/direction = get_dir(src, B) - ldat += "Cleanbot - \[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\] - [B.on ? "Online" : "Offline"]
    " - - if (!ldat) - menu += "None" - else - menu += "[ldat]" - - else - menu += "ERROR: Unable to determine current location." - menu += "

    Refresh GPS Locator" +/obj/item/weapon/cartridge/signal + name = "generic signaler cartridge" + desc = "A data cartridge with an integrated radio signaler module." + +/obj/item/weapon/cartridge/signal/toxins + name = "Signal Ace 2" + desc = "Complete with integrated radio signaler!" + icon_state = "cart-tox" + access_reagent_scanner = 1 + access_atmos = 1 + +/obj/item/weapon/cartridge/signal/New() + ..() + spawn(5) + radio = new /obj/item/radio/integrated/signal(src) + + + +/obj/item/weapon/cartridge/quartermaster + name = "Space Parts & Space Vendors Cartridge" + desc = "Perfect for the Quartermaster on the go!" + icon_state = "cart-q" + access_quartermaster = 1 + +/obj/item/weapon/cartridge/quartermaster/New() + ..() + spawn(5) + radio = new /obj/item/radio/integrated/mule(src) + +/obj/item/weapon/cartridge/head + name = "Easy-Record DELUXE" + icon_state = "cart-h" + access_status_display = 1 + +/obj/item/weapon/cartridge/hop + name = "HumanResources9001" + icon_state = "cart-h" + access_status_display = 1 + access_quartermaster = 1 + access_janitor = 1 + access_security = 1 + +/obj/item/weapon/cartridge/hop/New() + ..() + spawn(5) + radio = new /obj/item/radio/integrated/mule(src) + +/obj/item/weapon/cartridge/hos + name = "R.O.B.U.S.T. DELUXE" + icon_state = "cart-hos" + access_status_display = 1 + access_security = 1 + +/obj/item/weapon/cartridge/hos/New() + ..() + spawn(5) + radio = new /obj/item/radio/integrated/beepsky(src) + +/obj/item/weapon/cartridge/ce + name = "Power-On DELUXE" + icon_state = "cart-ce" + access_status_display = 1 + access_engine = 1 + access_atmos = 1 + +/obj/item/weapon/cartridge/cmo + name = "Med-U DELUXE" + icon_state = "cart-cmo" + access_status_display = 1 + access_reagent_scanner = 1 + access_medical = 1 + +/obj/item/weapon/cartridge/rd + name = "Signal Ace DELUXE" + icon_state = "cart-rd" + access_status_display = 1 + access_reagent_scanner = 1 + access_atmos = 1 + +/obj/item/weapon/cartridge/rd/New() + ..() + spawn(5) + radio = new /obj/item/radio/integrated/signal(src) + +/obj/item/weapon/cartridge/captain + name = "Value-PAK Cartridge" + desc = "Now with 200% more value!" + icon_state = "cart-c" + access_quartermaster = 1 + access_janitor = 1 + access_engine = 1 + access_security = 1 + access_medical = 1 + access_reagent_scanner = 1 + access_status_display = 1 + access_atmos = 1 + +/obj/item/weapon/cartridge/syndicate + name = "Detomatix Cartridge" + icon_state = "cart" + access_remote_door = 1 + remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing. + charges = 4 + +/obj/item/weapon/cartridge/proc/post_status(var/command, var/data1, var/data2) + + var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + if(!frequency) return + + var/datum/signal/status_signal = new + status_signal.source = src + status_signal.transmission_method = 1 + status_signal.data["command"] = command + + switch(command) + if("message") + status_signal.data["msg1"] = data1 + status_signal.data["msg2"] = data2 + if(loc) + var/obj/item/PDA = loc + var/mob/user = PDA.fingerprintslast + if(istype(PDA.loc,/mob/living)) + name = PDA.loc + log_admin("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") + message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]") + + if("alert") + status_signal.data["picture_state"] = data1 + + frequency.post_signal(src, status_signal) + + +/* + This generates the nano values of the cart menus. + Because we close the UI when we insert a new cart + we don't have to worry about null values on items + the user can't access. Well, unless they are href hacking. + But in that case their UI will just lock up. +*/ + + +/obj/item/weapon/cartridge/proc/create_NanoUI_values(mob/user as mob) + var/obj/item/device/pda/PDA = loc + var/datum/nanoui/ui = nanomanager.get_open_ui(user, PDA, "main") + var/values[0] + + /* Signaler (Mode: 40) */ + + + if(istype(radio,/obj/item/radio/integrated/signal) && (mode==40 || !ui )) + var/obj/item/radio/integrated/signal/R = radio + values["signal_freq"] = format_frequency(R.frequency) + values["signal_code"] = R.code + + + /* Station Display (Mode: 42) */ + + if(mode==42 || !ui) + values["message1"] = message1 ? message1 : "(none)" + values["message2"] = message2 ? message2 : "(none)" + + + + /* Power Monitor (Mode: 43 / 433) */ + if(mode==43 || mode==433 || !ui) + var/pMonData[0] + for(var/obj/machinery/power/monitor/pMon in world) + if(!(pMon.stat & (NOPOWER|BROKEN)) ) + pMonData[++pMonData.len] = list ("Name" = pMon.name, "ref" = "\ref[pMon]") + if(isnull(powmonitor)) powmonitor = pMon + + values["powermonitors"] = pMonData + + values["poweravail"] = powmonitor.powernet.avail + values["powerload"] = num2text(powmonitor.powernet.viewload,10) + + var/list/L = list() + for(var/obj/machinery/power/terminal/term in powmonitor.powernet.nodes) + if(istype(term.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/A = term.master + L += A + + var/list/Status = list(0,0,1,1) // Status: off, auto-off, on, auto-on + var/list/chg = list(0,1,1) // Charging: nope, charging, full + var/apcData[0] + for(var/obj/machinery/power/apc/A in L) + apcData[++apcData.len] = list("Name" = html_encode(A.area.name), "Equipment" = Status[A.equipment+1], "Lights" = Status[A.lighting+1], "Environment" = Status[A.environ+1], "CellPct" = A.cell ? round(A.cell.percent(),1) : -1, "CellStatus" = A.cell ? chg[A.charging+1] : 0) + + values["apcs"] = apcData + + + + + + /* General Records (Mode: 44 / 441 / 45 / 451) */ + if(mode == 44 || mode == 441 || mode == 45 || mode ==451 || !ui) + if(istype(active1, /datum/data/record) && (active1 in data_core.general)) + values["general"] = active1.fields + values["general_exists"] = 1 + + else + + values["general"] = list("name" = null,\ + "id" = null,\ + "sex" = null,\ + "species" = null,\ + "age" = null,\ + "rank" = null,\ + "fingerprint" = null,\ + "p_stat" = null,\ + "m_stat" = null,\ + ) + values["general_exists"] = 0 + + + + /* Medical Records (Mode: 44 / 441) */ + + if(mode == 44 || mode == 441 || !ui) + var/medData[0] + for(var/datum/data/record/R in sortRecord(data_core.general)) + medData[++medData.len] = list(Name = R.fields["name"],"ref" = "\ref[R]") + values["medical_records"] = medData + + if(istype(active2, /datum/data/record) && (active2 in data_core.medical)) + values["medical"] = active2.fields + values["medical_exists"] = 1 + else + values["medical"] = list(\ + "b_type" = null,\ + "mi_dis" = null,\ + "mi_dis_d" = null,\ + "ma_dis" = null,\ + "ma_dis_d" = null,\ + "alg" = null,\ + "alg_d" = null,\ + "cdi" = null,\ + "cdi_d" = null,\ + "notes" = null,\ + ) + values["medical_exists"] = 0 + + /* Security Records (Mode:45 / 451) */ + + if(mode == 45 || mode == 451 || !ui) + var/secData[0] + for (var/datum/data/record/R in sortRecord(data_core.general)) + secData[++secData.len] = list(Name = R.fields["name"], "ref" = "\ref[R]") + values["security_records"] = secData + + if(istype(active3, /datum/data/record) && (active3 in data_core.security)) + values["security"] = active3.fields + values["security_exists"] = 1 + else + values["security"] = list(\ + "criminal" = null,\ + "mi_crim" = null,\ + "ma_crim" = null,\ + "ma_crim_d" = null,\ + "notes"\ + ) + values["security_exists"] = 0 + + /* Security Bot Control (Mode: 46) */ + + if(mode==46 || !ui) + var/botsData[0] + var/beepskyData[0] + if(istype(radio,/obj/item/radio/integrated/beepsky)) + var/obj/item/radio/integrated/beepsky/SC = radio + beepskyData["active"] = SC.active + if(SC.active && !isnull(SC.botstatus)) + var/area/loca = SC.botstatus["loca"] + var/loca_name = sanitize(loca.name) + beepskyData["botstatus"] = list("loca" = loca_name, "mode" = SC.botstatus["mode"]) + else + beepskyData["botstatus"] = list("loca" = null, "mode" = -1) + var/botsCount=0 + if(SC.botlist && SC.botlist.len) + for(var/obj/machinery/bot/B in SC.botlist) + botsCount++ + if(B.loc) + botsData[++botsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]") + + if(!botsData.len) + botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + + beepskyData["bots"] = botsData + beepskyData["count"] = botsCount + + else + beepskyData["active"] = 0 + botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + beepskyData["botstatus"] = list("loca" = null, "mode" = null) + beepskyData["bots"] = botsData + beepskyData["count"] = 0 + + values["beepsky"] = beepskyData + + + /* MULEBOT Control (Mode: 48) */ + + if(mode==48 || !ui) + var/muleData[0] + var/mulebotsData[0] + if(istype(radio,/obj/item/radio/integrated/mule)) + var/obj/item/radio/integrated/mule/QC = radio + muleData["active"] = QC.active + if(QC.active && !isnull(QC.botstatus)) + var/area/loca = QC.botstatus["loca"] + var/loca_name = sanitize(loca.name) + muleData["botstatus"] = list("loca" = loca_name, "mode" = QC.botstatus["mode"],"home"=QC.botstatus["home"],"powr" = QC.botstatus["powr"],"retn" =QC.botstatus["retn"], "pick"=QC.botstatus["pick"], "load" = QC.botstatus["load"], "dest" = sanitize(QC.botstatus["dest"])) + + else + muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null) + + + var/mulebotsCount=0 + for(var/obj/machinery/bot/B in QC.botlist) + mulebotsCount++ + if(B.loc) + mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]") + + if(!mulebotsData.len) + mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + + muleData["bots"] = mulebotsData + muleData["count"] = mulebotsCount + + else + muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null) + muleData["active"] = 0 + mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null) + muleData["bots"] = mulebotsData + muleData["count"] = 0 + + values["mulebot"] = muleData + + + + /* Supply Shuttle Requests Menu (Mode: 47) */ + + if(mode==47 || !ui) + var/supplyData[0] + supplyData["shuttle_moving"] = supply_shuttle.moving + supplyData["shuttle_eta"] = supply_shuttle.eta + supplyData["shuttle_loc"] = supply_shuttle.at_station ? "Station" : "Dock" + var/supplyOrderCount = 0 + var/supplyOrderData[0] + for(var/S in supply_shuttle.shoppinglist) + var/datum/supply_order/SO = S + + supplyOrderData[++supplyOrderData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "ApprovedBy" = SO.orderedby, "Comment" = html_encode(SO.comment)) + if(!supplyOrderData.len) + supplyOrderData[++supplyOrderData.len] = list("Number" = null, "Name" = null, "OrderedBy"=null) + + supplyData["approved"] = supplyOrderData + supplyData["approved_count"] = supplyOrderCount + + var/requestCount = 0 + var/requestData[0] + for(var/S in supply_shuttle.requestlist) + var/datum/supply_order/SO = S + requestCount++ + requestData[++requestData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "OrderedBy" = SO.orderedby, "Comment" = html_encode(SO.comment)) + if(!requestData.len) + requestData[++requestData.len] = list("Number" = null, "Name" = null, "orderedBy" = null, "Comment" = null) + + supplyData["requests"] = requestData + supplyData["requests_count"] = requestCount + + + values["supply"] = supplyData + + + + /* Janitor Supplies Locator (Mode: 49) */ + if(mode==49 || !ui) + var/JaniData[0] + var/turf/cl = get_turf(src) + + if(cl) + JaniData["user_loc"] = list("x" = cl.x, "y" = cl.y) + else + JaniData["user_loc"] = list("x" = 0, "y" = 0) + var/MopData[0] + for(var/obj/item/weapon/mop/M in world) + var/turf/ml = get_turf(M) + if(ml) + if(ml.z != cl.z) + continue + var/direction = get_dir(src, M) + MopData[++MopData.len] = list ("x" = ml.x, "y" = ml.y, "dir" = uppertext(dir2text(direction)), "status" = M.reagents.total_volume ? "Wet" : "Dry") + + if(!MopData.len) + MopData[++MopData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + + + var/BucketData[0] + for(var/obj/structure/mopbucket/B in world) + var/turf/bl = get_turf(B) + if(bl) + if(bl.z != cl.z) + continue + var/direction = get_dir(src,B) + BucketData[++BucketData.len] = list ("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100) + + if(!BucketData.len) + BucketData[++BucketData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + + var/CbotData[0] + for(var/obj/machinery/bot/cleanbot/B in world) + var/turf/bl = get_turf(B) + if(bl) + if(bl.z != cl.z) + continue + var/direction = get_dir(src,B) + CbotData[++CbotData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.on ? "Online" : "Offline") + + + if(!CbotData.len) + CbotData[++CbotData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + var/CartData[0] + for(var/obj/structure/janitorialcart/B in world) + var/turf/bl = get_turf(B) + if(bl) + if(bl.z != cl.z) + continue + var/direction = get_dir(src,B) + CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100) + if(!CartData.len) + CartData[++CartData.len] = list("x" = 0, "y" = 0, dir=null, status = null) + + + + + JaniData["mops"] = MopData + JaniData["buckets"] = BucketData + JaniData["cleanbots"] = CbotData + JaniData["carts"] = CartData + values["janitor"] = JaniData + + return values + + + /obj/item/weapon/cartridge/Topic(href, href_list) @@ -611,6 +555,9 @@ Code: usr << browse(null, "window=pda") return + + + switch(href_list["choice"]) if("Medical Records") var/datum/data/record/R = locate(href_list["target"]) @@ -668,10 +615,9 @@ Code: else post_status(href_list["statdisp"]) if("Power Select") - var/pnum = text2num(href_list["target"]) - powmonitor = powermonitors[pnum] + var/pref = href_list["target"] + powmonitor = locate(pref) loc:mode = 433 mode = 433 - generate_menu() - print_to_host(menu) + return 1 diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm index 45bcff1c052..9dc462814e4 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/game/objects/items/devices/PDA/radio.dm @@ -31,15 +31,6 @@ frequency.post_signal(src, signal, filter = s_filter) - proc/print_to_host(var/text) - if (isnull(src.hostpda)) - return - src.hostpda.cart = text - - for (var/mob/M in viewers(1, src.hostpda.loc)) - if (M.client && M.machine == src.hostpda) - src.hostpda.cartridge.unlock() - return proc/generate_menu() @@ -107,7 +98,6 @@ if("summon") post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(PDA) , s_filter = RADIO_SECBOT) post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT) - PDA.cartridge.unlock() /obj/item/radio/integrated/mule var/list/botlist = null // list of bots @@ -163,7 +153,6 @@ Topic(href, href_list) ..() - var/obj/item/device/pda/PDA = src.hostpda var/cmd = "command" if(active) cmd = "command [active.suffix]" @@ -208,7 +197,6 @@ if("stop", "go", "home") post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT) post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT) - PDA.cartridge.unlock() diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index ebe7b751de0..e04ab62671e 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -12,6 +12,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid var/item_data // raw item text var/list/ItemList // Parsed list of items var/uses // Numbers of crystals + var/nanoui_items[0] // List of items not to shove in their hands. var/list/NotInHand = list(/obj/machinery/singularity_beacon/syndicate) @@ -23,6 +24,39 @@ A list of items and costs is stored under the datum of every game mode, alongsid items = replacetext(item_data) ItemList = text2list(src.items, ";") // Parsing the items text string uses = ticker.mode.uplink_uses + nanoui_items = generate_nanoui_items() + +/* + Built the Items List for use with NanoUI +*/ + +/obj/item/device/uplink/proc/generate_nanoui_items() + var/items_nano[0] + for(var/D in ItemList) + var/list/O = stringsplit(D, ":") + if(O.len != 3) //If it is not an actual item, make a break in the menu. + if(O.len == 1) //If there is one item, it's probably a title + items_nano[++items_nano.len] = list("Category" = "[O[1]]", "items" = list()) + continue + + var/path_text = O[1] + var/cost = text2num(O[2]) + + var/path_obj = text2path(path_text) + + // Because we're using strings, this comes up if item paths change. + // Failure to handle this error borks uplinks entirely. -Sayu + if(!path_obj) + error("Syndicate item is not a valid path: [path_text]") + else + var/itemname = O[3] + items_nano[items_nano.len]["items"] += list(list("Name" = itemname, "Cost" = cost, "obj_path" = path_text)) + + return items_nano + + + + //Let's build a menu! /obj/item/device/uplink/proc/generate_menu() @@ -230,8 +264,8 @@ A list of items and costs is stored under the datum of every game mode, alongsid feedback_add_details("traitor_uplink_items_bought","ST") /obj/item/device/uplink/Topic(href, href_list) - if (href_list["buy_item"]) + if(href_list["buy_item"] == "random") var/boughtItem = chooseRandomItem() if(boughtItem) @@ -299,31 +333,48 @@ A list of items and costs is stored under the datum of every game mode, alongsid return 1 return 0 -// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button. -/obj/item/device/uplink/hidden/interact(mob/user as mob) +/* + NANO UI FOR UPLINK WOOP WOOP +*/ +/obj/item/device/uplink/hidden/ui_interact(mob/user, ui_key = "main") + var/title = "Syndicate Uplink" + var/data[0] + + data["crystals"] = uses + data["nano_items"] = nanoui_items + data["welcome"] = welcome - var/dat = "" - dat += src.generate_menu() - dat += "Lock" - dat += "" - user << browse(dat, "window=hidden") - onclose(user, "hidden") - return + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key) + if (!ui) + // the ui does not exist, so we'll create a new one + ui = new(user, src, ui_key, "uplink.tmpl", title, 450, 600) + // When the UI is first opened this is the data it will use + ui.set_initial_data(data) + ui.open() + else + // The UI is already open so push the new data to it + ui.push_data(data) + return + +// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button. +/obj/item/device/uplink/hidden/interact(mob/user) + + ui_interact(user) // The purchasing code. /obj/item/device/uplink/hidden/Topic(href, href_list) - if (usr.stat || usr.restrained()) return if (!( istype(usr, /mob/living/carbon/human))) return 0 - + var/mob/user = usr + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf)))) usr.set_machine(src) if(href_list["lock"]) toggle() - usr << browse(null, "window=hidden") + ui.close() return 1 if(..(href, href_list) == 1) @@ -334,7 +385,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid A.put_in_any_hand_if_possible(I) purchase_log += "[usr] ([usr.ckey]) bought [I]." interact(usr) - return + return 1 // I placed this here because of how relevant it is. // You place this in your uplinkable item to check if an uplink is active or not. diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 95c5d638406..eabee2ba46d 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -254,13 +254,17 @@ 'nano/templates/geoscanner.tmpl', 'nano/templates/dna_modifier.tmpl', 'nano/templates/telescience_console.tmpl', + 'nano/templates/pda.tmpl', + 'nano/templates/uplink.tmpl', 'nano/images/uiBackground.png', 'nano/images/uiIcons16.png', 'nano/images/uiIcons24.png', + 'nano/images/uiBackground-Syndicate.png', 'nano/images/uiLinkPendingIcon.gif', 'nano/images/uiMaskBackground.png', 'nano/images/uiNoticeBackground.jpg', 'nano/images/uiTitleFluff.png', + 'nano/images/uiTitleFluff-Syndicate.png', 'html/search.js', 'html/panels.css', 'icons/pda_icons/pda_atmos.png', diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 474e955f57a..a6a73004698 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -136,10 +136,13 @@ nanoui is used to open and update nano browser uis close() return + if ((allowed_user_stat > -1) && (user.stat > allowed_user_stat)) set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) else if (user.restrained() || user.lying) set_status(STATUS_UPDATE, push_update) // update only (orange visibility) + else if (istype(src_object, /obj/item/device/uplink/hidden)) // You know what if they have the uplink open let them use the UI + set_status(STATUS_INTERACTIVE, push_update) // Will build in distance checks on the topics for sanity. else if (!(src_object in view(4, user))) // If the src object is not in visable, set status to 0 set_status(STATUS_DISABLED, push_update) // interactive (green visibility) else if (dist <= 1) diff --git a/nano/css/shared.css b/nano/css/shared.css index 5d41a4f330f..241ec579ab6 100644 --- a/nano/css/shared.css +++ b/nano/css/shared.css @@ -23,7 +23,9 @@ hr { padding: 0px 4px 4px 4px; margin: 0 2px 2px 0; cursor:default; + white-space: nowrap; } + .hasIcon { padding: 0px 4px 4px 0px; } @@ -138,6 +140,12 @@ h4 { clear: both; padding: 8px; } + +.white { + color: white; + font-weight: bold; +} + .good { color: #4f7529; font-weight: bold; @@ -192,6 +200,8 @@ div.notice { margin: 4px 0 0 0; clear: both; } + + .itemLabel { float: left; width: 30%; @@ -206,6 +216,13 @@ div.notice { width: 20%; color: #e9c183; } +.itemLabelWide { + float: left; + width: 45%; + color: #e9c183; +} + + .itemContentWide { float: left; width: 79%; @@ -214,6 +231,11 @@ div.notice { float: left; width: 33%; } +.itemContentMedium { + float: left; + width: 55%; +} + .statusDisplay { background: #000000; color: #ffffff; @@ -221,6 +243,17 @@ div.notice { padding: 4px; margin: 3px 0; } +.statusDisplayRecords { + background: #000000; + color: #ffffff; + border: 1px solid #40628a; + padding: 4px; + margin: 3px 0; + overflow-x: hidden; + overflow-y: auto; +} + + .statusLabel { width: 138px; float: left; @@ -307,7 +340,17 @@ div.notice { float: left; } .fixedLeftWide { - width: 150px; + width: 165px; + float: left; +} + +.fixedLeftWider{ + width: 220px; + float: left; +} + +.fixedLeftWidest{ + width: 250px; float: left; } @@ -315,6 +358,24 @@ div.notice { float: right; } +/* Used in PDA */ + + +.wholeScreen +{ + position: absolute + color: #517087; + font-size: 16px; + font-weight: bold; + text-align:center; +} + +.pdalink +{ + float: left; + white-space:nowrap; +} + /* DNA Modifier UI (dna_modifier.tmpl) */ .dnaBlock @@ -363,3 +424,67 @@ div.notice { margin: 200px 0; text-align: center; } + +/* Table stuffs for power monitor */ +table.pmon +{ +border:2px solid RoyalBlue; +} + +table.pmon td, table.pmon th +{ +border-bottom:1px dotted black; +padding:0px 5px 0px 5px; +} + + + +/* Table Stuffs for manifest*/ + +th.command +{ + background: #3333FF; + font-weight: bold; + color: #ffffff; +} + +th.sec +{ + background: #8e0000; + font-weight: bold; + color: #ffffff; +} +th.med +{ + background: #006600; + font-weight: bold; + color: #ffffff; +} +th.eng +{ + background: #b27300; + font-weight: bold; + color: #ffffff; +} +th.sci +{ + background: #a65ba6; + font-weight: bold; + color: #ffffff; +} +th.civ +{ + background: #a32800; + font-weight: bold; + color: #ffffff; +} +th.misc +{ + background: #666666; + font-weight: bold; + color: #ffffff; +} + + + + diff --git a/nano/images/uiBackground-Syndicate.png b/nano/images/uiBackground-Syndicate.png new file mode 100644 index 00000000000..3ca932cb835 Binary files /dev/null and b/nano/images/uiBackground-Syndicate.png differ diff --git a/nano/images/uiBackground-Syndicate.xcf b/nano/images/uiBackground-Syndicate.xcf new file mode 100644 index 00000000000..c86cea69d14 Binary files /dev/null and b/nano/images/uiBackground-Syndicate.xcf differ diff --git a/nano/images/uiTitleFluff-Syndicate.png b/nano/images/uiTitleFluff-Syndicate.png new file mode 100644 index 00000000000..b09f5ba6b29 Binary files /dev/null and b/nano/images/uiTitleFluff-Syndicate.png differ diff --git a/nano/js/nano_base_helpers.js b/nano/js/nano_base_helpers.js index ef34bd506a4..338be422562 100644 --- a/nano/js/nano_base_helpers.js +++ b/nano/js/nano_base_helpers.js @@ -15,6 +15,20 @@ NanoBaseHelpers = function () var initHelpers = function () { $.views.helpers({ + + syndicateMode: function() { + $('body').css("background-color","#8f1414"); + $('body').css("background-image","url('uiBackground-Syndicate.png')"); + $('body').css("background-position","50% 0"); + $('body').css("background-repeat","repeat-x"); + + $('#uiTitleFluff').css("background-image","url('uiTitleFluff-Syndicate.png')"); + $('#uiTitleFluff').css("background-position","50% 50%"); + $('#uiTitleFluff').css("background-repeat", "no-repeat"); + + return ''; + }, + // Generate a Byond link link: function( text, icon, parameters, status, elementClass, elementId) { diff --git a/nano/templates/pda.tmpl b/nano/templates/pda.tmpl new file mode 100644 index 00000000000..2494983f087 --- /dev/null +++ b/nano/templates/pda.tmpl @@ -0,0 +1,930 @@ + + +{^{if owner}} +
    +
    + Functions: +
    +
    + {^{:~link('Refresh', 'refresh', {'choice' : "Refresh"}, null, 'fixedLeft')}} + {^{:~link('Close', 'gear', {'choice' : "Close"}, null, 'fixedLeft')}} + {^{if idInserted}} {^{:~link('Update PDA Info', 'eject', {'choice' : "UpdateInfo"}, null, 'fixedLeftWide')}} {{/if}} + {^{if mode != 0}} {^{:~link('Return', 'arrowreturn-1-w', {'choice' : "Return"}, null, 'fixedLeft')}} {{/if}} +
    +
    +
    +
    +
    + Station Time: +
    +
    + {^{:stationTime}} +
    +
    +
    + {^{if mode == 0}} +
    +
    + Owner: +
    +
    + {^{:owner}}, {^{:ownjob}} +
    +
    +
    +
    +
    + ID: +
    +
    + {^{:~link(idLink, 'eject', {'choice' : "Authenticate"}, idInserted ? null : 'disabled', idInserted ? 'fixedLeftWidest' : 'fixedLeft')}} +
    +
    +
    +
    +
    + Cartridge: +
    +
    + {^{:~link(cartridge ? cartridge.name : 'no cartridge', 'eject', {'choice' : "Eject"}, cartridge ? null : 'disabled', cartridge ? 'fixedLeftWider' : 'fixedLeft')}} +
    +
    +
    +

    Functions

    +
    +
    +
    + General: +
    +
    + {^{:~link('Notekeeper', 'note', {'choice' : "1"},null, 'fixedLeftWide')}} + {^{:~link('Messenger', newMessage ? 'mail-closed' : 'mail-open', {'choice' : "2"},null, 'fixedLeftWide')}} + {^{:~link('Crew Manifest', 'contact', {'choice' : "41"},null, 'fixedLeftWide')}} +
    +
    +
    + {^{if cartridge}} + {^{if cartridge.access.access_clown == 1}} +
    +
    + Clown: +
    +
    + {^{:~link('Honk Synthesizer', 'gear', {'choice' : "Honk"},null, 'fixedLeftWide')}} +
    +
    +
    + {{/if}} + {^{if cartridge.access.access_engine == 1}} +
    +
    + Engineering: +
    +
    + {^{:~link('Power Monitor', 'alert', {'choice' : "43"},null, 'fixedLeftWide')}} +
    +
    +
    + {{/if}} + {^{if cartridge.access.access_medical == 1}} +
    +
    + Medical: +
    +
    + {^{:~link('Medical Records', 'gear', {'choice' : "44"},null, 'fixedLeftWide')}} + {^{:~link(scanmode == 1 ? 'Disable Med Scanner' : 'Enable Med Scanner', 'gear', {'choice' : "Medical Scan"},null , 'fixedLeftWide')}} +
    +
    +
    + {{/if}} + {^{if cartridge.access.access_security == 1}} +
    +
    + Security: +
    +
    + {^{:~link('Security Records', 'gear', {'choice' : "45"},null, 'fixedLeftWide')}} + {^{if cartridge.radio ==1}} {^{:~link('Security Bot Access', 'gear', {'choice' : "46"},null, 'fixedLeftWide')}} {{/if}} +
    +
    +
    +
    + {{/if}} + {^{if cartridge.access.access_quartermaster == 1}} +
    +
    + Quartermaster: +
    +
    + {^{:~link('Supply Records', 'gear', {'choice' : "47"},null, 'fixedLeftWide')}} + {^{if cartridge.radio == 3}} {^{:~link('Delivery Bot Control', 'gear', {'choice' : "48"},null, 'fixedLeftWide')}} {{/if}} +
    +
    +
    +
    + {{/if}} + {{/if}} +
    +
    +
    + Utilities: +
    +
    + {^{if cartridge}} + {^{if cartridge.access.access_status_display == 1}} {^{:~link('Status Display', 'gear', {'choice' : "42"},null, 'fixedLeftWide')}}{{/if}} + {^{if cartridge.access.access_janitor==1}} {^{:~link('Custodial Locator', 'gear', {'choice' : "49"},null, 'fixedLeftWide')}} {{/if}} + {^{if cartridge.radio == 2}} {^{:~link('Signaler System', 'gear', {'choice' : "40"},null, 'fixedLeftWide')}} {{/if}} + {^{if cartridge.access.access_reagent_scanner==1}} {^{:~link(scanmode == 3 ? 'Disable Reagent Scanner' : 'Enable Reagent Scanner', 'gear', {'choice' : "Reagent Scan"},null, 'fixedLeftWider')}} {{/if}} + {^{if cartridge.access.access_engine==1}} {^{:~link(scanmode == 4 ? 'Disable Halogen Counter' : 'Enable Halogen Counter', 'gear', {'choice' : "Halogen Counter"}, null, 'fixedLeftWider')}} {{/if}} + {^{if cartridge.access.access_atmos==1}} {^{:~link(scanmode == 5 ? 'Disable Gas Scanner' : 'Enable Gas Scanner', 'gear', {'choice' : "Gas Scan"}, null, 'fixedLeftWide')}} {{/if}} + {^{if cartridge.access.access_remote_door==1}}{^{:~link('Toggle Door', 'gear', {'choice' : "Toggle Door"},null, 'fixedLeftWide')}} {{/if}} + {{/if}} + {^{:~link('Atmospheric Scan', 'gear', {'choice' : "3"},null, 'fixedLeftWide')}} + {^{:~link(fon==1 ? 'Disable Flashlight' : 'Enable Flashlight', 'lightbulb', {'choice' : "Light"}, null,'fixedLeftWide')}} +
    +
    + {^{if pai}} +
    +
    + PAI Utilities: +
    +
    + {^{:~link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"},null, 'fixedLeft')}} + {^{:~link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"},null, 'fixedLeft')}} +
    +
    + {{/if}} + {{/if}} + {^{if mode == 1}} +
    +
    + Notes: +
    +
    +
    +
    +
    + {^{:note}} +
    +
    +
    +
    +
    + {^{:~link('Edit Notes', 'gear', {'choice' : "Edit"},null, 'fixedLeft')}} +
    +
    + + + {{else mode == 2}} +

    SpaceMessenger V4.0.1

    +
    +
    + Messenger Functions: +
    + +
    + {^{:~link(silent==1 ? 'Ringer: Off' : 'Ringer: On', silent==1 ? 'volume-off' : 'volume-on', {'choice' : "Toggle Ringer"},null, 'fixedLeftWide')}} + {^{:~link(toff==1 ? 'Messenger: Off' : 'Messenger: On',toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"},null, 'fixedLeftWide')}} + {^{:~link('Set Ringtone', 'comment', {'choice' : "Ringtone"}, null, 'fixedLeftWide')}} + {^{:~link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"},null, 'fixedLeftWider')}} +
    +
    + {^{if toff == 0}} +

    + {^{if cartridge}} + {^{if cartridge.charges}} +
    + {^{:cartridge.charges}} + {^{if cartridge.type == "/obj/item/weapon/cartridge/syndicate"}} detonation charges left. {{/if}} + {^{if cartridge.type == "/obj/item/weapon/cartridge/clown" || cartridge.type == "/obj/item/weapon/cartridge/mime"}} viral files left. {{/if}} +

    +
    + {{/if}} + {{/if}} + + {^{if pda_count == 0}}No other PDAS located + {{else}} +

    Current Conversations

    + {^{for convopdas}} +
    + {^{:~link(Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : Reference } , null, fixedLeftWider)}} + {^{if ~root.cartridge}} + {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && Detonate == 1}} {^{:~link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : Reference}, null, 'fixedLeft')}} {{/if}} + {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/clown"}} {^{:~link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : Reference}, null, 'fixedLeft')}} {{/if}} + {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/mime"}} {^{:~link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : Reference}, null, 'fixedLeft')}} {{/if}} + {{/if}} +
    + {{/for}} +

    Other PDAs

    + {^{for pdas}} +
    + {^{:~link(Name, 'circle-arrow-s', {'choice' : "Message", 'target' : Reference}, null, fixedLeftWider)}} + {^{if ~root.cartridge}} + {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && Detonate == 1}} {^{:~link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : Reference}, null, 'fixedLeft')}} {{/if}} + {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/clown"}} {^{:~link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : Reference}, null, 'fixedLeft')}} {{/if}} + {^{if ~root.cartridge.type == "/obj/item/weapon/cartridge/mime"}} {^{:~link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : Reference}, null, 'fixedLeft')}} {{/if}} + {{/if}} +
    + {{/for}} + {{/if}} + {{/if}} + + {{else mode == 21}} +

    SpaceMessenger V4.0.1

    +
    +
    + Messenger Functions: +
    + +
    + {^{:~link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"},null, 'fixedLeftWide')}} +
    +
    +

    +

    Conversation with: {^{:convo_name}} ({^{:convo_job}})

    +
    +
    +
    + {^{for messages}} + {^{if ~root.active_conversation == target}} + {^{if sent==0}} + Them: {^{:message}}
    + {{else}} + You: {^{:message}}
    + {{/if}} + {{/if}} + {{/for}} + +
    +
    +
    + {^{:~link('Reply', 'comment', {'choice' : "Message", 'target': active_conversation},null, 'fixedLeft')}} + + {{else mode== 41}} +
    +
    + {^{if manifest.heads.length}} + + {^{for manifest["heads"]}} + {^{if rank == "Captain"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {^{if manifest.sec.length}} + + {^{for manifest["sec"]}} + {^{if rank == "Head of Security"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {^{if manifest.eng.length}} + + {^{for manifest["eng"]}} + {^{if rank == "Chief Engineer"}} + + {{else}} + + {{/if}} + + {{/for}} + {{/if}} + {^{if manifest.med.length}} + + {^{for manifest["med"]}} + {^{if rank == "Chief Medical Officer"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {^{if manifest.sci.length}} + + {^{for manifest["sci"]}} + {^{if rank == "Research Director"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {^{if manifest.civ.length}} + + {^{for manifest["civ"]}} + {^{if rank == "Head of Personnel"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {^{if manifest.misc.length}} + + {^{for manifest["misc"]}} + + {{/for}} + {{/if}} + + +
    Command
    {^{:name}}{^{:rank}}{^{:active}}
    {^{:name}}{^{:rank}}{^{:active}}
    Security
    {^{:name}}{^{:rank}}{^{:active}}
    {^{:name}}{^{:rank}}{^{:active}}
    Engineering
    {^{:name}}{^{:rank}}{^{:active}}
    {^{:name}}{^{:rank}}{^{:active}}
    Medical
    {^{:name}}{^{:rank}}{^{:active}}
    {^{:name}}{^{:rank}}{^{:active}}
    Science
    {^{:name}}{^{:rank}}{^{:active}}
    {^{:name}}{^{:rank}}{^{:active}}
    Civilian
    {^{:name}}{^{:rank}}{^{:active}}
    {^{:name}}{^{:rank}}{^{:active}}
    Misc
    {^{:name}}{^{:rank}}{^{:active}}
    +
    + {{else mode == 3}} + +

    Atmospheric Scan

    +
    +
    + {^{if aircontents.reading == 1}} +
    + Pressure: +
    +
    + {^{:~string('{1} kPa', aircontents.pressure < 80 || aircontents.pressure > 120 ? 'bad' : aircontents.pressure < 95 || aircontents.pressure > 110 ? 'average' : 'good' , aircontents.pressure)}} +
    +
    + Temperature: +
    +
    + {^{:~string('{1} °C', aircontents.temp < 5 || aircontents.temp > 35 ? 'bad' : aircontents.temp < 15 || aircontents.temp > 25 ? 'average' : 'good' , aircontents.temp)}} +
    +
    +
    + Oxygen: +
    +
    + {^{:~string('{1}%', aircontents.oxygen < 17 ? 'bad' : aircontents.oxygen < 19 ? 'average' : 'good' , aircontents.oxygen)}} +
    +
    + Nitrogen: +
    +
    + {^{:~string('{1}%', aircontents.nitrogen > 82 ? 'bad' : aircontents.nitrogen > 80 ? 'average' : 'good' , aircontents.nitrogen)}} +
    +
    + Carbon Dioxide: +
    +
    + {^{:~string('{1}%', aircontents.carbon_dioxide > 5 ? 'bad' : 'good' , aircontents.carbon_dioxide)}} +
    +
    + Plasma: +
    +
    + {^{:~string('{1}%', aircontents.plasma > 0 ? 'bad' : 'good' , aircontents.plasma)}} + +
    + {^{if aircontents.other > 0}} +
    + Unknown: +
    +
    + {^{:aircontents.other}}% +
    + {{/if}} + {{else}} +
    + Unable to get air reading +
    + {{/if}} +
    + +
    + {{else mode == 40}} +

    Remote Signaling System

    +
    +
    + Frequency: +
    +
    + {^{:records.signal_freq}} +
    +  {^{:~link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-10"},null, null)}}  + {^{:~link('-.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-2"},null, null)}}  + + {^{:~link('+.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "2"},null, null)}}  + {^{:~link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "10"},null, null)}} +
    +
    +

    +
    +
    + Code: +
    +
    + + {^{:records.signal_code}}
    +
    + {^{:~link('-5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-5"},null, null)}} + {^{:~link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-1"},null, null)}} + {^{:~link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "1"},null, null)}} + {^{:~link('+5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "5"},null, null)}} +
    +
    +
    + {^{:~link('Send Signal', 'radiation', {'cartmenu' : "1", 'choice' : "Send Signal"},null, null)}} +
    + + {{else mode == 42}} +

    Station Status Displays Interlink

    +
    +
    + Code: +
    +
    + {^{:~link('Clear', 'trash', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "blank"},null, null)}} + {^{:~link('Shuttle ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "shuttle"},null, null)}} + {^{:~link('Message', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "message"},null, null)}} +
    +
    +
    +
    +
    + Message line 1 +
    +
    + {^{:~link(records.message1 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg1"},null, null)}} +
    +
    +
    +
    + Message line 2 +
    +
    + {^{:~link(records.message2 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg2"},null, null)}} +
    +
    + +
    +
    +
    + ALERT!: +
    +
    + {^{:~link('None', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'default' : "alert"},null, null)}} + {^{:~link('Alert', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "alert"},null, null)}} + {^{:~link('Lockdown', 'caution', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "alert"},null, null)}} + {^{:~link('Biohazard', 'radiation', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "alert"},null, null)}} +
    +
    + + {{else mode == 43}} + +

    Station Powermonitors

    +
    + Select A power monitor: +
    + {^{for records.powermonitors}} +
    + {^{:~link(Name, 'radiation', {'cartmenu' : "1", 'choice' : "Power Select",'target' : ref},null, null)}} +
    + {{/for}} + + {{else mode == 433}} +

    Powernet Status

    +
    +
    + Current Load: +
    +
    + {^{:records.powerload}} W +
    +
    +
    +
    + Total Power: +
    +
    + {^{:records.poweravail}} W +
    +
    +
    +
    + + {^{for records.apcs}} + {^{if #index % 20 === 0}} + + {{/if}} + + + {^{:~string('', Equipment==1 ? '#4f7529' : '#8f1414' )}} + {^{:~string('', Lights==1 ? '#4f7529' : '#8f1414' )}} + {^{:~string('', Environment==1 ? '#4f7529' : '#8f1414' )}} + {^{:~string('', CellStatus==1 ? '#4f7529' : '#8f1414', CellStatus==-1 ? 'No Cell' : CellPct + '%' )}} + + {{/for}} +
     Area  Eqp.  Lgt.  Env  Cell 
    {^{:Name}}   {1}
    +
    + + {{else mode == 44}} +

    Medical Record List

    +
    + Select A record +
    +
    + {^{for records.medical_records}} +
    + {^{:~link(Name, 'gear', {'cartmenu' : "1", 'choice' : "Medical Records",'target' : ref},null, null)}} +
    + {{/for}} + + + + {{else mode == 441}} +

    Medical Record

    +
    +
    +
    + {^{if records.general_exists == 1}} + Name: {^{:records.general.name}}
    + Sex: {^{:records.general.sex}}
    + Species: {^{:records.general.species}}
    + Age: {^{:records.general.age}}
    + Rank: {^{:records.general.rank}}
    + Fingerprint: {^{:records.general.fingerprint}}
    + Physical Status: {^{:records.general.p_stat}}
    + Mental Status: {^{:records.general.m_stat}}

    + {{else}} + + General Record Lost!

    +
    + {{/if}} + {^{if records.medical_exists == 1}} + Medical Data:
    + Blood Type: {^{:records.medical.b_type}}

    + Minor Disabilities: {^{:records.medical.mi_dis}}
    + Details: {^{:records.medical.mi_dis_d}}

    + Major Disabilities: {^{:records.medical.ma_dis}}
    + Details: {^{:records.medical.ma_dis_d}}

    + Allergies: {^{:records.medical.alg}}
    + Details: {^{:records.medical.alg_d}}

    + Current Disease: {^{:records.medical.cdi}}
    + Details: {^{:records.medical.alg_d}}

    + Important Notes: {^{:records.medical.notes}} + {{else}} + + Medical Record Lost!

    +
    + {{/if}} +
    +
    +
    + + + {{else mode == 45}} +

    Security Record List

    +
    + Select A record +
    +
    + {^{for records.security_records}} +
    + {^{:~link(Name, 'gear', {'cartmenu' : "1", 'choice' : "Security Records",'target' : ref},null, null)}} +
    + {{/for}} + + + + {{else mode == 451}} +

    Security Record

    +
    +
    +
    + {^{if records.general_exists == 1}} + Name: {^{:records.general.name}}
    + Sex: {^{:records.general.sex}}
    + Species: {^{:records.general.species}}
    + Age: {^{:records.general.age}}
    + Rank: {^{:records.general.rank}}
    + Fingerprint: {^{:records.general.fingerprint}}
    + Physical Status: {^{:records.general.p_stat}}
    + Mental Status: {^{:records.general.m_stat}}

    + {{else}} + + General Record Lost!

    +
    + {{/if}} + {^{if records.security_exists == 1}} + Security Data:
    + Criminal Status: {^{:records.security.criminal}}

    + Minor Crimes: {^{:records.security.mi_crim}}
    + Details: {^{:records.security.mi_crim_d}}

    + Major Crimes: {^{:records.security.ma_crim}}
    + Details: {^{:records.security.ma_crim_d}}

    + Important Notes: {^{:records.security.notes}} + {{else}} + + Security Record Lost!

    +
    + {{/if}} +
    +
    +
    + {{else mode == 46}} +

    Security Bot Control

    + {^{if records.beepsky.active == null || records.beepsky.active == 0}} + {^{if records.beepsky.count == 0}} +

    No bots found.

    + {{else}} +
    + Select A Bot. +
    +
    + {^{for records.beepsky.bots}} +
    + {^{:~link(Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : ref},null, null)}} (Location: {^{:Location}}) +
    + {{/for}} + {{/if}} +
    + {^{:~link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"},null, null)}} + + {{else}} +

    {^{:records.beepsky.active}}

    +

    + {^{if records.beepsky.botstatus.mode == -1}} +

    Waiting for response...

    + {{else}} +

    Status:

    +
    +
    +
    + Location: +
    +
    + {^{:records.beepsky.botstatus.loca}} +
    +
    +
    +
    + Mode: +
    +
    + + {^{if records.beepsky.botstatus.mode ==0}} Ready + {{else records.beepsky.botstatus.mode == 1}} + Apprehending target + {{else records.beepsky.botstatus.mode ==2 || records.beepsky.botstatus.mode == 3}} + Arresting target + {{else records.beepsky.botstatus.mode ==4}} + Starting patrol + {{else records.beepsky.botstatus.mode ==5}} + On Patrol + {{else records.beepsky.botstatus.mode ==6}} + Responding to summons + {{/if}} + +
    +
    +
    + {^{:~link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"},null, null)}} + {^{:~link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"},null, null)}} + {^{:~link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"},null, null)}} +
    + {{/if}} + {^{:~link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"},null, null)}} + {{/if}} + {{else mode == 47}} +

    Supply Record Interlink

    +
    +
    + Location: +
    +
    + + {^{if records.supply.shuttle_moving}} + Moving to station ({^{:records.supply.shuttle_eta}}) + {{else}} + Shuttle at {^{:records.supply.shuttle_loc}} + {{/if}} + +
    +
    +
    +
    +
    + Current Approved Orders
    + {^{if records.supply.approved_count == 0}} + No current approved orders

    + {{else}} + {^{for records.supply.approved}} + #{^{:Number}} - {^{:Name}} approved by {^{:OrderedBy}}
    {^{if Comment != ""}} {^{:Comment}}
    {{/if}}
    + {{/for}} + {{/if}} +

    + Current Requested Orders
    + {^{if records.supply.requests_count == 0}} + No current requested orders

    + {{else}} + {^{for records.supply.requests}} + #{^{:Number}} - {^{:Name}} requested by {^{:OrderedBy}}
    {^{if Comment != ""}} {^{:Comment}}
    {{/if}}
    + {{/for}} + {{/if}} +
    +
    +
    + + {{else mode == 48}} +

    Mule Control

    + {^{if records.mulebot.active == null || records.mulebot.active == 0}} + {^{if records.mulebot.count == 0}} +

    No bots found.

    + + {{else}} +

    Mule List

    +
    + Select A Mulebot +
    +
    + {^{for records.mulebot.bots}} +
    + {^{:~link(Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : ref},null, null)}} (Location: {^{:Location}}) +
    + {{/for}} + {{/if}} +
    + {^{:~link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"},null, null)}} + {{else}} + {^{if records.mulebot.botstatus.mode == -1}} +

    Waiting for response...

    + {{else}} +

    Status:

    +
    +
    +
    + Location: +
    +
    + {^{:records.mulebot.botstatus.loca}} +
    +
    +
    +
    + Mode: +
    +
    + + {^{if records.mulebot.botstatus.mode ==0}} Ready + {{else records.mulebot.botstatus.mode == 1}} + Loading/Unloading + {{else records.mulebot.botstatus.mode ==2}} + Navigating to Delivery Location + {{else records.mulebot.botstatus.mode == 3}} + Navigating to Home + {{else records.mulebot.botstatus.mode ==4}} + Waiting for Clear Path + {{else records.mulebot.botstatus.mode ==5 || records.mulebot.botstatus.mode == 6}} + Calculating navigation Path + + {{else records.mulebot.botstatus.mode ==7}} + Unable to locate destination + {{/if}} + +
    +
    +
    +
    + Current Load: +
    +
    + + {^{:~link(records.mulebot.botstatus.load == null ? 'None (Unload)' : records.mulebot.botstatus.load + ' (Unload)', 'gear', {'radiomenu' : "1", 'op' : "unload"},records.mulebot.botstatus.load == null ? 'disabled' : null, null)}} + +
    +
    +
    +
    + Power: +
    +
    + + {^{:records.mulebot.botstatus.powr}}% + +
    +
    + +
    +
    + Destination: +
    +
    + {^{:~link(records.mulebot.botstatus.dest == null || records.mulebot.botstatus.dest == "" ? 'None (Set)': records.mulebot.botstatus.dest+ ' (Set)', 'gear', {'radiomenu' : "1", 'op' : "setdest"},null, null)}} +
    + +
    +
    +
    + Home: +
    +
    + {^{if records.mulebot.botstatus.home == null}} None {{else}} {^{:records.mulebot.botstatus.home}} {{/if}} +
    +
    +
    +
    + Auto Return: +
    +
    + {^{:~link(records.mulebot.botstatus.retn == 1 ? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : records.mulebot.botstatus.retn==1 ? "retoff" : "reton"},null, null)}} +
    +
    +
    +
    + Auto Pickup: +
    +
    + {^{:~link(records.mulebot.botstatus.pick==1? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : records.mulebot.botstatus.pick==1 ? "pickoff" : "pickon"},null, null)}} +
    +
    +
    +
    + Functions: +
    +
    + {^{:~link('Stop', 'gear', {'radiomenu' : "1", 'op' : "stop"},null, null)}} + {^{:~link('Proceed', 'gear', {'radiomenu' : "1", 'op' : "go"},null, null)}} + {^{:~link('Return Home', 'gear', {'radiomenu' : "1", 'op' : "home"},null, null)}} +
    +
    +

    + {^{:~link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"},null, null)}} + + + {{/if}} + {{/if}} + + + + {{else mode == 49}} +

    Janatorial Supplies Locator

    +
    + Current Location: + {^{if records.janitor.user_loc.x == 0}} + Unknown + {{else}} + {^{:records.janitor.user_loc.x}} / {^{:records.janitor.user_loc.y}} + {{/if}} +
    +
    + {^{for records.janitor.mops}} + {^{if x==0}} + Unable to locate Mop + {{else}} + Mop Location: + ({^{:x}} / {^{:y}}) - {^{:dir}} - Status: {^{:status}}
    + {{/if}} + {{/for}} +
    +
    + {^{for records.janitor.buckets}} + {^{if x==0}} + Unable to locate Water Buckets + {{else}} + Water Buckets Location: + ({^{:x}} / {^{:y}}) - {^{:dir}} - Water Level: {^{:status}}
    + {{/if}} + {{/for}} +
    +
    + {^{for records.janitor.cleanbots}} + {^{if x==0}} + Unable to locate Clean Bots + {{else}} + Clean Bots Location: + ({^{:x}} / {^{:y}}) - {^{:dir}} - Status: {^{:status}}
    + {{/if}} + + {{/for}} +
    +
    + {^{for records.janitor.carts}} + {^{if x==0}} + Unable to locate Janitorial Cart + {{else}} + Janitorial cart Location: + ({^{:x}} / {^{:y}}) - {^{:dir}} - Status: {^{:status}}
    + {{/if}} + + {{/for}} +
    + + + + + {{/if}} + + +{{else}} +







    No Owner information found, please swipe ID +
    +{{/if}} + diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl new file mode 100644 index 00000000000..2f47c196358 --- /dev/null +++ b/nano/templates/uplink.tmpl @@ -0,0 +1,46 @@ + + +{^{:~syndicateMode()}} +

    {^{:welcome}}

    +
    +
    +
    + Functions: +
    +
    + {^{:~link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}} +
    +
    +
    +
    +
    + Tele-Crystals: +
    +
    + {^{:crystals}} +
    +
    +

    Request items:


    +Each item costs a number of tele-crystals as indicated by the number following their name. + +

    +{^{for nano_items}} +
    +

    {^{:Category}}

    +
    + {^{for items}} +
    + {^{:~link( Name, 'gear', {'buy_item' : obj_path, 'cost' : Cost}, Cost > ~root.crystals ? 'disabled' : null, null)}} - {^{:Cost}} +
    + {{/for}} +
    + +{{/for}} + +
    + {^{:~link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, null, 'fixedLeftWidest')}} +
    +