changed cost into function; changed inc into ResourcNumber
This commit is contained in:
parent
a0daffbddf
commit
0b6e263cc7
14
TODO.md
14
TODO.md
|
@ -1,7 +1,5 @@
|
|||
## In Progress
|
||||
|
||||
- [ ] change `inc` to a `ResourceNumber` instead of a `number`
|
||||
- [ ] change `cost` into a function that computes based on `value`
|
||||
|
||||
## Initial Game Progression Plan
|
||||
|
||||
|
@ -13,17 +11,16 @@
|
|||
- [x] houses (+follower cap)
|
||||
- [x] churches (+pastor cap)
|
||||
- [x] hire pastors to recruit and gather tithes (+money, +followers)
|
||||
- [ ] hire compound managers to auto-build (+tents, +houses, +churches)
|
||||
- [ ] fluctuating crypto market value passive determines crypto value
|
||||
- [x] hire compound managers to auto-build (+tents, +houses, +churches)
|
||||
- [x] fluctuating crypto market value passive determines crypto value
|
||||
- [ ] prosperity gospel policy increases tithes, decreases recruitment rate
|
||||
- main resource problems:
|
||||
- [x] lose money on purchases
|
||||
- [x] lose money for salaries
|
||||
- [ ] lose money for compound maintenance
|
||||
- [x] gain money from tithes
|
||||
- [x] low credibility loses followers
|
||||
- [ ] low and decreasing money loses jobs
|
||||
- [ ] gain or lose money on crypto based on market passive
|
||||
- [x] low and decreasing money loses jobs
|
||||
- [x] gain or lose money on crypto based on market passive
|
||||
|
||||
### Phase 2: 1K-100K Followers
|
||||
|
||||
|
@ -84,10 +81,7 @@
|
|||
## Short-Term Todos
|
||||
|
||||
- [ ] add `disabledHint` to `userActions` to generate hint about how to enable an action
|
||||
- [x] add an action to sell purchasables and regain some portion of their cost
|
||||
- [ ] add a `policy` resource type that can be toggled on or off
|
||||
- [x] remove recruitment effects of credibility (that will be for notoriety instead)
|
||||
- [x] change `value` to a getter that does `Math.floor` if it's a whole number resource
|
||||
|
||||
## Long-Term Ideas
|
||||
|
||||
|
|
|
@ -89,12 +89,12 @@ class GameConfig {
|
|||
public cfgCryptoMarketAdjustAmount = 0.1;
|
||||
public cfgCryptoMarketAdjustPeriod = 30000;
|
||||
public cfgCryptoMarketGrowthBias = 0.1;
|
||||
public cfgDefaultSellMultiplier = 0.5;
|
||||
public cfgFollowerGainLossLogTimer = 10000;
|
||||
public cfgNoMoneyQuitRate = 0.2;
|
||||
public cfgNoMoneyQuitTime = 10000;
|
||||
public cfgPassiveMax = 100;
|
||||
public cfgPastorRecruitRate = 0.01;
|
||||
public cfgSellCostBackMultiplier = 0.5;
|
||||
public cfgTimeBetweenTithes = 10000;
|
||||
public cfgTitheAmount = 10000;
|
||||
public cfgTitheCredibilityHitFactor = 3;
|
||||
|
@ -202,7 +202,7 @@ class GameConfig {
|
|||
|
||||
// add resources
|
||||
state.addResource(new Money(3.5));
|
||||
state.addResource(new CryptoCurrency(this));
|
||||
state.addResource(new CryptoCurrency());
|
||||
state.addResource(new Tent(this));
|
||||
state.addResource(new House(this));
|
||||
state.addResource(new Church(this));
|
||||
|
|
|
@ -58,7 +58,10 @@ class GameState {
|
|||
resource.inc !== undefined &&
|
||||
(resource.max === undefined || resource.value < resource.max(this))
|
||||
) {
|
||||
resource.addValue((resource.inc(this) * time) / 1000, this);
|
||||
resource.addValue(
|
||||
(resourceNumberSum(resource.inc(this)) * time) / 1000,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
if (resource.max !== undefined && resource.value > resource.max(this)) {
|
||||
|
@ -138,7 +141,6 @@ class GameState {
|
|||
if (resource === undefined) continue;
|
||||
const resSav: ResourceConfig = {
|
||||
value: resource.value,
|
||||
cost: resource.cost,
|
||||
};
|
||||
if (resource.emitConfig !== undefined) {
|
||||
resSav.config = resource.emitConfig();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="./resource/SharedTypes.ts" />
|
||||
|
||||
const numberFormatDigits = 1;
|
||||
|
||||
function formatNumber(num: number): string {
|
||||
|
@ -26,3 +28,12 @@ function formatNumber(num: number): string {
|
|||
|
||||
return `${sign}${number}`;
|
||||
}
|
||||
|
||||
function resourceNumberSum(res: ResourceNumber): number {
|
||||
let sum = 0;
|
||||
for (const key in res) {
|
||||
const rkey = <ResourceKey>key;
|
||||
sum += res[rkey] ?? 0;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class BuildingPermit extends Research {
|
|||
'building permits',
|
||||
'Unlocks several new buildings you can build outside of your compounds.'
|
||||
);
|
||||
this.cost.money = config.cfgInitialCost.buildingPermit;
|
||||
this._baseCost.money = config.cfgInitialCost.buildingPermit;
|
||||
}
|
||||
|
||||
public isUnlocked = (state: GameState): boolean => {
|
||||
|
|
|
@ -15,7 +15,7 @@ class Church extends Infrastructure {
|
|||
undefined,
|
||||
undefined
|
||||
);
|
||||
this.cost.money = config.cfgInitialCost.churches;
|
||||
this._baseCost.money = config.cfgInitialCost.churches;
|
||||
this._costMultiplier.money = config.cfgCostMultiplier.churches;
|
||||
}
|
||||
|
||||
|
@ -23,12 +23,15 @@ class Church extends Infrastructure {
|
|||
(state.resource.compounds?.value ?? 0) *
|
||||
(state.config.cfgCapacity.compounds?.churches ?? 0);
|
||||
|
||||
public inc = (state: GameState): number => {
|
||||
// compound managers
|
||||
return (
|
||||
public inc = (state: GameState): ResourceNumber => {
|
||||
const inc: ResourceNumber = {};
|
||||
const compoundManagers =
|
||||
(state.resource.compoundManagers?.value ?? 0) *
|
||||
(state.config.cfgBuySpeed.compoundManagers?.churches ?? 0)
|
||||
);
|
||||
(state.config.cfgBuySpeed.compoundManagers?.churches ?? 0);
|
||||
if (compoundManagers > 0) {
|
||||
inc.compoundManagers = compoundManagers;
|
||||
}
|
||||
return inc;
|
||||
};
|
||||
|
||||
public isUnlocked = (state: GameState): boolean => {
|
||||
|
|
|
@ -11,7 +11,7 @@ class Compound extends Infrastructure {
|
|||
'Provides space for tents, houses, and churches and a place to hide more money.',
|
||||
true
|
||||
);
|
||||
this.cost.money = config.cfgInitialCost.compounds;
|
||||
this._baseCost.money = config.cfgInitialCost.compounds;
|
||||
this._costMultiplier.money = config.cfgCostMultiplier.compounds;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ class Credibility extends Passive {
|
|||
|
||||
public max = (state: GameState): number => state.config.cfgPassiveMax;
|
||||
|
||||
public inc = (state: GameState): number =>
|
||||
state.config.cfgCredibilityRestoreRate;
|
||||
public inc = (state: GameState): ResourceNumber => {
|
||||
const inc: ResourceNumber = {};
|
||||
inc.credibility = state.config.cfgCredibilityRestoreRate;
|
||||
return inc;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class CryptoCurrency extends Purchasable {
|
||||
public readonly resourceKey = ResourceKey.cryptoCurrency;
|
||||
|
||||
constructor(config: GameConfig) {
|
||||
constructor() {
|
||||
super(
|
||||
'FaithCoin',
|
||||
'faithcoin',
|
||||
|
@ -11,11 +11,21 @@ class CryptoCurrency extends Purchasable {
|
|||
"A crypto coin that can't be spent directly, but provides a steady stream of passive income.",
|
||||
true
|
||||
);
|
||||
this.cost.money = config.cfgInitialCost.cryptoCurrency;
|
||||
this.valueInWholeNumbers = false;
|
||||
}
|
||||
|
||||
public isUnlocked = (_state: GameState): boolean => true;
|
||||
public cost = (state: GameState): ResourceNumber => {
|
||||
const cost: ResourceNumber = {};
|
||||
const market = state.resource.cryptoMarket;
|
||||
if (market !== undefined) {
|
||||
cost.money = market.value;
|
||||
} else {
|
||||
cost.money = state.config.cfgInitialCost.cryptoCurrency;
|
||||
}
|
||||
return cost;
|
||||
};
|
||||
|
||||
public isUnlocked = (): boolean => true;
|
||||
|
||||
public max = (state: GameState): number =>
|
||||
state.config.cfgInitialMax.cryptoCurrency ?? 0;
|
||||
|
|
|
@ -40,17 +40,13 @@ class CryptoMarket extends Hidden {
|
|||
) {
|
||||
adjustment = state.config.cfgCryptoCurrencyMinimumValue - this.value;
|
||||
}
|
||||
//if (Math.abs(adjustment) > 0) {
|
||||
if (Math.abs(adjustment) > 0) {
|
||||
this.addValue(adjustment, state);
|
||||
state.log(
|
||||
`FaithCoin just ${
|
||||
adjustment > 0 ? 'increased' : 'decreased'
|
||||
} in value by $${formatNumber(Math.abs(adjustment))}.`
|
||||
);
|
||||
//}
|
||||
if (crypto?.cost !== undefined) {
|
||||
crypto.cost.money = this.value;
|
||||
state.autoAction(); // cause redraw
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -39,12 +39,14 @@ class Follower extends Resource {
|
|||
return max;
|
||||
};
|
||||
|
||||
public inc = (state: GameState): number => {
|
||||
let inc = 0;
|
||||
public inc = (state: GameState): ResourceNumber => {
|
||||
const inc: ResourceNumber = {};
|
||||
|
||||
// pastor recruiting
|
||||
const pastors = state.resource.pastors?.value ?? 0;
|
||||
inc += pastors * state.config.cfgPastorRecruitRate;
|
||||
const pastors =
|
||||
(state.resource.pastors?.value ?? 0) * state.config.cfgPastorRecruitRate;
|
||||
|
||||
if (pastors > 0) inc.pastors = pastors;
|
||||
|
||||
// credibility adjustment
|
||||
// this should be based on notoriety instead
|
||||
|
|
|
@ -13,7 +13,7 @@ class House extends Infrastructure {
|
|||
)} followers.`,
|
||||
true
|
||||
);
|
||||
this.cost.money = config.cfgInitialCost.houses;
|
||||
this._baseCost.money = config.cfgInitialCost.houses;
|
||||
this._costMultiplier.money = config.cfgCostMultiplier.houses;
|
||||
}
|
||||
|
||||
|
@ -21,12 +21,15 @@ class House extends Infrastructure {
|
|||
(state.resource.compounds?.value ?? 0) *
|
||||
(state.config.cfgCapacity.compounds?.houses ?? 0);
|
||||
|
||||
public inc = (state: GameState): number => {
|
||||
// compound managers
|
||||
return (
|
||||
public inc = (state: GameState): ResourceNumber => {
|
||||
const inc: ResourceNumber = {};
|
||||
const compoundManagers =
|
||||
(state.resource.compoundManagers?.value ?? 0) *
|
||||
(state.config.cfgBuySpeed.compoundManagers?.houses ?? 0)
|
||||
);
|
||||
(state.config.cfgBuySpeed.compoundManagers?.houses ?? 0);
|
||||
if (compoundManagers > 0) {
|
||||
inc.compoundManagers = compoundManagers;
|
||||
}
|
||||
return inc;
|
||||
};
|
||||
|
||||
public isUnlocked = (state: GameState): boolean => {
|
||||
|
|
|
@ -4,10 +4,9 @@ abstract class Job extends Resource {
|
|||
public readonly resourceType = ResourceType.job;
|
||||
|
||||
public readonly valueInWholeNumbers = true;
|
||||
public readonly cost: ResourceNumber = {};
|
||||
|
||||
public max?: (state: GameState) => number = undefined;
|
||||
public inc?: (state: GameState) => number = undefined;
|
||||
public inc?: (state: GameState) => ResourceNumber = undefined;
|
||||
|
||||
public userActions: ResourceAction[] = [
|
||||
{
|
||||
|
@ -31,7 +30,6 @@ abstract class Job extends Resource {
|
|||
},
|
||||
];
|
||||
|
||||
protected _costMultiplier: { [key in ResourceKey]?: number } = {};
|
||||
protected _isUnlocked = false;
|
||||
|
||||
constructor(
|
||||
|
@ -102,18 +100,9 @@ abstract class Job extends Resource {
|
|||
|
||||
private _promoteFollower(state: GameState): void {
|
||||
if (Job.availableJobs(state) <= 0) return;
|
||||
if (
|
||||
this.max !== undefined &&
|
||||
this.value < this.max(state) &&
|
||||
state.deductCost(this.cost)
|
||||
) {
|
||||
if (this.max !== undefined && this.value < this.max(state)) {
|
||||
this.addValue(1, state);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,10 +110,5 @@ abstract class Job extends Resource {
|
|||
if (this.value <= 0) return;
|
||||
this.addValue(-1, state);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ class Megachurch extends Infrastructure {
|
|||
)} pastors`,
|
||||
true
|
||||
);
|
||||
this.cost.money = config.cfgInitialCost.megaChurches;
|
||||
this._baseCost.money = config.cfgInitialCost.megaChurches;
|
||||
this._costMultiplier.money = config.cfgCostMultiplier.megaChurches;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,11 @@ class Money extends Resource {
|
|||
return max;
|
||||
};
|
||||
|
||||
public inc = (state: GameState): number => {
|
||||
let inc = 0;
|
||||
public inc = (state: GameState): ResourceNumber => {
|
||||
const inc: ResourceNumber = {};
|
||||
|
||||
// tithings
|
||||
inc +=
|
||||
const tithings =
|
||||
((state.resource.pastors?.value ?? 0) *
|
||||
(state.resource.followers?.value ?? 0) *
|
||||
(state.config.cfgTitheAmount ?? 0) *
|
||||
|
@ -52,10 +52,13 @@ class Money extends Resource {
|
|||
state.config.cfgTimeBetweenTithes;
|
||||
|
||||
// salaries
|
||||
inc -=
|
||||
const compoundManagers =
|
||||
(state.resource.compoundManagers?.value ?? 0) *
|
||||
(state.config.cfgSalary.compoundManagers ?? 0);
|
||||
|
||||
if (tithings > 0) inc.pastors = tithings;
|
||||
if (compoundManagers > 0) inc.compoundManagers = compoundManagers * -1;
|
||||
|
||||
return inc;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,10 +4,9 @@ abstract class Purchasable extends Resource {
|
|||
public readonly resourceType: ResourceType = ResourceType.purchasable;
|
||||
|
||||
public valueInWholeNumbers = true;
|
||||
public cost: ResourceNumber = {};
|
||||
|
||||
public inc?: (state: GameState) => number = undefined;
|
||||
public max?: (state: GameState) => number = undefined;
|
||||
public inc?: (state: GameState) => ResourceNumber = undefined;
|
||||
|
||||
public userActions: ResourceAction[] = [
|
||||
{
|
||||
|
@ -15,19 +14,17 @@ abstract class Purchasable extends Resource {
|
|||
description: this._purchaseDescription,
|
||||
isEnabled: (state: GameState): boolean =>
|
||||
(this.max === undefined || this.value < this.max(state)) &&
|
||||
state.isPurchasable(this.cost),
|
||||
state.isPurchasable(this.cost(state)),
|
||||
performAction: (state: GameState): void => {
|
||||
this._purchase(state);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
protected _costMultiplier: ResourceNumber = {};
|
||||
protected _sellMultiplier?: number | ResourceNumber;
|
||||
protected readonly _baseCost: ResourceNumber = {};
|
||||
protected readonly _costMultiplier: ResourceNumber = {};
|
||||
protected _isUnlocked = false;
|
||||
|
||||
private _lastWholeNumberValue = 0;
|
||||
|
||||
constructor(
|
||||
public readonly label: string,
|
||||
public readonly singularName: string,
|
||||
|
@ -52,8 +49,21 @@ abstract class Purchasable extends Resource {
|
|||
}
|
||||
}
|
||||
|
||||
public cost = (_: GameState): ResourceNumber => {
|
||||
if (this.value <= 0) return this._baseCost;
|
||||
|
||||
const actualCost: ResourceNumber = {};
|
||||
for (const key in this._baseCost) {
|
||||
const rkey = <ResourceKey>key;
|
||||
const baseCost = this._baseCost[rkey] ?? 0;
|
||||
const multiplier = this._costMultiplier[rkey] ?? 1;
|
||||
actualCost[rkey] = baseCost * Math.pow(multiplier, this.value);
|
||||
}
|
||||
return actualCost;
|
||||
};
|
||||
|
||||
public isUnlocked = (state: GameState): boolean => {
|
||||
if (!this._isUnlocked && state.isPurchasable(this.cost)) {
|
||||
if (!this._isUnlocked && state.isPurchasable(this.cost(state))) {
|
||||
this._isUnlocked = true;
|
||||
}
|
||||
return this._isUnlocked;
|
||||
|
@ -73,21 +83,6 @@ abstract class Purchasable extends Resource {
|
|||
}
|
||||
};
|
||||
|
||||
public addValue = (amount: number, _: GameState): void => {
|
||||
this.rawValue += amount;
|
||||
const wholeNumberChange = this.value - this._lastWholeNumberValue;
|
||||
if (wholeNumberChange > 0) {
|
||||
for (const key in this._costMultiplier) {
|
||||
const rkey = <ResourceKey>key;
|
||||
this.cost[rkey] =
|
||||
(this.cost[rkey] ?? 0) *
|
||||
(this._costMultiplier[rkey] ?? 1) *
|
||||
wholeNumberChange;
|
||||
}
|
||||
this._lastWholeNumberValue = this.value;
|
||||
}
|
||||
};
|
||||
|
||||
protected _purchaseLog(amount: number, _state: GameState): string {
|
||||
let verb = 'purchased';
|
||||
if (amount < 0) {
|
||||
|
@ -101,7 +96,7 @@ abstract class Purchasable extends Resource {
|
|||
|
||||
private _purchase(state: GameState): void {
|
||||
if (this.max !== undefined && this.value >= this.max(state)) return;
|
||||
if (state.deductCost(this.cost)) {
|
||||
if (state.deductCost(this.cost(state))) {
|
||||
this.addValue(1, state);
|
||||
state.log(this._purchaseLog(1, state));
|
||||
}
|
||||
|
@ -109,25 +104,17 @@ abstract class Purchasable extends Resource {
|
|||
|
||||
private _sell(state: GameState): void {
|
||||
if (this.value <= 0) return;
|
||||
const costBack: ResourceNumber = {};
|
||||
for (const key in this.cost) {
|
||||
const rkey = <ResourceKey>key;
|
||||
let cost = this.cost[rkey];
|
||||
if (cost === undefined) continue;
|
||||
// revert cost multiplier
|
||||
cost /= this._costMultiplier[rkey] ?? 1;
|
||||
this.cost[rkey] = cost;
|
||||
const multiplier =
|
||||
this._sellMultiplier === undefined
|
||||
? state.config.cfgDefaultSellMultiplier
|
||||
: typeof this._sellMultiplier === 'number'
|
||||
? this._sellMultiplier
|
||||
: this._sellMultiplier[rkey] ?? state.config.cfgDefaultSellMultiplier;
|
||||
// penalize return on used item
|
||||
costBack[rkey] = cost * -1 * multiplier;
|
||||
state.deductCost(costBack);
|
||||
}
|
||||
|
||||
this.addValue(-1, state);
|
||||
state.log(this._purchaseLog(-1, state));
|
||||
|
||||
const costBack: ResourceNumber = {};
|
||||
for (const key in this.cost(state)) {
|
||||
const rkey = <ResourceKey>key;
|
||||
const cost = this.cost(state)[rkey];
|
||||
if (cost === undefined) continue;
|
||||
costBack[rkey] = cost * state.config.cfgSellCostBackMultiplier * -1;
|
||||
}
|
||||
state.deductCost(costBack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
/// <reference path="./IResource.ts" />
|
||||
|
||||
abstract class Resource implements IResource {
|
||||
public inc?: (state: GameState) => ResourceNumber = undefined;
|
||||
public cost?: (state: GameState) => ResourceNumber = undefined;
|
||||
public max?: (state: GameState) => number = undefined;
|
||||
|
||||
protected rawValue = 0;
|
||||
|
||||
public abstract readonly resourceType: ResourceType;
|
||||
|
|
|
@ -13,7 +13,7 @@ class Tent extends Infrastructure {
|
|||
)} followers.`,
|
||||
true
|
||||
);
|
||||
this.cost.money = config.cfgInitialCost.tents;
|
||||
this._baseCost.money = config.cfgInitialCost.tents;
|
||||
this._costMultiplier.money = config.cfgCostMultiplier.tents;
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,14 @@ class Tent extends Infrastructure {
|
|||
return max;
|
||||
};
|
||||
|
||||
public inc = (state: GameState): number =>
|
||||
// compound managers
|
||||
public inc = (state: GameState): ResourceNumber => {
|
||||
const inc: ResourceNumber = {};
|
||||
const compoundManagers =
|
||||
(state.resource.compoundManagers?.value ?? 0) *
|
||||
(state.config.cfgBuySpeed.compoundManagers?.tents ?? 0);
|
||||
if (compoundManagers > 0) {
|
||||
inc.compoundManagers = compoundManagers;
|
||||
}
|
||||
return inc;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ class DebugRenderer implements IRenderer {
|
|||
}
|
||||
if (
|
||||
resource.cost !== undefined &&
|
||||
Object.keys(resource.cost).length !== 0
|
||||
Object.keys(resource.cost(state)).length !== 0
|
||||
) {
|
||||
content += "<br>Cost: <span class='resource-cost'></span>";
|
||||
}
|
||||
|
@ -81,7 +81,6 @@ class DebugRenderer implements IRenderer {
|
|||
resContainer.appendChild(el);
|
||||
if (resource.userActions !== undefined) {
|
||||
for (let i = 0; i < resource.userActions.length; i++) {
|
||||
const action = resource.userActions[i];
|
||||
const btn = document.getElementById(`resource-btn-${rkey}-${i}`);
|
||||
btn?.addEventListener('click', (): void => {
|
||||
state.performAction(rkey, i);
|
||||
|
@ -135,13 +134,17 @@ class DebugRenderer implements IRenderer {
|
|||
}
|
||||
}
|
||||
}
|
||||
const inc =
|
||||
resource.inc !== undefined ? resource.inc(state) : undefined;
|
||||
if (resource.inc !== undefined) {
|
||||
const resInc = resource.inc(state);
|
||||
const inc = resourceNumberSum(resInc);
|
||||
const elI = el.getElementsByClassName('resource-inc')[0];
|
||||
if (inc !== undefined && inc !== 0) {
|
||||
if (inc !== 0) {
|
||||
elI.innerHTML = ` ${inc > 0 ? '+' : ''}${formatNumber(inc)}/s`;
|
||||
elI.setAttribute('title', this._getIncDetails(resource, state));
|
||||
} else if (elI.innerHTML !== '') {
|
||||
elI.innerHTML = '';
|
||||
elI.removeAttribute('title');
|
||||
}
|
||||
}
|
||||
if (this._handleClick) {
|
||||
const elC = el.getElementsByClassName('resource-cost');
|
||||
|
@ -177,17 +180,37 @@ class DebugRenderer implements IRenderer {
|
|||
|
||||
private _getCostStr(resource: IResource, state: GameState): string {
|
||||
let cost = '';
|
||||
if (resource.cost === undefined) return cost;
|
||||
for (const rkey of state.resources) {
|
||||
if (resource.cost?.[rkey] !== undefined) {
|
||||
const rcost = resource.cost(state)[rkey];
|
||||
if (rcost !== undefined && rcost > 0) {
|
||||
if (cost !== '') cost += ', ';
|
||||
if (rkey === ResourceKey.money) {
|
||||
cost += `$${formatNumber(resource.cost[rkey] ?? 0)}`;
|
||||
cost += `$${formatNumber(rcost)}`;
|
||||
} else {
|
||||
cost += `${formatNumber(resource.cost[rkey] ?? 0)}
|
||||
${state.resource[rkey]?.pluralName ?? rkey}`;
|
||||
cost += `${formatNumber(rcost)} ${
|
||||
(rcost > 1
|
||||
? state.resource[rkey]?.pluralName
|
||||
: state.resource[rkey]?.singularName) ?? rkey
|
||||
}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
private _getIncDetails(resource: IResource, state: GameState): string {
|
||||
let inc = '';
|
||||
if (resource.inc === undefined) return inc;
|
||||
for (const rkey of state.resources) {
|
||||
const incRes = state.resource[rkey];
|
||||
if (incRes === undefined || incRes.label === undefined) continue;
|
||||
const rinc = resource.inc(state)[rkey];
|
||||
if (rinc !== undefined && rinc !== 0) {
|
||||
if (inc !== '') inc += '\n';
|
||||
inc += `${incRes.label}: ${rinc > 0 ? '+' : ''}${formatNumber(rinc)}/s`;
|
||||
}
|
||||
}
|
||||
return inc;
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue