diff --git a/src/model/GameState.ts b/src/model/GameState.ts index 08263f0..3a3801b 100644 --- a/src/model/GameState.ts +++ b/src/model/GameState.ts @@ -50,13 +50,14 @@ class GameState { : 0; if (inc > 0 && (max === null || this._resources[rkey].value < max)) { - this._resources[rkey].value += inc * time / 1000; + this._resources[rkey].addValue(inc * time / 1000, this); } - if (max !== null && this._resources[rkey].value > max) { - this._resources[rkey].value = max; + const val: number = this._resources[rkey].value; + if (max !== null && val > max) { + this._resources[rkey].addValue((val - max) * -1, this); } - if (this._resources[rkey].value < 0) { - this._resources[rkey].value = 0; + if (val < 0) { + this._resources[rkey].addValue(val * -1, this); } } } @@ -82,7 +83,7 @@ class GameState { if (cost === null || Object.keys(cost) === null) return true; if (!this.isPurchasable(cost)) return false; for (const rkey of Object.keys(cost)) { - this._resources[rkey].value -= cost[rkey]; + this._resources[rkey].addValue(cost[rkey] * -1, this); } return true; } @@ -151,7 +152,9 @@ class GameState { if (saveObj[rkey] !== undefined && saveObj[rkey].value !== undefined && saveObj[rkey].cost !== undefined) { + // @ts-ignore this._resources[rkey].value = saveObj[rkey].value; + // @ts-ignore this._resources[rkey].cost = saveObj[rkey].cost; } } diff --git a/src/model/resource/Credibility.ts b/src/model/resource/Credibility.ts index a01e024..ba880d3 100644 --- a/src/model/resource/Credibility.ts +++ b/src/model/resource/Credibility.ts @@ -6,8 +6,9 @@ class Credibility extends Passive { constructor () { super( 'Credibility', - 'Affects your ability to recruit and retain followers.', - 100, 100, 0.25); + 'Affects your ability to recruit and retain followers.'); + this._baseMax = 100; + this.value = 100; } public max (state: GameState): number { diff --git a/src/model/resource/CryptoCurrency.ts b/src/model/resource/CryptoCurrency.ts index 3455663..ab475b0 100644 --- a/src/model/resource/CryptoCurrency.ts +++ b/src/model/resource/CryptoCurrency.ts @@ -1,13 +1,12 @@ /// class CryptoCurrency extends Purchasable { - public readonly valueInWholeNumbers: boolean = false; - constructor () { super('Faithcoin', "A crypto coin that can't be spent directly, but provides a steady stream of passive income."); this.cost.money = 100; this._costMultiplier.money = 1.1; this._baseMax = 1000; + this.valueInWholeNumbers = false; } } diff --git a/src/model/resource/IResource.ts b/src/model/resource/IResource.ts index 537aebe..2bb0eb0 100644 --- a/src/model/resource/IResource.ts +++ b/src/model/resource/IResource.ts @@ -7,24 +7,19 @@ enum ResourceType { } interface IResource { - name: string | null; - description: string | null; - - resourceType: ResourceType; - value: number; - valueInWholeNumbers: boolean; - - clickText: string; - clickDescription: string; - - clickAction (state: GameState): void; - - cost: { [key: string]: number }; + readonly resourceType: ResourceType; + readonly name: string | null; + readonly description: string | null; + readonly valueInWholeNumbers: boolean; + readonly clickText: string; + readonly clickDescription: string; + readonly value: number; + readonly cost: { [key: string]: number }; max (state: GameState): number | null; inc (state: GameState): number | null; - + clickAction (state: GameState): void; + addValue (amount: number, state: GameState): void; isUnlocked (state: GameState): boolean; - advanceAction (time: number, state: GameState): void; } diff --git a/src/model/resource/Job.ts b/src/model/resource/Job.ts index 081ffff..4b9db53 100644 --- a/src/model/resource/Job.ts +++ b/src/model/resource/Job.ts @@ -2,13 +2,12 @@ abstract class Job implements IResource { public readonly resourceType: ResourceType = ResourceType.Job; - public value: number = 0; public readonly valueInWholeNumbers: boolean = true; - - public clickText: string = 'Hire'; - public clickDescription: string = 'Promote one of your followers.'; - - public cost: { [key: string]: number } = { }; + public readonly clickText: string = 'Hire'; + public readonly clickDescription: string = + 'Promote one of your followers.'; + public value: number = 0; + public readonly cost: { [key: string]: number } = { }; protected _costMultiplier: { [key: string]: number } = { }; protected _isUnlocked: boolean = false; @@ -18,13 +17,21 @@ abstract class Job implements IResource { public readonly description: string ) { } + public max (state: GameState): number | null { + return null; + } + + public inc (state: GameState): number | null { + return null; + } + public clickAction (state: GameState): void { if (this._availableJobs(state) <= 0) { state.log('You have no unemployed followers to promote.'); return; } if (this.value < this.max(state) && state.deductCost(this.cost)) { - this.value++; + this.addValue(1, state); state.log(this._hireLog(1, state)); for (const rkey of Object.keys(this._costMultiplier)) { this.cost[rkey] *= this._costMultiplier[rkey]; @@ -32,22 +39,18 @@ abstract class Job implements IResource { } } - public inc (state: GameState): number | null { - return null; - } - - public max (state: GameState): number | null { - return null; - } - - public advanceAction (time: number, state: GameState): void { - return; + public addValue (amount: number, state: GameState): void { + this.value += amount; } public isUnlocked (state: GameState): boolean { return this._isUnlocked; } + public advanceAction (time: number, state: GameState): void { + return; + } + protected _availableJobs (state: GameState): number { // number of followers minus the number of filled jobs const followers: number = state.getResource('plorg').value; diff --git a/src/model/resource/Money.ts b/src/model/resource/Money.ts index 1ae8a54..e4abf33 100644 --- a/src/model/resource/Money.ts +++ b/src/model/resource/Money.ts @@ -1,11 +1,9 @@ /// class Money extends Purchasable { - private _lastCollectionTime: number = 0; + public readonly resourceType: ResourceType = ResourceType.Consumable; - public resourceType: ResourceType = ResourceType.Consumable; - public cost: { [key: string]: number } = { }; - public readonly valueInWholeNumbers: boolean = false; + private _lastCollectionTime: number = 0; constructor ( public value: number @@ -14,10 +12,14 @@ class Money extends Purchasable { this.clickText = 'Collect Tithes'; this.clickDescription = 'Voluntary contributions from followers.'; this._baseMax = 500000; + this.valueInWholeNumbers = false; + this._isUnlocked = true; } - public isUnlocked (state: GameState): boolean { - return true; + public max (state: GameState): number | null { + let max: number = this._baseMax; + max += state.getResource('cmpnd').value * 500000; + return max; } public inc (state: GameState): number { @@ -39,7 +41,7 @@ class Money extends Purchasable { const diff: number = state.now - this._lastCollectionTime; if (diff < state.config.cfgTimeBetweenTithes) { const lost: number = state.config.cfgTimeBetweenTithes / diff / 3; - state.getResource('creds').value -= lost; + state.getResource('creds').addValue(lost * -1, state); } // each follower gives you $10 const tithings: number = plorg.value * state.config.cfgTitheAmount; @@ -51,10 +53,4 @@ class Money extends Purchasable { const followers: number = state.getResource('plorg').value; return `You collected $${state.formatNumber(amount)} from ${state.formatNumber(followers)} followers.`; } - - public max (state: GameState): number | null { - let max: number = this._baseMax; - max += state.getResource('cmpnd').value * 500000; - return max; - } } diff --git a/src/model/resource/Passive.ts b/src/model/resource/Passive.ts index 63a91c3..36f5d01 100644 --- a/src/model/resource/Passive.ts +++ b/src/model/resource/Passive.ts @@ -2,32 +2,32 @@ abstract class Passive implements IResource { public readonly resourceType: ResourceType = ResourceType.Passive; + public readonly valueInWholeNumbers: boolean = false; public readonly clickText: null = null; public readonly clickDescription: null = null; + public value: number = 0; public readonly cost: null = null; + public readonly clickAction: null = null; - public readonly valueInWholeNumbers: boolean = false; protected _baseMax: number | null; protected _baseInc: number | null; constructor ( - public name: string, - public description: string, - public value: number, - max: number | null, - inc: number | null - ) { - this._baseMax = max; - this._baseInc = inc; + public readonly name: string, + public readonly description: string + ) { } + + public max (state: GameState): number | null { + return this._baseMax; } public inc (state: GameState): number | null { return this._baseInc; } - public max (state: GameState): number | null { - return this._baseMax; + public addValue (amount: number, state: GameState): void { + this.value += amount; } public isUnlocked (state: GameState): boolean { diff --git a/src/model/resource/Pastor.ts b/src/model/resource/Pastor.ts index 1b662cd..b75ad26 100644 --- a/src/model/resource/Pastor.ts +++ b/src/model/resource/Pastor.ts @@ -28,7 +28,7 @@ class Pastor extends Job { if (collected > money.max(state) - money.value) collected = money.max(state) - money.value; if (collected > 0) { - money.value += collected; + money.addValue(collected, state); state.log(`Your pastors collected $${state.formatNumber(collected)} in tithings from ${state.formatNumber(tithed)} followers.`); } this._timeSinceLastTithe = 0; diff --git a/src/model/resource/PlayerOrg.ts b/src/model/resource/PlayerOrg.ts index 9131471..5261a1c 100644 --- a/src/model/resource/PlayerOrg.ts +++ b/src/model/resource/PlayerOrg.ts @@ -4,22 +4,17 @@ class PlayerOrg implements IResource { public readonly resourceType: ResourceType = ResourceType.Religion; public readonly name: string = 'Player'; public readonly description: string = 'In you they trust.'; - - public cost: { [key: string]: number } = { }; - - public value: number = 0; public readonly valueInWholeNumbers: boolean = true; + public readonly clickText: string = 'Recruit'; + public readonly clickDescription: string = 'Gather new followers.'; + public value: number = 0; + public readonly cost: { [key: string]: number } = { }; - public clickText: string = 'Recruit'; - public clickDescription: string = 'Gather new followers.'; + public readonly inc: null = null; private _lastLostTime: number = 0; private _baseMax: number = 5; - public isUnlocked (state: GameState): boolean { - return true; - } - public max (state: GameState): number { let max: number = this._baseMax; max += state.getResource('tents').value * 2; @@ -53,14 +48,12 @@ class PlayerOrg implements IResource { } } - public inc (state: GameState): number { - let inc: number = 0; + public addValue (amount: number, state: GameState): void { + this.value += amount; + } - // pastor auto-recruit - inc += state.getResource('pstor').value - * state.config.cfgPastorRecruitRate; - - return inc; + public isUnlocked (state: GameState): boolean { + return true; } public advanceAction (time: number, state: GameState): void { @@ -71,9 +64,9 @@ class PlayerOrg implements IResource { const ratio: number = Math.ceil(creds.value) / creds.max(state); if (Math.random() > ratio) { const lost: number = Math.ceil(this.value / 25 * (1 - ratio)); - this.value -= lost; + this.addValue(lost * -1, state); const dest: [string, IResource] = this._getRandomReligion(state); - dest[1].value += lost; + dest[1].addValue(lost, state); state.log(`You lost ${lost} followers to ${dest[1].name}.`); } } diff --git a/src/model/resource/Purchasable.ts b/src/model/resource/Purchasable.ts index 0620059..d12f581 100644 --- a/src/model/resource/Purchasable.ts +++ b/src/model/resource/Purchasable.ts @@ -2,13 +2,11 @@ abstract class Purchasable implements IResource { public readonly resourceType: ResourceType = ResourceType.Consumable; - public value: number = 0; public valueInWholeNumbers: boolean = true; - public clickText: string = 'Purchase'; public clickDescription: string = 'Purchase'; - - public cost: { [key: string]: number } = { }; + public value: number = 0; + public readonly cost: { [key: string]: number } = { }; protected _costMultiplier: { [key: string]: number } = { }; protected _baseMax: number | null = null; @@ -19,6 +17,14 @@ abstract class Purchasable implements IResource { public readonly description: string ) { } + public max (state: GameState): number | null { + return this._baseMax; + } + + public inc (state: GameState): number | null { + return null; + } + public clickAction (state: GameState): void { if (this.max(state) !== null && this.value >= this.max(state)) return; if (state.deductCost(this.cost)) { @@ -33,16 +39,8 @@ abstract class Purchasable implements IResource { } } - public inc (state: GameState): number | null { - return null; - } - - public max (state: GameState): number | null { - return this._baseMax; - } - - public advanceAction (time: number, state: GameState): void { - return; + public addValue (amount: number, state: GameState): void { + this.value += amount; } public isUnlocked (state: GameState): boolean { @@ -52,6 +50,10 @@ abstract class Purchasable implements IResource { return this._isUnlocked; } + public advanceAction (time: number, state: GameState): void { + return; + } + protected _purchaseAmount (state: GameState): number { return 1; } diff --git a/src/model/resource/Religion.ts b/src/model/resource/Religion.ts index 4fa83cd..b958177 100644 --- a/src/model/resource/Religion.ts +++ b/src/model/resource/Religion.ts @@ -2,14 +2,15 @@ class Religion implements IResource { public readonly resourceType: ResourceType = ResourceType.Religion; + public readonly valueInWholeNumbers: boolean = true; public readonly clickText: null = null; public readonly clickDescription: null = null; - public readonly clickAction: null = null; - public readonly advanceAction: null = null; public readonly cost: null = null; + public readonly max: null = null; public readonly inc: null = null; - public readonly valueInWholeNumbers: boolean = true; + public readonly clickAction: null = null; + public readonly advanceAction: null = null; constructor ( public readonly name: string, @@ -17,6 +18,10 @@ class Religion implements IResource { public value: number, ) { } + public addValue (amount: number, state: GameState): void { + this.value += amount; + } + public isUnlocked (state: GameState): boolean { return true; }