GIDOI5BK3WYIDEQL7SZTJPR3Q5TDQ34YHDPDCUFFH6PX4POEDSQQC
XIWBV6OZXBNUEDNRH2ERMXBLKDV3JNZILXG2ZDZDDGVMXSTX3HEAC
QTTO6EU2UCXVVPN724D2FUMGKJSEWTG7FXLOFNUB3IL3RVV3AVUAC
TWWXXFP7B7ESYFOB5BOLLUSYTVPBDW33SISI4HZINYZ7ODRKPMPQC
Y7TNTUXM44MRLGA6FEG7J6BR77I7N3AIPZYVPXULOQZQ6PNOWJ7QC
HXHNGFB2VCXB6YXDND35HJI22GBJC3QTSUR2TK3M3LXGJHVNXVHAC
ED3IWKTSVYYD52TWW5TOC4H63YZ7FTO3E53YO5NELPG5I3RLRAYAC
PEQNQJYNX7QOEM67QH2UF7VZ43AXHUBO76DN77L43MEFRHVDBO5QC
WBAN6KIPMKEXHGGQGE3TB6G7YXHGOPT3HRCEUYZKLNJCJBMR7JHAC
FLGWAOMMMGBO5ICWD3SXBOGJQA6LL2ZHTIQIMGY5VNFAETKDPPYAC
DJCKOKLLR6ROMDLANSOZVWTCRPQMMWAZYCABIT3CCTVWHCYQYSVAC
WPC667PRTGRE7BNP6E7ZCQIKXYMIHJT3LUTTQT7VX2HQVRBXNIKAC
DPJCZOPIKAKQIS4YRXETBSJA5ZTL2KQESSJE2TEZFLRQARXUVFXQC
Z5I5KK7NX6RS23QAB7ISLQCM5Z6TMVZK532NPSE7CO4MNXNKVKMAC
5NOOFT552GDEBDUACQZXG4TOLQSILGZEPGEJRS5BQD34TIJQ6T2QC
Z3E7XJOW6NSBDYRDKSGTOAEJSPATAUX4JUFCL4DIL3372GL4K52QC
6EXHALB3E5HP3IQVC47M4RVZE2JERJHX37GOOHPYIVAFBWSWUX7QC
GZRMSSTEWT3T2JERC7WCVT727X237UA6MXWVT6OSV5D5BRD4UOGQC
TQ57VE45BHV7MOZ6GKTYZEAMAOTXLPQ3ROCWJ2FUCITQWOYVMUIAC
3UFL673QX2JG7KHTAM7DFH4BBYVHDNMXBS2RW45G3JBNFZFLSRRQC
NKWFGTCM6HM35MAJAREANFQS76ALYOD7K6FT77X5HQPBCRAPXVRAC
NIYF4R7SECNOBIZNKAR627Q5BW7ANIFCKKKPHOM2OZIBVEGYWWZQC
3J7QNHQ4F2VBYCK6SWKPO3AW3YYAJZNWOW6XNSURSRDZOE2ZIGQAC
WO2ALETBVNH7N3NXJ6JKWCQ2YIZN6LBO7WEXPHAT3EQQJEUCJITQC
L72HFM6IYLNHEFEIFOQQQUAGMY2RN4POCV3Q3SMQERSQBMEZ5J3QC
GJGKS2YPL6XOT4CLQ2NVHUU2W7MDHYE2XC77WWRGPBCPSTWZ5GIAC
import { GameState } from "../data/GameState";
import { UpdaterGeneratorType2 } from "../lib/util/updaterGenerator";
import { GameState, PlayerSaveState, PointNodeRef } from "../data/GameState";
import { canAllocate } from "./Neighbors";
// Things that should happen after allocation history is appended to , in order to maintain the game state in a good state
export function afterAppendAllocationHistory(updaters: UpdaterGeneratorType2<GameState>) {
updaters.playerSave.enqueueUpdate((prev, prevGameState) => {
let justAllocated = prevGameState.playerSave.justAllocated; // we are assuming that someone verified that this is good2go
if (!justAllocated) { return prev; }
export function doTryAllocate(prev: PlayerSaveState, prevGameState: GameState, selfPointNodeRef: PointNodeRef): [PlayerSaveState, boolean] {
if (canAllocate(
selfPointNodeRef,
prevGameState.worldGen,
prevGameState.playerSave.allocatedPointNodeSet,
prevGameState.playerSave.availableSp
) === 'yes') {
// do the change
const nextSet = prev.allocatedPointNodeSet.clone();
nextSet.put(selfPointNodeRef);
const nextHistory = [...prev.allocatedPointNodeHistory];
nextHistory.push(selfPointNodeRef);
let availableSp = prev.availableSp - 1;
return [{
...prev,
allocatedPointNodeHistory: nextHistory,
allocatedPointNodeSet: nextSet,
availableSp
}, true];
} else {
return [prev, false];
}
}
let prevSet = prev.allocatedPointNodeSet;
if (!prevSet.contains(justAllocated)) { // if it's new, add it to history, set, and decrement sp
const nextSet = prev.allocatedPointNodeSet.clone();
nextSet.put(justAllocated);
const nextHistory = [...prev.allocatedPointNodeHistory];
nextHistory.push(justAllocated);
let availableSp = prev.availableSp - 1;
return {
...prev,
allocatedPointNodeHistory: nextHistory,
allocatedPointNodeSet: nextSet,
availableSp
};
}
return prev;
});
export function afterMaybeSpendingSp(prev: PlayerSaveState, prevGameState: GameState): PlayerSaveState {
if (prev.availableSp === 0 && prev.activeQuest) {
return {
...prev,
availableSp: 5,
batchesSinceQuestStart: prev.batchesSinceQuestStart + 1
};
}
return prev;
}
/**
* Same use case and types as [batchify], however, specifically we expect [fn] to be a setState function which takes value-or-callback
* as its single argument, and instead of calling [fn] repeatedly for each callback in the batch, we apply the callbacks in the batch
* sequentially to get a single state update which we then provide to [fn].
*/
export function batchifySetState<T>(
fn: (arg: T) => void
): [((arg: T) => void), () => void] {
let batch: T[] = [];
return [(arg: T) => {
batch.push(arg);
console.log({ batchSize: batch.length });
}, (() => {
if (batch.length === 0) {
return;
}
console.log({ fired: batch.length });
let thisBatch = [...batch];
batch = [];
(fn as any)((prev: any) => {
let next = prev;
for (let valueOrCallback of thisBatch) {
if (typeof valueOrCallback === 'function') {
next = valueOrCallback(next);
} else {
next = valueOrCallback;
}
}
return next;
});
})]
updaters.playerSave.justAllocated.enqueueUpdate((prev: PointNodeRef | undefined, prevGameState) : PointNodeRef | undefined => {
// if we were already selected, but not yet allocated, allocate us and add to the history (maybe this should be managed elsewhere??)
if (prevGameState.playerUI.selectedPointNode?.pointNodeId === args.selfPointNodeRef.pointNodeId) {
if (canAllocate(
args.selfPointNodeRef,
prevGameState.worldGen,
prevGameState.playerSave.allocatedPointNodeSet,
prevGameState.playerSave.availableSp
) === 'yes') {
return args.selfPointNodeRef;
// update selected to ourselves
updaters.playerUI.selectedPointNode.enqueueUpdate((prev, gameState) => {
if (prev?.pointNodeId === args.selfPointNodeRef.pointNodeId) {
this.state.justTriedToAllocate = true;
}
return args.selfPointNodeRef;
});
// if we tried to allocate ourselves, see if we can
updaters.playerSave.enqueueUpdate((prev, prevGameState) => {
if (this.state.justTriedToAllocate) {
this.state.justTriedToAllocate = false;
let [next, succeeded] = doTryAllocate(prev, prevGameState, args.selfPointNodeRef);
if (succeeded) {
this.state.justSpentSp = true;
return next;
// whether or not we successfully allocated, run this just in case
afterAppendAllocationHistory(updaters);
// if we spent sp, remember to update quest status and such
updaters.playerSave.enqueueUpdate((prev, prevGameState) => {
if (this.state.justSpentSp) {
this.state.justSpentSp = false;
return afterMaybeSpendingSp(prev, prevGameState);
}
return prev;
})
// update selected to ourselves
updaters.playerUI.selectedPointNode.enqueueUpdate((prev, gameState) => {
return args.selfPointNodeRef;
})
// if we failed to allocate, shift the active tab so the player can see why
updaters.playerUI.activeTab.enqueueUpdate((prev, prevGameState) => {
if (this.state.justFailedToAllocate) {
this.state.justFailedToAllocate = false;
return 1;
}
return prev;
});