From e37c5c22d456e7512cc09063ffdaf520807a41f2 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Fri, 10 Apr 2015 11:03:00 +0200 Subject: [PATCH] Refactors NanoUI interaction (again) Takes NanoUI interaction code and splits it into more manageable modules. The default handler that checks distances, camera coverage, etc., etc. Admin NanoUI windows now only check for admin rights, ignoring sight, distance, and anything else. ERT/mercenary appearance changer now remains open for as long as the mob remains on the admin Z-level. PDAs and uplinks now require that you keep the item somewhere in your main inventory (or contents to be precise). Hands or ears are fine, inside bags are not. Rig suits also check that they are in the operator's inventory or that the synthetic operator is somewhere within the suit's contents (recursively). --- baystation12.dme | 7 +- code/game/antagonist/antagonist_build.dm | 2 +- code/game/machinery/alarm.dm | 26 ++++---- code/game/machinery/computer/atmos_alert.dm | 11 ++-- code/game/machinery/computer/atmos_control.dm | 3 +- code/game/machinery/doors/airlock.dm | 2 +- code/game/machinery/machinery.dm | 2 +- code/game/objects/items/devices/PDA/PDA.dm | 2 +- code/game/objects/items/devices/uplinks.dm | 5 +- code/game/objects/objs.dm | 5 +- code/modules/admin/admin_verbs.dm | 5 +- code/modules/clothing/spacesuits/rig/rig.dm | 2 +- .../mob/living/carbon/human/appearance.dm | 4 +- code/modules/nano/interaction/admin.dm | 7 ++ code/modules/nano/interaction/base.dm | 19 ++++++ code/modules/nano/interaction/contained.dm | 18 ++++++ .../default.dm} | 64 ++++++------------- code/modules/nano/interaction/inventory.dm | 10 +++ code/modules/nano/interaction/zlevel.dm | 13 ++++ code/modules/nano/modules/human_appearance.dm | 16 ++--- code/modules/nano/modules/law_manager.dm | 4 +- code/modules/nano/modules/nano_module.dm | 7 +- code/modules/nano/nanoexternal.dm | 2 +- code/modules/nano/nanoui.dm | 13 ++-- code/setup.dm | 2 - 25 files changed, 146 insertions(+), 105 deletions(-) create mode 100644 code/modules/nano/interaction/admin.dm create mode 100644 code/modules/nano/interaction/base.dm create mode 100644 code/modules/nano/interaction/contained.dm rename code/modules/nano/{nanointeraction.dm => interaction/default.dm} (63%) create mode 100644 code/modules/nano/interaction/inventory.dm create mode 100644 code/modules/nano/interaction/zlevel.dm diff --git a/baystation12.dme b/baystation12.dme index 915c098b3e3..c394229a031 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1267,10 +1267,15 @@ #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\nanoui.dm" +#include "code\modules\nano\interaction\admin.dm" +#include "code\modules\nano\interaction\base.dm" +#include "code\modules\nano\interaction\contained.dm" +#include "code\modules\nano\interaction\default.dm" +#include "code\modules\nano\interaction\inventory.dm" +#include "code\modules\nano\interaction\zlevel.dm" #include "code\modules\nano\modules\alarm_monitor.dm" #include "code\modules\nano\modules\crew_monitor.dm" #include "code\modules\nano\modules\human_appearance.dm" diff --git a/code/game/antagonist/antagonist_build.dm b/code/game/antagonist/antagonist_build.dm index 34631d36fba..40ba798aae9 100644 --- a/code/game/antagonist/antagonist_build.dm +++ b/code/game/antagonist/antagonist_build.dm @@ -34,7 +34,7 @@ return 1 if(flags & ANTAG_SET_APPEARANCE) - player.change_appearance(APPEARANCE_ALL, player, player, valid_species) + player.change_appearance(APPEARANCE_ALL, player.loc, player, valid_species, state = z_state) /datum/antagonist/proc/unequip(var/mob/living/carbon/human/player) if(!istype(player)) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 9e3e56f5582..f6d2820d5bb 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -469,14 +469,14 @@ ui_interact(user) wires.Interact(user) -/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/custom_state = null) +/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) var/data[0] var/remote_connection = 0 var/remote_access = 0 - if(custom_state) - var/list/state = custom_state.href_list(user) - remote_connection = state["remote_connection"] // Remote connection means we're non-adjacent/connecting from another computer - remote_access = state["remote_access"] // Remote access means we also have the privilege to alter the air alarm. + if(state) + var/list/href = state.href_list(user) + remote_connection = href["remote_connection"] // Remote connection means we're non-adjacent/connecting from another computer + remote_access = href["remote_access"] // Remote access means we also have the privilege to alter the air alarm. data["locked"] = locked && !user.isSilicon() data["remote_connection"] = remote_connection @@ -491,7 +491,7 @@ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) - ui = new(user, src, ui_key, "air_alarm.tmpl", src.name, 325, 625, master_ui = master_ui, custom_state = custom_state) + ui = new(user, src, ui_key, "air_alarm.tmpl", src.name, 325, 625, master_ui = master_ui, state = state) ui.set_initial_data(data) ui.open() ui.set_auto_update(1) @@ -616,7 +616,7 @@ data["thresholds"] = thresholds -/obj/machinery/alarm/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state) +/obj/machinery/alarm/CanUseTopic(var/mob/user, var/datum/topic_state/state, var/href_list = list()) if(buildstage != 2) return STATUS_CLOSE @@ -627,17 +627,15 @@ . = shorted ? STATUS_DISABLED : STATUS_INTERACTIVE if(. == STATUS_INTERACTIVE) - var/extra_href = custom_state.href_list(usr) - // Prevent remote users from altering RCON settings unless they already have access (I realize the risks) + var/extra_href = state.href_list(usr) + // Prevent remote users from altering RCON settings unless they already have access if(href_list["rcon"] && extra_href["remote_connection"] && !extra_href["remote_access"]) . = STATUS_UPDATE - //TODO: Move the rest of if(!locked || extra_href["remote_access"] || usr.isAI()) and hrefs here - return min(..(), .) -/obj/machinery/alarm/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/custom_state) - if(..(href, href_list, nowindow, custom_state)) +/obj/machinery/alarm/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state) + if(..(href, href_list, nowindow, state)) return 1 // hrefs that can always be called -walter0o @@ -666,7 +664,7 @@ return 1 // hrefs that need the AA unlocked -walter0o - var/extra_href = custom_state.href_list(usr) + var/extra_href = state.href_list(usr) if(!(locked && !extra_href["remote_connection"]) || extra_href["remote_access"] || usr.isSilicon()) if(href_list["command"]) var/device_id = href_list["id_tag"] diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 8306b3a87e0..77f76476085 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -13,7 +13,7 @@ var/global/list/minor_air_alarms = list() /obj/machinery/computer/atmos_alert/New() ..() atmosphere_alarm.register(src, /obj/machinery/computer/station_alert/update_icon) - + /obj/machinery/computer/atmos_alert/Del() atmosphere_alarm.unregister(src) ..() @@ -68,16 +68,13 @@ var/global/list/minor_air_alarms = list() var/obj/machinery/alarm/air_alarm = alarm_source.source if(istype(air_alarm)) var/list/new_ref = list("atmos_reset" = 1) - air_alarm.Topic(href, new_ref, custom_state = atmos_alert_topic) + air_alarm.Topic(href, new_ref, state = air_alarm_topic) return 1 -var/datum/topic_state/atmos_alert/atmos_alert_topic = new() +var/datum/topic_state/air_alarm_topic/air_alarm_topic = new() -/datum/topic_state/atmos_alert - flags = NANO_IGNORE_DISTANCE - -/datum/topic_state/air_alarm/href_list(var/mob/user) +/datum/topic_state/air_alarm_topic/href_list(var/mob/user) var/list/extra_href = list() extra_href["remote_connection"] = 1 extra_href["remote_access"] = 1 diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index d63259bc4c5..2e79d927be5 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -76,7 +76,7 @@ var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms ? monitored_alarms : machines) if(alarm) var/datum/topic_state/TS = generate_state(alarm) - alarm.ui_interact(usr, master_ui = ui_ref, custom_state = TS) + alarm.ui_interact(usr, master_ui = ui_ref, state = TS) return 1 /obj/machinery/computer/atmoscontrol/proc/generate_state(var/alarm) @@ -86,7 +86,6 @@ return state /datum/topic_state/air_alarm - flags = NANO_IGNORE_DISTANCE var/obj/machinery/computer/atmoscontrol/atmos_control = null var/obj/machinery/alarm/air_alarm = null diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 40c137e77b3..c275d8f7287 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -610,7 +610,7 @@ About the new airlock wires panel: ..(user) return -/obj/machinery/door/airlock/CanUseTopic(var/mob/user, href_list) +/obj/machinery/door/airlock/CanUseTopic(var/mob/user) if(!user.isSilicon()) return STATUS_CLOSE diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index c573229a109..d601146c186 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -185,7 +185,7 @@ Class Procs: /obj/machinery/proc/inoperable(var/additional_flags = 0) return (stat & (NOPOWER|BROKEN|additional_flags)) -/obj/machinery/CanUseTopic(var/mob/user, var/be_close) +/obj/machinery/CanUseTopic(var/mob/user) if(!interact_offline && (stat & (NOPOWER|BROKEN))) return STATUS_CLOSE diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 87f7b0fd8a6..fe9305646a3 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -542,7 +542,7 @@ var/global/list/obj/item/device/pda/PDAs = list() 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, "pda.tmpl", title, 520, 400) + ui = new(user, src, ui_key, "pda.tmpl", title, 520, 400, state = inventory_state) // when the ui is first opened this is the data it will use ui.load_cached_data(ManifestJSON) diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index b2ac742a7c8..57b569c599a 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -53,6 +53,9 @@ datum/nano_item_lists var/uplink_owner = null//text-only var/used_TC = 0 +/obj/item/device/uplink/nano_host() + return loc + /obj/item/device/uplink/New() ..() welcome = ticker.mode.uplink_welcome @@ -219,7 +222,7 @@ datum/nano_item_lists 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, "uplink.tmpl", title, 450, 600) + ui = new(user, src, ui_key, "uplink.tmpl", title, 450, 600, state = inventory_state) // 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/code/game/objects/objs.dm b/code/game/objects/objs.dm index 51cb54ea2dc..39b767263fc 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -16,15 +16,14 @@ var/damtype = "brute" var/force = 0 -/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/custom_state = default_state) +/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state = default_state) // Calling Topic without a corresponding window open causes runtime errors if(!nowindow && ..()) return 1 // 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) + if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE) CouldUseTopic(usr) return 0 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 59e40e2a444..5a006c27184 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -724,7 +724,8 @@ var/list/admin_verbs_mentor = list( return if(holder) - S.subsystem_law_manager() + var/obj/nano_module/law_manager/L = new(S) + L.ui_interact(usr, state = admin_state) admin_log_and_message_admins("has opened [S]'s law manager.") feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -738,7 +739,7 @@ var/list/admin_verbs_mentor = list( if(holder) admin_log_and_message_admins("is altering the appearance of [H].") - H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0) + H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0, state = admin_state) feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/change_human_appearance_self(mob/living/carbon/human/H in mob_list) diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 4c8da1665a6..529d9aee82a 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -459,7 +459,7 @@ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) - ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550) + ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, data["ai"] ? contained_state : inventory_state) ui.set_initial_data(data) ui.open() ui.set_auto_update(1) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index e2ef586f05c..52ba116d43b 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -1,7 +1,7 @@ -/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list()) +/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = default_state) var/obj/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) AC.flags = flags - AC.ui_interact(user) + AC.ui_interact(user, state = state) /mob/living/carbon/human/proc/change_species(var/new_species) if(!new_species) diff --git a/code/modules/nano/interaction/admin.dm b/code/modules/nano/interaction/admin.dm new file mode 100644 index 00000000000..59de0ce22eb --- /dev/null +++ b/code/modules/nano/interaction/admin.dm @@ -0,0 +1,7 @@ +/* + This state checks that the user is an admin, end of story +*/ +/var/global/datum/topic_state/admin_state/admin_state = new() + +/datum/topic_state/admin_state/can_use_topic(var/src_object, var/mob/user) + return check_rights(R_ADMIN, 0, user) ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm new file mode 100644 index 00000000000..46b11278d64 --- /dev/null +++ b/code/modules/nano/interaction/base.dm @@ -0,0 +1,19 @@ +/atom/proc/nano_host() + return src + +/atom/proc/CanUseTopic(var/mob/user, var/datum/topic_state/state) + var/src_object = nano_host() + return state.can_use_topic(src_object, user) + +/datum/topic_state/proc/href_list(var/mob/user) + return list() + +/datum/topic_state/proc/can_use_topic(var/src_object, var/mob/user) + return STATUS_INTERACTIVE + +/mob/proc/shared_nano_interaction() + if (src.stat || !client) + 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 diff --git a/code/modules/nano/interaction/contained.dm b/code/modules/nano/interaction/contained.dm new file mode 100644 index 00000000000..c9ecba15be2 --- /dev/null +++ b/code/modules/nano/interaction/contained.dm @@ -0,0 +1,18 @@ +/* + This state checks if user is somewhere within src_object, as well as the default NanoUI interaction. +*/ +/var/global/datum/topic_state/contained_state/contained_state = new() + +/datum/topic_state/contained_state/can_use_topic(var/atom/src_object, var/mob/user) + if(!src_object.contains(src)) + return STATUS_CLOSE + + return user.shared_nano_interaction() + +/atom/proc/contains(var/atom/location) + if(!location) + return 0 + if(location == src) + return 1 + + return contains(location.loc) diff --git a/code/modules/nano/nanointeraction.dm b/code/modules/nano/interaction/default.dm similarity index 63% rename from code/modules/nano/nanointeraction.dm rename to code/modules/nano/interaction/default.dm index d929cfe2b58..7135d876bcf 100644 --- a/code/modules/nano/nanointeraction.dm +++ b/code/modules/nano/interaction/default.dm @@ -1,41 +1,36 @@ -/atom/proc/nano_host() - return src +/var/global/datum/topic_state/default_state = new() -/obj/nano_module/nano_host() - return loc +/datum/topic_state/default/href_list(var/mob/user) + return list() +/datum/topic_state/default/can_use_topic(var/src_object, var/mob/user) + return user.default_can_use_topic(src_object) -/atom/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) +/mob/proc/default_can_use_topic(var/src_object) return STATUS_CLOSE // By default no mob can do anything with NanoUI -/mob/dead/observer/can_use_topic() +/mob/dead/observer/default_can_use_topic() if(check_rights(R_ADMIN, 0, src)) return STATUS_INTERACTIVE // Admins are more equal return STATUS_UPDATE // Ghosts can view updates -/mob/living/silicon/pai/can_use_topic(var/src_object) +/mob/living/silicon/pai/default_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) +/mob/living/silicon/robot/default_can_use_topic(var/src_object) if(stat || !client) return STATUS_CLOSE if(lockcharge || stunned || weakened) return STATUS_DISABLED - if(custom_state.flags & NANO_IGNORE_DISTANCE) - return STATUS_INTERACTIVE // robots can interact with things they can see within their view range if((src_object in view(src)) && get_dist(src_object, src) <= src.client.view) 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) +/mob/living/silicon/robot/syndicate/default_can_use_topic(var/src_object) . = ..() if(. != STATUS_INTERACTIVE) return @@ -50,7 +45,7 @@ return STATUS_INTERACTIVE return STATUS_UPDATE -/mob/living/silicon/ai/can_use_topic(var/src_object) +/mob/living/silicon/ai/default_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) @@ -71,26 +66,13 @@ 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 + return STATUS_CLOSE //Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI. /atom/proc/contents_nano_distance(var/src_object, var/mob/living/user) return user.shared_living_nano_distance(src_object) /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 @@ -103,27 +85,17 @@ 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)) +/mob/living/default_can_use_topic(var/src_object) + . = shared_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE) if(loc) . = loc.contents_nano_distance(src_object, src) - else - . = 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)) +/mob/living/carbon/human/default_can_use_topic(var/src_object) + . = shared_nano_interaction(src_object) + if(. == STATUS_INTERACTIVE) . = 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/interaction/inventory.dm b/code/modules/nano/interaction/inventory.dm new file mode 100644 index 00000000000..9bbd7c7ecb5 --- /dev/null +++ b/code/modules/nano/interaction/inventory.dm @@ -0,0 +1,10 @@ +/* + This state checks that the src_object is somewhere in the user's first-level inventory (in hands, on ear, etc.), but not further down (such as in bags). +*/ +/var/global/datum/topic_state/inventory_state/inventory_state = new() + +/datum/topic_state/inventory_state/can_use_topic(var/src_object, var/mob/user) + if(!(src_object in src)) + return STATUS_CLOSE + + return user.shared_nano_interaction() diff --git a/code/modules/nano/interaction/zlevel.dm b/code/modules/nano/interaction/zlevel.dm new file mode 100644 index 00000000000..80d4c2e601c --- /dev/null +++ b/code/modules/nano/interaction/zlevel.dm @@ -0,0 +1,13 @@ +/* + This state checks that the user is on the same Z-level as src_object +*/ + +/var/global/datum/topic_state/z_state/z_state = new() + +/datum/topic_state/z_state/can_use_topic(var/src_object, var/mob/user) + var/turf/turf_obj = get_turf(src_object) + var/turf/turf_usr = get_turf(user) + if(!turf_obj || !turf_usr) + return STATUS_CLOSE + + return turf_obj.z == turf_usr.z ? STATUS_INTERACTIVE : STATUS_CLOSE diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index be2259d618f..47324c47b07 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -18,7 +18,7 @@ src.whitelist = species_whitelist src.blacklist = species_blacklist -/obj/nano_module/appearance_changer/Topic(ref, href_list) +/obj/nano_module/appearance_changer/Topic(ref, href_list, var/nowindow, var/datum/topic_state/state = default_state) if(..()) return 1 @@ -35,13 +35,13 @@ if(href_list["skin_tone"]) if(can_change_skin_tone()) var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null - if(isnum(new_s_tone) && CanUseTopic(usr) == STATUS_INTERACTIVE) + if(isnum(new_s_tone) && can_still_topic(state)) new_s_tone = 35 - max(min( round(new_s_tone), 220),1) return owner.change_skin_tone(new_s_tone) if(href_list["skin_color"]) if(can_change_skin_color()) var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(owner.r_skin, owner.g_skin, owner.b_skin)) as color|null - if(new_skin && can_still_topic()) + if(new_skin && can_still_topic(state)) var/r_skin = hex2num(copytext(new_skin, 2, 4)) var/g_skin = hex2num(copytext(new_skin, 4, 6)) var/b_skin = hex2num(copytext(new_skin, 6, 8)) @@ -56,7 +56,7 @@ if(href_list["hair_color"]) if(can_change(APPEARANCE_HAIR_COLOR)) var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null - if(new_hair && can_still_topic()) + if(new_hair && can_still_topic(state)) var/r_hair = hex2num(copytext(new_hair, 2, 4)) var/g_hair = hex2num(copytext(new_hair, 4, 6)) var/b_hair = hex2num(copytext(new_hair, 6, 8)) @@ -71,7 +71,7 @@ if(href_list["facial_hair_color"]) if(can_change(APPEARANCE_FACIAL_HAIR_COLOR)) var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null - if(new_facial && can_still_topic()) + if(new_facial && can_still_topic(state)) var/r_facial = hex2num(copytext(new_facial, 2, 4)) var/g_facial = hex2num(copytext(new_facial, 4, 6)) var/b_facial = hex2num(copytext(new_facial, 6, 8)) @@ -81,7 +81,7 @@ if(href_list["eye_color"]) if(can_change(APPEARANCE_EYE_COLOR)) var/new_eyes = input("Please select eye color.", "Eye Color", rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) as color|null - if(new_eyes && can_still_topic()) + if(new_eyes && can_still_topic(state)) var/r_eyes = hex2num(copytext(new_eyes, 2, 4)) var/g_eyes = hex2num(copytext(new_eyes, 4, 6)) var/b_eyes = hex2num(copytext(new_eyes, 6, 8)) @@ -91,7 +91,7 @@ return 0 -/obj/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) generate_data(check_whitelist, whitelist, blacklist) var/data[0] @@ -128,7 +128,7 @@ data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) - ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src.name]", 800, 450) + ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src.name]", 800, 450, state = state) ui.set_initial_data(data) ui.open() ui.set_auto_update(1) diff --git a/code/modules/nano/modules/law_manager.dm b/code/modules/nano/modules/law_manager.dm index 4f81585a04a..7cdd93b4dcf 100644 --- a/code/modules/nano/modules/law_manager.dm +++ b/code/modules/nano/modules/law_manager.dm @@ -152,7 +152,7 @@ return 0 -/obj/nano_module/law_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/nano_module/law_manager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) var/data[0] owner.lawsync() @@ -189,7 +189,7 @@ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) - ui = new(user, src, ui_key, "law_manager.tmpl", sanitize("[src] - [owner]"), 800, is_malf(user) ? 600 : 400) + ui = new(user, src, ui_key, "law_manager.tmpl", sanitize("[src] - [owner]"), 800, is_malf(user) ? 600 : 400, state = state) ui.set_initial_data(data) ui.open() ui.set_auto_update(1) diff --git a/code/modules/nano/modules/nano_module.dm b/code/modules/nano/modules/nano_module.dm index 3787639c9d0..3fa82750992 100644 --- a/code/modules/nano/modules/nano_module.dm +++ b/code/modules/nano/modules/nano_module.dm @@ -1,2 +1,5 @@ -/obj/nano_module/proc/can_still_topic() - return CanUseTopic(usr, list(), default_state) == STATUS_INTERACTIVE +/obj/nano_module/nano_host() + return loc + +/obj/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state) + return CanUseTopic(usr, state) == STATUS_INTERACTIVE diff --git a/code/modules/nano/nanoexternal.dm b/code/modules/nano/nanoexternal.dm index b029019f1a3..bb283accf52 100644 --- a/code/modules/nano/nanoexternal.dm +++ b/code/modules/nano/nanoexternal.dm @@ -37,7 +37,7 @@ * * @return nothing */ -/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) +/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/state = default_state) return // Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 2c86343515b..ffc6208f39e 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -55,7 +55,7 @@ nanoui is used to open and update nano browser uis // 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/datum/topic_state/state = null var/cached_data = null @@ -73,7 +73,7 @@ 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, var/datum/nanoui/master_ui = null, var/datum/topic_state/custom_state = default_state) +/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/state = default_state) user = nuser src_object = nsrc_object ui_key = nui_key @@ -82,7 +82,7 @@ nanoui is used to open and update nano browser uis src.master_ui = master_ui if(master_ui) master_ui.children += src - src.custom_state = custom_state + src.state = state // add the passed template filename as the "main" template, this is required add_template("main", ntemplate_filename) @@ -142,8 +142,7 @@ nanoui is used to open and update nano browser uis * @return nothing */ /datum/nanoui/proc/update_status(var/push_update = 0) - var/atom/movable/host = src_object.nano_host() - var/new_status = host.CanUseTopic(user, list(), custom_state) + var/new_status = src_object.CanUseTopic(user, state) if(master_ui) new_status = min(new_status, master_ui.status) @@ -483,7 +482,7 @@ nanoui is used to open and update nano browser uis set_map_z_level(text2num(href_list["mapZLevel"])) map_update = 1 - if ((src_object && src_object.Topic(href, href_list, 0, custom_state)) || map_update) + if ((src_object && src_object.Topic(href, href_list, 0, state)) || map_update) nanomanager.update_uis(src_object) // update all UIs attached to src_object /** @@ -510,4 +509,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, master_ui, custom_state) + src_object.ui_interact(user, ui_key, src, force_open, master_ui, state) diff --git a/code/setup.dm b/code/setup.dm index 127c33f89f8..514cf1e5eed 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -779,8 +779,6 @@ var/list/be_special_flags = list( //General-purpose life speed define for plants. #define HYDRO_SPEED_MULTIPLIER 1 -#define NANO_IGNORE_DISTANCE 1 - // Robot AI notifications #define ROBOT_NOTIFICATION_NEW_UNIT 1 #define ROBOT_NOTIFICATION_NEW_NAME 2