146 lines
3.8 KiB
TypeScript
146 lines
3.8 KiB
TypeScript
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);
|
|
}
|
|
} |