From df8946306efd5a3deacdd43b9f779ca08fd74292 Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Tue, 6 Jan 2026 14:36:51 -0800 Subject: [PATCH] Fixes missing icons in tgui [no gbp] (#94748) ## About The Pull Request Should* fix it. tgui was set up to not block while waiting on the icon ref map via #90270 (a perf win bc it's huge). However, if the icon ref map's filename hadn't been sent yet, it would error and eventually quit. This simplifies it by directly assigning the icons once we get the asset rather than playing catch. unrelated but removed vector.ts which was already in tgui-core ## Why It's Good For The Game Fixes #94644 ## Changelog :cl: fix: Fixed an issue in TGUI that caused icons to not load sometimes /:cl: --- tgui/global.d.ts | 2 +- tgui/packages/common/vector.ts | 55 -------------------- tgui/packages/tgui-panel/panelFocus.ts | 2 +- tgui/packages/tgui/App.tsx | 2 - tgui/packages/tgui/Icons.tsx | 33 ------------ tgui/packages/tgui/drag.ts | 2 +- tgui/packages/tgui/events/handlers/assets.ts | 20 ++++++- tgui/packages/tgui/interfaces/Gps.jsx | 2 +- 8 files changed, 23 insertions(+), 95 deletions(-) delete mode 100644 tgui/packages/common/vector.ts delete mode 100644 tgui/packages/tgui/Icons.tsx diff --git a/tgui/global.d.ts b/tgui/global.d.ts index 73080063878..ef127804749 100644 --- a/tgui/global.d.ts +++ b/tgui/global.d.ts @@ -177,7 +177,7 @@ type ByondType = { /** * Maps icons to their ref */ - iconRefMap: Record; + iconRefMap: Record; /** * Downloads a blob, platform-agnostic diff --git a/tgui/packages/common/vector.ts b/tgui/packages/common/vector.ts deleted file mode 100644 index 78d22c35d11..00000000000 --- a/tgui/packages/common/vector.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * N-dimensional vector manipulation functions. - * - * Vectors are plain number arrays, i.e. [x, y, z]. - * - * @file - * @copyright 2020 Aleksej Komarov - * @license MIT - */ - -import { zip } from 'es-toolkit'; -import { map, reduce } from 'es-toolkit/compat'; - -const ADD = (a: number, b: number): number => a + b; -const SUB = (a: number, b: number): number => a - b; -const MUL = (a: number, b: number): number => a * b; -const DIV = (a: number, b: number): number => a / b; - -export type Vector = number[]; - -// It's really not ideal to bypass the type system and use `as Vector` -// however, there isn't a more eloquent way to type these - -export const vecAdd = (...vecs: Vector[]): Vector => { - return map(zip(...vecs) as Vector[], (x) => reduce(x, ADD)) as Vector; -}; - -export const vecSubtract = (...vecs: Vector[]): Vector => { - return map(zip(...vecs) as Vector[], (x) => reduce(x, SUB)) as Vector; -}; - -export const vecMultiply = (...vecs: Vector[]): Vector => { - return map(zip(...vecs) as Vector[], (x) => reduce(x, MUL)) as Vector; -}; - -export const vecDivide = (...vecs: Vector[]): Vector => { - return map(zip(...vecs) as Vector[], (x) => reduce(x, DIV)) as Vector; -}; - -export const vecScale = (vec: Vector, n: number): Vector => { - return map(vec, (x) => x * n); -}; - -export const vecInverse = (vec: Vector): Vector => { - return map(vec, (x) => -x); -}; - -export const vecLength = (vec: Vector): number => { - return Math.sqrt(reduce(vecMultiply(vec, vec), ADD) as number); -}; - -export const vecNormalize = (vec: Vector): Vector => { - const length = vecLength(vec); - return map(vec, (c) => c / length); -}; diff --git a/tgui/packages/tgui-panel/panelFocus.ts b/tgui/packages/tgui-panel/panelFocus.ts index 9706b4fc8fe..cf232a17df3 100644 --- a/tgui/packages/tgui-panel/panelFocus.ts +++ b/tgui/packages/tgui-panel/panelFocus.ts @@ -7,7 +7,7 @@ * @license MIT */ -import { vecLength, vecSubtract } from 'common/vector'; +import { vecLength, vecSubtract } from 'tgui-core/vector'; import { focusMap } from 'tgui/focus'; import { canStealFocus, globalEvents } from 'tgui-core/events'; diff --git a/tgui/packages/tgui/App.tsx b/tgui/packages/tgui/App.tsx index 4fb650ae016..bb128901bf1 100644 --- a/tgui/packages/tgui/App.tsx +++ b/tgui/packages/tgui/App.tsx @@ -1,13 +1,11 @@ import { Provider } from 'jotai'; import { store } from './events/store'; -import { IconProvider } from './Icons'; import { RoutedComponent } from './routes'; export function App() { return ( - ); } diff --git a/tgui/packages/tgui/Icons.tsx b/tgui/packages/tgui/Icons.tsx deleted file mode 100644 index 3023399dcd5..00000000000 --- a/tgui/packages/tgui/Icons.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Suspense, useEffect } from 'react'; -import { fetchRetry } from 'tgui-core/http'; -import { resolveAsset } from './assets'; -import { logger } from './logging'; - -function setIconRefMap(map: Record): void { - Byond.iconRefMap = map; -} - -function loadIconMap(): void { - fetchRetry(resolveAsset('icon_ref_map.json')) - .then((res) => res.json()) - .then(setIconRefMap) - .catch((error) => logger.log(error)); -} - -function IconMapLoader(): null { - useEffect(() => { - if (Object.keys(Byond.iconRefMap).length === 0) { - loadIconMap(); - } - }, []); - - return null; -} - -export function IconProvider() { - return ( - - - - ); -} diff --git a/tgui/packages/tgui/drag.ts b/tgui/packages/tgui/drag.ts index 0d832217be1..aeb991bac36 100644 --- a/tgui/packages/tgui/drag.ts +++ b/tgui/packages/tgui/drag.ts @@ -5,7 +5,7 @@ */ import { storage } from 'common/storage'; -import { vecAdd, vecMultiply, vecScale, vecSubtract } from 'common/vector'; +import { vecAdd, vecMultiply, vecScale, vecSubtract } from 'tgui-core/vector'; import type { BooleanLike } from 'tgui-core/react'; import { createLogger } from './logging'; diff --git a/tgui/packages/tgui/events/handlers/assets.ts b/tgui/packages/tgui/events/handlers/assets.ts index 6ebf914a238..8a9117f3a35 100644 --- a/tgui/packages/tgui/events/handlers/assets.ts +++ b/tgui/packages/tgui/events/handlers/assets.ts @@ -1,9 +1,27 @@ import { loadMappings } from 'common/assets'; +import { fetchRetry } from 'tgui-core/http'; import { loadedMappings } from '../../assets'; /// --------- Handlers ------------------------------------------------------/// -/** This just lets us load in our own independent map */ export function handleLoadAssets(payload: Record): void { loadMappings(payload, loadedMappings); + + if ( + 'icon_ref_map.json' in payload && + Byond.iconRefMap && + Object.keys(Byond.iconRefMap).length === 0 + ) { + fetchRetry(payload['icon_ref_map.json']) + .then((res) => res.json()) + .then(setIconRefMap) + .catch(console.error); + } +} + +/// --------- Helpers -------------------------------------------------------/// + +// https://biomejs.dev/linter/rules/no-assign-in-expressions/ +function setIconRefMap(map: Record): void { + Byond.iconRefMap = map; } diff --git a/tgui/packages/tgui/interfaces/Gps.jsx b/tgui/packages/tgui/interfaces/Gps.jsx index f3c44ec8c4b..f4f2ec96e1c 100644 --- a/tgui/packages/tgui/interfaces/Gps.jsx +++ b/tgui/packages/tgui/interfaces/Gps.jsx @@ -1,4 +1,4 @@ -import { vecLength, vecSubtract } from 'common/vector'; +import { vecLength, vecSubtract } from 'tgui-core/vector'; import { sortBy } from 'es-toolkit'; import { map } from 'es-toolkit/compat'; import {