diff --git a/web/js/interiors/dig.js b/web/js/interiors/dig.js index 21c1199..daff7cb 100644 --- a/web/js/interiors/dig.js +++ b/web/js/interiors/dig.js @@ -116,6 +116,7 @@ export function createDig(THREE, renderer) { let recs = [], cursor = 0, vel = 0, active = false, pulled = null, lastFloor = -1; let crate = null, offers = [], onCloseCb = null, onBuyCb = null, getCashCb = null; + let onWantCb = null, isWantedCb = null; // [R33] the wantlist seams — absent (?game=0/classic) ⇒ no WANT DOM at all let emitters = null; // [R28] room.audio.emitters, per open — where the till sounds from. Optional. // shared across opens (persistent): sleeves are all the same box; sides + crate timber never vary const sleeveGeo = trackGeo(new THREE.BoxGeometry(SLEEVE[0], SLEEVE[1], SLEEVE[2])); @@ -141,6 +142,9 @@ export function createDig(THREE, renderer) { .pcdg-panel button{margin-top:13px;width:100%;padding:9px;border:1px solid #8a7f66;background:#e7dcc2;color:#241f18;font:700 13px "Courier New",monospace;letter-spacing:.06em;cursor:pointer} .pcdg-panel button:hover:not(:disabled){background:#241f18;color:#f4e11a;border-color:#241f18} .pcdg-panel button:disabled{color:#9a917c;border-color:#c3b99f;cursor:default} + .pcdg-panel .want{margin-top:7px;text-align:center;font:700 11px "Courier New",monospace;letter-spacing:.08em;color:#8a7f66;cursor:pointer;user-select:none} + .pcdg-panel .want:hover{color:#241f18} + .pcdg-panel .want.on{color:#b3121f;cursor:default} .pcdg-panel .x{position:absolute;top:4px;left:8px;cursor:pointer;color:#a89e86;font-size:13px} .pcdg-out{position:fixed;left:16px;top:16px;background:#1d1d2b;border:1px solid #666;color:#d8d8e0;padding:8px 14px;font:13px "Courier New",monospace;cursor:pointer;display:none;z-index:60} .pcdg-out:hover{border-color:#3dff8b;color:#3dff8b} @@ -268,14 +272,25 @@ export function createDig(THREE, renderer) { // the sticker; whether it's under the guide is for the PLAYER to notice — the card never says gem. const guide = guideText('record', o.band); if (guide) stamps.push(`${esc(guide)}`); + // [R33] the WANT line — only when the game layer wired the seams (construction-gated DOM: a + // ?game=0 / classic card carries no wantlist trace). Already-wanted reads as a stamp, not a button. + const wanted = isWantedCb ? !!isWantedCb(o) : false; + const wantLine = onWantCb + ? `
${wanted ? '★ ON THE WANTLIST' : '☆ WANT IT — hunt one cheaper'}
` + : ''; panel.innerHTML = `
` + `
$${esc(o.price)}
` + `

${esc(o.a)}

` + (o.t ? `
“${esc(o.t)}”
` : '') + (stamps.length ? `
${stamps.join('')}
` : '') - + ``; + + `` + + wantLine; panel.style.display = 'block'; panel.querySelector('.x').onclick = unpull; + const wantEl = panel.querySelector('.want'); + if (wantEl && !wanted) wantEl.onclick = () => { + if (onWantCb(o) !== false) { wantEl.classList.add('on'); wantEl.textContent = '★ ON THE WANTLIST'; wantEl.onclick = null; } + }; const b = panel.querySelector('button'); if (b && !b.disabled) b.onclick = () => { // STUB economy (round 6+): onBuy may veto; default is a toast + remove-from-bin. @@ -395,6 +410,7 @@ export function createDig(THREE, renderer) { function open(opts = {}) { active = true; onCloseCb = opts.onClose || null; onBuyCb = opts.onBuy || null; getCashCb = opts.getCash || null; + onWantCb = opts.onWant || null; isWantedCb = opts.isWanted || null; // [R33] wantlist seams emitters = opts.emitters || null; const count = opts.count || 16; const gone = opts.gone instanceof Set && opts.gone.size ? opts.gone : null;