Lots of pet updates

This commit is contained in:
Bill 2021-07-09 13:29:00 -04:00
parent 2f96c83c44
commit afa70ff93e
26 changed files with 581 additions and 61 deletions

View File

@ -0,0 +1,22 @@
import { IFurnitureData, RoomObjectCategory, RoomObjectVariable } from 'nitro-renderer';
import { GetRoomEngine } from '../room';
import { GetSessionDataManager } from './GetSessionDataManager';
export function GetFurnitureDataForRoomObject(roomId: number, objectId: number, category: number): IFurnitureData
{
const roomObject = GetRoomEngine().getRoomObject(roomId, objectId, category);
if(!roomObject) return;
const typeId = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_TYPE_ID);
switch(category)
{
case RoomObjectCategory.FLOOR:
return GetSessionDataManager().getFloorItemData(typeId);
case RoomObjectCategory.WALL:
return GetSessionDataManager().getWallItemData(typeId);
}
return null;
}

View File

@ -2,6 +2,7 @@ export * from './CanManipulateFurniture';
export * from './GetCanStandUp';
export * from './GetCanUseExpression';
export * from './GetFurnitureDataForProductOffer';
export * from './GetFurnitureDataForRoomObject';
export * from './GetOwnPosture';
export * from './GetProductDataForLocalization';
export * from './GetRoomSession';

View File

@ -60,7 +60,7 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
roomPreviewer.reset(false);
roomPreviewer.updateRoomWallsAndFloorVisibility(true, true);
roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType);
roomPreviewer.addPetIntoRoom(petData.figureData.figuredata);
roomPreviewer.addPetIntoRoom(petData.figureString);
}, [ roomPreviewer, petItem ]);
if(!petItems || !petItems.length)

View File

@ -39,7 +39,7 @@ export const InventoryPetItemView: FC<InventoryPetItemViewProps> = props =>
return (
<NitroCardGridItemView itemActive={ isActive } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
<PetImageView figure={ petItem.petData.figureData.figuredata } direction={ 3 } headOnly={ true } />
<PetImageView figure={ petItem.petData.figureString } direction={ 3 } headOnly={ true } />
</NitroCardGridItemView>
);
}

View File

@ -1,4 +1,3 @@
import { PetFigureData } from 'nitro-renderer';
import { RoomWidgetUpdateInfostandEvent } from './RoomWidgetUpdateInfostandEvent';
export class RoomWidgetUpdateInfostandPetEvent extends RoomWidgetUpdateInfostandEvent
@ -21,7 +20,7 @@ export class RoomWidgetUpdateInfostandPetEvent extends RoomWidgetUpdateInfostand
public image: HTMLImageElement = null;
public petType: number = 0;
public petBreed: number = 0;
public petFigure: PetFigureData = null;
public petFigure: string = '';
public posture: string = 'std';
public isOwner: boolean = false;
public ownerId: number = -1;

View File

@ -0,0 +1,21 @@
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
import { UseProductItem } from './UseProductItem';
export class RoomWidgetUseProductBubbleEvent extends RoomWidgetUpdateEvent
{
public static USE_PRODUCT_BUBBLES: string = 'RWUPBE_USE_PRODUCT_BUBBLES';
private _items: UseProductItem[];
constructor(type: string, items: UseProductItem[])
{
super(type);
this._items = items;
}
public get items(): UseProductItem[]
{
return this._items;
}
}

View File

@ -0,0 +1,50 @@
export class UseProductItem
{
private _id: number;
private _category: number;
private _name: string;
private _requestRoomObjectId: number;
private _targetRoomObjectId: number;
private _requestInventoryStripId: number;
private _replace: boolean;
constructor(id: number, category: number, name: string, requestRoomObjectId: number, targetRoomObjectId: number, requestInventoryStripId: number, replace: boolean)
{
this._id = id;
this._category = category;
this._name = name;
this._requestRoomObjectId = requestRoomObjectId;
this._requestInventoryStripId = requestInventoryStripId;
this._replace = replace;
}
public get id(): number
{
return this._id;
}
public get category(): number
{
return this._category;
}
public get name(): string
{
return this._name;
}
public get requestRoomObjectId(): number
{
return this._requestRoomObjectId;
}
public get requestInventoryStripId(): number
{
return this._requestInventoryStripId;
}
public get replace(): boolean
{
return this._replace;
}
}

View File

@ -14,3 +14,5 @@ export * from './RoomWidgetUpdateInfostandRentableBotEvent';
export * from './RoomWidgetUpdateInfostandUserEvent';
export * from './RoomWidgetUpdateRentableBotChatEvent';
export * from './RoomWidgetUpdateUserDataEvent';
export * from './RoomWidgetUseProductBubbleEvent';
export * from './UseProductItem';

View File

@ -1,7 +1,8 @@
import { NitroEvent, RoomSessionDanceEvent, RoomSessionUserDataUpdateEvent } from 'nitro-renderer';
import { GetRoomSession, GetSessionDataManager } from '../../../api';
import { RoomWidgetAvatarInfoEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateUserDataEvent } from '../events';
import { RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetRoomObjectMessage, RoomWidgetUserActionMessage } from '../messages';
import { NitroEvent, RoomEngineUseProductEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionDanceEvent, RoomSessionUserDataUpdateEvent } from 'nitro-renderer';
import { GetRoomEngine, GetRoomSession, GetSessionDataManager, IsOwnerOfFurniture } from '../../../api';
import { FurniCategory } from '../../inventory/common/FurniCategory';
import { RoomWidgetAvatarInfoEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateUserDataEvent, RoomWidgetUseProductBubbleEvent, UseProductItem } from '../events';
import { RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetRoomObjectMessage, RoomWidgetUseProductMessage, RoomWidgetUserActionMessage } from '../messages';
import { RoomWidgetHandler } from './RoomWidgetHandler';
export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
@ -24,6 +25,11 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateDanceStatusEvent(isDancing));
return;
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY:
return;
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM:
this.processUsableRoomObject((event as RoomEngineUseProductEvent).objectId);
return;
}
}
@ -56,6 +62,12 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
GetRoomSession().sendPostureMessage(postureMessage.posture);
break;
}
case RoomWidgetUseProductMessage.PET_PRODUCT: {
const productMessage = (message as RoomWidgetUseProductMessage);
GetRoomSession().usePetProduct(productMessage.objectId, productMessage.petId);
break;
}
}
return null;
@ -71,11 +83,81 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
if(userData) this.container.eventDispatcher.dispatchEvent(new RoomWidgetAvatarInfoEvent(userId, userName, userData.type, userData.roomIndex, allowNameChange));
}
private processUsableRoomObject(objectId: number): void
{
const roomId = this.container.roomSession.roomId;
const roomObject = GetRoomEngine().getRoomObject(roomId, objectId, RoomObjectCategory.FLOOR);
if(!roomObject || !IsOwnerOfFurniture(roomObject)) return;
const ownerId = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
const typeId = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_TYPE_ID);
const furniData = GetSessionDataManager().getFloorItemData(typeId);
const parts = furniData.customParams.split(' ');
const part = (parts.length ? parseInt(parts[0]) : -1);
if(part === -1) return;
this.processUseableProduct(roomId, objectId, part, furniData.specialType, ownerId);
}
private processUseableProduct(roomId: number, objectId: number, part: number, specialType: number, ownerId: number, arg6 = -1): void
{
const useProductBubbles: UseProductItem[] = [];
const roomObjects = GetRoomEngine().getRoomObjects(roomId, RoomObjectCategory.UNIT);
for(const roomObject of roomObjects)
{
const userData = this.container.roomSession.userDataManager.getUserDataByIndex(roomObject.id);
let replace = false;
if(!userData || (userData.type !== RoomObjectType.PET))
{
}
else
{
if(userData.ownerId === ownerId)
{
if(userData.hasSaddle && (specialType === FurniCategory._Str_6096)) replace = true;
const figureParts = userData.figure.split(' ');
const figurePart = (figureParts.length ? parseInt(figureParts[0]) : -1);
if(figurePart === part)
{
if(specialType === FurniCategory._Str_6915)
{
if(!userData.canRevive) continue;
}
if(specialType === FurniCategory._Str_8726)
{
if((userData.petLevel < 7) || userData.canRevive || userData.canBreed) continue;
}
if(specialType === FurniCategory._Str_9449)
{
if((userData.petLevel >= 7) || userData.canRevive) continue;
}
useProductBubbles.push(new UseProductItem(userData.roomIndex, RoomObjectCategory.UNIT, userData.name, objectId, roomObject.id, arg6, replace));
}
}
}
}
if(useProductBubbles.length) this.container.eventDispatcher.dispatchEvent(new RoomWidgetUseProductBubbleEvent(RoomWidgetUseProductBubbleEvent.USE_PRODUCT_BUBBLES, useProductBubbles));
}
public get eventTypes(): string[]
{
return [
RoomSessionUserDataUpdateEvent.USER_DATA_UPDATED,
RoomSessionDanceEvent.RSDE_DANCE
RoomSessionDanceEvent.RSDE_DANCE,
RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY,
RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM
];
}
@ -85,7 +167,9 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
RoomWidgetRoomObjectMessage.GET_OWN_CHARACTER_INFO,
RoomWidgetDanceMessage.DANCE,
RoomWidgetAvatarExpressionMessage.AVATAR_EXPRESSION,
RoomWidgetChangePostureMessage.CHANGE_POSTURE
RoomWidgetChangePostureMessage.CHANGE_POSTURE,
RoomWidgetUseProductMessage.PET_PRODUCT,
RoomWidgetUseProductMessage.MONSTERPLANT_SEED
];
}
}

View File

@ -7,7 +7,7 @@ import { SendMessageHook } from '../../../hooks/messages';
import { LocalizeText } from '../../../utils/LocalizeText';
import { RoomWidgetObjectNameEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events';
import { RoomWidgetChangeMottoMessage, RoomWidgetFurniActionMessage, RoomWidgetMessage, RoomWidgetRoomObjectMessage, RoomWidgetUserActionMessage } from '../messages';
import { PetSupplementEnum } from '../widgets/avatar-info/utils/PetSupplementEnum';
import { PetSupplementEnum } from '../widgets/avatar-info/common/PetSupplementEnum';
import { RoomWidgetHandler } from './RoomWidgetHandler';
export class RoomWidgetInfostandHandler extends RoomWidgetHandler
@ -128,18 +128,18 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
case RoomWidgetUserActionMessage.MOUNT_PET:
this.container.roomSession.mountPet(userId);
break;
// case RoomWidgetUserActionMessage.RWUAM_TOGGLE_PET_RIDING_PERMISSION:
// this._container.roomSession._Str_21025(_local_2);
// break;
// case RoomWidgetUserActionMessage.RWUAM_TOGGLE_PET_BREEDING_PERMISSION:
// this._container.roomSession._Str_21562(_local_2);
// break;
case RoomWidgetUserActionMessage.TOGGLE_PET_RIDING_PERMISSION:
this.container.roomSession.togglePetRiding(userId);
break;
case RoomWidgetUserActionMessage.TOGGLE_PET_BREEDING_PERMISSION:
this.container.roomSession.togglePetBreeding(userId);
break;
case RoomWidgetUserActionMessage.DISMOUNT_PET:
this.container.roomSession.dismountPet(userId);
break;
// case RoomWidgetUserActionMessage.RWUAM_SADDLE_OFF:
// this._container.roomSession._Str_21635(_local_2);
// break;
case RoomWidgetUserActionMessage.SADDLE_OFF:
this.container.roomSession.removePetSaddle(userId);
break;
case RoomWidgetUserActionMessage.PASS_CARRY_ITEM:
SendMessageHook(new RoomUnitGiveHandItemComposer(userId));
break;
@ -620,7 +620,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
infostandEvent.rarityLevel = petData.rarityLevel;
infostandEvent.petType = figure.typeId;
infostandEvent.petBreed = figure.paletteId;
infostandEvent.petFigure = figure;
infostandEvent.petFigure = roomPetData.figure;
infostandEvent.posture = posture;
infostandEvent.isOwner = isOwner;
infostandEvent.roomIndex = roomPetData.roomIndex;

View File

@ -0,0 +1,28 @@
import { RoomWidgetMessage } from './RoomWidgetMessage';
export class RoomWidgetUseProductMessage extends RoomWidgetMessage
{
public static PET_PRODUCT: string = 'RWUPM_PET_PRODUCT';
public static MONSTERPLANT_SEED: string = 'RWUPM_MONSTERPLANT_SEED';
private _objectId: number;
public _petId: number;
constructor(type: string, objectId: number, petId: number = -1)
{
super(type);
this._objectId = objectId;
this._petId = petId;
}
public get objectId(): number
{
return this._objectId;
}
public get petId(): number
{
return this._petId;
}
}

View File

@ -9,4 +9,5 @@ export * from './RoomWidgetFurniActionMessage';
export * from './RoomWidgetMessage';
export * from './RoomWidgetRequestWidgetMessage';
export * from './RoomWidgetRoomObjectMessage';
export * from './RoomWidgetUseProductMessage';
export * from './RoomWidgetUserActionMessage';

View File

@ -1,6 +1,6 @@
import { RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent } from 'nitro-renderer';
import { NitroEvent, RoomEngineUseProductEvent, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent } from 'nitro-renderer';
import { FC, useCallback } from 'react';
import { useRoomSessionManagerEvent } from '../../../hooks/events';
import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events';
import { LocalizeText } from '../../../utils/LocalizeText';
import { useRoomContext } from '../context/RoomContext';
import { AvatarInfoWidgetView } from './avatar-info/AvatarInfoWidgetView';
@ -15,24 +15,26 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
{
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
const onNitroEvent = useCallback((event: NitroEvent) =>
{
if(!widgetHandler) return;
widgetHandler.processEvent(event);
}, [ widgetHandler ]);
useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionChatEvent.FLOOD_EVENT, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionDanceEvent.RSDE_DANCE, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionUserBadgesEvent.RSUBE_BADGES, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionDoorbellEvent.DOORBELL, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionDoorbellEvent.RSDE_REJECTED, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionDoorbellEvent.RSDE_ACCEPTED, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionFriendRequestEvent.RSFRE_FRIEND_REQUEST, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionPetInfoUpdateEvent.PET_INFO, onRoomSessionEvent);
useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionChatEvent.FLOOD_EVENT, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionDanceEvent.RSDE_DANCE, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionUserBadgesEvent.RSUBE_BADGES, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionDoorbellEvent.DOORBELL, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionDoorbellEvent.RSDE_REJECTED, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionDoorbellEvent.RSDE_ACCEPTED, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionFriendRequestEvent.RSFRE_FRIEND_REQUEST, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, onNitroEvent);
useRoomSessionManagerEvent(RoomSessionPetInfoUpdateEvent.PET_INFO, onNitroEvent);
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onNitroEvent);
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onNitroEvent);
const onRoomErrorEvent = useCallback((event: RoomSessionEvent) =>
{

View File

@ -5,7 +5,7 @@ import { FriendEnteredRoomEvent } from '../../../../events';
import { useUiEvent } from '../../../../hooks/events';
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
import { useRoomContext } from '../../context/RoomContext';
import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent } from '../../events';
import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent, RoomWidgetUseProductBubbleEvent, UseProductItem } from '../../events';
import { RoomWidgetRoomObjectMessage } from '../../messages';
import { AvatarInfoWidgetViewProps } from './AvatarInfoWidgetView.types';
import { AvatarInfoWidgetAvatarView } from './views/avatar/AvatarInfoWidgetAvatarView';
@ -16,12 +16,16 @@ import { AvatarInfoWidgetOwnPetView } from './views/own-pet/AvatarInfoWidgetOwnP
import { AvatarInfoWidgetPetView } from './views/pet/AvatarInfoWidgetPetView';
import { AvatarInfoRentableBotChatView } from './views/rentable-bot-chat/AvatarInfoRentableBotChatView';
import { AvatarInfoWidgetRentableBotView } from './views/rentable-bot/AvatarInfoWidgetRentableBotView';
import { AvatarInfoUseProductConfirmView } from './views/use-product-confirm/AvatarInfoUseProductConfirmView';
import { AvatarInfoUseProductView } from './views/use-product/AvatarInfoUseProductView';
export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
{
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
const { roomSession = null, eventDispatcher = null, widgetHandler = null } = useRoomContext();
const [ name, setName ] = useState<RoomWidgetObjectNameEvent>(null);
const [ nameBubbles, setNameBubbles ] = useState<RoomWidgetObjectNameEvent[]>([]);
const [ productBubbles, setProductBubbles ] = useState<UseProductItem[]>([]);
const [ confirmingProduct, setConfirmingProduct ] = useState<UseProductItem>(null);
const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null);
const [ isGameMode, setGameMode ] = useState(false);
const [ isDancing, setIsDancing ] = useState(false);
@ -40,6 +44,19 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
});
}, []);
const removeProductBubble = useCallback((index: number) =>
{
setProductBubbles(prevValue =>
{
const newValue = [ ...prevValue ];
const item = newValue.splice(index, 1)[0];
if(confirmingProduct === item) setConfirmingProduct(null);
return newValue;
});
}, [ confirmingProduct ]);
const clearInfoStandEvent = useCallback(() =>
{
setInfoStandEvent(null);
@ -83,6 +100,31 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
});
if(nameBubbleIndex > -1) removeNameBubble(nameBubbleIndex);
if(productBubbles.length)
{
setProductBubbles(prevValue =>
{
return prevValue.filter(bubble =>
{
return (bubble.id !== event.id);
});
});
}
}
else if(event.category === RoomObjectCategory.FLOOR)
{
if(productBubbles.length)
{
setProductBubbles(prevValue =>
{
return prevValue.filter(bubble =>
{
return (bubble.requestRoomObjectId !== event.id);
});
});
}
}
if(infoStandEvent)
@ -102,7 +144,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
if(infoStandEvent.roomIndex === event.id) setInfoStandEvent(null);
}
}
}, [ name, infoStandEvent, nameBubbles, removeNameBubble ]);
}, [ name, infoStandEvent, nameBubbles, productBubbles, removeNameBubble ]);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved);
@ -137,10 +179,9 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
const onObjectDeselected = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
{
if(!infoStandEvent) return;
setInfoStandEvent(null);
}, [ infoStandEvent ]);
if(infoStandEvent) setInfoStandEvent(null);
if(productBubbles.length) setProductBubbles([]);
}, [ infoStandEvent, productBubbles ]);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, eventDispatcher, onObjectDeselected);
@ -182,6 +223,27 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
CreateEventDispatcherHook(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT, eventDispatcher, onRoomWidgetUpdateRentableBotChatEvent);
const onRoomWidgetUseProductBubbleEvent = useCallback((event: RoomWidgetUseProductBubbleEvent) =>
{
setProductBubbles(prevValue =>
{
const newBubbles = [ ...prevValue ];
for(const item of event.items)
{
const index = newBubbles.findIndex(bubble => (bubble.id === item.id));
if(index > -1) newBubbles.splice(index, 1);
newBubbles.push(item);
}
return newBubbles;
});
}, []);
CreateEventDispatcherHook(RoomWidgetUseProductBubbleEvent.USE_PRODUCT_BUBBLES, eventDispatcher, onRoomWidgetUseProductBubbleEvent);
const onFriendEnteredRoomEvent = useCallback((event: FriendEnteredRoomEvent) =>
{
setNameBubbles(prevValue =>
@ -278,7 +340,12 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
{
return <AvatarInfoWidgetNameView key={ index } nameData={ name } close={ () => removeNameBubble(index) } />;
}) }
{ (productBubbles.length > 0) && productBubbles.map((item, index) =>
{
return <AvatarInfoUseProductView key={ item.id } item={ item } setConfirmingProduct={ setConfirmingProduct } close={ () => removeProductBubble(index) } />;
}) }
{ rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> }
{ confirmingProduct && <AvatarInfoUseProductConfirmView item={ confirmingProduct } close={ () => setConfirmingProduct(null) } /> }
</>
)
}

View File

@ -70,18 +70,15 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
break;
case 'pick_up':
messageType = RoomWidgetUserActionMessage.PICKUP_PET;
//this.widget._Str_25401();
break;
case 'mount':
messageType = RoomWidgetUserActionMessage.MOUNT_PET;
break;
case 'toggle_riding_permission':
messageType = RoomWidgetUserActionMessage.TOGGLE_PET_RIDING_PERMISSION;
// update riding checkbox
break;
case 'toggle_breeding_permission':
messageType = RoomWidgetUserActionMessage.TOGGLE_PET_BREEDING_PERMISSION
// update breeding checkbox;
messageType = RoomWidgetUserActionMessage.TOGGLE_PET_BREEDING_PERMISSION;
break;
case 'dismount':
messageType = RoomWidgetUserActionMessage.DISMOUNT_PET;
@ -173,6 +170,7 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
{ LocalizeText('infostand.button.mount') }
</ContextMenuListItemView>
<ContextMenuListItemView onClick={ event => processAction('toggle_riding_permission') }>
<input type="checkbox" className="me-1" checked={ !!petData.publiclyRideable } readOnly={ true } />
{ LocalizeText('infostand.button.toggle_riding_permission') }
</ContextMenuListItemView>
{ (respectsLeft > 0) &&
@ -186,7 +184,7 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
{ LocalizeText('infostand.button.pickup') }
</ContextMenuListItemView>
<ContextMenuListItemView onClick={ event => processAction('saddle_off') }>
{ LocalizeText('infostand.button.saddle_off') }
{ LocalizeText('infostand.button.saddleoff') }
</ContextMenuListItemView>
</> }
{ (mode === _Str_5938) &&
@ -219,6 +217,7 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
{ !petData.dead && (petData.level === petData.maximumLevel) && petData.breedable &&
<>
<ContextMenuListItemView onClick={ event => processAction('toggle_breeding_permission') }>
<input type="checkbox" className="me-1" checked={ petData.publiclyBreedable } readOnly={ true } />
{ LocalizeText('infostand.button.toggle_breeding_permission') }
</ContextMenuListItemView>
<ContextMenuListItemView onClick={ event => processAction('breed') }>

View File

@ -7,7 +7,7 @@ import { RoomWidgetUpdateRentableBotChatEvent } from '../../../../events';
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
import { BotSkillsEnum } from '../../utils/BotSkillsEnum';
import { BotSkillsEnum } from '../../common/BotSkillsEnum';
import { AvatarInfoWidgetRentableBotViewProps } from './AvatarInfoWidgetRentableBotView.types';
const MODE_NORMAL = 0;

View File

@ -0,0 +1,83 @@
import { IFurnitureData, RoomObjectCategory, RoomUserData } from 'nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { GetFurnitureDataForRoomObject } from '../../../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../layout';
import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { FurniCategory } from '../../../../../inventory/common/FurniCategory';
import { useRoomContext } from '../../../../context/RoomContext';
import { RoomWidgetUseProductMessage } from '../../../../messages';
import { AvatarInfoUseProductConfirmViewProps } from './AvatarInfoUseProductConfirmView.types';
const _Str_5091: number = -1;
const _Str_11906: number = 0;
const _Str_11214: number = 1;
const _Str_11733: number = 2;
const _Str_11369: number = 3;
const _Str_8759: number = 4;
const _Str_8432: number = 5;
const _Str_9653: number = 6;
export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmViewProps> = props =>
{
const { item = null, close = null } = props;
const [ mode, setMode ] = useState(_Str_5091);
const [ petData, setPetData ] = useState<RoomUserData>(null);
const [ furniData, setFurniData ] = useState<IFurnitureData>(null);
const { roomSession = null, widgetHandler = null } = useRoomContext();
const useProduct = useCallback(() =>
{
widgetHandler.processWidgetMessage(new RoomWidgetUseProductMessage(RoomWidgetUseProductMessage.PET_PRODUCT, item.requestRoomObjectId, petData.webID));
}, [ widgetHandler, item, petData ]);
useEffect(() =>
{
const userData = roomSession.userDataManager.getUserDataByIndex(item.id);
setPetData(userData);
const furniData = GetFurnitureDataForRoomObject(roomSession.roomId, item.requestRoomObjectId, RoomObjectCategory.FLOOR);
if(!furniData) return;
setFurniData(furniData);
let mode = _Str_5091;
switch(furniData.specialType)
{
case FurniCategory._Str_7696:
mode = _Str_11906;
break;
case FurniCategory._Str_7297:
mode = _Str_11214;
break;
case FurniCategory._Str_7954:
mode = _Str_11733;
break;
case FurniCategory._Str_6096:
mode = _Str_11369;
break;
case FurniCategory._Str_6915:
mode = _Str_8759;
break;
case FurniCategory._Str_8726:
mode = _Str_8432;
break;
case FurniCategory._Str_9449:
mode = _Str_9653;
break;
}
setMode(mode);
}, [ roomSession, item ]);
return (
<NitroCardView>
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title', [ 'name' ], [ petData.name ]) } onCloseClick={ close } />
<NitroCardContentView>
<button type="button" className="btn btn-primary" onClick={ useProduct }>Use it</button>
</NitroCardContentView>
</NitroCardView>
)
}

View File

@ -0,0 +1,7 @@
import { UseProductItem } from '../../../../events';
export interface AvatarInfoUseProductConfirmViewProps
{
item: UseProductItem;
close: () => void;
}

View File

@ -0,0 +1,138 @@
import { RoomObjectCategory } from 'nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { GetFurnitureDataForRoomObject } from '../../../../../../api';
import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { FurniCategory } from '../../../../../inventory/common/FurniCategory';
import { useRoomContext } from '../../../../context/RoomContext';
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
import { AvatarInfoUseProductViewProps } from './AvatarInfoUseProductView.types';
const _Str_2906: number = 0;
const _Str_13718: number = 1;
const _Str_14146: number = 2;
const _Str_15667: number = 3;
const _Str_14658: number = 4;
const _Str_14165: number = 5;
const _Str_12577: number = 6;
const _Str_14611: number = 7;
export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props =>
{
const { item = null, setConfirmingProduct = null, close = null } = props;
const [ mode, setMode ] = useState(0);
const { roomSession = null } = useRoomContext();
useEffect(() =>
{
if(!item) return;
const furniData = GetFurnitureDataForRoomObject(roomSession.roomId, item.requestRoomObjectId, RoomObjectCategory.FLOOR);
if(!furniData) return;
let mode = _Str_2906;
switch(furniData.specialType)
{
case FurniCategory._Str_7696:
mode = _Str_13718;
break;
case FurniCategory._Str_7297:
mode = _Str_14146;
break;
case FurniCategory._Str_7954:
mode = _Str_15667;
break;
case FurniCategory._Str_6096:
mode = _Str_14658;
break;
case FurniCategory._Str_6915:
mode = _Str_14165;
break;
case FurniCategory._Str_8726:
mode = _Str_12577;
break;
case FurniCategory._Str_9449:
mode = _Str_14611;
break;
}
setMode(mode);
}, [ roomSession, item ]);
const processAction = useCallback((name: string) =>
{
let hideMenu = true;
if(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;
}
}
if(hideMenu) close();
}, [ item, setConfirmingProduct, close ]);
return (
<ContextMenuView objectId={ item.id } category={ RoomObjectCategory.UNIT } close={ close }>
<ContextMenuHeaderView>
{ item.name }
</ContextMenuHeaderView>
{ (mode === _Str_2906) &&
<ContextMenuListItemView onClick={ event => processAction('use_product') }>
{ LocalizeText('infostand.button.useproduct') }
</ContextMenuListItemView> }
{ (mode === _Str_13718) &&
<ContextMenuListItemView onClick={ event => processAction('use_product_shampoo') }>
{ LocalizeText('infostand.button.useproduct_shampoo') }
</ContextMenuListItemView> }
{ (mode === _Str_14146) &&
<ContextMenuListItemView onClick={ event => processAction('use_product_custom_part') }>
{ LocalizeText('infostand.button.useproduct_custom_part') }
</ContextMenuListItemView> }
{ (mode === _Str_15667) &&
<ContextMenuListItemView onClick={ event => processAction('use_product_custom_part_shampoo') }>
{ LocalizeText('infostand.button.useproduct_custom_part_shampoo') }
</ContextMenuListItemView> }
{ (mode === _Str_14658) &&
<>
{ item.replace &&
<ContextMenuListItemView onClick={ event => processAction('replace_product_saddle') }>
{ LocalizeText('infostand.button.replaceproduct_saddle') }
</ContextMenuListItemView> }
{ !item.replace &&
<ContextMenuListItemView onClick={ event => processAction('use_product_saddle') }>
{ LocalizeText('infostand.button.useproduct_saddle') }
</ContextMenuListItemView> }
</> }
{ (mode === _Str_14165) &&
<ContextMenuListItemView onClick={ event => processAction('revive_monsterplant') }>
{ LocalizeText('infostand.button.revive_monsterplant') }
</ContextMenuListItemView> }
{ (mode === _Str_12577) &&
<ContextMenuListItemView onClick={ event => processAction('rebreed_monsterplant') }>
{ LocalizeText('infostand.button.rebreed_monsterplant') }
</ContextMenuListItemView> }
{ (mode === _Str_14611) &&
<ContextMenuListItemView onClick={ event => processAction('fertilize_monsterplant') }>
{ LocalizeText('infostand.button.fertilize_monsterplant') }
</ContextMenuListItemView> }
</ContextMenuView>
);
}

View File

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

View File

@ -15,6 +15,7 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
const [ opacity, setOpacity ] = useState(1);
const [ isFading, setIsFading ] = useState(false);
const [ fadeTime, setFadeTime ] = useState(0);
const [ frozen, setFrozen ] = useState(false);
const elementRef = useRef<HTMLDivElement>();
const update = useCallback((time: number) =>
@ -72,13 +73,20 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
useEffect(() =>
{
let added = false;
if(!frozen)
{
added = true;
GetTicker().add(update);
}
return () =>
{
GetTicker().remove(update);
if(added) GetTicker().remove(update);
}
}, [ update ]);
}, [ frozen, update ]);
useEffect(() =>
{
@ -93,7 +101,7 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
}, [ fades ]);
return (
<div ref={ elementRef } className={ `position-absolute nitro-context-menu ${ className }${ (pos.x !== null ? ' visible' : ' invisible') }` } style={ { left: (pos.x || 0), top: (pos.y || 0), opacity: opacity } }>
<div ref={ elementRef } className={ `position-absolute nitro-context-menu ${ className }${ (pos.x !== null ? ' visible' : ' invisible') }` } style={ { left: (pos.x || 0), top: (pos.y || 0), opacity: opacity } } onMouseEnter={ event => setFrozen(true) } onMouseLeave={ event => setFrozen(false) }>
{ children }
</div>
);

View File

@ -14,7 +14,7 @@ export const InfoStandWidgetPetView: FC<InfoStandWidgetPetViewProps> = props =>
<InfoStandBaseView headerText={ <>{ petData.name }<br />{ LocalizeText('pet.breed.' + petData.petType + '.' + petData.petBreed) }</> } onCloseClick={ close }>
<div className="d-flex">
<div className="body-image pet w-100">
<PetImageView typeId={ petData.petType } paletteId={ petData.petBreed } color={ petData.petFigure.color } posture={ petData.posture } direction={ 4 } />
<PetImageView figure={ petData.petFigure } posture={ petData.posture } direction={ 4 } />
</div>
<div className="w-100 d-flex flex-column align-items-center">
<div className="small text-center mb-1">{ LocalizeText('pet.level', ['level', 'maxlevel'], [petData.level.toString(), petData.maximumLevel.toString()]) }</div>

View File

@ -4,7 +4,7 @@ import { SendMessageHook } from '../../../../../../hooks/messages';
import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { AvatarImageView } from '../../../../../shared/avatar-image/AvatarImageView';
import { BadgeImageView } from '../../../../../shared/badge-image/BadgeImageView';
import { BotSkillsEnum } from '../../../avatar-info/utils/BotSkillsEnum';
import { BotSkillsEnum } from '../../../avatar-info/common/BotSkillsEnum';
import { InfoStandBaseView } from '../base/InfoStandBaseView';
import { InfoStandWidgetRentableBotViewProps } from './InfoStandWidgetRentableBotView.types';

View File

@ -1,8 +1,8 @@
import { ConditionDefinition, Triggerable, TriggerDefinition, UpdateActionMessageComposer, UpdateConditionMessageComposer, UpdateTriggerMessageComposer, WiredActionDefinition } from 'nitro-renderer';
import { FC, useCallback, useMemo, useState } from 'react';
import { GetConnection } from '../../api';
import { WiredEvent } from '../../events';
import { useUiEvent } from '../../hooks/events';
import { SendMessageHook } from '../../hooks/messages';
import { GetWiredLayout } from './common/GetWiredLayout';
import { WiredContextProvider } from './context/WiredContext';
import { WiredMessageHandler } from './WiredMessageHandler';
@ -27,18 +27,17 @@ export const WiredView: FC<WiredFurniSelectorViewProps> = props =>
if(trigger instanceof WiredActionDefinition)
{
GetConnection().send(new UpdateActionMessageComposer(trigger.id, intParams, stringParam, furniIds, actionDelay, trigger.stuffTypeSelectionCode));
SendMessageHook(new UpdateActionMessageComposer(trigger.id, intParams, stringParam, furniIds, actionDelay, trigger.stuffTypeSelectionCode));
}
else if(trigger instanceof TriggerDefinition)
{
console.log(intParams, stringParam);
GetConnection().send(new UpdateTriggerMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode));
SendMessageHook(new UpdateTriggerMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode));
}
else if(trigger instanceof ConditionDefinition)
{
GetConnection().send(new UpdateConditionMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode));
SendMessageHook(new UpdateConditionMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode));
}
}, [ trigger, intParams, stringParam, furniIds, actionDelay ]);