import { makeAutoObservable } from "mobx"; import { WorldFactory } from "../model/worldFactory"; import type { ObjectType, RunningGameState, Scene, World } from "../types"; import { CharacterState } from "./character"; import type { Pos3, V3 } from "../types/3d"; import { clone, randomId } from "../utils"; import type { VoxelType } from "../types/voxel"; import { state } from "./root"; export class WorldState { public data: World = WorldFactory.create(); public character = new CharacterState(this); constructor() { this.load(); makeAutoObservable(this); } public reset() { this.data = WorldFactory.create(); } public loadMock() { this.data = { objectTypes: [ { id: 'test1', name: 'Test Object', voxels: [ { typeId: 'red', position: [0, 0, 0], color: 'red', opacity: 1, }, ], }, ], voxelTypes: [ { id: 'red', collidable: true, name: 'Red', opacity: 1, color: 'red', } ], editorCamera: { position: [0, 2, 10], look: [0, 0, 0], }, intialScene: { character: { position: [0, 0, 0], look: [0, 0, 0], }, objects: [ { id: randomId(), typeId: 'test1', position: [0, 0, 0], rotation: [0, 0, 0], }, ], }, gameRules: { gravity: true, }, state: { playing: false, }, }; } public load() { this.data = WorldFactory.load() ?? WorldFactory.create(); } 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.intialScene; } 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.intialScene), } } state.worldEditor.setSelectedObjectId(undefined); } 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.find((obj) => obj.id === id); } public getVoxelTypeById(id: string): VoxelType | undefined { return this.data.voxelTypes.find((obj) => obj.id === id); } }