implemented credibility and tithes

This commit is contained in:
Rudis Muiznieks 2021-08-21 17:06:51 -05:00
parent fb72e52786
commit 70fa078579
9 changed files with 130 additions and 17 deletions

View File

@ -1,5 +1,7 @@
/// <reference path="./GameState.ts" />
/// <reference path="./resource/Credibility.ts" />
/// <reference path="./resource/Money.ts" />
/// <reference path="./resource/PlayerOrg.ts" />
/// <reference path="./resource/Religion.ts" />
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;

View File

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

View File

@ -1,4 +1,27 @@
/// <reference path="./Hidden.ts" />
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;
}
}

View File

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

View File

@ -1,6 +1,10 @@
/// <reference path="./Purchasable.ts" />
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;
}
}

View File

@ -0,0 +1,63 @@
/// <reference path="./Religion.ts" />
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)];
}
}

View File

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

View File

@ -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}</button>`;
}
if (resource.cost !== null
&& Object.keys(resource.cost) !== null) {
content += `<br>Cost: <span class='resource-cost'></span>`;
&& Object.keys(resource.cost).length !== 0) {
content += "<br>Cost: <span class='resource-cost'></span>";
}
el.innerHTML = content;
container.appendChild(el);

View File

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