X7IQA5I46B6EHXPBIWTPCMZR4RZQ7PSJN5IMSEHA7H6F2NWQSNSQC
NXFHSO7QRL6QWEPDEK4E25UIYLH2HQX4BDWA5IHXSZQCGM6LV2YAC
BGASX3JPOPME4PSC34CHD5VLBZAQMXIAPZQ4DKCWZGEASXCKGW3AC
PZNEDCRDS5IBR7QDPHTW5HZRMQAZFIF7VB3IKWPZDC7IALHZKHWAC
FLGWAOMMMGBO5ICWD3SXBOGJQA6LL2ZHTIQIMGY5VNFAETKDPPYAC
EMED7UWAGESRTWJJWVXRL27O4XMBGZDDAU4LNVF3MQAYKFKRDNXQC
HXHNGFB2VCXB6YXDND35HJI22GBJC3QTSUR2TK3M3LXGJHVNXVHAC
TWWXXFP7B7ESYFOB5BOLLUSYTVPBDW33SISI4HZINYZ7ODRKPMPQC
Y7TNTUXM44MRLGA6FEG7J6BR77I7N3AIPZYVPXULOQZQ6PNOWJ7QC
PEQNQJYNX7QOEM67QH2UF7VZ43AXHUBO76DN77L43MEFRHVDBO5QC
PSY4Y3X4ZWLXR2FEDR2W5E4SW2ASS4BPBOT4W5TDLNU2NCFZISNAC
GIDOI5BK3WYIDEQL7SZTJPR3Q5TDQ34YHDPDCUFFH6PX4POEDSQQC
WPC667PRTGRE7BNP6E7ZCQIKXYMIHJT3LUTTQT7VX2HQVRBXNIKAC
WBAN6KIPMKEXHGGQGE3TB6G7YXHGOPT3HRCEUYZKLNJCJBMR7JHAC
WTINQMZSNRT5MSAXLMMZVM6OU6TMD4AP4OEUYAXZUFNY5IWFLZSQC
DPJCZOPIKAKQIS4YRXETBSJA5ZTL2KQESSJE2TEZFLRQARXUVFXQC
DJCKOKLLR6ROMDLANSOZVWTCRPQMMWAZYCABIT3CCTVWHCYQYSVAC
SJGRJWVRMIYRCSQUR4LMS2APZNSJ64JAW7647NYTB52REONXVD2QC
L72HFM6IYLNHEFEIFOQQQUAGMY2RN4POCV3Q3SMQERSQBMEZ5J3QC
Z5I5KK7NX6RS23QAB7ISLQCM5Z6TMVZK532NPSE7CO4MNXNKVKMAC
QTTO6EU2UCXVVPN724D2FUMGKJSEWTG7FXLOFNUB3IL3RVV3AVUAC
DNNKTYMMT2SXGZDMTFYZOQPZ3IX5EF6ESQAMGO5UUDFUA44FXMGAC
CZPLX4O4R7K3TF3NSAL5PT7NO3CUOLDY3OR332GBIYYNKMZTW24AC
B4JS4Z3VVAD5RJJ272S7GJM5BUNIHHMGNK2VSKVGZFPOVFP2YO4QC
J6PGLNNQWZU7S7QKFZ7QXLMSVIISQM6BHALJ6EU3JPMDXLAEB7OQC
DDJJXZKSQLXUXIMLKMKHY75JKC2IRA2A7SEVSUNL5FSCFH77T4IAC
6EXHALB3E5HP3IQVC47M4RVZE2JERJHX37GOOHPYIVAFBWSWUX7QC
ZHOSSPNKGFIKSFPDXCGLMSYMMX2J433VU2BUUWBKUH7TOLQUBSPQC
Z3E7XJOW6NSBDYRDKSGTOAEJSPATAUX4JUFCL4DIL3372GL4K52QC
DFFMZSJOCLTBA3IGRYS2ZIJNO2MC3VLBBU42QL5DFY2SMCNFXPIAC
WBDAIDQZ3J7ON5DWIDA2L4OJEEZCUP2RLEWJSNR4AC3SDBHDBXIQC
6REHBZAOJN4CVZY4HFXVNEUMWGQUXFTXMLQPXEH7RTH5FBL2TXIAC
ZGS4FTTFBXTF2SHYTPAJJBWEUVWVYXPSJVEFI5NYJWTW273B4NHAC
HUH4SI4HXIP72KQSJP2I4ELHX5KUQZM7FFGKZZGJ33DF7E3JHMYQC
GZRMSSTEWT3T2JERC7WCVT727X237UA6MXWVT6OSV5D5BRD4UOGQC
5NOOFT552GDEBDUACQZXG4TOLQSILGZEPGEJRS5BQD34TIJQ6T2QC
YBUOYJDAPDTPBG7F6QXYQDX53UFJ5WTHI32V6WOENCZIHZCPPLBQC
NJ3CLHJNB5S7K7XHXLMDGD3RDVIFIHYNDMFQJF3CUVMAK6E436YQC
OPUQ6NVYM2BN4H2FENH6EBGVU25XQBY2GRRZANPZEBEACZMDOGEAC
6OD22ZHHEANTKREVSWHHAWEDVUFWTZHUKJD35ICBPWYERYPABGDQC
3J7UJFGYFKBWC3IBUP32XODZND5ZLHZQJGXSYXMAW4DCREUOEOQAC
DHO4JCJIELKX4R42XXAMAHVQTTE6OWULLP2QF4BXO3UWC5UTMSMAC
import { Lazy } from "./lib/util/misc";
import { updaterGenerator2 } from "./lib/util/updaterGenerator";
import { DebugTab } from "./components/DebugTab";
let [batchedSetGameState, fireBatch] = useMemo(() => batchifySetState(setGameState), [setGameState]);
let updaters = useMemo(() => updaterGenerator2(initialGameState.get(), batchedSetGameState), [batchedSetGameState]);
let [batchedSetGameState, fireBatch] = useMemo(
() => batchifySetState(setGameState),
[setGameState]
);
let updaters = useMemo(
() => updaterGenerator2(initialGameState.get(), batchedSetGameState),
[batchedSetGameState]
);
import React from "react";
import { GameState, IntentName, PlayerIntentState } from "../data/GameState";
import { UpdaterGeneratorType2 } from "../lib/util/updaterGenerator";
type Props = {
updaters: UpdaterGeneratorType2<GameState>["intent"];
intent: PlayerIntentState;
};
type keyToIntentMap = {
[key in BrowserKeys]: IntentName;
};
type BrowserKeys = string;
const defaultKeyIntentConfig = {
ArrowUp: IntentName.PAN_UP,
ArrowLeft: IntentName.PAN_LEFT,
ArrowDown: IntentName.PAN_DOWN,
ArrowRight: IntentName.PAN_RIGHT,
"<": IntentName.TRAVEL_OUT,
">": IntentName.TRAVEL_IN,
};
type State = {
keyIntentConfig: keyToIntentMap;
};
export class KeyboardControlComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
keyIntentConfig: defaultKeyIntentConfig,
};
document.addEventListener("keydown", this.handleKeydown);
document.addEventListener("keyup", this.handleKeyup);
}
handleKeydown = (e: KeyboardEvent) => {
const keyIntentConfig = this.state.keyIntentConfig;
const key: BrowserKeys = e.key;
const configuredIntent = keyIntentConfig[key];
if (
configuredIntent !== undefined &&
configuredIntent !== IntentName.NOOP
) {
this.props.updaters.newIntent[configuredIntent].enqueueUpdate(
(wasNewIntent, prevGameState) => {
if (prevGameState.intent.activeIntent[configuredIntent])
return wasNewIntent;
this.props.updaters.newIntent[configuredIntent].enqueueUpdate(
() => false
);
return true;
}
);
this.props.updaters.activeIntent[configuredIntent].enqueueUpdate(
() => true
);
}
};
handleKeyup = (e: KeyboardEvent) => {
const keyIntentConfig = this.state.keyIntentConfig;
const key: BrowserKeys = e.key;
const configuredIntent = keyIntentConfig[key];
if (
configuredIntent !== undefined &&
configuredIntent !== IntentName.NOOP
) {
this.props.updaters.activeIntent[configuredIntent].enqueueUpdate(
() => false
);
this.props.updaters.endedIntent[configuredIntent].enqueueUpdate(() => {
this.props.updaters.endedIntent[configuredIntent].enqueueUpdate(
() => false
);
return true;
});
}
};
componentWillUnmount() {
document.removeEventListener("keydown", this.handleKeydown);
document.removeEventListener("keyup", this.handleKeyup);
}
render() {
return "hi";
}
}
import { HashMap, HashSet, KeyedHashMap } from "../lib/util/data_structures/hash"
import { Vector2 } from "../lib/util/geometry/vector2"
import {
HashMap,
HashSet,
KeyedHashMap,
} from "../lib/util/data_structures/hash";
import { Vector2 } from "../lib/util/geometry/vector2";
worldGen: WorldGenState,
playerSave: PlayerSaveState,
playerUI: PlayerUIState,
computed: ComputedState
worldGen: WorldGenState;
playerSave: PlayerSaveState;
playerUI: PlayerUIState;
computed: ComputedState;
intent: PlayerIntentState;
};
export type PlayerIntentState = {
activeIntent: Intent;
newIntent: Intent;
endedIntent: Intent;
};
export type Intent = {
[name in IntentName]: boolean;
};
export enum IntentName {
NOOP = "NOOP",
PAN_UP = "PAN_UP",
PAN_DOWN = "PAN_DOWN",
PAN_LEFT = "PAN_LEFT",
PAN_RIGHT = "PAN_RIGHT",
TRAVEL_IN = "TRAVEL_IN",
TRAVEL_OUT = "TRAVEL_OUT",
description: string | undefined,
resourceType: ResourceType,
resourceAmount: number,
}
description: string | undefined;
resourceType: ResourceType;
resourceAmount: number;
};
selectedPointNode: PointNodeRef | undefined,
activeTab: number,
}
selectedPointNode: PointNodeRef | undefined;
activeTab: number;
};
orientation: "original" | "rotated", // rotated === we are forcing landscape-in-portrait
innerWidth: number,
innerHeight: number,
}
orientation: "original" | "rotated"; // rotated === we are forcing landscape-in-portrait
innerWidth: number;
innerHeight: number;
};
playerResourceAmounts?: { [k in ResourceType]: number }
playerResourceNodesAggregated?: HashMap<ResourceTypeAndModifier, number>
}
playerResourceAmounts?: { [k in ResourceType]: number };
playerResourceNodesAggregated?: HashMap<ResourceTypeAndModifier, number>;
};
const activeIntent = props.gameState.intent.activeIntent;
let deltaX = 0;
let deltaY = 0;
const unit = 5;
if (activeIntent[IntentName.PAN_DOWN]) deltaY += -unit;
if (activeIntent[IntentName.PAN_LEFT]) deltaX += unit;
if (activeIntent[IntentName.PAN_RIGHT]) deltaX += -unit;
if (activeIntent[IntentName.PAN_UP]) deltaY += unit;
if (deltaX) this.actionStage.x += deltaX;
if (deltaY) this.actionStage.y += deltaY;