diff --git a/src/components/catalog/CatalogView.tsx b/src/components/catalog/CatalogView.tsx index 28b6e8de..3af9b189 100644 --- a/src/components/catalog/CatalogView.tsx +++ b/src/components/catalog/CatalogView.tsx @@ -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(() => { diff --git a/src/components/catalog/views/gift/CatalogGiftView.tsx b/src/components/catalog/views/gift/CatalogGiftView.tsx index 0180eaec..74cb4a84 100644 --- a/src/components/catalog/views/gift/CatalogGiftView.tsx +++ b/src/components/catalog/views/gift/CatalogGiftView.tsx @@ -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); diff --git a/src/components/catalog/views/page/common/CatalogGridOfferView.tsx b/src/components/catalog/views/page/common/CatalogGridOfferView.tsx index 79d79d38..507bb6c7 100644 --- a/src/components/catalog/views/page/common/CatalogGridOfferView.tsx +++ b/src/components/catalog/views/page/common/CatalogGridOfferView.tsx @@ -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 = 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 = props => setMouseDown(false); return; case MouseEventType.ROLL_OUT: - if(!isMouseDown || !itemActive) return; + if(!isMouseDown || !itemActive || !isVisible) return; requestOfferToMover(offer); return; diff --git a/src/components/catalog/views/page/layout/pets/CatalogLayoutPetPurchaseView.tsx b/src/components/catalog/views/page/layout/pets/CatalogLayoutPetPurchaseView.tsx deleted file mode 100644 index 694b8e26..00000000 --- a/src/components/catalog/views/page/layout/pets/CatalogLayoutPetPurchaseView.tsx +++ /dev/null @@ -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 = 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 ( - -
- -
- -
- { LocalizeText('catalog.bundlewidget.price') } -
- - { ((offer.priceType === Offer.PRICE_TYPE_CREDITS_ACTIVITYPOINTS) || (offer.priceType === Offer.PRICE_TYPE_CREDITS)) && - - { offer.priceInCredits } - - } - { ((offer.priceType === Offer.PRICE_TYPE_CREDITS_ACTIVITYPOINTS) || (offer.priceType === Offer.PRICE_TYPE_ACTIVITYPOINTS)) && - - { offer.priceInActivityPoints } - - } - -
- - - { /* - { offer.giftable && - } */ } - -
- ); -} diff --git a/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx b/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx index b0f23bd7..39d0c95e 100644 --- a/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx +++ b/src/components/catalog/views/page/layout/pets/CatalogLayoutPetView.tsx @@ -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 = 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(() => { diff --git a/src/components/catalog/views/page/layout/pets/CatalogPetNameApprovalView.tsx b/src/components/catalog/views/page/layout/pets/CatalogPetNameApprovalView.tsx deleted file mode 100644 index ca22262d..00000000 --- a/src/components/catalog/views/page/layout/pets/CatalogPetNameApprovalView.tsx +++ /dev/null @@ -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>; - nameApproved: boolean; - setNameApproved: Dispatch>; -} - -export const CatalogPetNameApprovalView: FC = 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 ( -
- 0) ? 'is-invalid ' : '') } placeholder={ LocalizeText('widgets.petpackage.name.title') } value={ petNameValue } onChange={ event => setPetNameValue(event.target.value) } /> - { (validationResult > 0) && -
{ validationErrorMessage }
} -
- ); -} diff --git a/src/events/catalog/CatalogEvent.ts b/src/events/catalog/CatalogEvent.ts index 58ef7b7b..893775a5 100644 --- a/src/events/catalog/CatalogEvent.ts +++ b/src/events/catalog/CatalogEvent.ts @@ -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'; diff --git a/src/events/catalog/CatalogGiftReceiverNotFoundEvent.ts b/src/events/catalog/CatalogGiftReceiverNotFoundEvent.ts deleted file mode 100644 index 611eaff7..00000000 --- a/src/events/catalog/CatalogGiftReceiverNotFoundEvent.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { CatalogEvent } from './CatalogEvent'; - -export class CatalogGiftReceiverNotFoundEvent extends CatalogEvent -{ - constructor() - { - super(CatalogEvent.GIFT_RECEIVER_NOT_FOUND); - } -} diff --git a/src/events/catalog/CatalogNameResultEvent.ts b/src/events/catalog/CatalogNameResultEvent.ts deleted file mode 100644 index 70e4c0ec..00000000 --- a/src/events/catalog/CatalogNameResultEvent.ts +++ /dev/null @@ -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; - } -} diff --git a/src/events/catalog/CatalogWidgetEvent.ts b/src/events/catalog/CatalogWidgetEvent.ts index 9f3f5a41..fd0e6026 100644 --- a/src/events/catalog/CatalogWidgetEvent.ts +++ b/src/events/catalog/CatalogWidgetEvent.ts @@ -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'; diff --git a/src/events/catalog/index.ts b/src/events/catalog/index.ts index d8bc3f33..a7c15725 100644 --- a/src/events/catalog/index.ts +++ b/src/events/catalog/index.ts @@ -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'; diff --git a/src/hooks/catalog/index.ts b/src/hooks/catalog/index.ts index 9798d048..75d29849 100644 --- a/src/hooks/catalog/index.ts +++ b/src/hooks/catalog/index.ts @@ -1,5 +1,3 @@ export * from './useCatalog'; -export * from './useCatalogBuildersClub'; -export * from './useCatalogItemMover'; export * from './useCatalogPlaceMultipleItems'; export * from './useCatalogSkipPurchaseConfirmation'; diff --git a/src/hooks/catalog/useCatalog.ts b/src/hooks/catalog/useCatalog.ts index ca2d4701..2e90d17a 100644 --- a/src/hooks/catalog/useCatalog.ts +++ b/src/hooks/catalog/useCatalog.ts @@ -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({ quantity: 1, extraData: null, extraParamRequired: false, previewStuffData: null }); const [ catalogOptions, setCatalogOptions ] = useState({}); - 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(null); + const [ placedObjectPurchaseData, setPlacedObjectPurchaseData ] = useState(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(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); + let floorType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); + let landscapeType = roomEngine.getRoomInstanceVariable(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(() => diff --git a/src/hooks/catalog/useCatalogBuildersClub.ts b/src/hooks/catalog/useCatalogBuildersClub.ts deleted file mode 100644 index 538277a1..00000000 --- a/src/hooks/catalog/useCatalogBuildersClub.ts +++ /dev/null @@ -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; diff --git a/src/hooks/catalog/useCatalogItemMover.ts b/src/hooks/catalog/useCatalogItemMover.ts deleted file mode 100644 index 2df4d140..00000000 --- a/src/hooks/catalog/useCatalogItemMover.ts +++ /dev/null @@ -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(null); - const [ placedObjectPurchaseData, setPlacedObjectPurchaseData ] = useState(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(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); - let floorType = roomEngine.getRoomInstanceVariable(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); - let landscapeType = roomEngine.getRoomInstanceVariable(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; diff --git a/src/hooks/inventory/useInventoryFurni.ts b/src/hooks/inventory/useInventoryFurni.ts index 13d19463..18c0b740 100644 --- a/src/hooks/inventory/useInventoryFurni.ts +++ b/src/hooks/inventory/useInventoryFurni.ts @@ -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);