import {
HashMap,
} from "../lib/util/data_structures/hash";
import { enumKeys } from "../lib/util/misc";
import { PlayerSaveState } from "./PlayerSaveState";
import { PointNodeRef} from "./PointNodeRef";
import { ResourceModifier, ResourceNontrivialType, ResourceType, WorldGenState } from "./WorldGenState";
export { PointNodeRef, ChunkRef } from "./PointNodeRef";
export type { PlayerSaveState, Quest } from "./PlayerSaveState";
export type { WorldGenState, ChunkGen, ZLevelGen,PointNodeGen, } from "./WorldGenState";
export { ChunkGenConstants, ResourceModifier, ResourceNontrivialType, ResourceType } from "./WorldGenState";
/**
* Data owned by the master "App" component, to be made available as props to ALL subcomponents (both pixi and react); react uses context providers to make this easier
* 1. world generation data, stuff that was computed off of the random seed and is stored so we can do logic off of it,
* but can be deleted/recomputed any time.
* May or may not be persisted to disk - unimportant apart from the random seed.
* 2. data about player activity in the game e.g. which nodes were allocated, what quest stage they are on
* Must be persisted to disk - this is essentially the player's "save file"
* 3. data about player activity that only influences the UI, e.g. which node was selected, but affects UI across
* very far away pixi/react components.
* Should be persisted to disk - will help the player "remember their place" in the game, but not a big deal if lost.
* 4. data about the window display - should never be persisted to disk.
* 5. data that is computed from other data - no need to persist to disk.
*
* Does NOT include UI data which is only relevant to a small part of the component hierarchy - e.g. how many seconds since last tap.
* That data should belong in state owned by subcomponents.
*/
export type GameState = {
worldGen: WorldGenState;
playerSave: PlayerSaveState;
playerUI: PlayerUIState;
computed: ComputedState;
intent: PlayerIntentState;
};
/**
* Player intents == what they want to do when they press certain mouse/keyboard keys. This is decoupled
* from their actual keyboard keys to make remapping easier.
*/
export type PlayerIntentState = {
activeIntent: Intent;
newIntent: Intent;
endedIntent: Intent;
};
export type Intent = {
[name in IntentName]: boolean;
};
export enum IntentName {
// Default intent - does nothing
NOOP = "NOOP",
PAN_NORTH = "PAN_NORTH",
PAN_SOUTH = "PAN_SOUTH",
PAN_WEST = "PAN_WEST",
PAN_EAST = "PAN_EAST",
TRAVEL_IN = "TRAVEL_IN",
TRAVEL_OUT = "TRAVEL_OUT",
}
export const noIntent = enumKeys(IntentName).reduce((object: Intent, key) => {
object[key] = false;
return object;
}, {} as Intent);
/**
* current window settings -- allows for dynamic resizing and also rotation on mobile web
*/
export type WindowState = {
orientation: "original" | "rotated"; // rotated === we are forcing landscape-in-portrait
innerWidth: number;
innerHeight: number;
};
export type ComputedState = {
playerResourceAmounts?: { [k in ResourceType]: number };
playerResourceNodesAggregated?: HashMap<ResourceTypeAndModifier, number>;
};
export class ResourceTypeAndModifier {
public type: ResourceNontrivialType;
public modifier: ResourceModifier;
constructor(args: {
type: ResourceNontrivialType;
modifier: ResourceModifier;
}) {
this.type = args.type;
this.modifier = args.modifier;
}
public hash(): string {
return this.type.toString() + "," + this.modifier.toString();
}
}
export type PlayerUIState = {
selectedPointNode: PointNodeRef | undefined;
activeTab: number;
};