From d9c80ec06b92c1bd1822cb872d57435ccc450e78 Mon Sep 17 00:00:00 2001 From: Kashargul <144968721+Kashargul@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:05:36 +0200 Subject: [PATCH] spawn panel fixes (#95566) --- .../admin/spawn_panel/spawn_handling.dm | 19 ++-------- .../interfaces/SpawnPanel/CreateObject.tsx | 23 +++++++----- .../SpawnPanel/CreateObjectSettings.tsx | 37 ++++++++++--------- .../tgui/interfaces/SpawnPanel/constants.tsx | 18 ++++++--- tgui/packages/tgui/interfaces/SpawnSearch.tsx | 30 +++++++-------- 5 files changed, 64 insertions(+), 63 deletions(-) diff --git a/code/modules/admin/spawn_panel/spawn_handling.dm b/code/modules/admin/spawn_panel/spawn_handling.dm index dddfbda0eb8..265dd6c38da 100644 --- a/code/modules/admin/spawn_panel/spawn_handling.dm +++ b/code/modules/admin/spawn_panel/spawn_handling.dm @@ -24,22 +24,9 @@ var/amount = clamp(text2num(spawn_params["atom_amount"]), 1, ADMIN_SPAWN_CAP) - var/list/offset_data - if(islist(spawn_params["offset"])) - offset_data = spawn_params["offset"] - else if(istext(spawn_params["offset"])) - var/list/parsed = splittext(spawn_params["offset"], ",") - if(length(parsed) >= 3) - offset_data = list("X" = text2num(parsed[1]), "Y" = text2num(parsed[2]), "Z" = text2num(parsed[3])) - else - offset_data = list("X" = 0, "Y" = 0, "Z" = 0) - else - offset_data = list("X" = 0, "Y" = 0, "Z" = 0) - - - var/X = offset_data["X"] || 0 - var/Y = offset_data["Y"] || 0 - var/Z = offset_data["Z"] || 0 + var/X = offset["X"] || 0 + var/Y = offset["Y"] || 0 + var/Z = offset["Z"] || 0 var/atom_dir = text2num(spawn_params["atom_dir"]) || 1 var/atom_name = sanitize(spawn_params["atom_name"]) diff --git a/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx b/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx index 4398a83a3dd..3123ef023af 100644 --- a/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx +++ b/tgui/packages/tgui/interfaces/SpawnPanel/CreateObject.tsx @@ -56,7 +56,11 @@ export function CreateObject(props: CreateObjectProps) { const currentType = allObjects[data.copied_type ?? '']?.type || 'Objects'; const getSearchString = useCallback( - (key: string) => (searchBy ? key : allObjects[key]?.name || ''), + (key: string) => { + const item = allObjects[key]; + if (!item) return key; + return searchBy ? key : `${key} ${item.name || ''}`; + }, [searchBy, allObjects], ); @@ -121,14 +125,15 @@ export function CreateObject(props: CreateObjectProps) { if (storedHideMapping !== undefined) setHideMapping(storedHideMapping); if (storedShowIcons !== undefined) setshowIcons(storedShowIcons); if (storedShowPreview !== undefined) setshowPreview(storedShowPreview); - if (storedSelectedObj) { - if (allObjects[storedSelectedObj]) { - setSelectedObj(storedSelectedObj); - props.onIconSettingsChange?.({ - icon: allObjects[storedSelectedObj].icon, - iconState: allObjects[storedSelectedObj].icon_state, - }); - } + if (storedSelectedObj && allObjects[storedSelectedObj]) { + act('selected-atom-changed', { + newObj: storedSelectedObj, + }); + setSelectedObj(storedSelectedObj); + props.onIconSettingsChange?.({ + icon: allObjects[storedSelectedObj].icon, + iconState: allObjects[storedSelectedObj].icon_state, + }); } }; diff --git a/tgui/packages/tgui/interfaces/SpawnPanel/CreateObjectSettings.tsx b/tgui/packages/tgui/interfaces/SpawnPanel/CreateObjectSettings.tsx index fc93d7b14f8..9ac66f499c5 100644 --- a/tgui/packages/tgui/interfaces/SpawnPanel/CreateObjectSettings.tsx +++ b/tgui/packages/tgui/interfaces/SpawnPanel/CreateObjectSettings.tsx @@ -3,6 +3,7 @@ import { useEffect, useState } from 'react'; import { Button, Dropdown, + Icon, Input, NumberInput, Slider, @@ -12,8 +13,8 @@ import { import { useBackend } from '../../backend'; import { - directionIcons, directionNames, + directionRotation, spawnLocationIcons, spawnLocationOptions, } from './constants'; @@ -44,6 +45,7 @@ export function CreateObjectSettings(props: CreateObjectSettingsProps) { const [objectName, setObjectName] = useState(''); const [offset, setOffset] = useState(''); + const dirValues = [1, 5, 4, 6, 2, 10, 8, 9]; const updateAmount = (value: number) => { setAmount(value); sendUpdatedSettings({ atom_amount: value }); @@ -66,7 +68,7 @@ export function CreateObjectSettings(props: CreateObjectSettingsProps) { const updateDirection = (value: number) => { setDirection(value); storage.set('spawnpanel-direction', value); - sendUpdatedSettings({ atom_dir: [1, 2, 4, 8][value] }); + sendUpdatedSettings({ atom_dir: dirValues[value] }); }; const updateObjectName = (value: string) => { @@ -121,7 +123,7 @@ export function CreateObjectSettings(props: CreateObjectSettingsProps) { atom_amount: amount, offset_type: cordsType ? 'Absolute offset' : 'Relative offset', where_target_type: spawnLocation, - atom_dir: [1, 2, 4, 8][direction], + atom_dir: dirValues[direction], offset: parseOffset(offset), atom_name: objectName, atom_icon_size: iconSettings.iconSize, @@ -157,7 +159,7 @@ export function CreateObjectSettings(props: CreateObjectSettingsProps) { atom_amount: defaultAmount, offset_type: defaultCordsType ? 'Absolute offset' : 'Relative offset', where_target_type: defaultSpawnLocation, - atom_dir: [1, 2, 4, 8][defaultDirection], + atom_dir: dirValues[defaultDirection], offset: defaultOffset, atom_name: defaultObjectName, }); @@ -221,7 +223,7 @@ export function CreateObjectSettings(props: CreateObjectSettingsProps) { atom_amount: amount, offset_type: cordsType ? 'Absolute offset' : 'Relative offset', where_target_type: spawnLocation, - atom_dir: [1, 2, 4, 8][direction], + atom_dir: dirValues[direction], offset: parseOffset(offset), atom_name: objectName, atom_icon_size: iconSettings.iconSize, @@ -288,31 +290,32 @@ export function CreateObjectSettings(props: CreateObjectSettingsProps) { Dir: { - const values = [1, 2, 4, 8]; - return values[value].toString(); - }} + format={(value) => dirValues[value].toString()} onChange={(e, value) => updateDirection(value)} disabled={isAnyPreciseModeActive} /> diff --git a/tgui/packages/tgui/interfaces/SpawnPanel/constants.tsx b/tgui/packages/tgui/interfaces/SpawnPanel/constants.tsx index 13be3441059..f0707f757a5 100644 --- a/tgui/packages/tgui/interfaces/SpawnPanel/constants.tsx +++ b/tgui/packages/tgui/interfaces/SpawnPanel/constants.tsx @@ -32,11 +32,15 @@ export const spawnLocationIcons = { "In targeted mob's hand": 'crosshairs', }; -export const directionIcons = { - 1: 'arrow-up', - 2: 'arrow-down', - 4: 'arrow-right', - 8: 'arrow-left', +export const directionRotation = { + 1: 0, + 5: 45, + 4: 90, + 6: 135, + 2: 180, + 10: 225, + 8: 270, + 9: 315, }; export const directionNames = { @@ -44,4 +48,8 @@ export const directionNames = { 2: 'SOUTH', 4: 'EAST', 8: 'WEST', + 5: 'NORTHEAST', + 6: 'SOUTHEAST', + 9: 'NORTHWEST', + 10: 'SOUTHWEST', }; diff --git a/tgui/packages/tgui/interfaces/SpawnSearch.tsx b/tgui/packages/tgui/interfaces/SpawnSearch.tsx index 3e2299444df..5dbe4cb7f4c 100644 --- a/tgui/packages/tgui/interfaces/SpawnSearch.tsx +++ b/tgui/packages/tgui/interfaces/SpawnSearch.tsx @@ -175,23 +175,18 @@ export function SpawnSearch() { // User presses up or down on keyboard // Simulates clicking an item function handleArrowKey(key: number): void { - const len = Object.keys(filteredItems).length - 1; + if (!filteredItems.length) return; + + const len = filteredItems.length - 1; + if (key === KEY_DOWN) { - if (selected === null || selected === len) { - setSelected(0); - document!.getElementById('0')?.scrollIntoView(); - } else { - setSelected(selected + 1); - document!.getElementById((selected + 1).toString())?.scrollIntoView(); - } + const next = selected >= len ? 0 : selected + 1; + setSelected(next); + document?.getElementById(next.toString())?.scrollIntoView(); } else if (key === KEY_UP) { - if (selected === null || selected === 0) { - setSelected(len); - document!.getElementById(len.toString())?.scrollIntoView(); - } else { - setSelected(selected - 1); - document!.getElementById((selected - 1).toString())?.scrollIntoView(); - } + const prev = selected <= 0 ? len : selected - 1; + setSelected(prev); + document?.getElementById(prev.toString())?.scrollIntoView(); } } @@ -225,7 +220,9 @@ export function SpawnSearch() { } } - function handleSelect(selection: AtomTypeData): void { + function handleSelect(selection?: AtomTypeData): void { + if (!selection) return; + act('spawn', { type: selection.typepath, amount: spawnAmount }); } @@ -287,6 +284,7 @@ export function SpawnSearch() { className="candystripe" color="transparent" fluid + id={index.toString()} key={index} onClick={() => { if (index !== selected) setSelected(index);