From 6b70bfec7400fd7693af27796076fe047919d658 Mon Sep 17 00:00:00 2001 From: Markolie Date: Sun, 1 Mar 2015 04:22:12 +0100 Subject: [PATCH] NanoUI update --- code/game/machinery/computer/camera.dm | 3 + code/game/machinery/computer/computer.dm | 12 ++ code/game/machinery/computer/law.dm | 6 +- code/game/machinery/machinery.dm | 70 ++------ code/game/machinery/portable_turret.dm | 33 ++-- code/game/objects/items/devices/uplinks.dm | 7 +- code/game/objects/objs.dm | 22 ++- .../modules/mob/living/silicon/robot/robot.dm | 10 -- code/modules/mob/mob_helpers.dm | 5 + code/modules/nano/nanoexternal.dm | 7 +- code/modules/nano/nanointeraction.dm | 120 +++++++++++++ code/modules/nano/nanomanager.dm | 3 +- code/modules/nano/nanoprocs.dm | 11 -- code/modules/nano/nanoui.dm | 167 ++++-------------- code/modules/power/apc.dm | 8 +- code/modules/power/smes.dm | 3 + code/setup.dm | 2 + nano/css/shared.css | 10 +- nano/js/nano_base_helpers.js | 3 + paradise.dme | 2 +- 20 files changed, 255 insertions(+), 249 deletions(-) create mode 100644 code/modules/nano/nanointeraction.dm delete mode 100644 code/modules/nano/nanoprocs.dm diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index c48a2056572..8370dd40f3c 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -199,6 +199,9 @@ else if(isAI(user)) var/mob/living/silicon/ai/A = user + // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. + if(!A.is_in_chassis()) + return 0 A.eyeobj.setLoc(get_turf(C)) A.client.eye = A.eyeobj else diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 13fe459ec45..b5e28c3b7a1 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -102,7 +102,19 @@ stat |= BROKEN update_icon() +/obj/machinery/computer/proc/decode(text) + // Adds line breaks + text = replacetext(text, "\n", "
") + return text + +/obj/machinery/computer/attack_ghost(user as mob) + return src.attack_hand(user) +/obj/machinery/computer/attack_hand(user as mob) + /* Observers can view computers, but not actually use them via Topic*/ + if(istype(user, /mob/dead/observer)) return 0 + return ..() + /obj/machinery/computer/attackby(I as obj, user as mob, params) if(istype(I, /obj/item/weapon/screwdriver) && circuit) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 6901f72d63f..4802e855af2 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -53,7 +53,8 @@ usr << "[src.current.name] selected for law changes." return - + attack_ghost(user as mob) + return 1 /obj/machinery/computer/borgupload name = "Cyborg Upload" @@ -85,3 +86,6 @@ else usr << "[src.current.name] selected for law changes." return + + attack_ghost(user as mob) + return 1 diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 519fb09b0cd..6a0bcbf496f 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -184,65 +184,21 @@ Class Procs: use_power(active_power_usage,power_channel, 1) return 1 -/obj/machinery/Topic(href, href_list, var/nowindow = 0, var/checkrange = 1) - if(..()) - return 1 - if(!can_be_used_by(usr, be_close = checkrange)) - return 1 - add_fingerprint(usr) - return 0 +/obj/machinery/CanUseTopic(var/mob/user, var/be_close) + if(!interact_offline && (stat & (NOPOWER|BROKEN))) + return STATUS_CLOSE -/obj/machinery/proc/can_be_used_by(mob/user, be_close = 1) - if(!interact_offline && stat & (NOPOWER|BROKEN)) - return 0 - if(!user.canUseTopic(src, be_close)) - return 0 - return 1 + return ..() + +/obj/machinery/CouldUseTopic(var/mob/user) + ..() + user.set_machine(src) + +/obj/machinery/CouldNotUseTopic(var/mob/user) + usr.unset_machine() + +//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////// - -/mob/proc/canUseTopic(atom/movable/M, be_close = 1) - return - -/mob/dead/observer/canUseTopic(atom/movable/M, be_close = 1) - if(check_rights(R_ADMIN, 0)) - return - -/mob/living/canUseTopic(atom/movable/M, be_close = 1, no_dextery = 0) - if(no_dextery) - src << "You don't have the dexterity to do this!" - return 0 - return be_close && !in_range(M, src) - -/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 1) - if(restrained() || lying || stat || stunned || weakened) - return - if(be_close && !in_range(M, src)) - if(TK in mutations) - var/mob/living/carbon/human/H = M - if(istype(H.l_hand, /obj/item/tk_grab) || istype(H.r_hand, /obj/item/tk_grab)) - return 1 - return - if(!isturf(M.loc) && M.loc != src) - return - return 1 - -/mob/living/silicon/ai/canUseTopic(atom/movable/M) - if(stat) - return - //stop AIs from leaving windows open and using then after they lose vision - //apc_override is needed here because AIs use their own APC when powerless - if(cameranet && !cameranet.checkTurfVis(get_turf(M)) && !apc_override) - return - return 1 - -/mob/living/silicon/robot/canUseTopic(atom/movable/M) - if(stat || lockcharge || stunned || weakened) - return - return 1 - -//////////////////////////////////////////////////////////////////////////////////////////// - /obj/machinery/attack_ai(var/mob/user as mob) if(isAI(user)) var/mob/living/silicon/ai/A = user diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index cdab2906826..fa56228cc09 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -155,15 +155,13 @@ qdel(cover) // qdel ..() -/obj/machinery/porta_turret/proc/isLocked(mob/user,var/message = 1) +/obj/machinery/porta_turret/proc/isLocked(mob/user) if(ailock && (isrobot(user) || isAI(user))) - if(message) - user << "There seems to be a firewall preventing you from accessing this device." + user << "There seems to be a firewall preventing you from accessing this device." return 1 if(locked && !(isrobot(user) || isAI(user))) - if(message) - user << "Access denied." + user << "Access denied." return 1 return 0 @@ -208,20 +206,23 @@ /obj/machinery/porta_turret/proc/HasController() var/area/A = get_area(src) return A && A.turret_controls.len > 0 - -/obj/machinery/porta_turret/Topic(href, href_list, var/nowindow = 0) - if(..()) - return 1 - + +/obj/machinery/porta_turret/CanUseTopic(var/mob/user) if(HasController()) - usr << "Turrets can only be controlled using the assigned turret controller." - return 1 + user << "Turrets can only be controlled using the assigned turret controller." + return STATUS_CLOSE - if(isLocked(usr,0)) - return 1 + if(isLocked(user)) + return STATUS_CLOSE if(!anchored) usr << "\The [src] has to be secured first!" + return STATUS_CLOSE + + return STATUS_INTERACTIVE + +/obj/machinery/porta_turret/Topic(href, href_list, var/nowindow = 0) + if(..()) return 1 if(href_list["command"] && href_list["value"]) @@ -754,12 +755,12 @@ if(4) if(isprox(I)) - build_step = 5 if(!user.unEquip(I)) user << "\the [I] is stuck to your hand, you cannot put it in \the [src]" return + build_step = 5 + del(I) // del user << "You add the prox sensor to the turret." - qdel(I) // qdel return //attack_hand() removes the gun diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index 3fce029a056..fc7a294309e 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -103,7 +103,9 @@ var/list/world_uplinks = list() /obj/item/device/uplink/Topic(href, href_list) - ..() + if(..()) + return 1 + if(!active) return @@ -152,7 +154,8 @@ var/list/world_uplinks = list() desc = "There is something wrong if you're examining this." /obj/item/device/uplink/hidden/Topic(href, href_list) - ..() + if(..()) + return 1 if(href_list["lock"]) toggle() usr << browse(null, "window=hidden") diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 6049d30bd51..168134c6591 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -21,15 +21,27 @@ // Reagent ID => friendly name var/list/reagents_to_log=list() -/obj/Topic(href, href_list, var/nowindow = 0, var/checkrange = 1) +/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/custom_state = default_state) // Calling Topic without a corresponding window open causes runtime errors if(!nowindow && ..()) return 1 - if(usr.can_interact_with_interface(nano_host(), checkrange) != STATUS_INTERACTIVE) - return 1 - add_fingerprint(usr) - return 0 + // In the far future no checks are made in an overriding Topic() beyond if(..()) return + // Instead any such checks are made in CanUseTopic() + var/obj/host = nano_host() + if(host.CanUseTopic(usr, href_list, custom_state) == STATUS_INTERACTIVE) + CouldUseTopic(usr) + return 0 + + CouldNotUseTopic(usr) + return 1 + +/obj/proc/CouldUseTopic(var/mob/user) + var/atom/host = nano_host() + host.add_fingerprint(user) + +/obj/proc/CouldNotUseTopic(var/mob/user) + // Nada /obj/Destroy() machines -= src diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 3775adfba20..9bb0eee9203 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1484,16 +1484,6 @@ var/list/robot_verbs_default = list( radio.recalculateChannels() playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) - -/mob/living/silicon/robot/syndicate/canUseTopic(atom/movable/M) - if(stat || lockcharge || stunned || weakened) - return - if(z in config.admin_levels) - return 1 - /*if(istype(M, /obj/machinery)) - var/obj/machinery/Machine = M - return Machine.emagged*/ - return 1 /mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/oldname, var/newname) if(!connected_ai) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index cf801fc4311..d306f739835 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -114,6 +114,11 @@ proc/isembryo(A) if(istype(A, /mob/living/silicon)) return 1 return 0 + +/proc/isSilicon(A) // Bay support + if(istype(A, /mob/living/silicon)) + return 1 + return 0 /proc/isliving(A) if(istype(A, /mob/living)) diff --git a/code/modules/nano/nanoexternal.dm b/code/modules/nano/nanoexternal.dm index 3e5a011d5fa..b029019f1a3 100644 --- a/code/modules/nano/nanoexternal.dm +++ b/code/modules/nano/nanoexternal.dm @@ -31,18 +31,13 @@ * ui_interact is currently defined for /atom/movable * * @param user /mob The mob who is interacting with this ui -<<<<<<< HEAD * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui -======= - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui * @param force_open boolean Force the UI to (re)open, even if it's already open ->>>>>>> 7e7e6cd... Continued work in progress on a major revision of the NanoUI templating system. * * @return nothing */ -/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/custom_state = null) return // Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob diff --git a/code/modules/nano/nanointeraction.dm b/code/modules/nano/nanointeraction.dm new file mode 100644 index 00000000000..d746c64d689 --- /dev/null +++ b/code/modules/nano/nanointeraction.dm @@ -0,0 +1,120 @@ +/atom/movable/proc/nano_host() + return src + +/obj/nano_module/nano_host() + return loc + + +/atom/movable/proc/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state) + return user.can_use_topic(nano_host(), custom_state) + + +/mob/proc/can_use_topic(var/mob/user, var/datum/topic_state/custom_state) + return STATUS_CLOSE // By default no mob can do anything with NanoUI + +/mob/dead/observer/can_use_topic() + if(check_rights(R_ADMIN, 0)) + return STATUS_INTERACTIVE // Admins are more equal + return STATUS_UPDATE // Ghosts can view updates + +/mob/living/silicon/pai/can_use_topic(var/src_object) + if(src_object == src && !stat) + return STATUS_INTERACTIVE + else + return ..() + +/mob/living/silicon/robot/can_use_topic(var/src_object, var/datum/topic_state/custom_state) + if(stat || !client) + return STATUS_CLOSE + if(lockcharge || stunned || weakened) + return STATUS_DISABLED + // robots can interact with things they can see within their view range + if(!(custom_state.flags & NANO_IGNORE_DISTANCE) && (src_object in view(src))) + return STATUS_INTERACTIVE // interactive (green visibility) + return STATUS_DISABLED // no updates, completely disabled (red visibility) + +/mob/living/silicon/robot/syndicate/can_use_topic(var/src_object) + . = ..() + if(. != STATUS_INTERACTIVE) + return + + if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level + return STATUS_INTERACTIVE + if(istype(get_area(src), /area/syndicate_station)) // If elsewhere, they can interact with everything on the syndicate shuttle + return STATUS_INTERACTIVE + if(istype(src_object, /obj/machinery)) // Otherwise they can only interact with emagged machinery + var/obj/machinery/Machine = src_object + if(Machine.emagged) + return STATUS_INTERACTIVE + return STATUS_UPDATE + +/mob/living/silicon/ai/can_use_topic(var/src_object) + if(!client || check_unable(1)) + return STATUS_CLOSE + // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) + // unless it's on the same level as the object it's interacting with. + var/turf/T = get_turf(src_object) + if(!T || !(z == T.z || (T.z in config.player_levels))) + return STATUS_CLOSE + + // If an object is in view then we can interact with it + if(src_object in view(client.view, src)) + return STATUS_INTERACTIVE + + // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view + if(is_in_chassis()) + //stop AIs from leaving windows open and using then after they lose vision + //apc_override is needed here because AIs use their own APC when powerless + if(cameranet && !cameranet.checkTurfVis(get_turf(src_object))) + return apc_override ? STATUS_INTERACTIVE : STATUS_CLOSE + return STATUS_INTERACTIVE + + return STATUS_CLOSE + +/mob/living/proc/shared_living_nano_interaction(var/src_object) + if (src.stat != CONSCIOUS) + return STATUS_CLOSE // no updates, close the interface + else if (restrained() || lying || stat || stunned || weakened) + return STATUS_UPDATE // update only (orange visibility) + return STATUS_INTERACTIVE + +/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) + if(!isturf(src_object.loc)) + if(src_object.loc == src) // Item in the inventory + return STATUS_INTERACTIVE + if(src.contents.Find(src_object.loc)) // A hidden uplink inside an item + return STATUS_INTERACTIVE + + if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates + return STATUS_CLOSE + + var/dist = get_dist(src_object, src) + if (dist <= 1) + return STATUS_INTERACTIVE // interactive (green visibility) + else if (dist <= 2) + return STATUS_UPDATE // update only (orange visibility) + else if (dist <= 4) + return STATUS_DISABLED // no updates, completely disabled (red visibility) + return STATUS_CLOSE + +/mob/living/can_use_topic(var/src_object, var/datum/topic_state/custom_state) + . = shared_living_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE)) + . = shared_living_nano_distance(src_object) + if(STATUS_INTERACTIVE) + return STATUS_UPDATE + +/mob/living/carbon/human/can_use_topic(var/src_object, var/datum/topic_state/custom_state) + . = shared_living_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE)) + . = shared_living_nano_distance(src_object) + if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction. + return STATUS_INTERACTIVE + +/var/global/datum/topic_state/default_state = new() + +/datum/topic_state + var/flags = 0 + +/datum/topic_state/proc/href_list(var/mob/user) + return list() \ No newline at end of file diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm index 36241b2ec75..1fd76dcf726 100644 --- a/code/modules/nano/nanomanager.dm +++ b/code/modules/nano/nanomanager.dm @@ -186,7 +186,8 @@ return 0 // wasn't open processing_uis.Remove(ui) - ui.user.open_uis.Remove(ui) + if(ui.user) // Sanity check in case a user has been deleted (say a blown up borg watching the alarm interface) + ui.user.open_uis.Remove(ui) var/list/uis = open_uis[src_object_key][ui.ui_key] uis.Remove(ui) diff --git a/code/modules/nano/nanoprocs.dm b/code/modules/nano/nanoprocs.dm deleted file mode 100644 index 81b939cf5c4..00000000000 --- a/code/modules/nano/nanoprocs.dm +++ /dev/null @@ -1,11 +0,0 @@ -/atom/movable/proc/nano_host() - return src - -/obj/nano_module/nano_host() - return loc - -/atom/movable/proc/nano_can_update() - return 1 - -/obj/machinery/nano_can_update() - return !(stat & (NOPOWER|BROKEN)) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 884fee74982..0a588e9b51a 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -13,8 +13,6 @@ nanoui is used to open and update nano browser uis var/atom/movable/src_object // the title of this ui var/title - // /vg/ - Whether to write debug information to nano/debug.html - var/writeDebug=TRUE // the key of this ui, this is to allow multiple (different) uis for each src_object var/ui_key // window_id is used as the window name/identifier for browse and onclose @@ -53,13 +51,14 @@ nanoui is used to open and update nano browser uis var/is_auto_updating = 0 // the current status/visibility of the ui var/status = STATUS_INTERACTIVE - + + // Relationship between a master interface and its children. Used in update_status + var/datum/nanoui/master_ui + var/list/datum/nanoui/children = list() + var/datum/topic_state/custom_state = null + var/cached_data = null - - // 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 - /** * Create a new nanoui instance. * @@ -74,17 +73,22 @@ nanoui is used to open and update nano browser uis * * @return /nanoui new nanoui object */ -/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null) +/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/custom_state = default_state) user = nuser src_object = nsrc_object ui_key = nui_key window_id = "[ui_key]\ref[src_object]" + src.master_ui = master_ui + if(master_ui) + master_ui.children += src + src.custom_state = custom_state + // add the passed template filename as the "main" template, this is required add_template("main", ntemplate_filename) if (ntitle) - title = ntitle + title = sanitize(ntitle) if (nwidth) width = nwidth if (nheight) @@ -139,120 +143,13 @@ nanoui is used to open and update nano browser uis */ /datum/nanoui/proc/update_status(var/push_update = 0) var/atom/movable/host = src_object.nano_host() - if(!host.nano_can_update()) + var/new_status = host.CanUseTopic(user, list(), custom_state) + if(master_ui) + new_status = min(new_status, master_ui.status) + + set_status(new_status, push_update) + if(new_status == STATUS_CLOSE) close() - return - - var/status = user.can_interact_with_interface(host.nano_host()) - set_status(status, push_update) - if(status == STATUS_CLOSE) - close() - -/* - Procs called by update_status() -*/ - -/mob/living/silicon/pai/can_interact_with_interface(src_object) - if(src_object == src && !stat) - return STATUS_INTERACTIVE - else - return ..() - -/mob/proc/can_interact_with_interface(var/src_object) - return STATUS_CLOSE // By default no mob can do anything with NanoUI - -/mob/dead/observer/can_interact_with_interface() - if(check_rights(R_ADMIN, 0)) - return STATUS_INTERACTIVE // Admins are more equal - return STATUS_UPDATE // Ghosts can view updates - -/mob/living/silicon/robot/can_interact_with_interface(var/src_object) - if(stat || !client) - return STATUS_CLOSE - if(lockcharge || stunned || weakened) - return STATUS_DISABLED - if (src_object in view(client.view, src)) // robots can see and interact with things they can see within their view range - return STATUS_INTERACTIVE // interactive (green visibility) - return STATUS_DISABLED // no updates, completely disabled (red visibility) - -/mob/living/silicon/robot/syndicate/can_interact_with_interface(var/src_object) - . = ..() - if(. != STATUS_INTERACTIVE) - return - - if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level - return STATUS_INTERACTIVE - if(istype(get_area(src), /area/syndicate_station) || istype(get_area(src), /area/traitor)) // If elsewhere, they can interact with everything on the syndicate shuttle and traitor station - return STATUS_INTERACTIVE - if(istype(src_object, /obj/machinery)) // And they can also interact with everything else - /*var/obj/machinery/Machine = src_object - if(Machine.emagged) // Uncomment so they can only interact with emagged machinery - return STATUS_INTERACTIVE*/ - return STATUS_INTERACTIVE - return STATUS_UPDATE - -/mob/living/silicon/ai/can_interact_with_interface(var/src_object) - if(!client || check_unable(1)) - return STATUS_CLOSE - // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) - // unless it's on the same level as the object it's interacting with. - var/turf/T = get_turf(src_object) - if(!T || !(z == T.z || (T.z in config.player_levels))) - return STATUS_CLOSE - - // If an object is in view then we can interact with it - if(src_object in view(client.view, src)) - return STATUS_INTERACTIVE - - // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view - if(is_in_chassis()) - //stop AIs from leaving windows open and using then after they lose vision - //apc_override is needed here because AIs use their own APC when powerless - if(cameranet && !cameranet.checkTurfVis(get_turf(src_object))) - return apc_override ? STATUS_INTERACTIVE : STATUS_CLOSE - return STATUS_INTERACTIVE - - return STATUS_CLOSE - -/mob/living/proc/shared_living_nano_interaction(var/src_object) - if (src.stat != CONSCIOUS) - return STATUS_CLOSE // no updates, close the interface - else if (restrained() || lying || stat || stunned || weakened) - return STATUS_UPDATE // update only (orange visibility) - return STATUS_INTERACTIVE - -/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) - if(!isturf(src_object.loc)) - if(src_object.loc == src) // Item in the inventory - return STATUS_INTERACTIVE - if(src.contents.Find(src_object.loc)) // A hidden uplink inside an item - return STATUS_INTERACTIVE - - if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates - return STATUS_CLOSE - - var/dist = get_dist(src_object, src) - if (dist <= 1) - return STATUS_INTERACTIVE // interactive (green visibility) - else if (dist <= 2) - return STATUS_UPDATE // update only (orange visibility) - else if (dist <= 4) - return STATUS_DISABLED // no updates, completely disabled (red visibility) - return STATUS_CLOSE - -/mob/living/can_interact_with_interface(var/src_object, var/be_close = 1) - . = shared_living_nano_interaction(src_object) - if(. == STATUS_INTERACTIVE && be_close) - . = shared_living_nano_distance(src_object) - if(STATUS_INTERACTIVE) - return STATUS_UPDATE - -/mob/living/carbon/human/can_interact_with_interface(var/src_object, var/be_close = 1) - . = shared_living_nano_interaction(src_object) - if(. == STATUS_INTERACTIVE && be_close) - . = shared_living_nano_distance(src_object) - if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction. - return STATUS_INTERACTIVE /** * Set the ui to auto update (every master_controller tick) @@ -408,7 +305,7 @@ nanoui is used to open and update nano browser uis */ /datum/nanoui/proc/set_show_map(nstate) show_map = nstate - + /** * Toggle showing the map ui * @@ -495,20 +392,15 @@ nanoui is used to open and update nano browser uis * @return nothing */ /datum/nanoui/proc/open() - var/window_size = "" if (width && height) window_size = "size=[width]x[height];" update_status(0) if(status == STATUS_CLOSE) return - var/html=get_html() - if(src.writeDebug) - var/f = file("nano/debug.html") - fdel(f) - f << html - user << browse(html, "window=[window_id];[window_size][window_options]") - winset(user, "mapwindow.map", "focus=true") // Return keyboard focus to map. + + user << browse(get_html(), "window=[window_id];[window_size][window_options]") + winset(user, "mapwindow.map", "focus=true") // return keyboard focus to map on_close_winset() //onclose(user, window_id) nanomanager.ui_opened(src) @@ -522,6 +414,8 @@ nanoui is used to open and update nano browser uis is_auto_updating = 0 nanomanager.ui_closed(src) user << browse(null, "window=[window_id]") + for(var/datum/nanoui/child in children) + child.close() /** * Set the UI window to call the nanoclose verb when the window is closed @@ -535,11 +429,12 @@ nanoui is used to open and update nano browser uis var/params = "\ref[src]" winset(user, window_id, "on-close=\"nanoclose [params]\"") - + /** * Appends already processed json txt to the list2json proc when setting initial-data and data pushes * Used for data that is fucking huge like manifests and camera lists that doesn't change often. * And we only want to process them when they change. + * Fuck javascript * * @return nothing */ @@ -547,6 +442,7 @@ nanoui is used to open and update nano browser uis cached_data = data return + /** * Push data to an already open UI window * @@ -579,12 +475,12 @@ nanoui is used to open and update nano browser uis if(href_list["showMap"]) set_show_map(text2num(href_list["showMap"])) map_update = 1 - + if(href_list["mapZLevel"]) set_map_z_level(text2num(href_list["mapZLevel"])) map_update = 1 - if ((src_object && src_object.Topic(href, href_list)) || map_update) + if ((src_object && src_object.Topic(href, href_list, 0, custom_state)) || map_update) nanomanager.update_uis(src_object) // update all UIs attached to src_object /** @@ -611,5 +507,4 @@ nanoui is used to open and update nano browser uis * @return nothing */ /datum/nanoui/proc/update(var/force_open = 0) - src_object.ui_interact(user, ui_key, src, force_open) - + src_object.ui_interact(user, ui_key, src, force_open, master_ui, custom_state) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 86dfcc247c4..d0cf07fc9e1 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -691,8 +691,12 @@ else beenhit += 1 return - - + +/obj/machinery/power/apc/attack_ghost(user as mob) + if(stat & (BROKEN|MAINT)) + return + return ui_interact(user) + /obj/machinery/power/apc/interact(mob/user) if(!user) return diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 1f1e01938fb..d7fedfb7a8f 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -332,6 +332,9 @@ add_fingerprint(user) ui_interact(user) +/obj/machinery/power/smes/attack_ghost(mob/user) + ui_interact(user) + /obj/machinery/power/smes/attack_hand(mob/user) add_fingerprint(user) ui_interact(user) diff --git a/code/setup.dm b/code/setup.dm index db4fe56cb65..c18d1ac0d12 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -968,6 +968,8 @@ var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF") #define STATUS_DISABLED 0 // RED Visability #define STATUS_CLOSE -1 // Close the interface +#define NANO_IGNORE_DISTANCE 1 + //Click cooldowns, in tenths of a second #define CLICK_CD_MELEE 8 #define CLICK_CD_RANGE 4 diff --git a/nano/css/shared.css b/nano/css/shared.css index a733031b8de..02476dcb8f1 100644 --- a/nano/css/shared.css +++ b/nano/css/shared.css @@ -128,7 +128,7 @@ img, a img { h1, h2, h3, h4, h5, h6 { margin: 0; padding: 12px 0 6px 0; - color: #517087; + color: #FFFFFF; clear: both; } @@ -488,6 +488,14 @@ div.notice { text-align: center; } +table.fixed { + table-layout:fixed; +} + +table.fixed td { + overflow: hidden; +} + /* Table styling for the power monitor */ table.pmon { border: 2px solid RoyalBlue; diff --git a/nano/js/nano_base_helpers.js b/nano/js/nano_base_helpers.js index 67dffc064cc..40c6b6077e5 100644 --- a/nano/js/nano_base_helpers.js +++ b/nano/js/nano_base_helpers.js @@ -64,6 +64,9 @@ NanoBaseHelpers = function () round: function(number) { return Math.round(number); }, + fixed: function(number) { + return Math.round(number * 10) / 10; + }, // Round a number down to integer floor: function(number) { return Math.floor(number); diff --git a/paradise.dme b/paradise.dme index fff8f6e2281..c45f9ec2a06 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1418,9 +1418,9 @@ #include "code\modules\nano\JSON Reader.dm" #include "code\modules\nano\JSON Writer.dm" #include "code\modules\nano\nanoexternal.dm" +#include "code\modules\nano\nanointeraction.dm" #include "code\modules\nano\nanomanager.dm" #include "code\modules\nano\nanomapgen.dm" -#include "code\modules\nano\nanoprocs.dm" #include "code\modules\nano\nanoui.dm" #include "code\modules\nano\modules\crew_monitor.dm" #include "code\modules\organs\blood.dm"