Update avatar info use product

This commit is contained in:
Bill 2021-07-11 02:37:56 -04:00
parent afa70ff93e
commit 2f1bbf83f9
10 changed files with 250 additions and 41 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,3 +1,4 @@
@import './avatar-info/AvatarInfoWidgetView';
@import './camera/CameraWidgetView';
@import './chat/ChatWidgetView';
@import './chat-input/ChatInputView';

View File

@ -0,0 +1,13 @@
.nitro-use-product-confirmation {
.product-preview {
width: 122px;
height: 130px;
background: url('../../../../assets/images/room-widgets/avatar-info/preview-background.png') no-repeat center;
.pet-image {
width: 122px;
height: 130px;
}
}
}

View File

@ -57,6 +57,11 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
});
}, [ confirmingProduct ]);
const clearProductBubbles = useCallback(() =>
{
setProductBubbles([]);
}, []);
const clearInfoStandEvent = useCallback(() =>
{
setInfoStandEvent(null);
@ -67,6 +72,12 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
setName(null);
}, []);
const updateConfirmingProduct = useCallback((product: UseProductItem) =>
{
setConfirmingProduct(product);
setProductBubbles([]);
}, []);
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) =>
{
switch(event.type)
@ -131,20 +142,20 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
{
if(infoStandEvent instanceof RoomWidgetUpdateInfostandFurniEvent)
{
if(infoStandEvent.id === event.id) setInfoStandEvent(null);
if(infoStandEvent.id === event.id) clearInfoStandEvent();
}
else if((infoStandEvent instanceof RoomWidgetUpdateInfostandUserEvent) || (infoStandEvent instanceof RoomWidgetUpdateInfostandRentableBotEvent))
{
if(infoStandEvent.roomIndex === event.id) setInfoStandEvent(null);
if(infoStandEvent.roomIndex === event.id) clearInfoStandEvent();
}
else if(infoStandEvent instanceof RoomWidgetUpdateInfostandPetEvent)
{
if(infoStandEvent.roomIndex === event.id) setInfoStandEvent(null);
if(infoStandEvent.roomIndex === event.id) clearInfoStandEvent();
}
}
}, [ name, infoStandEvent, nameBubbles, productBubbles, removeNameBubble ]);
}, [ name, infoStandEvent, nameBubbles, productBubbles, removeNameBubble, clearInfoStandEvent ]);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved);
@ -179,9 +190,9 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
const onObjectDeselected = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
{
if(infoStandEvent) setInfoStandEvent(null);
if(infoStandEvent) clearInfoStandEvent();
if(productBubbles.length) setProductBubbles([]);
}, [ infoStandEvent, productBubbles ]);
}, [ infoStandEvent, productBubbles, clearInfoStandEvent ]);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, eventDispatcher, onObjectDeselected);
@ -190,7 +201,8 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
if(event.category !== RoomObjectCategory.UNIT) return;
setName(event);
}, []);
clearProductBubbles();
}, [ clearProductBubbles ]);
CreateEventDispatcherHook(RoomWidgetObjectNameEvent.TYPE, eventDispatcher, onRoomWidgetObjectNameEvent);
@ -198,9 +210,11 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
{
if(name) setName(null);
if(event.type === RoomWidgetUpdateInfostandFurniEvent.FURNI) setInfoStandEvent(null);
if(event.type === RoomWidgetUpdateInfostandFurniEvent.FURNI) clearInfoStandEvent();
else setInfoStandEvent(event);
}, [ name ]);
clearProductBubbles();
}, [ name, clearInfoStandEvent, clearProductBubbles ]);
CreateEventDispatcherHook(RoomWidgetUpdateInfostandFurniEvent.FURNI, eventDispatcher, onRoomWidgetUpdateInfostandEvent);
CreateEventDispatcherHook(RoomWidgetUpdateInfostandUserEvent.OWN_USER, eventDispatcher, onRoomWidgetUpdateInfostandEvent);
@ -225,6 +239,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
const onRoomWidgetUseProductBubbleEvent = useCallback((event: RoomWidgetUseProductBubbleEvent) =>
{
setConfirmingProduct(null);
setProductBubbles(prevValue =>
{
const newBubbles = [ ...prevValue ];
@ -342,7 +357,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
}) }
{ (productBubbles.length > 0) && productBubbles.map((item, index) =>
{
return <AvatarInfoUseProductView key={ item.id } item={ item } setConfirmingProduct={ setConfirmingProduct } close={ () => removeProductBubble(index) } />;
return <AvatarInfoUseProductView key={ item.id } item={ item } updateConfirmingProduct={ updateConfirmingProduct } close={ () => removeProductBubble(index) } />;
}) }
{ rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> }
{ confirmingProduct && <AvatarInfoUseProductConfirmView item={ confirmingProduct } close={ () => setConfirmingProduct(null) } /> }

View File

@ -1,9 +1,10 @@
import { IFurnitureData, RoomObjectCategory, RoomUserData } from 'nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { GetFurnitureDataForRoomObject } from '../../../../../../api';
import { IFurnitureData, PetCustomPart, PetFigureData, RoomObjectCategory, RoomObjectVariable, RoomUserData } from 'nitro-renderer';
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { GetFurnitureDataForRoomObject, GetRoomEngine } from '../../../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../layout';
import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { FurniCategory } from '../../../../../inventory/common/FurniCategory';
import { PetImageView } from '../../../../../shared/pet-image/PetImageView';
import { useRoomContext } from '../../../../context/RoomContext';
import { RoomWidgetUseProductMessage } from '../../../../messages';
import { AvatarInfoUseProductConfirmViewProps } from './AvatarInfoUseProductConfirmView.types';
@ -28,7 +29,145 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
const useProduct = useCallback(() =>
{
widgetHandler.processWidgetMessage(new RoomWidgetUseProductMessage(RoomWidgetUseProductMessage.PET_PRODUCT, item.requestRoomObjectId, petData.webID));
}, [ widgetHandler, item, petData ]);
close();
}, [ widgetHandler, item, petData, close ]);
const getPetImage = useMemo(() =>
{
if(!petData || !furniData) return null;
const petFigureData = new PetFigureData(petData.figure);
const customParts = furniData.customParams.split(' ');
const petIndex = parseInt(customParts[0]);
switch(furniData.specialType)
{
case FurniCategory._Str_7696: {
if(customParts.length < 2) return null;
const currentPalette = GetRoomEngine().getPetColorResult(petIndex, petFigureData.paletteId);
const possiblePalettes = GetRoomEngine().getPetColorResultsForTag(petIndex, customParts[1]);
let paletteId = -1;
for(const result of possiblePalettes)
{
if(result.breed === currentPalette.breed)
{
paletteId = parseInt(result.id);
break;
}
}
return <PetImageView typeId={ petFigureData.typeId } paletteId={ paletteId } color={ petFigureData.color } customParts={ petFigureData.customParts } direction={ 2 } />
}
case FurniCategory._Str_7297: {
if(customParts.length < 4) return null;
const newCustomParts: PetCustomPart[] = [];
const _local_6 = customParts[1].split(',').map(piece => parseInt(piece));
const _local_7 = customParts[2].split(",").map(piece => parseInt(piece));
const _local_8 = customParts[3].split(",").map(piece => parseInt(piece));
let _local_10 = 0;
while(_local_10 < _local_6.length)
{
const _local_13 = _local_6[_local_10];
const _local_15 = petFigureData.getCustomPart(_local_13);
let _local_12 = _local_8[_local_10];
if (_local_15 != null) _local_12 = _local_15.paletteId;
newCustomParts.push(new PetCustomPart(_local_13, _local_7[_local_10], _local_12));
_local_10++;
}
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
}
case FurniCategory._Str_7954: {
if(customParts.length < 3) return null;
const newCustomParts: PetCustomPart[] = [];
const _local_6 = customParts[1].split(",").map(piece => parseInt(piece));
const _local_8 = customParts[2].split(",").map(piece => parseInt(piece));
let _local_10 = 0;
while(_local_10 < _local_6.length)
{
const _local_13 = _local_6[_local_10];
const _local_15 = petFigureData.getCustomPart(_local_13);
let _local_14 = -1;
if(_local_15 != null) _local_14 = _local_15.partId;
newCustomParts.push(new PetCustomPart(_local_6[_local_10], _local_14, _local_8[_local_10]));
_local_10++;
}
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
}
case FurniCategory._Str_6096: {
if(customParts.length < 4) return null;
const newCustomParts: PetCustomPart[] = [];
const _local_6 = customParts[1].split(',').map(piece => parseInt(piece));
const _local_7 = customParts[2].split(",").map(piece => parseInt(piece));
const _local_8 = customParts[3].split(",").map(piece => parseInt(piece));
let _local_10 = 0;
while(_local_10 < _local_6.length)
{
newCustomParts.push(new PetCustomPart(_local_6[_local_10], _local_7[_local_10], _local_8[_local_10]));
_local_10++;
}
for(const _local_21 of petFigureData.customParts)
{
if(_local_6.indexOf(_local_21.layerId) === -1)
{
newCustomParts.push(_local_21);
}
}
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
}
case FurniCategory._Str_8726:
case FurniCategory._Str_6915:
case FurniCategory._Str_9449: {
let posture = 'rip';
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, petData.roomIndex, RoomObjectCategory.UNIT);
if(roomObject)
{
posture = roomObject.model.getValue<string>(RoomObjectVariable.FIGURE_POSTURE);
if(posture === 'rip')
{
const level = petData.petLevel;
if(level < 7) posture = `grw${ level }`;
else posture = 'std';
}
}
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ petFigureData.customParts } posture={ posture } direction={ 2 } />;
}
}
}, [ petData, furniData, roomSession ]);
useEffect(() =>
{
@ -72,11 +211,60 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
setMode(mode);
}, [ roomSession, item ]);
if(!petData) return null;
return (
<NitroCardView>
<NitroCardView className="nitro-use-product-confirmation">
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title', [ 'name' ], [ petData.name ]) } onCloseClick={ close } />
<NitroCardContentView>
<button type="button" className="btn btn-primary" onClick={ useProduct }>Use it</button>
<div className="d-flex">
<div className="product-preview">
{ getPetImage }
</div>
<div className="d-flex flex-column ms-2 mt-2">
<div className="d-flex flex-column justify-content-center align-items-center w-100 h-100">
{ (mode === _Str_11906) &&
<>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.shampoo', [ 'productName' ], [ furniData.name ] ) }</div>
<div className="text-black text-italics">{ LocalizeText('useproduct.widget.info.shampoo') }</div>
</> }
{ (mode === _Str_11214) &&
<>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.custompart', [ 'productName' ], [ furniData.name ] ) }</div>
<div className="text-black text-italics">{ LocalizeText('useproduct.widget.info.custompart') }</div>
</> }
{ (mode === _Str_11733) &&
<>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.custompartshampoo', [ 'productName' ], [ furniData.name ] ) }</div>
<div className="text-black text-italics">{ LocalizeText('useproduct.widget.info.custompartshampoo') }</div>
</> }
{ (mode === _Str_11369) &&
<>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.saddle', [ 'productName' ], [ furniData.name ] ) }</div>
<div className="text-black text-italics">{ LocalizeText('useproduct.widget.info.saddle') }</div>
</> }
{ (mode === _Str_8759) &&
<>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.revive_monsterplant', [ 'productName' ], [ furniData.name ] ) }</div>
<div className="text-black text-italics">{ LocalizeText('useproduct.widget.info.revive_monsterplant') }</div>
</> }
{ (mode === _Str_8432) &&
<>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.rebreed_monsterplant', [ 'productName' ], [ furniData.name ] ) }</div>
<div className="text-black text-italics">{ LocalizeText('useproduct.widget.info.rebreed_monsterplant') }</div>
</> }
{ (mode === _Str_9653) &&
<>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.fertilize_monsterplant', [ 'productName' ], [ furniData.name ] ) }</div>
<div className="text-black text-italics">{ LocalizeText('useproduct.widget.info.fertilize_monsterplant') }</div>
</> }
</div>
<div className="d-flex justify-content-between align-items-center w-100">
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</button>
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('useproduct.widget.use') }</button>
</div>
</div>
</div>
</NitroCardContentView>
</NitroCardView>
)

View File

@ -20,7 +20,7 @@ const _Str_14611: number = 7;
export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props =>
{
const { item = null, setConfirmingProduct = null, close = null } = props;
const { item = null, updateConfirmingProduct = null, close = null } = props;
const [ mode, setMode ] = useState(0);
const { roomSession = null } = useRoomContext();
@ -64,30 +64,23 @@ export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props
const processAction = useCallback((name: string) =>
{
let hideMenu = true;
if(name)
if(!name) return;
switch(name)
{
switch(name)
{
case 'use_product':
case 'use_product_shampoo':
case 'use_product_custom_part':
case 'use_product_custom_part_shampoo':
case 'use_product_saddle':
case 'replace_product_saddle':
case 'revive_monsterplant':
case 'rebreed_monsterplant':
case 'fertilize_monsterplant':
setConfirmingProduct(item);
break;
default:
break;
}
case 'use_product':
case 'use_product_shampoo':
case 'use_product_custom_part':
case 'use_product_custom_part_shampoo':
case 'use_product_saddle':
case 'replace_product_saddle':
case 'revive_monsterplant':
case 'rebreed_monsterplant':
case 'fertilize_monsterplant':
updateConfirmingProduct(item);
break;
}
if(hideMenu) close();
}, [ item, setConfirmingProduct, close ]);
}, [ item, updateConfirmingProduct ]);
return (
<ContextMenuView objectId={ item.id } category={ RoomObjectCategory.UNIT } close={ close }>

View File

@ -1,9 +1,8 @@
import { Dispatch, SetStateAction } from 'react';
import { UseProductItem } from '../../../../events';
export interface AvatarInfoUseProductViewProps
{
item: UseProductItem;
setConfirmingProduct: Dispatch<SetStateAction<UseProductItem>>;
updateConfirmingProduct: (product: UseProductItem) => void;
close: () => void;
}