This repository has been archived on 2022-01-16. You can view files and clone it, but cannot push or open issues or pull requests.
irreligious/src/render/DebugRenderer.ts

186 lines
6.6 KiB
TypeScript
Raw Normal View History

2021-09-06 08:51:41 -05:00
/// <reference path="../logging/DebugLogger.ts" />
2021-09-05 14:45:37 -05:00
class DebugRenderer implements IRenderer {
2021-09-06 08:51:41 -05:00
public onInitialRender?: (state: GameState) => void;
2021-09-04 22:21:14 -05:00
private _initialized = false;
private _handleClick = true;
public render(state: GameState): void {
const rkeys = state.resources;
2021-09-05 14:45:37 -05:00
const container = document.getElementById('irreligious-game');
2021-08-21 09:22:11 -05:00
if (!this._initialized) {
2021-09-05 14:45:37 -05:00
if (container === null) {
console.error('could not find game container');
return;
}
state.onResourceClick.push((): void => {
this._handleClick = true;
});
2021-09-05 14:45:37 -05:00
const style = document.createElement('link');
2021-08-21 09:22:11 -05:00
style.setAttribute('rel', 'stylesheet');
style.setAttribute('href', 'css/debugger.css');
2021-09-05 14:45:37 -05:00
const head = document.getElementsByTagName('head')[0];
2021-08-21 09:22:11 -05:00
head.appendChild(style);
2021-08-21 21:06:29 -05:00
// create resource area and logging area
2021-09-05 14:45:37 -05:00
const resDiv = document.createElement('div');
2021-08-21 21:06:29 -05:00
resDiv.id = 'resource-section';
container.appendChild(resDiv);
2021-09-05 14:45:37 -05:00
const logDiv = document.createElement('div');
2021-08-21 21:06:29 -05:00
logDiv.id = 'logging-section';
container.appendChild(logDiv);
2021-09-05 14:45:37 -05:00
const logContent = document.createElement('div');
2021-08-21 21:06:29 -05:00
logDiv.appendChild(logContent);
state.logger = new DebugLogger(logContent);
2021-08-21 09:22:11 -05:00
// create containers for each resource type
for (const item in ResourceType) {
2021-08-21 19:02:57 -05:00
if (isNaN(Number(item))) {
2021-09-05 14:45:37 -05:00
const el = document.createElement('div');
el.id = `resource-container-${item.toString()}`;
2021-08-21 09:22:11 -05:00
el.className = 'resource-type-container';
2021-08-21 21:06:29 -05:00
resDiv.appendChild(el);
2021-08-21 09:22:11 -05:00
}
}
2021-08-22 13:08:41 -05:00
// create containers for each resource
for (const rkey of rkeys) {
const resource = state.resource[rkey];
2021-09-06 08:51:41 -05:00
if (resource === undefined || resource.label === undefined) continue;
2021-09-05 14:45:37 -05:00
const resContainer = document.getElementById(
`resource-container-${resource.resourceType}`
);
2021-09-05 14:45:37 -05:00
if (resContainer === null) continue;
const el = document.createElement('div');
2021-08-22 13:08:41 -05:00
el.className = 'resource locked';
el.id = `resource-details-${rkey}`;
2021-09-04 22:21:14 -05:00
let content = `
2021-08-22 13:08:41 -05:00
<span class='resource-title'
title='${this._escape(resource.description)}'>
2021-09-06 08:51:41 -05:00
${this._escape(resource.label)}</span><br>
2021-08-22 13:08:41 -05:00
<span class='resource-value'></span>
<span class='resource-max'></span>
<span class='resource-inc'></span>
`;
if (resource.userActions !== undefined) {
content += '<br>';
for (let i = 0; i < resource.userActions.length; i++) {
const action = resource.userActions[i];
content += `<button
id='resource-btn-${rkey}-${i}'
class='resource-btn'
title='${this._escape(action.description)}'>
${this._escape(action.name)}</button>`;
}
2021-08-22 13:08:41 -05:00
}
if (
resource.cost !== undefined &&
Object.keys(resource.cost).length !== 0
) {
2021-08-22 13:08:41 -05:00
content += "<br>Cost: <span class='resource-cost'></span>";
}
el.innerHTML = content;
resContainer.appendChild(el);
if (resource.userActions !== undefined) {
for (let i = 0; i < resource.userActions.length; i++) {
const action = resource.userActions[i];
const btn = document.getElementById(`resource-btn-${rkey}-${i}`);
btn?.addEventListener('click', (): void => {
state.performAction(rkey, i);
});
}
2021-08-22 13:08:41 -05:00
}
}
2021-08-22 13:48:48 -05:00
// create tools footer
2021-09-05 14:45:37 -05:00
const footer = document.createElement('div');
2021-08-22 13:48:48 -05:00
footer.className = 'footer';
footer.innerHTML = `
<button id='dbg-btn-reset'>Reset Game</button>
`;
resDiv.appendChild(footer);
document
.getElementById('dbg-btn-reset')
?.addEventListener('click', (): void => {
2021-08-22 13:48:48 -05:00
state.reset();
2021-09-05 14:45:37 -05:00
container.innerHTML = '';
2021-08-22 14:29:49 -05:00
this._initialized = false;
2021-08-22 13:48:48 -05:00
});
2021-08-21 09:22:11 -05:00
}
for (const rkey of rkeys) {
const resource = state.resource[rkey];
if (resource === undefined) continue;
2021-09-05 14:45:37 -05:00
const el = document.getElementById(`resource-details-${rkey}`);
if (el !== null && resource.isUnlocked(state)) {
2021-08-22 13:08:41 -05:00
if (el.className !== 'resource') el.className = 'resource';
const elV = el.getElementsByClassName('resource-value')[0];
const elT = el.getElementsByClassName('resource-max')[0];
const value = resource.valueInWholeNumbers
2021-08-22 11:07:49 -05:00
? Math.floor(resource.value)
: resource.value;
elV.innerHTML = formatNumber(value);
elT.innerHTML =
resource.max !== undefined
? ` / ${formatNumber(resource.max(state))}`
: '';
if (resource.userActions !== undefined) {
for (let i = 0; i < resource.userActions.length; i++) {
const elB = document.getElementById(`resource-btn-${rkey}-${i}`);
if (elB === null) continue;
if (resource.userActions[i].isEnabled(state)) {
elB.removeAttribute('disabled');
} else {
elB.setAttribute('disabled', 'disabled');
}
}
2021-08-21 21:06:29 -05:00
}
2021-09-05 19:20:24 -05:00
if (resource.inc !== undefined && resource.inc(state) > 0) {
const elI = el.getElementsByClassName('resource-inc')[0];
elI.innerHTML = ` +${formatNumber(resource.inc(state))}/s`;
2021-08-22 13:48:48 -05:00
}
2021-08-21 09:22:11 -05:00
if (this._handleClick) {
const elC = el.getElementsByClassName('resource-cost');
2021-08-21 09:22:11 -05:00
if (elC.length > 0) {
2021-08-21 19:02:57 -05:00
elC[0].innerHTML = this._getCostStr(resource, state);
}
}
2021-08-22 13:48:48 -05:00
} else {
2021-09-05 14:45:37 -05:00
if (el !== null && el.className !== 'resource locked')
2021-08-22 13:48:48 -05:00
el.className = 'resource locked';
}
}
2021-08-21 09:22:11 -05:00
this._handleClick = false;
2021-09-06 08:51:41 -05:00
if (!this._initialized && this.onInitialRender !== undefined) {
this.onInitialRender(state);
}
this._initialized = true;
}
private _escape(text: string): string {
2021-08-21 19:02:57 -05:00
const escapes: { [key: string]: string } = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
2021-09-05 14:45:37 -05:00
'/': '&#x2F;',
};
2021-09-04 22:21:14 -05:00
const escaper = /[&<>"'/]/g;
return text.replace(escaper, (match: string): string => escapes[match]);
2021-08-21 19:02:57 -05:00
}
private _getCostStr(resource: IResource, state: GameState): string {
2021-09-04 22:21:14 -05:00
let cost = '';
for (const rkey of state.resources) {
if (resource.cost?.[rkey] !== undefined) {
if (cost !== '') cost += ', ';
if (rkey === ResourceKey.money) {
cost += `$${formatNumber(resource.cost[rkey] ?? 0)}`;
} else {
cost += `${formatNumber(resource.cost[rkey] ?? 0)}
${state.resource[rkey]?.pluralName ?? rkey}`;
}
}
}
return cost;
}
}