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 cfgCredibilityRestoreRate = 0.25;
public cfgPastorRecruitRate = 0.01;
public cfgPastorTitheCollectionFollowerMax = 100;
public cfgPastorSalary = 7.5;
public cfgFollowerGainLossLogTimer = 10000;
public cfgFollowerStartingMax = 5;
public cfgPastorRecruitRate = 0.01;
public cfgTimeBetweenTithes = 30000;
public cfgTitheAmount = 10;
public cfgCryptoReturnAmount = 1;
public cfgMoneyStartingMax = 500000;
public cfgPastorTitheCollectionFollowerMax = 100;
public cfgBuildingPermitCost = 250000;
@ -113,7 +115,7 @@ class GameConfig {
// add resources
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.houses, new House(this));
state.addResource(ResourceKey.churches, new Church(this));

View File

@ -15,11 +15,18 @@ class GameState {
private _resources: { [key in ResourceKey]?: IResource } = { };
private readonly _resourceKeys: ResourceKey[] = [];
constructor (config: GameConfig) {
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 {
this._resourceKeys.push(key);
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 {
const resource = this._resources[resourceKey];
if (resource === undefined || !resource.isUnlocked(this)) return;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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