From dca44a60984d84762a8df059239e65b0e60aa934 Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:51:47 -0700 Subject: [PATCH] [MIRROR] moves robot decals and animations to an ui (#11851) Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> --- code/datums/ghost_spawn.dm | 1 + .../mob/living/carbon/human/appearance.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 44 ------- .../living/silicon/robot/robot_ui_decals.dm | 66 ++++++++++ .../living/silicon/robot/robot_ui_module.dm | 1 + code/modules/mob/living/silicon/silicon.dm | 1 + code/modules/mob/living/silicon/subystems.dm | 29 +++++ .../tgui/modules/admin/player_notes.dm | 8 ++ .../tgui/modules/admin_shuttle_controller.dm | 4 + .../tgui/modules/appearance_changer.dm | 21 ++++ code/modules/tgui/modules/law_manager.dm | 4 + code/modules/tgui/modules/overmap.dm | 4 + tgui/packages/tgui/interfaces/RobotDecals.tsx | 117 ++++++++++++++++++ vorestation.dme | 1 + 14 files changed, 258 insertions(+), 45 deletions(-) create mode 100644 code/modules/mob/living/silicon/robot/robot_ui_decals.dm create mode 100644 tgui/packages/tgui/interfaces/RobotDecals.tsx diff --git a/code/datums/ghost_spawn.dm b/code/datums/ghost_spawn.dm index 4cb767c67e..3a5f5e2965 100644 --- a/code/datums/ghost_spawn.dm +++ b/code/datums/ghost_spawn.dm @@ -18,6 +18,7 @@ GLOBAL_VAR_INIT(allowed_ghost_spawns, 2) if(isobserver(user)) var/mob/observer/dead/observer = user observer.selecting_ghostrole = FALSE + qdel(src) /datum/tgui_module/ghost_spawn_menu/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) . = ..() diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 0208345d5d..6921721a36 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -4,7 +4,7 @@ var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/tgui_state/state = GLOB.tgui_self_state) - var/datum/tgui_module/appearance_changer/AC = new(src, src, check_species_whitelist, species_whitelist, species_blacklist) + var/datum/tgui_module/appearance_changer/self_deleting/AC = new(src, src, check_species_whitelist, species_whitelist, species_blacklist) AC.flags = flags AC.tgui_interact(user, custom_state = state) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 51f4c91253..c60477d5c7 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -491,50 +491,6 @@ handle_light() update_icon() -/mob/living/silicon/robot/verb/toggle_robot_decals() // loads overlay UNDER lights. - set category = "Abilities.Settings" - set name = "Toggle Extra Decals" - - if(!sprite_datum) - return - if(!LAZYLEN(sprite_datum.sprite_decals)) - to_chat(src, span_warning("This module does not support decals.")) - return - - var/extra_message = "Enabled decals:\n" - for(var/decal in robotdecal_on) - extra_message += decal + "\n" - - var/decal_to_toggle = tgui_input_list(src, "Please select which decal you want to toggle\n[extra_message]", "Decal Toggle", sprite_datum.sprite_decals) - if(!decal_to_toggle) - return - - decal_to_toggle = lowertext(decal_to_toggle) - - if(robotdecal_on.Find(decal_to_toggle)) - robotdecal_on -= decal_to_toggle - to_chat(src, span_filter_notice("You disable your \"[decal_to_toggle]\" extra apperances.")) - else - robotdecal_on += decal_to_toggle - to_chat(src, span_filter_notice("You enable your \"[decal_to_toggle]\" extra apperances.")) - update_icon() - -/mob/living/silicon/robot/verb/flick_robot_animation() - set category = "Abilities.Settings" - set name = "Flick Animation" - - if(!sprite_datum) - return - if(!LAZYLEN(sprite_datum.sprite_animations)) - to_chat(src, span_warning("This module does not support animations.")) - return - - var/animation_to_play = tgui_input_list(src, "Please select which decal you want to flick", "Flick Decal", sprite_datum.sprite_animations) - if(!animation_to_play) - return - - flick("[sprite_datum.sprite_icon_state]-[animation_to_play]", src) - /mob/living/silicon/robot/verb/toggle_glowy_stomach() set category = "Abilities.Settings" set name = "Toggle Glowing Stomach & Accents" diff --git a/code/modules/mob/living/silicon/robot/robot_ui_decals.dm b/code/modules/mob/living/silicon/robot/robot_ui_decals.dm new file mode 100644 index 0000000000..f10c52e69b --- /dev/null +++ b/code/modules/mob/living/silicon/robot/robot_ui_decals.dm @@ -0,0 +1,66 @@ +// Robot decal and animation control +/datum/tgui_module/robot_ui_decals + name = "Robot Decal & Animation Control" + tgui_id = "RobotDecals" + +/datum/tgui_module/robot_ui_decals/tgui_state(mob/user) + return GLOB.tgui_self_state + +/datum/tgui_module/robot_ui_decals/tgui_static_data() + var/list/data = ..() + + var/mob/living/silicon/robot/R = host + + if(!R.sprite_datum) + return data + + data["all_decals"] = R.sprite_datum.sprite_decals + data["all_animations"] = R.sprite_datum.sprite_animations + + return data + +/datum/tgui_module/robot_ui_decals/tgui_data() + var/list/data = ..() + + var/mob/living/silicon/robot/R = host + data["active_decals"] = R.robotdecal_on + + var/robot_theme = R.get_ui_theme() + if(robot_theme) + data["theme"] = robot_theme + + return data + +/datum/tgui_module/robot_ui_decals/tgui_act(action, params) + . = ..() + if(.) + return + + var/mob/living/silicon/robot/R = host + if(!R.sprite_datum) + return FALSE + + switch(action) + if("toggle_decal") + if(!LAZYLEN(R.sprite_datum.sprite_decals)) + return FALSE + var/decal_to_toggle = lowertext(params["value"]) + if(!(decal_to_toggle in R.sprite_datum.sprite_decals)) + return FALSE + if(R.robotdecal_on.Find(decal_to_toggle)) + R.robotdecal_on -= decal_to_toggle + else + R.robotdecal_on += decal_to_toggle + R.update_icon() + . = TRUE + if("flick_animation") + if(!LAZYLEN(R.sprite_datum.sprite_animations)) + return FALSE + var/animation_to_flick = lowertext(params["value"]) + if(!(animation_to_flick in R.sprite_datum.sprite_animations)) + return FALSE + R.cut_overlays() + R.ImmediateOverlayUpdate() + flick("[R.sprite_datum.sprite_icon_state]-[animation_to_flick]", R) + R.update_icon() + . = TRUE diff --git a/code/modules/mob/living/silicon/robot/robot_ui_module.dm b/code/modules/mob/living/silicon/robot/robot_ui_module.dm index cb3ca77baa..96d84514fe 100644 --- a/code/modules/mob/living/silicon/robot/robot_ui_module.dm +++ b/code/modules/mob/living/silicon/robot/robot_ui_module.dm @@ -14,6 +14,7 @@ if(isrobot(user)) var/mob/living/silicon/robot/R = user R.selecting_module = FALSE + qdel(src) /datum/tgui_module/robot_ui_module/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) . = ..() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index a39063dc1f..28e45ac204 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -52,6 +52,7 @@ QDEL_NULL(idcard) if(laws) QDEL_NULL(laws) + clear_subsystems() return ..() /mob/living/silicon/proc/init_id() diff --git a/code/modules/mob/living/silicon/subystems.dm b/code/modules/mob/living/silicon/subystems.dm index 851159c109..d1d4f6096f 100644 --- a/code/modules/mob/living/silicon/subystems.dm +++ b/code/modules/mob/living/silicon/subystems.dm @@ -46,6 +46,15 @@ AH.register_alarm(src, /mob/living/silicon/proc/receive_alarm) queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order +/mob/living/silicon/proc/clear_subsystems() + QDEL_NULL(alarm_monitor) + QDEL_NULL(atmos_control) + QDEL_NULL(crew_monitor) + QDEL_NULL(crew_manifest) + QDEL_NULL(law_manager) + QDEL_NULL(power_monitor) + QDEL_NULL(rcon) + /******************** * Alarm Monitor * ********************/ @@ -108,3 +117,23 @@ set name = "RCON" rcon.tgui_interact(src) + +/mob/living/silicon/robot + var/datum/tgui_module/robot_ui_decals/decal_control + +/mob/living/silicon/robot/init_subsystems() + ..() + decal_control = new(src) + +/mob/living/silicon/robot/clear_subsystems() + QDEL_NULL(decal_control) + ..() + +/mob/living/silicon/robot/verb/toggle_robot_decals() + set category = "Abilities.Settings" + set name = "Control Robot Decals & Animations" + + if(!sprite_datum) + return + + decal_control.tgui_interact(src) diff --git a/code/modules/tgui/modules/admin/player_notes.dm b/code/modules/tgui/modules/admin/player_notes.dm index de68787c9b..183ce66d4b 100644 --- a/code/modules/tgui/modules/admin/player_notes.dm +++ b/code/modules/tgui/modules/admin/player_notes.dm @@ -11,6 +11,10 @@ var/number_pages = 0 +/datum/tgui_module/player_notes/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/player_notes/proc/filter_ckeys(var/page, var/filter) var/savefile/S=new("data/player_notes.sav") var/list/note_keys @@ -106,6 +110,10 @@ var/key = null +/datum/tgui_module/player_notes_info/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/player_notes_info/tgui_state(mob/user) return ADMIN_STATE(R_ADMIN|R_EVENT|R_DEBUG) diff --git a/code/modules/tgui/modules/admin_shuttle_controller.dm b/code/modules/tgui/modules/admin_shuttle_controller.dm index 4191ffa499..cf25d98647 100644 --- a/code/modules/tgui/modules/admin_shuttle_controller.dm +++ b/code/modules/tgui/modules/admin_shuttle_controller.dm @@ -4,6 +4,10 @@ name = "Admin Shuttle Controller" tgui_id = "AdminShuttleController" +/datum/tgui_module/admin_shuttle_controller/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/admin_shuttle_controller/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) var/list/data = ..() diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index 3995570eff..045c5ef1cf 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -1024,6 +1024,10 @@ return STATUS_CLOSE return ..() +/datum/tgui_module/appearance_changer/vore/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/appearance_changer/vore/update_active_camera_screen() cam_screen.vis_contents = list(owner) cam_background.icon_state = "clear" @@ -1066,6 +1070,10 @@ flags = APPEARANCE_ALL_COSMETIC customize_usr = TRUE +/datum/tgui_module/appearance_changer/cocoon/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/appearance_changer/cocoon/tgui_status(mob/user, datum/tgui_state/state) if(!istype(owner.loc, /obj/item/holder/micro)) return STATUS_CLOSE @@ -1079,6 +1087,10 @@ flags = APPEARANCE_ALL_COSMETIC customize_usr = TRUE +/datum/tgui_module/appearance_changer/superpower/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/appearance_changer/superpower/tgui_status(mob/user, datum/tgui_state/state) var/datum/gene/G = get_gene_from_trait(/datum/trait/positive/superpower_morph) if(!owner.dna.GetSEState(G.block)) @@ -1093,6 +1105,10 @@ flags = APPEARANCE_ALL_COSMETIC customize_usr = TRUE +/datum/tgui_module/appearance_changer/innate/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/appearance_changer/innate/tgui_status(mob/user, datum/tgui_state/state) if(owner.stat != CONSCIOUS) return STATUS_CLOSE @@ -1148,3 +1164,8 @@ // Add listeners back owner.AddComponent(/datum/component/recursive_move) RegisterSignal(owner, COMSIG_OBSERVER_MOVED, PROC_REF(update_active_camera_screen), TRUE) + +/datum/tgui_module/appearance_changer/self_deleting +/datum/tgui_module/appearance_changer/self_deleting/tgui_close(mob/user) + . = ..() + qdel(src) diff --git a/code/modules/tgui/modules/law_manager.dm b/code/modules/tgui/modules/law_manager.dm index 16d13964ac..d0e98d7dd5 100644 --- a/code/modules/tgui/modules/law_manager.dm +++ b/code/modules/tgui/modules/law_manager.dm @@ -217,3 +217,7 @@ /datum/tgui_module/law_manager/admin /datum/tgui_module/law_manager/admin/tgui_state(mob/user) return ADMIN_STATE(R_ADMIN|R_EVENT|R_DEBUG) + +/datum/tgui_module/law_manager/admin/tgui_close(mob/user) + . = ..() + qdel(src) diff --git a/code/modules/tgui/modules/overmap.dm b/code/modules/tgui/modules/overmap.dm index 8bc7b82f06..f9fca8daa0 100644 --- a/code/modules/tgui/modules/overmap.dm +++ b/code/modules/tgui/modules/overmap.dm @@ -166,6 +166,10 @@ /datum/tgui_module/ship/fullmonty/tgui_state(mob/user) return ADMIN_STATE(R_ADMIN|R_EVENT|R_DEBUG) +/datum/tgui_module/ship/fullmonty/tgui_close(mob/user) + . = ..() + qdel(src) + /datum/tgui_module/ship/fullmonty/New(host, obj/effect/overmap/visitable/ship/new_linked) . = ..() if(!istype(new_linked)) diff --git a/tgui/packages/tgui/interfaces/RobotDecals.tsx b/tgui/packages/tgui/interfaces/RobotDecals.tsx new file mode 100644 index 0000000000..3202d34b20 --- /dev/null +++ b/tgui/packages/tgui/interfaces/RobotDecals.tsx @@ -0,0 +1,117 @@ +import { useState } from 'react'; +import { useBackend } from 'tgui/backend'; +import { Window } from 'tgui/layouts'; +import { Box, Button, Input, Section, Stack } from 'tgui-core/components'; +import { createSearch } from 'tgui-core/string'; + +type Data = { + theme?: string; + all_decals?: string[] | null; + all_animations?: string[] | null; + active_decals: string[]; +}; + +export const RobotDecals = () => { + const { act, data } = useBackend(); + const { theme, all_decals, all_animations, active_decals } = data; + + const [decalSearchText, setDecalSearchText] = useState(''); + const [animationSearchText, setAnimationSearchText] = useState(''); + + const decalSearcher = createSearch(decalSearchText, (decal: string) => decal); + const filteredDecals = all_decals?.filter(decalSearcher) ?? []; + + const animationSearcher = createSearch( + animationSearchText, + (anim: string) => anim, + ); + const filteredAnimations = all_animations?.filter(animationSearcher) ?? []; + + return ( + + + + +
+ + + setDecalSearchText(value)} + /> + + + +
+ + {!filteredDecals.length ? ( + No decals found. + ) : ( + filteredDecals.map((decal) => ( + + + act('toggle_decal', { value: decal }) + } + > + {decal} + {active_decals.includes(decal) + ? ` (${active_decals.indexOf(decal) + 1})` + : ''} + + + )) + )} + +
+
+
+
+
+ +
+ + + setAnimationSearchText(value)} + /> + + + +
+ + {!filteredAnimations.length ? ( + No animations found. + ) : ( + filteredAnimations.map((anim) => ( + + + + )) + )} + +
+
+
+
+
+
+
+
+ ); +}; diff --git a/vorestation.dme b/vorestation.dme index dc3f0d3772..c10b0417e1 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -3562,6 +3562,7 @@ #include "code\modules\mob\living\silicon\robot\robot_remote_control.dm" #include "code\modules\mob\living\silicon\robot\robot_simple_items.dm" #include "code\modules\mob\living\silicon\robot\robot_ui.dm" +#include "code\modules\mob\living\silicon\robot\robot_ui_decals.dm" #include "code\modules\mob\living\silicon\robot\robot_ui_module.dm" #include "code\modules\mob\living\silicon\robot\dogborg\dog_defense_modules.dm" #include "code\modules\mob\living\silicon\robot\dogborg\dog_modules.dm"