diff --git a/public/css/debugger.css b/public/css/debugger.css
index cf30440..6997729 100644
--- a/public/css/debugger.css
+++ b/public/css/debugger.css
@@ -39,6 +39,9 @@ body, html {
padding: 0.25em 0.5em;
margin: 0 0.5em 0.5em 0;
}
+.resource.locked {
+ display: none;
+}
#resource-container-religion .resource {
background-color: #ccf;
}
diff --git a/src/model/resource/Pastor.ts b/src/model/resource/Pastor.ts
index b75ad26..d009240 100644
--- a/src/model/resource/Pastor.ts
+++ b/src/model/resource/Pastor.ts
@@ -4,7 +4,8 @@ class Pastor extends Job {
private _timeSinceLastTithe: number = 0;
constructor () {
- super('Pastors', 'Leaders of the faith.');
+ super('Pastors',
+ 'Collect tithings for you and recruit new members from other faiths automatically.');
}
public max (state: GameState): number {
diff --git a/src/model/resource/PlayerOrg.ts b/src/model/resource/PlayerOrg.ts
index 5261a1c..10b9971 100644
--- a/src/model/resource/PlayerOrg.ts
+++ b/src/model/resource/PlayerOrg.ts
@@ -8,12 +8,13 @@ class PlayerOrg implements IResource {
public readonly clickText: string = 'Recruit';
public readonly clickDescription: string = 'Gather new followers.';
public value: number = 0;
- public readonly cost: { [key: string]: number } = { };
+ public readonly cost: null = null;
- public readonly inc: null = null;
-
- private _lastLostTime: number = 0;
+ private _timeSinceLastLost: number = 0;
private _baseMax: number = 5;
+ private _lastRecruitmentLog: number = 0;
+ private _followerSources: { [key: string]: number } = { };
+ private _followerDests: { [key: string]: number } = { };
public max (state: GameState): number {
let max: number = this._baseMax;
@@ -22,6 +23,20 @@ class PlayerOrg implements IResource {
return max;
}
+ public inc (state: GameState): number {
+ let inc: number = 0;
+
+ // pastor recruiting
+ const pastors: number = state.getResource('pstor').value;
+ inc += pastors * state.config.cfgPastorRecruitRate;
+
+ // credibility adjustment
+ const creds: IResource = state.getResource('creds');
+ inc *= creds.value / creds.max(state);
+
+ return inc;
+ }
+
public clickAction (state: GameState): void {
// don't exceed max
if (this.value >= this.max(state)) {
@@ -33,23 +48,39 @@ class PlayerOrg implements IResource {
const creds: IResource = state.getResource('creds');
const ratio: number = Math.ceil(creds.value) / creds.max(state);
if (Math.random() > ratio) {
- state.log('Your recruiting efforts failed.');
+ state.log('Your recruitment efforts failed.');
return;
}
- 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.');
- }
+ this.addValue(1, state);
}
public addValue (amount: number, state: GameState): void {
+ const oldValue: number = this.value;
this.value += amount;
+ const diff: number = Math.floor(this.value) - Math.floor(oldValue);
+
+ if (diff > 0) {
+ // gained followers must come from other faiths
+ for (let i: number = 0; i < diff; i++) {
+ const source: [string, IResource] = this._getRandomReligion(state);
+ source[1].addValue(-1, state);
+ const curFollowers: number = this._followerSources[source[0]];
+ this._followerSources[source[0]] = curFollowers
+ ? curFollowers + 1
+ : 1;
+ }
+ } else {
+ // lost followers must return to other faiths
+ for (let i: number = 0; i < diff * -1; i++) {
+ const dest: [string, IResource] = this._getRandomReligion(state);
+ dest[1].addValue(1, state);
+ const curFollowers: number = this._followerDests[dest[0]];
+ this._followerDests[dest[0]] = curFollowers
+ ? curFollowers + 1
+ : 1;
+ }
+ }
}
public isUnlocked (state: GameState): boolean {
@@ -58,19 +89,48 @@ class PlayerOrg implements IResource {
public advanceAction (time: number, state: GameState): void {
// chance to lose some followers every 10s if credibility < 100%
- if (state.now - this._lastLostTime > 10000) {
+ this._timeSinceLastLost += time;
+ if (this._timeSinceLastLost > 10000) {
if (this.value > 0) {
const creds: IResource = state.getResource('creds');
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.addValue(lost * -1, state);
- const dest: [string, IResource] = this._getRandomReligion(state);
- dest[1].addValue(lost, state);
- state.log(`You lost ${lost} followers to ${dest[1].name}.`);
}
}
- this._lastLostTime = state.now;
+ this._timeSinceLastLost = 0;
+ }
+
+ // log lost and gained followers every 10s
+ if (state.now - this._lastRecruitmentLog > 10000
+ && (Object.keys(this._followerSources).length > 0
+ || Object.keys(this._followerDests).length > 0)) {
+ if (Object.keys(this._followerDests).length > 0) {
+ let msg: string;
+ for (const rkey of Object.keys(this._followerDests)) {
+ if (msg === undefined) msg = 'You lost ';
+ else msg += ' and ';
+ const religion: IResource = state.getResource(rkey);
+ msg +=
+ `${state.formatNumber(this._followerDests[rkey])} followers to ${religion.name}`;
+ delete this._followerDests[rkey];
+ }
+ state.log(msg);
+ }
+ if (Object.keys(this._followerSources).length > 0) {
+ let msg: string;
+ for (const rkey of Object.keys(this._followerSources)) {
+ if (msg === undefined) msg = 'You gained ';
+ else msg += ' and ';
+ const religion: IResource = state.getResource(rkey);
+ msg +=
+ `${state.formatNumber(this._followerSources[rkey])} followers from ${religion.name}`;
+ delete this._followerSources[rkey];
+ }
+ state.log(msg);
+ }
+ this._lastRecruitmentLog = state.now;
}
}
diff --git a/src/render/DebugRenderer.ts b/src/render/DebugRenderer.ts
index 1649e41..f213202 100644
--- a/src/render/DebugRenderer.ts
+++ b/src/render/DebugRenderer.ts
@@ -5,6 +5,7 @@ class DebugRenderer implements IRenderer {
private _handleClick: boolean = true;
public render (state: GameState): void {
+ const rkeys: string[] = state.getResources();
if (!this._initialized) {
const container: HTMLElement =
document.getElementById('irreligious-game');
@@ -36,48 +37,53 @@ class DebugRenderer implements IRenderer {
resDiv.appendChild(el);
}
}
+ // create containers for each resource
+ for (const rkey of rkeys) {
+ const resource: IResource = state.getResource(rkey);
+ const resContainer: HTMLElement =
+ document.getElementById(
+ `resource-container-${resource.resourceType}`);
+ const el: HTMLElement = document.createElement('div');
+ el.className = 'resource locked';
+ el.id = `resource-details-${rkey}`;
+ let content: string = `
+
+ ${this._escape(resource.name
+ ? resource.name
+ : rkey)}
+
+
+
+ `;
+ if (resource.clickText !== null) {
+ content += `
+ `;
+ }
+ if (resource.cost !== null
+ && Object.keys(resource.cost).length !== 0) {
+ content += "
Cost: ";
+ }
+ el.innerHTML = content;
+ resContainer.appendChild(el);
+ if (resource.clickAction !== null) {
+ const btn: Element =
+ el.getElementsByClassName('resource-btn')[0];
+ btn.addEventListener('click', (): void =>
+ state.performClick(rkey));
+ }
+ }
}
- const rkeys: string[] = state.getResources();
for (const rkey of rkeys) {
const resource: IResource = state.getResource(rkey);
const container: HTMLElement = document
.getElementById(`resource-container-${resource.resourceType}`);
if (resource.isUnlocked(state)) {
- let el: HTMLElement = document
+ const el: HTMLElement = document
.getElementById(`resource-details-${rkey}`);
- if (el === null) {
- el = document.createElement('div');
- el.className = 'resource';
- el.id = `resource-details-${rkey}`;
- let content: string = `
-
- ${this._escape(resource.name
- ? resource.name
- : rkey)}
-
-
-
- `;
- if (resource.clickText !== null) {
- content += `
- `;
- }
- if (resource.cost !== null
- && Object.keys(resource.cost).length !== 0) {
- content += "
Cost: ";
- }
- el.innerHTML = content;
- container.appendChild(el);
- if (resource.clickAction !== null) {
- const btn: Element =
- el.getElementsByClassName('resource-btn')[0];
- btn.addEventListener('click', (): void =>
- state.performClick(rkey));
- }
- }
+ if (el.className !== 'resource') el.className = 'resource';
const elV: Element =
el.getElementsByClassName('resource-value')[0];
const elT: Element =