From 1e2136781c59a4ff1c3a19287a27e0e3f2b0a7b4 Mon Sep 17 00:00:00 2001 From: SinTwo Date: Mon, 20 Jun 2016 11:48:52 -0400 Subject: [PATCH] Adds NanoUI for multiple computers. --- code/game/machinery/adv_med.dm | 812 ++++++++++++---------- code/game/machinery/atmo_control.dm | 221 +++--- code/game/machinery/computer/Operating.dm | 75 +- code/game/machinery/computer/arcade.dm | 130 ++-- code/game/machinery/computer/cloning.dm | 267 +++---- code/game/machinery/computer/guestpass.dm | 66 +- code/game/machinery/computer3/lapvend.dm | 114 +-- code/modules/holodeck/HolodeckControl.dm | 78 +-- code/modules/paperwork/faxmachine.dm | 72 +- code/modules/paperwork/photocopier.dm | 51 +- nano/templates/adv_med.tmpl | 279 ++++++++ nano/templates/arcade_battle.tmpl | 26 + nano/templates/atmo_control.tmpl | 218 ++++++ nano/templates/chem_master.tmpl | 205 ++++++ nano/templates/cloning.tmpl | 115 +++ nano/templates/fax.tmpl | 32 + nano/templates/guest_pass.tmpl | 59 ++ nano/templates/holodeck.tmpl | 33 + nano/templates/laptop_vendor.tmpl | 175 +++++ nano/templates/operating.tmpl | 75 ++ nano/templates/photocopier.tmpl | 47 ++ 21 files changed, 2159 insertions(+), 991 deletions(-) create mode 100644 nano/templates/adv_med.tmpl create mode 100644 nano/templates/arcade_battle.tmpl create mode 100644 nano/templates/atmo_control.tmpl create mode 100644 nano/templates/chem_master.tmpl create mode 100644 nano/templates/cloning.tmpl create mode 100644 nano/templates/fax.tmpl create mode 100644 nano/templates/guest_pass.tmpl create mode 100644 nano/templates/holodeck.tmpl create mode 100644 nano/templates/laptop_vendor.tmpl create mode 100644 nano/templates/operating.tmpl create mode 100644 nano/templates/photocopier.tmpl diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 90ff3f0d6b..9b24af92d2 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -8,13 +8,17 @@ icon = 'icons/obj/Cryogenic2.dmi' icon_state = "body_scanner_0" density = 1 + dir = 8 anchored = 1 + circuit = /obj/item/weapon/circuitboard/body_scanner use_power = 1 idle_power_usage = 60 active_power_usage = 10000 //10 kW. It's a big all-body scanner. + light_color = "#00FF00" + /obj/machinery/bodyscanner/New() ..() spawn( 5 ) @@ -34,72 +38,12 @@ component_parts += new /obj/item/stack/material/glass/reinforced(src, 2) RefreshParts() -/obj/machinery/bodyscanner/relaymove(mob/user as mob) - if (user.stat) - return - src.go_out() - return - -/obj/machinery/bodyscanner/verb/eject() - set src in oview(1) - set category = "Object" - set name = "Eject Body Scanner" - - if (usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return - -/obj/machinery/bodyscanner/verb/move_inside() - set src in oview(1) - set category = "Object" - set name = "Enter Body Scanner" - - if (usr.stat != 0) - return - if (src.occupant) - usr << "The scanner is already occupied!" - return - if (usr.abiotic()) - usr << "The subject cannot have abiotic items on." - return - usr.pulling = null - usr.client.perspective = EYE_PERSPECTIVE - usr.client.eye = src - usr.loc = src - src.occupant = usr - update_use_power(2) - src.icon_state = "body_scanner_1" - for(var/obj/O in src) - //O = null - if(O in component_parts) - continue - if(O == circuit) - continue - qdel(O) - //Foreach goto(124) - src.add_fingerprint(usr) - return - -/obj/machinery/bodyscanner/proc/go_out() - if ((!( src.occupant ) || src.locked)) - return - for(var/obj/O in src) - if(O in component_parts) - continue - if(O == circuit) - continue - O.loc = src.loc - //Foreach goto(30) - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.occupant = null - update_use_power(1) - src.icon_state = "body_scanner_0" - return +/obj/machinery/bodyscanner/power_change() + ..() + if(!(stat & (BROKEN|NOPOWER))) + set_light(2) + else + set_light(0) /obj/machinery/bodyscanner/attackby(var/obj/item/G, user as mob) if(default_deconstruction_screwdriver(user, G)) @@ -109,42 +53,96 @@ if(istype(G, /obj/item/weapon/grab)) var/obj/item/weapon/grab/H = G - if(!(ismob(H.affecting))) + if(panel_open) + user << "Close the maintenance panel first." return - if (src.occupant) - user << "The scanner is already occupied!" + if(!ismob(H.affecting)) return - if (H.affecting.abiotic()) - user << "Subject cannot have abiotic items on." + if(occupant) + user << "The scanner is already occupied!" return + for(var/mob/living/carbon/slime/M in range(1, H.affecting)) + if(M.Victim == H.affecting) + user << "[H.affecting.name] has a fucking slime attached to them, deal with that first." + return var/mob/M = H.affecting - if (M.client) - M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.loc = src - src.occupant = M - update_use_power(2) - src.icon_state = "body_scanner_1" - for(var/obj/O in src) - if(O in component_parts) - continue - if(O == circuit) - continue - O.loc = src.loc - //Foreach goto(154) - src.add_fingerprint(user) - //G = null + if(M.abiotic()) + user << "Subject cannot have abiotic items on." + return + M.forceMove(src) + occupant = M + icon_state = "body_scanner_1" + add_fingerprint(user) qdel(G) + +/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/O, mob/user as mob) + if(!istype(O)) + return 0 //not a mob + if(user.incapacitated()) + return 0 //user shouldn't be doing things + if(O.anchored) + return 0 //mob is anchored??? + if(get_dist(user, src) > 1 || get_dist(user, O) > 1) + return 0 //doesn't use adjacent() to allow for non-cardinal (fuck my life) + if(!ishuman(user) && !isrobot(user)) + return 0 //not a borg or human + if(panel_open) + user << "Close the maintenance panel first." + return 0 //panel open + if(occupant) + user << "\The [src] is already occupied." + return 0 //occupied + + if(O.buckled) + return 0 + if(O.abiotic()) + user << "Subject cannot have abiotic items on." + return 0 + for(var/mob/living/carbon/slime/M in range(1, O)) + if(M.Victim == O) + user << "[O] has a fucking slime attached to them, deal with that first." + return 0 + + if(O == user) + visible_message("[user] climbs into \the [src].") + else + visible_message("[user] puts [O] into the body scanner.") + + O.forceMove(src) + occupant = O + icon_state = "body_scanner_1" + add_fingerprint(user) + +/obj/machinery/bodyscanner/relaymove(mob/user as mob) + if(user.incapacitated()) + return 0 //maybe they should be able to get out with cuffs, but whatever + go_out() + +/obj/machinery/bodyscanner/verb/eject() + set src in oview(1) + set category = "Object" + set name = "Eject Body Scanner" + + if(usr.incapacitated()) + return + go_out() + add_fingerprint(usr) + +/obj/machinery/bodyscanner/proc/go_out() + if ((!( src.occupant ) || src.locked)) + return + if (src.occupant.client) + src.occupant.client.eye = src.occupant.client.mob + src.occupant.client.perspective = MOB_PERSPECTIVE + src.occupant.loc = src.loc + src.occupant = null + src.icon_state = "body_scanner_0" return /obj/machinery/bodyscanner/ex_act(severity) switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - if(A in component_parts) - continue - if(A == circuit) - continue A.loc = src.loc ex_act(severity) //Foreach goto(35) @@ -154,10 +152,6 @@ if(2.0) if (prob(50)) for(var/atom/movable/A as mob|obj in src) - if(A in component_parts) - continue - if(A == circuit) - continue A.loc = src.loc ex_act(severity) //Foreach goto(108) @@ -167,10 +161,6 @@ if(3.0) if (prob(25)) for(var/atom/movable/A as mob|obj in src) - if(A in component_parts) - continue - if(A == circuit) - continue A.loc = src.loc ex_act(severity) //Foreach goto(181) @@ -180,32 +170,7 @@ else return -/obj/machinery/body_scanconsole/ex_act(severity) - - switch(severity) - if(1.0) - //SN src = null - qdel(src) - return - if(2.0) - if (prob(50)) - //SN src = null - qdel(src) - return - else - return - -/obj/machinery/body_scanconsole/power_change() - ..() - if(stat & BROKEN) - icon_state = "body_scannerconsole-p" - else - if (stat & NOPOWER) - spawn(rand(0, 15)) - src.icon_state = "body_scannerconsole-p" - else - icon_state = initial(icon_state) - +//Body Scan Console /obj/machinery/body_scanconsole var/obj/machinery/bodyscanner/connected var/known_implants = list(/obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking) @@ -218,67 +183,12 @@ density = 0 anchored = 1 circuit = /obj/item/weapon/circuitboard/scanner_console + var/printing = null + var/printing_text = null /obj/machinery/body_scanconsole/New() ..() - spawn( 5 ) - src.connected = locate(/obj/machinery/bodyscanner) in range(2,src) - return - return - -/* - -/obj/machinery/body_scanconsole/process() //not really used right now - if(stat & (NOPOWER|BROKEN)) - return - //use_power(250) // power stuff - -// var/mob/M //occupant -// if (!( src.status )) //remove this -// return -// if ((src.connected && src.connected.occupant)) //connected & occupant ok -// M = src.connected.occupant -// else -// if (istype(M, /mob)) -// //do stuff -// else -/// src.temphtml = "Process terminated due to lack of occupant in scanning chamber." -// src.status = null -// src.updateDialog() -// return - -*/ - -/obj/machinery/body_scanconsole/attack_ai(user as mob) - return src.attack_hand(user) - -/obj/machinery/body_scanconsole/attack_hand(user as mob) - if(..()) - return - if(stat & (NOPOWER|BROKEN)) - return - if(!connected || (connected.stat & (NOPOWER|BROKEN))) - user << "This console is not connected to a functioning body scanner." - return - if(!ishuman(connected.occupant)) - user << "This device can only scan compatible lifeforms." - return - - var/dat - if (src.delete && src.temphtml) //Window in buffer but its just simple message, so nothing - src.delete = src.delete - else if (!src.delete && src.temphtml) //Window in buffer - its a menu, dont add clear message - dat = text("[]

Main Menu", src.temphtml, src) - else - if (src.connected) //Is something connected? - dat = format_occupant_data(src.connected.get_occupant_data()) - dat += "
Print
" - else - dat = "Error: No Body Scanner connected." - - dat += text("
Close", user) - user << browse(dat, "window=scanconsole;size=430x600") - return + findscanner() /obj/machinery/body_scanconsole/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/weapon/screwdriver) && circuit) @@ -311,205 +221,355 @@ src.attack_hand(user) return +/obj/machinery/body_scanconsole/power_change() + if(stat & BROKEN) + icon_state = "body_scannerconsole-p" + else if(powered() && !panel_open) + icon_state = initial(icon_state) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + src.icon_state = "body_scannerconsole-p" + stat |= NOPOWER + +/obj/machinery/body_scanconsole/ex_act(severity) + switch(severity) + if(1.0) + //SN src = null + qdel(src) + return + if(2.0) + if (prob(50)) + //SN src = null + qdel(src) + return + else + return + +/obj/machinery/body_scanconsole/proc/findscanner() + spawn( 5 ) + var/obj/machinery/bodyscanner/bodyscannernew = null + // Loop through every direction + for(dir in list(NORTH,EAST,SOUTH,WEST)) + // Try to find a scanner in that direction + bodyscannernew = locate(/obj/machinery/bodyscanner, get_step(src, dir)) + src.connected = bodyscannernew + return + return + +/obj/machinery/body_scanconsole/attack_ai(user as mob) + return attack_hand(user) + +/obj/machinery/body_scanconsole/attack_ghost(user as mob) + return attack_hand(user) + +/obj/machinery/body_scanconsole/attack_hand(user as mob) + if(stat & (NOPOWER|BROKEN)) + return + + if (panel_open) + user << "Close the maintenance panel first." + return + + if(!src.connected) + findscanner() + + ui_interact(user) + +/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + + data["connected"] = connected ? 1 : 0 + + if(connected) + data["occupied"] = connected.occupant ? 1 : 0 + + var/occupantData[0] + if(connected.occupant && ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + occupantData["name"] = H.name + occupantData["stat"] = H.stat + occupantData["health"] = H.health + + occupantData["hasVirus"] = H.virus2.len + + occupantData["bruteLoss"] = H.getBruteLoss() + occupantData["oxyLoss"] = H.getOxyLoss() + occupantData["toxLoss"] = H.getToxLoss() + occupantData["fireLoss"] = H.getFireLoss() + + occupantData["radLoss"] = H.radiation + occupantData["cloneLoss"] = H.getCloneLoss() + occupantData["brainLoss"] = H.getBrainLoss() + occupantData["paralysis"] = H.paralysis + occupantData["paralysisSeconds"] = round(H.paralysis / 4) + occupantData["bodyTempC"] = H.bodytemperature-T0C + occupantData["bodyTempF"] = (((H.bodytemperature-T0C) * 1.8) + 32) + + occupantData["hasBorer"] = H.has_brain_worms() + + var/bloodData[0] + if(H.vessel) + var/blood_volume = round(H.vessel.get_reagent_amount("blood")) + bloodData["volume"] = blood_volume + bloodData["percent"] = round(((blood_volume / 560)*100)) + + occupantData["blood"] = bloodData + + var/reagentData[0] + if(H.reagents) + for(var/datum/reagent/R in H.reagents) + reagentData[++reagentData.len] = list("name" = R.name, "amount" = R.volume) + + occupantData["reagents"] = reagentData + + var/extOrganData[0] + for(var/obj/item/organ/external/E in H.organs) + var/organData[0] + organData["name"] = E.name + organData["open"] = E.open + organData["germ_level"] = E.germ_level + organData["bruteLoss"] = E.brute_dam + organData["fireLoss"] = E.burn_dam + + var/implantData[0] + for(var/obj/I in E.implants) + var/implantSubData[0] + implantSubData["name"] = I.name + if(is_type_in_list(I, known_implants)) + implantSubData["known"] = 1 + + implantData.Add(list(implantSubData)) + + organData["implants"] = implantData + organData["implants_len"] = implantData.len + + var/organStatus[0] + if(E.status & ORGAN_DESTROYED) + organStatus["destroyed"] = 1 + if(E.status & ORGAN_BROKEN) + organStatus["broken"] = E.broken_description + if(E.status & ORGAN_ROBOT) + organStatus["robotic"] = 1 + if(E.status & ORGAN_SPLINTED) + organStatus["splinted"] = 1 + if(E.status & ORGAN_BLEEDING) + organStatus["bleeding"] = 1 + + organData["status"] = organStatus + + if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured()) + organData["lungRuptured"] = 1 + + for(var/datum/wound/W in E.wounds) + if(W.internal) + organData["internalBleeding"] = 1 + break + + extOrganData.Add(list(organData)) + + occupantData["extOrgan"] = extOrganData + + var/intOrganData[0] + for(var/obj/item/organ/I in H.internal_organs) + var/organData[0] + organData["name"] = I.name + organData["desc"] = I.desc + organData["germ_level"] = I.germ_level + organData["damage"] = I.damage + + intOrganData.Add(list(organData)) + + occupantData["intOrgan"] = intOrganData + + occupantData["blind"] = (H.sdisabilities & BLIND) + occupantData["nearsighted"] = (H.disabilities & NEARSIGHTED) + + data["occupant"] = occupantData + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + /obj/machinery/body_scanconsole/Topic(href, href_list) - if (..()) - return + if(..()) + return 1 - if (href_list["print"]) - if (!src.connected) - usr << "\icon[src]Error: No body scanner connected." - return - var/mob/living/carbon/human/occupant = src.connected.occupant - if (!src.connected.occupant) - usr << "\icon[src]The body scanner is empty." - return - if (!istype(occupant,/mob/living/carbon/human)) - usr << "\icon[src]The body scanner cannot scan that lifeform." - return - var/obj/item/weapon/paper/R = new(src.loc) - R.name = "Body scan report" - R.info = format_occupant_data(src.connected.get_occupant_data()) + if (href_list["print_p"]) + generate_printing_text() + if (!(printing) && printing_text) + printing = 1 + visible_message("\The [src] rattles and prints out a sheet of paper.") + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) + P.info = "
Body Scan - [href_list["name"]]

" + P.info += "Time of scan: [worldtime2text(world.time)]

" + P.info += "[printing_text]" + P.info += "

Notes:
" + P.name = "Body Scan - [href_list["name"]]" + printing = null + printing_text = null -/obj/machinery/bodyscanner/proc/get_occupant_data() - if (!occupant || !istype(occupant, /mob/living/carbon/human)) - return - var/mob/living/carbon/human/H = occupant - var/list/occupant_data = list( - "stationtime" = worldtime2text(), - "stat" = H.stat, - "health" = round(H.health/H.maxHealth)*100, - "virus_present" = H.virus2.len, - "bruteloss" = H.getBruteLoss(), - "fireloss" = H.getFireLoss(), - "oxyloss" = H.getOxyLoss(), - "toxloss" = H.getToxLoss(), - "rads" = H.radiation, - "cloneloss" = H.getCloneLoss(), - "brainloss" = H.getBrainLoss(), - "paralysis" = H.paralysis, - "bodytemp" = H.bodytemperature, - "borer_present" = H.has_brain_worms(), - "inaprovaline_amount" = H.reagents.get_reagent_amount("inaprovaline"), - "dexalin_amount" = H.reagents.get_reagent_amount("dexalin"), - "stoxin_amount" = H.reagents.get_reagent_amount("stoxin"), - "bicaridine_amount" = H.reagents.get_reagent_amount("bicaridine"), - "dermaline_amount" = H.reagents.get_reagent_amount("dermaline"), - "blood_amount" = round((H.vessel.get_reagent_amount("blood") / H.species.blood_volume)*100), - "disabilities" = H.sdisabilities, - "lung_ruptured" = H.is_lung_ruptured(), - "external_organs" = H.organs.Copy(), - "internal_organs" = H.internal_organs.Copy(), - "species_organs" = H.species.has_organ //Just pass a reference for this, it shouldn't ever be modified outside of the datum. - ) - return occupant_data +/obj/machinery/body_scanconsole/proc/generate_printing_text() + var/dat = "" - -/obj/machinery/body_scanconsole/proc/format_occupant_data(var/list/occ) - var/dat = "Scan performed at [occ["stationtime"]]
" - dat += "Occupant Statistics:
" - var/aux - switch (occ["stat"]) - if(0) - aux = "Conscious" - if(1) - aux = "Unconscious" - else - aux = "Dead" - dat += text("[]\tHealth %: [] ([])
", ("Viral pathogen detected in blood stream.
" - dat += text("[]\t-Brute Damage %: []
", (""), occ["bruteloss"]) - dat += text("[]\t-Respiratory Damage %: []
", (""), occ["oxyloss"]) - dat += text("[]\t-Toxin Content %: []
", (""), occ["toxloss"]) - dat += text("[]\t-Burn Severity %: []

", (""), occ["fireloss"]) - - dat += text("[]\tRadiation Level %: []
", (""), occ["rads"]) - dat += text("[]\tGenetic Tissue Damage %: []
", (""), occ["cloneloss"]) - dat += text("[]\tApprox. Brain Damage %: []
", (""), occ["brainloss"]) - dat += text("Paralysis Summary %: [] ([] seconds left!)
", occ["paralysis"], round(occ["paralysis"] / 4)) - dat += text("Body Temperature: [occ["bodytemp"]-T0C]°C ([occ["bodytemp"]*1.8-459.67]°F)

") - - if(occ["borer_present"]) - dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" - - dat += text("[]\tBlood Level %: [] ([] units)

", (""), occ["blood_amount"], occ["blood_amount"]) - - dat += text("Inaprovaline: [] units
", occ["inaprovaline_amount"]) - dat += text("Soporific: [] units
", occ["stoxin_amount"]) - dat += text("[]\tDermaline: [] units

", (""), occ["dermaline_amount"]) - dat += text("[]\tBicaridine: [] units
", (""), occ["bicaridine_amount"]) - dat += text("[]\tDexalin: [] units
", (""), occ["dexalin_amount"]) - - dat += "
" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - - for(var/obj/item/organ/external/e in occ["external_organs"]) - var/AN = "" - var/open = "" - var/infected = "" - var/imp = "" - var/bled = "" - var/robot = "" - var/splint = "" - var/internal_bleeding = "" - var/lung_ruptured = "" - - dat += "" - - for(var/datum/wound/W in e.wounds) if(W.internal) - internal_bleeding = "
Internal bleeding" - break - if(istype(e, /obj/item/organ/external/chest) && occ["lung_ruptured"]) - lung_ruptured = "Lung ruptured:" - if(e.status & ORGAN_SPLINTED) - splint = "Splinted:" - if(e.status & ORGAN_BLEEDING) - bled = "Bleeding:" - if(e.status & ORGAN_BROKEN) - AN = "[e.broken_description]:" - if(e.status & ORGAN_ROBOT) - robot = "Prosthetic:" - if(e.open) - open = "Open:" - - switch (e.germ_level) - if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) - infected = "Mild Infection:" - if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) - infected = "Mild Infection+:" - if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) - infected = "Mild Infection++:" - if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) - infected = "Acute Infection:" - if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) - infected = "Acute Infection+:" - if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400) - infected = "Acute Infection++:" - if (INFECTION_LEVEL_THREE to INFINITY) - infected = "Septic:" - if(e.rejecting) - infected += "(being rejected)" - if (e.implants.len) - var/unknown_body = 0 - for(var/I in e.implants) - if(is_type_in_list(I,known_implants)) - imp += "[I] implanted:" + if(connected) + var/mob/living/carbon/human/occupant = connected.occupant + dat = "Occupant Statistics:
" //Blah obvious + if(istype(occupant)) //is there REALLY someone in there? + var/t1 + switch(occupant.stat) // obvious, see what their status is + if(0) + t1 = "Conscious" + if(1) + t1 = "Unconscious" else - unknown_body++ - if(unknown_body) - imp += "Unknown body present:" + t1 = "*dead*" + dat += "[occupant.health > 50 ? "" : ""]\tHealth %: [occupant.health], ([t1])
" - if(!AN && !open && !infected & !imp) - AN = "None:" - if(!e.is_stump()) - dat += "
" + if(occupant.virus2.len) + dat += "Viral pathogen detected in blood stream.
" + + var/extra_font = null + extra_font = (occupant.getBruteLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Brute Damage %: [occupant.getBruteLoss()]
" + + extra_font = (occupant.getOxyLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Respiratory Damage %: [occupant.getOxyLoss()]
" + + extra_font = (occupant.getToxLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Toxin Content %: [occupant.getToxLoss()]
" + + extra_font = (occupant.getFireLoss() < 60 ? "" : "") + dat += "[extra_font]\t-Burn Severity %: [occupant.getFireLoss()]
" + + extra_font = (occupant.radiation < 10 ?"" : "") + dat += "[extra_font]\tRadiation Level %: [occupant.radiation]
" + + extra_font = (occupant.getCloneLoss() < 1 ?"" : "") + dat += "[extra_font]\tGenetic Tissue Damage %: [occupant.getCloneLoss()]
" + + extra_font = (occupant.getBrainLoss() < 1 ?"" : "") + dat += "[extra_font]\tApprox. Brain Damage %: [occupant.getBrainLoss()]
" + + dat += "Paralysis Summary %: [occupant.paralysis] ([round(occupant.paralysis / 4)] seconds left!)
" + dat += "Body Temperature: [occupant.bodytemperature-T0C]°C ([occupant.bodytemperature*1.8-459.67]°F)
" + + dat += "
" + + if(occupant.has_brain_worms()) + dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" + + if(occupant.vessel) + var/blood_volume = round(occupant.vessel.get_reagent_amount("blood")) + var/blood_percent = blood_volume / 560 + blood_percent *= 100 + + extra_font = (blood_volume > 448 ? "" : "") + dat += "[extra_font]\tBlood Level %: [blood_percent] ([blood_volume] units)
" + + if(occupant.reagents) + for(var/datum/reagent/R in occupant.reagents) + dat += "Reagent: [R.name], Amount: [R.volume]
" + + dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]
" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + + for(var/obj/item/organ/external/e in occupant.organs) + dat += "" + var/AN = "" + var/open = "" + var/infected = "" + var/robot = "" + var/imp = "" + var/bled = "" + var/splint = "" + var/internal_bleeding = "" + var/lung_ruptured = "" + for(var/datum/wound/W in e.wounds) if(W.internal) + internal_bleeding = "
Internal bleeding" + break + if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured()) + lung_ruptured = "Lung ruptured:" + if(e.status & ORGAN_SPLINTED) + splint = "Splinted:" + if(e.status & ORGAN_BLEEDING) + bled = "Bleeding:" + if(e.status & ORGAN_BROKEN) + AN = "[e.broken_description]:" + if(e.status & ORGAN_ROBOT) + robot = "Prosthetic:" + if(e.open) + open = "Open:" + switch (e.germ_level) + if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) + infected = "Mild Infection:" + if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) + infected = "Mild Infection+:" + if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) + infected = "Mild Infection++:" + if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) + infected = "Acute Infection:" + if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) + infected = "Acute Infection+:" + if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400) + infected = "Acute Infection++:" + if (INFECTION_LEVEL_THREE to INFINITY) + infected = "Septic:" + + var/unknown_body = 0 + for(var/I in e.implants) + if(is_type_in_list(I,known_implants)) + imp += "[I] implanted:" + else + unknown_body++ + + if(unknown_body) + imp += "Unknown body present:" + if(!AN && !open && !infected & !imp) + AN = "None:" + if(!(e.status & ORGAN_DESTROYED)) + dat += "
" + else + dat += "" + dat += "" + for(var/obj/item/organ/i in occupant.internal_organs) + var/mech = i.desc + var/infection = "None" + switch (i.germ_level) + if (1 to INFECTION_LEVEL_ONE + 200) + infection = "Mild Infection:" + if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) + infection = "Mild Infection+:" + if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) + infection = "Mild Infection++:" + if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) + infection = "Acute Infection:" + if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) + infection = "Acute Infection+:" + if (INFECTION_LEVEL_TWO + 300 to INFINITY) + infection = "Acute Infection++:" + + dat += "" + dat += "" + dat += "" + dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured][e.name]--Not Found
[i.name]N/A[i.damage][infection]:[mech]
" + if(occupant.sdisabilities & BLIND) + dat += "Cataracts detected.
" + if(occupant.disabilities & NEARSIGHTED) + dat += "Retinal misalignment detected.
" else - dat += "[e.name]--Not [e.is_stump() ? "Found" : "Attached Completely"]" - dat += "" + dat += "\The [src] is empty." + else + dat = " Error: No Body Scanner connected." - for(var/obj/item/organ/i in occ["internal_organs"]) - - var/mech = "" - if(i.status & ORGAN_ASSISTED) - mech = "Assisted:" - if(i.status & ORGAN_ROBOT) - mech = "Mechanical:" - - var/infection = "None" - switch (i.germ_level) - if (1 to INFECTION_LEVEL_ONE + 200) - infection = "Mild Infection:" - if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) - infection = "Mild Infection+:" - if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) - infection = "Mild Infection++:" - if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) - infection = "Acute Infection:" - if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) - infection = "Acute Infection+:" - if (INFECTION_LEVEL_TWO + 300 to INFINITY) - infection = "Acute Infection++:" - if(i.rejecting) - infection += "(being rejected)" - - dat += "" - dat += "[i.name]N/A[i.damage][infection]:[mech]" - dat += "" - dat += "" - - var/list/species_organs = occ["species_organs"] - for(var/organ_name in species_organs) - if(!locate(species_organs[organ_name]) in occ["internal_organs"]) - dat += text("No [organ_name] detected.
") - - if(occ["sdisabilities"] & BLIND) - dat += text("Cataracts detected.
") - if(occ["sdisabilities"] & NEARSIGHTED) - dat += text("Retinal misalignment detected.
") - return dat + printing_text = dat \ No newline at end of file diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index c7b5f3c73a..43b9bf5913 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -94,13 +94,8 @@ obj/machinery/computer/general_air_control/Destroy() /obj/machinery/computer/general_air_control/attack_hand(mob/user) if(..(user)) return - user << browse(return_text(),"window=computer") - user.set_machine(src) - onclose(user, "computer") -/obj/machinery/computer/general_air_control/process() - ..() - src.updateUsrDialog() + ui_interact(user) /obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -110,43 +105,27 @@ obj/machinery/computer/general_air_control/Destroy() sensor_information[id_tag] = signal.data -/obj/machinery/computer/general_air_control/proc/return_text() - var/sensor_data +/obj/machinery/computer/general_air_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() + var/sensors_ui[0] if(sensors.len) for(var/id_tag in sensors) var/long_name = sensors[id_tag] - var/list/data = sensor_information[id_tag] - var/sensor_part = "[long_name]:
" - - if(data) - if(data["pressure"]) - sensor_part += " Pressure: [data["pressure"]] kPa
" - if(data["temperature"]) - sensor_part += " Temperature: [data["temperature"]] K
" - if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"]) - sensor_part += " Gas Composition :" - if(data["oxygen"]) - sensor_part += "[data["oxygen"]]% O2; " - if(data["nitrogen"]) - sensor_part += "[data["nitrogen"]]% N; " - if(data["carbon_dioxide"]) - sensor_part += "[data["carbon_dioxide"]]% CO2; " - if(data["phoron"]) - sensor_part += "[data["phoron"]]% TX; " - sensor_part += "
" - - else - sensor_part = "[long_name] can not be found!
" - - sensor_data += sensor_part - + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) else - sensor_data = "No sensors connected." + sensors_ui = null - var/output = {"[name]
-Sensor Data:

[sensor_data]"} + data["sensors"] = sensors_ui - return output + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency) radio_controller.remove_object(src, frequency) @@ -156,7 +135,6 @@ obj/machinery/computer/general_air_control/Destroy() /obj/machinery/computer/general_air_control/initialize() set_frequency(frequency) - /obj/machinery/computer/general_air_control/large_tank_control icon = 'icons/obj/computer.dmi' @@ -171,39 +149,40 @@ obj/machinery/computer/general_air_control/Destroy() var/pressure_setting = ONE_ATMOSPHERE * 45 circuit = /obj/item/weapon/circuitboard/air_management/tank_control +/obj/machinery/computer/general_air_control/large_tank_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) -/obj/machinery/computer/general_air_control/large_tank_control/return_text() - var/output = ..() - //if(signal.data) - // input_info = signal.data // Attempting to fix intake control -- TLE + var/list/data = list() + var/sensors_ui[0] + if(sensors.len) + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) + else + sensors_ui = null + + data["sensors"] = sensors_ui + data["tanks"] = 1 - output += "Tank Control System

" if(input_info) - var/power = (input_info["power"]) - var/volume_rate = round(input_info["volume_rate"], 0.1) - output += "Input: [power?("Injecting"):("On Hold")] Refresh
Flow Rate Limit: [volume_rate] L/s
" - output += "Command: Toggle Power Set Flow Rate
" - + data["input_info"] = list("power" = input_info["power"], "volume_rate" = round(input_info["volume_rate"], 0.1)) else - output += "ERROR: Can not find input port Search
" - - output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
" - - output += "
" - + data["input_info"] = null if(output_info) - var/power = (output_info["power"]) - var/output_pressure = output_info["internal"] - output += {"Output: [power?("Open"):("On Hold")] Refresh
-Max Output Pressure: [output_pressure] kPa
"} - output += "Command: Toggle Power Set Pressure
" - + data["output_info"] = list("power" = output_info["power"], "output_pressure" = output_info["internal"]) else - output += "ERROR: Can not find output port Search
" + data["output_info"] = null - output += "Max Output Pressure Set: - - - - [pressure_setting] kPa + + + +
" + data["input_flow_setting"] = round(input_flow_setting, 0.1) + data["pressure_setting"] = pressure_setting - return output + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -222,17 +201,13 @@ Max Output Pressure: [output_pressure] kPa
"} return 1 if(href_list["adj_pressure"]) - var/change = text2num(href_list["adj_pressure"]) + var/change = href_list["adj_pressure"] pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE) - spawn(1) - src.updateUsrDialog() return 1 if(href_list["adj_input_flow_rate"]) - var/change = text2num(href_list["adj_input_flow_rate"]) + var/change = href_list["adj_input_flow_rate"] input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors - spawn(1) - src.updateUsrDialog() return 1 if(!radio_connection) @@ -273,9 +248,6 @@ Max Output Pressure: [output_pressure] kPa
"} signal.data["sigtype"]="command" radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - spawn(5) - src.updateUsrDialog() - /obj/machinery/computer/general_air_control/supermatter_core icon = 'icons/obj/computer.dmi' @@ -290,39 +262,40 @@ Max Output Pressure: [output_pressure] kPa
"} var/pressure_setting = 100 circuit = /obj/item/weapon/circuitboard/air_management/supermatter_core +/obj/machinery/computer/general_air_control/supermatter_core/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) -/obj/machinery/computer/general_air_control/supermatter_core/return_text() - var/output = ..() - //if(signal.data) - // input_info = signal.data // Attempting to fix intake control -- TLE + var/list/data = list() + var/sensors_ui[0] + if(sensors.len) + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) + else + sensors_ui = null + + data["sensors"] = sensors_ui + data["core"] = 1 - output += "Core Cooling Control System

" if(input_info) - var/power = (input_info["power"]) - var/volume_rate = round(input_info["volume_rate"], 0.1) - output += "Coolant Input: [power?("Injecting"):("On Hold")] Refresh
Flow Rate Limit: [volume_rate] L/s
" - output += "Command: Toggle Power Set Flow Rate
" - + data["input_info"] = list("power" = input_info["power"], "volume_rate" = round(input_info["volume_rate"], 0.1)) else - output += "ERROR: Can not find input port Search
" - - output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
" - - output += "
" - + data["input_info"] = null if(output_info) - var/power = (output_info["power"]) - var/pressure_limit = output_info["external"] - output += {"Core Outpump: [power?("Open"):("On Hold")] Refresh
-Min Core Pressure: [pressure_limit] kPa
"} - output += "Command: Toggle Power Set Pressure
" - + data["output_info"] = list("power" = output_info["power"], "pressure_limit" = output_info["external"]) else - output += "ERROR: Can not find output port Search
" + data["output_info"] = null - output += "Min Core Pressure Set: - - - - [pressure_setting] kPa + + + +
" + data["input_flow_setting"] = round(input_flow_setting, 0.1) + data["pressure_setting"] = pressure_setting - return output + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -341,17 +314,13 @@ Min Core Pressure: [pressure_limit] kPa
"} return 1 if(href_list["adj_pressure"]) - var/change = text2num(href_list["adj_pressure"]) + var/change = href_list["adj_pressure"] pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE) - spawn(1) - src.updateUsrDialog() return 1 if(href_list["adj_input_flow_rate"]) - var/change = text2num(href_list["adj_input_flow_rate"]) + var/change = href_list["adj_input_flow_rate"] input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors - spawn(1) - src.updateUsrDialog() return 1 if(!radio_connection) @@ -392,9 +361,6 @@ Min Core Pressure: [pressure_limit] kPa
"} signal.data["sigtype"]="command" radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - spawn(5) - src.updateUsrDialog() - /obj/machinery/computer/general_air_control/fuel_injection icon = 'icons/obj/computer.dmi' icon_screen = "alert:0" @@ -437,27 +403,34 @@ Min Core Pressure: [pressure_limit] kPa
"} ..() -/obj/machinery/computer/general_air_control/fuel_injection/return_text() - var/output = ..() - - output += "Fuel Injection System
" - if(device_info) - var/power = device_info["power"] - var/volume_rate = device_info["volume_rate"] - output += {"Status: [power?("Injecting"):("On Hold")] Refresh
-Rate: [volume_rate] L/sec
"} - - if(automation) - output += "Automated Fuel Injection: Engaged
" - output += "Injector Controls Locked Out
" - else - output += "Automated Fuel Injection: Disengaged
" - output += "Injector: Toggle Power Inject (1 Cycle)
" +/obj/machinery/computer/general_air_control/fuel_injection/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + var/list/data = list() + var/sensors_ui[0] + if(sensors.len) + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) else - output += "ERROR: Can not find device Search
" + sensors_ui = null - return output + data["sensors"] = sensors_ui + data["fuel"] = 1 + data["automation"] = automation + + if(device_info) + data["device_info"] = list("power" = device_info["power"], "volume_rate" = device_info["volume_rate"]) + else + data["device_info"] = null + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 8427a08418..5cc9801d0f 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -22,62 +22,51 @@ add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - interact(user) + ui_interact(user) /obj/machinery/computer/operating/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - interact(user) - - -/obj/machinery/computer/operating/interact(mob/user) - if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) ) - if (!istype(user, /mob/living/silicon)) - user.unset_machine() - user << browse(null, "window=op") - return + ui_interact(user) +/** + * Display the NanoUI window for the operating computer. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) user.set_machine(src) - var/dat = "Operating Computer\n" - dat += "Close

" //| Update" - if(src.table && (src.table.check_victim())) - src.victim = src.table.victim - dat += {" -Patient Information:
-
-Name: [src.victim.real_name]
-Age: [src.victim.age]
-Blood Type: [src.victim.b_type]
-
-Health: [src.victim.health]
-Brute Damage: [src.victim.getBruteLoss()]
-Toxins Damage: [src.victim.getToxLoss()]
-Fire Damage: [src.victim.getFireLoss()]
-Suffocation Damage: [src.victim.getOxyLoss()]
-Patient Status: [src.victim.stat ? "Non-Responsive" : "Stable"]
-Heartbeat rate: [victim.get_pulse(GETPULSE_TOOL)]
-"} - else - src.victim = null - dat += {" -Patient Information:
-
-No Patient Detected -"} - user << browse(dat, "window=op") - onclose(user, "op") + var/list/data = list() + var/list/victim_ui = list() + + if(table && (table.check_victim())) + victim = table.victim + + victim_ui = list("real_name" = victim.real_name, "age" = victim.age, "b_type" = victim.b_type, "health" = victim.health, + "brute" = victim.getBruteLoss(), "tox" = src.victim.getToxLoss(), "burn" = victim.getFireLoss(), "oxy" = victim.getOxyLoss(), + "stat" = (victim.stat ? "Non-Responsive" : "Stable"), "pulse" = victim.get_pulse(GETPULSE_TOOL)) + else + victim = null + victim_ui = null + + data["table"] = table + data["victim"] = victim_ui + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "operating.tmpl", src.name, 380, 400) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/operating/Topic(href, href_list) if(..()) return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) - return - -/obj/machinery/computer/operating/process() - if(..()) - src.updateDialog() + src.add_fingerprint(usr) + nanomanager.update_uis(src) \ No newline at end of file diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 189fe5b40a..68b62bd1ab 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -53,7 +53,7 @@ prize.loc = src.loc /obj/machinery/computer/arcade/attack_ai(mob/user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/computer/arcade/emp_act(severity) @@ -103,81 +103,79 @@ name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") - src.enemy_name = replacetext((name_part1 + name_part2), "the ", "") - src.name = (name_action + name_part1 + name_part2) + enemy_name = replacetext((name_part1 + name_part2), "the ", "") + name = (name_action + name_part1 + name_part2) /obj/machinery/computer/arcade/battle/attack_hand(mob/user as mob) if(..()) return user.set_machine(src) - var/dat = "Close" - dat += "

[src.enemy_name]

" + ui_interact(user) - dat += "

[src.temp]

" - dat += "
Health: [src.player_hp] | Magic: [src.player_mp] | Enemy Health: [src.enemy_hp]
" +/** + * Display the NanoUI window for the arcade machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/arcade/battle/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - dat += "
" - if (src.gameover) - dat += "New Game" - else - dat += "Attack | " - dat += "Heal | " - dat += "Recharge Power" + var/list/data = list() + data["temp"] = temp + data["enemyName"] = enemy_name + data["playerHP"] = player_hp + data["playerMP"] = player_mp + data["enemyHP"] = enemy_hp + data["gameOver"] = gameover - dat += "
" - - user << browse(dat, "window=arcade") - onclose(user, "arcade") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "arcade_battle.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + //ui.set_auto_update(2) /obj/machinery/computer/arcade/battle/Topic(href, href_list) if(..()) return 1 - if (!src.blocked && !src.gameover) + if (!blocked && !gameover) if (href_list["attack"]) - src.blocked = 1 + blocked = 1 var/attackamt = rand(2,6) - src.temp = "You attack for [attackamt] damage!" - src.updateUsrDialog() + temp = "You attack for [attackamt] damage!" if(turtle > 0) turtle-- sleep(10) - src.enemy_hp -= attackamt - src.arcade_action() + enemy_hp -= attackamt + arcade_action() else if (href_list["heal"]) - src.blocked = 1 + blocked = 1 var/pointamt = rand(1,3) var/healamt = rand(6,8) - src.temp = "You use [pointamt] magic to heal for [healamt] damage!" - src.updateUsrDialog() + temp = "You use [pointamt] magic to heal for [healamt] damage!" turtle++ sleep(10) - src.player_mp -= pointamt - src.player_hp += healamt - src.blocked = 1 - src.updateUsrDialog() - src.arcade_action() + player_mp -= pointamt + player_hp += healamt + blocked = 1 + arcade_action() else if (href_list["charge"]) - src.blocked = 1 + blocked = 1 var/chargeamt = rand(4,7) - src.temp = "You regain [chargeamt] points" - src.player_mp += chargeamt + temp = "You regain [chargeamt] points" + player_mp += chargeamt if(turtle > 0) turtle-- - src.updateUsrDialog() sleep(10) - src.arcade_action() + arcade_action() - if (href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") else if (href_list["newgame"]) //Reset everything temp = "New Round" @@ -193,14 +191,14 @@ emagged = 0 src.add_fingerprint(usr) - src.updateUsrDialog() + nanomanager.update_uis(src) return /obj/machinery/computer/arcade/battle/proc/arcade_action() - if ((src.enemy_mp <= 0) || (src.enemy_hp <= 0)) + if ((enemy_mp <= 0) || (enemy_hp <= 0)) if(!gameover) - src.gameover = 1 - src.temp = "[src.enemy_name] has fallen! Rejoice!" + gameover = 1 + temp = "[enemy_name] has fallen! Rejoice!" if(emagged) feedback_inc("arcade_win_emagged") @@ -212,53 +210,52 @@ emagged = 0 else if(!contents.len) feedback_inc("arcade_win_normal") - src.prizevend() + prizevend() else feedback_inc("arcade_win_normal") - src.prizevend() + prizevend() else if (emagged && (turtle >= 4)) var/boomamt = rand(5,10) - src.temp = "[src.enemy_name] throws a bomb, exploding you for [boomamt] damage!" - src.player_hp -= boomamt + temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" + player_hp -= boomamt - else if ((src.enemy_mp <= 5) && (prob(70))) + else if ((enemy_mp <= 5) && (prob(70))) var/stealamt = rand(2,3) - src.temp = "[src.enemy_name] steals [stealamt] of your power!" - src.player_mp -= stealamt - src.updateUsrDialog() + temp = "[enemy_name] steals [stealamt] of your power!" + player_mp -= stealamt - if (src.player_mp <= 0) - src.gameover = 1 + if (player_mp <= 0) + gameover = 1 sleep(10) - src.temp = "You have been drained! GAME OVER" + temp = "You have been drained! GAME OVER" if(emagged) feedback_inc("arcade_loss_mana_emagged") usr.gib() else feedback_inc("arcade_loss_mana_normal") - else if ((src.enemy_hp <= 10) && (src.enemy_mp > 4)) - src.temp = "[src.enemy_name] heals for 4 health!" - src.enemy_hp += 4 - src.enemy_mp -= 4 + else if ((enemy_hp <= 10) && (enemy_mp > 4)) + temp = "[enemy_name] heals for 4 health!" + enemy_hp += 4 + enemy_mp -= 4 else var/attackamt = rand(3,6) - src.temp = "[src.enemy_name] attacks for [attackamt] damage!" - src.player_hp -= attackamt + temp = "[enemy_name] attacks for [attackamt] damage!" + player_hp -= attackamt - if ((src.player_mp <= 0) || (src.player_hp <= 0)) - src.gameover = 1 - src.temp = "You have been crushed! GAME OVER" + if ((player_mp <= 0) || (player_hp <= 0)) + gameover = 1 + temp = "You have been crushed! GAME OVER" if(emagged) feedback_inc("arcade_loss_hp_emagged") usr.gib() else feedback_inc("arcade_loss_hp_normal") - src.blocked = 0 + blocked = 0 return @@ -276,7 +273,6 @@ enemy_name = "Cuban Pete" name = "Outbomb Cuban Pete" - src.updateUsrDialog() return 1 diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 83b6f2ce86..68bac8ec1e 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -16,6 +16,7 @@ var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything. var/loading = 0 // Nice loading text + /obj/machinery/computer/cloning/initialize() ..() updatemodules() @@ -25,7 +26,7 @@ ..() /obj/machinery/computer/cloning/proc/updatemodules() - src.scanner = findscanner() + scanner = findscanner() releasecloner() findcloner() @@ -63,12 +64,12 @@ /obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) + if (!diskette) user.drop_item() W.loc = src - src.diskette = W + diskette = W user << "You insert [W]." - src.updateUsrDialog() + updateUsrDialog() return else if(istype(W, /obj/item/device/multitool)) var/obj/item/device/multitool/M = W @@ -78,6 +79,15 @@ P.connected = src P.name = "[initial(P.name)] #[pods.len]" user << "You connect [P] to [src]." + + else if (menu == 4 && (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))) + if(check_access(W)) + records.Remove(active_record) + qdel(active_record) + temp = "Record deleted." + menu = 2 + else + temp = "Access Denied." else ..() return @@ -94,109 +104,53 @@ updatemodules() - var/dat = "

Cloning System Control

" - dat += "Refresh" + ui_interact(user) - dat += "
[temp]
" +/obj/machinery/computer/cloning/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - switch(src.menu) - if(1) - // Modules - dat += "

Modules

" - //dat += "Reload Modules" - if (isnull(src.scanner)) - dat += " DNA scanner not found.
" - else - dat += " DNA scanner found.
" - if (pods.len) - dat += " [pods.len] cloning vat\s found.
" - else - dat += " No cloning vats found.
" + var/data[0] - // Scanner - dat += "

Scanner Functions

" + var/records_list_ui[0] + for(var/datum/dna2/record/R in records) + records_list_ui[++records_list_ui.len] = list("record" = R, "name" = R.dna.real_name) - if(loading) - dat += "Scanning...
" - else - dat += "[scantemp]
" + var/pods_list_ui[0] + for(var/obj/machinery/clonepod/pod in pods) + pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.biomass) - if (isnull(src.scanner)) - dat += "No scanner connected!
" - else - if (src.scanner.occupant) - if(scantemp == "Scanner unoccupied") scantemp = "" // Stupid check to remove the text + if(pods) + data["pods"] = pods + else + data["pods"] = null - dat += "Scan - [src.scanner.occupant]
" - else - scantemp = "Scanner unoccupied" + if(records) + data["records"] = records_list_ui + else + data["records"] = null - dat += "Lock status: [src.scanner.locked ? "Locked" : "Unlocked"]
" + if(active_record) + data["activeRecord"] = list("active_record" = active_record, "real_name" = active_record.dna.real_name, \ + "ui" = active_record.dna.uni_identity, "se" = active_record.dna.struc_enzymes) + else + data["activeRecord"] = null - if (pods.len) - for (var/obj/machinery/clonepod/pod in pods) - dat += "[pod] biomass: [pod.biomass]
" + data["menu"] = menu + data["connected"] = scanner + data["podsLen"] = pods.len + data["loading"] = loading + data["scantemp"] = scantemp + data["occupant"] = scanner.occupant + data["locked"] = scanner.locked + data["diskette"] = diskette + data["temp"] = temp - // Database - dat += "

Database Functions

" - dat += "View Records
" - if (src.diskette) - dat += "Eject Disk" - - - if(2) - dat += "

Current records

" - dat += "Back

" - for(var/datum/dna2/record/R in src.records) - dat += "
  • [R.dna.real_name]
  • " - - if(3) - dat += "

    Selected Record

    " - dat += "Back
    " - - if (!src.active_record) - dat += "ERROR: Record not found." - else - dat += {"
    Delete Record
    - Name: [src.active_record.dna.real_name]
    "} - var/obj/item/weapon/implant/health/H = null - if(src.active_record.implant) - H=locate(src.active_record.implant) - - if ((H) && (istype(H))) - dat += "Health: [H.sensehealth()] | OXY-BURN-TOX-BRUTE
    " - else - dat += "Unable to locate implant.
    " - - if (!isnull(src.diskette)) - dat += "Load from disk." - - dat += " | Save: UI + UE" - dat += " | Save: UI" - dat += " | Save: SE" - dat += "
    " - else - dat += "
    " //Keeping a line empty for appearances I guess. - - dat += {"UI: [src.active_record.dna.uni_identity]
    - SE: [src.active_record.dna.struc_enzymes]

    "} - - if(pods.len) - dat += {"Clone
    "} - - if(4) - if (!src.active_record) - src.menu = 2 - dat = "[src.temp]
    " - dat += "

    Confirm Record Deletion

    " - - dat += "Scan card to confirm.
    " - dat += "No" - - - user << browse(dat, "window=cloning") - onclose(user, "cloning") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "cloning.tmpl", src.name, 400, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/cloning/Topic(href, href_list) if(..()) @@ -205,98 +159,80 @@ if(loading) return - if ((href_list["scan"]) && (!isnull(src.scanner))) + if ((href_list["scan"]) && (!isnull(scanner))) scantemp = "" loading = 1 - src.updateUsrDialog() spawn(20) - src.scan_mob(src.scanner.occupant) + scan_mob(scanner.occupant) loading = 0 - src.updateUsrDialog() - //No locking an open scanner. - else if ((href_list["lock"]) && (!isnull(src.scanner))) - if ((!src.scanner.locked) && (src.scanner.occupant)) - src.scanner.locked = 1 + else if ((href_list["lock"]) && (!isnull(scanner))) + if ((!scanner.locked) && (scanner.occupant)) + scanner.locked = 1 else - src.scanner.locked = 0 + scanner.locked = 0 else if (href_list["view_rec"]) - src.active_record = locate(href_list["view_rec"]) - if(istype(src.active_record,/datum/dna2/record)) - if ((isnull(src.active_record.ckey))) - qdel(src.active_record) - src.temp = "ERROR: Record Corrupt" + active_record = locate(href_list["view_rec"]) + if(istype(active_record,/datum/dna2/record)) + if ((isnull(active_record.ckey))) + qdel(active_record) + temp = "ERROR: Record Corrupt" else - src.menu = 3 + menu = 3 else - src.active_record = null - src.temp = "Record missing." + active_record = null + temp = "Record missing." else if (href_list["del_rec"]) - if ((!src.active_record) || (src.menu < 3)) + if ((!active_record) || (menu < 3)) return - if (src.menu == 3) //If we are viewing a record, confirm deletion - src.temp = "Delete record?" - src.menu = 4 - - else if (src.menu == 4) - var/obj/item/weapon/card/id/C = usr.get_active_hand() - if (istype(C)||istype(C, /obj/item/device/pda)) - if(src.check_access(C)) - src.records.Remove(src.active_record) - qdel(src.active_record) - src.temp = "Record deleted." - src.menu = 2 - else - src.temp = "Access Denied." + if (menu == 3) //If we are viewing a record, confirm deletion + temp = "Delete record?" + menu = 4 else if (href_list["disk"]) //Load or eject. switch(href_list["disk"]) if("load") - if ((isnull(src.diskette)) || isnull(src.diskette.buf)) - src.temp = "Load error." - src.updateUsrDialog() + if ((isnull(diskette)) || isnull(diskette.buf)) + temp = "Load error." return - if (isnull(src.active_record)) - src.temp = "Record error." - src.menu = 1 - src.updateUsrDialog() + if (isnull(active_record)) + temp = "Record error." + menu = 1 return - src.active_record = src.diskette.buf + active_record = diskette.buf - src.temp = "Load successful." + temp = "Load successful." if("eject") - if (!isnull(src.diskette)) - src.diskette.loc = src.loc - src.diskette = null + if (!isnull(diskette)) + diskette.loc = loc + diskette = null else if (href_list["save_disk"]) //Save to disk! - if ((isnull(src.diskette)) || (src.diskette.read_only) || (isnull(src.active_record))) - src.temp = "Save error." - src.updateUsrDialog() - return + if ((isnull(diskette)) || (diskette.read_only) || (isnull(active_record))) + temp = "Save error." // DNA2 makes things a little simpler. - src.diskette.buf=src.active_record - src.diskette.buf.types=0 + diskette.buf = active_record + diskette.buf.types = 0 switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se if("ui") - src.diskette.buf.types=DNA2_BUF_UI + diskette.buf.types = DNA2_BUF_UI if("ue") - src.diskette.buf.types=DNA2_BUF_UI|DNA2_BUF_UE + diskette.buf.types = DNA2_BUF_UI | DNA2_BUF_UE if("se") - src.diskette.buf.types=DNA2_BUF_SE - src.diskette.name = "data disk - '[src.active_record.dna.real_name]'" - src.temp = "Save \[[href_list["save_disk"]]\] successful." + diskette.buf.types = DNA2_BUF_SE + diskette.name = "data disk - '[active_record.dna.real_name]'" + temp = "Save \[[href_list["save_disk"]]\] successful." else if (href_list["refresh"]) - src.updateUsrDialog() + updateUsrDialog() else if (href_list["clone"]) var/datum/dna2/record/C = locate(href_list["clone"]) @@ -340,11 +276,10 @@ temp = "Error: Data corruption." else if (href_list["menu"]) - src.menu = text2num(href_list["menu"]) + menu = href_list["menu"] - src.add_fingerprint(usr) - src.updateUsrDialog() - return + nanomanager.update_uis(src) + add_fingerprint(usr) /obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob) if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna)) @@ -381,13 +316,13 @@ subject.dna.check_integrity() var/datum/dna2/record/R = new /datum/dna2/record() - R.dna=subject.dna + R.dna = subject.dna R.ckey = subject.ckey - R.id= copytext(md5(subject.real_name), 2, 6) - R.name=R.dna.real_name - R.types=DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE - R.languages=subject.languages - R.flavor=subject.flavor_texts.Copy() + R.id = copytext(md5(subject.real_name), 2, 6) + R.name = R.dna.real_name + R.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE + R.languages = subject.languages + R.flavor = subject.flavor_texts.Copy() //Add an implant if needed var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) @@ -402,13 +337,13 @@ if (!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning. R.mind = "\ref[subject.mind]" - src.records += R + records += R scantemp = "Subject successfully scanned." //Find a specific record by key. /obj/machinery/computer/cloning/proc/find_record(var/find_key) var/selected_record = null - for(var/datum/dna2/record/R in src.records) + for(var/datum/dna2/record/R in records) if (R.ckey == find_key) selected_record = R break diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index a4553403bc..eeec3a703e 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -102,40 +102,51 @@ return user.set_machine(src) - var/dat - if (mode == 1) //Logs - dat += "

    Activity log


    " - for (var/entry in internal_log) - dat += "[entry]

    " - dat += "Print
    " - dat += "Back
    " - else - dat += "

    Guest pass terminal #[uid]


    " - dat += "View activity log

    " - dat += "Issuing ID: [giver]
    " - dat += "Issued to: [giv_name]
    " - dat += "Reason: [reason]
    " - dat += "Duration (minutes): [duration] m
    " - dat += "Access to areas:
    " - if (giver && giver.access) - for (var/A in giver.access) - var/area = get_access_desc(A) - if (A in accesses) - area = "[area]" - dat += "[area]
    " - dat += "
    Issue pass
    " + ui_interact(user) - user << browse(dat, "window=guestpass;size=400x520") - onclose(user, "guestpass") +/** + * Display the NanoUI window for the guest pass console. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/guestpass/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + var/list/data = list() + + var/area_list[0] + + if (giver && giver.access) + data["access"] = giver.access + for (var/A in giver.access) + if(A in accesses) + area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = 1) + else + area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = null) + + data["giver"] = giver + data["giveName"] = giv_name + data["reason"] = reason + data["duration"] = duration + data["area"] = area_list + data["mode"] = mode + data["log"] = internal_log + data["uid"] = uid + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "guest_pass.tmpl", src.name, 400, 520) + ui.set_initial_data(data) + ui.open() + //ui.set_auto_update(5) /obj/machinery/computer/guestpass/Topic(href, href_list) if(..()) return 1 usr.set_machine(src) if (href_list["mode"]) - mode = text2num(href_list["mode"]) + mode = href_list["mode"] if (href_list["choice"]) switch(href_list["choice"]) @@ -182,7 +193,6 @@ if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) I.loc = src giver = I - updateUsrDialog() if ("print") var/dat = "

    Activity log of guest pass terminal #[uid]


    " @@ -213,6 +223,4 @@ pass.reason = reason pass.name = "guest pass #[number]" else - usr << "Cannot issue pass without issuing ID." - updateUsrDialog() - return + usr << "Cannot issue pass without issuing ID." \ No newline at end of file diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm index efd0747b35..ceb66a68bd 100644 --- a/code/game/machinery/computer3/lapvend.dm +++ b/code/game/machinery/computer3/lapvend.dm @@ -6,12 +6,10 @@ layer = 2.9 anchored = 1 density = 1 - var/datum/browser/popup = null var/obj/machinery/computer3/laptop/vended/newlap = null var/obj/item/device/laptop/relap = null var/vendmode = 0 - var/cardreader = 0 var/floppy = 0 var/radionet = 0 @@ -34,7 +32,7 @@ if(vendmode == 1 && I) scan_id(I, W) vendmode = 0 - if(vendmode == 3 && I) + if(vendmode == 2 && I) if(reimburse_id(I, W)) vendmode = 0 if(vendmode == 0) @@ -44,84 +42,48 @@ calc_reimburse(L) usr.drop_item() L.loc = src - vendmode = 3 + vendmode = 2 usr << "You slot your [L.name] into \The [src.name]" else ..() /obj/machinery/lapvend/attack_hand(mob/user as mob) + if(stat & (BROKEN|NOPOWER)) + return + + ui_interact(user) + +/** + * Display the NanoUI window for the vending machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) user.set_machine(src) - var/vendorname = (src.name) //import the machine's name - var/dat = "
    [vendorname]


    " //display the name, and added a horizontal rule - if(vendmode == 0) - dat += "
    Please choose your laptop customization options

    " - dat += "
    Your comptuer will automatically be loaded with any programs you can use after the transaction is complete.
    " - dat += "
    Some programs will require additional components to be installed!


    " - dat += "
    HDD (Required) : Added

    " - dat += "
    Card Reader : Single (50) | Dual (125)

    " - dat += "
    Floppy Drive: Add (50)

    " - dat += "
    Radio Network card Add (50)

    " - dat += "
    Camera Card Add (100)

    " - dat += "
    Network card Area (75) Adjacent (50)Powernet (25)

    " - dat += "
    Power source upgrade
    Extended (175) Unreal (250)" - if(vendmode == 0 || vendmode == 1) - dat += "

    Cart

    " - dat += "Total: [total()]
    " - if(cardreader == 1) - dat += "Card Reader: (single) (50)
    " - else if (cardreader == 2) - dat += "Card Reader: (double) (125)
    " - else - dat += "Card Reader: None
    " - if(floppy == 0) - dat += "Floppy Drive: None
    " - else - dat += "Floppy Drive: Added (50)
    " - if(radionet == 1) - dat += "Radio Card: Added (50)
    " - else - dat += "Radio Card: None
    " - if(camera == 1) - dat += "Camera Card: Added (100)
    " - else - dat += "Camera Card: None
    " - if(network == 1) - dat += "Network card: Area (75)
    " - else if(network == 2) - dat += "Network card: Adjacent (50)
    " - else if(network == 3) - dat += "Network card: Powernet (25)
    " - else - dat += "Network card: None" - if (power == 0) - dat += "Power source: Regular" - else if (power == 1) - dat += "Power source: Extended (175)
    " - else - dat += "Power source: Unreal (250)
    " - - if(vendmode == 0) - dat += "
    Vend Laptop" - - if(vendmode == 1) - dat += "Please swipe your card and enter your PIN to complete the transaction" - - if(vendmode == 3) - dat += "Please swipe your card and enter your PIN to be finish returning your computer
    " - dat += "Cancel" - - - - - popup = new(user, "lapvend", name, 450, 500) - popup.set_content(dat) - popup.open() - return + var/list/data = list() + data["mode"] = vendmode + data["cardreader"] = cardreader + data["floppy"] = floppy + data["radionet"] = radionet + data["camera"] = camera + data["network"] = network + data["power"] = power + data["total"] = total() + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "laptop_vendor.tmpl", src.name, 480, 500) + ui.set_initial_data(data) + ui.open() + //ui.set_auto_update(5) /obj/machinery/lapvend/Topic(href, href_list) + if(stat & (BROKEN|NOPOWER)) + return + if(usr.stat || usr.restrained()) + return if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) usr.set_machine(src) switch(href_list["choice"]) @@ -146,7 +108,7 @@ if ("super_add") power = 2 - if ("single_rem" || "dual_rem") + if ("cardreader_rem") cardreader = 0 if ("floppy_rem") floppy = 0 @@ -154,9 +116,9 @@ radionet = 0 if ("camnet_rem") camera = 0 - if ("area_rem" || "prox_rem" || "cable_rem") + if ("network_rem") network = 0 - if ("high_rem" || "super_rem") + if ("power_rem") power = 0 if("vend") @@ -168,9 +130,8 @@ relap = null vendmode = 0 - src.updateUsrDialog() - return - + src.add_fingerprint(usr) + nanomanager.update_uis(src) /obj/machinery/lapvend/proc/vend() if(cardreader > 0) @@ -253,7 +214,6 @@ choose_progs(C) vend() - popup.close() newlap.close_laptop() newlap = null cardreader = 0 diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index 4c0d0a755e..fd887db55e 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -30,62 +30,60 @@ "Snow Field" = "snowfield", \ "Theatre" = "theatre", \ "Meeting Hall" = "meetinghall", \ - "Courtroom" = "courtroom" \ + "Courtroom" = "courtroom", \ + "Turn Off" = "turnoff" \ ) var/list/restricted_programs = list("Atmospheric Burn Simulation" = "burntest", "Wildlife Simulation" = "wildlifecarp") + var/current_program = "turnoff" /obj/machinery/computer/HolodeckControl/attack_ai(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/computer/HolodeckControl/attack_hand(var/mob/user as mob) - if(..()) return user.set_machine(src) - var/dat - dat += "Holodeck Control System
    " - dat += "
    Current Loaded Programs:
    " - for(var/prog in supported_programs) - dat += "([prog])
    " + ui_interact(user) - dat += "
    " - dat += "(Turn Off)
    " +/** + * Display the NanoUI window for the Holodeck Computer. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/HolodeckControl/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - dat += "
    " - dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
    " + var/list/data = list() + var/program_list[0] + var/restricted_program_list[0] + for(var/P in supported_programs) + program_list[++program_list.len] = list("name" = P, "program" = supported_programs[P]) + + for(var/P in restricted_programs) + restricted_program_list[++restricted_program_list.len] = list("name" = P, "program" = restricted_programs[P]) + + data["supportedPrograms"] = program_list + data["restrictedPrograms"] = restricted_program_list + data["currentProgram"] = current_program if(issilicon(user)) - dat += "
    " - if(safety_disabled) - if (emagged) - dat += "ERROR: Cannot re-enable Safety Protocols.
    " - else - dat += "(Re-Enable Safety Protocols?)
    " - else - dat += "(Override Safety Protocols?)
    " - - dat += "
    " - - if(safety_disabled) - for(var/prog in restricted_programs) - dat += "(Begin [prog])
    " - dat += "Ensure the holodeck is empty before testing.
    " - dat += "
    " - dat += "Safety Protocols are DISABLED
    " + data["isSilicon"] = 1 else - dat += "Safety Protocols are ENABLED
    " - + data["isSilicon"] = null + data["safetyDisabled"] = safety_disabled + data["emagged"] = emagged if(linkedholodeck.has_gravity) - dat += "Gravity is (ON)
    " + data["gravity"] = 1 else - dat += "Gravity is (OFF)
    " - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - - return + data["gravity"] = null + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "holodeck.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + //ui.set_auto_update(5) /obj/machinery/computer/HolodeckControl/Topic(href, href_list) if(..()) @@ -97,6 +95,7 @@ var/prog = href_list["program"] if(prog in holodeck_programs) loadProgram(holodeck_programs[prog]) + current_program = href_list["program"] else if(href_list["AIoverride"]) if(!issilicon(usr)) @@ -118,8 +117,8 @@ toggleGravity(linkedholodeck) src.add_fingerprint(usr) - src.updateUsrDialog() - return + + nanomanager.update_uis(src) /obj/machinery/computer/HolodeckControl/emag_act(var/remaining_charges, var/mob/user as mob) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) @@ -132,7 +131,6 @@ user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call [company_name] maintenance and do not use the simulator." log_game("[key_name(usr)] emagged the Holodeck Control Computer") return 1 - src.updateUsrDialog() return /obj/machinery/computer/HolodeckControl/proc/update_projections() diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index a0f515ac13..27474a75c6 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -41,54 +41,37 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins /obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob) user.set_machine(src) - var/dat = "Fax Machine
    " + ui_interact(user) - var/scan_name +/** + * Display the NanoUI window for the fax machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() if(scan) - scan_name = scan.name + data["scanName"] = scan.name else - scan_name = "--------" - - dat += "Confirm Identity: [scan_name]
    " - - if(authenticated) - dat += "{Log Out}" + data["scanName"] = null + data["bossName"] = boss_name + data["authenticated"] = authenticated + data["copyItem"] = copyitem + if(copyitem) + data["copyItemName"] = copyitem.name else - dat += "{Log In}" + data["copyItemName"] = null + data["cooldown"] = sendcooldown + data["destination"] = destination - dat += "
    " - - if(authenticated) - dat += "Logged in to: [boss_name] Quantum Entanglement Network

    " - - if(copyitem) - dat += "Remove Item

    " - - if(sendcooldown) - dat += "Transmitter arrays realigning. Please stand by.
    " - - else - - dat += "Send
    " - dat += "Currently sending: [copyitem.name]
    " - dat += "Sending to: [destination]
    " - - else - if(sendcooldown) - dat += "Please insert paper to send via secure connection.

    " - dat += "Transmitter arrays realigning. Please stand by.
    " - else - dat += "Please insert paper to send via secure connection.

    " - - else - dat += "Proper authentication is required to use this device.

    " - - if(copyitem) - dat += "Remove Item
    " - - user << browse(dat, "window=copier") - onclose(user, "copier") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "fax.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(10) //this machine is so unimportant let's not have it update that often. /obj/machinery/photocopier/faxmachine/Topic(href, href_list) if(href_list["send"]) @@ -108,7 +91,6 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins usr.put_in_hands(copyitem) usr << "You take \the [copyitem] out of \the [src]." copyitem = null - updateUsrDialog() if(href_list["scan"]) if (scan) @@ -140,7 +122,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins if(href_list["logout"]) authenticated = 0 - updateUsrDialog() + nanomanager.update_uis(src) /obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) if(stat & (BROKEN|NOPOWER)) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index dcee1fb3fa..cee22ff30b 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -30,24 +30,32 @@ /obj/machinery/photocopier/attack_hand(mob/user as mob) user.set_machine(src) - var/dat = "Photocopier

    " - if(copyitem) - dat += "Remove Item
    " - if(toner) - dat += "Copy
    " - dat += "Printing: [copies] copies." - dat += "- " - dat += "+

    " - else if(toner) - dat += "Please insert something to copy.

    " + ui_interact(user) + +/** + * Display the NanoUI window for the photocopier. + * + * See NanoUI documentation for details. + */ +/obj/machinery/photocopier/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() + data["copyItem"] = copyitem + data["toner"] = toner + data["copies"] = copies + data["maxCopies"] = maxcopies if(istype(user,/mob/living/silicon)) - dat += "Print photo from database

    " - dat += "Current toner level: [toner]" - if(!toner) - dat +="
    Please insert a new toner cartridge!" - user << browse(dat, "window=copier") - onclose(user, "copier") - return + data["isSilicon"] = 1 + else + data["isSilicon"] = null + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "photocopier.tmpl", src.name, 400, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(10) /obj/machinery/photocopier/Topic(href, href_list) if(href_list["copy"]) @@ -72,22 +80,18 @@ break use_power(active_power_usage) - updateUsrDialog() else if(href_list["remove"]) if(copyitem) copyitem.loc = usr.loc usr.put_in_hands(copyitem) usr << "You take \the [copyitem] out of \the [src]." copyitem = null - updateUsrDialog() else if(href_list["min"]) if(copies > 1) copies-- - updateUsrDialog() else if(href_list["add"]) if(copies < maxcopies) copies++ - updateUsrDialog() else if(href_list["aipic"]) if(!istype(usr,/mob/living/silicon)) return if(stat & (BROKEN|NOPOWER)) return @@ -109,7 +113,8 @@ p.desc += " - Copied by [tempAI.name]" toner -= 5 sleep(15) - updateUsrDialog() + + nanomanager.update_uis(src) /obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob) if(istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo) || istype(O, /obj/item/weapon/paper_bundle)) @@ -119,7 +124,6 @@ O.loc = src user << "You insert \the [O] into \the [src]." flick(insert_anim, src) - updateUsrDialog() else user << "There is already something in \the [src]." else if(istype(O, /obj/item/device/toner)) @@ -129,7 +133,6 @@ var/obj/item/device/toner/T = O toner += T.toner_amount qdel(O) - updateUsrDialog() else user << "This cartridge is not yet ready for replacement! Use up the rest of the toner." else if(istype(O, /obj/item/weapon/wrench)) diff --git a/nano/templates/adv_med.tmpl b/nano/templates/adv_med.tmpl new file mode 100644 index 0000000000..5dc8c5e427 --- /dev/null +++ b/nano/templates/adv_med.tmpl @@ -0,0 +1,279 @@ + +{{if !data.occupied}} +

    No occupant detected.

    +{{else}} +

    Occupant Data:

    +
    +
    + Name: +
    +
    + {{:data.occupant.name}} +
    +
    +
    +
    + Health: +
    + {{:helper.displayBar(data.occupant.health, 0, 100, (data.occupant.health >= 50) ? 'good' : (data.occupant.health >= 25) ? 'average' : 'bad')}} +
    + {{:helper.round(data.occupant.health*10)/10}}% +
    +
    +
    + Status: +
    +
    + {{if data.occupant.stat==0}} + Alive + {{else data.occupant.stat==1}} + Critical + {{else}} + Dead + {{/if}} +
    +
    + {{:helper.link('Print', 'document', {'print_p' : 1, 'name' : data.occupant.name})}} +
    +

    Damage:

    +
    + Brute: +
    +
    + {{:data.occupant.bruteLoss}} +

    +
    + Burn: +
    +
    + {{:data.occupant.fireLoss}} +

    +
    + Oxygen: +
    +
    + {{:data.occupant.oxyLoss}} +

    +
    + Toxins: +
    +
    + {{:data.occupant.toxLoss}} +

    +
    + Brain: +
    +
    + {{:data.occupant.brainLoss}} +

    +
    + Radiation Level: +
    +
    + {{:data.occupant.radLoss}} +

    +
    + Genetic: +
    +
    + {{:data.occupant.cloneLoss}} +

    +
    + Paralysis: +
    +
    + {{:data.occupant.paralysis}}% ({{:data.occupant.paralysisSeconds}} seconds left!) +

    +
    +
    +
    + Body Temperature: +
    +
    + {{:data.occupant.bodyTempC}}°C, {{:data.occupant.bodyTempF}}°F +
    +
    + {{if data.occupant.hasVirus}} +
    + Viral pathogen detected in blood stream. +
    + {{/if}} + {{if data.occupant.hasBorer}} +
    + Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended. +
    + {{/if}} + {{if data.occupant.blind}} + Pupils unresponsive.
    + {{/if}} + {{if data.occupant.nearsighted}} + Retinal Misalignment Detected + {{/if}} +
    +
    + Blood +
    +
    +
    + Volume +
    +
    + {{:data.occupant.blood.volume}} +
    +
    + Percent +
    +
    + {{:data.occupant.blood.percent}}% +
    +
    +
    +
    + Reagents +
    +
    + {{for data.occupant.reagents}} +
    + {{:value.name}} +
    +
    + {{:value.amount}} +
    + {{/for}} +
    +
    + External Organs +
    + {{for data.occupant.extOrgan}} +
    + {{if value.status.destroyed}} +
    + {{:value.name}} - DESTROYED +
    + {{else}} +
    +
    + {{:value.name}} +
    +
    +
    + {{if value.status.broken}} + {{:value.status.broken}} + {{else value.status.splinted}} + Splinted + {{else value.status.robotic}} + Robotic + {{/if}} +
    +
    +  Brute/Burn +
    +
    + {{:value.bruteLoss}}/{{:value.fireLoss}} +
    +
    +  Injuries +
    +
    + {{if !value.status.bleeding}} + {{if !value.status.internalBleeding}} + No Injuries Detected + {{else}} + Internal Bleeding Detected + {{/if}} + {{else}} + {{if value.status.internalBleeding}} +
    Internal Bleeding Detected. External Bleeding Detected.
    + {{else}} + External Bleeding Detected + {{/if}} + {{/if}} +
    + {{if value.germ_level > 100}} +
    +  Infection +
    +
    + {{if value.germ_level < 300}} + Mild Infection + {{else value.germ_level < 400}} + Mild Infection+ + {{else value.germ_level < 500}} + Mild Infection++ + {{else value.germ_level < 700}} + Acute Infection + {{else value.germ_level < 800}} + Acute Infection+ + {{else value.germ_level < 900}} + Acute Infection++ + {{else value.germ_level >= 900}} + Septic + {{/if}} +
    + {{/if}} + {{if value.open}} +
    +  Operation Status +
    +
    + Open Incision +
    + {{/if}} + {{if value.implants_len}} +
    +  Implants +

    + {{for value.implants :impValue:impindex}} +
    +   {{:impValue.known ? impValue.name : "Unknown"}} +

    + {{/for}} + {{/if}} + {{/if}} +

    + {{/for}} +
    + Internal Organs +
    + {{for data.occupant.intOrgan}} +
    +
    + {{:value.name}} +
    +
    +
    + {{if value.germ_level > 100}} +
    +  Infection +
    +
    + {{if value.germ_level < 300}} + Mild Infection + {{else value.germ_level < 400}} + Mild Infection+ + {{else value.germ_level < 500}} + Mild Infection++ + {{else value.germ_level < 700}} + Acute Infection + {{else value.germ_level < 800}} + Acute Infection+ + {{else value.germ_level < 900}} + Acute Infection++ + {{else value.germ_level >= 900}} + Septic + {{/if}} +
    + {{/if}} +
    +  Damage +
    +
    + {{:value.damage}} +
    +
    + {{/for}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/arcade_battle.tmpl b/nano/templates/arcade_battle.tmpl new file mode 100644 index 0000000000..0455649404 --- /dev/null +++ b/nano/templates/arcade_battle.tmpl @@ -0,0 +1,26 @@ + + +

    {{:data.enemyName}}

    + +
    {{:data.temp}}
    +
    +
    Health:
    +
    {{:data.playerHP}}
    +
    Magic:
    +
    {{:data.playerMP}}
    +
    Enemy Health:
    +
    {{:data.enemyHP}}
    +
    + +{{if data.gameOver}} +
    {{:helper.link('New Game', null, {'newgame' : 1})}}
    +{{else}} +
    + {{:helper.link('Attack', null, {'attack' : 1})}} + {{:helper.link('Heal', null, {'heal' : 1})}} + {{:helper.link('Recharge Power', null, {'charge' : 1})}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/atmo_control.tmpl b/nano/templates/atmo_control.tmpl new file mode 100644 index 0000000000..503f15458f --- /dev/null +++ b/nano/templates/atmo_control.tmpl @@ -0,0 +1,218 @@ + +{{if data.sensors}} + {{for data.sensors}} + {{if value.sensor_data}} +
    + {{:value.long_name}} + {{if value.sensor_data.pressure}} +
    Pressure:
    + {{:value.sensor_data.pressure}} kPa + {{/if}} + {{if value.sensor_data.temperature}} +
    Temperature:
    + {{:value.sensor_data.temperature}} kPa + {{/if}} + {{if value.sensor_data.oxygen || value.sensor_data.nitrogen || value.sensor_data.carbon_dioxide || value.sensor_data.phoron}} +
    Gas Composition:
    + {{if value.sensor_data.oxygen}} + {{:value.sensor_data.pressure}} % O2 + {{/if}} + {{if value.sensor_data.nitrogen}} + {{:value.sensor_data.pressure}} % N + {{/if}} + {{if value.sensor_data.carbon_dioxide}} + {{:value.sensor_data.pressure}} % CO2 + {{/if}} + {{if value.sensor_data.phoron}} + {{:value.sensor_data.pressure}} % TX + {{/if}} + {{/if}} +
    + {{else}} +
    +
    {{:value.long_name}} can not be found!
    +
    + {{/if}} + {{/for}} +{{else}} +
    + No sensors connected. +
    +{{/if}} + +{{if data.tanks || data.core}} +

    + {{if data.tanks}} + Tank Control System + {{else data.core}} + Core Cooling Control System + {{/if}} +

    + + {{if data.input_info}} +
    +
    + {{if data.tanks}} + Input: + {{else data.core}} + Coolant Input: + {{/if}} +
    +
    + {{if data.input_info.power}} + Injecting + {{else}} + On Hold + {{/if}} +
    + {{:helper.link('Refresh', null, {'in_refresh_status' : 1})}} +
    +
    +
    Flow Rate Limit:
    +
    {{:data.input_info.volume_rate}} L/s
    +
    +
    +
    Command:
    + {{:helper.link('Toggle Power', null, {'in_toggle_injector' : 1})}} + {{:helper.link('Set Flow Rate', null, {'in_set_flowrate' : 1})}} +
    + {{else}} +
    +
    ERROR: Can not find input port
    + {{:helper.link('Search', null, {'in_refresh_status' : 1})}} +
    + {{/if}} +
    +
    + Flow Rate Limit: +
    +
    + {{:helper.link('-', null, {'adj_input_flow_rate' : -100})}} + {{:helper.link('-', null, {'adj_input_flow_rate' : -10})}} + {{:helper.link('-', null, {'adj_input_flow_rate' : -1})}} + {{:helper.link('-', null, {'adj_input_flow_rate' : -0.1})}} +
     {{:data.input_flow_setting}} L/s 
    + {{:helper.link('+', null, {'adj_input_flow_rate' : 0.1})}} + {{:helper.link('+', null, {'adj_input_flow_rate' : 1})}} + {{:helper.link('+', null, {'adj_input_flow_rate' : 10})}} + {{:helper.link('+', null, {'adj_input_flow_rate' : 100})}} +
    +
    + + {{if data.output_info}} +
    +
    + {{if data.tanks}} + Output: + {{else data.core}} + Core Outpump: + {{/if}} +
    +
    + {{if data.input_info.power}} + Open + {{else}} + On Hold + {{/if}} +
    + {{:helper.link('Refresh', null, {'out_refresh_status' : 1})}} +
    +
    + {{if data.tanks}} +
    Max Output Pressure:
    +
    {{:data.output_info.output_pressure}} kPa
    + {{else data.core}} +
    Min Core Pressure:
    +
    {{:data.output_info.pressure_limit}} kPa
    + {{/if}} +
    +
    +
    Command:
    + {{:helper.link('Toggle Power', null, {'out_toggle_power' : 1})}} + {{:helper.link('Set Pressure', null, {'out_set_pressure' : 1})}} +
    + {{else}} +
    +
    ERROR: Can not find output port
    + {{:helper.link('Search', null, {'out_refresh_status' : 1})}} +
    + {{/if}} + +
    + {{if data.tanks}} +
    + Max Output Pressure Set: +
    +
    + {{:helper.link('-', null, {'adj_pressure' : -1000})}} + {{:helper.link('-', null, {'adj_pressure' : -100})}} + {{:helper.link('-', null, {'adj_pressure' : -10})}} + {{:helper.link('-', null, {'adj_pressure' : -1})}} +
     {{:data.pressure_setting}} kPa 
    + {{:helper.link('+', null, {'adj_pressure' : 1})}} + {{:helper.link('+', null, {'adj_pressure' : 10})}} + {{:helper.link('+', null, {'adj_pressure' : 100})}} + {{:helper.link('+', null, {'adj_pressure' : 1000})}} +
    + {{else data.core}} +
    + Min Core Pressure Set: +
    +
    + {{:helper.link('-', null, {'adj_pressure' : -100})}} + {{:helper.link('-', null, {'adj_pressure' : -50})}} + {{:helper.link('-', null, {'adj_pressure' : -10})}} + {{:helper.link('-', null, {'adj_pressure' : -1})}} +
     {{:data.pressure_setting}} kPa 
    + {{:helper.link('+', null, {'adj_pressure' : 1})}} + {{:helper.link('+', null, {'adj_pressure' : 10})}} + {{:helper.link('+', null, {'adj_pressure' : 50})}} + {{:helper.link('+', null, {'adj_pressure' : 100})}} +
    + {{/if}} +
    +{{/if}} + +{{if data.fuel}} +

    Fuel Injection System

    + + {{if data.device_info}} +
    +
    + Status: +
    +
    + {{if data.device_info.power}} + Injecting + {{else}} + On Hold + {{/if}} +
    + {{:helper.link('Refresh', null, {'refresh_status' : 1})}} +
    +
    +
    Rate:
    +
    {{:data.device_info.volume_rate}} L/s
    +
    +
    +
    Automated Fuel Injection:
    + {{if data.automation}} + {{:helper.link('Engaged', null, {'toggle_automation' : 1})}} +
    Injector Controls Locked Out
    + {{else}} + {{:helper.link('Disengaged', null, {'toggle_automation' : 1})}} +
    Injector:
    + {{:helper.link('Toggle Power', null, {'toggle_injector' : 1})}} + {{:helper.link('Inject (1 Cycle)', null, {'injection' : 1})}} + {{/if}} +
    + {{else}} +
    +
    ERROR: Can not find device
    + {{:helper.link('Search', null, {'refresh_status' : 1})}} +
    + {{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/chem_master.tmpl b/nano/templates/chem_master.tmpl new file mode 100644 index 0000000000..f163447dbf --- /dev/null +++ b/nano/templates/chem_master.tmpl @@ -0,0 +1,205 @@ +/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) + + if(beaker) + var/datum/reagents/R = beaker:reagents + if (href_list["analyze"]) + var/dat = "" + if(!condi) + if(href_list["name"] == "Blood") + var/datum/reagent/blood/G + for(var/datum/reagent/F in R.reagent_list) + if(F.name == href_list["name"]) + G = F + break + var/A = G.name + var/B = G.data["blood_type"] + var/C = G.data["blood_DNA"] + dat += "Chemmaster 3000Chemical infos:

    Name:
    [A]

    Description:
    Blood Type: [B]
    DNA: [C]


    (Back)" + else + dat += "Chemmaster 3000Chemical infos:

    Name:
    [href_list["name"]]

    Description:
    [href_list["desc"]]


    (Back)" + else + dat += "Condimaster 3000Condiment infos:

    Name:
    [href_list["name"]]

    Description:
    [href_list["desc"]]


    (Back)" + usr << browse(dat, "window=chem_master;size=575x400") + return + + else if (href_list["add"]) + + if(href_list["amount"]) + var/id = href_list["add"] + var/amount = Clamp((text2num(href_list["amount"])), 0, 200) + R.trans_id_to(src, id, amount) + + else if (href_list["addcustom"]) + + var/id = href_list["addcustom"] + useramount = input("Select the amount to transfer.", 30, useramount) as num + useramount = Clamp(useramount, 0, 200) + src.Topic(null, list("amount" = "[useramount]", "add" = "[id]")) + + else if (href_list["remove"]) + + if(href_list["amount"]) + var/id = href_list["remove"] + var/amount = Clamp((text2num(href_list["amount"])), 0, 200) + if(mode) + reagents.trans_id_to(beaker, id, amount) + else + reagents.remove_reagent(id, amount) + + + else if (href_list["removecustom"]) + + var/id = href_list["removecustom"] + useramount = input("Select the amount to transfer.", 30, useramount) as num + useramount = Clamp(useramount, 0, 200) + src.Topic(null, list("amount" = "[useramount]", "remove" = "[id]")) + + else if (href_list["toggle"]) + mode = !mode + + else if (href_list["main"]) + attack_hand(usr) + return + else if (href_list["eject"]) + if(beaker) + beaker:loc = src.loc + beaker = null + reagents.clear_reagents() + icon_state = "mixer0" + else if (href_list["createpill"] || href_list["createpill_multiple"]) + var/count = 1 + + if(reagents.total_volume/count < 1) //Sanity checking. + return + + if (href_list["createpill_multiple"]) + count = input("Select the number of pills to make.", "Max [max_pill_count]", pillamount) as num + count = Clamp(count, 1, max_pill_count) + + if(reagents.total_volume/count < 1) //Sanity checking. + return + + var/amount_per_pill = reagents.total_volume/count + if (amount_per_pill > 60) amount_per_pill = 60 + + var/name = sanitizeSafe(input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill] units)"), MAX_NAME_LEN) + + if(reagents.total_volume/count < 1) //Sanity checking. + return + while (count--) + var/obj/item/weapon/reagent_containers/pill/P = new/obj/item/weapon/reagent_containers/pill(src.loc) + if(!name) name = reagents.get_master_reagent_name() + P.name = "[name] pill" + P.pixel_x = rand(-7, 7) //random position + P.pixel_y = rand(-7, 7) + P.icon_state = "pill"+pillsprite + reagents.trans_to_obj(P,amount_per_pill) + if(src.loaded_pill_bottle) + if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots) + P.loc = loaded_pill_bottle + src.updateUsrDialog() + + else if (href_list["createbottle"]) + if(!condi) + var/name = sanitizeSafe(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()), MAX_NAME_LEN) + var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) + if(!name) name = reagents.get_master_reagent_name() + P.name = "[name] bottle" + P.pixel_x = rand(-7, 7) //random position + P.pixel_y = rand(-7, 7) + P.icon_state = bottlesprite + reagents.trans_to_obj(P,60) + P.update_icon() + else + var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc) + reagents.trans_to_obj(P,50) + else if(href_list["change_pill"]) + #define MAX_PILL_SPRITE 20 //max icon state of the pill sprites + var/dat = "" + for(var/i = 1 to MAX_PILL_SPRITE) + dat += "" + dat += "
    " + usr << browse(dat, "window=chem_master") + return + else if(href_list["change_bottle"]) + var/dat = "" + for(var/sprite in BOTTLE_SPRITES) + dat += "" + dat += "
    " + usr << browse(dat, "window=chem_master") + return + else if(href_list["pill_sprite"]) + pillsprite = href_list["pill_sprite"] + else if(href_list["bottle_sprite"]) + bottlesprite = href_list["bottle_sprite"] + + src.updateUsrDialog() + return + + +{{:helper.link(data.beaker ? 'Eject Beaker and Clear Buffer' : 'Please insert beaker', 'eject', {'eject' : 1}), data.beaker ? null : 'linkOff'}} +{{:helper.link(data.pillBottle ? 'Eject Pill Bottle' : 'Please insert beaker', 'eject', {'ejectp' : 1}), data.pillBottle ? null : 'linkOff'}} +{{:data.pillBottleTotal}} / {{:data.pillBottleMax}} + +{{if data.beakerReagent}} + Add to buffer: + {{for data.beakerReagent}} + {{:value.name}} , {{:value.volume}} Units - + {{:helper.link('Analyze', 'signal-diag', {'analyze' : 1, 'desc' : value.description, 'name' : value.name})}} + {{:helper.link('1', 'plus', {'add' : value.id, 'amount' : 1})}} + {{:helper.link('5', 'plus', {'add' : value.id, 'amount' : 5})}} + {{:helper.link('10', 'plus', {'add' : value.id, 'amount' : 10})}} + {{:helper.link('30', 'plus', {'add' : value.id, 'amount' : 30})}} + {{:helper.link('60', 'plus', {'add' : value.id, 'amount' : 60})}} + {{:helper.link('All', 'plus', {'add' : value.id, 'amount' : value.volume})}} + {{:helper.link('Custom', 'plus', {'addcustom' : value.id})}} + +if(!beaker) data.beaker +if(src.loaded_pill_bottle) data.pillBottle +[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\] data.pillBottleTotal data.pillBottleMax + +var/datum/reagents/R = beaker:reagents +if(!R.total_volume) + dat += "Beaker is empty." + else + dat += "Add to buffer:
    " + for(var/datum/reagent/G in R.reagent_list) + dat += "[G.name] , [G.volume] Units - " + dat += "(Analyze) " + dat += "(1) " + dat += "(5) " + dat += "(10) " + dat += "(30) " + dat += "(60) " + dat += "(All) " + dat += "(Custom)
    " + + dat += "
    Transfer to [(!mode ? "disposal" : "beaker")]:
    " + if(reagents.total_volume) + for(var/datum/reagent/N in reagents.reagent_list) + dat += "[N.name] , [N.volume] Units - " + dat += "(Analyze) " + dat += "(1) " + dat += "(5) " + dat += "(10) " + dat += "(30) " + dat += "(60) " + dat += "(All) " + dat += "(Custom)
    " + else + dat += "Empty
    " + if(!condi) + dat += "

    Create pill (60 units max)
    " + dat += "Create multiple pills
    " + dat += "Create bottle (60 units max)" + else + dat += "Create bottle (50 units max)" + if(!condi) + user << browse("Chemmaster 3000Chemmaster menu:

    [dat]", "window=chem_master;size=575x400") + else + user << browse("Condimaster 3000Condimaster menu:

    [dat]", "window=chem_master;size=575x400") + onclose(user, "chem_master") + return \ No newline at end of file diff --git a/nano/templates/cloning.tmpl b/nano/templates/cloning.tmpl new file mode 100644 index 0000000000..d1ea7df3ad --- /dev/null +++ b/nano/templates/cloning.tmpl @@ -0,0 +1,115 @@ + + +{{:data.temp}} + +{{if data.menu == 1}} + +

    Modules

    + {{if data.scanner}} + DNA scanner found. + {{else}} + DNA scanner not found. + {{/if}} + + {{if data.podsLen > 0}} + {{:data.podsLen}} cloning vat\s found. + {{else}} + No cloning vats found. + {{/if}} + + +

    Scanner Functions

    + + {{if data.loading}} + Scanning... + {{else}} + {{:data.scantemp}} + {{/if}} + + {{if data.scanner}} + {{if data.occupant}} + + {{:helper.link('Scan - ' + {{:data.occupant}}, 'play', {'scan' : 1})}} + {{else}} + Scanner unoccupied + {{/if}} + + {{if data.locked}} + {{:helper.link('Unlock', 'locked', {'lock' : 1}, null, 'redButton')}} + {{else}} + {{:helper.link('Lock', 'unlocked', {'lock' : 1})}} + {{/if}} + + {{else}} + No scanner connected! + {{/if}} + + {{if data.podsLen}} + {{for data.pods}} + {{:value.pod}} biomass: {{:value.biomass}} + {{/for}} + {{/if}} + + +

    Database Functions

    + + {{:helper.link('View Records', 'list', {'menu' : 2})}} + + {{:helper.link('Eject Disk', 'eject', {'disk' : 'eject'}, data.diskette ? null : 'linkOff')}} + +{{else data.menu == 2}} +

    Current records

    + + {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}} + + {{for data.records}} +
  • {{:helper.link(value.name, 'document', {'view_rec' : value.record})}}
  • + {{/for}} + +{{else data.menu == 3}} +

    Selected Record

    + {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 2})}} + + {{if activeRecord}} + {{:helper.link('Delete Record', 'trash', {'del_rec' : 1}, null, 'redButton')}} + Name: {{:data.activeRecord.real_name}} + + + + {{:helper.link('Load from disk', 'transfer-e-w', {'disk' : 'load'}, data.disk ? null : 'linkOff')}} + + Save: {{:helper.link('UI + UE', 'disk', {'save_disk' : 'ue'}, data.disk ? null : 'linkOff')}} + {{:helper.link('UI', 'disk', {'save_disk' : 'ui'}, data.disk ? null : 'linkOff')}} + {{:helper.link('SE', 'disk', {'save_disk' : 'se'}, data.disk ? null : 'linkOff')}} + + UI: {{:data.activeRecord.ui}} + SE: {{:data.activeRecord.se}} + + {{:helper.link('Clone', 'play', {'clone' : data.activeRecord.active_record}, data.podsLen ? null : 'linkOff')}} + + {{else}} + ERROR: Record not found. + {{/if}} + +{{else data.menu == 4}} + {{:data.temp}} + +

    Confirm Record Deletion

    + + Scan card to confirm. + + {{:helper.link('Cancel', 'cancel', {'menu' : 3})}} + +{{/if}} \ No newline at end of file diff --git a/nano/templates/fax.tmpl b/nano/templates/fax.tmpl new file mode 100644 index 0000000000..5af31d6adc --- /dev/null +++ b/nano/templates/fax.tmpl @@ -0,0 +1,32 @@ + + +Confirm Identity: {{:helper.link(data.scanName, 'check', {'scan' : 1})}} +{{if data.authenticated}} + {{:helper.link('Log Out', 'eject', {'logout' : 1}, null, 'linkDanger')}} +
    + Logged in to: {{:data.bossName}} Quantum Entanglement Network + {{if data.copyItem}} + {{:helper.link('Remove Item', 'eject', {'remove' : 1})}} + {{if data.cooldown}} + Transmitter arrays realigning. Please stand by. + {{else}} + {{:helper.link('Send', 'signal-diag', {'send' : 1})}} + Currently sending: {{:data.copyItemName}} + Sending to: {{:helper.link(data.destination, 'tag', {'dept' : 1})}} + {{/if}} + {{else}} + Please insert paper to send via secure connection. + {{if data.cooldown}} + Transmitter arrays realigning. Please stand by. + {{/if}} + {{/if}} +{{else}} + {{:helper.link('Log In', 'person', {'auth' : 1})}} + Proper authentication is required to use this device. + {{if data.copyItem}} + {{:helper.link('Remove Item', 'eject', {'remove' : 1})}} + {{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/guest_pass.tmpl b/nano/templates/guest_pass.tmpl new file mode 100644 index 0000000000..bed279b51a --- /dev/null +++ b/nano/templates/guest_pass.tmpl @@ -0,0 +1,59 @@ + + +{{if data.mode == 1}} +
    +
    + Activity Log +
    + {{:helper.link('Print', 'print', {'print' : 1})}} {{:helper.link('Back', 'arrowreturn-1-w', {'mode' : 0})}} +
    +
    + {{for data.log}} +
    + {{:value}} +
    + {{/for}} +{{else}} +

    Guest pass terminal #{{:data.uid}}

    +
    + {{:helper.link('View activity log', 'list', {'mode' : 1})}} {{:helper.link('Issure Pass', 'eject', {'action' : 'issue'})}} +
    +
    +
    +
    + Issuing ID: +
    + {{:helper.link(data.giver, 'person', {'action' : 'id'})}} +
    +
    +
    + Issued to: +
    + {{:helper.link(data.giveName, 'pencil', {'choice' : 'giv_name'})}} +
    +
    +
    + Reason: +
    + {{:helper.link(data.reason, 'pencil', {'choice' : 'reason'})}} +
    +
    +
    + Duration (minutes): +
    + {{:helper.link(data.duration, 'clock', {'choice' : 'duration'})}} +
    +
    +
    + Access to areas: +
    +
    + {{for data.area}} +
    + {{:helper.link(value.area_name, value.on ? 'check' : 'close', {'choice' : 'access', 'access' : value.area}, null, value.on ? 'linkOn' : null)}} +
    + {{/for}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/holodeck.tmpl b/nano/templates/holodeck.tmpl new file mode 100644 index 0000000000..6c813944dd --- /dev/null +++ b/nano/templates/holodeck.tmpl @@ -0,0 +1,33 @@ + + +Current Loaded Programs: +{{for data.supportedPrograms}} + {{:helper.link(value.name, data.currentProgram == value.program ? 'check' : 'clear', {'program' : value.program}, data.currentProgram == value.program ? 'linkOn' : null)}} +{{/for}} +Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded. +{{if data.isSilicon}} + {{if data.safetyDisabled}} + {{if data.emagged}} + ERROR: Cannot re-enable Safety Protocols. + {{else}} + {{:helper.link('Re-Enable Safety Protocols?', 'help', {'AIoverride' : 1}, null, 'linkOn')}} + {{/if}} + {{else}} + {{:helper.link('Re-Enable Safety Protocols?', 'help', {'AIoverride' : 1}, null, 'linkDanger')}} + {{/if}} +{{/if}} + +{{if data.safetyDisabled}} + {{for data.restrictedPrograms}} + {{:helper.link('Begin ' + value.name, data.currentProgram == value.program ? 'check' : 'clear', {'program' : value.program}, data.currentProgram == value.program ? 'linkOn' : null)}} + Ensure the holodeck is empty before testing. + {{/for}} + Safety Protocols are DISABLED +{{else}} + Safety Protocols are ENABLED +{{/if}} + +{{:helper.link(data.gravity ? 'On ' : 'Off', data.gravity ? 'check' : 'clear', {'gravity' : 1}, null, data.gravity ? 'linkOn' : linkDanger')}} \ No newline at end of file diff --git a/nano/templates/laptop_vendor.tmpl b/nano/templates/laptop_vendor.tmpl new file mode 100644 index 0000000000..6854619b19 --- /dev/null +++ b/nano/templates/laptop_vendor.tmpl @@ -0,0 +1,175 @@ + + +{{if data.mode == 0}} +
    +
    + Please choose your laptop customization options.
    + Your comptuer will automatically be loaded with any programs you can use after the transaction is complete.
    + Some programs will require additional components to be installed! +
    +
    + +
    + +
    +
    HDD (Required):
    +
    Added
    +
    + +
    +
    + Card Reader: +
    + {{:helper.link('Single (50)', data.cardreader == 1 ? 'check' : 'plus', {'choice' : 'single_add'}, data.cardreader == 1 ? 'selected' : null)}} + {{:helper.link('Dual (125)', data.cardreader == 2 ? 'check' : 'plus', {'choice' : 'dual_add'}, data.cardreader == 2 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'cardreader_rem'}, data.cardreader == 0 ? 'redButton' : null)}} +
    + +
    +
    + Floppy Drive: +
    + {{:helper.link('Add (50)', data.floppy == 1 ? 'check' : 'plus', {'choice' : 'floppy_add'}, data.floppy == 1 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'floppy_rem'}, data.floppy == 0 ? 'redButton' : null)}} +
    + +
    +
    + Radio card: +
    + {{:helper.link('Add (50)', data.radionet == 1 ? 'check' : 'plus', {'choice' : 'radio_add'}, data.radionet == 1 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'radio_rem'}, data.radionet == 0 ? 'redButton' : null)}} +
    + +
    +
    + Camera Card: +
    + {{:helper.link('Add (100)', data.camera == 1 ? 'check' : 'plus', {'choice' : 'camnet_add'}, data.camera == 1 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'camnet_rem'}, data.camera == 0 ? 'redButton' : null)}} +
    + +
    +
    + Network card: +
    +
    + {{:helper.link('Area (75)', data.network == 1 ? 'check' : 'plus', {'choice' : 'area_add'}, data.network == 1 ? 'selected' : null)}} + {{:helper.link('Adjacent (50)', data.network == 2 ? 'check' : 'plus', {'choice' : 'prox_add'}, data.network == 2 ? 'selected' : null)}} + {{:helper.link('Powernet (25)', data.network == 3 ? 'check' : 'plus', {'choice' : 'cable_add'}, data.network == 3 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'network_rem'}, data.network == 0 ? 'redButton' : null)}} +
    +
    + +
    + +
    +
    + Power Source: +
    + {{:helper.link('Extended (175)', data.power == 1 ? 'check' : 'plus', {'choice' : 'high_add'}, data.power == 1 ? 'selected' : null)}} + {{:helper.link('Unreal (250)', data.power == 2 ? 'check' : 'plus', {'choice' : 'super_add'}, data.power == 2 ? 'selected' : null)}} + {{:helper.link('Default', data.power == 0 ? 'check' : 'plus', {'choice' : 'power_rem'}, data.power == 0 ? 'selected' : null)}} +
    + +
    +
    +
    Total:
    +
    {{:data.total}}
    + {{:helper.link('Vend Laptop', 'cart', {'choice' : 'vend'})}} +
    + +{{else data.mode == 1}} +

    Cart

    + +
    + +
    +
    Total:
    +
    {{:data.total}}
    +
    + +
    +
    Card Reader:
    + {{if data.cardreader == 1}} + {{:helper.link('(single) (50)', 'close', {'choice' : 'cardreader_rem'})}} + {{else data.cardreader == 2}} + {{:helper.link('(double) (125)', 'close', {'choice' : 'cardreader_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Floppy Drive:
    + {{if data.floppy == 1}} + {{:helper.link('Added (50)', 'close', {'choice' : 'floppy_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Radio Card:
    + {{if data.radionet == 1}} + {{:helper.link('Added (50)', 'close', {'choice' : 'radio_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Camera Card:
    + {{if data.camera == 1}} + {{:helper.link('Added (100)', 'close', {'choice' : 'camnet_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Network Card:
    + {{if data.network == 1}} + {{:helper.link('Area (75)', 'close', {'choice' : 'network_rem'})}} + {{else data.network == 2}} + {{:helper.link('Adjacent (50)', 'close', {'choice' : 'network_rem'})}} + {{else data.network == 3}} + {{:helper.link('Powernet (25)', 'close', {'choice' : 'network_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Power Source:
    + {{if data.power == 1}} + {{:helper.link('Unreal (250)', 'close', {'choice' : 'power_rem'})}} + {{else data.power == 2}} + {{:helper.link('Extended (175)', 'close', {'choice' : 'power_rem'})}} + {{else}} +
    Regular
    + {{/if}} +
    + +
    + +
    +
    Please swipe your card and enter your PIN to complete the transaction
    +
    + +
    + + {{:helper.link('Cancel', 'close', {'choice' : 'cancel'}, null, 'redButton')}} + +{{else data.mode == 2}} +
    + Please swipe your card and enter your PIN to finish returning your computer. + +
    + + {{:helper.link('Cancel', 'close', {'choice' : 'cancel'}, null, 'redButton')}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/operating.tmpl b/nano/templates/operating.tmpl new file mode 100644 index 0000000000..3772639915 --- /dev/null +++ b/nano/templates/operating.tmpl @@ -0,0 +1,75 @@ + + +{{if data.table}} +

    Patient Information:

    + {{if data.victim}} +
    +
    + Name: +
    + {{:data.victim.real_name}} +
    +
    +
    + Age: +
    + {{:data.victim.age}} +
    +
    +
    + Blood Type: +
    + {{:data.victim.b_type}} +
    +
    +
    +
    + Health: +
    + {{:data.victim.health}} +
    +
    +
    + Brute Damage: +
    + {{:data.victim.brute}} +
    +
    +
    + Toxins Damage: +
    + {{:data.victim.tox}} +
    +
    +
    + Fire Damage: +
    + {{:data.victim.burn}} +
    +
    +
    + Suffocation Damage: +
    + {{:data.victim.oxy}} +
    +
    +
    + Patient Status: +
    + {{:data.victim.stat}} +
    +
    +
    + Heartbeat Rate: +
    + {{:data.victim.pulse}} +
    + {{else}} + No Patient Detected + {{/if}} +{{else}} + No Table Detected +{{/if}} diff --git a/nano/templates/photocopier.tmpl b/nano/templates/photocopier.tmpl new file mode 100644 index 0000000000..9d1bcf7918 --- /dev/null +++ b/nano/templates/photocopier.tmpl @@ -0,0 +1,47 @@ + + +{{if data.copyItem}} +
    + {{:helper.link('Remove Item', 'eject', {'remove' : 1})}} + {{if data.toner}} + {{:helper.link('Copy', 'copy', {'copy' : 1})}}
    +
    +
    +
    + Printing: +
    +
    +
    + {{:helper.link('-', null, {'min' : 1}, data.copies == 1 ? 'linkOff' : null)}} +
    {{:data.copies}}
    + {{:helper.link('+', null, {'add' : 1}, data.copies == data.maxCopies ? 'linkOff' : null)}} +
    +
    +
    +
    +
    +
    Current toner level:
    +
    {{:data.toner}}u
    +
    + {{else}} +
    + Please insert a new toner cartridge! +
    + {{/if}} +{{else data.toner}} +

    Please insert something to copy.

    + {{if data.isSilicon}} + {{:helper.link('Print photo from database', 'image', {'aipic' : 1})}} + {{/if}} +
    +
    Current toner level:
    +
    {{:data.toner}}u
    +
    +{{else}} +
    + Please insert a new toner cartridge! +
    +{{/if}} \ No newline at end of file