diff --git a/.eslintrc.json b/.eslintrc.json index e4a913e..1ab1085 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,104 +2,13 @@ "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking" ], "parser": "@typescript-eslint/parser", "parserOptions": {"project": "tsconfig.json"}, "plugins": ["@typescript-eslint"], "rules": { - "max-len": ["warn", { - "ignoreStrings": true, - "ignoreTemplateLiterals": true, - "ignoreRegExpLiterals": true}], "@typescript-eslint/triple-slash-reference": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/no-inferrable-types": "warn", - "@typescript-eslint/array-type": ["warn", {"default": "array-simple"}], - "@typescript-eslint/consistent-indexed-object-style": ["warn", "index-signature"], - "@typescript-eslint/consistent-type-assertions": ["warn", { - "assertionStyle": "angle-bracket", - "objectLiteralTypeAssertions": "never"}], - "@typescript-eslint/explicit-function-return-type": "warn", - "@typescript-eslint/explicit-member-accessibility": ["error", { - "accessibility": "explicit", - "overrides": {"constructors": "no-public"}}], - "@typescript-eslint/member-delimiter-style": ["warn", { - "multiline": {"delimiter": "semi", "requireLast": true}, - "singleline": {"delimiter": "comma", "requireLast": false}}], - "@typescript-eslint/member-ordering": "warn", - "@typescript-eslint/method-signature-style": ["warn", "property"], - "@typescript-eslint/naming-convention": "warn", - "@typescript-eslint/no-base-to-string": "error", - "@typescript-eslint/no-confusing-non-null-assertion": "error", - "@typescript-eslint/no-confusing-void-expression": "error", - "@typescript-eslint/no-extraneous-class": "error", - "@typescript-eslint/no-implicit-any-catch": "error", - "@typescript-eslint/no-invalid-void-type": "error", - "@typescript-eslint/no-unnecessary-boolean-literal-compare": "warn", - "@typescript-eslint/no-unnecessary-condition": "warn", - "@typescript-eslint/no-unnecessary-qualifier": "warn", - "@typescript-eslint/no-unnecessary-type-arguments": "warn", - "@typescript-eslint/no-unnecessary-type-constraint": "warn", - "@typescript-eslint/no-unsafe-argument": "error", - "@typescript-eslint/non-nullable-type-assertion-style": "warn", - "@typescript-eslint/prefer-enum-initializers": "warn", - "@typescript-eslint/prefer-function-type": "warn", - "@typescript-eslint/prefer-includes": "warn", - "@typescript-eslint/prefer-literal-enum-member": "error", - "@typescript-eslint/prefer-nullish-coalescing": "warn", - "@typescript-eslint/prefer-optional-chain": "warn", - "@typescript-eslint/prefer-readonly": "warn", - "@typescript-eslint/prefer-reduce-type-parameter": "warn", - "@typescript-eslint/prefer-return-this-type": "warn", - "@typescript-eslint/prefer-string-starts-ends-with": "warn", - "@typescript-eslint/prefer-ts-expect-error": "error", - "@typescript-eslint/promise-function-async": "warn", - "@typescript-eslint/require-array-sort-compare": "warn", - "@typescript-eslint/strict-boolean-expressions": ["error", { - "allowString": false, - "allowNumber": false, - "allowNullableObject": false}], - "@typescript-eslint/switch-exhaustiveness-check": "warn", - "@typescript-eslint/type-annotation-spacing": "warn", - "@typescript-eslint/unified-signatures": "warn", - "@typescript-eslint/brace-style": "warn", - "@typescript-eslint/comma-dangle": ["warn", "always-multiline"], - "@typescript-eslint/comma-spacing": "warn", - "@typescript-eslint/default-param-last": "error", - "@typescript-eslint/dot-notation": "error", - "@typescript-eslint/func-call-spacing": ["warn", "never"], - "@typescript-eslint/indent": ["warn", 2, { - "SwitchCase": 1, - "VariableDeclarator": 1, - "outerIIFEBody": 1, - "FunctionDeclaration": {"parameters": 1, "body": 1}, - "CallExpression": {"arguments": 1}, - "ArrayExpression": 1, - "ObjectExpression": 1, - "MemberExpression": 2, - "flatTernaryExpressions": false, - "ignoreComments": false}], - "@typescript-eslint/keyword-spacing": "error", - "@typescript-eslint/lines-between-class-members": ["warn", "always", { - "exceptAfterSingleLine": true}], - "@typescript-eslint/no-dupe-class-members": "error", - "@typescript-eslint/no-extra-parens": "warn", - "@typescript-eslint/no-invalid-this": "error", - "@typescript-eslint/no-loop-func": "error", - "@typescript-eslint/no-loss-of-precision": "warn", - "@typescript-eslint/no-redeclare": "error", - "@typescript-eslint/no-shadow": "error", - "@typescript-eslint/no-unused-expressions": "error", - "@typescript-eslint/no-use-before-define": "error", - "@typescript-eslint/no-useless-constructor": "warn", - "@typescript-eslint/object-curly-spacing": ["warn", "always", { - "arraysInObjects": true, - "objectsInObjects": false}], - "@typescript-eslint/quotes": ["warn", "single", {"avoidEscape": true}], - "@typescript-eslint/semi": ["error", "always"], - "@typescript-eslint/space-before-function-paren": ["warn", "always"], - "@typescript-eslint/space-infix-ops": "warn" + "@typescript-eslint/no-unused-vars": "off" } } diff --git a/src/main.ts b/src/main.ts index 235c122..c4129ef 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,9 @@ /// /// +const versionMajor = 2; +const versionMinor = 0; + let globalStartTime = 0; let globalTimeout: number | null = null; const cycleLength = 250; @@ -27,7 +30,7 @@ function startGame (state: GameState, renderer: IRenderer): void { function initialRender (state: GameState): void { if (state.logger === null) return; - state.logger.unsafeMsg(`Welcome to irreligio.us! + state.logger.unsafeMsg(`Welcome to irreligio.us! alpha v${versionMajor}.${versionMinor}

The game is still in an active state of development and nowhere near its final form. This is a debugging interface that can show all resources even before they're unlocked, and many factors may be sped up significantly to aid in development. There is a chance that playing it now may spoil aspects of the game for you later when it's closer to being finished.

@@ -38,7 +41,7 @@ The game's source code on Github // run with default config at startup ((): void => { - const config = new GameConfig(); + const config = new GameConfig(versionMajor, versionMinor); // debug values to make the game play faster while testing config.cfgTitheAmount = 1000; diff --git a/src/model/GameConfig.ts b/src/model/GameConfig.ts index 5c7a93c..c844061 100644 --- a/src/model/GameConfig.ts +++ b/src/model/GameConfig.ts @@ -79,6 +79,11 @@ class GameConfig { public cfgTitheAmount = 10; public cfgTitheCredibilityHitFactor = 3; + constructor ( + public versionMajor: number, + public versionMinor: number, + ) {} + public generateState (): GameState { const state = new GameState(this); diff --git a/src/model/GameState.ts b/src/model/GameState.ts index 933c1c5..0d37912 100644 --- a/src/model/GameState.ts +++ b/src/model/GameState.ts @@ -8,9 +8,6 @@ class GameState { public now = 0; - private readonly _versionMaj = 0; - private readonly _versionMin = 1; - private _timeSinceSave = 0; private readonly _timeBetweenSaves = 10000; @@ -116,19 +113,25 @@ class GameState { } public save (): void { - const saveObj: SaveData = {}; - saveObj.version = { - maj: this._versionMaj, - min: this._versionMin, + const saveObj: SaveData = { + version: { + maj: this.config.versionMajor, + min: this.config.versionMinor, + }, + resources: {}, }; for (const key in this._resources) { const rkey = key; const resource = this._resources[rkey]; if (resource === undefined) continue; - saveObj[rkey] = { + const resSav: ResourceConfig = { value: resource.value, cost: resource.cost, }; + if (resource.emitConfig !== undefined) { + resSav.config = resource.emitConfig(); + } + saveObj.resources[rkey] = resSav; } const saveStr: string = btoa(JSON.stringify(saveObj)); localStorage.setItem('savegame', saveStr); @@ -139,18 +142,21 @@ class GameState { if (saveStr !== null) { try { const saveObj: SaveData = JSON.parse(atob(saveStr)); - if (this._versionMaj === saveObj.version?.maj) { + if (this.config.versionMajor === saveObj.version.maj) { for (const key in this._resources) { const rkey = key; - const saveRes = <{ - value: number; - cost?: { [key: string]: number }; - } | undefined> saveObj[key]; + const resource = this._resources[rkey]; + if (resource === undefined) continue; + const saveRes = saveObj.resources[rkey]; if (saveRes !== undefined) { // @ts-expect-error writing read-only value from save data - this._resources[rkey].value = saveRes.value; + resource.value = saveRes.value; // @ts-expect-error writing read-only cost from save data - this._resources[rkey].cost = saveRes.cost; + resource.cost = saveRes.cost; + if (saveRes.config !== undefined + && resource.restoreConfig !== undefined) { + resource.restoreConfig(saveRes.config); + } } } } else { @@ -173,11 +179,3 @@ class GameState { this.log('Reset all game resources.'); } } - -type SaveData = { - [key: string]: { - value: number; - cost?: { [key: string]: number }; - } | { maj: number, min: number } | undefined; - version?: { maj: number, min: number }; -}; diff --git a/src/model/resource/IResource.ts b/src/model/resource/IResource.ts index 7e1175d..0f02949 100644 --- a/src/model/resource/IResource.ts +++ b/src/model/resource/IResource.ts @@ -18,4 +18,8 @@ interface IResource { addValue: (amount: number, state: GameState) => void; isUnlocked: (state: GameState) => boolean; + + emitConfig?: () => { [key: string]: string | number | boolean }; + restoreConfig?: ( + config: { [key: string]: string | number | boolean }) => void; } diff --git a/src/model/resource/Money.ts b/src/model/resource/Money.ts index e0f5864..674ff26 100644 --- a/src/model/resource/Money.ts +++ b/src/model/resource/Money.ts @@ -13,7 +13,7 @@ class Money implements IResource { name: 'Collect Tithes', description: 'Voluntary contributions from followers.', isEnabled: (state: GameState): boolean => - this.value <= this.max(state) + this.value < this.max(state) && (state.resource.followers?.value ?? 0) >= 1, performAction: (state: GameState): void => { this._collectTithes(state); diff --git a/src/model/resource/SharedTypes.ts b/src/model/resource/SharedTypes.ts index 4228493..01e73db 100644 --- a/src/model/resource/SharedTypes.ts +++ b/src/model/resource/SharedTypes.ts @@ -39,3 +39,14 @@ type ResourceAction = { isEnabled: (state: GameState) => boolean; performAction: (state: GameState) => void; }; + +type ResourceConfig = { + value: number; + cost?: ResourceNumber; + config?: { [key: string]: string | number | boolean }; +}; + +type SaveData = { + version: { maj: number, min: number }; + resources: { [key in ResourceKey]?: ResourceConfig }; +};