import { makeAutoObservable } from "mobx"; import { WorldFactory } from "../model/worldFactory"; import type { ObjectType, RunningGameState, Scene, World } from "../types"; import { CharacterState } from "./character"; import type { Pos3 } from "../types/3d"; import { clone } from "../utils"; import type { VoxelType } from "../types/voxel"; import { state } from "./root"; import { DEFAULT_VOXEL_TYPES } from "../model/defaultVoxelTypes"; export class WorldState { public data: World = WorldFactory.create(); public character = new CharacterState(this); constructor() { makeAutoObservable(this); } public reset() { state.worldEditor.resetSelectedObject(); this.data = WorldFactory.create(); } public loadMock() { const objTypeId = 'test1'; const voxelTypeId = 'glass'; const objectId1 = 'object1'; const objectId2 = 'object2'; this.data = { objectTypes: { [objTypeId]: { id: objTypeId, name: 'Test Object', voxels: [ { typeId: voxelTypeId, position: [0, 0, 0], }, ], }, }, voxelTypes: DEFAULT_VOXEL_TYPES, editorCamera: { position: [0, 2, 10], look: [0, 0, 0], }, initialScene: { character: { position: [0, 0, 0], look: [0, 0, 0], }, objects: { [objectId1]: { id: objectId1, typeId: objTypeId, position: [0, 0, 0], rotation: [0, 0, 0], scale: [1, 1, 1], }, [objectId2]: { id: objectId2, typeId: objTypeId, position: [1, 0, 0], rotation: [0, 0, 0], scale: [1, 1, 1], }, }, }, gameRules: { gravity: true, }, state: { playing: false, }, }; state.worldEditor.resetSelectedObject(); this.save(); } public load() { this.data = WorldFactory.load() ?? WorldFactory.create(); state.worldEditor.resetSelectedObject(); } public save(): void { WorldFactory.save(this.data); } public get isPlaying(): boolean { return this.data.state.playing; } public get currentScene(): Scene { return this.isPlaying ? (this.data.state as RunningGameState).scene : this.data.initialScene; } public get currentCamera(): Pos3 { return this.isPlaying ? (this.data.state as RunningGameState).scene.character : this.data.editorCamera; } public tick(_delta: number) { if (!this.isPlaying) return; //TODO } public play(): void { if (this.isPlaying) { const state = clone(this.data.state) as RunningGameState; state.paused = false; this.data.state = state; } else { this.data.state = { playing: true, paused: false, time: 0, scene: clone(this.data.initialScene), } } state.worldEditor.resetSelectedObject(); } public pause(): void { if (!this.isPlaying) return; const state = clone(this.data.state) as RunningGameState; state.paused = true; this.data.state = state; } public stop(): void { if (!this.isPlaying) return; this.data.state = { playing: false }; } public getObjectTypeById(id: string): ObjectType | undefined { return this.data.objectTypes[id]; } public getVoxelTypeById(id: string): VoxelType | undefined { return this.data.voxelTypes[id]; } }