diff --git a/web/index.html b/web/index.html
index 7e2a4b3..1adad8e 100644
--- a/web/index.html
+++ b/web/index.html
@@ -264,7 +264,9 @@ const game = GAME_ON ? createGame({
onDay: (day) => {
if (gigState) gigState.setWeekNight(weekNightOf(day)); // (day โ 1) % 7 โ see the seam note below
lighting.setSegment(0);
- hud.showToast(`๐
day ${day}`);
+ // [R34] the morning paper: GODBAY resolved before this hook fired โ fold the results in
+ const news = game ? game.takeAuctionNews() : [];
+ hud.showToast(`๐
day ${day}` + (news.length ? ' ยท ' + news.join(' ยท ') : ''), news.length ? 6 : 2.6);
},
}) : null;
const wallet = game ? game.wallet : baseWallet;
@@ -283,7 +285,13 @@ const weekNightOf = (day) => (Math.max(1, day) - 1) % 7;
if (game && gigState) gigState.setWeekNight(weekNightOf(game.day));
// [R33 โ TRAVEL COSTS A DAY] this boot adopted a save from another town: the ride ate a day (save.js
// adopt() did the increment + pull-pruning; weekNight above already read the incremented day). Tell John.
-if (game && game.traveled) hud.showToast(`๐ ${plan.name || 'a new town'} โ the ride cost a day. Day ${game.day}`, 4);
+// [R34] the ride also resolved any GODBAY listings the day moved past โ the arrival toast carries the news.
+if (game) {
+ const bootNews = game.takeAuctionNews();
+ if (game.traveled) hud.showToast(`๐ ${plan.name || 'a new town'} โ the ride cost a day. Day ${game.day}`
+ + (bootNews.length ? ' ยท ' + bootNews.join(' ยท ') : ''), bootNews.length ? 7 : 4);
+ else if (bootNews.length) hud.showToast(bootNews.join(' ยท '), 6);
+}
// [Lane F R9] occupancyOf closure defers to `citizens` (declared just below); only invoked at enter()
// time (door click), long after citizens is initialized โ so the forward reference is safe.
const interiorMode = createInteriorMode({ THREE, renderer, camera, plan, fleet, useGLB: !NOASSETS,
diff --git a/web/js/world/hud.js b/web/js/world/hud.js
index 00de507..9b7879c 100644
--- a/web/js/world/hud.js
+++ b/web/js/world/hud.js
@@ -200,7 +200,34 @@ export function createHUD({ camera, renderer, plan, getDoorMeshes, onEnterShop }
const meta = document.createElement('div'); meta.className = 'pc-crate-meta';
meta.textContent = `paid $${e.pricePaid} ยท ${foundAt(e, game)} ยท day ${e.dayFound}`;
main.append(t, a, meta);
- row.append(th, main); panel.appendChild(row);
+ row.append(th, main);
+ // [R34 GODBAY] โ LIST โ mail-in consignment; the entry leaves the crate, hammers tomorrow.
+ if (typeof game.listFind === 'function') {
+ const lb = document.createElement('div');
+ lb.textContent = 'โ'; lb.title = 'LIST at GodBay โ the auction resolves tomorrow';
+ lb.style.cssText = 'cursor:pointer;opacity:.65;padding:0 4px;flex:none;font-size:15px';
+ lb.onclick = () => { if (game.listFind(e)) rebuildList(); };
+ row.appendChild(lb);
+ }
+ panel.appendChild(row);
+ }
+ // [R34] AT AUCTION โ consigned finds, hammering overnight. Non-empty only (no header over nothing).
+ const listings = game.listings || [];
+ if (listings.length) {
+ const lh = document.createElement('h3');
+ lh.style.marginTop = '10px';
+ lh.textContent = `AT AUCTION โ ${listings.length} consigned ยท hammers tomorrow`;
+ panel.appendChild(lh);
+ for (const l of listings) {
+ const row = document.createElement('div'); row.className = 'pc-crate-row';
+ const main = document.createElement('div'); main.className = 'pc-crate-main';
+ const t = document.createElement('div'); t.className = 'pc-crate-title';
+ t.textContent = l.title || l.sku || l.slotId || 'item';
+ const meta = document.createElement('div'); meta.className = 'pc-crate-meta';
+ meta.textContent = `paid $${l.pricePaid} ยท listed day ${l.listDay}`;
+ main.append(t, meta);
+ row.append(main); panel.appendChild(row);
+ }
}
// [R33] THE WANTLIST โ what you're hunting (โ on a pull card adds; โ here removes; buying one
// clears it automatically). Section exists only when non-empty โ no stray header over nothing.
@@ -245,8 +272,8 @@ export function createHUD({ camera, renderer, plan, getDoorMeshes, onEnterShop }
shownCount = col.length; btnCrate.textContent = `CRATE ${shownCount}`;
if (open) rebuildList();
}
- const nw = (game.wants || []).length; // [R33] want add/clear refreshes an open panel too
- if (nw !== shownWants) { shownWants = nw; if (open) rebuildList(); }
+ const nw = (game.wants || []).length + (game.listings || []).length * 100; // [R33/R34] wants OR
+ if (nw !== shownWants) { shownWants = nw; if (open) rebuildList(); } // listings change โ rebuild
// [R32] the surface yields to the map and to the dig/sell cards (they own the screen), and shows
// everywhere else โ street AND interior. Cheap: a style write only when the answer changes.
const P = window.PROCITY, im = P && P.interiorMode;