diff --git a/src/core/game.ts b/src/core/game.ts index 0afba2f..c0fe78b 100644 --- a/src/core/game.ts +++ b/src/core/game.ts @@ -57,7 +57,8 @@ import { useServer, useState, useWO, - useQuestion + useQuestion, + useAlternative } from "@utils"; import type { Entity, GameObject } from "@world"; import { ConflictResolverPlugin } from "@plugins"; @@ -424,6 +425,9 @@ export class Game implements IGame { useState.prototype.game = this useWO.prototype.game = this useQuestion.prototype.game = this + + if (!useAlternative.prototype) useAlternative.prototype = { game: this } + else useAlternative.prototype.game = this } } diff --git a/src/utils/hooks/index.ts b/src/utils/hooks/index.ts index 909fbb3..dbf00f3 100644 --- a/src/utils/hooks/index.ts +++ b/src/utils/hooks/index.ts @@ -6,4 +6,5 @@ export * from "./use-async-state.hook.js" export * from "./use-server.hook.js" export * from "./use-state.hook.js" export * from "./use-wo.hook.js" -export * from "./use-question.hook.js" \ No newline at end of file +export * from "./use-question.hook.js" +export * from "./use-alternative.hook.js" \ No newline at end of file diff --git a/src/utils/hooks/use-alternative.hook.ts b/src/utils/hooks/use-alternative.hook.ts new file mode 100644 index 0000000..97b5c34 --- /dev/null +++ b/src/utils/hooks/use-alternative.hook.ts @@ -0,0 +1,21 @@ +import { Game } from "@core"; +import type { ICommand } from "@interfaces"; +import { AsyncPlugin } from "@plugins"; + +/** + * This hook allows you to client-side prediction command + * Command will be executed in alternative game + * @param command - Command to execute in alternative world + * @param core - Game reference if hydration disabled + * @returns { Promise } - Alternative isolated game (not affect real) + */ +export async function useAlternative(command: ICommand, core?: Game): Promise { + const game = useAlternative.prototype.game as Game || core + + const asyncPlugin = new AsyncPlugin() + const alternative = Game.fromSnapshot(game.save(), alternative => alternative.registerPlugin(asyncPlugin)) + + await asyncPlugin.asyncExecute(command) + + return alternative +} \ No newline at end of file diff --git a/test/gametest.ts b/test/gametest.ts index 580ca75..f205337 100644 --- a/test/gametest.ts +++ b/test/gametest.ts @@ -6,7 +6,7 @@ import { BASE_SEARCH_RADIUS, USE_VALIDATION_EVENT_PREFIX, USE_VISIBILITY_EVENT } import { BluePrintsFactory, EffectFactory, IteractionsFactory, QuestsFactory, SoundsFactory } from "@factories"; import { loggerMiddleware } from "@middlewares"; import { RegenerationPlugin, NetworkPlguin, AsyncPlugin, GraphicPlugin } from "@plugins"; -import { useVisibility, checkTwoPositions, useValidation, useLink, useAsyncState, useServer, useState, useWO, useQuestion } from "@utils"; +import { useVisibility, checkTwoPositions, useValidation, useLink, useAsyncState, useServer, useState, useWO, useQuestion, useAlternative } from "@utils"; const [game, manager, map] = createGame({ usingEntityMiddlewares: true, @@ -417,6 +417,16 @@ async function checkAsyncPlugin() { console.log(game.options.store.get('async'), 'ASYNC RESULT') } +console.log((await useAlternative({ + type: CommandType.SET_STATE, + tick: game.currentTick, + data: { + key: 'alternative', + value: true + } +})).options.store.get('alternative'), 'ALTERNATIVE') +console.log(game.options.store.get('alternative')) + checkAsyncPlugin() game.options.store.set('isNight', false)