diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index cd63e415a4..1d955a9e74 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -242,30 +242,11 @@
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
/client/proc/send_resources()
// preload_vox() //Causes long delays with initial start window and subsequent windows when first logged in.
+
+ // Send NanoUI resources to this client
+ nanomanager.send_resources(src)
+
getFiles(
- 'nano/js/libraries.min.js',
- 'nano/js/nano_update.js',
- 'nano/js/nano_config.js',
- 'nano/js/nano_base_helpers.js',
- 'nano/css/shared.css',
- 'nano/css/icons.css',
- 'nano/templates/chem_dispenser.tmpl',
- 'nano/templates/cryo.tmpl',
- 'nano/templates/geoscanner.tmpl',
- 'nano/templates/dna_modifier.tmpl',
- 'nano/templates/telescience_console.tmpl',
- 'nano/templates/pda.tmpl',
- 'nano/templates/smes.tmpl',
- 'nano/templates/uplink.tmpl',
- 'nano/images/uiBackground.png',
- 'nano/images/uiIcons16.png',
- 'nano/images/uiIcons24.png',
- 'nano/images/uiBackground-Syndicate.png',
- 'nano/images/uiLinkPendingIcon.gif',
- 'nano/images/uiMaskBackground.png',
- 'nano/images/uiNoticeBackground.jpg',
- 'nano/images/uiTitleFluff.png',
- 'nano/images/uiTitleFluff-Syndicate.png',
'html/search.js',
'html/panels.css',
'icons/pda_icons/pda_atmos.png',
diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm
index b7b45060bb..ae938a9a8a 100644
--- a/code/modules/nano/nanomanager.dm
+++ b/code/modules/nano/nanomanager.dm
@@ -197,4 +197,28 @@
oldMob.open_uis.Cut()
return 1 // success
+
+ /**
+ * Sends all nano assets to the client
+ * This is called on user login
+ *
+ * @param client /client The user's client
+ *
+ * @return nothing
+ */
+
+/datum/nanomanager/proc/send_resources(client)
+ var/list/nano_asset_dirs = list(\
+ "nano/css/",\
+ "nano/images/",\
+ "nano/js/",\
+ "nano/templates/"\
+ )
+
+ var/list/files = null
+ for (var/path in nano_asset_dirs)
+ files = flist(path)
+ for(var/file in files)
+ if(copytext(file, length(file)) != "/") // files which end in "/" are actually directories, which we want to ignore
+ client << browse_rsc(file(path + file)) // send the file to the client
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 560590cbad..e46ff88e2a 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -520,129 +520,87 @@
user << browse(t1, "window=apcwires")
onclose(user, "apcwires")
- user.set_machine(src)
- var/t = "
[area.name] APCArea Power Controller ([area.name])
"
-
- //This goes after the wire stuff. They should be able to fix a physical problem when a wire is cut
- if ( (get_dist(src, user) > 1 ))
- if (!istype(user, /mob/living/silicon))
- user.unset_machine()
- user << browse(null, "window=apc")
- return
- else if (istype(user, /mob/living/silicon) && src.aidisabled && !src.malfhack)
- user << "AI control for this APC interface has been disabled."
- user.unset_machine()
- user << browse(null, "window=apc")
- return
- else if (src.malfai)
- if ((src.malfai != user && src.malfai != user:parent) && !islinked(user, malfai))
- user << "AI control for this APC interface has been disabled."
- user.unset_machine()
- user << browse(null, "window=apc")
- return
-
-
- if(locked && (!istype(user, /mob/living/silicon)))
- t += "(Swipe ID card to unlock inteface.)
"
- t += "Main breaker : [operating ? "On" : "Off"]
"
- t += "External power : [ main_status ? (main_status ==2 ? "Good" : "Low") : "None"]
"
- t += "Power cell: [cell ? "[round(cell.percent())]%" : "Not connected."]"
- if(cell)
- t += " ([charging ? ( charging == 1 ? "Charging" : "Fully charged" ) : "Not charging"])"
- t += " ([chargemode ? "Auto" : "Off"])"
-
- t += "
Power channels
"
-
- var/list/L = list ("Off","Off (Auto)", "On", "On (Auto)")
-
- t += "Equipment: [add_lspace(lastused_equip, 6)] W : [L[equipment+1]]
"
- t += "Lighting: [add_lspace(lastused_light, 6)] W : [L[lighting+1]]
"
- t += "Environmental:[add_lspace(lastused_environ, 6)] W : [L[environ+1]]
"
-
- t += "
Total load: [lastused_light + lastused_equip + lastused_environ] W"
- t += "
Cover lock: [coverlocked ? "Engaged" : "Disengaged"]"
-
- else
- if (!istype(user, /mob/living/silicon))
- t += "(Swipe ID card to lock interface.)
"
- t += "Main breaker: [operating ? "On Off" : "On Off" ]
"
- t += "External power : [ main_status ? (main_status ==2 ? "Good" : "Low") : "None"]
"
- if(cell)
- t += "Power cell: [round(cell.percent())]%"
- t += " ([charging ? ( charging == 1 ? "Charging" : "Fully charged" ) : "Not charging"])"
- t += " ([chargemode ? "Off Auto" : "Off Auto"])"
-
- else
- t += "Power cell: Not connected."
-
- t += "
Power channels
"
-
-
- t += "Equipment: [add_lspace(lastused_equip, 6)] W : "
- switch(equipment)
- if(0)
- t += "Off On Auto"
- if(1)
- t += "Off On Auto (Off)"
- if(2)
- t += "Off On Auto"
- if(3)
- t += "Off On Auto (On)"
- t +="
"
-
- t += "Lighting: [add_lspace(lastused_light, 6)] W : "
-
- switch(lighting)
- if(0)
- t += "Off On Auto"
- if(1)
- t += "Off On Auto (Off)"
- if(2)
- t += "Off On Auto"
- if(3)
- t += "Off On Auto (On)"
- t +="
"
-
-
- t += "Environmental:[add_lspace(lastused_environ, 6)] W : "
- switch(environ)
- if(0)
- t += "Off On Auto"
- if(1)
- t += "Off On Auto (Off)"
- if(2)
- t += "Off On Auto"
- if(3)
- t += "Off On Auto (On)"
-
-
-
- t += "
Total load: [lastused_light + lastused_equip + lastused_environ] W
"
- t += "
Cover lock: [coverlocked ? "Engaged" : "Disengaged"]"
-
-
- if (istype(user, /mob/living/silicon))
- t += "
Overload lighting circuit
"
- if (ticker && ticker.mode)
-// world << "there's a ticker"
- if(user.mind in ticker.mode.malf_ai)
-// world << "ticker says its malf"
- if (!src.malfai)
- t += "
Override Programming
"
- else
- t += "
APC Hacked
"
- /*if(!src.occupant)
- t += "Shunt Core Processes
"
- else
- t += "Core Processes Uploaded
"*/
-
- t += "
Close"
-
- t += ""
- user << browse(t, "window=apc")
- onclose(user, "apc")
+ // Open the APC NanoUI
+ ui_interact(user)
return
+/obj/machinery/power/apc/proc/get_malf_status(mob/user)
+ if (ticker && ticker.mode && (user.mind in ticker.mode.malf_ai) && istype(user, /mob/living/silicon/ai))
+ if (src.malfai == (user:parent ? user:parent : user))
+ if (src.occupant == user)
+ return 3 // 3 = User is shunted in this APC
+ else if (istype(user.loc, /obj/machinery/power/apc))
+ return 4 // 4 = User is shunted in another APC
+ else
+ return 2 // 2 = APC hacked by user, and user is in its core.
+ else
+ return 1 // 1 = APC not hacked.
+ else
+ return 0 // 0 = User is not a Malf AI
+
+/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ if(!user)
+ return
+
+ var/list/data = list(
+ "locked" = locked,
+ "isOperating" = operating,
+ "externalPower" = main_status,
+ "powerCellStatus" = cell ? cell.percent() : null,
+ "chargeMode" = chargemode,
+ "chargingStatus" = charging,
+ "totalLoad" = lastused_equip + lastused_light + lastused_environ,
+ "coverLocked" = coverlocked,
+ "siliconUser" = istype(user, /mob/living/silicon),
+ "malfStatus" = get_malf_status(user),
+
+ "powerChannels" = list(
+ list(
+ "title" = "Equipment",
+ "powerLoad" = lastused_equip,
+ "status" = equipment,
+ "topicParams" = list(
+ "auto" = list("eqp" = 3),
+ "on" = list("eqp" = 2),
+ "off" = list("eqp" = 1)
+ )
+ ),
+ list(
+ "title" = "Lighting",
+ "powerLoad" = lastused_light,
+ "status" = lighting,
+ "topicParams" = list(
+ "auto" = list("lgt" = 3),
+ "on" = list("lgt" = 2),
+ "off" = list("lgt" = 1)
+ )
+ ),
+ list(
+ "title" = "Environment",
+ "powerLoad" = lastused_environ,
+ "status" = environ,
+ "topicParams" = list(
+ "auto" = list("env" = 3),
+ "on" = list("env" = 2),
+ "off" = list("env" = 1)
+ )
+ )
+ )
+ )
+
+ // update the ui if it exists, returns null if no ui is passed/found
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+ if (!ui)
+ // the ui does not exist, so we'll create a new() one
+ // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
+ ui = new(user, src, ui_key, "apc.tmpl", "[area.name] - APC", 520, data["siliconUser"] ? 465 : 440)
+ // when the ui is first opened this is the data it will use
+ ui.set_initial_data(data)
+ // open the new ui window
+ ui.open()
+ // auto update every Master Controller tick
+ ui.set_auto_update(1)
+
/obj/machinery/power/apc/proc/report()
return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])"
@@ -754,8 +712,8 @@
istype(user, /mob/living/silicon) || \
istype(user, /mob/living/carbon/monkey) /*&& ticker && ticker.mode.name == "monkey"*/) )
user << "\red You don't have the dexterity to use this [src]!"
- user << browse(null, "window=apc")
- user.unset_machine()
+ nanomanager.close_user_uis(user, src)
+
return 0
if(user.restrained())
user << "\red You must have free hands to use this [src]"
@@ -776,13 +734,13 @@
)
if(!loud)
user << "\red \The [src] have AI control disabled!"
- user << browse(null, "window=apc")
- user.unset_machine()
+ nanomanager.close_user_uis(user, src)
+
return 0
else
if ((!in_range(src, user) || !istype(src.loc, /turf)))
- user << browse(null, "window=apc")
- user.unset_machine()
+ nanomanager.close_user_uis(user, src)
+
return 0
var/mob/living/carbon/human/H = user
@@ -800,9 +758,8 @@
if(!(isrobot(usr) && (href_list["apcwires"] || href_list["pulse"])))
if(!can_use(usr, 1))
return
- src.add_fingerprint(usr)
- if(usingUI) // If we set their machine and they're not using the UI, it'll cause the UI to pop up.
- usr.set_machine(src)
+ src.add_fingerprint(usr)
+
if (href_list["apcwires"])
var/t1 = text2num(href_list["apcwires"])
if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
@@ -864,12 +821,12 @@
update_icon()
update()
else if( href_list["close"] )
- usr << browse(null, "window=apc")
- usr.unset_machine()
+ nanomanager.close_user_uis(usr, src)
+
return
else if (href_list["close2"])
usr << browse(null, "window=apcwires")
- usr.unset_machine()
+
return
else if (href_list["overload"])
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 776e07e42c..100882055d 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -146,7 +146,7 @@
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
- ui = new(user, src, ui_key, "chem_dispenser.tmpl", ui_title, 370, 605)
+ ui = new(user, src, ui_key, "chem_dispenser.tmpl", ui_title, 380, 650)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
diff --git a/nano/templates/apc.tmpl b/nano/templates/apc.tmpl
new file mode 100644
index 0000000000..56c6a1f1ee
--- /dev/null
+++ b/nano/templates/apc.tmpl
@@ -0,0 +1,174 @@
+
+ {{if siliconUser}}
+
+ Interface Lock:
+
+
+ {{:~link('Engaged', 'locked', {'toggleaccess' : 1}, locked ? 'selected' : null)}}{{:~link('Disengaged', 'unlocked', {'toggleaccess' : 1}, malfStatus >= 2 ? 'linkOff' : (locked ? null : 'selected'))}}
+
+
+ {{else}}
+ {{if locked}}
+ Swipe an ID card to unlock this interface.
+ {{else}}
+ Swipe an ID card to lock this interface.
+ {{/if}}
+ {{/if}}
+
+
+
+
+
Power Status
+
+
+
+ Main Breaker:
+
+
+ {{if locked && !siliconUser}}
+ {{if isOperating}}
+ On
+ {{else}}
+ Off
+ {{/if}}
+ {{else}}
+ {{:~link('On', 'power', {'breaker' : 1}, isOperating ? 'selected' : null)}}{{:~link('Off', 'close', {'breaker' : 1}, isOperating ? null : 'selected')}}
+ {{/if}}
+
+
+
+
+
+ External Power:
+
+
+ {{if externalPower == 2}}
+ Good
+ {{else externalPower == 1}}
+ Low
+ {{else}}
+ None
+ {{/if}}
+
+
+
+
+
+ Power Cell:
+
+ {{if powerCellStatus == null}}
+
+ Power cell removed.
+
+ {{else}}
+
+ {{:~round(powerCellStatus*10)/10}}%
+
+ {{:~displayBar(powerCellStatus, 0, 100, powerCellStatus >= 50 ? 'good' : powerCellStatus >= 25 ? 'average' : 'bad')}}
+ {{/if}}
+
+
+ {{if powerCellStatus != null}}
+
+
+ Charge Mode:
+
+
+ {{if locked && !siliconUser}}
+ {{if chargeMode}}
+ Auto
+ {{else}}
+ Off
+ {{/if}}
+ {{else}}
+ {{:~link('Auto', 'refresh', {'cmode' : 1}, chargeMode ? 'selected' : null)}}{{:~link('Off', 'close', {'cmode' : 1}, chargeMode ? null : 'selected')}}
+ {{/if}}
+
+ {{if chargingStatus > 1}}
+ [Fully Charged]
+ {{else chargingStatus == 1}}
+ [Charging]
+ {{else}}
+ [Not Charging]
+ {{/if}}
+
+
+ {{/if}}
+
+
+
Power Channels
+
+ {{for powerChannels}}
+
+
+ {{:title}}:
+
+
+ {{:powerLoad}} W
+
+
+
+ {{if status <= 1}}
+ Off
+ {{else status >= 2}}
+ On
+ {{/if}}
+ {{if status == 1 || status == 3}}
+ [Auto]
+ {{else}}
+ [Manual]
+ {{/if}}
+
+ {{if !~root.locked || ~root.siliconUser}}
+
+ {{:~link('Auto', 'refresh', topicParams.auto, (status == 1 || status == 3) ? 'selected' : null)}}
+ {{:~link('On', 'power', topicParams.on, (status == 2) ? 'selected' : null)}}
+ {{:~link('Off', 'close', topicParams.off, (status == 0) ? 'selected' : null)}}
+
+ {{/if}}
+
+ {{/for}}
+
+
+
+ Total Load:
+
+
+ {{:totalLoad}} W
+
+
+
+
+
+
+
+ Cover Lock:
+
+
+ {{if locked && !siliconUser}}
+ {{if coverLocked}}
+ Engaged
+ {{else}}
+ Disengaged
+ {{/if}}
+ {{else}}
+ {{:~link('Engaged', 'locked', {'lock' : 1}, coverLocked ? 'selected' : null)}}{{:~link('Disengaged', 'unlocked', {'lock' : 1}, coverLocked ? null : 'selected')}}
+ {{/if}}
+
+
+
+ {{if siliconUser}}
+
System Overrides
+
+
+ {{:~link('Overload Lighting Circuit', 'lightbulb', {'overload' : 1})}}
+ {{if malfStatus == 1}}
+ {{:~link('Override Programming', 'script', {'malfhack' : 1})}}
+ {{else malfStatus > 1}}
+
APC Hacked
+ {{/if}}
+
+ {{/if}}
+
+
+
\ No newline at end of file
diff --git a/nano/templates/smes.tmpl b/nano/templates/smes.tmpl
index c4431cd805..760228e4cd 100644
--- a/nano/templates/smes.tmpl
+++ b/nano/templates/smes.tmpl
@@ -34,8 +34,8 @@
{{:~displayBar(chargeLevel, 0, chargeMax)}}
{{:~link('MIN', null, {'input' : 'min'}, (chargeLevel > 0) ? null : 'disabled')}}
- {{:~link('MAX', null, {'input' : 'max'}, (chargeLevel < chargeMax) ? null : 'disabled')}}
{{:~link('SET', null, {'input' : 'set'}, null)}}
+ {{:~link('MAX', null, {'input' : 'max'}, (chargeLevel < chargeMax) ? null : 'disabled')}}
{{:chargeLevel}} W
@@ -59,8 +59,8 @@
{{:~displayBar(outputLevel, 0, outputMax)}}
{{:~link('MIN', null, {'output' : 'min'}, (outputLevel > 0) ? null : 'disabled')}}
- {{:~link('MAX', null, {'output' : 'max'}, (outputLevel < outputMax) ? null : 'disabled')}}
{{:~link('SET', null, {'output' : 'set'}, null)}}
+ {{:~link('MAX', null, {'output' : 'max'}, (outputLevel < outputMax) ? null : 'disabled')}}
{{:outputLevel}} W