From a4d59ca1621c3a7724472c93f844a284c36b3e54 Mon Sep 17 00:00:00 2001 From: DuckieTM Date: Sat, 24 May 2025 19:05:08 +0200 Subject: [PATCH] :up: :Chooser and :furni --- .../room/widgets/ChooserSelectionFilter.ts | 111 ++++++++++++ .../widgets/ChooserSelectionVisualizer.ts | 105 +++++++++++ src/api/room/widgets/RoomObjectItem.ts | 47 +++-- src/api/room/widgets/index.ts | 2 + .../widgets/choosers/ChooserWidgetView.scss | 6 +- .../widgets/choosers/ChooserWidgetView.tsx | 167 ++++++++++++++---- .../choosers/FurniChooserWidgetView.tsx | 21 ++- .../choosers/UserChooserWidgetView.tsx | 30 +++- .../rooms/widgets/useFurniChooserWidget.ts | 76 ++++++-- .../rooms/widgets/useUserChooserWidget.ts | 44 +++-- 10 files changed, 525 insertions(+), 84 deletions(-) create mode 100644 src/api/room/widgets/ChooserSelectionFilter.ts create mode 100644 src/api/room/widgets/ChooserSelectionVisualizer.ts diff --git a/src/api/room/widgets/ChooserSelectionFilter.ts b/src/api/room/widgets/ChooserSelectionFilter.ts new file mode 100644 index 0000000..864f134 --- /dev/null +++ b/src/api/room/widgets/ChooserSelectionFilter.ts @@ -0,0 +1,111 @@ +import { ColorConverter, NitroFilter } from '@nitrots/nitro-renderer'; + +const vertex = ` +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +uniform mat3 projectionMatrix; +varying vec2 vTextureCoord; +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; +}`; + +const fragment = ` +varying vec2 vTextureCoord; +uniform sampler2D uSampler; +uniform vec3 lineColor; +uniform vec3 color; +uniform float time; // Added time uniform for animation +void main(void) { + vec4 currentColor = texture2D(uSampler, vTextureCoord); + vec3 colorLine = lineColor * currentColor.a; + vec3 colorOverlay = color * currentColor.a; + + // Calculate fading factor using sine wave (oscillates between 0.5 and 1.0) + float fadeFactor = 0.75 + 0.25 * sin(time * 3.0); // Adjust speed with multiplier + + if(currentColor.r == 0.0 && currentColor.g == 0.0 && currentColor.b == 0.0 && currentColor.a > 0.0) { + gl_FragColor = vec4(colorLine.r * fadeFactor, colorLine.g * fadeFactor, colorLine.b * fadeFactor, currentColor.a); + } else if(currentColor.a > 0.0) { + gl_FragColor = vec4(colorOverlay.r * fadeFactor, colorOverlay.g * fadeFactor, colorOverlay.b * fadeFactor, currentColor.a * 0.35); + } +}`; + +export class ChooserSelectionFilter extends NitroFilter +{ + private _lineColor: number; + private _color: number; + private _time: number; + + constructor(lineColor: number | number[] = [0.700, 0.880, 0.950], color: number | number[] = [0.290, 0.350, 0.390]) + { + super(vertex, fragment); + + this.uniforms.lineColor = new Float32Array(3); + this.uniforms.color = new Float32Array(3); + this.uniforms.time = 0.0; // Initialize time uniform + this._time = 0.0; + this.lineColor = lineColor; + this.color = color; + } + + public get lineColor(): number | number[] + { + return this._lineColor; + } + + public set lineColor(value: number | number[]) + { + const arr = this.uniforms.lineColor; + + if(typeof value === 'number') + { + ColorConverter.hex2rgb(value, arr); + this._lineColor = value; + } + else + { + arr[0] = value[0]; + arr[1] = value[1]; + arr[2] = value[2]; + + this._lineColor = ColorConverter.rgb2hex(arr); + } + } + + public get color(): number | number[] + { + return this._color; + } + + public set color(value: number | number[]) + { + const arr = this.uniforms.color; + + if(typeof value === 'number') + { + ColorConverter.hex2rgb(value, arr); + this._color = value; + } + else + { + arr[0] = value[0]; + arr[1] = value[1]; + arr[2] = value[2]; + + this._color = ColorConverter.rgb2hex(arr); + } + } + + public get time(): number + { + return this._time; + } + + public set time(value: number) + { + this._time = value; + this.uniforms.time = value; + } +} \ No newline at end of file diff --git a/src/api/room/widgets/ChooserSelectionVisualizer.ts b/src/api/room/widgets/ChooserSelectionVisualizer.ts new file mode 100644 index 0000000..4b6679c --- /dev/null +++ b/src/api/room/widgets/ChooserSelectionVisualizer.ts @@ -0,0 +1,105 @@ +import { IRoomObjectSpriteVisualization, RoomObjectCategory } from '@nitrots/nitro-renderer'; +import { ChooserSelectionFilter, GetRoomEngine } from '../..'; + +export class chooserSelectionVisualizer +{ + private static glowFilter = new ChooserSelectionFilter( + [0.700, 0.880, 0.950], + [0.290, 0.350, 0.390] + ); + private static activeFilters: Map = new Map(); + private static animationFrameId: number | null = null; + + private static startAnimation(): void + { + if (this.animationFrameId !== null) return; + + const animate = (time: number) => { + const elapsed = time / 1000; // Convert to seconds + this.activeFilters.forEach(filter => { + filter.time = elapsed; // Update time uniform + }); + this.animationFrameId = requestAnimationFrame(animate); + }; + + this.animationFrameId = requestAnimationFrame(animate); + } + + private static stopAnimation(): void + { + if (this.animationFrameId !== null) { + cancelAnimationFrame(this.animationFrameId); + this.animationFrameId = null; + } + } + + public static show(id: number, category: number = RoomObjectCategory.FLOOR): void + { + const roomObject = GetRoomEngine().getRoomObject(GetRoomEngine().activeRoomId, id, category); + if (!roomObject) return; + + const visualization = roomObject.visualization as IRoomObjectSpriteVisualization; + if (!visualization || !visualization.sprites || !visualization.sprites.length) return; + + // Create a unique filter instance for this object + const filter = new ChooserSelectionFilter( + [0.700, 0.880, 0.950], + [0.290, 0.350, 0.390] + ); + const key = `${id}_${category}`; + this.activeFilters.set(key, filter); + + for (const sprite of visualization.sprites) + { + if (sprite.blendMode === 1) continue; + sprite.filters = [filter]; + } + + this.startAnimation(); + } + + public static hide(id: number, category: number = RoomObjectCategory.FLOOR): void + { + const roomObject = GetRoomEngine().getRoomObject(GetRoomEngine().activeRoomId, id, category); + if (!roomObject) return; + + const visualization = roomObject.visualization as IRoomObjectSpriteVisualization; + if (!visualization) return; + + const key = `${id}_${category}`; + this.activeFilters.delete(key); + + for (const sprite of visualization.sprites) + { + sprite.filters = []; + } + + if (this.activeFilters.size === 0) { + this.stopAnimation(); + } + } + + public static clearAll(): void + { + const roomEngine = GetRoomEngine(); + + const roomObjects = [ + ...roomEngine.getRoomObjects(roomEngine.activeRoomId, RoomObjectCategory.FLOOR), + ...roomEngine.getRoomObjects(roomEngine.activeRoomId, RoomObjectCategory.WALL) + ]; + + for (const roomObject of roomObjects) + { + const visualization = roomObject.visualization as IRoomObjectSpriteVisualization; + if (!visualization) continue; + + for (const sprite of visualization.sprites) + { + sprite.filters = []; + } + } + + this.activeFilters.clear(); + this.stopAnimation(); + } +} \ No newline at end of file diff --git a/src/api/room/widgets/RoomObjectItem.ts b/src/api/room/widgets/RoomObjectItem.ts index f4fb2d6..a2800b5 100644 --- a/src/api/room/widgets/RoomObjectItem.ts +++ b/src/api/room/widgets/RoomObjectItem.ts @@ -3,26 +3,41 @@ export class RoomObjectItem private _id: number; private _category: number; private _name: string; + private _ownerId: number; + private _ownerName: string; + private _type?: string; - constructor(id: number, category: number, name: string) + constructor( id: number, category: number, name: string, ownerId: number = 0, ownerName: string = '#', type?: string ) { this._id = id; this._category = category; this._name = name; + this._ownerId = ownerId; + this._ownerName = ownerName; + this._type = type; } - public get id(): number - { - return this._id; - } - - public get category(): number - { - return this._category; - } - - public get name(): string - { - return this._name; - } -} + public get id(): number { + return this._id; + } + + public get category(): number { + return this._category; + } + + public get name(): string { + return this._name; + } + + public get ownerId(): number { + return this._ownerId; + } + + public get ownerName(): string { + return this._ownerName ?? '#'; + } + + public get type(): string { + return this._type ?? '-'; + } +} \ No newline at end of file diff --git a/src/api/room/widgets/index.ts b/src/api/room/widgets/index.ts index c43d6aa..acaa7d6 100644 --- a/src/api/room/widgets/index.ts +++ b/src/api/room/widgets/index.ts @@ -7,6 +7,8 @@ export * from './AvatarInfoUtilities'; export * from './BotSkillsEnum'; export * from './ChatBubbleMessage'; export * from './ChatMessageTypeEnum'; +export * from './ChooserSelectionFilter'; +export * from './ChooserSelectionVisualizer'; export * from './DimmerFurnitureWidgetPresetItem'; export * from './DoChatsOverlap'; export * from './FurnitureDimmerUtilities'; diff --git a/src/components/room/widgets/choosers/ChooserWidgetView.scss b/src/components/room/widgets/choosers/ChooserWidgetView.scss index 026e95b..f9abf77 100644 --- a/src/components/room/widgets/choosers/ChooserWidgetView.scss +++ b/src/components/room/widgets/choosers/ChooserWidgetView.scss @@ -1,4 +1,4 @@ .nitro-chooser-widget { - width: $nitro-chooser-width; - height: $nitro-chooser-height; -} + width: 420px; + height: 400px; +} \ No newline at end of file diff --git a/src/components/room/widgets/choosers/ChooserWidgetView.tsx b/src/components/room/widgets/choosers/ChooserWidgetView.tsx index e6655d2..67c04cc 100644 --- a/src/components/room/widgets/choosers/ChooserWidgetView.tsx +++ b/src/components/room/widgets/choosers/ChooserWidgetView.tsx @@ -1,6 +1,6 @@ import { FurniturePickupAllComposer } from '@nitrots/nitro-renderer'; import { FC, useEffect, useMemo, useState } from 'react'; -import { GetSessionDataManager, LocalizeText, RoomObjectItem, SendMessageComposer } from '../../../../api'; +import { GetSessionDataManager, LocalizeText, RoomObjectItem, SendMessageComposer, chooserSelectionVisualizer } from '../../../../api'; import { Base, Button, Flex, InfiniteScroll, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, classNames } from '../../../../common'; const LIMIT_FURNI_PICKALL = 100; @@ -12,18 +12,35 @@ interface ChooserWidgetViewProps selectItem: (item: RoomObjectItem) => void; onClose: () => void; pickallFurni?: boolean; + type?: 'furni' | 'users'; } export const ChooserWidgetView: FC = props => { - const { title = null, items = [], selectItem = null, onClose = null } = props; - const [ selectedItem, setSelectedItem ] = useState(null); + const { title = null, items = [], selectItem = null, onClose = null, pickallFurni = false, type = 'furni' } = props; + const [ selectedItems, setSelectedItems ] = useState([]); const [ searchValue, setSearchValue ] = useState(''); const canSeeId = GetSessionDataManager().isModerator; const [ checkAll, setCheckAll ] = useState(false); const [ checkedIds, setCheckedIds ] = useState([]); - + + const ownerNames = useMemo(() => { + const names = Array.from(new Set(items.map(item => item.ownerName || 'Unknown'))); + return names.sort(); + }, [items]); + + const [ selectedFilter, setSelectedFilter ] = useState(() => { + if (pickallFurni) return 'all'; + return ownerNames.length > 0 ? ownerNames[0] : ''; + }); + + useEffect(() => { + if (!pickallFurni && ownerNames.length > 0 && !selectedFilter) { + setSelectedFilter(ownerNames[0]); + } + }, [pickallFurni, ownerNames, selectedFilter]); + const checkedId = (id?: number) => { if (id) @@ -56,48 +73,134 @@ export const ChooserWidgetView: FC = props => SendMessageComposer(new FurniturePickupAllComposer(...checkedIds)); setCheckedIds([]); setCheckAll(false); + chooserSelectionVisualizer.clearAll(); + setSelectedItems([]); } const filteredItems = useMemo(() => { const value = searchValue.toLocaleLowerCase(); - const itemsFilter = items.filter(item => item.name?.toLocaleLowerCase().includes(value)); - - const itemsFilterSorted = itemsFilter.sort((a, b) => a.name.localeCompare(b.name)); - - return itemsFilterSorted - }, [ items, searchValue ]); + return items + .filter(item => + { + const matchesSearch = item.name?.toLocaleLowerCase().includes(value); + const matchesFilter = !pickallFurni ? (selectedFilter ? item.ownerName === selectedFilter : true) : (selectedFilter === 'all' || item.ownerName === selectedFilter); + return matchesSearch && matchesFilter; + }) + .sort((a, b) => a.name.localeCompare(b.name)); + }, [ items, searchValue, selectedFilter, pickallFurni ]); useEffect(() => { - if(!selectedItem) return; + if (selectedItems.length === 0) return; - selectItem(selectedItem); - }, [ selectedItem, selectItem ]); + selectItem(selectedItems[selectedItems.length - 1]); + + chooserSelectionVisualizer.clearAll(); + selectedItems.forEach(item => { + if (item.id && item.category) { + chooserSelectionVisualizer.show(item.id, item.category); + } + }); + }, [ selectedItems, selectItem ]); + + const toggleItemSelection = (item: RoomObjectItem) => { + setSelectedItems(prev => { + if (prev.some(selected => selected.id === item.id)) { + chooserSelectionVisualizer.hide(item.id, item.category); + return prev.filter(selected => selected.id !== item.id); + } else { + return [...prev, item]; + } + }); + }; + + const handleClose = () => { + chooserSelectionVisualizer.clearAll(); + setSelectedItems([]); + onClose(); + }; return ( - + - setSearchValue(event.target.value) } /> - { props.pickallFurni && - checkedId() } /> - - } - - { - return ( - setSelectedItem(row) }> - { props.pickallFurni && checkedId(row.id) } /> } - { row.name } { canSeeId && (' - ' + row.id) } - - ); - } } /> - { props.pickallFurni && } + + setSearchValue(event.target.value) } + /> + { pickallFurni && ( + + )} + + { pickallFurni && ( + + checkedId() } + /> + + + )} + + { + return ( + item.id === row.id) && 'bg-muted') } + pointer + onClick={ event => { + toggleItemSelection(row); + }} + > + { pickallFurni && ( + checkedId(row.id) } + /> + )} + + { row.name } { canSeeId && (' - ' + row.id) } + { type === 'furni' && row.ownerName && row.ownerName !== '-' && ` (Owner: ${row.ownerName})` } + + + ); + } } + /> + { pickallFurni && ( + + )} ); -} +} \ No newline at end of file diff --git a/src/components/room/widgets/choosers/FurniChooserWidgetView.tsx b/src/components/room/widgets/choosers/FurniChooserWidgetView.tsx index 3ccdf46..30b051b 100644 --- a/src/components/room/widgets/choosers/FurniChooserWidgetView.tsx +++ b/src/components/room/widgets/choosers/FurniChooserWidgetView.tsx @@ -1,6 +1,6 @@ import { ILinkEventTracker } from '@nitrots/nitro-renderer'; import { FC, useEffect } from 'react'; -import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../../../api'; +import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker, chooserSelectionVisualizer } from '../../../../api'; import { useFurniChooserWidget, useRoom } from '../../../../hooks'; import { ChooserWidgetView } from './ChooserWidgetView'; @@ -23,10 +23,23 @@ export const FurniChooserWidgetView: FC<{}> = props => AddEventLinkTracker(linkTracker); - return () => RemoveLinkEventTracker(linkTracker); + return () => { + chooserSelectionVisualizer.clearAll(); + RemoveLinkEventTracker(linkTracker); + }; }, [ populateChooser ]); if (!items) return null; - return ; -} + return { + chooserSelectionVisualizer.clearAll(); + onClose(); + }} + pickallFurni={ roomSession?.isRoomOwner } + type="furni" + />; +} \ No newline at end of file diff --git a/src/components/room/widgets/choosers/UserChooserWidgetView.tsx b/src/components/room/widgets/choosers/UserChooserWidgetView.tsx index f73e074..b4426b4 100644 --- a/src/components/room/widgets/choosers/UserChooserWidgetView.tsx +++ b/src/components/room/widgets/choosers/UserChooserWidgetView.tsx @@ -1,12 +1,13 @@ import { ILinkEventTracker } from '@nitrots/nitro-renderer'; import { FC, useEffect } from 'react'; -import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../../../api'; -import { useUserChooserWidget } from '../../../../hooks'; -import { ChooserWidgetView } from './ChooserWidgetView'; +import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker, chooserSelectionVisualizer } from '../../../../api'; +import { useUserChooserWidget, useRoom } from '../../../../hooks'; // Adjust hook as needed +import { ChooserWidgetView } from './ChooserWidgetView'; // Adjust path as needed export const UserChooserWidgetView: FC<{}> = props => { - const { items = null, onClose = null, selectItem = null, populateChooser = null } = useUserChooserWidget(); + const { items = null, onClose = null, selectItem = null, populateChooser = null } = useUserChooserWidget(); // Adjust hook + const { roomSession = null } = useRoom(); useEffect(() => { @@ -22,10 +23,23 @@ export const UserChooserWidgetView: FC<{}> = props => AddEventLinkTracker(linkTracker); - return () => RemoveLinkEventTracker(linkTracker); + return () => { + chooserSelectionVisualizer.clearAll(); + RemoveLinkEventTracker(linkTracker); + }; }, [ populateChooser ]); - if(!items) return null; + if (!items) return null; - return ; -} + return { + chooserSelectionVisualizer.clearAll(); + onClose(); + }} + pickallFurni={ false } + type="users" + />; +} \ No newline at end of file diff --git a/src/hooks/rooms/widgets/useFurniChooserWidget.ts b/src/hooks/rooms/widgets/useFurniChooserWidget.ts index 4542dba..9303b9d 100644 --- a/src/hooks/rooms/widgets/useFurniChooserWidget.ts +++ b/src/hooks/rooms/widgets/useFurniChooserWidget.ts @@ -13,6 +13,24 @@ const useFurniChooserWidgetState = () => const selectItem = (item: RoomObjectItem) => item && GetRoomEngine().selectRoomObject(GetRoomSession().roomId, item.id, item.category); + const resolveType = (userType: number): string => { + switch(userType) { + case 1: return 'Habbo'; + case 2: return 'Pet'; + case 3: return 'Bot'; + default: return '-'; + } + } + + const isPetOrBot = (roomObjectType: string): boolean => { + // Check for pet or bot furniture based on type + return roomObjectType.includes('pet_') || + roomObjectType.includes('bot_') || + roomObjectType === 'pet' || + roomObjectType === 'bot' || + roomObjectType.includes('rentableBot'); + } + const populateChooser = () => { const sessionDataManager = GetSessionDataManager(); @@ -37,8 +55,18 @@ const useFurniChooserWidgetState = () => if(furniData && furniData.name.length) name = furniData.name; } - return new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name); - }); + const ownerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID) || 0; + const ownerName = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_NAME) || + (sessionDataManager.getUserData ? sessionDataManager.getUserData(ownerId)?.name : null) || + `User_${ownerId}`; + + // Skip pet/bot furniture + if(isPetOrBot(roomObject.type)) { + return null; + } + + return new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name, ownerId, ownerName, 'furniture'); + }).filter(item => item !== null); const floorItems = floorObjects.map(roomObject => { @@ -51,8 +79,18 @@ const useFurniChooserWidgetState = () => if(furniData && furniData.name.length) name = furniData.name; - return new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name); - }); + const ownerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID) || 0; + const ownerName = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_NAME) || + (sessionDataManager.getUserData ? sessionDataManager.getUserData(ownerId)?.name : null) || + `User_${ownerId}`; + + // Skip pet/bot furniture + if(isPetOrBot(roomObject.type)) { + return null; + } + + return new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name, ownerId, ownerName, 'furniture'); + }).filter(item => item !== null); setItems([ ...wallItems, ...floorItems ].sort((a, b) => ((a.name < b.name) ? -1 : 1))); } @@ -62,7 +100,6 @@ const useFurniChooserWidgetState = () => if(event.id < 0) return; const roomObject = GetRoomEngine().getRoomObject(GetRoomSession().roomId, event.id, event.category); - if(!roomObject) return; let item: RoomObjectItem = null; @@ -84,8 +121,17 @@ const useFurniChooserWidgetState = () => if(furniData && furniData.name.length) name = furniData.name; } - item = new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name); + const ownerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID) || 0; + const ownerName = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_NAME) || + (GetSessionDataManager().getUserData ? GetSessionDataManager().getUserData(ownerId)?.name : null) || + `User_${ownerId}`; + // Skip pet/bot furniture + if(isPetOrBot(roomObject.type)) { + return; + } + + item = new RoomObjectItem(roomObject.id, RoomObjectCategory.WALL, name, ownerId, ownerName, 'furniture'); break; } case RoomObjectCategory.FLOOR: { @@ -96,11 +142,22 @@ const useFurniChooserWidgetState = () => if(furniData && furniData.name.length) name = furniData.name; - item = new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name); + const ownerId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_ID) || 0; + const ownerName = roomObject.model.getValue(RoomObjectVariable.FURNITURE_OWNER_NAME) || + (GetSessionDataManager().getUserData ? GetSessionDataManager().getUserData(ownerId)?.name : null) || + `User_${ownerId}`; + + // Skip pet/bot furniture + if(isPetOrBot(roomObject.type)) { + return; + } + + item = new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name, ownerId, ownerName, 'furniture'); + break; } } - setItems(prevValue => [ ...prevValue, item ].sort((a, b) => ((a.name < b.name) ? -1 : 1))); + if(item) setItems(prevValue => [ ...prevValue, item ].sort((a, b) => ((a.name < b.name) ? -1 : 1))); }); useFurniRemovedEvent(!!items, event => @@ -118,7 +175,6 @@ const useFurniChooserWidgetState = () => if((existingValue.id !== event.id) || (existingValue.category !== event.category)) continue; newValue.splice(i, 1); - break; } @@ -129,4 +185,4 @@ const useFurniChooserWidgetState = () => return { items, onClose, selectItem, populateChooser }; } -export const useFurniChooserWidget = useFurniChooserWidgetState; +export const useFurniChooserWidget = useFurniChooserWidgetState; \ No newline at end of file diff --git a/src/hooks/rooms/widgets/useUserChooserWidget.ts b/src/hooks/rooms/widgets/useUserChooserWidget.ts index 857922a..a728c01 100644 --- a/src/hooks/rooms/widgets/useUserChooserWidget.ts +++ b/src/hooks/rooms/widgets/useUserChooserWidget.ts @@ -11,7 +11,19 @@ const useUserChooserWidgetState = () => const onClose = () => setItems(null); - const selectItem = (item: RoomObjectItem) => item && GetRoomEngine().selectRoomObject(GetRoomSession().roomId, item.id, item.category); + const selectItem = (item: RoomObjectItem) => + item && GetRoomEngine().selectRoomObject(GetRoomSession().roomId, item.id, item.category); + + const resolveType = (userType: number): string => + { + switch(userType) + { + case 1: return 'Habbo'; + case 2: return 'Pet'; + case 3: return 'Bot'; + default: return '-'; + } + } const populateChooser = () => { @@ -22,14 +34,21 @@ const useUserChooserWidgetState = () => .map(roomObject => { if(roomObject.id < 0) return null; - - const userData = roomSession.userDataManager.getUserDataByIndex(roomObject.id); + const userData = roomSession.userDataManager.getUserDataByIndex(roomObject.id); if(!userData) return null; - return new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name); + if(userData.type !== 1) { + return null; + } + + const type = resolveType(userData.type); + const item = new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name, 0, '-', type); + return item; }) - .sort((a, b) => ((a.name < b.name) ? -1 : 1))); + .filter(Boolean) + .sort((a, b) => ((a.name < b.name) ? -1 : 1)) + ); } useUserAddedEvent(!!items, event => @@ -37,16 +56,20 @@ const useUserChooserWidgetState = () => if(event.id < 0) return; const userData = GetRoomSession().userDataManager.getUserDataByIndex(event.id); - if(!userData) return; + if(userData.type !== 1) { + return; + } + + const type = resolveType(userData.type); + const item = new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name, 0, '-', type); + setItems(prevValue => { const newValue = [ ...prevValue ]; - - newValue.push(new RoomObjectItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name)); + newValue.push(item); newValue.sort((a, b) => ((a.name < b.name) ? -1 : 1)); - return newValue; }); }); @@ -66,7 +89,6 @@ const useUserChooserWidgetState = () => if((existingValue.id !== event.id) || (existingValue.category !== event.category)) continue; newValue.splice(i, 1); - break; } @@ -77,4 +99,4 @@ const useUserChooserWidgetState = () => return { items, onClose, selectItem, populateChooser }; } -export const useUserChooserWidget = useUserChooserWidgetState; +export const useUserChooserWidget = useUserChooserWidgetState; \ No newline at end of file