Fix silently-dropped log entries past the 40-line cap, add pause, clarify locations panel
Docker / build-and-push (push) Successful in 42s
Docker / build-and-push (push) Successful in 42s
- The log view only re-rendered when state.log.length changed, but the log is capped at 40 entries — so once a run had logged 40+ things (easy in a normal session), every entry after that point, including choice-event outcomes, upgrade purchases, and location visits, stopped appearing even though the underlying state updated. Fixed by tracking a monotonic logSeq counter that increments on every push regardless of the cap, and rendering off that instead of array length. Consolidated the repeated unshift+cap logic into one pushLog() helper so future call sites can't reintroduce the bug. - Added a pause button (and "PAUSAD" indicator) that freezes the tick loop without touching game state, so a hectic run can be paused to think without it counting as a save-scummy state mutation. Manual actions (buying upgrades, visiting locations) still work while paused, since that's usually the point of pausing. - The "Aktiva områden" sidebar only ever listed the 3 story-gated core areas, while the map has 7 clickable locations — making it look like 4 of the map pins didn't really exist. Split the panel into "Ritualens kärnplatser" (the 3 gated ones, unlock status shown as before) and "Övriga platser" (the 4 always-open flavor locations), so the sidebar and map agree. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
4b4e5c14aa
commit
b7c052a11f
@@ -9,12 +9,14 @@ export function initUI(
|
||||
onEventChoice: (index: number) => void,
|
||||
onStart: () => void,
|
||||
onAbandon: () => void,
|
||||
onTogglePause: () => void,
|
||||
): void {
|
||||
app.innerHTML = `
|
||||
<div id="header">
|
||||
<div class="brand">DJUPET</div>
|
||||
<div class="brand-sub">Malmö, Sverige · <span id="phase-tag" class="phase-tag early">Tidigt skede</span></div>
|
||||
<div class="brand-sub">Malmö, Sverige · <span id="phase-tag" class="phase-tag early">Tidigt skede</span><span id="pause-tag" class="pause-tag"></span></div>
|
||||
<div class="header-actions">
|
||||
<button id="pause-btn" class="help-btn" title="Pausa spelet">Pausa</button>
|
||||
<button id="abandon-btn" class="help-btn" title="Överge kulten">Avbryt</button>
|
||||
<button id="help-btn" class="help-btn" title="Hjälp & Ändringslogg">? v${VERSION}</button>
|
||||
</div>
|
||||
@@ -126,12 +128,21 @@ export function initUI(
|
||||
</div>
|
||||
|
||||
<div class="panel" id="panel-right">
|
||||
<div class="panel-title">Aktiva områden</div>
|
||||
<div class="panel-title">Ritualens kärnplatser</div>
|
||||
<div id="areas" style="font-size:11px;color:var(--dim);line-height:2;">
|
||||
<div id="area-rosengard">○ Rosengård</div>
|
||||
<div id="area-varnhem">○ Värnhemstorget</div>
|
||||
<div id="area-torso">○ Turning Torso</div>
|
||||
</div>
|
||||
<div style="margin-top:16px;">
|
||||
<div class="panel-title">Övriga platser</div>
|
||||
<div style="font-size:11px;color:var(--dim);line-height:2;">
|
||||
<div>Øresundsbron</div>
|
||||
<div>Ribersborgsstranden</div>
|
||||
<div>Davidshallsgatan</div>
|
||||
<div>Stortorget</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:20px;" id="investigator-section">
|
||||
<div class="panel-title">Utredarna</div>
|
||||
<div id="investigator-status" style="font-size:11px;color:var(--safe);">Inaktiva</div>
|
||||
@@ -163,6 +174,7 @@ export function initUI(
|
||||
document.getElementById('abandon-btn')!.addEventListener('click', () => {
|
||||
if (window.confirm('Överge kulten? Cirkeln bryts och ni går skilda vägar.')) onAbandon();
|
||||
});
|
||||
document.getElementById('pause-btn')!.addEventListener('click', onTogglePause);
|
||||
|
||||
document.getElementById('event-modal-choices')!.addEventListener('click', e => {
|
||||
const btn = (e.target as Element).closest('[data-choice]') as HTMLElement | null;
|
||||
@@ -320,12 +332,12 @@ function renderUpgrades(state: State): void {
|
||||
}).join('');
|
||||
}
|
||||
|
||||
let lastLogLength = 0;
|
||||
let lastLogSeq = -1;
|
||||
|
||||
function renderLog(state: State): void {
|
||||
const log = document.getElementById('log')!;
|
||||
if (state.log.length === lastLogLength) return;
|
||||
lastLogLength = state.log.length;
|
||||
if (state.logSeq === lastLogSeq) return;
|
||||
lastLogSeq = state.logSeq;
|
||||
// state.log is newest-first (unshift); render as-is, scroll to top
|
||||
log.innerHTML = state.log.map(e =>
|
||||
`<div class="log-entry ${e.kind}">${e.text}</div>`
|
||||
@@ -363,6 +375,13 @@ function showOverlay(state: State): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function setPausedUI(paused: boolean): void {
|
||||
const btn = document.getElementById('pause-btn')!;
|
||||
btn.textContent = paused ? 'Fortsätt' : 'Pausa';
|
||||
document.getElementById('app')!.classList.toggle('paused', paused);
|
||||
setText('pause-tag', paused ? '⏸ Pausad' : '');
|
||||
}
|
||||
|
||||
function setText(id: string, val: string): void {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = val;
|
||||
|
||||
Reference in New Issue
Block a user