From 70fa078579a0d93b25c728d4b246fefc338a28f0 Mon Sep 17 00:00:00 2001 From: Rudis Muiznieks Date: Sat, 21 Aug 2021 17:06:51 -0500 Subject: [PATCH] implemented credibility and tithes --- src/model/GameConfig.ts | 10 +++-- src/model/GameState.ts | 22 ++++++----- src/model/resource/Credibility.ts | 23 +++++++++++ src/model/resource/Hidden.ts | 5 ++- src/model/resource/Money.ts | 10 +++++ src/model/resource/PlayerOrg.ts | 63 +++++++++++++++++++++++++++++++ src/model/resource/Religion.ts | 3 +- src/render/DebugRenderer.ts | 5 ++- tslint.json | 6 +++ 9 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 src/model/resource/PlayerOrg.ts diff --git a/src/model/GameConfig.ts b/src/model/GameConfig.ts index 7f684d3..f5d74a6 100644 --- a/src/model/GameConfig.ts +++ b/src/model/GameConfig.ts @@ -1,5 +1,7 @@ /// +/// /// +/// /// class GameConfig { @@ -19,8 +21,7 @@ class GameConfig { const state: GameState = new GameState(); // create player organization - state.addResource('plorg', new Religion( - 'Player', 'In you they trust.', 0)); + state.addResource('plorg', new PlayerOrg()); // create world religions state.addResource('xtian', new Religion( @@ -55,7 +56,10 @@ class GameConfig { 'Non-Religious', 'Atheists and agnostics.', this.relNoneShare * this.worldPopulation)); - // add purchasable resources + // add hidden resources + state.addResource('creds', new Credibility(2)); + + // add resources state.addResource('money', new Money(100)); return state; diff --git a/src/model/GameState.ts b/src/model/GameState.ts index 564e0d7..bdeea2c 100644 --- a/src/model/GameState.ts +++ b/src/model/GameState.ts @@ -9,12 +9,16 @@ class GameState { public logger: ILogger = null; public numberFormatDigits: number = 1; + public now: number = 0; + public addResource (key: string, resource: IResource): void { this._resourceKeys.push(key); this._resources[key] = resource; } public advance (time: number): void { + this.now = (new Date()).getTime(); + // advance each resource for (const rkey of this._resourceKeys) { if (this._resources[rkey].advanceAction !== null) { @@ -79,13 +83,13 @@ class GameState { public formatNumber (num: number): string { type vlookup = { value: number, symbol: string }; const lookup: vlookup[] = [ - { 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" } + { 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: RegExp = /\.0+$|(\.[0-9]*[1-9])0+$/; const item: vlookup = @@ -93,8 +97,8 @@ class GameState { .find((i: vlookup): boolean => num >= i.value); return item ? (num / item.value).toFixed(this.numberFormatDigits) - .replace(rx, "$1") + item.symbol - : num.toFixed(this.numberFormatDigits).replace(rx, "$1"); + .replace(rx, '$1') + item.symbol + : num.toFixed(this.numberFormatDigits).replace(rx, '$1'); } public log (text: string): void { diff --git a/src/model/resource/Credibility.ts b/src/model/resource/Credibility.ts index 119c147..1ebb3b4 100644 --- a/src/model/resource/Credibility.ts +++ b/src/model/resource/Credibility.ts @@ -1,4 +1,27 @@ /// class Credibility extends Hidden { + private _lastValue: number; + + constructor (public value: number) { + super(value); + this._lastValue = value; + } + + public max (state: GameState): number { + return 2; + } + + public inc (state: GameState): number { + return 0.01; + } + + public advanceAction (time: number, state: GameState): void { + if (Math.ceil(this._lastValue) < Math.ceil(this.value)) { + state.log('Your credibility has gone up.'); + } else if (Math.ceil(this._lastValue) > Math.ceil(this.value)) { + state.log('Your credibility has gone down.'); + } + this._lastValue = this.value; + } } diff --git a/src/model/resource/Hidden.ts b/src/model/resource/Hidden.ts index 83a3ffa..21da49d 100644 --- a/src/model/resource/Hidden.ts +++ b/src/model/resource/Hidden.ts @@ -4,7 +4,6 @@ abstract class Hidden implements IResource { public readonly resourceType: ResourceType = ResourceType.Hidden; public readonly clickText: null = null; public readonly clickDescription: null = null; - public readonly advanceAction: null = null; public readonly cost: null = null; public readonly clickAction: null = null; public readonly name: null = null; @@ -27,4 +26,8 @@ abstract class Hidden implements IResource { public isUnlocked (state: GameState): boolean { return true; } + + public advanceAction (time: number, state: GameState): void { + return; + } } diff --git a/src/model/resource/Money.ts b/src/model/resource/Money.ts index eb2121f..11160f5 100644 --- a/src/model/resource/Money.ts +++ b/src/model/resource/Money.ts @@ -1,6 +1,10 @@ /// class Money extends Purchasable { + private _lastCollectionTime: number = 0; + + public cost: { [key: string]: number } = { }; + constructor ( public value: number, ) { @@ -19,9 +23,15 @@ class Money extends Purchasable { state.log('You have no followers to collect from!'); return 0; } + if (state.now - this._lastCollectionTime < 30000) { + this.cost.creds = 0.05; + state.deductCost(this.cost); + delete this.cost.creds; + } // each follower gives you $10 const tithings: number = plorg.value * 10; state.log(`You collected $${state.formatNumber(tithings)} from ${state.formatNumber(plorg.value)} followers.`); + this._lastCollectionTime = state.now; return tithings; } } diff --git a/src/model/resource/PlayerOrg.ts b/src/model/resource/PlayerOrg.ts new file mode 100644 index 0000000..9f41471 --- /dev/null +++ b/src/model/resource/PlayerOrg.ts @@ -0,0 +1,63 @@ +/// + +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 readonly max: null = null; + public readonly inc: null = null; + + public value: number = 0; + + public clickText: string = 'Recruit'; + public clickDescription: string = 'Gather new followers.'; + + private _lastLostTime: number = 0; + + public isUnlocked (state: GameState): boolean { + return true; + } + + public clickAction (state: GameState): void { + const creds: number = + Math.pow(Math.ceil(state.getResource('creds').value), 2); + if (this.value >= creds) { + state.log('Your recruiting efforts failed.'); + } else { + const source: [string, IResource] = this._getRandomReligion(state); + this.cost[source[0]] = 1; + if (state.deductCost(this.cost)) { + this.value++; + delete this.cost[source[0]]; + state.log(`You converted one new follower from ${source[1].name}!`); + } else { + state.log('Your recruiting efforts failed.'); + } + } + } + + public advanceAction (time: number, state: GameState): void { + const creds: number = + Math.pow(Math.ceil(state.getResource('creds').value), 2); + if (this.value > creds) { + if (state.now - this._lastLostTime > 10000) { + const lost: number = + Math.ceil((this.value - creds) / 10 * Math.random()); + this.value -= lost; + const dest: [string, IResource] = this._getRandomReligion(state); + dest[1].value += lost; + state.log(`You lost ${lost} followers to ${dest[1].name}.`); + this._lastLostTime = state.now; + } + } + } + + private _getRandomReligion (state: GameState): [string, IResource] { + const religs: string[] = ['xtian', 'islam', 'hindu', + 'buddh', 'sikhi', 'judah', 'other', 'agnos']; + const source: string = religs[Math.floor(Math.random() * 8)]; + return [source, state.getResource(source)]; + } +} diff --git a/src/model/resource/Religion.ts b/src/model/resource/Religion.ts index adc1cfe..b645147 100644 --- a/src/model/resource/Religion.ts +++ b/src/model/resource/Religion.ts @@ -4,12 +4,11 @@ class Religion implements IResource { public readonly resourceType: ResourceType = ResourceType.Religion; 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 clickAction: null = null; constructor ( public readonly name: string, diff --git a/src/render/DebugRenderer.ts b/src/render/DebugRenderer.ts index 4656c11..6f94eef 100644 --- a/src/render/DebugRenderer.ts +++ b/src/render/DebugRenderer.ts @@ -34,6 +34,7 @@ class DebugRenderer implements IRenderer { const rkeys: string[] = state.getResources(); for (const rkey of rkeys) { const resource: IResource = state.getResource(rkey); + if (resource.resourceType === ResourceType.Hidden) continue; const container: HTMLElement = document .getElementById(`resource-container-${resource.resourceType}`); if (resource.isUnlocked(state)) { @@ -57,8 +58,8 @@ class DebugRenderer implements IRenderer { ${resource.clickText}`; } if (resource.cost !== null - && Object.keys(resource.cost) !== null) { - content += `
Cost: `; + && Object.keys(resource.cost).length !== 0) { + content += "
Cost: "; } el.innerHTML = content; container.appendChild(el); diff --git a/tslint.json b/tslint.json index 78166b7..0699b91 100644 --- a/tslint.json +++ b/tslint.json @@ -4,6 +4,12 @@ "no-reference": false, "space-before-function-paren": true, "triple-equals": true, + "quotemark": [ + true, + "single", + "avoid-escape", + "avoid-template" + ], "max-line-length": [ true, { "limit": 75,