diff --git a/public/css/debugger.css b/public/css/debugger.css
index 7cc7c98..af26d36 100644
--- a/public/css/debugger.css
+++ b/public/css/debugger.css
@@ -1,9 +1,10 @@
.resource-type-container {
display: flex;
+ flex-wrap: wrap;
}
.resource {
+ min-width: 8em;
border: 2px solid black;
- padding: 5px 10px;
- margin: 0 5px 5px 0;
- flex-shrink: 0;
+ padding: 0.25em 0.5em;
+ margin: 0 0.5em 0.5em 0;
}
diff --git a/src/model/GameConfig.ts b/src/model/GameConfig.ts
index 903b7fe..7f684d3 100644
--- a/src/model/GameConfig.ts
+++ b/src/model/GameConfig.ts
@@ -1,7 +1,6 @@
///
///
///
-///
class GameConfig {
public worldPopulation: number = 790000000;
@@ -57,8 +56,7 @@ class GameConfig {
this.relNoneShare * this.worldPopulation));
// add purchasable resources
- state.addResource('money', new Money(0));
- state.addResource('bonds', new Savings(0));
+ state.addResource('money', new Money(100));
return state;
}
diff --git a/src/model/GameState.ts b/src/model/GameState.ts
index 0169c34..564e0d7 100644
--- a/src/model/GameState.ts
+++ b/src/model/GameState.ts
@@ -1,3 +1,4 @@
+///
///
class GameState {
@@ -5,6 +6,8 @@ class GameState {
private _resourceKeys: string[] = [];
public onResourceClick: (() => void)[] = [];
+ public logger: ILogger = null;
+ public numberFormatDigits: number = 1;
public addResource (key: string, resource: IResource): void {
this._resourceKeys.push(key);
@@ -12,15 +15,24 @@ class GameState {
}
public advance (time: number): void {
+ // advance each resource
for (const rkey of this._resourceKeys) {
if (this._resources[rkey].advanceAction !== null) {
this._resources[rkey].advanceAction(time, this);
}
- const max: number | null = this._resources[rkey].max(this);
- if (this._resources[rkey].inc(this) > 0
- && (max === null || this._resources[rkey].value < max)) {
- this._resources[rkey].value +=
- this._resources[rkey].inc(this) * time / 1000;
+ }
+
+ // perform auto increments
+ for (const rkey of this._resourceKeys) {
+ const max: number = this._resources[rkey].max
+ ? this._resources[rkey].max(this)
+ : null;
+ const inc: number = this._resources[rkey].inc
+ ? this._resources[rkey].inc(this)
+ : 0;
+ if (inc > 0 && (max === null
+ || this._resources[rkey].value < max)) {
+ this._resources[rkey].value += inc * time / 1000;
}
if (max !== null && this._resources[rkey].value > max) {
this._resources[rkey].value = max;
@@ -63,4 +75,31 @@ class GameState {
}
return true;
}
+
+ 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" }
+ ];
+ const rx: RegExp = /\.0+$|(\.[0-9]*[1-9])0+$/;
+ const item: vlookup =
+ lookup.slice().reverse()
+ .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");
+ }
+
+ public log (text: string): void {
+ if (this.logger !== null) {
+ this.logger.msg(text);
+ }
+ }
}
diff --git a/src/model/logging/ConsoleLogger.ts b/src/model/logging/ConsoleLogger.ts
new file mode 100644
index 0000000..8fa5b65
--- /dev/null
+++ b/src/model/logging/ConsoleLogger.ts
@@ -0,0 +1,7 @@
+///
+
+class ConsoleLogger implements ILogger {
+ public msg (text: string): void {
+ console.log(text); // tslint:disable-line
+ }
+}
diff --git a/src/model/logging/ILogger.ts b/src/model/logging/ILogger.ts
new file mode 100644
index 0000000..2ea8fd6
--- /dev/null
+++ b/src/model/logging/ILogger.ts
@@ -0,0 +1,3 @@
+interface ILogger {
+ msg (text: string): void;
+}
diff --git a/src/model/resource/Credibility.ts b/src/model/resource/Credibility.ts
new file mode 100644
index 0000000..119c147
--- /dev/null
+++ b/src/model/resource/Credibility.ts
@@ -0,0 +1,4 @@
+///
+
+class Credibility extends Hidden {
+}
diff --git a/src/model/resource/Hidden.ts b/src/model/resource/Hidden.ts
new file mode 100644
index 0000000..83a3ffa
--- /dev/null
+++ b/src/model/resource/Hidden.ts
@@ -0,0 +1,30 @@
+///
+
+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;
+ public readonly description: null = null;
+
+ protected _baseMax: number | null = null;
+
+ constructor (
+ public value: number
+ ) { }
+
+ public inc (state: GameState): number | null {
+ return null;
+ }
+
+ public max (state: GameState): number | null {
+ return this._baseMax;
+ }
+
+ public isUnlocked (state: GameState): boolean {
+ return true;
+ }
+}
diff --git a/src/model/resource/IResource.ts b/src/model/resource/IResource.ts
index 9e9bb54..46ef5db 100644
--- a/src/model/resource/IResource.ts
+++ b/src/model/resource/IResource.ts
@@ -1,24 +1,28 @@
enum ResourceType {
Religion = 'religion',
Consumable = 'consumable',
- Infrastructure = 'infrastructure'
+ Infrastructure = 'infrastructure',
+ Hidden = 'hidden'
}
interface IResource {
- name: string;
- description: string;
+ name: string | null;
+ description: string | null;
resourceType: ResourceType;
value: number;
- max: (state: GameState) => number | null;
- inc: (state: GameState) => number | null;
- cost: { [key: string]: number };
-
- isUnlocked: (state: GameState) => boolean;
clickText: string;
clickDescription: string;
- clickAction: (state: GameState) => void;
- advanceAction: (time: number, state: GameState) => void;
+ clickAction (state: GameState): void;
+
+ cost: { [key: string]: number };
+
+ max (state: GameState): number | null;
+ inc (state: GameState): number | null;
+
+ isUnlocked (state: GameState): boolean;
+
+ advanceAction (time: number, state: GameState): void;
}
diff --git a/src/model/resource/Money.ts b/src/model/resource/Money.ts
index 6972d10..eb2121f 100644
--- a/src/model/resource/Money.ts
+++ b/src/model/resource/Money.ts
@@ -5,19 +5,23 @@ class Money extends Purchasable {
public value: number,
) {
super('Money', 'Used to purchase goods and services.');
- this.clickText = 'Beg';
- this.clickDescription = 'Alms for the poor.';
- this._baseMax = 1000;
+ this.clickText = 'Collect Tithes';
+ this.clickDescription = 'Voluntary contributions from followers.';
}
public isUnlocked (state: GameState): boolean {
return true;
}
- public inc (state: GameState): number {
- let baseInc: number = 0;
- // bonds give $1/s
- baseInc += state.getResource('bonds').value;
- return baseInc;
+ protected _incrementAmount (state: GameState): number {
+ const plorg: IResource = state.getResource('plorg');
+ if (plorg.value === 0) {
+ state.log('You have no followers to collect from!');
+ return 0;
+ }
+ // each follower gives you $10
+ const tithings: number = plorg.value * 10;
+ state.log(`You collected $${state.formatNumber(tithings)} from ${state.formatNumber(plorg.value)} followers.`);
+ return tithings;
}
}
diff --git a/src/model/resource/Purchasable.ts b/src/model/resource/Purchasable.ts
index c2f7bc6..2cc9b06 100644
--- a/src/model/resource/Purchasable.ts
+++ b/src/model/resource/Purchasable.ts
@@ -7,9 +7,9 @@ abstract class Purchasable implements IResource {
public clickText: string = 'Purchase';
public clickDescription: string = 'Purchase';
- public cost: { [key: string]: number } = null;
+ public cost: { [key: string]: number } | null = null;
- protected _costMultiplier: { [key: string]: number } = null;
+ protected _costMultiplier: { [key: string]: number } | null = null;
protected _baseMax: number | null = null;
constructor (
@@ -20,7 +20,7 @@ abstract class Purchasable implements IResource {
public clickAction (state: GameState): void {
if (this.max(state) !== null && this.value >= this.max(state)) return;
if (state.deductCost(this.cost)) {
- this.value += 1;
+ this.value += this._incrementAmount(state);
if (this._costMultiplier !== null
&& Object.keys(this._costMultiplier !== null)) {
for (const rkey of Object.keys(this._costMultiplier)) {
@@ -45,4 +45,8 @@ abstract class Purchasable implements IResource {
public isUnlocked (state: GameState): boolean {
return false;
}
+
+ protected _incrementAmount (state: GameState): number {
+ return 1;
+ }
}
diff --git a/src/model/resource/Religion.ts b/src/model/resource/Religion.ts
index 1f97936..adc1cfe 100644
--- a/src/model/resource/Religion.ts
+++ b/src/model/resource/Religion.ts
@@ -2,14 +2,14 @@
class Religion implements IResource {
public readonly resourceType: ResourceType = ResourceType.Religion;
- public readonly clickText: string = null;
- public readonly clickDescription: string = null;
- public readonly advanceAction: (time: number) => void = null;
- public readonly cost: { [key: string]: number } = null;
+ public readonly clickText: null = null;
+ public readonly clickDescription: null = null;
+ public readonly advanceAction: null = null;
+ public readonly cost: null = null;
- public readonly max: () => null = (): null => null;
- public readonly inc: () => null = (): null => null;
- public readonly clickAction: () => void = 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/model/resource/Savings.ts b/src/model/resource/Savings.ts
deleted file mode 100644
index a4f9ee3..0000000
--- a/src/model/resource/Savings.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-///
-
-class Savings extends Purchasable {
- private _isUnlocked: boolean = false;
-
- constructor (
- public value: number,
- ) {
- super('Savings', "Can't be spent, but grows money over time.");
- this.cost = { 'money': 10 };
- this._costMultiplier = { 'money': 1.1 };
- }
-
- public isUnlocked (state: GameState): boolean {
- if (this._isUnlocked) return true;
- if (state.getResource('money').value >= this.cost.money) {
- this._isUnlocked = true;
- return true;
- }
- return false;
- }
-
- protected purchaseEffect (state: GameState): void {
- return;
- }
-}
diff --git a/src/render/DebugRenderer.ts b/src/render/DebugRenderer.ts
index 767ff35..96abbf8 100644
--- a/src/render/DebugRenderer.ts
+++ b/src/render/DebugRenderer.ts
@@ -1,4 +1,5 @@
///
+///
///
class DebugRenderer implements IRenderer {
@@ -7,6 +8,7 @@ class DebugRenderer implements IRenderer {
public render (state: GameState): void {
if (!this._initialized) {
+ state.logger = new ConsoleLogger();
const container: HTMLElement =
document.getElementById('irreligious-game');
this._initialized = true;
@@ -70,16 +72,17 @@ class DebugRenderer implements IRenderer {
el.getElementsByClassName('resource-value')[0];
const elT: Element =
el.getElementsByClassName('resource-max')[0];
- elV.innerHTML = this.formatNumber(resource.value, 1);
- elT.innerHTML = resource.max(state) !== null
- ? ` / ${this.formatNumber(resource.max(state), 1)}`
+ elV.innerHTML = state.formatNumber(resource.value);
+ elT.innerHTML = resource.max !== null
+ && resource.max(state) !== null
+ ? ` / ${state.formatNumber(resource.max(state))}`
: '';
if (this._handleClick) {
- if (resource.inc(state) > 0) {
+ if (resource.inc !== null && resource.inc(state) > 0) {
const elI: Element =
el.getElementsByClassName('resource-inc')[0];
elI.innerHTML =
- ` +${this.formatNumber(resource.inc(state), 1)}/s`;
+ ` +${state.formatNumber(resource.inc(state))}/s`;
}
const elC: HTMLCollectionOf =
el.getElementsByClassName('resource-cost');
@@ -98,33 +101,13 @@ class DebugRenderer implements IRenderer {
if (resource.cost[rkey] !== undefined) {
if (cost !== '') cost += ', ';
if (rkey === 'money') {
- cost += `$${this.formatNumber(resource.cost[rkey], 1)}`;
+ cost += `$${state.formatNumber(resource.cost[rkey])}`;
} else {
- cost += `${this.formatNumber(resource.cost[rkey], 1)}
+ cost += `${state.formatNumber(resource.cost[rkey])}
${state.getResource(rkey).name}`;
}
}
}
return cost;
}
-
- private formatNumber (num: number, digits: 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" }
- ];
- const rx: RegExp = /\.0+$|(\.[0-9]*[1-9])0+$/;
- const item: vlookup =
- lookup.slice().reverse()
- .find((i: vlookup): boolean => num >= i.value);
- return item
- ? (num / item.value).toFixed(digits).replace(rx, "$1") + item.symbol
- : num.toFixed(digits).replace(rx, "$1");
- }
}
diff --git a/tslint.json b/tslint.json
index fe04b0d..78166b7 100644
--- a/tslint.json
+++ b/tslint.json
@@ -7,7 +7,8 @@
"max-line-length": [
true, {
"limit": 75,
- "check-strings": true
+ "check-strings": true,
+ "ignore-pattern": "\\s+state\\.log\\("
}
],
"whitespace": [