added manual upgraded generators

This commit is contained in:
azykov@mail.ru 2026-02-13 16:36:15 +03:00
parent 9d605b3772
commit c9c9f03526
6 changed files with 183 additions and 128 deletions

View File

@ -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;

View File

@ -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<Record<Resource, ResourceGenParams>>,
visibilityPrice?: Partial<Record<Resource, ResourceGenParams>>,
openPrice: Partial<Record<Resource, ResourceGenParams>>,
upgradePrice?: Partial<Record<Resource, ResourceGenParams>>,
}
function simpleResGen(params: SimpleResGenParams): ResourceGeneratorRule {
function resourceGen(p?: Partial<Record<Resource, ResourceGenParams>>): (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)
};

View File

@ -9,4 +9,5 @@ export type ResourceGeneratorRule = {
openPrice: (level: number) => PartialResources;
upgradePrice: (level: number) => PartialResources;
resetProgressOnUpgrade: boolean;
manualProgressReset: boolean;
};

View File

@ -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 {};
// },
// },
],
}

View File

@ -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) } }
})),
],
}

View File

@ -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<Record<Resource, ResourceGenParams>>,
visibilityPrice?: Partial<Record<Resource, ResourceGenParams>>,
openPrice: Partial<Record<Resource, ResourceGenParams>>,
upgradePrice?: Partial<Record<Resource, ResourceGenParams>>,
}
export function resourceGen(p?: Partial<Record<Resource, ResourceGenParams>>): (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),
}
}