ability to define mulitple user actions per resource
This commit is contained in:
parent
ce3ae26b4b
commit
1bc4206a32
|
@ -37,8 +37,6 @@
|
||||||
"@typescript-eslint/no-extraneous-class": "error",
|
"@typescript-eslint/no-extraneous-class": "error",
|
||||||
"@typescript-eslint/no-implicit-any-catch": "error",
|
"@typescript-eslint/no-implicit-any-catch": "error",
|
||||||
"@typescript-eslint/no-invalid-void-type": "error",
|
"@typescript-eslint/no-invalid-void-type": "error",
|
||||||
"@typescript-eslint/no-parameter-properties": ["error", {
|
|
||||||
"allows": ["public", "readonly", "public readonly"]}],
|
|
||||||
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "warn",
|
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "warn",
|
||||||
"@typescript-eslint/no-unnecessary-condition": "warn",
|
"@typescript-eslint/no-unnecessary-condition": "warn",
|
||||||
"@typescript-eslint/no-unnecessary-qualifier": "warn",
|
"@typescript-eslint/no-unnecessary-qualifier": "warn",
|
||||||
|
|
|
@ -4,27 +4,28 @@
|
||||||
/// <reference path="./resource/Compound.ts" />
|
/// <reference path="./resource/Compound.ts" />
|
||||||
/// <reference path="./resource/Credibility.ts" />
|
/// <reference path="./resource/Credibility.ts" />
|
||||||
/// <reference path="./resource/CryptoCurrency.ts" />
|
/// <reference path="./resource/CryptoCurrency.ts" />
|
||||||
|
/// <reference path="./resource/Follower.ts" />
|
||||||
/// <reference path="./resource/House.ts" />
|
/// <reference path="./resource/House.ts" />
|
||||||
/// <reference path="./resource/MegaChurch.ts" />
|
/// <reference path="./resource/Megachurch.ts" />
|
||||||
/// <reference path="./resource/Money.ts" />
|
/// <reference path="./resource/Money.ts" />
|
||||||
/// <reference path="./resource/Pastor.ts" />
|
/// <reference path="./resource/Pastor.ts" />
|
||||||
/// <reference path="./resource/PlayerOrg.ts" />
|
|
||||||
/// <reference path="./resource/Religion.ts" />
|
/// <reference path="./resource/Religion.ts" />
|
||||||
/// <reference path="./resource/Tent.ts" />
|
/// <reference path="./resource/Tent.ts" />
|
||||||
|
|
||||||
class GameConfig {
|
class GameConfig {
|
||||||
public worldPopulation = 790000000;
|
public worldPopulation = 790000000;
|
||||||
public numberFormatDigits = 1;
|
|
||||||
|
|
||||||
// religion configs
|
// religion configs
|
||||||
public relChristianitySharer = 0.325;
|
public cfgReligion: ResourceNumber = {
|
||||||
public relIslamShare = 0.215;
|
christianity: 0.325,
|
||||||
public relHinduismShare = 0.16;
|
islam: 0.215,
|
||||||
public relBuddhismShare = 0.06;
|
hinduism: 0.16,
|
||||||
public relSikhismShare = 0.04;
|
buddhism: 0.06,
|
||||||
public relJudaismShare = 0.02;
|
sikhism: 0.04,
|
||||||
public relOtherShare = 0.02;
|
judaism: 0.02,
|
||||||
public relNoneShare = 0.16;
|
other: 0.02,
|
||||||
|
atheism: 0.16,
|
||||||
|
};
|
||||||
|
|
||||||
// general configs
|
// general configs
|
||||||
public cfgInitialMax: ResourceNumber = {
|
public cfgInitialMax: ResourceNumber = {
|
||||||
|
@ -81,40 +82,40 @@ class GameConfig {
|
||||||
const state = new GameState(this);
|
const state = new GameState(this);
|
||||||
|
|
||||||
// create player organization
|
// create player organization
|
||||||
state.addResource(ResourceKey.playerOrg, new PlayerOrg());
|
state.addResource(ResourceKey.playerOrg, new Follower());
|
||||||
|
|
||||||
// create world religions
|
// create world religions
|
||||||
state.addResource(ResourceKey.christianity, new Religion(
|
state.addResource(ResourceKey.christianity, new Religion(
|
||||||
'Christianity', 'God, Jesus, Bible, churches.',
|
'christian', 'christians', 'God, Jesus, Bible, churches.',
|
||||||
this.relChristianitySharer * this.worldPopulation));
|
(this.cfgReligion.christianity ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
state.addResource(ResourceKey.islam, new Religion(
|
state.addResource(ResourceKey.islam, new Religion(
|
||||||
'Islam', 'God, Muhammad, Quran, mosques.',
|
'muslim', 'muslims', 'God, Muhammad, Quran, mosques.',
|
||||||
this.relIslamShare * this.worldPopulation));
|
(this.cfgReligion.islam ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
state.addResource(ResourceKey.hinduism, new Religion(
|
state.addResource(ResourceKey.hinduism, new Religion(
|
||||||
'Hinduism', 'Dogma-free spiritualism.',
|
'hindu', 'hindus', 'Dogma-free spiritualism.',
|
||||||
this.relHinduismShare * this.worldPopulation));
|
(this.cfgReligion.hinduism ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
state.addResource(ResourceKey.buddhism, new Religion(
|
state.addResource(ResourceKey.buddhism, new Religion(
|
||||||
'Buddhism', 'The minimization of suffering.',
|
'buddhist', 'buddhists', 'The minimization of suffering.',
|
||||||
this.relBuddhismShare * this.worldPopulation));
|
(this.cfgReligion.buddhism ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
state.addResource(ResourceKey.sikhism, new Religion(
|
state.addResource(ResourceKey.sikhism, new Religion(
|
||||||
'Sikhism', 'Meditation and ten Gurus',
|
'sikh', 'sikhs', 'Meditation and ten Gurus',
|
||||||
this.relSikhismShare * this.worldPopulation));
|
(this.cfgReligion.sikhism ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
state.addResource(ResourceKey.judaism, new Religion(
|
state.addResource(ResourceKey.judaism, new Religion(
|
||||||
'Judaism', 'God, Abraham, Torah, synagogues.',
|
'jew', 'jews', 'God, Abraham, Torah, synagogues.',
|
||||||
this.relJudaismShare * this.worldPopulation));
|
(this.cfgReligion.judaism ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
state.addResource(ResourceKey.other, new Religion(
|
state.addResource(ResourceKey.other, new Religion(
|
||||||
'Other', 'A variety of belief systems.',
|
'other', 'others', 'A variety of belief systems.',
|
||||||
this.relOtherShare * this.worldPopulation));
|
(this.cfgReligion.other ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
state.addResource(ResourceKey.atheism, new Religion(
|
state.addResource(ResourceKey.atheism, new Religion(
|
||||||
'Non-Religious', 'Atheists and agnostics.',
|
'atheist', 'atheists', 'Atheists and agnostics.',
|
||||||
this.relNoneShare * this.worldPopulation));
|
(this.cfgReligion.atheism ?? 0) * this.worldPopulation));
|
||||||
|
|
||||||
// add jobs
|
// add jobs
|
||||||
state.addResource(ResourceKey.pastors, new Pastor());
|
state.addResource(ResourceKey.pastors, new Pastor());
|
||||||
|
@ -126,7 +127,7 @@ class GameConfig {
|
||||||
state.addResource(ResourceKey.houses, new House(this));
|
state.addResource(ResourceKey.houses, new House(this));
|
||||||
state.addResource(ResourceKey.churches, new Church(this));
|
state.addResource(ResourceKey.churches, new Church(this));
|
||||||
state.addResource(ResourceKey.compounds, new Compound(this));
|
state.addResource(ResourceKey.compounds, new Compound(this));
|
||||||
state.addResource(ResourceKey.megaChurches, new MegaChurch(this));
|
state.addResource(ResourceKey.megaChurches, new Megachurch(this));
|
||||||
|
|
||||||
// add research
|
// add research
|
||||||
state.addResource(ResourceKey.buildingPermit, new BuildingPermit(this));
|
state.addResource(ResourceKey.buildingPermit, new BuildingPermit(this));
|
||||||
|
@ -136,26 +137,4 @@ class GameConfig {
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public formatNumber (num: number): string {
|
|
||||||
type UnitLookup = { value: number, symbol: string };
|
|
||||||
const lookup: UnitLookup[] = [
|
|
||||||
{ value: 1, symbol: '' },
|
|
||||||
{ value: 1e3, symbol: 'K' },
|
|
||||||
{ value: 1e6, symbol: 'M' },
|
|
||||||
{ value: 1e9, symbol: 'G' },
|
|
||||||
{ value: 1e12, symbol: 'T' },
|
|
||||||
{ value: 1e15, symbol: 'P' },
|
|
||||||
{ value: 1e18, symbol: 'E' },
|
|
||||||
];
|
|
||||||
const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
|
|
||||||
let item: UnitLookup | undefined;
|
|
||||||
for (item of lookup.slice().reverse()) {
|
|
||||||
if (num >= item.value) break;
|
|
||||||
}
|
|
||||||
return item !== undefined
|
|
||||||
? (num / item.value).toFixed(
|
|
||||||
this.numberFormatDigits).replace(rx, '$1') + item.symbol
|
|
||||||
: num.toFixed(this.numberFormatDigits).replace(rx, '$1');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/// <reference path="./Utils.ts" />
|
||||||
|
|
||||||
class GameState {
|
class GameState {
|
||||||
public readonly config: GameConfig;
|
public readonly config: GameConfig;
|
||||||
|
|
||||||
|
@ -69,17 +71,19 @@ class GameState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public performClick (resourceKey: ResourceKey): void {
|
public performAction (resourceKey: ResourceKey, actionIndex: number): void {
|
||||||
const resource = this._resources[resourceKey];
|
const resource = this._resources[resourceKey];
|
||||||
if (resource === undefined || !resource.isUnlocked(this)) return;
|
if (resource === undefined || resource.userActions === undefined
|
||||||
|
|| actionIndex > resource.userActions.length
|
||||||
|
|| !resource.isUnlocked(this)) return;
|
||||||
|
|
||||||
if (resource.clickAction !== undefined) {
|
const action = resource.userActions[actionIndex];
|
||||||
resource.clickAction(this);
|
|
||||||
|
action.performAction(this);
|
||||||
for (const callback of this.onResourceClick) {
|
for (const callback of this.onResourceClick) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public deductCost (cost: ResourceNumber | null): boolean {
|
public deductCost (cost: ResourceNumber | null): boolean {
|
||||||
if (cost === null) return true;
|
if (cost === null) return true;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
const numberFormatDigits = 1;
|
||||||
|
|
||||||
|
function formatNumber (num: number): string {
|
||||||
|
type UnitLookup = { value: number, symbol: string };
|
||||||
|
const lookup: UnitLookup[] = [
|
||||||
|
{ value: 1, symbol: '' },
|
||||||
|
{ value: 1e3, symbol: 'K' },
|
||||||
|
{ value: 1e6, symbol: 'M' },
|
||||||
|
{ value: 1e9, symbol: 'G' },
|
||||||
|
{ value: 1e12, symbol: 'T' },
|
||||||
|
{ value: 1e15, symbol: 'P' },
|
||||||
|
{ value: 1e18, symbol: 'E' },
|
||||||
|
];
|
||||||
|
const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
|
||||||
|
let item: UnitLookup | undefined;
|
||||||
|
for (item of lookup.slice().reverse()) {
|
||||||
|
if (num >= item.value) break;
|
||||||
|
}
|
||||||
|
return item !== undefined
|
||||||
|
? (num / item.value).toFixed(
|
||||||
|
numberFormatDigits).replace(rx, '$1') + item.symbol
|
||||||
|
: num.toFixed(numberFormatDigits).replace(rx, '$1');
|
||||||
|
}
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
class BuildingPermit extends Research {
|
class BuildingPermit extends Research {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super('Building Permit',
|
super(
|
||||||
|
'building permit',
|
||||||
|
'building permits',
|
||||||
'Unlocks several new buildings you can build outside of your compounds.');
|
'Unlocks several new buildings you can build outside of your compounds.');
|
||||||
this.cost.money = config.cfgInitialMax.buildingPermit;
|
this.cost.money = config.cfgInitialMax.buildingPermit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
class Church extends Infrastructure {
|
class Church extends Infrastructure {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super('Churches',
|
super(
|
||||||
`Preaching grounds for ${config.formatNumber(config.cfgCapacity.churches?.pastors ?? 0)} pastors.`);
|
'church',
|
||||||
|
'churches',
|
||||||
|
`Preaching grounds for ${formatNumber(config.cfgCapacity.churches?.pastors ?? 0)} pastors.`);
|
||||||
this.cost.money = config.cfgInitialCost.churches;
|
this.cost.money = config.cfgInitialCost.churches;
|
||||||
this._costMultiplier.money = config.cfgCostMultiplier.churches;
|
this._costMultiplier.money = config.cfgCostMultiplier.churches;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
class Compound extends Infrastructure {
|
class Compound extends Infrastructure {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super('Compounds',
|
super(
|
||||||
|
'compound',
|
||||||
|
'compounds',
|
||||||
'Provides space for tents, houses, and churches and a place to hide more money.');
|
'Provides space for tents, houses, and churches and a place to hide more money.');
|
||||||
this.cost.money = config.cfgInitialCost.compounds;
|
this.cost.money = config.cfgInitialCost.compounds;
|
||||||
this._costMultiplier.money = config.cfgCostMultiplier.compounds;
|
this._costMultiplier.money = config.cfgCostMultiplier.compounds;
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
class Credibility extends Passive {
|
class Credibility extends Passive {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super(
|
super(
|
||||||
'Credibility',
|
'credibility',
|
||||||
|
'credibilities',
|
||||||
'Affects your ability to recruit and retain followers.');
|
'Affects your ability to recruit and retain followers.');
|
||||||
this.value = config.cfgPassiveMax;
|
this.value = config.cfgPassiveMax;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
class CryptoCurrency extends Purchasable {
|
class CryptoCurrency extends Purchasable {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super('Faithcoin',
|
super(
|
||||||
|
'FaithCoin',
|
||||||
|
'FaithCoins',
|
||||||
"A crypto coin that can't be spent directly, but provides a steady stream of passive income.");
|
"A crypto coin that can't be spent directly, but provides a steady stream of passive income.");
|
||||||
this.cost.money = config.cfgInitialCost.cryptoCurrency;
|
this.cost.money = config.cfgInitialCost.cryptoCurrency;
|
||||||
this._costMultiplier.money = config.cfgCostMultiplier.cryptoCurrency;
|
this._costMultiplier.money = config.cfgCostMultiplier.cryptoCurrency;
|
||||||
|
|
|
@ -1,14 +1,24 @@
|
||||||
/// <reference path="./IResource.ts" />
|
/// <reference path="./IResource.ts" />
|
||||||
|
|
||||||
class PlayerOrg implements IResource {
|
class Follower implements IResource {
|
||||||
public readonly resourceType = ResourceType.religion;
|
public readonly resourceType = ResourceType.religion;
|
||||||
public readonly name = 'Player';
|
public readonly singularName = 'follower';
|
||||||
|
public readonly pluralName = 'followers';
|
||||||
public readonly description = 'In you they trust.';
|
public readonly description = 'In you they trust.';
|
||||||
public readonly valueInWholeNumbers = true;
|
public readonly valueInWholeNumbers = true;
|
||||||
public readonly clickText = 'Recruit';
|
|
||||||
public readonly clickDescription = 'Gather new followers.';
|
|
||||||
public value = 0;
|
public value = 0;
|
||||||
|
|
||||||
|
public userActions: ResourceAction[] = [
|
||||||
|
{
|
||||||
|
name: 'Recruit',
|
||||||
|
description: 'Gather new followers.',
|
||||||
|
isEnabled: (state: GameState): boolean => this.value < this.max(state),
|
||||||
|
performAction: (state: GameState): void => {
|
||||||
|
this._recruitFollower(state);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
private _timeSinceLastLost = 0;
|
private _timeSinceLastLost = 0;
|
||||||
private _lastRecruitmentLog = 0;
|
private _lastRecruitmentLog = 0;
|
||||||
private _followerSources: ResourceNumber = { };
|
private _followerSources: ResourceNumber = { };
|
||||||
|
@ -37,27 +47,6 @@ class PlayerOrg implements IResource {
|
||||||
return inc;
|
return inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public clickAction (state: GameState): void {
|
|
||||||
// don't exceed max
|
|
||||||
if (this.value >= this.max(state)) {
|
|
||||||
state.log('You have no room for more followers.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// chance to fail increases as credibility decreases
|
|
||||||
const creds = state.resource.credibility;
|
|
||||||
if (creds?.max !== undefined) {
|
|
||||||
const ratio = Math.ceil(creds.value) / creds.max(state);
|
|
||||||
if (Math.random() > ratio) {
|
|
||||||
state.log('Your recruitment efforts failed.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._lastRecruitmentLog = 0; // always log on click
|
|
||||||
this.addValue(1, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public addValue (amount: number, state: GameState): void {
|
public addValue (amount: number, state: GameState): void {
|
||||||
const oldValue = this.value;
|
const oldValue = this.value;
|
||||||
this.value += amount;
|
this.value += amount;
|
||||||
|
@ -124,12 +113,12 @@ class PlayerOrg implements IResource {
|
||||||
const followers = this._followerDests[rkey];
|
const followers = this._followerDests[rkey];
|
||||||
if (religion !== undefined && followers !== undefined) {
|
if (religion !== undefined && followers !== undefined) {
|
||||||
if (msg !== '') msg += ', ';
|
if (msg !== '') msg += ', ';
|
||||||
msg += `${state.config.formatNumber(followers)} to ${religion.name}`;
|
msg += `${formatNumber(followers)} to ${religion.pluralName}`;
|
||||||
total += followers;
|
total += followers;
|
||||||
delete this._followerDests[rkey];
|
delete this._followerDests[rkey];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.log(`You lost ${state.config.formatNumber(total)} followers: ${msg}`);
|
state.log(`You lost ${formatNumber(total)} followers: ${msg}`);
|
||||||
}
|
}
|
||||||
if (Object.keys(this._followerSources).length > 0) {
|
if (Object.keys(this._followerSources).length > 0) {
|
||||||
let msg = '';
|
let msg = '';
|
||||||
|
@ -141,17 +130,38 @@ class PlayerOrg implements IResource {
|
||||||
if (religion !== undefined && followers !== undefined) {
|
if (religion !== undefined && followers !== undefined) {
|
||||||
if (msg !== '') msg += ', ';
|
if (msg !== '') msg += ', ';
|
||||||
msg +=
|
msg +=
|
||||||
`${state.config.formatNumber(followers)} from ${religion.name}`;
|
`${formatNumber(followers)} from ${religion.pluralName}`;
|
||||||
total += followers;
|
total += followers;
|
||||||
delete this._followerSources[rkey];
|
delete this._followerSources[rkey];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.log(`You gained ${state.config.formatNumber(total)} followers: ${msg}`);
|
state.log(`You gained ${formatNumber(total)} followers: ${msg}`);
|
||||||
}
|
}
|
||||||
this._lastRecruitmentLog = state.now;
|
this._lastRecruitmentLog = state.now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _recruitFollower (state: GameState): void {
|
||||||
|
// don't exceed max
|
||||||
|
if (this.value >= this.max(state)) {
|
||||||
|
state.log('You have no room for more followers.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// chance to fail increases as credibility decreases
|
||||||
|
const creds = state.resource.credibility;
|
||||||
|
if (creds?.max !== undefined) {
|
||||||
|
const ratio = Math.ceil(creds.value) / creds.max(state);
|
||||||
|
if (Math.random() > ratio) {
|
||||||
|
state.log('Your recruitment efforts failed.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._lastRecruitmentLog = 0; // always log on click
|
||||||
|
this.addValue(1, state);
|
||||||
|
}
|
||||||
|
|
||||||
private _getRandomReligion (
|
private _getRandomReligion (
|
||||||
state: GameState): [ResourceKey, IResource] | null {
|
state: GameState): [ResourceKey, IResource] | null {
|
||||||
const religs = [ResourceKey.christianity, ResourceKey.islam,
|
const religs = [ResourceKey.christianity, ResourceKey.islam,
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
class House extends Infrastructure {
|
class House extends Infrastructure {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super('Houses',
|
super(
|
||||||
`Provides room to house ${config.formatNumber(config.cfgCapacity.houses?.playerOrg ?? 0)} followers.`);
|
'house',
|
||||||
|
'houses',
|
||||||
|
`Provides room to house ${formatNumber(config.cfgCapacity.houses?.playerOrg ?? 0)} followers.`);
|
||||||
this.cost.money = config.cfgInitialCost.houses;
|
this.cost.money = config.cfgInitialCost.houses;
|
||||||
this._costMultiplier.money = config.cfgCostMultiplier.houses;
|
this._costMultiplier.money = config.cfgCostMultiplier.houses;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,19 @@
|
||||||
enum ResourceType {
|
/// <reference path="./SharedTypes.ts" />
|
||||||
religion = 'religion',
|
|
||||||
job = 'job',
|
|
||||||
consumable = 'consumable',
|
|
||||||
infrastructure = 'infrastructure',
|
|
||||||
research = 'research',
|
|
||||||
passive = 'passive',
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ResourceKey {
|
|
||||||
playerOrg = 'playerOrg',
|
|
||||||
christianity = 'christianity',
|
|
||||||
islam = 'islam',
|
|
||||||
hinduism = 'hinduism',
|
|
||||||
buddhism = 'buddhism',
|
|
||||||
sikhism = 'sikhism',
|
|
||||||
judaism = 'judaism',
|
|
||||||
other = 'other',
|
|
||||||
atheism = 'atheism',
|
|
||||||
pastors = 'pastors',
|
|
||||||
money = 'money',
|
|
||||||
cryptoCurrency = 'cryptoCurrency',
|
|
||||||
tents = 'tents',
|
|
||||||
houses = 'houses',
|
|
||||||
churches = 'churches',
|
|
||||||
compounds = 'compounds',
|
|
||||||
buildingPermit = 'buildingPermit',
|
|
||||||
megaChurches = 'megaChurches',
|
|
||||||
credibility = 'credibility',
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceNumber = { [key in ResourceKey]?: number };
|
|
||||||
|
|
||||||
interface IResource {
|
interface IResource {
|
||||||
readonly resourceType: ResourceType;
|
readonly resourceType: ResourceType;
|
||||||
readonly name: string;
|
readonly singularName: string;
|
||||||
|
readonly pluralName: string;
|
||||||
readonly description: string;
|
readonly description: string;
|
||||||
readonly valueInWholeNumbers: boolean;
|
readonly valueInWholeNumbers: boolean;
|
||||||
|
|
||||||
readonly value: number;
|
readonly value: number;
|
||||||
readonly cost?: ResourceNumber;
|
readonly cost?: ResourceNumber;
|
||||||
|
|
||||||
readonly clickText?: string;
|
|
||||||
readonly clickDescription?: string;
|
|
||||||
// readonly altClickText?: string;
|
|
||||||
// readonly altClickDescription?: string;
|
|
||||||
|
|
||||||
max?: (state: GameState) => number;
|
max?: (state: GameState) => number;
|
||||||
inc?: (state: GameState) => number;
|
inc?: (state: GameState) => number;
|
||||||
clickAction?: (state: GameState) => void;
|
|
||||||
// altClickAction (state: GameState): void;
|
|
||||||
advanceAction?: (time: number, state: GameState) => void;
|
advanceAction?: (time: number, state: GameState) => void;
|
||||||
|
userActions?: ResourceAction[];
|
||||||
|
|
||||||
addValue: (amount: number, state: GameState) => void;
|
addValue: (amount: number, state: GameState) => void;
|
||||||
isUnlocked: (state: GameState) => boolean;
|
isUnlocked: (state: GameState) => boolean;
|
||||||
|
|
|
@ -3,39 +3,34 @@
|
||||||
abstract class Job implements IResource {
|
abstract class Job implements IResource {
|
||||||
public readonly resourceType = ResourceType.job;
|
public readonly resourceType = ResourceType.job;
|
||||||
public readonly valueInWholeNumbers = true;
|
public readonly valueInWholeNumbers = true;
|
||||||
public readonly clickText = 'Hire';
|
|
||||||
public readonly clickDescription = 'Promote one of your followers.';
|
|
||||||
public value = 0;
|
public value = 0;
|
||||||
public readonly cost: ResourceNumber = { };
|
public readonly cost: ResourceNumber = { };
|
||||||
|
|
||||||
public max?: (state: GameState) => number = undefined;
|
public max?: (state: GameState) => number = undefined;
|
||||||
public inc?: (state: GameState) => number = undefined;
|
public inc?: (state: GameState) => number = undefined;
|
||||||
|
|
||||||
|
public userActions: ResourceAction[] = [
|
||||||
|
{
|
||||||
|
name: 'Hire',
|
||||||
|
description: 'Promote one of your followers.',
|
||||||
|
isEnabled: (state: GameState): boolean =>
|
||||||
|
(this.max === undefined || this.value < this.max(state))
|
||||||
|
&& this.value < this._availableJobs(state),
|
||||||
|
performAction: (state: GameState): void => {
|
||||||
|
this._promoteFollower(state);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
protected _costMultiplier: { [key in ResourceKey]?: number } = { };
|
protected _costMultiplier: { [key in ResourceKey]?: number } = { };
|
||||||
protected _isUnlocked = false;
|
protected _isUnlocked = false;
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
public readonly name: string,
|
public readonly singularName: string,
|
||||||
|
public readonly pluralName: string,
|
||||||
public readonly description: string
|
public readonly description: string
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
public clickAction (state: GameState): void {
|
|
||||||
if (this._availableJobs(state) <= 0) {
|
|
||||||
state.log('You have no unemployed followers to promote.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.max !== undefined && this.value < this.max(state)
|
|
||||||
&& state.deductCost(this.cost)) {
|
|
||||||
this.addValue(1);
|
|
||||||
state.log(this._hireLog(1, state));
|
|
||||||
for (const key in this._costMultiplier) {
|
|
||||||
const rkey = <ResourceKey>key;
|
|
||||||
this.cost[rkey] =
|
|
||||||
(this.cost[rkey] ?? 0) * (this._costMultiplier[rkey] ?? 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public addValue (amount: number): void {
|
public addValue (amount: number): void {
|
||||||
this.value += amount;
|
this.value += amount;
|
||||||
if (this.value < 0) this.value = 0;
|
if (this.value < 0) this.value = 0;
|
||||||
|
@ -81,6 +76,23 @@ abstract class Job implements IResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _hireLog (amount: number, _state: GameState): string {
|
protected _hireLog (amount: number, _state: GameState): string {
|
||||||
return `You hired ${amount} x ${this.name}.`;
|
return `You hired ${amount} x ${this.pluralName}.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _promoteFollower (state: GameState): void {
|
||||||
|
if (this._availableJobs(state) <= 0) {
|
||||||
|
state.log('You have no unemployed followers to promote.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.max !== undefined && this.value < this.max(state)
|
||||||
|
&& state.deductCost(this.cost)) {
|
||||||
|
this.addValue(1);
|
||||||
|
state.log(this._hireLog(1, state));
|
||||||
|
for (const key in this._costMultiplier) {
|
||||||
|
const rkey = <ResourceKey>key;
|
||||||
|
this.cost[rkey] =
|
||||||
|
(this.cost[rkey] ?? 0) * (this._costMultiplier[rkey] ?? 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
/// <reference path="./Infrastructure.ts" />
|
/// <reference path="./Infrastructure.ts" />
|
||||||
|
|
||||||
class MegaChurch extends Infrastructure {
|
class Megachurch extends Infrastructure {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super('MegaChurches',
|
super(
|
||||||
`Room for ${config.formatNumber(config.cfgCapacity.megaChurches?.pastors ?? 0)} pastors`);
|
'megachurch',
|
||||||
|
'megachurches',
|
||||||
|
`Room for ${formatNumber(config.cfgCapacity.megaChurches?.pastors ?? 0)} pastors`);
|
||||||
this.cost.money = config.cfgInitialCost.megaChurches;
|
this.cost.money = config.cfgInitialCost.megaChurches;
|
||||||
this._costMultiplier.money = config.cfgCostMultiplier.megaChurches;
|
this._costMultiplier.money = config.cfgCostMultiplier.megaChurches;
|
||||||
}
|
}
|
|
@ -8,9 +8,12 @@ class Money extends Purchasable {
|
||||||
constructor (
|
constructor (
|
||||||
public value: number
|
public value: number
|
||||||
) {
|
) {
|
||||||
super('Money', 'Used to purchase goods and services.');
|
super(
|
||||||
this.clickText = 'Collect Tithes';
|
'money',
|
||||||
this.clickDescription = 'Voluntary contributions from followers.';
|
'moneys',
|
||||||
|
'Used to purchase goods and services.',
|
||||||
|
'Collect Tithes',
|
||||||
|
'Voluntary contributions from followers.');
|
||||||
this.valueInWholeNumbers = false;
|
this.valueInWholeNumbers = false;
|
||||||
this._isUnlocked = true;
|
this._isUnlocked = true;
|
||||||
}
|
}
|
||||||
|
@ -54,6 +57,6 @@ class Money extends Purchasable {
|
||||||
|
|
||||||
protected _purchaseLog (amount: number, state: GameState): string {
|
protected _purchaseLog (amount: number, state: GameState): string {
|
||||||
const followers = state.resource.playerOrg?.value ?? 0;
|
const followers = state.resource.playerOrg?.value ?? 0;
|
||||||
return `You collected $${state.config.formatNumber(amount)} from ${state.config.formatNumber(followers)} followers.`;
|
return `You collected $${formatNumber(amount)} from ${formatNumber(followers)} followers.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ abstract class Passive implements IResource {
|
||||||
public advanceAction?: (time: number, state: GameState) => void = undefined;
|
public advanceAction?: (time: number, state: GameState) => void = undefined;
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
public readonly name: string,
|
public readonly singularName: string,
|
||||||
|
public readonly pluralName: string,
|
||||||
public readonly description: string
|
public readonly description: string
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@ class Pastor extends Job {
|
||||||
private _timeSinceLastTithe = 0;
|
private _timeSinceLastTithe = 0;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
super('Pastors',
|
super(
|
||||||
|
'pastor',
|
||||||
|
'pastors',
|
||||||
'Collect tithings for you and recruit new members from other faiths automatically.');
|
'Collect tithings for you and recruit new members from other faiths automatically.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ class Pastor extends Job {
|
||||||
collected = money.max(state) - money.value;
|
collected = money.max(state) - money.value;
|
||||||
if (collected > 0) {
|
if (collected > 0) {
|
||||||
money?.addValue(collected, state);
|
money?.addValue(collected, state);
|
||||||
state.log(`Your pastors collected $${state.config.formatNumber(collected)} in tithings from ${state.config.formatNumber(tithed)} followers.`);
|
state.log(`Your pastors collected $${formatNumber(collected)} in tithings from ${formatNumber(tithed)} followers.`);
|
||||||
}
|
}
|
||||||
this._timeSinceLastTithe = 0;
|
this._timeSinceLastTithe = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,39 +3,36 @@
|
||||||
abstract class Purchasable implements IResource {
|
abstract class Purchasable implements IResource {
|
||||||
public readonly resourceType: ResourceType = ResourceType.consumable;
|
public readonly resourceType: ResourceType = ResourceType.consumable;
|
||||||
public valueInWholeNumbers = true;
|
public valueInWholeNumbers = true;
|
||||||
public clickText = 'Purchase';
|
|
||||||
public clickDescription = 'Purchase';
|
|
||||||
public value = 0;
|
public value = 0;
|
||||||
public readonly cost: ResourceNumber = { };
|
public readonly cost: ResourceNumber = { };
|
||||||
|
|
||||||
public inc?: (state: GameState) => number = undefined;
|
public inc?: (state: GameState) => number = undefined;
|
||||||
public max?: (_state: GameState) => number = undefined;
|
public max?: (_state: GameState) => number = undefined;
|
||||||
|
|
||||||
|
public userActions: ResourceAction[] = [
|
||||||
|
{
|
||||||
|
name: this._purchaseButtonText,
|
||||||
|
description: this._purchaseDescription,
|
||||||
|
isEnabled: (state: GameState): boolean =>
|
||||||
|
(this.max === undefined || this.value < this.max(state))
|
||||||
|
&& state.isPurchasable(this.cost),
|
||||||
|
performAction: (state: GameState): void => {
|
||||||
|
this._purchase(state);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
protected _costMultiplier: ResourceNumber = { };
|
protected _costMultiplier: ResourceNumber = { };
|
||||||
protected _isUnlocked = false;
|
protected _isUnlocked = false;
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
public readonly name: string,
|
public readonly singularName: string,
|
||||||
public readonly description: string
|
public readonly pluralName: string,
|
||||||
|
public readonly description: string,
|
||||||
|
private readonly _purchaseButtonText: string = 'Purchase',
|
||||||
|
private readonly _purchaseDescription: string = `Buy a ${singularName}.`,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
|
||||||
public clickAction (state: GameState): void {
|
|
||||||
if (this.max !== undefined && this.value >= this.max(state)) return;
|
|
||||||
if (state.deductCost(this.cost)) {
|
|
||||||
const amount = this._purchaseAmount(state);
|
|
||||||
if (amount > 0) {
|
|
||||||
this.value += amount;
|
|
||||||
state.log(this._purchaseLog(amount, state));
|
|
||||||
for (const key in this._costMultiplier) {
|
|
||||||
const rkey = <ResourceKey>key;
|
|
||||||
this.cost[rkey] =
|
|
||||||
(this.cost[rkey] ?? 0) * (this._costMultiplier[rkey] ?? 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public addValue (amount: number, _state: GameState): void {
|
public addValue (amount: number, _state: GameState): void {
|
||||||
this.value += amount;
|
this.value += amount;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +53,22 @@ abstract class Purchasable implements IResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _purchaseLog (amount: number, _state: GameState): string {
|
protected _purchaseLog (amount: number, _state: GameState): string {
|
||||||
return `You purchased ${amount} x ${this.name}.`;
|
return `You purchased ${amount} x ${this.pluralName}.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _purchase (state: GameState): void {
|
||||||
|
if (this.max !== undefined && this.value >= this.max(state)) return;
|
||||||
|
if (state.deductCost(this.cost)) {
|
||||||
|
const amount = this._purchaseAmount(state);
|
||||||
|
if (amount > 0) {
|
||||||
|
this.value += amount;
|
||||||
|
state.log(this._purchaseLog(amount, state));
|
||||||
|
for (const key in this._costMultiplier) {
|
||||||
|
const rkey = <ResourceKey>key;
|
||||||
|
this.cost[rkey] =
|
||||||
|
(this.cost[rkey] ?? 0) * (this._costMultiplier[rkey] ?? 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ class Religion implements IResource {
|
||||||
public readonly valueInWholeNumbers = true;
|
public readonly valueInWholeNumbers = true;
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
public readonly name: string,
|
public readonly singularName: string,
|
||||||
|
public readonly pluralName: string,
|
||||||
public readonly description: string,
|
public readonly description: string,
|
||||||
public value: number,
|
public value: number,
|
||||||
) { }
|
) { }
|
||||||
|
|
|
@ -5,13 +5,17 @@ abstract class Research extends Purchasable {
|
||||||
public inc = undefined;
|
public inc = undefined;
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
public readonly name: string,
|
public readonly singularName: string,
|
||||||
|
public readonly pluralName: string,
|
||||||
public readonly description: string
|
public readonly description: string
|
||||||
) {
|
) {
|
||||||
super(name, description);
|
super(
|
||||||
|
singularName,
|
||||||
|
pluralName,
|
||||||
|
description,
|
||||||
|
'Learn',
|
||||||
|
'Complete this research.');
|
||||||
this.value = 0;
|
this.value = 0;
|
||||||
this.clickText = 'Learn';
|
|
||||||
this.clickDescription = 'Complete this research.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public max: (state: GameState) => number = (_state) => 1;
|
public max: (state: GameState) => number = (_state) => 1;
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/// <reference path="../GameState.ts" />
|
||||||
|
|
||||||
|
enum ResourceType {
|
||||||
|
religion = 'religion',
|
||||||
|
job = 'job',
|
||||||
|
consumable = 'consumable',
|
||||||
|
infrastructure = 'infrastructure',
|
||||||
|
research = 'research',
|
||||||
|
passive = 'passive',
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ResourceKey {
|
||||||
|
playerOrg = 'playerOrg',
|
||||||
|
christianity = 'christianity',
|
||||||
|
islam = 'islam',
|
||||||
|
hinduism = 'hinduism',
|
||||||
|
buddhism = 'buddhism',
|
||||||
|
sikhism = 'sikhism',
|
||||||
|
judaism = 'judaism',
|
||||||
|
other = 'other',
|
||||||
|
atheism = 'atheism',
|
||||||
|
pastors = 'pastors',
|
||||||
|
money = 'money',
|
||||||
|
cryptoCurrency = 'cryptoCurrency',
|
||||||
|
tents = 'tents',
|
||||||
|
houses = 'houses',
|
||||||
|
churches = 'churches',
|
||||||
|
compounds = 'compounds',
|
||||||
|
buildingPermit = 'buildingPermit',
|
||||||
|
megaChurches = 'megaChurches',
|
||||||
|
credibility = 'credibility',
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourceNumber = { [key in ResourceKey]?: number };
|
||||||
|
|
||||||
|
type ResourceAction = {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
isEnabled: (state: GameState) => boolean;
|
||||||
|
performAction: (state: GameState) => void;
|
||||||
|
};
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
class Tent extends Infrastructure {
|
class Tent extends Infrastructure {
|
||||||
constructor (config: GameConfig) {
|
constructor (config: GameConfig) {
|
||||||
super('Tents',
|
super(
|
||||||
`Provides room to house ${config.formatNumber(config.cfgCapacity.tents?.playerOrg ?? 0)} followers.`);
|
'tent',
|
||||||
|
'tents',
|
||||||
|
`Provides room to house ${formatNumber(config.cfgCapacity.tents?.playerOrg ?? 0)} followers.`);
|
||||||
this.cost.money = config.cfgInitialCost.tents;
|
this.cost.money = config.cfgInitialCost.tents;
|
||||||
this._costMultiplier.money = config.cfgCostMultiplier.tents;
|
this._costMultiplier.money = config.cfgCostMultiplier.tents;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,17 +53,21 @@ class DebugRenderer implements IRenderer {
|
||||||
let content = `
|
let content = `
|
||||||
<span class='resource-title'
|
<span class='resource-title'
|
||||||
title='${this._escape(resource.description)}'>
|
title='${this._escape(resource.description)}'>
|
||||||
${this._escape(resource.name)}</span><br>
|
${this._escape(resource.pluralName)}</span><br>
|
||||||
<span class='resource-value'></span>
|
<span class='resource-value'></span>
|
||||||
<span class='resource-max'></span>
|
<span class='resource-max'></span>
|
||||||
<span class='resource-inc'></span>
|
<span class='resource-inc'></span>
|
||||||
`;
|
`;
|
||||||
if (resource.clickText !== undefined
|
if (resource.userActions !== undefined) {
|
||||||
&& resource.clickDescription !== undefined) {
|
content += '<br>';
|
||||||
content += `<br>
|
for (let i = 0; i < resource.userActions.length; i++) {
|
||||||
<button class='resource-btn'
|
const action = resource.userActions[i];
|
||||||
title='${this._escape(resource.clickDescription)}'>
|
content += `<button
|
||||||
${this._escape(resource.clickText)}</button>`;
|
id='resource-btn-${rkey}-${i}'
|
||||||
|
class='resource-btn'
|
||||||
|
title='${this._escape(action.description)}'>
|
||||||
|
${this._escape(action.name)}</button>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (resource.cost !== undefined
|
if (resource.cost !== undefined
|
||||||
&& Object.keys(resource.cost).length !== 0) {
|
&& Object.keys(resource.cost).length !== 0) {
|
||||||
|
@ -71,13 +75,16 @@ class DebugRenderer implements IRenderer {
|
||||||
}
|
}
|
||||||
el.innerHTML = content;
|
el.innerHTML = content;
|
||||||
resContainer.appendChild(el);
|
resContainer.appendChild(el);
|
||||||
if (resource.clickAction !== undefined) {
|
if (resource.userActions !== undefined) {
|
||||||
const btn = el.getElementsByClassName('resource-btn')[0];
|
for (let i = 0; i < resource.userActions.length; i++) {
|
||||||
btn.addEventListener('click', (): void => {
|
const action = resource.userActions[i];
|
||||||
state.performClick(rkey);
|
const btn = document.getElementById(`resource-btn-${rkey}-${i}`);
|
||||||
|
btn?.addEventListener('click', (): void => {
|
||||||
|
state.performAction(rkey, i);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// create tools footer
|
// create tools footer
|
||||||
const footer = document.createElement('div');
|
const footer = document.createElement('div');
|
||||||
footer.className = 'footer';
|
footer.className = 'footer';
|
||||||
|
@ -103,22 +110,25 @@ class DebugRenderer implements IRenderer {
|
||||||
const value = resource.valueInWholeNumbers
|
const value = resource.valueInWholeNumbers
|
||||||
? Math.floor(resource.value)
|
? Math.floor(resource.value)
|
||||||
: resource.value;
|
: resource.value;
|
||||||
elV.innerHTML = state.config.formatNumber(value);
|
elV.innerHTML = formatNumber(value);
|
||||||
elT.innerHTML = resource.max !== undefined
|
elT.innerHTML = resource.max !== undefined
|
||||||
? ` / ${state.config.formatNumber(resource.max(state))}`
|
? ` / ${formatNumber(resource.max(state))}`
|
||||||
: '';
|
: '';
|
||||||
const elB = el.getElementsByClassName('resource-btn');
|
if (resource.userActions !== undefined) {
|
||||||
if (elB.length > 0) {
|
for (let i = 0; i < resource.userActions.length; i++) {
|
||||||
const enabled = state.isPurchasable(resource.cost)
|
const elB = document.getElementById(`resource-btn-${rkey}-${i}`);
|
||||||
&& (resource.max === undefined
|
if (elB === null) continue;
|
||||||
|| resource.value < resource.max(state));
|
if (resource.userActions[i].isEnabled(state)) {
|
||||||
if (enabled) elB[0].removeAttribute('disabled');
|
elB.removeAttribute('disabled');
|
||||||
else elB[0].setAttribute('disabled', 'disabled');
|
} else {
|
||||||
|
elB.setAttribute('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (resource.inc !== undefined && resource.inc(state) > 0) {
|
if (resource.inc !== undefined && resource.inc(state) > 0) {
|
||||||
const elI = el.getElementsByClassName('resource-inc')[0];
|
const elI = el.getElementsByClassName('resource-inc')[0];
|
||||||
elI.innerHTML =
|
elI.innerHTML =
|
||||||
` +${state.config.formatNumber(resource.inc(state))}/s`;
|
` +${formatNumber(resource.inc(state))}/s`;
|
||||||
}
|
}
|
||||||
if (this._handleClick) {
|
if (this._handleClick) {
|
||||||
const elC = el.getElementsByClassName('resource-cost');
|
const elC = el.getElementsByClassName('resource-cost');
|
||||||
|
@ -154,10 +164,10 @@ class DebugRenderer implements IRenderer {
|
||||||
if (resource.cost?.[rkey] !== undefined) {
|
if (resource.cost?.[rkey] !== undefined) {
|
||||||
if (cost !== '') cost += ', ';
|
if (cost !== '') cost += ', ';
|
||||||
if (rkey === ResourceKey.money) {
|
if (rkey === ResourceKey.money) {
|
||||||
cost += `$${state.config.formatNumber(resource.cost[rkey] ?? 0)}`;
|
cost += `$${formatNumber(resource.cost[rkey] ?? 0)}`;
|
||||||
} else {
|
} else {
|
||||||
cost += `${state.config.formatNumber(resource.cost[rkey] ?? 0)}
|
cost += `${formatNumber(resource.cost[rkey] ?? 0)}
|
||||||
${state.resource[rkey]?.name ?? rkey}`;
|
${state.resource[rkey]?.pluralName ?? rkey}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue