5180 fichiers 38.5 Mo 0 téléchargements 427 vues mis à jour il y a 7 heures ui
nitro-v36-with-renderer-v36 / src / hooks / rooms / widgets / furniture / useFurnitureCraftingWidget.ts
useFurnitureCraftingWidget.ts 5.8 Ko Télécharger le fichier
import {
    CraftableProductsEvent,
    CraftComposer,
    CraftingRecipeEvent,
    CraftingRecipeIngredientParser,
    CraftingRecipesAvailableEvent,
    CraftingResultEvent,
    GetCraftableProductsComposer,
    GetCraftingRecipeComposer,
    GetRoomContentLoader,
    GetRoomEngine,
    RoomEngineTriggerWidgetEvent,
    RoomWidgetEnum
} from '@octane/renderer';
import { useEffect, useRef, useState } from 'react';
import { ICraftingIngredient, ICraftingRecipe, LocalizeText, SendMessageComposer } from '../../../../api';
import { useMessageEvent, useOctaneEvent } 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 requestedRecipesRef = useRef<string[]>([]);
    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());
        requestedRecipesRef.current = [];
    };

    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) {
            requestedRecipesRef.current.push(recipe.name);
            SendMessageComposer(new GetCraftingRecipeComposer(recipe.name));
        }
    };

    useOctaneEvent<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();
        // The answer carries no recipe name; the server answers in order, so it belongs to the oldest request. It
        // was filed under the recipe selected now: two quick clicks put one recipe's ingredients under the other,
        // and with nothing selected the widget threw.
        const recipeName = requestedRecipesRef.current.shift();

        if (!recipeName) return;

        setCachedIngredients((prevValue) => {
            const newValue = new Map(prevValue);

            newValue.set(recipeName, 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;
15Sujets
1Dépôts
20Membres
3En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser