🆙 Init V3

This commit is contained in:
DuckieTM
2026-01-31 09:10:52 +01:00
commit 7feb10ab15
1733 changed files with 53405 additions and 0 deletions
@@ -0,0 +1,20 @@
export * from './useFurnitureAreaHideWidget';
export * from './useFurnitureBackgroundColorWidget';
export * from './useFurnitureBadgeDisplayWidget';
export * from './useFurnitureContextMenuWidget';
export * from './useFurnitureCraftingWidget';
export * from './useFurnitureDimmerWidget';
export * from './useFurnitureExchangeWidget';
export * from './useFurnitureExternalImageWidget';
export * from './useFurnitureFriendFurniWidget';
export * from './useFurnitureHighScoreWidget';
export * from './useFurnitureInternalLinkWidget';
export * from './useFurnitureMannequinWidget';
export * from './useFurniturePlaylistEditorWidget';
export * from './useFurniturePresentWidget';
export * from './useFurnitureRoomLinkWidget';
export * from './useFurnitureSpamWallPostItWidget';
export * from './useFurnitureStackHeightWidget';
export * from './useFurnitureStickieWidget';
export * from './useFurnitureTrophyWidget';
export * from './useFurnitureYoutubeWidget';
@@ -0,0 +1,93 @@
import { GetRoomEngine, RoomAreaSelectionManager, RoomEngineAreaHideStateEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useEffect, useState } from 'react';
import { CanManipulateFurniture } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useRoom } from '../../useRoom';
const useFurnitureAreaHideWidgetState = () =>
{
const [ objectId, setObjectId ] = useState<number>(-1);
const [ category, setCategory ] = useState<number>(-1);
const [ isOn, setIsOn ] = useState<boolean>(false);
const [ rootX, setRootX ] = useState<number>(0);
const [ rootY, setRootY ] = useState<number>(0);
const [ width, setWidth ] = useState<number>(0);
const [ length, setLength ] = useState<number>(0);
const [ invisibility, setInvisibility ] = useState<boolean>(false);
const [ wallItems, setWallItems ] = useState<boolean>(false);
const [ inverted, setInverted ] = useState<boolean>(false);
const { roomSession = null } = useRoom();
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setIsOn(false);
setRootX(0);
setRootY(0);
setWidth(0);
setLength(0);
setInvisibility(false);
setWallItems(false);
setInverted(false);
GetRoomEngine().areaSelectionManager.deactivate();
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_AREA_HIDE, event =>
{
if(!CanManipulateFurniture(roomSession, event.objectId, event.category)) return;
setObjectId(event.objectId);
setCategory(event.category);
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
const model = roomObject.model;
setIsOn(roomObject.getState(0) === 1);
setRootX(model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_ROOT_X) ?? 0);
setRootY(model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_ROOT_Y) ?? 0);
setWidth(model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_WIDTH) ?? 0);
setLength(model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_LENGTH) ?? 0);
setInvisibility(model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_INVISIBILITY) === 1);
setWallItems(model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_WALL_ITEMS) === 1);
setInverted(model.getValue<number>(RoomObjectVariable.FURNITURE_AREA_HIDE_INVERT) === 1);
});
useNitroEvent<RoomEngineAreaHideStateEvent>(RoomEngineAreaHideStateEvent.UPDATE_STATE_AREA_HIDE, event =>
{
setObjectId(event.objectId);
setCategory(event.category);
setIsOn(event.isOn);
});
useEffect(() =>
{
if(objectId === -1) return;
if(!isOn)
{
const callback = (rootX: number, rootY: number, width: number, height: number) =>
{
setRootX(rootX);
setRootY(rootY);
setWidth(width);
setLength(height);
};
if(GetRoomEngine().areaSelectionManager.activate(callback, RoomAreaSelectionManager.HIGHLIGHT_DARKEN))
{
GetRoomEngine().areaSelectionManager.setHighlight(rootX, rootY, width, length);
}
}
else
{
GetRoomEngine().areaSelectionManager.deactivate();
}
}, [ objectId, isOn, rootX, rootY, width, length ]);
return { objectId, category, isOn, setIsOn, rootX, setRootX, rootY, setRootY, width, setWidth, length, setLength, invisibility, setInvisibility, wallItems, setWallItems, inverted, setInverted, onClose };
};
export const useFurnitureAreaHideWidget = useFurnitureAreaHideWidgetState;
@@ -0,0 +1,71 @@
import { ApplyTonerComposer, ColorConverter, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useEffect, useState } from 'react';
import { CanManipulateFurniture, ColorUtils, DispatchUiEvent, RoomWidgetUpdateBackgroundColorPreviewEvent, SendMessageComposer } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
import { useRoom } from '../../useRoom';
const useFurnitureBackgroundColorWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ color, setColor ] = useState(0);
const { roomSession = null } = useRoom();
const applyToner = () =>
{
const hsl = ColorConverter.rgbToHSL(color);
const [ _, hue, saturation, lightness ] = ColorUtils.int_to_8BitVals(hsl);
SendMessageComposer(new ApplyTonerComposer(objectId, hue, saturation, lightness));
};
const toggleToner = () => roomSession.useMultistateItem(objectId);
const onClose = () =>
{
DispatchUiEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.CLEAR_PREVIEW));
setObjectId(-1);
setCategory(-1);
setColor(0);
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, event =>
{
if(!CanManipulateFurniture(roomSession, event.objectId, event.category)) return;
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
const model = roomObject.model;
setObjectId(event.objectId);
setCategory(event.category);
const hue = parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE));
const saturation = parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION));
const light = parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS));
const hsl = ColorUtils.eight_bitVals_to_int(0, hue,saturation,light);
const rgbColor = ColorConverter.hslToRGB(hsl);
setColor(rgbColor);
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
useEffect(() =>
{
if((objectId === -1) || (category === -1)) return;
const hls = ColorConverter.rgbToHSL(color);
const [ _, hue, saturation, lightness ] = ColorUtils.int_to_8BitVals(hls);
DispatchUiEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.PREVIEW, hue, saturation, lightness));
}, [ objectId, category, color ]);
return { objectId, color, setColor, applyToner, toggleToner, onClose };
};
export const useFurnitureBackgroundColorWidget = useFurnitureBackgroundColorWidgetState;
@@ -0,0 +1,75 @@
import { GetRoomEngine, GetSessionDataManager, RoomEngineTriggerWidgetEvent, RoomObjectVariable, StringDataType } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useNotification } from '../../../notification';
import { useFurniRemovedEvent } from '../../engine';
const useFurnitureBadgeDisplayWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ color, setColor ] = useState('1');
const [ badgeName, setBadgeName ] = useState('');
const [ badgeDesc, setBadgeDesc ] = useState('');
const [ date, setDate ] = useState('');
const [ senderName, setSenderName ] = useState('');
const { simpleAlert = null } = useNotification();
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setColor('1');
setBadgeName('');
setBadgeDesc('');
setDate('');
setSenderName('');
};
useNitroEvent<RoomEngineTriggerWidgetEvent>([
RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING,
RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING
], event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const stringStuff = new StringDataType();
stringStuff.initializeFromRoomObjectModel(roomObject.model);
setObjectId(event.objectId);
setCategory(event.category);
setColor('1');
setBadgeName(LocalizeBadgeName(stringStuff.getValue(1)));
setBadgeDesc(LocalizeBadgeDescription(stringStuff.getValue(1)));
setDate(stringStuff.getValue(2));
setSenderName(stringStuff.getValue(3));
});
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_FAILED, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const ownerId = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
if(ownerId !== GetSessionDataManager().userId) return;
simpleAlert(`${ LocalizeText('resolution.failed.subtitle') } ${ LocalizeText('resolution.failed.text') }`, null, null, null, LocalizeText('resolution.failed.title'));
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, category, color, badgeName, badgeDesc, date, senderName, onClose };
};
export const useFurnitureBadgeDisplayWidget = useFurnitureBadgeDisplayWidgetState;
@@ -0,0 +1,179 @@
import { ContextMenuEnum, GetRoomEngine, GroupFurniContextMenuInfoMessageEvent, GroupFurniContextMenuInfoMessageParser, RoomEngineTriggerWidgetEvent, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { IsOwnerOfFurniture, TryJoinGroup, TryVisitRoom } from '../../../../api';
import { useMessageEvent, useNitroEvent } from '../../../events';
import { useRoom } from '../../useRoom';
export const MONSTERPLANT_SEED_CONFIRMATION: string = 'MONSTERPLANT_SEED_CONFIRMATION';
export const PURCHASABLE_CLOTHING_CONFIRMATION: string = 'PURCHASABLE_CLOTHING_CONFIRMATION';
export const GROUP_FURNITURE: string = 'GROUP_FURNITURE';
export const EFFECTBOX_OPEN: string = 'EFFECTBOX_OPEN';
export const MYSTERYTROPHY_OPEN_DIALOG: string = 'MYSTERYTROPHY_OPEN_DIALOG';
const useFurnitureContextMenuWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ mode, setMode ] = useState<string>(null);
const [ confirmMode, setConfirmMode ] = useState<string>(null);
const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1);
const [ groupData, setGroupData ] = useState<GroupFurniContextMenuInfoMessageParser>(null);
const [ isGroupMember, setIsGroupMember ] = useState(false);
const [ objectOwnerId, setObjectOwnerId ] = useState(-1);
const { roomSession = null } = useRoom();
const onClose = () =>
{
setObjectId(-1);
setGroupData(null);
setIsGroupMember(false);
setMode(null);
};
const closeConfirm = () =>
{
setConfirmMode(null);
setConfirmingObjectId(-1);
};
const processAction = (name: string) =>
{
if(name)
{
switch(name)
{
case 'use_friend_furni':
roomSession.useMultistateItem(objectId);
break;
case 'use_monsterplant_seed':
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
setConfirmingObjectId(objectId);
break;
case 'use_random_teleport':
GetRoomEngine().useRoomObject(objectId, RoomObjectCategory.FLOOR);
break;
case 'use_purchaseable_clothing':
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
setConfirmingObjectId(objectId);
break;
case 'use_mystery_box':
roomSession.useMultistateItem(objectId);
break;
case 'use_mystery_trophy':
setConfirmMode(MYSTERYTROPHY_OPEN_DIALOG);
setConfirmingObjectId(objectId);
break;
case 'join_group':
TryJoinGroup(groupData.guildId);
setIsGroupMember(true);
return;
case 'go_to_group_homeroom':
if(groupData) TryVisitRoom(groupData.guildHomeRoomId);
break;
}
}
onClose();
};
useNitroEvent<RoomEngineTriggerWidgetEvent>([
RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU,
RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU,
RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG,
RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG,
RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG,
RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYBOX_OPEN_DIALOG,
RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYTROPHY_OPEN_DIALOG
], event =>
{
const object = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, event.category);
if(!object) return;
setObjectOwnerId(object.model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID));
switch(event.type)
{
case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
onClose();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(EFFECTBOX_OPEN);
onClose();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
onClose();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYBOX_OPEN_DIALOG:
roomSession.useMultistateItem(object.id);
onClose();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYTROPHY_OPEN_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(MYSTERYTROPHY_OPEN_DIALOG);
onClose();
return;
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
setObjectId(object.id);
switch(event.contextMenu)
{
case ContextMenuEnum.FRIEND_FURNITURE:
setMode(ContextMenuEnum.FRIEND_FURNITURE);
return;
case ContextMenuEnum.MONSTERPLANT_SEED:
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.MONSTERPLANT_SEED);
return;
case ContextMenuEnum.MYSTERY_BOX:
setMode(ContextMenuEnum.MYSTERY_BOX);
return;
case ContextMenuEnum.MYSTERY_TROPHY:
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.MYSTERY_TROPHY);
return;
case ContextMenuEnum.RANDOM_TELEPORT:
setMode(ContextMenuEnum.RANDOM_TELEPORT);
return;
case ContextMenuEnum.PURCHASABLE_CLOTHING:
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING);
return;
}
return;
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
if(object.id === objectId) onClose();
return;
}
});
useMessageEvent<GroupFurniContextMenuInfoMessageEvent>(GroupFurniContextMenuInfoMessageEvent, event =>
{
const parser = event.getParser();
setObjectId(parser.objectId);
setGroupData(parser);
setIsGroupMember(parser.userIsMember);
setMode(GROUP_FURNITURE);
});
return { objectId, mode, confirmMode, confirmingObjectId, groupData, isGroupMember, objectOwnerId, closeConfirm, processAction, onClose };
};
export const useFurnitureContextMenuWidget = useFurnitureContextMenuWidgetState;
@@ -0,0 +1,166 @@
import { CraftableProductsEvent, CraftComposer, CraftingRecipeEvent, CraftingRecipeIngredientParser, CraftingRecipesAvailableEvent, CraftingResultEvent, GetCraftableProductsComposer, GetCraftingRecipeComposer, GetRoomContentLoader, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomWidgetEnum } from '@nitrots/nitro-renderer';
import { useEffect, useState } from 'react';
import { ICraftingIngredient, ICraftingRecipe, LocalizeText, SendMessageComposer } from '../../../../api';
import { useMessageEvent, useNitroEvent } from '../../../events';
import { useInventoryFurni } from '../../../inventory';
import { useNotification } from './../../../notification';
const useFurnitureCraftingWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ recipes, setRecipes ] = useState<ICraftingRecipe[]>([]);
const [ selectedRecipe, setSelectedRecipe ] = useState<ICraftingRecipe>(null);
const [ ingredients, setIngredients ] = useState<ICraftingIngredient[]>([]);
const [ ingredientNames, setIngredientNames ] = useState<string[]>(null);
const [ cachedIngredients, setCachedIngredients ] = useState<Map<string, CraftingRecipeIngredientParser[]>>(new Map());
const [ isCrafting, setIsCrafting ] = useState(false);
const { groupItems = [], getItemsByType = null, activate = null, deactivate = null } = useInventoryFurni();
const { simpleAlert = null } = useNotification();
const requiredIngredients = ((selectedRecipe && cachedIngredients.get(selectedRecipe.name) || null));
const resetData = () =>
{
setRecipes([]);
setSelectedRecipe(null);
setIngredients([]);
setCachedIngredients(new Map());
};
const onClose = () =>
{
setObjectId(-1);
resetData();
};
const craft = () =>
{
setIsCrafting(true);
SendMessageComposer(new CraftComposer(objectId, selectedRecipe.name));
};
const selectRecipe = (recipe: ICraftingRecipe) =>
{
setSelectedRecipe(recipe);
const cache = cachedIngredients.get(recipe.name);
if(!cache) SendMessageComposer(new GetCraftingRecipeComposer(recipe.name));
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.OPEN_WIDGET, event =>
{
if(event.widget !== RoomWidgetEnum.CRAFTING) return;
setObjectId(event.objectId);
resetData();
SendMessageComposer(new GetCraftableProductsComposer(event.objectId));
});
useMessageEvent<CraftableProductsEvent>(CraftableProductsEvent, event =>
{
const parser = event.getParser();
if(!parser.isActive())
{
setObjectId(-1);
return;
}
setRecipes(prevValue =>
{
const newValue: ICraftingRecipe[] = [];
for(const recipe of parser.recipes)
{
//@ts-ignore
const itemId = GetRoomContentLoader()._activeObjectTypeIds.get(recipe.itemName);
const iconUrl = GetRoomEngine().getFurnitureFloorIconUrl(itemId);
newValue.push({
name: recipe.recipeName,
localizedName: LocalizeText('roomItem.name.' + itemId),
iconUrl
});
}
return newValue;
});
setIngredientNames(parser.ingredients);
});
useMessageEvent<CraftingRecipeEvent>(CraftingRecipeEvent, event =>
{
const parser = event.getParser();
setCachedIngredients(prevValue =>
{
const newValue = new Map(prevValue);
newValue.set(selectedRecipe.name, parser.ingredients);
return newValue;
});
});
useMessageEvent<CraftingResultEvent>(CraftingResultEvent, event =>
{
setSelectedRecipe(null);
setIsCrafting(false);
const parser = event.getParser();
if(parser.result) simpleAlert(LocalizeText('crafting.info.result.ok'));
});
useMessageEvent<CraftingRecipesAvailableEvent>(CraftingRecipesAvailableEvent, event =>
{
});
useEffect(() =>
{
if(!ingredientNames || !ingredientNames.length) return;
setIngredients(prevValue =>
{
const newValue: ICraftingIngredient[] = [];
for(const name of ingredientNames)
{
//@ts-ignore
const itemId = GetRoomContentLoader()._activeObjectTypeIds.get(name);
const iconUrl = GetRoomEngine().getFurnitureFloorIconUrl(itemId);
const inventoryItems = getItemsByType(itemId);
let amountAvailable = 0;
if(inventoryItems) for(const inventoryItem of inventoryItems) amountAvailable += inventoryItem.items.length;
newValue.push({
name: name,
iconUrl,
count: amountAvailable
});
}
return newValue;
});
}, [ groupItems, ingredientNames, getItemsByType ]);
useEffect(() =>
{
if((objectId === -1)) return;
const id = activate();
return () => deactivate(id);
}, [ objectId, activate, deactivate ]);
return { objectId, recipes, ingredients, selectedRecipe, requiredIngredients, isCrafting, selectRecipe, craft, onClose };
};
export const useFurnitureCraftingWidget = useFurnitureCraftingWidgetState;
@@ -0,0 +1,110 @@
import { GetSessionDataManager, RoomControllerLevel, RoomEngineDimmerStateEvent, RoomEngineTriggerWidgetEvent, RoomId, RoomSessionDimmerPresetsEvent } from '@nitrots/nitro-renderer';
import { useEffect, useState } from 'react';
import { DimmerFurnitureWidgetPresetItem, FurnitureDimmerUtilities } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useRoom } from '../../useRoom';
const useFurnitureDimmerWidgetState = () =>
{
const [ presets, setPresets ] = useState<DimmerFurnitureWidgetPresetItem[]>([]);
const [ selectedPresetId, setSelectedPresetId ] = useState(0);
const [ dimmerState, setDimmerState ] = useState(0);
const [ lastDimmerState, setLastDimmerState ] = useState(0);
const [ effectId, setEffectId ] = useState(0);
const [ color, setColor ] = useState(0xFFFFFF);
const [ brightness, setBrightness ] = useState(0xFF);
const [ selectedEffectId, setSelectedEffectId ] = useState(0);
const [ selectedColor, setSelectedColor ] = useState(0);
const [ selectedBrightness, setSelectedBrightness ] = useState(0);
const { roomSession = null } = useRoom();
const canOpenWidget = () => (roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator);
const selectPresetId = (id: number) =>
{
const preset = presets[(id - 1)];
if(!preset) return;
setSelectedPresetId(preset.id);
setSelectedEffectId(preset.type);
setSelectedColor(preset.color);
setSelectedBrightness(preset.light);
};
const applyChanges = () =>
{
if(dimmerState === 0) return;
const selectedPresetIndex = (selectedPresetId - 1);
if((selectedPresetId < 1) || (selectedPresetId > presets.length)) return;
const preset = presets[selectedPresetIndex];
if(!preset || ((selectedEffectId === preset.type) && (selectedColor === preset.color) && (selectedBrightness === preset.light))) return;
setPresets(prevValue =>
{
const newValue = [ ...prevValue ];
newValue[selectedPresetIndex] = new DimmerFurnitureWidgetPresetItem(preset.id, selectedEffectId, selectedColor, selectedBrightness);
return newValue;
});
FurnitureDimmerUtilities.savePreset(preset.id, selectedEffectId, selectedColor, selectedBrightness, true);
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, event =>
{
if(!canOpenWidget()) return;
roomSession.requestMoodlightSettings();
});
useNitroEvent<RoomSessionDimmerPresetsEvent>(RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS, event =>
{
const presets: DimmerFurnitureWidgetPresetItem[] = [];
let i = 0;
while(i < event.presetCount)
{
const preset = event.getPreset(i);
if(preset) presets.push(new DimmerFurnitureWidgetPresetItem(preset.id, preset.type, preset.color, preset.brightness));
i++;
}
setPresets(presets);
setSelectedPresetId(event.selectedPresetId);
});
useNitroEvent<RoomEngineDimmerStateEvent>(RoomEngineDimmerStateEvent.ROOM_COLOR, event =>
{
if(RoomId.isRoomPreviewerId(event.roomId)) return;
setLastDimmerState(dimmerState);
setDimmerState(event.state);
setSelectedPresetId(event.presetId);
setEffectId(event.effectId);
setSelectedEffectId(event.effectId);
setColor(event.color);
setSelectedColor(event.color);
setBrightness(event.brightness);
setSelectedBrightness(event.brightness);
});
useEffect(() =>
{
if((dimmerState === 0) && (lastDimmerState === 0)) return;
FurnitureDimmerUtilities.previewDimmer(selectedColor, selectedBrightness, (selectedEffectId === 2));
}, [ dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]);
return { presets, selectedPresetId, dimmerState, lastDimmerState, effectId, color, brightness, selectedEffectId, setSelectedEffectId, selectedColor, setSelectedColor, selectedBrightness, setSelectedBrightness, selectPresetId, applyChanges };
};
export const useFurnitureDimmerWidget = useFurnitureDimmerWidgetState;
@@ -0,0 +1,48 @@
import { FurnitureExchangeComposer, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { IsOwnerOfFurniture, SendMessageComposer } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
const useFurnitureExchangeWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ value, setValue ] = useState(0);
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setValue(0);
};
const redeem = () =>
{
SendMessageComposer(new FurnitureExchangeComposer(objectId));
onClose();
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject || !IsOwnerOfFurniture(roomObject)) return;
setObjectId(event.objectId);
setCategory(event.category);
setValue(roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_CREDIT_VALUE) || 0);
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, value, redeem, onClose };
};
export const useFurnitureExchangeWidget = useFurnitureExchangeWidgetState;
@@ -0,0 +1,74 @@
import { GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { IPhotoData } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
import { useRoom } from '../../useRoom';
const useFurnitureExternalImageWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ currentPhotoIndex, setCurrentPhotoIndex ] = useState(-1);
const [ currentPhotos, setCurrentPhotos ] = useState<IPhotoData[]>([]);
const { roomSession = null } = useRoom();
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setCurrentPhotoIndex(-1);
setCurrentPhotos([]);
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_EXTERNAL_IMAGE, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
const roomTotalImages = GetRoomEngine().getRoomObjects(roomSession?.roomId, RoomObjectCategory.WALL);
if(!roomObject) return;
const datas: IPhotoData[] = [];
roomTotalImages.forEach(object =>
{
if(object.type !== 'external_image_wallitem_poster_small') return null;
const data = object.model.getValue<string>(RoomObjectVariable.FURNITURE_DATA);
const jsonData: IPhotoData = JSON.parse(data);
datas.push(jsonData);
});
setObjectId(event.objectId);
setCategory(event.category);
setCurrentPhotos(datas);
const roomObjectPhotoData = (JSON.parse(roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_DATA)) as IPhotoData);
setCurrentPhotoIndex(prevValue =>
{
let index = 0;
if(roomObjectPhotoData)
{
index = datas.findIndex(data => (data.u === roomObjectPhotoData.u));
}
if(index < 0) index = 0;
return index;
});
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, currentPhotoIndex, currentPhotos, onClose };
};
export const useFurnitureExternalImageWidget = useFurnitureExternalImageWidgetState;
@@ -0,0 +1,75 @@
import { FriendFurniConfirmLockMessageComposer, GetRoomEngine, LoveLockFurniFinishedEvent, LoveLockFurniFriendConfirmedEvent, LoveLockFurniStartEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { SendMessageComposer } from '../../../../api';
import { useMessageEvent, useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
const useFurnitureFriendFurniWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ type, setType ] = useState(0);
const [ usernames, setUsernames ] = useState<string[]>([]);
const [ figures, setFigures ] = useState<string[]>([]);
const [ date, setDate ] = useState<string>(null);
const [ stage, setStage ] = useState(0);
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setType(0);
setUsernames([]);
setFigures([]);
setDate(null);
};
const respond = (flag: boolean) =>
{
SendMessageComposer(new FriendFurniConfirmLockMessageComposer(objectId, flag));
onClose();
};
useMessageEvent<LoveLockFurniStartEvent>(LoveLockFurniStartEvent, event =>
{
const parser = event.getParser();
setObjectId(parser.furniId);
setStage(parser.start ? 1 : 2);
});
useMessageEvent<LoveLockFurniFinishedEvent>(LoveLockFurniFinishedEvent, event => onClose());
useMessageEvent<LoveLockFurniFriendConfirmedEvent>(LoveLockFurniFriendConfirmedEvent, event => onClose());
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_ENGRAVING, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const data = roomObject.model.getValue<string[]>(RoomObjectVariable.FURNITURE_DATA);
const type = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_FRIENDFURNI_ENGRAVING);
if((data[0] !== '1') || (data.length !== 6)) return;
setObjectId(event.objectId);
setCategory(event.category);
setType(type);
setUsernames([ data[1], data[2] ]);
setFigures([ data[3], data[4] ]);
setDate(data[5]);
setStage(0);
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, type, usernames, figures, date, stage, onClose, respond };
};
export const useFurnitureFriendFurniWidget = useFurnitureFriendFurniWidgetState;
@@ -0,0 +1,55 @@
import { GetRoomEngine, HighScoreDataType, ObjectDataFactory, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { useNitroEvent } from '../../../events';
import { useRoom } from '../../useRoom';
const SCORE_TYPES = [ 'perteam', 'mostwins', 'classic' ];
const CLEAR_TYPES = [ 'alltime', 'daily', 'weekly', 'monthly' ];
const useFurnitureHighScoreWidgetState = () =>
{
const [ stuffDatas, setStuffDatas ] = useState<Map<number, HighScoreDataType>>(new Map());
const { roomSession = null } = useRoom();
const getScoreType = (type: number) => SCORE_TYPES[type];
const getClearType = (type: number) => CLEAR_TYPES[type];
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_HIGH_SCORE_DISPLAY, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const formatKey = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_DATA_FORMAT);
const stuffData = (ObjectDataFactory.getData(formatKey) as HighScoreDataType);
stuffData.initializeFromRoomObjectModel(roomObject.model);
setStuffDatas(prevValue =>
{
const newValue = new Map(prevValue);
newValue.set(roomObject.id, stuffData);
return newValue;
});
});
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_HIDE_HIGH_SCORE_DISPLAY, event =>
{
if(event.roomId !== roomSession.roomId) return;
setStuffDatas(prevValue =>
{
const newValue = new Map(prevValue);
newValue.delete(event.objectId);
return newValue;
});
});
return { stuffDatas, getScoreType, getClearType };
};
export const useFurnitureHighScoreWidget = useFurnitureHighScoreWidgetState;
@@ -0,0 +1,26 @@
import { CreateLinkEvent, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useNitroEvent } from '../../../events';
const INTERNALLINK = 'internalLink';
const useFurnitureInternalLinkWidgetState = () =>
{
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const data = roomObject.model.getValue<any>(RoomObjectVariable.FURNITURE_DATA);
let link = data[INTERNALLINK];
if(!link || !link.length) link = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_INTERNAL_LINK);
if(link && link.length) CreateLinkEvent(link);
});
return {};
};
export const useFurnitureInternalLinkWidget = useFurnitureInternalLinkWidgetState;
@@ -0,0 +1,80 @@
import { FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, GetAvatarRenderManager, GetRoomEngine, HabboClubLevelEnum, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { MannequinUtilities, SendMessageComposer } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
const useFurnitureMannequinWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ figure, setFigure ] = useState(null);
const [ gender, setGender ] = useState(null);
const [ clubLevel, setClubLevel ] = useState(HabboClubLevelEnum.NO_CLUB);
const [ name, setName ] = useState(null);
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setFigure(null);
setGender(null);
setName(null);
};
const saveFigure = () =>
{
if(objectId === -1) return;
SendMessageComposer(new FurnitureMannequinSaveLookComposer(objectId));
onClose();
};
const wearFigure = () =>
{
if(objectId === -1) return;
SendMessageComposer(new FurnitureMultiStateComposer(objectId));
onClose();
};
const saveName = () =>
{
if(objectId === -1) return;
SendMessageComposer(new FurnitureMannequinSaveNameComposer(objectId, name));
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const model = roomObject.model;
const figure = (model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_FIGURE) || null);
const gender = (model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_GENDER) || null);
const figureContainer = GetAvatarRenderManager().createFigureContainer(figure);
const figureClubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, gender, MannequinUtilities.MANNEQUIN_CLOTHING_PART_TYPES);
setObjectId(event.objectId);
setCategory(event.category);
setFigure(figure);
setGender(gender);
setClubLevel(figureClubLevel);
setName(model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_NAME) || null);
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, figure, gender, clubLevel, name, setName, saveFigure, wearFigure, saveName, onClose };
};
export const useFurnitureMannequinWidget = useFurnitureMannequinWidgetState;
@@ -0,0 +1,108 @@
import { AddJukeboxDiskComposer, AdvancedMap, FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListRemovedEvent, FurnitureMultiStateComposer, GetRoomEngine, GetSessionDataManager, GetSoundManager, IAdvancedMap, IMessageEvent, ISongInfo, NotifyPlayedSongEvent, NowPlayingEvent, PlayListStatusEvent, RemoveJukeboxDiskComposer, RoomControllerLevel, RoomEngineTriggerWidgetEvent, SongDiskInventoryReceivedEvent } from '@nitrots/nitro-renderer';
import { useCallback, useState } from 'react';
import { IsOwnerOfFurniture, LocalizeText, NotificationAlertType, NotificationBubbleType, SendMessageComposer } from '../../../../api';
import { useMessageEvent, useNitroEvent } from '../../../events';
import { useNotification } from '../../../notification';
import { useFurniRemovedEvent } from '../../engine';
import { useRoom } from '../../useRoom';
const useFurniturePlaylistEditorWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ currentPlayingIndex, setCurrentPlayingIndex ] = useState(-1);
const [ diskInventory, setDiskInventory ] = useState<IAdvancedMap<number, number>>(new AdvancedMap());
const [ playlist, setPlaylist ] = useState<ISongInfo[]>([]);
const { roomSession = null } = useRoom();
const { showSingleBubble = null, simpleAlert = null } = useNotification();
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
};
const addToPlaylist = useCallback((diskId: number, slotNumber: number) => SendMessageComposer(new AddJukeboxDiskComposer(diskId, slotNumber)), []);
const removeFromPlaylist = useCallback((slotNumber: number) => SendMessageComposer(new RemoveJukeboxDiskComposer(slotNumber)), []);
const togglePlayPause = useCallback((furniId: number, position: number) => SendMessageComposer(new FurnitureMultiStateComposer(furniId, position)), []);
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_PLAYLIST_EDITOR, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
if(IsOwnerOfFurniture(roomObject))
{
// show the editor
setObjectId(event.objectId);
setCategory(event.category);
GetSoundManager().musicController?.requestUserSongDisks();
GetSoundManager().musicController?.getRoomItemPlaylist()?.requestPlayList();
return;
}
if(roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator) SendMessageComposer(new FurnitureMultiStateComposer(event.objectId, -2));
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
useNitroEvent<NowPlayingEvent>(NowPlayingEvent.NPE_SONG_CHANGED, event =>
{
setCurrentPlayingIndex(event.position);
});
useNitroEvent<NotifyPlayedSongEvent>(NotifyPlayedSongEvent.NOTIFY_PLAYED_SONG, event =>
{
showSingleBubble(LocalizeText('soundmachine.notification.playing', [ 'songname', 'songauthor' ], [ event.name, event.creator ]), NotificationBubbleType.SOUNDMACHINE);
});
useNitroEvent<SongDiskInventoryReceivedEvent>(SongDiskInventoryReceivedEvent.SDIR_SONG_DISK_INVENTORY_RECEIVENT_EVENT, event =>
{
setDiskInventory(GetSoundManager().musicController?.songDiskInventory.clone());
});
useNitroEvent<PlayListStatusEvent>(PlayListStatusEvent.PLUE_PLAY_LIST_UPDATED, event =>
{
setPlaylist(GetSoundManager().musicController?.getRoomItemPlaylist()?.entries.concat());
});
useNitroEvent<PlayListStatusEvent>(PlayListStatusEvent.PLUE_PLAY_LIST_FULL, event =>
{
simpleAlert(LocalizeText('playlist.editor.alert.playlist.full'), NotificationAlertType.ALERT, '', '', LocalizeText('playlist.editor.alert.playlist.full.title'));
});
const onFurniListUpdated = (event : IMessageEvent) =>
{
if(objectId === -1) return;
if(event instanceof FurnitureListEvent)
{
if(event.getParser().fragmentNumber === 0)
{
GetSoundManager().musicController?.requestUserSongDisks();
}
}
else
{
GetSoundManager().musicController?.requestUserSongDisks();
}
};
useMessageEvent(FurnitureListEvent, onFurniListUpdated);
useMessageEvent(FurnitureListRemovedEvent, onFurniListUpdated);
useMessageEvent(FurnitureListAddOrUpdateEvent, onFurniListUpdated);
return { objectId, diskInventory, playlist, currentPlayingIndex, onClose, addToPlaylist, removeFromPlaylist, togglePlayPause };
};
export const useFurniturePlaylistEditorWidget = useFurniturePlaylistEditorWidgetState;
@@ -0,0 +1,235 @@
import { GetRoomEngine, GetSessionDataManager, IFurnitureData, IGetImageListener, PetFigureData, RoomEngineTriggerWidgetEvent, RoomObjectCategory, RoomObjectVariable, RoomSessionPresentEvent, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
import { useMemo, useState } from 'react';
import { IsOwnerOfFurniture, LocalizeText, ProductTypeEnum } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
import { useRoom } from '../../useRoom';
const FLOOR: string = 'floor';
const WALLPAPER: string = 'wallpaper';
const LANDSCAPE: string = 'landscape';
const POSTER: string = 'poster';
const useFurniturePresentWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ classId, setClassId ] = useState(-1);
const [ itemType, setItemType ] = useState<string>(null);
const [ text, setText ] = useState<string>(null);
const [ isOwnerOfFurniture, setIsOwnerOfFurniture ] = useState(false);
const [ senderName, setSenderName ] = useState<string>(null);
const [ senderFigure, setSenderFigure ] = useState<string>(null);
const [ placedItemId, setPlacedItemId ] = useState(-1);
const [ placedItemType, setPlacedItemType ] = useState<string>(null);
const [ placedInRoom, setPlacedInRoom ] = useState(false);
const [ imageUrl, setImageUrl ] = useState<string>(null);
const { roomSession = null } = useRoom();
const onClose = () =>
{
setObjectId(-1);
setClassId(-1);
setItemType(null);
setText(null);
setIsOwnerOfFurniture(false);
setSenderName(null);
setSenderFigure(null);
setPlacedItemId(-1);
setPlacedItemType(null);
setPlacedInRoom(false);
setImageUrl(null);
};
const openPresent = () =>
{
if(objectId === -1) return;
roomSession.openGift(objectId);
GetRoomEngine().changeObjectModelData(GetRoomEngine().activeRoomId, objectId, RoomObjectCategory.FLOOR, RoomObjectVariable.FURNITURE_DISABLE_PICKING_ANIMATION, 1);
};
const imageListener: IGetImageListener = useMemo(() =>
{
// async fix image
return {
imageReady: (id, texture, image) =>
{
(async () =>
{
if(!image && texture)
{
image = await TextureUtils.generateImage(texture);
}
setImageUrl(image.src);
})();
},
imageFailed: null
};
}, []);
useNitroEvent<RoomSessionPresentEvent>(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, event =>
{
let furniData: IFurnitureData = null;
if(event.itemType === ProductTypeEnum.FLOOR)
{
furniData = GetSessionDataManager().getFloorItemData(event.classId);
}
else if(event.itemType === ProductTypeEnum.WALL)
{
furniData = GetSessionDataManager().getWallItemData(event.classId);
}
let isOwnerOfFurni = false;
if(event.placedInRoom)
{
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, event.placedItemId, RoomObjectCategory.FLOOR);
if(roomObject) isOwnerOfFurni = IsOwnerOfFurniture(roomObject);
}
let giftImage: string = null;
switch(event.itemType)
{
case ProductTypeEnum.WALL: {
if(furniData)
{
switch(furniData.className)
{
case FLOOR:
case LANDSCAPE:
case WALLPAPER:
let imageType = null;
let message = null;
if(furniData.className === FLOOR)
{
imageType = 'packagecard_icon_floor';
message = LocalizeText('inventory.furni.item.floor.name');
}
else if(furniData.className === LANDSCAPE)
{
imageType = 'packagecard_icon_landscape';
message = LocalizeText('inventory.furni.item.landscape.name');
}
else
{
imageType = 'packagecard_icon_wallpaper';
message = LocalizeText('inventory.furni.item.wallpaper.name');
}
setText(message);
//setImageUrl(getGiftImageUrl(imageType));
break;
case POSTER: {
const productCode = event.productCode;
let extras: string = null;
if(productCode.indexOf('poster') === 0) extras = productCode.replace('poster', '');
const productData = GetSessionDataManager().getProductData(productCode);
let name: string = null;
if(productData) name = productData.name;
else if(furniData) name = furniData.name;
setText(name);
setImageUrl(GetRoomEngine().getFurnitureWallIconUrl(event.classId, extras));
break;
}
default: {
setText(furniData.name || null);
setImageUrl(GetRoomEngine().getFurnitureWallIconUrl(event.classId));
break;
}
}
}
break;
}
case ProductTypeEnum.HABBO_CLUB:
setText(LocalizeText('widget.furni.present.hc'));
//setImageUrl(getGiftImageUrl('packagecard_icon_hc'));
break;
default: {
if(event.placedItemType === ProductTypeEnum.PET)
{
const petfigureString = event.petFigureString;
if(petfigureString && petfigureString.length)
{
const petFigureData = new PetFigureData(petfigureString);
(async () =>
{
const petImage = GetRoomEngine().getRoomObjectPetImage(petFigureData.typeId, petFigureData.paletteId, petFigureData.color, new Vector3d(90), 64, imageListener, true, 0, petFigureData.customParts);
if(petImage) setImageUrl((await petImage.getImage()).src);
})();
}
}
else
{
(async () =>
{
const furniImage = GetRoomEngine().getFurnitureFloorImage(event.classId, new Vector3d(90), 64, imageListener);
if(furniImage) setImageUrl((await furniImage.getImage()).src);
})();
}
const productData = GetSessionDataManager().getProductData(event.productCode);
setText((productData && productData.name) || furniData.name);
break;
}
}
setObjectId(0);
setClassId(event.classId);
setItemType(event.itemType);
setIsOwnerOfFurniture(isOwnerOfFurni);
setPlacedItemId(event.placedItemId);
setPlacedItemType(event.placedItemType);
setPlacedInRoom(event.placedInRoom);
});
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_PRESENT, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return null;
onClose();
setObjectId(event.objectId);
setClassId(-1);
setText((roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_DATA) || ''));
setIsOwnerOfFurniture(IsOwnerOfFurniture(roomObject));
setSenderName((roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_PURCHASER_NAME) || null));
setSenderFigure((roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_PURCHASER_FIGURE) || null));
});
useFurniRemovedEvent((objectId !== -1), event =>
{
if(event.id === objectId) onClose();
if(event.id === placedItemId)
{
if(placedInRoom) setPlacedInRoom(false);
}
});
return { objectId, classId, itemType, text, isOwnerOfFurniture, senderName, senderFigure, placedItemId, placedItemType, placedInRoom, imageUrl, openPresent, onClose };
};
export const useFurniturePresentWidget = useFurniturePresentWidgetState;
@@ -0,0 +1,49 @@
import { GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { SendMessageComposer } from '../../../../api';
import { useMessageEvent, useNitroEvent } from '../../../events';
const INTERNALLINK = 'internalLink';
const useFurnitureRoomLinkWidgetState = () =>
{
const [ roomIdToEnter, setRoomIdToEnter ] = useState(0);
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const data = roomObject.model.getValue<any>(RoomObjectVariable.FURNITURE_DATA);
let roomId = data[INTERNALLINK];
if(!roomId || !roomId.length) roomId = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_INTERNAL_LINK);
if(!roomId || !roomId.length) return;
roomId = parseInt(roomId, 10);
if(isNaN(roomId)) return;
setRoomIdToEnter(roomId);
SendMessageComposer(new GetGuestRoomMessageComposer(roomId, false, false));
});
useMessageEvent<GetGuestRoomResultEvent>(GetGuestRoomResultEvent, event =>
{
if(!roomIdToEnter) return;
const parser = event.getParser();
if(parser.data.roomId !== roomIdToEnter) return;
setRoomIdToEnter(0);
});
return {};
};
export const useFurnitureRoomLinkWidget = useFurnitureRoomLinkWidgetState;
@@ -0,0 +1,59 @@
import { AddSpamWallPostItMessageComposer, GetRoomEngine, RequestSpamWallPostItMessageEvent, RoomObjectCategory } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { SendMessageComposer } from '../../../../api';
import { useMessageEvent } from '../../../events';
import { useInventoryFurni } from '../../../inventory';
const useFurnitureSpamWallPostItWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ itemType, setItemType ] = useState('');
const [ location, setLocation ] = useState('');
const [ color, setColor ] = useState('0');
const [ text, setText ] = useState('');
const [ canModify, setCanModify ] = useState(false);
const { getWallItemById = null } = useInventoryFurni();
const onClose = () =>
{
SendMessageComposer(new AddSpamWallPostItMessageComposer(objectId, location, color, text));
setObjectId(-1);
setCategory(-1);
setItemType('');
setLocation('');
setColor('0');
setText('');
setCanModify(false);
};
useMessageEvent<RequestSpamWallPostItMessageEvent>(RequestSpamWallPostItMessageEvent, event =>
{
const parser = event.getParser();
setObjectId(parser.itemId);
setCategory(RoomObjectCategory.WALL);
const inventoryItem = getWallItemById(parser.itemId);
let itemType = 'post_it';
if(inventoryItem)
{
const wallItemType = GetRoomEngine().getFurnitureWallName(inventoryItem.type);
if(wallItemType.match('post_it_')) itemType = wallItemType;
}
setItemType(itemType);
setLocation(parser.location);
setColor('FFFF33');
setText('');
setCanModify(true);
});
return { objectId, color, setColor, text, setText, canModify, onClose };
};
export const useFurnitureSpamWallPostItWidget = useFurnitureSpamWallPostItWidgetState;
@@ -0,0 +1,79 @@
import { FurnitureStackHeightComposer, FurnitureStackHeightEvent, GetRoomEngine, RoomEngineTriggerWidgetEvent } from '@nitrots/nitro-renderer';
import { useEffect, useState } from 'react';
import { CanManipulateFurniture, GetRoomSession, SendMessageComposer } from '../../../../api';
import { useMessageEvent, useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
const MAX_HEIGHT: number = 40;
const useFurnitureStackHeightWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ height, setHeight ] = useState(0);
const [ pendingHeight, setPendingHeight ] = useState(-1);
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setHeight(0);
setPendingHeight(-1);
};
const updateHeight = (height: number, server: boolean = false) =>
{
if(!height) height = 0;
height = Math.abs(height);
if(!server) ((height > MAX_HEIGHT) && (height = MAX_HEIGHT));
setHeight(parseFloat(height.toFixed(2)));
if(!server) setPendingHeight(height * 100);
};
useMessageEvent<FurnitureStackHeightEvent>(FurnitureStackHeightEvent, event =>
{
const parser = event.getParser();
if(objectId !== parser.furniId) return;
updateHeight(parser.height, true);
});
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_STACK_HEIGHT, event =>
{
if(!CanManipulateFurniture(GetRoomSession(), event.objectId, event.category)) return;
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
setObjectId(event.objectId);
setCategory(event.category);
setHeight(roomObject.getLocation().z);
setPendingHeight(-1);
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
useEffect(() =>
{
if((objectId === -1) || (pendingHeight === -1)) return;
const timeout = setTimeout(() => SendMessageComposer(new FurnitureStackHeightComposer(objectId, ~~(pendingHeight))), 10);
return () => clearTimeout(timeout);
}, [ objectId, pendingHeight ]);
return { objectId, height, maxHeight: MAX_HEIGHT, onClose, updateHeight };
};
export const useFurnitureStackHeightWidget = useFurnitureStackHeightWidgetState;
@@ -0,0 +1,85 @@
import { GetRoomEngine, GetSessionDataManager, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { GetRoomSession, IsOwnerOfFurniture } from '../../../../api';
import { useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
const useFurnitureStickieWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ color, setColor ] = useState('0');
const [ text, setText ] = useState('');
const [ type, setType ] = useState('');
const [ canModify, setCanModify ] = useState(false);
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setColor('0');
setText('');
setType('');
setCanModify(false);
};
const updateColor = (newColor: string) =>
{
if(newColor === color) return;
setColor(newColor);
GetRoomEngine().modifyRoomObjectData(objectId, category, newColor, text);
};
const updateText = (newText: string) =>
{
setText(newText);
GetRoomEngine().modifyRoomObjectData(objectId, category, color, newText);
};
const trash = () => GetRoomEngine().deleteRoomObject(objectId, category);
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
const data = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_ITEMDATA);
if(data.length < 6) return;
let color: string = null;
let text: string = null;
if(data.indexOf(' ') > 0)
{
color = data.slice(0, data.indexOf(' '));
text = data.slice((data.indexOf(' ') + 1), data.length);
}
else
{
color = data;
}
setObjectId(event.objectId);
setCategory(event.category);
setColor(color || '0');
setText(text || '');
setType(roomObject.type || 'post_it');
setCanModify(GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator || IsOwnerOfFurniture(roomObject));
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, color, text, type, canModify, updateColor, updateText, trash, onClose };
};
export const useFurnitureStickieWidget = useFurnitureStickieWidgetState;
@@ -0,0 +1,62 @@
import { GetRoomEngine, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
const useFurnitureTrophyWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ color, setColor ] = useState('1');
const [ senderName, setSenderName ] = useState('');
const [ date, setDate ] = useState('');
const [ message, setMessage ] = useState('');
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setColor('1');
setSenderName('');
setDate('');
setMessage('');
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_TROPHY, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
let data = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_DATA);
let extra = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_EXTRAS);
if(!extra) extra = '0';
setObjectId(event.objectId);
setCategory(event.category);
setColor(roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_COLOR) || '1');
const senderName = data.substring(0, data.indexOf('\t'));
data = data.substring((senderName.length + 1), data.length);
const trophyDate = data.substring(0, data.indexOf('\t'));
const trophyText = data.substr((trophyDate.length + 1), data.length);
setSenderName(senderName);
setDate(trophyDate);
setMessage(trophyText);
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, color, senderName, date, message, onClose };
};
export const useFurnitureTrophyWidget = useFurnitureTrophyWidgetState;
@@ -0,0 +1,127 @@
import { ControlYoutubeDisplayPlaybackMessageComposer, GetRoomEngine, GetSessionDataManager, GetYoutubeDisplayStatusMessageComposer, RoomEngineTriggerWidgetEvent, RoomId, SecurityLevel, SetYoutubeDisplayPlaylistMessageComposer, YoutubeControlVideoMessageEvent, YoutubeDisplayPlaylist, YoutubeDisplayPlaylistsEvent, YoutubeDisplayVideoMessageEvent } from '@nitrots/nitro-renderer';
import { useState } from 'react';
import { IsOwnerOfFurniture, SendMessageComposer, YoutubeVideoPlaybackStateEnum } from '../../../../api';
import { useMessageEvent, useNitroEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../engine';
const CONTROL_COMMAND_PREVIOUS_VIDEO = 0;
const CONTROL_COMMAND_NEXT_VIDEO = 1;
const CONTROL_COMMAND_PAUSE_VIDEO = 2;
const CONTROL_COMMAND_CONTINUE_VIDEO = 3;
const useFurnitureYoutubeWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ category, setCategory ] = useState(-1);
const [ videoId, setVideoId ] = useState<string>(null);
const [ videoStart, setVideoStart ] = useState<number>(null);
const [ videoEnd, setVideoEnd ] = useState<number>(null);
const [ currentVideoState, setCurrentVideoState ] = useState(-1);
const [ selectedVideo, setSelectedVideo ] = useState<string>(null);
const [ playlists, setPlaylists ] = useState<YoutubeDisplayPlaylist[]>(null);
const [ hasControl, setHasControl ] = useState(false);
const onClose = () =>
{
setObjectId(-1);
setCategory(-1);
setVideoId(null);
setVideoStart(null);
setVideoEnd(null);
setCurrentVideoState(-1);
setSelectedVideo(null);
setPlaylists(null);
setHasControl(false);
};
const previous = () => SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_PREVIOUS_VIDEO));
const next = () => SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_NEXT_VIDEO));
const pause = () => (hasControl && videoId && videoId.length) && SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_PAUSE_VIDEO));
const play = () => (hasControl && videoId && videoId.length) && SendMessageComposer(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, CONTROL_COMMAND_CONTINUE_VIDEO));
const selectVideo = (video: string) =>
{
if(selectedVideo === video)
{
setSelectedVideo(null);
SendMessageComposer(new SetYoutubeDisplayPlaylistMessageComposer(objectId, ''));
return;
}
setSelectedVideo(video);
SendMessageComposer(new SetYoutubeDisplayPlaylistMessageComposer(objectId, video));
};
useNitroEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_YOUTUBE, event =>
{
if(RoomId.isRoomPreviewerId(event.roomId)) return;
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
if(!roomObject) return;
setObjectId(event.objectId);
setCategory(event.category);
setHasControl(GetSessionDataManager().hasSecurity(SecurityLevel.EMPLOYEE) || IsOwnerOfFurniture(roomObject));
SendMessageComposer(new GetYoutubeDisplayStatusMessageComposer(event.objectId));
});
useMessageEvent<YoutubeDisplayVideoMessageEvent>(YoutubeDisplayVideoMessageEvent, event =>
{
const parser = event.getParser();
if((objectId === -1) || (objectId !== parser.furniId)) return;
setVideoId(parser.videoId);
setVideoStart(parser.startAtSeconds);
setVideoEnd(parser.endAtSeconds);
setCurrentVideoState(parser.state);
});
useMessageEvent<YoutubeDisplayPlaylistsEvent>(YoutubeDisplayPlaylistsEvent, event =>
{
const parser = event.getParser();
if((objectId === -1) || (objectId !== parser.furniId)) return;
setPlaylists(parser.playlists);
setSelectedVideo(parser.selectedPlaylistId);
setVideoId(null);
setCurrentVideoState(-1);
setVideoEnd(null);
setVideoStart(null);
});
useMessageEvent<YoutubeControlVideoMessageEvent>(YoutubeControlVideoMessageEvent, event =>
{
const parser = event.getParser();
if((objectId === -1) || (objectId !== parser.furniId)) return;
switch(parser.commandId)
{
case 1:
setCurrentVideoState(YoutubeVideoPlaybackStateEnum.PLAYING);
break;
case 2:
setCurrentVideoState(YoutubeVideoPlaybackStateEnum.PAUSED);
break;
}
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{
if((event.id !== objectId) || (event.category !== category)) return;
onClose();
});
return { objectId, videoId, videoStart, videoEnd, currentVideoState, selectedVideo, playlists, onClose, previous, next, pause, play, selectVideo };
};
export const useFurnitureYoutubeWidget = useFurnitureYoutubeWidgetState;