improved resource access off game state

This commit is contained in:
Rudis Muiznieks 2021-09-05 18:39:08 -05:00
parent 3f57d6ce91
commit 30877e0bc0
14 changed files with 73 additions and 76 deletions

View File

@ -33,15 +33,17 @@ class GameConfig {
public cfgCredibilityFollowerLossTime = 10000; public cfgCredibilityFollowerLossTime = 10000;
public cfgCredibilityRestoreRate = 0.25; public cfgCredibilityRestoreRate = 0.25;
public cfgPastorRecruitRate = 0.01;
public cfgPastorTitheCollectionFollowerMax = 100;
public cfgPastorSalary = 7.5;
public cfgFollowerGainLossLogTimer = 10000; public cfgFollowerGainLossLogTimer = 10000;
public cfgFollowerStartingMax = 5; public cfgFollowerStartingMax = 5;
public cfgPastorRecruitRate = 0.01;
public cfgTimeBetweenTithes = 30000; public cfgTimeBetweenTithes = 30000;
public cfgTitheAmount = 10; public cfgTitheAmount = 10;
public cfgCryptoReturnAmount = 1; public cfgCryptoReturnAmount = 1;
public cfgMoneyStartingMax = 500000; public cfgMoneyStartingMax = 500000;
public cfgPastorTitheCollectionFollowerMax = 100;
public cfgBuildingPermitCost = 250000; public cfgBuildingPermitCost = 250000;
@ -113,7 +115,7 @@ class GameConfig {
// add resources // add resources
state.addResource(ResourceKey.money, new Money(3.50)); state.addResource(ResourceKey.money, new Money(3.50));
state.addResource(ResourceKey.faithCoin, new CryptoCurrency(this)); state.addResource(ResourceKey.cryptoCurrency, new CryptoCurrency(this));
state.addResource(ResourceKey.tents, new Tent(this)); state.addResource(ResourceKey.tents, new Tent(this));
state.addResource(ResourceKey.houses, new House(this)); state.addResource(ResourceKey.houses, new House(this));
state.addResource(ResourceKey.churches, new Church(this)); state.addResource(ResourceKey.churches, new Church(this));

View File

@ -15,11 +15,18 @@ class GameState {
private _resources: { [key in ResourceKey]?: IResource } = { }; private _resources: { [key in ResourceKey]?: IResource } = { };
private readonly _resourceKeys: ResourceKey[] = []; private readonly _resourceKeys: ResourceKey[] = [];
constructor (config: GameConfig) { constructor (config: GameConfig) {
this.config = config; this.config = config;
} }
public get resource (): { [key in ResourceKey]?: IResource } {
return this._resources;
}
public get resources (): ResourceKey[] {
return this._resourceKeys;
}
public addResource (key: ResourceKey, resource: IResource): void { public addResource (key: ResourceKey, resource: IResource): void {
this._resourceKeys.push(key); this._resourceKeys.push(key);
this._resources[key] = resource; this._resources[key] = resource;
@ -62,15 +69,6 @@ class GameState {
} }
} }
public getResources (): ResourceKey[] {
return this._resourceKeys;
}
public getResource (key: ResourceKey): IResource | null {
const resource = this._resources[key];
return resource !== undefined ? resource : null;
}
public performClick (resourceKey: ResourceKey): void { public performClick (resourceKey: ResourceKey): void {
const resource = this._resources[resourceKey]; const resource = this._resources[resourceKey];
if (resource === undefined || !resource.isUnlocked(this)) return; if (resource === undefined || !resource.isUnlocked(this)) return;

View File

@ -9,8 +9,8 @@ class BuildingPermit extends Research {
public isUnlocked (state: GameState): boolean { public isUnlocked (state: GameState): boolean {
if (this._isUnlocked) return true; if (this._isUnlocked) return true;
const compounds = state.getResource(ResourceKey.compounds); const compounds = state.resource.compounds;
if (compounds !== null && compounds.value > 0) { if (compounds !== undefined && compounds.value > 0) {
this._isUnlocked = true; this._isUnlocked = true;
} }
return this._isUnlocked; return this._isUnlocked;

View File

@ -9,12 +9,12 @@ class Church extends Infrastructure {
} }
public max: (state: GameState) => number = (state) => public max: (state: GameState) => number = (state) =>
state.getResource(ResourceKey.compounds)?.value ?? 0; state.resource.compounds?.value ?? 0;
public isUnlocked (state: GameState): boolean { public isUnlocked (state: GameState): boolean {
if (this._isUnlocked) return true; if (this._isUnlocked) return true;
const compounds = state.getResource(ResourceKey.compounds); const compounds = state.resource.compounds;
if (compounds != null && compounds.value > 0) { if (compounds !== undefined && compounds.value > 0) {
this._isUnlocked = true; this._isUnlocked = true;
} }
return this._isUnlocked; return this._isUnlocked;

View File

@ -10,8 +10,8 @@ class Compound extends Infrastructure {
public isUnlocked (state: GameState): boolean { public isUnlocked (state: GameState): boolean {
if (this._isUnlocked) return true; if (this._isUnlocked) return true;
const tents = state.getResource(ResourceKey.tents); const tents = state.resource.tents;
if (tents !== null && tents.value >= state.config.cfgTentStartingMax) { if (tents !== undefined && tents.value >= state.config.cfgTentStartingMax) {
this._isUnlocked = true; this._isUnlocked = true;
} }
return this._isUnlocked; return this._isUnlocked;

View File

@ -9,13 +9,13 @@ class House extends Infrastructure {
} }
public max: (state: GameState) => number = (state) => public max: (state: GameState) => number = (state) =>
(state.getResource(ResourceKey.compounds)?.value ?? 0) (state.resource.compounds?.value ?? 0)
* state.config.cfgCompoundHouseCapacity; * state.config.cfgCompoundHouseCapacity;
public isUnlocked (state: GameState): boolean { public isUnlocked (state: GameState): boolean {
if (this._isUnlocked) return true; if (this._isUnlocked) return true;
const compounds = state.getResource(ResourceKey.compounds); const compounds = state.resource.compounds;
if (compounds !== null && compounds.value > 0) { if (compounds !== undefined && compounds.value > 0) {
this._isUnlocked = true; this._isUnlocked = true;
} }
return this._isUnlocked; return this._isUnlocked;

View File

@ -8,25 +8,25 @@ enum ResourceType {
} }
enum ResourceKey { enum ResourceKey {
playerOrg = 'plorg', playerOrg = 'playerOrg',
christianity = 'xtian', christianity = 'christianity',
islam = 'islam', islam = 'islam',
hinduism = 'hindu', hinduism = 'hinduism',
buddhism = 'buddh', buddhism = 'buddhism',
sikhism = 'sikhi', sikhism = 'sikhism',
judaism = 'judah', judaism = 'judaism',
other = 'other', other = 'other',
atheism = 'agnos', atheism = 'atheism',
pastors = 'pstor', pastors = 'pastors',
money = 'money', money = 'money',
faithCoin = 'crpto', cryptoCurrency = 'cryptoCurrency',
tents = 'tents', tents = 'tents',
houses = 'houses', houses = 'houses',
churches = 'chrch', churches = 'churches',
compounds = 'cmpnd', compounds = 'compounds',
buildingPermit = 'blpmt', buildingPermit = 'buildingPermit',
megaChurches = 'mchch', megaChurches = 'megaChurches',
credibility = 'creds', credibility = 'credibility',
} }
interface IResource { interface IResource {

View File

@ -51,10 +51,10 @@ abstract class Job implements IResource {
protected _availableJobs (state: GameState): number { protected _availableJobs (state: GameState): number {
// number of followers minus the number of filled jobs // number of followers minus the number of filled jobs
const followers = state.getResource(ResourceKey.playerOrg)?.value ?? 0; const followers = state.resource.playerOrg?.value ?? 0;
const hired = state.getResources().reduce( const hired = state.resources.reduce(
(tot: number, rkey: ResourceKey): number => { (tot: number, rkey: ResourceKey): number => {
const res = state.getResource(rkey); const res = state.resource[rkey];
return res?.resourceType === ResourceType.job return res?.resourceType === ResourceType.job
? tot + res.value ? tot + res.value
: tot; : tot;

View File

@ -13,8 +13,8 @@ class MegaChurch extends Infrastructure {
public isUnlocked (state: GameState): boolean { public isUnlocked (state: GameState): boolean {
if (this._isUnlocked) return true; if (this._isUnlocked) return true;
const permit = state.getResource(ResourceKey.buildingPermit); const permit = state.resource.buildingPermit;
if (permit !== null && permit.value > 0) { if (permit !== undefined && permit.value > 0) {
this._isUnlocked = true; this._isUnlocked = true;
} }
return this._isUnlocked; return this._isUnlocked;

View File

@ -17,7 +17,7 @@ class Money extends Purchasable {
public max: (state: GameState) => number = (state: GameState) => { public max: (state: GameState) => number = (state: GameState) => {
let max = state.config.cfgMoneyStartingMax; let max = state.config.cfgMoneyStartingMax;
max += (state.getResource(ResourceKey.compounds)?.value ?? 0) max += (state.resource.compounds?.value ?? 0)
* state.config.cfgCompoundMoneyCapacity; * state.config.cfgCompoundMoneyCapacity;
return max; return max;
}; };
@ -26,24 +26,22 @@ class Money extends Purchasable {
let inc = 0; let inc = 0;
// crypto currency // crypto currency
inc += (state.getResource(ResourceKey.faithCoin)?.value ?? 0) inc += (state.resource.cryptoCurrency?.value ?? 0)
* state.config.cfgCryptoReturnAmount; * state.config.cfgCryptoReturnAmount;
// TODO: job salaries
return inc; return inc;
}; };
protected _purchaseAmount (state: GameState): number { protected _purchaseAmount (state: GameState): number {
const plorg = state.getResource(ResourceKey.playerOrg); const plorg = state.resource.playerOrg;
if (plorg === null || plorg.value === 0) { if (plorg === undefined || plorg.value === 0) {
state.log('You have no followers to collect from!'); state.log('You have no followers to collect from!');
return 0; return 0;
} }
const diff = state.now - this._lastCollectionTime; const diff = state.now - this._lastCollectionTime;
if (diff < state.config.cfgTimeBetweenTithes) { if (diff < state.config.cfgTimeBetweenTithes) {
const lost = state.config.cfgTimeBetweenTithes / diff / 3; const lost = state.config.cfgTimeBetweenTithes / diff / 3;
state.getResource(ResourceKey.credibility)?.addValue(lost * -1, state); state.resource.credibility?.addValue(lost * -1, state);
} }
const tithings = plorg.value * state.config.cfgTitheAmount; const tithings = plorg.value * state.config.cfgTitheAmount;
this._lastCollectionTime = state.now; this._lastCollectionTime = state.now;
@ -51,7 +49,7 @@ class Money extends Purchasable {
} }
protected _purchaseLog (amount: number, state: GameState): string { protected _purchaseLog (amount: number, state: GameState): string {
const followers = state.getResource(ResourceKey.playerOrg)?.value ?? 0; const followers = state.resource.playerOrg?.value ?? 0;
return `You collected $${state.config.formatNumber(amount)} from ${state.config.formatNumber(followers)} followers.`; return `You collected $${state.config.formatNumber(amount)} from ${state.config.formatNumber(followers)} followers.`;
} }
} }

View File

@ -9,25 +9,24 @@ class Pastor extends Job {
} }
public max: (state: GameState) => number = (state) => { public max: (state: GameState) => number = (state) => {
let max = (state.getResource(ResourceKey.churches)?.value ?? 0) let max = (state.resource.churches?.value ?? 0)
* state.config.cfgChurchPastorCapacity; * state.config.cfgChurchPastorCapacity;
max += (state.getResource(ResourceKey.megaChurches)?.value ?? 0) max += (state.resource.megaChurches?.value ?? 0)
* state.config.cfgMegaChurchPastorCapacity; * state.config.cfgMegaChurchPastorCapacity;
return max; return max;
}; };
public isUnlocked (state: GameState): boolean { public isUnlocked (state: GameState): boolean {
if (this._isUnlocked) return true; if (this._isUnlocked) return true;
this._isUnlocked = state.getResource( this._isUnlocked = state.resource.churches?.isUnlocked(state) === true;
ResourceKey.churches)?.isUnlocked(state) === true;
return this._isUnlocked; return this._isUnlocked;
} }
public advanceAction (time: number, state: GameState): void { public advanceAction (time: number, state: GameState): void {
this._timeSinceLastTithe += time; this._timeSinceLastTithe += time;
if (this._timeSinceLastTithe >= state.config.cfgTimeBetweenTithes) { if (this._timeSinceLastTithe >= state.config.cfgTimeBetweenTithes) {
const money = state.getResource(ResourceKey.money); const money = state.resource.money;
const plorg = state.getResource(ResourceKey.playerOrg); const plorg = state.resource.playerOrg;
let tithed = this.value let tithed = this.value
* state.config.cfgPastorTitheCollectionFollowerMax; * state.config.cfgPastorTitheCollectionFollowerMax;
if (Math.floor(plorg?.value ?? 0) < tithed) if (Math.floor(plorg?.value ?? 0) < tithed)

View File

@ -17,9 +17,9 @@ class PlayerOrg implements IResource {
public max (state: GameState): number { public max (state: GameState): number {
let max = state.config.cfgFollowerStartingMax; let max = state.config.cfgFollowerStartingMax;
max += (state.getResource(ResourceKey.tents)?.value ?? 0) max += (state.resource.tents?.value ?? 0)
* state.config.cfgTentFollowerCapacity; * state.config.cfgTentFollowerCapacity;
max += (state.getResource(ResourceKey.houses)?.value ?? 0) max += (state.resource.houses?.value ?? 0)
* state.config.cfgHouseFollowerCapacity; * state.config.cfgHouseFollowerCapacity;
return max; return max;
} }
@ -28,11 +28,11 @@ class PlayerOrg implements IResource {
let inc = 0; let inc = 0;
// pastor recruiting // pastor recruiting
const pastors = state.getResource(ResourceKey.pastors)?.value ?? 0; const pastors = state.resource.pastors?.value ?? 0;
inc += pastors * state.config.cfgPastorRecruitRate; inc += pastors * state.config.cfgPastorRecruitRate;
// credibility adjustment // credibility adjustment
const creds = state.getResource(ResourceKey.credibility); const creds = state.resource.credibility;
if (creds?.max !== null) inc *= if (creds?.max !== null) inc *=
(creds?.value ?? 0) / (creds?.max(state) ?? state.config.cfgPassiveMax); (creds?.value ?? 0) / (creds?.max(state) ?? state.config.cfgPassiveMax);
@ -47,7 +47,7 @@ class PlayerOrg implements IResource {
} }
// chance to fail increases as credibility decreases // chance to fail increases as credibility decreases
const creds = state.getResource(ResourceKey.credibility); const creds = state.resource.credibility;
if (creds?.max !== null) { if (creds?.max !== null) {
const ratio = Math.ceil(creds?.value ?? 0) / (creds?.max(state) const ratio = Math.ceil(creds?.value ?? 0) / (creds?.max(state)
?? state.config.cfgPassiveMax); ?? state.config.cfgPassiveMax);
@ -98,7 +98,7 @@ class PlayerOrg implements IResource {
this._timeSinceLastLost += time; this._timeSinceLastLost += time;
if (this._timeSinceLastLost > state.config.cfgCredibilityFollowerLossTime) { if (this._timeSinceLastLost > state.config.cfgCredibilityFollowerLossTime) {
if (this.value > 0) { if (this.value > 0) {
const creds = state.getResource(ResourceKey.credibility); const creds = state.resource.credibility;
if (creds?.max !== null) { if (creds?.max !== null) {
const ratio = const ratio =
Math.ceil(creds?.value ?? 0) / (creds?.max(state) Math.ceil(creds?.value ?? 0) / (creds?.max(state)
@ -124,9 +124,9 @@ class PlayerOrg implements IResource {
let total = 0; let total = 0;
for (const key in this._followerDests) { for (const key in this._followerDests) {
const rkey = <ResourceKey>key; const rkey = <ResourceKey>key;
const religion = state.getResource(rkey); const religion = state.resource[rkey];
const followers = this._followerDests[rkey]; const followers = this._followerDests[rkey];
if (religion !== null && followers !== undefined) { if (religion !== undefined && followers !== undefined) {
if (msg !== '') msg += ', '; if (msg !== '') msg += ', ';
msg += `${state.config.formatNumber(followers)} to ${religion.name}`; msg += `${state.config.formatNumber(followers)} to ${religion.name}`;
total += followers; total += followers;
@ -140,9 +140,9 @@ class PlayerOrg implements IResource {
let total = 0; let total = 0;
for (const key in this._followerSources) { for (const key in this._followerSources) {
const rkey = <ResourceKey>key; const rkey = <ResourceKey>key;
const religion = state.getResource(rkey); const religion = state.resource[rkey];
const followers = this._followerSources[rkey]; const followers = this._followerSources[rkey];
if (religion !== null && followers !== undefined) { if (religion !== undefined && followers !== undefined) {
if (msg !== '') msg += ', '; if (msg !== '') msg += ', ';
msg += msg +=
`${state.config.formatNumber(followers)} from ${religion.name}`; `${state.config.formatNumber(followers)} from ${religion.name}`;
@ -162,7 +162,7 @@ class PlayerOrg implements IResource {
ResourceKey.hinduism, ResourceKey.buddhism, ResourceKey.sikhism, ResourceKey.hinduism, ResourceKey.buddhism, ResourceKey.sikhism,
ResourceKey.judaism, ResourceKey.other, ResourceKey.atheism]; ResourceKey.judaism, ResourceKey.other, ResourceKey.atheism];
const source = religs[Math.floor(Math.random() * 8)]; const source = religs[Math.floor(Math.random() * 8)];
const resource = state.getResource(source); const resource = state.resource[source];
return resource !== null ? [source, resource] : null; return resource !== undefined ? [source, resource] : null;
} }
} }

View File

@ -11,7 +11,7 @@ class Tent extends Infrastructure {
public max: (state: GameState) => number = (state) => { public max: (state: GameState) => number = (state) => {
// ten extra tents per compound // ten extra tents per compound
let max = state.config.cfgTentStartingMax; let max = state.config.cfgTentStartingMax;
max += (state.getResource(ResourceKey.compounds)?.value ?? 0) max += (state.resource.compounds?.value ?? 0)
* state.config.cfgCompoundTentCapacity; * state.config.cfgCompoundTentCapacity;
return max; return max;
}; };

View File

@ -5,7 +5,7 @@ class DebugRenderer implements IRenderer {
private _handleClick = true; private _handleClick = true;
public render (state: GameState): void { public render (state: GameState): void {
const rkeys = state.getResources(); const rkeys = state.resources;
const container = document.getElementById('irreligious-game'); const container = document.getElementById('irreligious-game');
if (!this._initialized) { if (!this._initialized) {
if (container === null) { if (container === null) {
@ -42,8 +42,8 @@ class DebugRenderer implements IRenderer {
} }
// create containers for each resource // create containers for each resource
for (const rkey of rkeys) { for (const rkey of rkeys) {
const resource = state.getResource(rkey); const resource = state.resource[rkey];
if (resource === null) continue; if (resource === undefined) continue;
const resContainer = document.getElementById( const resContainer = document.getElementById(
`resource-container-${resource.resourceType}`); `resource-container-${resource.resourceType}`);
if (resContainer === null) continue; if (resContainer === null) continue;
@ -92,8 +92,8 @@ class DebugRenderer implements IRenderer {
}); });
} }
for (const rkey of rkeys) { for (const rkey of rkeys) {
const resource = state.getResource(rkey); const resource = state.resource[rkey];
if (resource === null) continue; if (resource === undefined) continue;
const el = document.getElementById(`resource-details-${rkey}`); const el = document.getElementById(`resource-details-${rkey}`);
if (el !== null && resource.isUnlocked(state)) { if (el !== null && resource.isUnlocked(state)) {
if (el.className !== 'resource') el.className = 'resource'; if (el.className !== 'resource') el.className = 'resource';
@ -148,14 +148,14 @@ class DebugRenderer implements IRenderer {
private _getCostStr (resource: IResource, state: GameState): string { private _getCostStr (resource: IResource, state: GameState): string {
let cost = ''; let cost = '';
for (const rkey of state.getResources()) { for (const rkey of state.resources) {
if (resource.cost?.[rkey] !== undefined) { if (resource.cost?.[rkey] !== undefined) {
if (cost !== '') cost += ', '; if (cost !== '') cost += ', ';
if (rkey === ResourceKey.money) { if (rkey === ResourceKey.money) {
cost += `$${state.config.formatNumber(resource.cost[rkey] ?? 0)}`; cost += `$${state.config.formatNumber(resource.cost[rkey] ?? 0)}`;
} else { } else {
cost += `${state.config.formatNumber(resource.cost[rkey] ?? 0)} cost += `${state.config.formatNumber(resource.cost[rkey] ?? 0)}
${state.getResource(rkey)?.name ?? rkey}`; ${state.resource[rkey]?.name ?? rkey}`;
} }
} }
} }