diff --git a/engine/src/game/ResourceGenerator.ts b/engine/src/game/ResourceGenerator.ts index 9780108..02333ee 100644 --- a/engine/src/game/ResourceGenerator.ts +++ b/engine/src/game/ResourceGenerator.ts @@ -31,14 +31,28 @@ export class ResourceGenerator { return; } - this._progress = (this._progress + time) % this.period; - this.game.resources.add(this.generation.times(time / this.period)); + if (this.rule.manualProgressReset) { + this._progress = Math.min(this._progress + time, this.period); + } + else { + this._progress = (this._progress + time) % this.period; + this.game.resources.add(this.generation.times(time / this.period)); + } } public upgrade(): boolean { + if (this.rule.manualProgressReset && this._progress < this.period) { + return false; + } + if (this.isOpen && this.canAffordUpgrade) { + console.log('ok to upgrade'); this.game.resources.remove(this.upgradePrice); this.increaseLevel(); + + if (this.rule.manualProgressReset) + this.game.resources.add(this.generation); + if (this.rule.resetProgressOnUpgrade) this._progress = 0; return true; diff --git a/engine/src/index.ts b/engine/src/index.ts index c438895..3a9994f 100644 --- a/engine/src/index.ts +++ b/engine/src/index.ts @@ -1,136 +1,12 @@ -import Decimal from 'break_eternity.js'; import { Game } from './game'; -import type { ResourceGeneratorRule } from './rules'; -import type { PartialResources, Resource, Resources } from './types'; export * from './types'; export * from './rules'; export * from './game'; export * from './actions'; -type ResourceGenParams = { - offset?: number, - power?: number, - factor?: number, -} - -type SimpleResGenParams = { - name: string, - startingLevel?: number, - period: number, - generation: Partial>, - visibilityPrice?: Partial>, - openPrice: Partial>, - upgradePrice?: Partial>, -} - -function simpleResGen(params: SimpleResGenParams): ResourceGeneratorRule { - - function resourceGen(p?: Partial>): (lvl: number) => PartialResources { - if (!p) - return () => ({}); - - return (lvl) => Object.fromEntries( - Object.entries(p) - .map(([res, rp]) => [ - res, - new Decimal((rp.offset ?? 0) + Math.pow(lvl, rp.power ?? 1) * (rp.factor ?? 0)), - ]) - ) as Resources; - } - - return { - name: params.name, - startingLevel: params.startingLevel ?? 0, - resetProgressOnUpgrade: true, - period: (level) => level ? params.period : 0, - generation: resourceGen(params.generation), - visibilityPrice: resourceGen(params.visibilityPrice), - openPrice: resourceGen(params.openPrice), - upgradePrice: resourceGen(params.upgradePrice), - } -} +import { rules } from './rulesets/rules'; export function makeGame(): Game { - return new Game({ - generators: [ - simpleResGen({ - name: 'red', - startingLevel: 1, - period: 1, - generation: { RED: { offset: 3, power: 1.5, factor: 1 } }, - openPrice: { RED: { offset: 10, power: 2.1, factor: 10 } } - }), - ...['orange', 'yellow', 'green', 'cyan', 'blue', 'violet'] - .map((color, idx) => simpleResGen({ - name: color, - period: idx + 2, - generation: { RED: { power: 1.5, factor: (idx + 2) ** 2 } }, - // visibilityPrice: { RED: { offset: 5 * 10 ** (idx + 1) } }, - openPrice: { RED: { offset: 10 ** (idx + 2), power: 2.1, factor: 10 * 5 ** (idx + 1) } } - })), - // simpleResGen({ - // name: 'blue', - // period: 2, - // generation: { RED: { factor: 4 } }, - // visibilityPrice: { RED: { offset: 50 } }, - // openPrice: { RED: { offset: 100, power: 2.1, factor: 50 } } - // }), - // simpleResGen({ - // name: 'green', - // period: 3, - // generation: { RED: { factor: 9 } }, - // visibilityPrice: { RED: { offset: 500 } }, - // openPrice: { RED: { offset: 1000, power: 2.1, factor: 250 } } - // }), - // { - // name: "red", - // startingLevel: 1, - // period: (level) => level ? 1 : 0, - // resetProgressOnUpgrade: true, - // generation: (level) => { - // return { RED: level + 3 }; - // }, - // visibilityPrice: (level) => { return {} }, - // openPrice: (level) => { - // return { RED: 10 + Math.pow(level, 2.1) * 10 }; - // }, - // upgradePrice: (level) => { - // return {}; - // }, - // }, - // { - // name: "blue", - // startingLevel: 0, - // period: (level) => level ? 2 : 0, - // resetProgressOnUpgrade: true, - // generation: (level) => { - // return { RED: level * 4 }; - // }, - // visibilityPrice: (level) => { return { RED: 50 } }, - // openPrice: (level) => { - // return { RED: 100 + Math.pow(level, 2.1) * 50 }; - // }, - // upgradePrice: (level) => { - // return {}; - // }, - // }, - // { - // name: "green", - // startingLevel: 0, - // period: (level) => level ? 3 : 0, - // resetProgressOnUpgrade: true, - // generation: (level) => { - // return { RED: level * 9 }; - // }, - // visibilityPrice: (level) => { return { RED: 500 } }, - // openPrice: (level) => { - // return { RED: 1000 + Math.pow(level, 2.1) * 250 }; - // }, - // upgradePrice: (level) => { - // return {}; - // }, - // }, - ], - }) + return new Game(rules) }; diff --git a/engine/src/rules/ResourceGeneratorRule.ts b/engine/src/rules/ResourceGeneratorRule.ts index 53878e0..da8cc42 100644 --- a/engine/src/rules/ResourceGeneratorRule.ts +++ b/engine/src/rules/ResourceGeneratorRule.ts @@ -9,4 +9,5 @@ export type ResourceGeneratorRule = { openPrice: (level: number) => PartialResources; upgradePrice: (level: number) => PartialResources; resetProgressOnUpgrade: boolean; + manualProgressReset: boolean; }; diff --git a/engine/src/rulesets/rules copy.ts b/engine/src/rulesets/rules copy.ts new file mode 100644 index 0000000..af3bbd1 --- /dev/null +++ b/engine/src/rulesets/rules copy.ts @@ -0,0 +1,84 @@ +import { GameRules } from "../rules/GameRules"; +import { simpleResGen } from "./utils"; + +export const rules: GameRules = { + generators: [ + simpleResGen({ + name: 'red', + startingLevel: 1, + period: 1, + generation: { RED: { offset: 3, power: 1.5, factor: 1 } }, + openPrice: { RED: { offset: 10, power: 2.1, factor: 10 } } + }), + ...['orange', 'yellow', 'green', 'cyan', 'blue', 'violet'] + .map((color, idx) => simpleResGen({ + name: color, + period: idx + 2, + generation: { RED: { power: 1.5, factor: (idx + 2) ** 2 } }, + // visibilityPrice: { RED: { offset: 5 * 10 ** (idx + 1) } }, + openPrice: { RED: { offset: 10 ** (idx + 2), power: 2.1, factor: 10 * 5 ** (idx + 1) } } + })), + // simpleResGen({ + // name: 'blue', + // period: 2, + // generation: { RED: { factor: 4 } }, + // visibilityPrice: { RED: { offset: 50 } }, + // openPrice: { RED: { offset: 100, power: 2.1, factor: 50 } } + // }), + // simpleResGen({ + // name: 'green', + // period: 3, + // generation: { RED: { factor: 9 } }, + // visibilityPrice: { RED: { offset: 500 } }, + // openPrice: { RED: { offset: 1000, power: 2.1, factor: 250 } } + // }), + // { + // name: "red", + // startingLevel: 1, + // period: (level) => level ? 1 : 0, + // resetProgressOnUpgrade: true, + // generation: (level) => { + // return { RED: level + 3 }; + // }, + // visibilityPrice: (level) => { return {} }, + // openPrice: (level) => { + // return { RED: 10 + Math.pow(level, 2.1) * 10 }; + // }, + // upgradePrice: (level) => { + // return {}; + // }, + // }, + // { + // name: "blue", + // startingLevel: 0, + // period: (level) => level ? 2 : 0, + // resetProgressOnUpgrade: true, + // generation: (level) => { + // return { RED: level * 4 }; + // }, + // visibilityPrice: (level) => { return { RED: 50 } }, + // openPrice: (level) => { + // return { RED: 100 + Math.pow(level, 2.1) * 50 }; + // }, + // upgradePrice: (level) => { + // return {}; + // }, + // }, + // { + // name: "green", + // startingLevel: 0, + // period: (level) => level ? 3 : 0, + // resetProgressOnUpgrade: true, + // generation: (level) => { + // return { RED: level * 9 }; + // }, + // visibilityPrice: (level) => { return { RED: 500 } }, + // openPrice: (level) => { + // return { RED: 1000 + Math.pow(level, 2.1) * 250 }; + // }, + // upgradePrice: (level) => { + // return {}; + // }, + // }, + ], +} \ No newline at end of file diff --git a/engine/src/rulesets/rules.ts b/engine/src/rulesets/rules.ts new file mode 100644 index 0000000..975bddb --- /dev/null +++ b/engine/src/rulesets/rules.ts @@ -0,0 +1,33 @@ +import type { GameRules } from "../rules/GameRules"; +import { simpleResGen, resourceGen } from './utils'; + +export const rules: GameRules = { + generators: [ + { + name: 'white', + startingLevel: 1, + resetProgressOnUpgrade: true, + manualProgressReset: true, + period: (level) => level ? 0.5 : 0, + generation: resourceGen({ RED: { offset: 14, power: 2, factor: 1 } }), + visibilityPrice: () => ({}), + openPrice: () => ({}), + upgradePrice: () => ({}), + }, + simpleResGen({ + name: 'red', + startingLevel: 1, + period: 1, + generation: { RED: { offset: 3, power: 1.5, factor: 1 } }, + openPrice: { RED: { offset: 3, power: 2.1, factor: 10 } } + }), + ...['orange', 'yellow', 'green', 'cyan', 'blue', 'violet'] + .map((color, idx) => simpleResGen({ + name: color, + period: idx + 2, + generation: { RED: { power: 1.5, factor: (idx + 2) ** 2 } }, + // visibilityPrice: { RED: { offset: 5 * 10 ** (idx + 1) } }, + openPrice: { RED: { offset: 10 ** (idx + 2), power: 2.1, factor: 10 * 5 ** (idx + 1) } } + })), + ], +} \ No newline at end of file diff --git a/engine/src/rulesets/utils.ts b/engine/src/rulesets/utils.ts new file mode 100644 index 0000000..3b512c4 --- /dev/null +++ b/engine/src/rulesets/utils.ts @@ -0,0 +1,47 @@ +import Decimal from "break_eternity.js"; +import type { PartialResources, Resource, Resources } from "../types"; +import type { ResourceGeneratorRule } from "../rules/ResourceGeneratorRule"; + +type ResourceGenParams = { + offset?: number, + power?: number, + factor?: number, +} + +type SimpleResGenParams = { + name: string, + startingLevel?: number, + period: number, + generation: Partial>, + visibilityPrice?: Partial>, + openPrice: Partial>, + upgradePrice?: Partial>, +} + +export function resourceGen(p?: Partial>): (lvl: number) => PartialResources { + if (!p) + return () => ({}); + + return (lvl) => Object.fromEntries( + Object.entries(p) + .map(([res, rp]) => [ + res, + new Decimal((rp.offset ?? 0) + Math.pow(lvl, rp.power ?? 1) * (rp.factor ?? 0)), + ]) + ) as Resources; +} + +export function simpleResGen(params: SimpleResGenParams): ResourceGeneratorRule { + + return { + name: params.name, + startingLevel: params.startingLevel ?? 0, + resetProgressOnUpgrade: true, + manualProgressReset: false, + period: (level) => level ? params.period : 0, + generation: resourceGen(params.generation), + visibilityPrice: resourceGen(params.visibilityPrice), + openPrice: resourceGen(params.openPrice), + upgradePrice: resourceGen(params.upgradePrice), + } +} \ No newline at end of file