mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-26 23:50:52 +01:00
More catalog changes
This commit is contained in:
parent
5426de9708
commit
c45a8030b4
@ -10,7 +10,7 @@ import { MarketplacePostOfferView } from './views/page/layout/marketplace/Market
|
||||
|
||||
export const CatalogView: FC<{}> = props =>
|
||||
{
|
||||
const { isVisible = false, setIsVisible = null, rootNode = null, currentPage = null, navigationHidden = false, setNavigationHidden = null, activeNodes = [], searchResult = null, setSearchResult = null, getNodeById = null, openPageByName = null, openPageByOfferId = null, activateNode = null } = useCatalog();
|
||||
const { isVisible = false, setIsVisible = null, rootNode = null, currentPage = null, navigationHidden = false, setNavigationHidden = null, activeNodes = [], searchResult = null, setSearchResult = null, openPageByName = null, openPageByOfferId = null, activateNode = null } = useCatalog();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer';
|
||||
import { GiftReceiverNotFoundEvent, PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer';
|
||||
import classNames from 'classnames';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText, ProductTypeEnum, SendMessageComposer } from '../../../../api';
|
||||
import { Base, Button, ButtonGroup, Column, Flex, FormGroup, LayoutCurrencyIcon, LayoutFurniImageView, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||
import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent } from '../../../../events';
|
||||
import { useCatalog, UseUiEvent } from '../../../../hooks';
|
||||
import { useCatalog, UseMessageEventHook, UseUiEvent } from '../../../../hooks';
|
||||
|
||||
export const CatalogGiftView: FC<{}> = props =>
|
||||
{
|
||||
@ -58,15 +58,11 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
setExtraData(castedEvent.extraData);
|
||||
setIsVisible(true);
|
||||
return;
|
||||
case CatalogEvent.GIFT_RECEIVER_NOT_FOUND:
|
||||
setReceiverNotFound(true);
|
||||
return;
|
||||
}
|
||||
}, [ close ]);
|
||||
|
||||
UseUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, onCatalogEvent);
|
||||
UseUiEvent(CatalogEvent.INIT_GIFT, onCatalogEvent);
|
||||
UseUiEvent(CatalogEvent.GIFT_RECEIVER_NOT_FOUND, onCatalogEvent);
|
||||
|
||||
const isBoxDefault = useMemo(() =>
|
||||
{
|
||||
@ -117,6 +113,13 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
}
|
||||
}, [ extraData, maxBoxIndex, maxRibbonIndex, message, offerId, pageId, receiverName, selectedBoxIndex, selectedColorId, selectedRibbonIndex, showMyFace ]);
|
||||
|
||||
const onGiftReceiverNotFoundEvent = useCallback(() =>
|
||||
{
|
||||
setReceiverNotFound(true);
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(GiftReceiverNotFoundEvent, onGiftReceiverNotFoundEvent);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setReceiverNotFound(false);
|
||||
|
@ -2,7 +2,7 @@ import { MouseEventType } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, useMemo, useState } from 'react';
|
||||
import { IPurchasableOffer, Offer, ProductTypeEnum } from '../../../../../api';
|
||||
import { LayoutAvatarImageView, LayoutGridItem, LayoutGridItemProps } from '../../../../../common';
|
||||
import { useCatalog } from '../../../../../hooks';
|
||||
import { useCatalog, useInventoryFurni } from '../../../../../hooks';
|
||||
|
||||
interface CatalogGridOfferViewProps extends LayoutGridItemProps
|
||||
{
|
||||
@ -15,6 +15,7 @@ export const CatalogGridOfferView: FC<CatalogGridOfferViewProps> = props =>
|
||||
const { offer = null, selectOffer = null, itemActive = false, ...rest } = props;
|
||||
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||
const { requestOfferToMover = null } = useCatalog();
|
||||
const { isVisible = false } = useInventoryFurni();
|
||||
|
||||
const iconUrl = useMemo(() =>
|
||||
{
|
||||
@ -38,7 +39,7 @@ export const CatalogGridOfferView: FC<CatalogGridOfferViewProps> = props =>
|
||||
setMouseDown(false);
|
||||
return;
|
||||
case MouseEventType.ROLL_OUT:
|
||||
if(!isMouseDown || !itemActive) return;
|
||||
if(!isMouseDown || !itemActive || !isVisible) return;
|
||||
|
||||
requestOfferToMover(offer);
|
||||
return;
|
||||
|
@ -1,67 +0,0 @@
|
||||
import { ApproveNameMessageComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { IPurchasableOffer, LocalizeText, Offer, SendMessageComposer } from '../../../../../../api';
|
||||
import { Column, Flex, LayoutCurrencyIcon, Text } from '../../../../../../common';
|
||||
import { CatalogPurchasedEvent } from '../../../../../../events';
|
||||
import { UseUiEvent } from '../../../../../../hooks';
|
||||
import { CatalogPurchaseWidgetView } from '../../widgets/CatalogPurchaseWidgetView';
|
||||
import { CatalogPetNameApprovalView } from './CatalogPetNameApprovalView';
|
||||
|
||||
export interface CatalogLayoutPetPurchaseViewProps
|
||||
{
|
||||
offer: IPurchasableOffer;
|
||||
pageId: number;
|
||||
extra?: string;
|
||||
}
|
||||
|
||||
export const CatalogLayoutPetPurchaseView: FC<CatalogLayoutPetPurchaseViewProps> = props =>
|
||||
{
|
||||
const { offer = null, pageId = -1, extra = '' } = props;
|
||||
const [ petNameValue, setPetNameValue ] = useState('');
|
||||
const [ nameApproved, setNameApproved ] = useState(false);
|
||||
|
||||
const onCatalogPurchasedEvent = useCallback((event: CatalogPurchasedEvent) =>
|
||||
{
|
||||
setNameApproved(false);
|
||||
}, []);
|
||||
|
||||
UseUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, onCatalogPurchasedEvent);
|
||||
|
||||
const beforePurchase = useCallback(() =>
|
||||
{
|
||||
SendMessageComposer(new ApproveNameMessageComposer(petNameValue, 1));
|
||||
}, [ petNameValue ]);
|
||||
|
||||
const extraData = `${ petNameValue }\n${ extra }`;
|
||||
|
||||
return (
|
||||
<Column fullWidth grow justifyContent="end">
|
||||
<div className="d-flex flex-grow-1 justify-content-center align-items-center">
|
||||
<CatalogPetNameApprovalView petNameValue={ petNameValue } setPetNameValue={ setPetNameValue } nameApproved={ nameApproved } setNameApproved={ setNameApproved } />
|
||||
</div>
|
||||
<Flex alignItems="end">
|
||||
<div className="flex-grow-1 align-items-end">
|
||||
<Text>{ LocalizeText('catalog.bundlewidget.price') }</Text>
|
||||
</div>
|
||||
<Column gap={ 1 }>
|
||||
{ ((offer.priceType === Offer.PRICE_TYPE_CREDITS_ACTIVITYPOINTS) || (offer.priceType === Offer.PRICE_TYPE_CREDITS)) &&
|
||||
<Flex alignItems="center" justifyContent="end" gap={ 1 }>
|
||||
<Text>{ offer.priceInCredits }</Text>
|
||||
<LayoutCurrencyIcon type={ -1 } />
|
||||
</Flex> }
|
||||
{ ((offer.priceType === Offer.PRICE_TYPE_CREDITS_ACTIVITYPOINTS) || (offer.priceType === Offer.PRICE_TYPE_ACTIVITYPOINTS)) &&
|
||||
<Flex alignItems="center" justifyContent="end" gap={ 1 }>
|
||||
<Text>{ offer.priceInActivityPoints }</Text>
|
||||
<LayoutCurrencyIcon type={ offer.activityPointType } />
|
||||
</Flex> }
|
||||
</Column>
|
||||
</Flex>
|
||||
<Column gap={ 1 }>
|
||||
<CatalogPurchaseWidgetView />
|
||||
{ /* <CatalogPurchaseButtonView offer={ offer } pageId={ pageId } extra={ extraData } quantity={ 1 } isPurchaseAllowed={ nameApproved } beforePurchase={ beforePurchase } />
|
||||
{ offer.giftable &&
|
||||
<CatalogPurchaseGiftButtonView offer={ offer } pageId={ pageId } extra={ extraData } disabled={ nameApproved } /> } */ }
|
||||
</Column>
|
||||
</Column>
|
||||
);
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { ApproveNameMessageComposer, ColorConverter, GetSellablePetPalettesComposer, PurchaseFromCatalogComposer, SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
import { ApproveNameMessageComposer, ApproveNameMessageEvent, ColorConverter, GetSellablePetPalettesComposer, PurchaseFromCatalogComposer, SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { GetPetAvailableColors, GetPetIndexFromLocalization, LocalizeText, SendMessageComposer } from '../../../../../../api';
|
||||
import { AutoGrid, Base, Button, Column, Flex, Grid, LayoutGridItem, LayoutPetImageView, Text } from '../../../../../../common';
|
||||
import { CatalogNameResultEvent, CatalogPurchaseFailureEvent, CatalogWidgetEvent } from '../../../../../../events';
|
||||
import { DispatchUiEvent, useCatalog, UseUiEvent } from '../../../../../../hooks';
|
||||
import { CatalogPurchaseFailureEvent } from '../../../../../../events';
|
||||
import { DispatchUiEvent, useCatalog, UseMessageEventHook } from '../../../../../../hooks';
|
||||
import { CatalogAddOnBadgeWidgetView } from '../../widgets/CatalogAddOnBadgeWidgetView';
|
||||
import { CatalogPurchaseWidgetView } from '../../widgets/CatalogPurchaseWidgetView';
|
||||
import { CatalogTotalPriceWidget } from '../../widgets/CatalogTotalPriceWidget';
|
||||
@ -104,15 +104,17 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
}
|
||||
}, [ page, currentOffer, petName, petPurchaseString, approvalResult ]);
|
||||
|
||||
const onCatalogNameResultEvent = useCallback((event: CatalogNameResultEvent) =>
|
||||
const onApproveNameMessageEvent = useCallback((event: ApproveNameMessageEvent) =>
|
||||
{
|
||||
setApprovalResult(event.result);
|
||||
const parser = event.getParser();
|
||||
|
||||
if(event.result === 0) purchasePet();
|
||||
setApprovalResult(parser.result);
|
||||
|
||||
if(parser.result === 0) purchasePet();
|
||||
else DispatchUiEvent(new CatalogPurchaseFailureEvent(-1));
|
||||
}, [ purchasePet ]);
|
||||
|
||||
UseUiEvent(CatalogWidgetEvent.APPROVE_RESULT, onCatalogNameResultEvent);
|
||||
UseMessageEventHook(ApproveNameMessageEvent, onApproveNameMessageEvent);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
|
@ -1,68 +0,0 @@
|
||||
import { Dispatch, FC, SetStateAction, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { CatalogEvent, CatalogNameResultEvent } from '../../../../../../events';
|
||||
import { UseUiEvent } from '../../../../../../hooks';
|
||||
|
||||
export interface CatalogPetNameApprovalViewProps
|
||||
{
|
||||
petNameValue: string;
|
||||
setPetNameValue: Dispatch<SetStateAction<string>>;
|
||||
nameApproved: boolean;
|
||||
setNameApproved: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
export const CatalogPetNameApprovalView: FC<CatalogPetNameApprovalViewProps> = props =>
|
||||
{
|
||||
const { petNameValue = null, setPetNameValue = null, nameApproved = false, setNameApproved = null } = props;
|
||||
const [ validationResult, setValidationResult ] = useState(-1);
|
||||
|
||||
const onCatalogNameResultEvent = useCallback((event: CatalogNameResultEvent) =>
|
||||
{
|
||||
if(event.result === 0)
|
||||
{
|
||||
setNameApproved(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setValidationResult(event.result);
|
||||
}, [ setNameApproved ]);
|
||||
|
||||
UseUiEvent(CatalogEvent.APPROVE_NAME_RESULT, onCatalogNameResultEvent);
|
||||
|
||||
const validationErrorMessage = () =>
|
||||
{
|
||||
let key: string = '';
|
||||
|
||||
switch(validationResult)
|
||||
{
|
||||
case 1:
|
||||
key = 'catalog.alert.petname.long';
|
||||
break;
|
||||
case 2:
|
||||
key = 'catalog.alert.petname.short';
|
||||
break;
|
||||
case 3:
|
||||
key = 'catalog.alert.petname.chars';
|
||||
break;
|
||||
case 4:
|
||||
key = 'catalog.alert.petname.bobba';
|
||||
break;
|
||||
}
|
||||
|
||||
return LocalizeText(key);
|
||||
}
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setValidationResult(-1);
|
||||
}, [ petNameValue ]);
|
||||
|
||||
return (
|
||||
<div className="input-group has-validation">
|
||||
<input type="text" className={ 'form-control form-control-sm '+ ((validationResult > 0) ? 'is-invalid ' : '') } placeholder={ LocalizeText('widgets.petpackage.name.title') } value={ petNameValue } onChange={ event => setPetNameValue(event.target.value) } />
|
||||
{ (validationResult > 0) &&
|
||||
<div className="invalid-feedback">{ validationErrorMessage }</div> }
|
||||
</div>
|
||||
);
|
||||
}
|
@ -7,7 +7,6 @@ export class CatalogEvent extends NitroEvent
|
||||
public static TOGGLE_CATALOG: string = 'CE_TOGGLE_CATALOG';
|
||||
public static SOLD_OUT: string = 'CE_SOLD_OUT';
|
||||
public static APPROVE_NAME_RESULT: string = 'CE_APPROVE_NAME_RESULT';
|
||||
public static GIFT_RECEIVER_NOT_FOUND: string = 'CE_GIFT_RECEIVER_NOT_FOUND';
|
||||
public static PURCHASE_APPROVED: string = 'CE_PURCHASE_APPROVED';
|
||||
public static INIT_GIFT: string = 'CE_INIT_GIFT';
|
||||
public static CATALOG_RESET: string = 'CE_RESET';
|
||||
|
@ -1,9 +0,0 @@
|
||||
import { CatalogEvent } from './CatalogEvent';
|
||||
|
||||
export class CatalogGiftReceiverNotFoundEvent extends CatalogEvent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super(CatalogEvent.GIFT_RECEIVER_NOT_FOUND);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||
import { CatalogWidgetEvent } from './CatalogWidgetEvent';
|
||||
|
||||
export class CatalogNameResultEvent extends NitroEvent
|
||||
{
|
||||
private _result: number;
|
||||
private _validationInfo: string;
|
||||
|
||||
constructor(result: number, validationInfo: string)
|
||||
{
|
||||
super(CatalogWidgetEvent.APPROVE_RESULT);
|
||||
|
||||
this._result = result;
|
||||
this._validationInfo = validationInfo;
|
||||
}
|
||||
|
||||
public get result(): number
|
||||
{
|
||||
return this._result;
|
||||
}
|
||||
|
||||
public get validationInfo(): string
|
||||
{
|
||||
return this._validationInfo;
|
||||
}
|
||||
}
|
@ -11,7 +11,6 @@ export class CatalogWidgetEvent extends NitroEvent
|
||||
public static COLOUR_INDEX: string = 'CWE_COLOUR_INDEX';
|
||||
public static TEXT_INPUT: string = 'CWE_TEXT_INPUT';
|
||||
public static DROPMENU_SELECT: string = 'CWE_CWE_DROPMENU_SELECT';
|
||||
public static APPROVE_RESULT: string = 'CWE_CWE_APPROVE_RESULT';
|
||||
public static PURCHASE_OVERRIDE: string = 'CWE_PURCHASE_OVERRIDE';
|
||||
public static SELLABLE_PET_PALETTES: string = 'CWE_SELLABLE_PET_PALETTES';
|
||||
public static UPDATE_ROOM_PREVIEW: string = 'CWE_UPDATE_ROOM_PREVIEW';
|
||||
|
@ -1,7 +1,5 @@
|
||||
export * from './CatalogEvent';
|
||||
export * from './CatalogGiftReceiverNotFoundEvent';
|
||||
export * from './CatalogInitGiftEvent';
|
||||
export * from './CatalogNameResultEvent';
|
||||
export * from './CatalogPostMarketplaceOfferEvent';
|
||||
export * from './CatalogPurchasedEvent';
|
||||
export * from './CatalogPurchaseFailureEvent';
|
||||
|
@ -1,5 +1,3 @@
|
||||
export * from './useCatalog';
|
||||
export * from './useCatalogBuildersClub';
|
||||
export * from './useCatalogItemMover';
|
||||
export * from './useCatalogPlaceMultipleItems';
|
||||
export * from './useCatalogSkipPurchaseConfirmation';
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { ApproveNameMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, ClubGiftInfoEvent, FrontPageItem, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetGiftWrappingConfigurationComposer, GiftReceiverNotFoundEvent, GiftWrappingConfigurationEvent, GuildMembershipsMessageEvent, HabboClubOffersMessageEvent, LimitedEditionSoldOutEvent, MarketplaceMakeOfferResult, NodeData, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, RoomPreviewer, SellablePetPalettesMessageEvent } from '@nitrots/nitro-renderer';
|
||||
import { BuildersClubFurniCountMessageEvent, BuildersClubPlaceRoomItemMessageComposer, BuildersClubPlaceWallItemMessageComposer, BuildersClubQueryFurniCountMessageComposer, BuildersClubSubscriptionStatusMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, ClubGiftInfoEvent, FrontPageItem, FurniturePlaceComposer, FurniturePlacePaintComposer, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetGiftWrappingConfigurationComposer, GiftWrappingConfigurationEvent, GuildMembershipsMessageEvent, HabboClubOffersMessageEvent, LegacyDataType, LimitedEditionSoldOutEvent, MarketplaceMakeOfferResult, NodeData, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseFromCatalogComposer, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, RoomControllerLevel, RoomEngineObjectPlacedEvent, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType, RoomObjectVariable, RoomPreviewer, SellablePetPalettesMessageEvent, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useBetween } from 'use-between';
|
||||
import { CatalogNode, CatalogPage, CatalogPetPalette, CatalogType, GetFurnitureData, GetProductDataForLocalization, GetRoomEngine, GiftWrappingConfiguration, ICatalogNode, ICatalogOptions, ICatalogPage, IPageLocalization, IProduct, IPurchasableOffer, IPurchaseOptions, LocalizeText, NotificationAlertType, NotificationUtilities, Offer, PageLocalization, PlaySound, Product, ProductTypeEnum, RequestedPage, SearchResult, SendMessageComposer, SoundNames } from '../../api';
|
||||
import { CatalogGiftReceiverNotFoundEvent, CatalogNameResultEvent, CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent } from '../../events';
|
||||
import { DispatchUiEvent, UseUiEvent } from '../events';
|
||||
import { BuilderFurniPlaceableStatus, CatalogNode, CatalogPage, CatalogPetPalette, CatalogType, CreateLinkEvent, FurniCategory, GetFurnitureData, GetNitroInstance, GetProductDataForLocalization, GetRoomEngine, GetRoomSession, GiftWrappingConfiguration, ICatalogNode, ICatalogOptions, ICatalogPage, IPageLocalization, IProduct, IPurchasableOffer, IPurchaseOptions, LocalizeText, NotificationAlertType, NotificationUtilities, Offer, PageLocalization, PlacedObjectPurchaseData, PlaySound, Product, ProductTypeEnum, RequestedPage, SearchResult, SendMessageComposer, SoundNames } from '../../api';
|
||||
import { CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent, InventoryFurniAddedEvent } from '../../events';
|
||||
import { DispatchUiEvent, UseRoomEngineEvent, UseUiEvent } from '../events';
|
||||
import { UseMessageEventHook } from '../messages';
|
||||
import { useCatalogBuildersClub } from './useCatalogBuildersClub';
|
||||
import { useCatalogItemMover } from './useCatalogItemMover';
|
||||
import { useCatalogPlaceMultipleItems } from './useCatalogPlaceMultipleItems';
|
||||
import { useCatalogSkipPurchaseConfirmation } from './useCatalogSkipPurchaseConfirmation';
|
||||
|
||||
const DUMMY_PAGE_ID_FOR_OFFER_SEARCH = -12345678;
|
||||
const DRAG_AND_DROP_ENABLED = true;
|
||||
|
||||
const useCatalogState = () =>
|
||||
{
|
||||
@ -26,8 +29,17 @@ const useCatalogState = () =>
|
||||
const [ navigationHidden, setNavigationHidden ] = useState(false);
|
||||
const [ purchaseOptions, setPurchaseOptions ] = useState<IPurchaseOptions>({ quantity: 1, extraData: null, extraParamRequired: false, previewStuffData: null });
|
||||
const [ catalogOptions, setCatalogOptions ] = useState<ICatalogOptions>({});
|
||||
const { furniCount = 0, furniLimit = 0, secondsLeft = 0 } = useCatalogBuildersClub();
|
||||
const { requestOfferToMover = null, cancelObjectMover = null } = useCatalogItemMover({ currentType, pageId, currentOffer, purchaseOptions }, { furniCount, furniLimit, secondsLeft });
|
||||
const [ objectMoverRequested, setObjectMoverRequested ] = useState(false);
|
||||
const [ catalogPlaceMultipleObjects, setCatalogPlaceMultipleObjects ] = useCatalogPlaceMultipleItems();
|
||||
const [ catalogSkipPurchaseConfirmation, setCatalogSkipPurchaseConfirmation ] = useCatalogSkipPurchaseConfirmation();
|
||||
const [ purchasableOffer, setPurchaseableOffer ] = useState<IPurchasableOffer>(null);
|
||||
const [ placedObjectPurchaseData, setPlacedObjectPurchaseData ] = useState<PlacedObjectPurchaseData>(null);
|
||||
const [ furniCount, setFurniCount ] = useState(0);
|
||||
const [ furniLimit, setFurniLimit ] = useState(0);
|
||||
const [ maxFurniLimit, setMaxFurniLimit ] = useState(0);
|
||||
const [ secondsLeft, setSecondsLeft ] = useState(0);
|
||||
const [ updateTime, setUpdateTime ] = useState(0);
|
||||
const [ secondsLeftWithGrace, setSecondsLeftWithGrace ] = useState(0);
|
||||
const requestedPage = useRef(new RequestedPage());
|
||||
|
||||
const resetState = useCallback(() =>
|
||||
@ -44,6 +56,166 @@ const useCatalogState = () =>
|
||||
setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
const getBuilderFurniPlaceableStatus = useCallback((offer: IPurchasableOffer) =>
|
||||
{
|
||||
if(!offer) return BuilderFurniPlaceableStatus.MISSING_OFFER;
|
||||
|
||||
if((furniCount < 0) || (furniCount >= furniLimit)) return BuilderFurniPlaceableStatus.FURNI_LIMIT_REACHED;
|
||||
|
||||
const roomSession = GetRoomSession();
|
||||
|
||||
if(!roomSession) return BuilderFurniPlaceableStatus.NOT_IN_ROOM;
|
||||
|
||||
if(!roomSession.isRoomOwner) return BuilderFurniPlaceableStatus.NOT_ROOM_OWNER;
|
||||
|
||||
if(secondsLeft <= 0)
|
||||
{
|
||||
const roomEngine = GetRoomEngine();
|
||||
|
||||
let objectCount = roomEngine.getRoomObjectCount(roomSession.roomId, RoomObjectCategory.UNIT);
|
||||
|
||||
while(objectCount > 0)
|
||||
{
|
||||
const roomObject = roomEngine.getRoomObjectByIndex(roomSession.roomId, objectCount, RoomObjectCategory.UNIT);
|
||||
const userData = roomSession.userDataManager.getUserDataByIndex(roomObject.id);
|
||||
|
||||
if(userData && (userData.type === RoomObjectType.USER) && (userData.roomIndex !== roomSession.ownRoomIndex) && !userData.isModerator) return BuilderFurniPlaceableStatus.VISITORS_IN_ROOM;
|
||||
|
||||
objectCount--;
|
||||
}
|
||||
}
|
||||
|
||||
return BuilderFurniPlaceableStatus.OKAY;
|
||||
}, [ furniCount, furniLimit, secondsLeft ]);
|
||||
|
||||
const isDraggable = useCallback((offer: IPurchasableOffer) =>
|
||||
{
|
||||
const roomSession = GetRoomSession();
|
||||
|
||||
if(((DRAG_AND_DROP_ENABLED && roomSession && offer.page && (offer.page.layoutCode !== 'sold_ltd_items') && (currentType === CatalogType.NORMAL) && (roomSession.isRoomOwner || (roomSession.isGuildRoom && (roomSession.controllerLevel >= RoomControllerLevel.GUILD_MEMBER)))) || ((currentType === CatalogType.BUILDER) && (getBuilderFurniPlaceableStatus(offer) === BuilderFurniPlaceableStatus.OKAY))) && (offer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (offer.product.productType !== ProductTypeEnum.EFFECT) && (offer.product.productType !== ProductTypeEnum.HABBO_CLUB)) return true;
|
||||
|
||||
return false;
|
||||
}, [ currentType, getBuilderFurniPlaceableStatus ]);
|
||||
|
||||
const requestOfferToMover = useCallback((offer: IPurchasableOffer) =>
|
||||
{
|
||||
if(!isDraggable(offer)) return;
|
||||
|
||||
const product = offer.product;
|
||||
|
||||
if(!product) return;
|
||||
|
||||
let category = 0;
|
||||
|
||||
switch(product.productType)
|
||||
{
|
||||
case ProductTypeEnum.FLOOR:
|
||||
category = RoomObjectCategory.FLOOR;
|
||||
break;
|
||||
case ProductTypeEnum.WALL:
|
||||
category = RoomObjectCategory.WALL;
|
||||
break;
|
||||
}
|
||||
|
||||
if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.CATALOG, -(offer.offerId), category, product.productClassId, product.extraParam))
|
||||
{
|
||||
setPurchaseableOffer(offer);
|
||||
setObjectMoverRequested(true);
|
||||
|
||||
setIsVisible(false);
|
||||
}
|
||||
}, [ isDraggable ]);
|
||||
|
||||
const resetRoomPaint = useCallback((planeType: string, type: string) =>
|
||||
{
|
||||
const roomEngine = GetRoomEngine();
|
||||
|
||||
let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE);
|
||||
let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE);
|
||||
let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE);
|
||||
|
||||
wallType = (wallType && wallType.length) ? wallType : '101';
|
||||
floorType = (floorType && floorType.length) ? floorType : '101';
|
||||
landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1';
|
||||
|
||||
switch(planeType)
|
||||
{
|
||||
case 'floor':
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, type, wallType, landscapeType, true);
|
||||
return;
|
||||
case 'wallpaper':
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, type, landscapeType, true);
|
||||
return;
|
||||
case 'landscape':
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, wallType, type, true);
|
||||
return;
|
||||
default:
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, wallType, landscapeType, true);
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const cancelObjectMover = useCallback(() =>
|
||||
{
|
||||
if(!purchasableOffer) return;
|
||||
|
||||
GetRoomEngine().cancelRoomObjectInsert();
|
||||
|
||||
setObjectMoverRequested(false);
|
||||
setPurchaseableOffer(null);
|
||||
}, [ purchasableOffer ]);
|
||||
|
||||
const resetObjectMover = useCallback((flag: boolean = true) =>
|
||||
{
|
||||
setObjectMoverRequested(prevValue =>
|
||||
{
|
||||
if(prevValue && flag)
|
||||
{
|
||||
CreateLinkEvent('catalog/open');
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const resetPlacedOfferData = useCallback((flag: boolean = false) =>
|
||||
{
|
||||
if(!flag) resetObjectMover();
|
||||
|
||||
setPlacedObjectPurchaseData(prevValue =>
|
||||
{
|
||||
if(prevValue)
|
||||
{
|
||||
switch(prevValue.category)
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
GetRoomEngine().removeRoomObjectFloor(prevValue.roomId, prevValue.objectId);
|
||||
break;
|
||||
case RoomObjectCategory.WALL: {
|
||||
|
||||
switch(prevValue.furniData.className)
|
||||
{
|
||||
case 'floor':
|
||||
case 'wallpaper':
|
||||
case 'landscape':
|
||||
resetRoomPaint('reset', '');
|
||||
break;
|
||||
default:
|
||||
GetRoomEngine().removeRoomObjectWall(prevValue.roomId, prevValue.objectId);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GetRoomEngine().deleteRoomObject(prevValue.objectId, prevValue.category);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}, [ resetObjectMover, resetRoomPaint ]);
|
||||
|
||||
const getNodeById = useCallback((id: number, node: ICatalogNode) =>
|
||||
{
|
||||
if((node.pageId === id) && (node !== rootNode)) return node;
|
||||
@ -238,6 +410,11 @@ const useCatalogState = () =>
|
||||
}
|
||||
}, [ isVisible, getNodesByOfferId, activateNode ]);
|
||||
|
||||
const refreshBuilderStatus = useCallback(() =>
|
||||
{
|
||||
|
||||
}, []);
|
||||
|
||||
const onCatalogPagesListEvent = useCallback((event: CatalogPagesListEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@ -421,22 +598,6 @@ const useCatalogState = () =>
|
||||
|
||||
UseMessageEventHook(SellablePetPalettesMessageEvent, onSellablePetPalettesMessageEvent);
|
||||
|
||||
const onApproveNameMessageEvent = useCallback((event: ApproveNameMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
DispatchUiEvent(new CatalogNameResultEvent(parser.result, parser.validationInfo));
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(ApproveNameMessageEvent, onApproveNameMessageEvent);
|
||||
|
||||
const onGiftReceiverNotFoundEvent = useCallback(() =>
|
||||
{
|
||||
DispatchUiEvent(new CatalogGiftReceiverNotFoundEvent());
|
||||
}, []);
|
||||
|
||||
UseMessageEventHook(GiftReceiverNotFoundEvent, onGiftReceiverNotFoundEvent);
|
||||
|
||||
const onHabboClubOffersMessageEvent = useCallback((event: HabboClubOffersMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@ -527,6 +688,32 @@ const useCatalogState = () =>
|
||||
|
||||
UseMessageEventHook(CatalogPublishedMessageEvent, onCatalogPublishedMessageEvent);
|
||||
|
||||
const onBuildersClubFurniCountMessageEvent = useCallback((event: BuildersClubFurniCountMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setFurniCount(parser.furniCount);
|
||||
|
||||
refreshBuilderStatus();
|
||||
}, [ refreshBuilderStatus ]);
|
||||
|
||||
UseMessageEventHook(BuildersClubFurniCountMessageEvent, onBuildersClubFurniCountMessageEvent);
|
||||
|
||||
const onBuildersClubSubscriptionStatusMessageEvent = useCallback((event: BuildersClubSubscriptionStatusMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setFurniLimit(parser._Str_15864);
|
||||
setMaxFurniLimit(parser._Str_24094);
|
||||
setSecondsLeft(parser._Str_3709);
|
||||
setUpdateTime(GetNitroInstance().time);
|
||||
setSecondsLeftWithGrace(parser._Str_24379);
|
||||
|
||||
refreshBuilderStatus();
|
||||
}, [ refreshBuilderStatus ]);
|
||||
|
||||
UseMessageEventHook(BuildersClubSubscriptionStatusMessageEvent, onBuildersClubSubscriptionStatusMessageEvent);
|
||||
|
||||
const onCatalogPurchasedEvent = useCallback((event: CatalogPurchasedEvent) =>
|
||||
{
|
||||
PlaySound(SoundNames.CREDITS);
|
||||
@ -534,6 +721,153 @@ const useCatalogState = () =>
|
||||
|
||||
UseUiEvent(CatalogPurchasedEvent.PURCHASE_SUCCESS, onCatalogPurchasedEvent);
|
||||
|
||||
const onRoomEngineObjectPlacedEvent = useCallback((event: RoomEngineObjectPlacedEvent) =>
|
||||
{
|
||||
if(!objectMoverRequested || (event.type !== RoomEngineObjectPlacedEvent.PLACED)) return;
|
||||
|
||||
resetPlacedOfferData(true);
|
||||
|
||||
if(!purchasableOffer)
|
||||
{
|
||||
resetObjectMover();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let placed = false;
|
||||
|
||||
const product = purchasableOffer.product;
|
||||
|
||||
if(event.category === RoomObjectCategory.WALL)
|
||||
{
|
||||
switch(product.furnitureData.className)
|
||||
{
|
||||
case 'floor':
|
||||
case 'wallpaper':
|
||||
case 'landscape':
|
||||
placed = (event.placedOnFloor || event.placedOnWall);
|
||||
break;
|
||||
default:
|
||||
placed = event.placedInRoom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
placed = event.placedInRoom;
|
||||
}
|
||||
|
||||
if(!placed)
|
||||
{
|
||||
resetObjectMover();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setPlacedObjectPurchaseData(new PlacedObjectPurchaseData(event.roomId, event.objectId, event.category, event.wallLocation, event.x, event.y, event.direction, purchasableOffer));
|
||||
|
||||
switch(currentType)
|
||||
{
|
||||
case CatalogType.NORMAL: {
|
||||
switch(event.category)
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
GetRoomEngine().addFurnitureFloor(event.roomId, event.objectId, product.productClassId, new Vector3d(event.x, event.y, event.z), new Vector3d(event.direction), 0, new LegacyDataType());
|
||||
break;
|
||||
case RoomObjectCategory.WALL: {
|
||||
switch(product.furnitureData.className)
|
||||
{
|
||||
case 'floor':
|
||||
case 'wallpaper':
|
||||
case 'landscape':
|
||||
resetRoomPaint(product.furnitureData.className, product.extraParam);
|
||||
break;
|
||||
default:
|
||||
GetRoomEngine().addFurnitureWall(event.roomId, event.objectId, product.productClassId, new Vector3d(event.x, event.y, event.z), new Vector3d(event.direction * 45), 0, event.instanceData, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
|
||||
|
||||
if(roomObject) roomObject.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 0.5);
|
||||
|
||||
if(catalogSkipPurchaseConfirmation)
|
||||
{
|
||||
SendMessageComposer(new PurchaseFromCatalogComposer(pageId, purchasableOffer.offerId, product.extraParam, 1));
|
||||
|
||||
if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// confirm
|
||||
|
||||
if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CatalogType.BUILDER: {
|
||||
let pageId = purchasableOffer.page.pageId;
|
||||
|
||||
if(pageId === DUMMY_PAGE_ID_FOR_OFFER_SEARCH)
|
||||
{
|
||||
pageId = -1;
|
||||
}
|
||||
|
||||
switch(event.category)
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
SendMessageComposer(new BuildersClubPlaceRoomItemMessageComposer(pageId, purchasableOffer.offerId, product.extraParam, event.x, event.y, event.direction));
|
||||
break;
|
||||
case RoomObjectCategory.WALL:
|
||||
SendMessageComposer(new BuildersClubPlaceWallItemMessageComposer(pageId, purchasableOffer.offerId, product.extraParam, event.wallLocation));
|
||||
break;
|
||||
}
|
||||
|
||||
if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, [ objectMoverRequested, purchasableOffer, catalogPlaceMultipleObjects, catalogSkipPurchaseConfirmation, currentType, pageId, resetPlacedOfferData, resetObjectMover, resetRoomPaint, requestOfferToMover ]);
|
||||
|
||||
UseRoomEngineEvent(RoomEngineObjectPlacedEvent.PLACED, onRoomEngineObjectPlacedEvent);
|
||||
|
||||
const onInventoryFurniAddedEvent = useCallback((event: InventoryFurniAddedEvent) =>
|
||||
{
|
||||
const roomEngine = GetRoomEngine();
|
||||
|
||||
if(!placedObjectPurchaseData || (placedObjectPurchaseData.productClassId !== event.spriteId) || (placedObjectPurchaseData.roomId !== roomEngine.activeRoomId)) return;
|
||||
|
||||
switch(event.category)
|
||||
{
|
||||
case FurniCategory.FLOOR: {
|
||||
const floorType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE);
|
||||
|
||||
if(placedObjectPurchaseData.extraParam !== floorType) SendMessageComposer(new FurniturePlacePaintComposer(event.id));
|
||||
break;
|
||||
}
|
||||
case FurniCategory.WALL_PAPER: {
|
||||
const wallType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE);
|
||||
|
||||
if(placedObjectPurchaseData.extraParam !== wallType) SendMessageComposer(new FurniturePlacePaintComposer(event.id));
|
||||
break;
|
||||
}
|
||||
case FurniCategory.LANDSCAPE: {
|
||||
const landscapeType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE);
|
||||
|
||||
if(placedObjectPurchaseData.extraParam !== landscapeType) SendMessageComposer(new FurniturePlacePaintComposer(event.id));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SendMessageComposer(new FurniturePlaceComposer(event.id, placedObjectPurchaseData.category, placedObjectPurchaseData.wallLocation, placedObjectPurchaseData.x, placedObjectPurchaseData.y, placedObjectPurchaseData.direction));
|
||||
}
|
||||
|
||||
if(!catalogPlaceMultipleObjects) resetPlacedOfferData();
|
||||
}, [ placedObjectPurchaseData, catalogPlaceMultipleObjects, resetPlacedOfferData ]);
|
||||
|
||||
UseUiEvent(InventoryFurniAddedEvent.FURNI_ADDED, onInventoryFurniAddedEvent);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
return () => setCurrentOffer(null);
|
||||
@ -588,6 +922,7 @@ const useCatalogState = () =>
|
||||
SendMessageComposer(new GetGiftWrappingConfigurationComposer());
|
||||
SendMessageComposer(new GetClubGiftInfo());
|
||||
SendMessageComposer(new GetCatalogIndexComposer(currentType));
|
||||
SendMessageComposer(new BuildersClubQueryFurniCountMessageComposer());
|
||||
}, [ isVisible, rootNode, currentType ]);
|
||||
|
||||
useEffect(() =>
|
||||
|
@ -1,54 +0,0 @@
|
||||
import { BuildersClubFurniCountMessageEvent, BuildersClubQueryFurniCountMessageComposer, BuildersClubSubscriptionStatusMessageEvent } from '@nitrots/nitro-renderer';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { GetNitroInstance, SendMessageComposer } from '../../api';
|
||||
import { UseMessageEventHook } from '../messages';
|
||||
|
||||
const useCatalogBuildersClubState = () =>
|
||||
{
|
||||
const [ furniCount, setFurniCount ] = useState(0);
|
||||
const [ furniLimit, setFurniLimit ] = useState(0);
|
||||
const [ maxFurniLimit, setMaxFurniLimit ] = useState(0);
|
||||
const [ secondsLeft, setSecondsLeft ] = useState(0);
|
||||
const [ updateTime, setUpdateTime ] = useState(0);
|
||||
const [ secondsLeftWithGrace, setSecondsLeftWithGrace ] = useState(0);
|
||||
|
||||
const refreshBuilderStatus = useCallback(() =>
|
||||
{
|
||||
|
||||
}, []);
|
||||
|
||||
const onBuildersClubFurniCountMessageEvent = useCallback((event: BuildersClubFurniCountMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setFurniCount(parser.furniCount);
|
||||
|
||||
refreshBuilderStatus();
|
||||
}, [ refreshBuilderStatus ]);
|
||||
|
||||
UseMessageEventHook(BuildersClubFurniCountMessageEvent, onBuildersClubFurniCountMessageEvent);
|
||||
|
||||
const onBuildersClubSubscriptionStatusMessageEvent = useCallback((event: BuildersClubSubscriptionStatusMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setFurniLimit(parser._Str_15864);
|
||||
setMaxFurniLimit(parser._Str_24094);
|
||||
setSecondsLeft(parser._Str_3709);
|
||||
setUpdateTime(GetNitroInstance().time);
|
||||
setSecondsLeftWithGrace(parser._Str_24379);
|
||||
|
||||
refreshBuilderStatus();
|
||||
}, [ refreshBuilderStatus ]);
|
||||
|
||||
UseMessageEventHook(BuildersClubSubscriptionStatusMessageEvent, onBuildersClubSubscriptionStatusMessageEvent);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageComposer(new BuildersClubQueryFurniCountMessageComposer());
|
||||
}, []);
|
||||
|
||||
return { furniCount, furniLimit, maxFurniLimit, secondsLeft, updateTime, secondsLeftWithGrace };
|
||||
}
|
||||
|
||||
export const useCatalogBuildersClub = useCatalogBuildersClubState;
|
@ -1,330 +0,0 @@
|
||||
import { BuildersClubPlaceRoomItemMessageComposer, BuildersClubPlaceWallItemMessageComposer, FurniturePlaceComposer, FurniturePlacePaintComposer, LegacyDataType, PurchaseFromCatalogComposer, RoomControllerLevel, RoomEngineObjectPlacedEvent, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType, RoomObjectVariable, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { BuilderFurniPlaceableStatus, CatalogType, CreateLinkEvent, FurniCategory, GetRoomEngine, GetRoomSession, IPurchasableOffer, IPurchaseOptions, Offer, PlacedObjectPurchaseData, ProductTypeEnum, SendMessageComposer } from '../../api';
|
||||
import { InventoryFurniAddedEvent } from '../../events';
|
||||
import { UseRoomEngineEvent, UseUiEvent } from '../events';
|
||||
import { useCatalogPlaceMultipleItems } from './useCatalogPlaceMultipleItems';
|
||||
import { useCatalogSkipPurchaseConfirmation } from './useCatalogSkipPurchaseConfirmation';
|
||||
|
||||
const DUMMY_PAGE_ID_FOR_OFFER_SEARCH = -12345678;
|
||||
const DRAG_AND_DROP_ENABLED = true;
|
||||
|
||||
const useCatalogItemMoverState = (catalog: { currentType: string, pageId: number, currentOffer: IPurchasableOffer, purchaseOptions: IPurchaseOptions }, buildersClub: { furniCount: number, furniLimit: number, secondsLeft: number }) =>
|
||||
{
|
||||
const [ objectMoverRequested, setObjectMoverRequested ] = useState(false);
|
||||
const [ catalogPlaceMultipleObjects, setCatalogPlaceMultipleObjects ] = useCatalogPlaceMultipleItems();
|
||||
const [ catalogSkipPurchaseConfirmation, setCatalogSkipPurchaseConfirmation ] = useCatalogSkipPurchaseConfirmation();
|
||||
const [ purchasableOffer, setPurchaseableOffer ] = useState<IPurchasableOffer>(null);
|
||||
const [ placedObjectPurchaseData, setPlacedObjectPurchaseData ] = useState<PlacedObjectPurchaseData>(null);
|
||||
|
||||
const getBuilderFurniPlaceableStatus = useCallback((offer: IPurchasableOffer) =>
|
||||
{
|
||||
if(!offer) return BuilderFurniPlaceableStatus.MISSING_OFFER;
|
||||
|
||||
if((buildersClub.furniCount < 0) || (buildersClub.furniCount >= buildersClub.furniLimit)) return BuilderFurniPlaceableStatus.FURNI_LIMIT_REACHED;
|
||||
|
||||
const roomSession = GetRoomSession();
|
||||
|
||||
if(!roomSession) return BuilderFurniPlaceableStatus.NOT_IN_ROOM;
|
||||
|
||||
if(!roomSession.isRoomOwner) return BuilderFurniPlaceableStatus.NOT_ROOM_OWNER;
|
||||
|
||||
if(buildersClub.secondsLeft <= 0)
|
||||
{
|
||||
const roomEngine = GetRoomEngine();
|
||||
|
||||
let objectCount = roomEngine.getRoomObjectCount(roomSession.roomId, RoomObjectCategory.UNIT);
|
||||
|
||||
while(objectCount > 0)
|
||||
{
|
||||
const roomObject = roomEngine.getRoomObjectByIndex(roomSession.roomId, objectCount, RoomObjectCategory.UNIT);
|
||||
const userData = roomSession.userDataManager.getUserDataByIndex(roomObject.id);
|
||||
|
||||
if(userData && (userData.type === RoomObjectType.USER) && (userData.roomIndex !== roomSession.ownRoomIndex) && !userData.isModerator) return BuilderFurniPlaceableStatus.VISITORS_IN_ROOM;
|
||||
|
||||
objectCount--;
|
||||
}
|
||||
}
|
||||
|
||||
return BuilderFurniPlaceableStatus.OKAY;
|
||||
}, [ buildersClub.furniCount, buildersClub.furniLimit, buildersClub.secondsLeft ]);
|
||||
|
||||
const isDraggable = useCallback((offer: IPurchasableOffer) =>
|
||||
{
|
||||
const roomSession = GetRoomSession();
|
||||
|
||||
if(((DRAG_AND_DROP_ENABLED && roomSession && offer.page && (offer.page.layoutCode !== 'sold_ltd_items') && (catalog.currentType === CatalogType.NORMAL) && (roomSession.isRoomOwner || (roomSession.isGuildRoom && (roomSession.controllerLevel >= RoomControllerLevel.GUILD_MEMBER)))) || ((catalog.currentType === CatalogType.BUILDER) && (getBuilderFurniPlaceableStatus(offer) === BuilderFurniPlaceableStatus.OKAY))) && (offer.pricingModel !== Offer.PRICING_MODEL_BUNDLE) && (offer.product.productType !== ProductTypeEnum.EFFECT) && (offer.product.productType !== ProductTypeEnum.HABBO_CLUB)) return true;
|
||||
|
||||
return false;
|
||||
}, [ catalog.currentType, getBuilderFurniPlaceableStatus ]);
|
||||
|
||||
const requestOfferToMover = useCallback((offer: IPurchasableOffer) =>
|
||||
{
|
||||
if(!isDraggable(offer)) return;
|
||||
|
||||
const product = offer.product;
|
||||
|
||||
if(!product) return;
|
||||
|
||||
let category = 0;
|
||||
|
||||
switch(product.productType)
|
||||
{
|
||||
case ProductTypeEnum.FLOOR:
|
||||
category = RoomObjectCategory.FLOOR;
|
||||
break;
|
||||
case ProductTypeEnum.WALL:
|
||||
category = RoomObjectCategory.WALL;
|
||||
break;
|
||||
}
|
||||
|
||||
if(GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.CATALOG, -(offer.offerId), category, product.productClassId, product.extraParam))
|
||||
{
|
||||
setPurchaseableOffer(offer);
|
||||
setObjectMoverRequested(true);
|
||||
|
||||
CreateLinkEvent('catalog/hide');
|
||||
}
|
||||
}, [ isDraggable ]);
|
||||
|
||||
const resetRoomPaint = useCallback((planeType: string, type: string) =>
|
||||
{
|
||||
const roomEngine = GetRoomEngine();
|
||||
|
||||
let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE);
|
||||
let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE);
|
||||
let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE);
|
||||
|
||||
wallType = (wallType && wallType.length) ? wallType : '101';
|
||||
floorType = (floorType && floorType.length) ? floorType : '101';
|
||||
landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1';
|
||||
|
||||
switch(planeType)
|
||||
{
|
||||
case 'floor':
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, type, wallType, landscapeType, true);
|
||||
return;
|
||||
case 'wallpaper':
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, type, landscapeType, true);
|
||||
return;
|
||||
case 'landscape':
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, wallType, type, true);
|
||||
return;
|
||||
default:
|
||||
roomEngine.updateRoomInstancePlaneType(roomEngine.activeRoomId, floorType, wallType, landscapeType, true);
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const cancelObjectMover = useCallback(() =>
|
||||
{
|
||||
if(!purchasableOffer) return;
|
||||
|
||||
GetRoomEngine().cancelRoomObjectInsert();
|
||||
|
||||
setObjectMoverRequested(false);
|
||||
setPurchaseableOffer(null);
|
||||
}, [ purchasableOffer ]);
|
||||
|
||||
const resetObjectMover = useCallback((flag: boolean = true) =>
|
||||
{
|
||||
setObjectMoverRequested(prevValue =>
|
||||
{
|
||||
if(prevValue && flag)
|
||||
{
|
||||
CreateLinkEvent('catalog/open');
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const resetPlacedOfferData = useCallback((flag: boolean = false) =>
|
||||
{
|
||||
if(!flag) resetObjectMover();
|
||||
|
||||
setPlacedObjectPurchaseData(prevValue =>
|
||||
{
|
||||
if(prevValue)
|
||||
{
|
||||
switch(prevValue.category)
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
GetRoomEngine().removeRoomObjectFloor(prevValue.roomId, prevValue.objectId);
|
||||
break;
|
||||
case RoomObjectCategory.WALL: {
|
||||
|
||||
switch(prevValue.furniData.className)
|
||||
{
|
||||
case 'floor':
|
||||
case 'wallpaper':
|
||||
case 'landscape':
|
||||
resetRoomPaint('reset', '');
|
||||
break;
|
||||
default:
|
||||
GetRoomEngine().removeRoomObjectWall(prevValue.roomId, prevValue.objectId);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GetRoomEngine().deleteRoomObject(prevValue.objectId, prevValue.category);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}, [ resetObjectMover, resetRoomPaint ]);
|
||||
|
||||
const onRoomEngineObjectPlacedEvent = useCallback((event: RoomEngineObjectPlacedEvent) =>
|
||||
{
|
||||
if(!objectMoverRequested || (event.type !== RoomEngineObjectPlacedEvent.PLACED)) return;
|
||||
|
||||
resetPlacedOfferData(true);
|
||||
|
||||
if(!purchasableOffer)
|
||||
{
|
||||
resetObjectMover();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let placed = false;
|
||||
|
||||
const product = purchasableOffer.product;
|
||||
|
||||
if(event.category === RoomObjectCategory.WALL)
|
||||
{
|
||||
switch(product.furnitureData.className)
|
||||
{
|
||||
case 'floor':
|
||||
case 'wallpaper':
|
||||
case 'landscape':
|
||||
placed = (event.placedOnFloor || event.placedOnWall);
|
||||
break;
|
||||
default:
|
||||
placed = event.placedInRoom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
placed = event.placedInRoom;
|
||||
}
|
||||
|
||||
if(!placed)
|
||||
{
|
||||
resetObjectMover();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setPlacedObjectPurchaseData(new PlacedObjectPurchaseData(event.roomId, event.objectId, event.category, event.wallLocation, event.x, event.y, event.direction, purchasableOffer));
|
||||
|
||||
switch(catalog.currentType)
|
||||
{
|
||||
case CatalogType.NORMAL: {
|
||||
switch(event.category)
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
GetRoomEngine().addFurnitureFloor(event.roomId, event.objectId, product.productClassId, new Vector3d(event.x, event.y, event.z), new Vector3d(event.direction), 0, new LegacyDataType());
|
||||
break;
|
||||
case RoomObjectCategory.WALL: {
|
||||
switch(product.furnitureData.className)
|
||||
{
|
||||
case 'floor':
|
||||
case 'wallpaper':
|
||||
case 'landscape':
|
||||
resetRoomPaint(product.furnitureData.className, product.extraParam);
|
||||
break;
|
||||
default:
|
||||
GetRoomEngine().addFurnitureWall(event.roomId, event.objectId, product.productClassId, new Vector3d(event.x, event.y, event.z), new Vector3d(event.direction * 45), 0, event.instanceData, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
|
||||
|
||||
if(roomObject) roomObject.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 0.5);
|
||||
|
||||
if(catalogSkipPurchaseConfirmation)
|
||||
{
|
||||
SendMessageComposer(new PurchaseFromCatalogComposer(catalog.pageId, purchasableOffer.offerId, product.extraParam, 1));
|
||||
|
||||
if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// confirm
|
||||
|
||||
if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CatalogType.BUILDER: {
|
||||
let pageId = purchasableOffer.page.pageId;
|
||||
|
||||
if(pageId === DUMMY_PAGE_ID_FOR_OFFER_SEARCH)
|
||||
{
|
||||
pageId = -1;
|
||||
}
|
||||
|
||||
switch(event.category)
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
SendMessageComposer(new BuildersClubPlaceRoomItemMessageComposer(pageId, purchasableOffer.offerId, product.extraParam, event.x, event.y, event.direction));
|
||||
break;
|
||||
case RoomObjectCategory.WALL:
|
||||
SendMessageComposer(new BuildersClubPlaceWallItemMessageComposer(pageId, purchasableOffer.offerId, product.extraParam, event.wallLocation));
|
||||
break;
|
||||
}
|
||||
|
||||
if(catalogPlaceMultipleObjects) requestOfferToMover(purchasableOffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, [ objectMoverRequested, purchasableOffer, catalogPlaceMultipleObjects, catalogSkipPurchaseConfirmation, catalog, resetPlacedOfferData, resetObjectMover, resetRoomPaint, requestOfferToMover ]);
|
||||
|
||||
UseRoomEngineEvent(RoomEngineObjectPlacedEvent.PLACED, onRoomEngineObjectPlacedEvent);
|
||||
|
||||
const onInventoryFurniAddedEvent = useCallback((event: InventoryFurniAddedEvent) =>
|
||||
{
|
||||
const roomEngine = GetRoomEngine();
|
||||
|
||||
if(!placedObjectPurchaseData || (placedObjectPurchaseData.productClassId !== event.spriteId) || (placedObjectPurchaseData.roomId !== roomEngine.activeRoomId)) return;
|
||||
|
||||
switch(event.category)
|
||||
{
|
||||
case FurniCategory.FLOOR: {
|
||||
const floorType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE);
|
||||
|
||||
if(placedObjectPurchaseData.extraParam !== floorType) SendMessageComposer(new FurniturePlacePaintComposer(event.id));
|
||||
break;
|
||||
}
|
||||
case FurniCategory.WALL_PAPER: {
|
||||
const wallType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE);
|
||||
|
||||
if(placedObjectPurchaseData.extraParam !== wallType) SendMessageComposer(new FurniturePlacePaintComposer(event.id));
|
||||
break;
|
||||
}
|
||||
case FurniCategory.LANDSCAPE: {
|
||||
const landscapeType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE);
|
||||
|
||||
if(placedObjectPurchaseData.extraParam !== landscapeType) SendMessageComposer(new FurniturePlacePaintComposer(event.id));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SendMessageComposer(new FurniturePlaceComposer(event.id, placedObjectPurchaseData.category, placedObjectPurchaseData.wallLocation, placedObjectPurchaseData.x, placedObjectPurchaseData.y, placedObjectPurchaseData.direction));
|
||||
}
|
||||
|
||||
if(!catalogPlaceMultipleObjects) resetPlacedOfferData();
|
||||
}, [ placedObjectPurchaseData, catalogPlaceMultipleObjects, resetPlacedOfferData ]);
|
||||
|
||||
UseUiEvent(InventoryFurniAddedEvent.FURNI_ADDED, onInventoryFurniAddedEvent);
|
||||
|
||||
return { requestOfferToMover, cancelObjectMover };
|
||||
}
|
||||
|
||||
export const useCatalogItemMover = useCatalogItemMoverState;
|
@ -268,7 +268,7 @@ const useInventoryFurniState = () =>
|
||||
setNeedsUpdate(false);
|
||||
}, [ isVisible, needsUpdate ]);
|
||||
|
||||
return { groupItems, setGroupItems, selectedItem, setSelectedItem, activate, deactivate };
|
||||
return { isVisible, groupItems, setGroupItems, selectedItem, setSelectedItem, activate, deactivate };
|
||||
}
|
||||
|
||||
export const useInventoryFurni = () => useBetween(useInventoryFurniState);
|
||||
|
Loading…
Reference in New Issue
Block a user