From eed4d09cba91b135534fba202cee5c1edecec4ad Mon Sep 17 00:00:00 2001 From: Wallem <66052067+Wallemations@users.noreply.github.com> Date: Wed, 26 Nov 2025 15:01:00 -0500 Subject: [PATCH] Abandoned crate UI (#94090) ## About The Pull Request Gives abandoned crates a ui when you use a multitool on them 423112 5656565623623 Each `Button` component has a tooltip explaining how the minigame works & what the column it's in means ## Why It's Good For The Game Now you don't need to scroll through chat to find all your previous attempts ## Changelog :cl: Wallem qol: Replaces abandoned crate multitool interaction with a TGUI window that shows ALL your previous attempts /:cl: --- .../abandoned_crates/abandoned_crates.dm | 37 +++++-- .../tgui/interfaces/AbandonedCrate.tsx | 101 ++++++++++++++++++ 2 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/AbandonedCrate.tsx diff --git a/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm b/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm index 9301a93a3f5..009a8c6a843 100644 --- a/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm +++ b/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm @@ -7,12 +7,14 @@ base_icon_state = "securecrate" integrity_failure = 0 //no breaking open the crate var/code = null - var/last_attempt = null + /// Associated list of previous attempts w/ bulls & cows + var/list/previous_attempts = list() var/attempts = 10 var/code_length = 4 var/qdel_on_open = FALSE var/spawned_loot = FALSE tamperproof = 90 + interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND divable = FALSE // Stop people from "diving into" the crate accidentally, and then detonating it. @@ -127,6 +129,7 @@ spawn_loot() tamperproof = 0 // set explosion chance to zero, so we dont accidently hit it with a multitool and instantly die togglelock(user) + SStgui.close_user_uis(user, src) return if(!validate_input(input)) @@ -134,7 +137,7 @@ return to_chat(user, span_warning("A red light flashes.")) - last_attempt = input + previous_attempts += list(bulls_and_cows(input)) attempts-- if(attempts <= 0) @@ -160,16 +163,28 @@ attack_hand(user) //this helps you not blow up so easily by overriding unlocking which results in an immediate boom. return CLICK_ACTION_SUCCESS +/obj/structure/closet/crate/secure/loot/ui_interact(mob/user, datum/tgui/ui) + . = ..() + + // Attempt to update tgui ui, open and update if needed. + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AbandonedCrate", name) + ui.open() + +/obj/structure/closet/crate/secure/loot/ui_data(mob/user) + var/list/data = list() + + data["previous_attempts"] = previous_attempts + data["attempts_left"] = attempts + + return data + /obj/structure/closet/crate/secure/loot/multitool_act(mob/living/user, obj/item/tool) if(!locked) return - - to_chat(user, span_boldnotice("DECA-CODE LOCK REPORT:")) - to_chat(user, span_warning("* Anti-Tamper Bomb will activate [attempts == 1 ? span_boldwarning("on next failed access attempt") : "after [span_boldwarning("[attempts]")] failed access attempts"].")) - - if(last_attempt) - var/list/bulls_cows = bulls_and_cows(last_attempt) - to_chat(user, span_notice("Last code attempt, [last_attempt], had [bulls_cows[1]] correct digits at correct positions and [bulls_cows[2]] correct digits at incorrect positions.")) + if(Adjacent(user)) + ui_interact(user) return ITEM_INTERACT_SUCCESS @@ -187,7 +202,7 @@ else if(findtext(code, guess_char)) cows++ - return list(bulls, cows) + return list("attempt" = guess, "bulls" = bulls, "cows" = cows) /obj/structure/closet/crate/secure/loot/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() @@ -204,7 +219,7 @@ //reset the anti-tampering, number of attempts and last attempt when the lock is re-enabled. tamperproof = initial(tamperproof) attempts = initial(attempts) - last_attempt = null + previous_attempts = list() return if(tamperproof) return diff --git a/tgui/packages/tgui/interfaces/AbandonedCrate.tsx b/tgui/packages/tgui/interfaces/AbandonedCrate.tsx new file mode 100644 index 00000000000..3498eb5cfd1 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AbandonedCrate.tsx @@ -0,0 +1,101 @@ +import { Box, Button, NoticeBox, Section, Table } from 'tgui-core/components'; + +import { useBackend } from '../backend'; +import { Window } from '../layouts'; + +type Data = { + previous_attempts: Attempts[]; + attempts_left: number; +}; + +type Attempts = { + attempt: string; + bulls: number; + cows: number; +}; + +const check_attempts = (attempts_to_check: number) => { + return attempts_to_check === 1 + ? 'on next failed access attempt.' + : `after ${attempts_to_check} failed access attempts.`; +}; + +const BULLS_COWS_INFO = `Codes are made of a series of non-repeating digits. +Each wrong guess will return the number of correct digits in correct locations, +and the number of correct digits in incorrect locations.`; + +export const AbandonedCrate = (props) => { + const { data } = useBackend(); + const { previous_attempts, attempts_left } = data; + + return ( + + +
+ } + > + + Anti-Tamper Bomb will activate {check_attempts(attempts_left)} + + + {!!previous_attempts.length && ( + + + Attempt + + +
+
+
+
+ ); +};