Skip to content

Commit

Permalink
Merge pull request #24 from Zemnmez/save-format
Browse files Browse the repository at this point in the history
save format
  • Loading branch information
Zemnmez authored Aug 23, 2021
2 parents 63f2606 + b4c5711 commit 4efe737
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 22 deletions.
2 changes: 2 additions & 0 deletions cultist/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from '//cultist/types';
export * as action from '//cultist/actions';
export * as save from '//cultist/save';
export * as state from '//cultist/state';
export { Action } from '//cultist/actions';
11 changes: 3 additions & 8 deletions cultist/savestate.ts → cultist/save.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ export interface ElementInstance {
lastTablePosY?: string;
markedForConsumption?: string;
elementId?: string;
quantity: string;
quantity?: string;
}

export interface SaveState {
export interface State {
elementStacks?: Record<string, ElementInstance>;
decks?: Record<string, Deck>;
metainfo?: {
Expand Down Expand Up @@ -70,12 +70,7 @@ export interface Situation {
recipeId?: string | null;
situationWindowX?: string;
state?: string;
situationOutputNotes?: Record<
string,
{
title?: string;
}
>;
situationOutputNotes?: Record<string, { title?: string }>;
situationWindowOpen?: string;
completioncount?: string;
}
6 changes: 6 additions & 0 deletions cultist/save_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import SaveStateExample from '//cultist/example/savestate';
import * as save from '//cultist/save';

test('savestate', () => {
const test: save.State = SaveStateExample;
});
6 changes: 0 additions & 6 deletions cultist/savestate_test.ts

This file was deleted.

168 changes: 168 additions & 0 deletions cultist/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/**
* @fileoverview like save state, but more sane.
*/

import * as save from '//cultist/save';

export interface State {
elementStacks?: {
[name: string]: ElementInstance;
};

decks?: {
[name: string]: Deck;
};

metainfo?: {
VERSIONNUMBER?: string;
};

characterDetails?: CharacterDetails;

situations?: {
[name: string]: Situation;
};
}

function dictMap<V, O>(
o: { [key: string]: V },
f: (v: V) => O
): { [key: string]: O } {
return Object.assign(
{},
...Object.entries(o).map(([n, el]) => ({ [n]: f(el) }))
);
}

export function serializeState(s: State): save.State {
return {
...s,
elementStacks: optionalChain(dictMap)(
s.elementStacks,
serializeElementInstance
),
decks: optionalChain(dictMap)(s.decks, serializeDeck),
situations: optionalChain(dictMap)(s.situations, SerializeSituation),
};
}

export interface ElementInstance {
/** Time in seconds */
lifetimeRemaining?: number;
lastTablePosX?: number;
lastTablePosY?: number;
/** Will be destroyed when recipe completes */
markedForConsumption?: boolean;
elementId?: string;
quantity?: number;
}

function optionalChain<T, O, P extends unknown[]>(f: (v: T, ...a: P) => O) {
return (v: T | undefined, ...a: P) => {
if (v === undefined) return undefined;
return f(v, ...a);
};
}

export function serializeBoolean(b: boolean): string {
return b ? 'True' : 'False';
}

export function serializeElementInstance(
e: ElementInstance
): save.ElementInstance {
return {
...e,
lifetimeRemaining: e.lifetimeRemaining?.toString(),
lastTablePosX: e.lastTablePosX?.toString(),
lastTablePosY: e.lastTablePosY?.toString(),
markedForConsumption: optionalChain(serializeBoolean)(
e.markedForConsumption
),
quantity: e.quantity?.toString(),
};
}

export interface Deck {
eliminatedCards: string[];
cards: string[];
}

function serializeDeck({ eliminatedCards, cards }: Deck): save.Deck {
return {
eliminatedCards,
...Object.assign(
{},
...cards.map(([card, index]) => ({ [index]: card }))
),
};
}

export interface Levers {
lastheadquarters?: string;
lastfollower?: string;
lastsignificantpainting?: string;
lastpersonkilled?: string;
lastcharactername?: string;
lastcult?: string;
lasttool?: string;
lastbook?: string;
lastdesire?: string;
}

export interface CharacterDetails {
name?: string;
/**
* Just a label, not an ID.
*/
profession?: string;

pastLevers?: Levers;

executions?: {
/**
* Not sure what this means yet,
* but it might be running recipes.
*/
[key: string]: string;
};

futureLevers?: Levers;

activeLegacy?: string;
}

export interface Situation {
situationStoredElements?: Record<string, ElementInstance>;
verbId?: string;
ongoingSlotElements?: Record<string, ElementInstance>;
situationWindowY?: string;
title?: string;
timeRemaining?: string;
recipeId?: string | null;
situationWindowX?: string;
state?: string;
situationOutputNotes?: Record<
string,
{
title?: string;
}
>;
situationWindowOpen?: string;
completioncount?: string;
}

function SerializeSituation(s: Situation): save.Situation {
return {
...s,
situationStoredElements: optionalChain(dictMap)(
s.situationStoredElements,
serializeElementInstance
),

ongoingSlotElements: optionalChain(dictMap)(
s.ongoingSlotElements,
serializeElementInstance
),
};
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"concurrently": "^6.2.1",
"jest-cli": "^27.0.6",
"module-alias": "^2.2.2",
"onchange": "^7.1.0",
"prettier": "^2.3.2",
"ts-node": "^10.2.1",
"ttypescript": "^1.5.12",
Expand All @@ -23,7 +24,9 @@
"scripts": {
"build": "yarn bazel build //...",
"test": "yarn bazel test //...",
"fix": "yarn prettier '**/*.ts' --ignore-path .gitignore --config .prettierrc.json --write"
"fix": "yarn run prettier-cmd '**/*.ts'",
"prettier-cmd": "yarn prettier --ignore-path .gitignore --config .prettierrc.json --write",
"prettier-watch": "onchange --exclude-path .gitignore '**/*.ts' -- yarn run prettier-cmd --ignore-unknown {{changed}}"
},
"dependencies": {
"@bazel/labs": "^3.8.0",
Expand Down
Loading

0 comments on commit 4efe737

Please sign in to comment.