From 9db4ba1da0eaa34e833078c6ff7d81f5ca1bb7b4 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Thu, 3 Dec 2015 09:27:28 +0100 Subject: [PATCH] Adds a remote interaction state for NanoUI. This state has two checks: A preliminary check of the remote target, ensuring it's powered, etc. If the remote target is fully disabled, it closes the window and conducts no further checks. It then makes a full check, ensuring that the mob is capable, within range of the source remoting to the remote target, etc. Unlike most other static interaction states, whoever initializes the remote state is responsible for deleting it properly. Conflicts: polaris.dme --- code/game/machinery/computer/crew.dm | 7 +++- code/modules/nano/interaction/base.dm | 3 ++ code/modules/nano/interaction/interactive.dm | 7 ++++ code/modules/nano/interaction/remote.dm | 39 ++++++++++++++++++++ code/modules/nano/nanoui.dm | 3 ++ polaris.dme | 2 + 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 code/modules/nano/interaction/interactive.dm create mode 100644 code/modules/nano/interaction/remote.dm diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 0c6c33928a..d780d47406 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -28,8 +28,11 @@ return ui_interact(user) -/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - crew_monitor.ui_interact(user, ui_key, ui, force_open) +/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + crew_monitor.ui_interact(user, ui_key, ui, force_open, state) + +/obj/machinery/computer/crew/nano_container() + return crew_monitor /obj/machinery/computer/crew/interact(mob/user) crew_monitor.ui_interact(user) diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm index ccd9f3740b..82fd32ea3c 100644 --- a/code/modules/nano/interaction/base.dm +++ b/code/modules/nano/interaction/base.dm @@ -1,6 +1,9 @@ /datum/proc/nano_host() return src +/datum/proc/nano_container() + return src + /datum/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state) var/src_object = nano_host() return state.can_use_topic(src_object, user) diff --git a/code/modules/nano/interaction/interactive.dm b/code/modules/nano/interaction/interactive.dm new file mode 100644 index 0000000000..ddd8f8f9e1 --- /dev/null +++ b/code/modules/nano/interaction/interactive.dm @@ -0,0 +1,7 @@ +/* + This state always returns STATUS_INTERACTIVE +*/ +/var/global/datum/topic_state/interactive/interactive_state = new() + +/datum/topic_state/interactive/can_use_topic(var/src_object, var/mob/user) + return STATUS_INTERACTIVE diff --git a/code/modules/nano/interaction/remote.dm b/code/modules/nano/interaction/remote.dm new file mode 100644 index 0000000000..ef2cb6926d --- /dev/null +++ b/code/modules/nano/interaction/remote.dm @@ -0,0 +1,39 @@ +/* + This state checks that user is capable, within range of the remoter, etc. and that src_object meets the basic requirements for interaction (being powered, non-broken, etc. + Whoever initializes this state is also responsible for deleting it properly. +*/ +/datum/topic_state/remote + var/datum/remoter + var/datum/remote_target + var/datum/topic_state/remoter_state + +/datum/topic_state/remote/New(var/remoter, var/remote_target, var/datum/topic_state/remoter_state = default_state) + src.remoter = remoter + src.remote_target = remote_target + src.remoter_state = remoter_state + ..() + +/datum/topic_state/remote/Destroy() + src.remoter = null + src.remoter_state = null + + // Force an UI update before we go, ensuring that any windows we may have opened for the remote target closes. + nanomanager.update_uis(remote_target.nano_container()) + remote_target = null + return ..() + +/datum/topic_state/remote/can_use_topic(var/datum/src_object, var/mob/user) + if(!(remoter && remoter_state)) // The remoter is gone, let us leave + return STATUS_CLOSE + + if(src_object != remote_target) + error("remote - Unexpected src_object: Expected '[remote_target]'/[remote_target.type], was '[src_object]'/[src_object.type]") + + // This checks if src_object is powered, etc. + // The interactive state is otherwise simplistic and only returns STATUS_INTERACTIVE and never checks distances, etc. + . = src_object.CanUseTopic(user, interactive_state) + if(. == STATUS_CLOSE) + return + + // This is the (generally) heavy checking, making sure the user is capable, within range of the remoter source, etc. + return min(., remoter.CanUseTopic(user, remoter_state)) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index e90a562fef..5fd221b2a8 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -428,6 +428,9 @@ nanoui is used to open and update nano browser uis user << browse(null, "window=[window_id]") for(var/datum/nanoui/child in children) child.close() + children.Cut() + state = null + master_ui = null /** * Set the UI window to call the nanoclose verb when the window is closed diff --git a/polaris.dme b/polaris.dme index 7a7d42d13d..16f869bee9 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1499,10 +1499,12 @@ #include "code\modules\nano\interaction\conscious.dm" #include "code\modules\nano\interaction\contained.dm" #include "code\modules\nano\interaction\default.dm" +#include "code\modules\nano\interaction\interactive.dm" #include "code\modules\nano\interaction\inventory.dm" #include "code\modules\nano\interaction\inventory_deep.dm" #include "code\modules\nano\interaction\outside.dm" #include "code\modules\nano\interaction\physical.dm" +#include "code\modules\nano\interaction\remote.dm" #include "code\modules\nano\interaction\self.dm" #include "code\modules\nano\interaction\zlevel.dm" #include "code\modules\nano\modules\alarm_monitor.dm"