From 3bb7a173cf47ece50fa739ea73487732e71e0947 Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Mon, 9 Sep 2013 18:40:26 -0400 Subject: [PATCH] A bunch of nano UI fixes + new Chem Dispenser UI! --- code/game/machinery/cryo.dm | 69 ++++++---- code/modules/client/client procs.dm | 3 +- code/modules/nano/JSON Writer.dm | 8 +- code/modules/nano/nanomanager.dm | 8 +- code/modules/nano/nanoui.dm | 81 ++++++++--- code/modules/reagents/Chemistry-Machinery.dm | 134 ++++++++++--------- nano/css/shared.css | 49 +++++-- nano/js/nano_base_helpers.js | 65 ++++++++- nano/js/nano_update.js | 102 ++++++++------ nano/templates/chem_dispenser.tmpl | 59 ++++++++ nano/templates/cryo.tmpl | 53 ++++++-- 11 files changed, 445 insertions(+), 186 deletions(-) create mode 100644 nano/templates/chem_dispenser.tmpl diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 163c5f6bae1..443ad0d309a 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -5,7 +5,7 @@ density = 1 anchored = 1.0 layer = 2.8 - + var/on = 0 var/temperature_archived var/mob/living/carbon/occupant = null @@ -13,8 +13,6 @@ var/current_heat_capacity = 50 - - /obj/machinery/atmospherics/unary/cryo_cell/New() ..() initialize_directions = dir @@ -65,17 +63,22 @@ ui_interact(user) /obj/machinery/atmospherics/unary/cryo_cell/ui_interact(mob/user, ui_key = "main") - + + if(user == occupant || user.stat) + return + var/data[0] data["isOperating"] = on data["hasOccupant"] = occupant ? 1 : 0 - + var/occupantData[0] if (!occupant) occupantData["name"] = null occupantData["stat"] = null occupantData["health"] = null + occupantData["maxHealth"] = null + occupantData["minHealth"] = null occupantData["bruteLoss"] = null occupantData["oxyLoss"] = null occupantData["toxLoss"] = null @@ -84,12 +87,14 @@ else occupantData["name"] = occupant.name occupantData["stat"] = occupant.stat - occupantData["health"] = round(occupant.health) - occupantData["bruteLoss"] = round(occupant.getBruteLoss()) - occupantData["oxyLoss"] = round(occupant.getOxyLoss()) - occupantData["toxLoss"] = round(occupant.getToxLoss()) - occupantData["fireLoss"] = round(occupant.getFireLoss()) - occupantData["bodyTemperature"] = round(occupant.bodytemperature) + occupantData["health"] = occupant.health + occupantData["maxHealth"] = occupant.maxHealth + occupantData["minHealth"] = config.health_threshold_dead + occupantData["bruteLoss"] = occupant.getBruteLoss() + occupantData["oxyLoss"] = occupant.getOxyLoss() + occupantData["toxLoss"] = occupant.getToxLoss() + occupantData["fireLoss"] = occupant.getFireLoss() + occupantData["bodyTemperature"] = occupant.bodytemperature data["occupant"] = occupantData; data["cellTemperature"] = round(air_contents.temperature) @@ -103,9 +108,9 @@ var beakerContents[0] if(beaker && beaker:reagents && beaker:reagents.reagent_list.len) for(var/datum/reagent/R in beaker:reagents.reagent_list) - beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... + beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... data["beakerContents"] = beakerContents - + //user << list2json(data) var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key) @@ -123,19 +128,33 @@ //user.set_machine(src) /obj/machinery/atmospherics/unary/cryo_cell/Topic(href, href_list) - if ((get_dist(src, usr) <= 1) || istype(usr, /mob/living/silicon/ai)) - if(href_list["start"]) - on = !on - update_icon() - if(href_list["eject"]) - if (beaker) - var/obj/item/weapon/reagent_containers/glass/B = beaker - B.loc = get_step(loc, SOUTH) - beaker = null + if(usr == occupant) + return 0 // don't update UIs attached to this object - nanomanager.update_uis(src) // update all UIs attached to this object - add_fingerprint(usr) - return + if(..()) + return 0 // don't update UIs attached to this object + + if(href_list["switchOn"]) + on = 1 + update_icon() + + if(href_list["switchOff"]) + on = 0 + update_icon() + + if(href_list["ejectBeaker"]) + if(beaker) + var/obj/item/weapon/reagent_containers/glass/B = beaker + B.loc = get_step(loc, SOUTH) + beaker = null + + if(href_list["ejectOccupant"]) + if(!occupant || isslime(usr) || ispAI(usr)) + return 0 // don't update UIs attached to this object + go_out() + + add_fingerprint(usr) + return 1 // update UIs attached to this object /obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) if(istype(G, /obj/item/weapon/reagent_containers/glass)) diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index f372f27e547..565609fe346 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -107,7 +107,7 @@ if(config.resource_urls) src.preload_rsc = pick(config.resource_urls) else src.preload_rsc = 1 // If config.resource_urls is not set, preload like normal. - + src << "\red If the title screen is black, resources are still downloading. Please be patient until the title screen appears." @@ -248,6 +248,7 @@ 'nano/js/nano_base_helpers.js', 'nano/css/shared.css', 'nano/css/icons.css', + 'nano/templates/chem_dispenser.tmpl', 'nano/templates/cryo.tmpl', 'nano/images/uiBackground.png', 'nano/images/uiIcons16.png', diff --git a/code/modules/nano/JSON Writer.dm b/code/modules/nano/JSON Writer.dm index 95c0cb7578b..ec9bf66804c 100644 --- a/code/modules/nano/JSON Writer.dm +++ b/code/modules/nano/JSON Writer.dm @@ -41,10 +41,14 @@ json_writer if(!i) break if(targ == "\n") - txt = copytext(txt, 1, i) + "\\n" + copytext(txt, i+1) + txt = copytext(txt, 1, i) + "\\n" + copytext(txt, i+2) + start = i + 1 // 1 character added + if(targ == "'") + txt = copytext(txt, 1, i) + "`" + copytext(txt, i+1) // apostrophies fuck shit up... + start = i + 1 // 1 character added else txt = copytext(txt, 1, i) + "\\" + copytext(txt, i) - start = i + 2 + start = i + 2 // 2 characters added return {""[txt]""} is_associative(list/L) diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm index c3edfa04ea9..1e0aa528c8b 100644 --- a/code/modules/nano/nanomanager.dm +++ b/code/modules/nano/nanomanager.dm @@ -19,17 +19,17 @@ return ui return null - + /datum/nanomanager/proc/update_uis(src_object) var/src_object_key = "\ref[src_object]" if (isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list)) - return 0 + return 0 var/update_count = 0 - for (var/ui_key in open_uis[src_object_key]) + for (var/ui_key in open_uis[src_object_key]) for (var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) if(ui && ui.src_object && ui.user) - ui.process() + ui.process(1) update_count++ return update_count diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index add6437c3be..567ce363a90 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -1,3 +1,7 @@ +#define STATUS_INTERACTIVE 2 // GREEN Visability +#define STATUS_UPDATE 1 // ORANGE Visability +#define STATUS_DISABLED 0 // RED Visability + /datum/nanoui var/mob/user var/atom/movable/src_object @@ -19,7 +23,10 @@ var/content = "
" // the #mainTemplate div will contain the compiled "main" template html var/list/initial_data[0] var/is_auto_updating = 0 - var/status = 2 + var/status = STATUS_INTERACTIVE + + // Only allow users with a certain user.stat to get updates. Defaults to 0 (concious) + var/allowed_user_stat = 0 // -1 = ignore, 0 = alive, 1 = unconcious or alive, 2 = dead concious or alive /datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null) @@ -49,13 +56,42 @@ add_stylesheet("shared.css") // this CSS sheet is common to all UIs add_stylesheet("icons.css") // this CSS sheet is common to all UIs -/datum/nanoui/proc/set_status(state) +/datum/nanoui/proc/set_status(state, push_update) if (state != status) status = state - push_data(list(), 1) // Update the UI + if (push_update || !status) + push_data(list(), 1) // Update the UI, force the update in case the status is 0 else status = state +/datum/nanoui/proc/update_status(push_update = 0) + if (istype(user, /mob/living/silicon/ai)) + set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) + else if (istype(user, /mob/living/silicon/robot)) + if (src_object in view(7, user)) // robots can see and interact with things they can see within 7 tiles + set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) + else + set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) + else + var/dist = get_dist(src_object, user) + + if (dist > 4) + close() + return + + if ((allowed_user_stat > -1) && (user.stat > allowed_user_stat)) + set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) + else if (user.restrained() || user.lying) + set_status(STATUS_UPDATE, push_update) // update only (orange visibility) + else if (!(src_object in view(4, user))) // If the src object is not in visable, set status to 0 + set_status(STATUS_DISABLED, push_update) // interactive (green visibility) + else if (dist <= 1) + set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility) + else if (dist <= 2) + set_status(STATUS_UPDATE, push_update) // update only (orange visibility) + else if (dist <= 4) + set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility) + /datum/nanoui/proc/set_auto_update(state = 1) is_auto_updating = state @@ -109,7 +145,9 @@ if (initial_data.len > 0) initial_data_json = list2json(initial_data) - var/url_parameters_json = list2json(list("src" = "\ref[src_object]")) + //user << initial_data_json + + var/url_parameters_json = list2json(list("src" = "\ref[src]")) return {" @@ -146,6 +184,17 @@
"} +/datum/nanoui/Topic(href, href_list) + update_status(0) // update the status + if (status != STATUS_INTERACTIVE || user != usr) // If UI is not interactive or usr calling Topic is not the UI user + return + + if (src_object.Topic(href, href_list)) + usr << "Update after Topic" + nanomanager.update_uis(src_object) // update all UIs attached to src_object + else + usr << "Don't update after Topic" + /datum/nanoui/proc/get_footer() var/scriptsContent = "" @@ -189,20 +238,10 @@ winset(user, window_id, "on-close=\"nanoclose [params]\"") /datum/nanoui/proc/process(update = 0) - var/dist = get_dist(src_object, user) - if (dist <= 1) - set_status(2) // interactive - else if (dist <= 2) - set_status(1) // update only - else if (dist <= 3) - set_status(0) // no updates, completely disabled - return // don't auto update + if (status && (update || is_auto_updating)) + src_object.ui_interact(user, ui_key) // Update the UI (update_status() is called whenever a UI is updated) else - close() - return - - if (update || is_auto_updating) - src_object.ui_interact(user, ui_key) + update_status(1) // Not updating UI, so lets check here if status has changed /datum/nanoui/proc/modify_data(data) data["ui"] = list( @@ -213,12 +252,12 @@ return data /datum/nanoui/proc/push_data(data, force_push = 0) - if (!status && !force_push) - user << "Cannot update UI, user out of range (status [status])" - return + update_status(0) + if (status == STATUS_DISABLED && !force_push) + return // Cannot update UI, no visibility data = modify_data(data) - + //user << list2json(data) user << output(list2params(list(list2json(data))),"[window_id].browser:receiveUpdateData") on_close_winset() diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 0624c99e49d..5f882f5390b 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -3,7 +3,7 @@ #define GAS 3 /obj/machinery/chem_dispenser - name = "chem dispenser" + name = "Chem Dispenser" density = 1 anchored = 1 icon = 'icons/obj/chemical.dmi' @@ -21,11 +21,12 @@ /obj/machinery/chem_dispenser/proc/recharge() if(stat & (BROKEN|NOPOWER)) return - var/addenergy = 2 + var/addenergy = 1 var/oldenergy = energy energy = min(energy + addenergy, max_energy) if(energy != oldenergy) - use_power(3000) // This thing uses up alot of power (this is still low as shit for creating reagents from thin air) + use_power(1500) // This thing uses up alot of power (this is still low as shit for creating reagents from thin air) + nanomanager.update_uis(src) // update all UIs attached to src /obj/machinery/chem_dispenser/power_change() if(powered()) @@ -33,6 +34,7 @@ else spawn(rand(0, 15)) stat |= NOPOWER + nanomanager.update_uis(src) // update all UIs attached to src /obj/machinery/chem_dispenser/process() @@ -65,74 +67,81 @@ del(src) return -/obj/machinery/chem_dispenser/proc/updateWindow(mob/user as mob) - winset(user, "chemdispenser.energy", "text=\"Energy: [src.energy]\"") - winset(user, "chemdispenser.amount", "text=\"Amount: [src.amount]\"") +/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main") + if(stat & (BROKEN|NOPOWER)) return + if(user.stat || user.restrained()) return + + var/data[0] + + data["amount"] = amount + data["energy"] = energy + data["maxEnergy"] = max_energy + + data["isBeakerLoaded"] = beaker ? 1 : 0 + + + var beakerContents[0] + var beakerCurrentVolume = 0 + if(beaker && beaker:reagents && beaker:reagents.reagent_list.len) + for(var/datum/reagent/R in beaker:reagents.reagent_list) + beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... + beakerCurrentVolume += R.volume + data["beakerContents"] = beakerContents if (beaker) - winset(user, "chemdispenser.eject", "text=\"Eject beaker\"") + data["beakerCurrentVolume"] = beakerCurrentVolume + data["beakerMaxVolume"] = beaker:volume else - winset(user, "chemdispenser.eject", "text=\"\[Insert beaker\]\"") -/obj/machinery/chem_dispenser/proc/initWindow(mob/user as mob) - var/i = 0 - var/list/nameparams = params2list(winget(user, "chemdispenser_reagents.template_name", "pos;size;type;image;image-mode")) - var/list/buttonparams = params2list(winget(user, "chemdispenser_reagents.template_dispense", "pos;size;type;image;image-mode;text;is-flat")) - for(var/re in dispensable_reagents) + data["beakerCurrentVolume"] = null + data["beakerMaxVolume"] = null + + var chemicals[0] + for (var/re in dispensable_reagents) var/datum/reagent/temp = chemical_reagents_list[re] if(temp) - var/list/newparams1 = nameparams.Copy() - var/list/newparams2 = buttonparams.Copy() - var/posy = 8 + 40 * i - newparams1["pos"] = text("8,[posy]") - newparams2["pos"] = text("248,[posy]") - newparams1["parent"] = "chemdispenser_reagents" - newparams2["parent"] = "chemdispenser_reagents" - newparams1["text"] = temp.name - newparams2["command"] = text("skincmd \"chemdispenser;[temp.id]\"") - winset(user, "chemdispenser_reagent_name[i]", list2params(newparams1)) - winset(user, "chemdispenser_reagent_dispense[i]", list2params(newparams2)) - i++ - winset(user, "chemdispenser_reagents", "size=340x[8 + 40 * i]") + chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list... + data["chemicals"] = chemicals -/obj/machinery/chem_dispenser/SkinCmd(mob/user as mob, var/data as text) - if(stat & (BROKEN|NOPOWER)) return - if(usr.stat || usr.restrained()) return - if(!in_range(src, usr)) return + //user << list2json(data) - usr.set_machine(src) - - if (data == "amountc") - var/num = input("Enter desired output amount", "Amount", "30") as num - if (num) - amount = text2num(num) - else if (data == "eject") - if (src.beaker) - var/obj/item/weapon/reagent_containers/glass/B = src.beaker - B.loc = src.loc - src.beaker = null - else if (copytext(data, 1, 7) == "amount") - if (text2num(copytext(data, 7))) - amount = text2num(copytext(data, 7)) + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key) + if (!ui) + ui = new(user, src, ui_key, "chem_dispenser.tmpl", "Chem Dispenser 5000", 370, 605) + // When the UI is first opened this is the data it will use + ui.set_initial_data(data) + ui.open() else - if (dispensable_reagents.Find(data) && beaker != null) + // The UI is already open so push the new data to it + ui.push_data(data) + return + +/obj/machinery/chem_dispenser/Topic(href, href_list) + if(stat & (NOPOWER|BROKEN)) + return 0 // don't update UIs attached to this object + + if(href_list["amount"]) + amount = round(text2num(href_list["amount"]), 5) // round to nearest 5 + if (amount < 0) // Since the user can actually type the commands himself, some sanity checking + amount = 0 + if (amount > 100) + amount = 100 + + if(href_list["dispense"]) + if (dispensable_reagents.Find(href_list["dispense"]) && beaker != null) var/obj/item/weapon/reagent_containers/glass/B = src.beaker var/datum/reagents/R = B.reagents var/space = R.maximum_volume - R.total_volume - R.add_reagent(data, min(amount, energy * 10, space)) + R.add_reagent(href_list["dispense"], min(amount, energy * 10, space)) energy = max(energy - min(amount, energy * 10, space) / 10, 0) - amount = round(amount, 10) // Chem dispenser doesnt really have that much prescion - if (amount < 0) // Since the user can actually type the commands himself, some sanity checking - amount = 0 - if (amount > 100) - amount = 100 + if(href_list["ejectBeaker"]) + if(beaker) + var/obj/item/weapon/reagent_containers/glass/B = beaker + B.loc = loc + beaker = null - for(var/mob/player in player_list) - if (player.machine == src && player.client) - updateWindow(player) - - src.add_fingerprint(usr) - return + add_fingerprint(usr) + return 1 // update UIs attached to this object /obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/reagent_containers/glass/B as obj, var/mob/user as mob) if(isrobot(user)) @@ -149,9 +158,7 @@ user.drop_item() B.loc = src user << "You add the beaker to the machine!" - for(var/mob/player in player_list) - if (player.machine == src && player.client) - updateWindow(player) + nanomanager.update_uis(src) // update all UIs attached to src /obj/machinery/chem_dispenser/attack_ai(mob/user as mob) return src.attack_hand(user) @@ -162,13 +169,8 @@ /obj/machinery/chem_dispenser/attack_hand(mob/user as mob) if(stat & BROKEN) return - user.set_machine(src) - initWindow(user) - updateWindow(user) - winshow(user, "chemdispenser", 1) - user.skincmds["chemdispenser"] = src - return + ui_interact(user) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/nano/css/shared.css b/nano/css/shared.css index 4d96bf988f5..7400e2e25e6 100644 --- a/nano/css/shared.css +++ b/nano/css/shared.css @@ -258,6 +258,7 @@ div.notice { float: left; width: 30%; + color: #e9c183; } .itemContent @@ -306,43 +307,62 @@ div.notice padding: 0; } -.progressBar +.displayBar { - width: 240px; - height: 14px; + position: relative; + width: 236px; + height: 16px; border: 1px solid #666666; float: left; - margin: 0 5px; + margin: 0 5px 0 0; overflow: hidden; + background: #000000; } -.progressFill +.displayBarText +{ + position: absolute; + top: -2px; + left: 5px; + width: 100%; + height: 100%; + color: #ffffff; + font-weight: normal; +} + +.displayBarFill { width: 0%; height: 100%; background: #40628a; overflow: hidden; + float: left; } -.progressFill.good +.displayBarFill.alignRight +{ + float: right; +} + +.displayBarFill.good { color: #ffffff; background: #4f7529; } -.progressFill.average +.displayBarFill.average { color: #ffffff; background: #cd6500; } -.progressFill.bad +.displayBarFill.bad { color: #ffffff; background: #ee0000; } -.progressFill.highlight +.displayBarFill.highlight { color: #ffffff; background: #8BA5C4; @@ -374,4 +394,15 @@ div.notice color: #ffffff; background: #999999; border-color: #666666; +} + +.fixedLeft +{ + width: 110px; + float: left; +} + +.floatRight +{ + float: right; } \ No newline at end of file diff --git a/nano/js/nano_base_helpers.js b/nano/js/nano_base_helpers.js index 61ca5267b9c..0272faf3e48 100644 --- a/nano/js/nano_base_helpers.js +++ b/nano/js/nano_base_helpers.js @@ -15,20 +15,31 @@ NanoBaseHelpers = function () { $.views.helpers({ // Generate a Byond link - link: function( text, icon, parameters, status ) { + link: function( text, icon, parameters, status, elementClass, elementId) { var iconHtml = ''; - if (typeof icon != 'undefined' && icon != null) + if (typeof icon != 'undefined' && icon) { iconHtml = '
'; } - if (typeof status != 'undefined' && status != null) + if (typeof elementClass == 'undefined' || !elementClass) { - return ''; + elementClass = ''; } - return ''; + var elementIdHtml = ''; + if (typeof elementId != 'undefined' && elementId) + { + elementIdHtml = 'id="' + elementId + '"'; + } + + if (typeof status != 'undefined' && status) + { + return ''; + } + + return ''; }, // Round a number to the nearest integer round: function(number) { @@ -46,7 +57,7 @@ NanoBaseHelpers = function () string: function() { if (arguments.length == 0) { - return ""; + return ''; } else if (arguments.length == 1) { @@ -61,7 +72,47 @@ NanoBaseHelpers = function () } return arguments[0].format(stringArgs); } - return + return ''; + }, + // Display a bar. Used to show health, capacity, etc. + displayBar: function(value, rangeMin, rangeMax, styleClass, showText) { + + if (rangeMin < rangeMax) + { + if (value < rangeMin) + { + value = rangeMin; + } + else if (value > rangeMax) + { + value = rangeMax; + } + } + else + { + if (value > rangeMin) + { + value = rangeMin; + } + else if (value < rangeMax) + { + value = rangeMax; + } + } + + if (typeof styleClass == 'undefined' || !styleClass) + { + styleClass = ''; + } + + if (typeof showText == 'undefined' || !showText) + { + showText = ''; + } + + var percentage = Math.round((value - rangeMin) / (rangeMax - rangeMin) * 100); + + return '
' + showText + '
'; } }); } diff --git a/nano/js/nano_update.js b/nano/js/nano_update.js index 1034ac89795..035d71862aa 100644 --- a/nano/js/nano_update.js +++ b/nano/js/nano_update.js @@ -13,9 +13,57 @@ NanoUpdate = function () var init = function () { + NanoUpdate.addAfterUpdateCallback(function (updateData) { + var uiStatusClass; + if (updateData['ui']['status'] == 2) + { + uiStatusClass = 'icon24 uiStatusGood'; + $('.linkActive').removeClass('inactive'); + } + else if (updateData['ui']['status'] == 1) + { + uiStatusClass = 'icon24 uiStatusAverage'; + $('.linkActive').addClass('inactive'); + } + else + { + uiStatusClass = 'icon24 uiStatusBad' + $('.linkActive').addClass('inactive'); + } + $('#uiStatusIcon').attr('class', uiStatusClass); + + $('.linkActive').stopTime('linkPending'); + $('.linkActive').removeClass('linkPending'); + + $('.linkActive').off('click'); + $('.linkActive').on('click', function (event) { + event.preventDefault(); + var href = $(this).data('href'); + if (href != null && _canClick) + { + _canClick = false; + $('body').oneTime(300, 'enableClick', function () { + _canClick = true; + }); + if (updateData['ui']['status'] == 2) + { + $(this).oneTime(300, 'linkPending', function () { + $(this).addClass('linkPending'); + }); + } + window.location.href = href; + } + }); + }); + var body = $('body'); // We store data in the body tag, it's as good a place as any _data = body.data('initialData'); + + if (!_data) + { + alert('Error: Initial data did not load correctly.'); + } var templateData = body.data('templateData'); @@ -57,6 +105,8 @@ NanoUpdate = function () { observedDataUpdateRecursive(_earlyUpdateData, _data); } + + executeCallbacks(_afterUpdateCallbacks, _data); //alert($("#mainTemplate").html()); } @@ -68,52 +118,22 @@ NanoUpdate = function () }); } } - - NanoUpdate.addAfterUpdateCallback(function (updateData) { - var uiStatusClass; - if (updateData['ui']['status'] == 2) - { - uiStatusClass = 'icon24 uiStatusGood'; - $('.linkActive').removeClass('inactive'); - } - else if (updateData['ui']['status'] == 1) - { - uiStatusClass = 'icon24 uiStatusAverage'; - $('.linkActive').addClass('inactive'); - } - else - { - uiStatusClass = 'icon24 uiStatusBad' - $('.linkActive').addClass('inactive'); - } - $('#uiStatusIcon').attr('class', uiStatusClass); - - $('.linkActive').stopTime('linkPending'); - $('.linkActive').removeClass('linkPending'); - - $('.linkActive').off('click'); - $('.linkActive').on('click', function (event) { - event.preventDefault(); - var href = $(this).data('href'); - if (href != null && _canClick) - { - _canClick = false; - $('body').oneTime(300, 'enableClick', function () { - _canClick = true; - }); - $(this).oneTime(300, 'linkPending', function () { - $(this).addClass('linkPending'); - }); - window.location.href = href; - } - }); - }); }; // Receive update data from the server var receiveUpdateData = function (jsonString) { - var updateData = jQuery.parseJSON(jsonString); + var updateData; + try + { + updateData = jQuery.parseJSON(jsonString); + } + catch (error) + { + alert(error.Message); + return; + } + if (_isInitialised) // templates have been loaded and are observing the data. We need to update it recursively { diff --git a/nano/templates/chem_dispenser.tmpl b/nano/templates/chem_dispenser.tmpl new file mode 100644 index 00000000000..c8371c1ca3a --- /dev/null +++ b/nano/templates/chem_dispenser.tmpl @@ -0,0 +1,59 @@ +
+
+ Energy: +
+
+ {^{:~displayBar(energy, 0, maxEnergy, 'good', energy + ' Units')}} +
+
+ +
+
+ Dispense: +
+
+ {^{:~link('5', 'gear', {'amount' : 5}, (amount == 5) ? 'selected' : null)}} + {^{:~link('10', 'gear', {'amount' : 10}, (amount == 10) ? 'selected' : null)}} + {^{:~link('20', 'gear', {'amount' : 20}, (amount == 20) ? 'selected' : null)}} + {^{:~link('30', 'gear', {'amount' : 30}, (amount == 30) ? 'selected' : null)}} + {^{:~link('50', 'gear', {'amount' : 50}, (amount == 50) ? 'selected' : null)}} +
+
+
 
+
+
+ Chemical Dispenser +
+
+
+
+ {^{for chemicals}} + {^{:~link(title, 'circle-arrow-s', commands, null, 'fixedLeft')}} + {{/for}} +
+
+
 
+
+
+ Beaker Contents +
+
+ {^{:~link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, isBeakerLoaded ? null : 'disabled', 'floatRight')}} +
+
+
+
+
+ {^{if isBeakerLoaded}} + Volume: {^{:beakerCurrentVolume}} / {^{:beakerMaxVolume}}
+ {^{for beakerContents}} + {^{:volume}} units of {^{:name}}
+ {{else}} + Beaker is empty + {{/for}} + {{else}} + No beaker loaded + {{/if}} +
+
+
\ No newline at end of file diff --git a/nano/templates/cryo.tmpl b/nano/templates/cryo.tmpl index 3399876ac0d..d55aa448415 100644 --- a/nano/templates/cryo.tmpl +++ b/nano/templates/cryo.tmpl @@ -14,16 +14,46 @@ DEAD {{/if}}
-
Health:
{^{:~string('
', [occupant.health])}}
{^{:occupant.health}}%
-
=> Brute Damage:
{^{:~string('
', [occupant.bruteLoss])}}
{^{:occupant.bruteLoss}}%
-
=> Resp. Damage:
{^{:~string('
', [occupant.oxyLoss])}}
{^{:occupant.oxyLoss}}%
-
=> Toxin Content:
{^{:~string('
', [occupant.toxLoss])}}
{^{:occupant.toxLoss}}%
-
=> Burn Severity:
{^{:~string('
', [occupant.fireLoss])}}
{^{:occupant.fireLoss}}%
-
Body Temperature:
{^{:occupant.bodyTemperature}} K
+ + {^{if occupant.stat < 2}} +
+
Health:
+ {^{if occupant.health >= 0}} + {^{:~displayBar(occupant.health, 0, occupant.maxHealth, 'good')}} + {{else}} + {^{:~displayBar(occupant.health, 0, occupant.minHealth, 'average alignRight')}} + {{/if}} +
{^{:~round(occupant.health)}}
+
+ +
+
=> Brute Damage:
+ {^{:~displayBar(occupant.bruteLoss, 0, occupant.maxHealth, 'bad')}} +
{^{:~round(occupant.bruteLoss)}}
+
+ +
+
=> Resp. Damage:
+ {^{:~displayBar(occupant.oxyLoss, 0, occupant.maxHealth, 'bad')}} +
{^{:~round(occupant.oxyLoss)}}
+
+ +
+
=> Toxin Damage:
+ {^{:~displayBar(occupant.toxLoss, 0, occupant.maxHealth, 'bad')}} +
{^{:~round(occupant.toxLoss)}}
+
+ +
+
=> Burn Severity:
+ {^{:~displayBar(occupant.fireLoss, 0, occupant.maxHealth, 'bad')}} +
{^{:~round(occupant.fireLoss)}}
+
+ {{/if}} {{/if}}
Cell Temperature:
- {^{:~string('{1} K', cellTemperatureStatus, cellTemperature)}} + {^{:~string('{1} K', cellTemperatureStatus, cellTemperature)}}
@@ -32,8 +62,11 @@
Cryo Cell Status:
-
- {^{:~link('On', 'power', {'start' : 1}, isOperating ? 'selected' : null)}}{^{:~link('Off', 'close', {'start' : 1}, isOperating ? null : 'selected')}} +
+ {^{:~link('On', 'power', {'switchOn' : 1}, isOperating ? 'selected' : null)}}{^{:~link('Off', 'close', {'switchOff' : 1}, isOperating ? null : 'selected')}} +
+
+ {^{:~link('Eject Occupant', 'arrowreturnthick-1-s', {'ejectOccupant' : 1}, hasOccupant ? null : 'disabled')}}
 
@@ -53,6 +86,6 @@ {{/if}}
- {^{:~link('Eject Beaker', 'eject', {'eject' : 1}, isBeakerLoaded ? null : 'disabled')}} + {^{:~link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, isBeakerLoaded ? null : 'disabled')}}
\ No newline at end of file