diff --git a/src/assets/images/mannequin/background.png b/src/assets/images/mannequin/background.png deleted file mode 100644 index e3c824a6..00000000 Binary files a/src/assets/images/mannequin/background.png and /dev/null differ diff --git a/src/assets/images/mannequin/hc.png b/src/assets/images/mannequin/hc.png deleted file mode 100644 index 949f3d47..00000000 Binary files a/src/assets/images/mannequin/hc.png and /dev/null differ diff --git a/src/assets/images/room-widgets/lovelock-widget/lovelock-spritesheet.png b/src/assets/images/room-widgets/lovelock-widget/lovelock-spritesheet.png new file mode 100644 index 00000000..9efcb328 Binary files /dev/null and b/src/assets/images/room-widgets/lovelock-widget/lovelock-spritesheet.png differ diff --git a/src/assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png b/src/assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png new file mode 100644 index 00000000..45e11f34 Binary files /dev/null and b/src/assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png differ diff --git a/src/assets/images/trophies/shine.png b/src/assets/images/trophies/shine.png deleted file mode 100644 index 4f42c70a..00000000 Binary files a/src/assets/images/trophies/shine.png and /dev/null differ diff --git a/src/views/room/widgets/furniture/FurnitureWidgets.scss b/src/views/room/widgets/furniture/FurnitureWidgets.scss index d58c1b66..bfb6128c 100644 --- a/src/views/room/widgets/furniture/FurnitureWidgets.scss +++ b/src/views/room/widgets/furniture/FurnitureWidgets.scss @@ -1,3 +1,5 @@ +@import './exchange-credit/FurnitureExchangeCreditView'; @import './manipulation-menu/FurnitureManipulationMenuView'; +@import './mannequin/FurnitureMannequinView'; @import './stickie/FurnitureStickieView'; @import './trophy/FurnitureTrophyView'; diff --git a/src/views/room/widgets/furniture/exchange-credit/FurnitureExchangeCreditView.scss b/src/views/room/widgets/furniture/exchange-credit/FurnitureExchangeCreditView.scss new file mode 100644 index 00000000..d7665d50 --- /dev/null +++ b/src/views/room/widgets/furniture/exchange-credit/FurnitureExchangeCreditView.scss @@ -0,0 +1,3 @@ +.nitro-exchange-credit { + width: 250px; +} diff --git a/src/views/room/widgets/furniture/exchange-credit/FurnitureExchangeCreditView.tsx b/src/views/room/widgets/furniture/exchange-credit/FurnitureExchangeCreditView.tsx index 414e5ac0..61c824dc 100644 --- a/src/views/room/widgets/furniture/exchange-credit/FurnitureExchangeCreditView.tsx +++ b/src/views/room/widgets/furniture/exchange-credit/FurnitureExchangeCreditView.tsx @@ -63,7 +63,7 @@ export const FurnitureExchangeCreditView: FC = pro if(!exchangeCreditData) return null; return ( - + processAction('close') } />
diff --git a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinData.ts b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinData.ts new file mode 100644 index 00000000..10928618 --- /dev/null +++ b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinData.ts @@ -0,0 +1,11 @@ +export class FurnitureMannequinData +{ + constructor( + public objectId: number, + public category: number, + public name: string, + public figure: string, + public gender: string, + public clubLevel: number, + public renderedFigure: string = null) {} +} diff --git a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss index e69de29b..cc16ce4c 100644 --- a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss +++ b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.scss @@ -0,0 +1,9 @@ +.nitro-mannequin { + width: 350px; + + .mannequin-preview { + width: 83px; + height: 130px; + background-image: url('../../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png'); + } +} diff --git a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx index 8c2d8e17..45ff3cad 100644 --- a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx +++ b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.tsx @@ -1,16 +1,218 @@ -import { RoomEngineObjectEvent, RoomEngineTriggerWidgetEvent } from 'nitro-renderer'; -import { FC } from 'react'; +import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, IAvatarFigureContainer, Nitro, NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from 'nitro-renderer'; +import { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react'; +import { GetRoomEngine } from '../../../../../api/nitro/room/GetRoomEngine'; +import { GetRoomSession } from '../../../../../api/nitro/session/GetRoomSession'; +import { GetSessionDataManager } from '../../../../../api/nitro/session/GetSessionDataManager'; +import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base'; import { useRoomEngineEvent } from '../../../../../hooks/events/nitro/room/room-engine-event'; -import { FurnitureMannequinViewProps } from './FurnitureMannequinView.types'; +import { NitroCardContentView } from '../../../../../layout/card/content/NitroCardContentView'; +import { NitroCardHeaderView } from '../../../../../layout/card/header/NitroCardHeaderView'; +import { NitroCardView } from '../../../../../layout/card/NitroCardView'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { AvatarImageView } from '../../../../avatar-image/AvatarImageView'; +import { RoomWidgetRoomObjectUpdateEvent } from '../../events'; +import { FurnitureMannequinData } from './FurnitureMannequinData'; +import { FurnitureMannequinViewMode, FurnitureMannequinViewProps } from './FurnitureMannequinView.types'; export const FurnitureMannequinView: FC = props => { - const onRoomEngineObjectEvent = (event: RoomEngineObjectEvent) => + const parts = [ + AvatarFigurePartType.CHEST_ACCESSORY, + AvatarFigurePartType.COAT_CHEST, + AvatarFigurePartType.CHEST, + AvatarFigurePartType.LEGS, + AvatarFigurePartType.SHOES, + AvatarFigurePartType.WAIST_ACCESSORY + ]; + const baseAvatar = ['hd', 99999, 99998]; + + const [ mannequinData, setMannequinData ] = useState(null); + const [ viewMode, setViewMode ] = useState(''); + + useEffect(() => { - console.log(event); + if(mannequinData && !mannequinData.renderedFigure) + { + const figureContainer = Nitro.instance.avatar.createFigureContainer(mannequinData.figure); + loadMannequinFigure(figureContainer); + } + }, [ mannequinData ]); + + const onNitroEvent = useCallback((event: NitroEvent) => + { + switch(event.type) + { + case RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN: { + const widgetEvent = (event as RoomEngineTriggerWidgetEvent); + + const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category); + + if(!roomObject) return; + + const figure = roomObject.model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_FIGURE); + const gender = roomObject.model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_GENDER); + const name = roomObject.model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_NAME); + + const figureContainer = Nitro.instance.avatar.createFigureContainer(figure); + const clubLevel = Nitro.instance.avatar.getFigureClubLevel(figureContainer, gender, parts); + + const mannequinData = new FurnitureMannequinData(widgetEvent.objectId, widgetEvent.category, name, figure, gender, clubLevel); + + setMannequinData(mannequinData); + loadViewMode(mannequinData); + return; + } + case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: { + const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent); + + setMannequinData(prevState => + { + if(!prevState || (widgetEvent.id !== prevState.objectId) || (widgetEvent.category !== prevState.category)) return prevState; + + return null; + }); + return; + } + } + }, []); + + useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, onNitroEvent); + CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, props.events, onNitroEvent); + + const loadMannequinFigure = useCallback((figureContainer: IAvatarFigureContainer) => + { + for(const item of figureContainer.getPartTypeIds()) + { + if(parts.indexOf(item) == -1) + { + figureContainer.removePart(item); + } + } + + figureContainer.updatePart(baseAvatar[0].toString(), Number(baseAvatar[1]), [ Number(baseAvatar[2]) ]); + + setMannequinData(mannequinData => new FurnitureMannequinData(mannequinData.objectId, mannequinData.category, mannequinData.name, mannequinData.figure, mannequinData.gender, mannequinData.clubLevel, figureContainer.getFigureString())); + }, []); + + const loadViewMode = useCallback((mannequinData: FurnitureMannequinData) => + { + if(!mannequinData) return; + + const userCanEdit = (GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator); + const userGender = Nitro.instance.sessionDataManager.gender; + const userClubLevel = Nitro.instance.sessionDataManager.clubLevel; + + if(userCanEdit) + { + setViewMode(FurnitureMannequinViewMode.EDIT); + } + else + { + if(!mannequinData.figure || mannequinData.figure.length <= 1) return; + + if(userGender.toUpperCase() !== mannequinData.gender.toUpperCase()) + { + setViewMode(FurnitureMannequinViewMode.INCOMPATIBLE_GENDER); + } + else if(userClubLevel < mannequinData.clubLevel) + { + setViewMode(FurnitureMannequinViewMode.CLUB); + } + else + { + setViewMode(FurnitureMannequinViewMode.DEFAULT); + } + } + }, []); + + const processAction = useCallback((type: string, value: string = null) => + { + switch(type) + { + case 'close': + setMannequinData(null); + return; + case 'set_name': + setMannequinData(mannequinData => new FurnitureMannequinData(mannequinData.objectId, mannequinData.category, value, mannequinData.figure, mannequinData.gender, mannequinData.clubLevel, mannequinData.renderedFigure)); + return; + case 'load_figure': + loadMannequinFigure(Nitro.instance.avatar.createFigureContainer(Nitro.instance.sessionDataManager.figure)); + setViewMode(FurnitureMannequinViewMode.SAVE); + return; + case 'back': + loadMannequinFigure(Nitro.instance.avatar.createFigureContainer(mannequinData.figure)); + setViewMode(FurnitureMannequinViewMode.EDIT); + return; + case 'save_name': + GetRoomSession().connection.send(new FurnitureMannequinSaveNameComposer(mannequinData.objectId, mannequinData.name)); + return; + case 'save_figure': + GetRoomSession().connection.send(new FurnitureMannequinSaveLookComposer(mannequinData.objectId)); + processAction('save_name'); + processAction('close'); + return; + case 'wear': + GetRoomSession().connection.send(new FurnitureMultiStateComposer(mannequinData.objectId)); + processAction('close'); + return; + } + }, [ mannequinData ]); + + const handleKeyDown = (event: KeyboardEvent) => + { + if(event.key !== 'Enter') return; + + processAction('save_name'); }; - useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, onRoomEngineObjectEvent); + if(!mannequinData) return null; - return null; + return ( + + processAction('close') } /> + +
+
+
+ +
+
+
+ { viewMode === FurnitureMannequinViewMode.EDIT && <> + processAction('set_name', event.target.value) } onKeyDown={ event => handleKeyDown(event) } /> +
processAction('load_figure') }>{ LocalizeText('mannequin.widget.style') }
+
processAction('wear') }>{ LocalizeText('mannequin.widget.wear') }
+ } + { viewMode === FurnitureMannequinViewMode.SAVE && <> +
+
+
{ mannequinData.name }
+
{ LocalizeText('mannequin.widget.savetext') }
+
+
+
processAction('back') }>{ LocalizeText('mannequin.widget.back') }
+
processAction('save_figure') }>{ LocalizeText('mannequin.widget.save') }
+
+
+ } + { viewMode === FurnitureMannequinViewMode.DEFAULT && <> +
+
+
{ mannequinData.name }
+
{ LocalizeText('mannequin.widget.weartext') }
+
+
processAction('wear') }>{ LocalizeText('mannequin.widget.wear') }
+
+ } + { viewMode === FurnitureMannequinViewMode.CLUB && <> +
{ LocalizeText('mannequin.widget.clubnotification') }
+ } + { viewMode === FurnitureMannequinViewMode.INCOMPATIBLE_GENDER && <> +
{ LocalizeText('mannequin.widget.wronggender') }
+ } +
+
+
+
+ ); } diff --git a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.types.tsx b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.types.tsx index b4e5e0ff..eae1f80c 100644 --- a/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.types.tsx +++ b/src/views/room/widgets/furniture/mannequin/FurnitureMannequinView.types.tsx @@ -1,6 +1,13 @@ import { FurnitureWidgetProps } from '../FurnitureWidget.types'; export interface FurnitureMannequinViewProps extends FurnitureWidgetProps -{ +{} +export class FurnitureMannequinViewMode +{ + public static readonly EDIT: string = 'edit'; + public static readonly SAVE: string = 'save'; + public static readonly CLUB: string = 'club'; + public static readonly DEFAULT: string = 'default'; + public static readonly INCOMPATIBLE_GENDER: string = 'incompatible_gender'; }