Skip to content

Commit ca68e5b

Browse files
claudemhanavan4-prog
authored andcommitted
Balefires on the Wilds map; the last unseen pieces looked at
- The Wilds map shows each balefire, with a ring round the ones still to light today, so the round can be planned. - A bound boss is now tested in the real dungeon tick: it covers six tenths of the ground, and its full stride again once the binding is off. - The ?testdrive=1 seam gains `manor()` to stand in the Manor's hall. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014upby61fMmizgg2cMkKvqW
1 parent dca0dfc commit ca68e5b

3 files changed

Lines changed: 28 additions & 1 deletion

File tree

‎client/main.js‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3094,7 +3094,7 @@ function onWsMessage(ev) {
30943094
return;
30953095
}
30963096
if (msg.type === 'dungeon_finds') { applyDungeonFinds(msg); showDungeonFindsHud(msg); return; }
3097-
if (msg.type === 'wilds_finds') { applyWildsFinds(msg); showWildsFindsHud(msg); return; }
3097+
if (msg.type === 'wilds_finds') { wildsFindsState = msg; applyWildsFinds(msg); showWildsFindsHud(msg); return; }
30983098
if (msg.type === 'trap_warn') { dungeonTrapWarn(msg.trap, msg.ms); setUnlockToast('⚠️ The roof is going. Move!', { always: true }); return; }
30993099
if (msg.type === 'toast') {
31003100
if (msg.message) setUnlockToast(msg.message, (msg.level || msg.always) ? { level: msg.level, always: !!msg.always } : undefined);
@@ -10403,6 +10403,7 @@ function showDungeonFindsHud(msg) {
1040310403
}
1040410404
// Out in the Wilds the same line counts the day's balefires.
1040510405
let wildsFindsAskedAt = 0;
10406+
let wildsFindsState = null; // the day's balefires and searched cairns, as the server last told it (the map marks them)
1040610407
function showWildsFindsHud(msg) {
1040710408
const el = document.getElementById('dungeonFindsHud');
1040810409
if (!el || !(me && me.room === 'wilds')) return;
@@ -17389,6 +17390,16 @@ const { openNotifModal } = _notif;
1738917390
if (typeof WILDS_CAMPFIRES !== 'undefined') {
1739017391
for (const f of WILDS_CAMPFIRES) drawProp(ctx, PX(f.x), PY(f.y) + fireS * 0.2, fireS, 'campfire');
1739117392
}
17393+
// Balefires: a fire for each, and a ring round the ones still to light today,
17394+
// so the round can be planned from the map.
17395+
if (world2.finds) {
17396+
const litToday = new Set((wildsFindsState && wildsFindsState.lit) || []);
17397+
for (const f of world2.finds.balefires) {
17398+
const fx = PX(f.x), fy = PY(f.y);
17399+
drawProp(ctx, fx, fy + fireS * 0.2, fireS * 0.9, 'campfire');
17400+
if (!litToday.has(f.id)) { ctx.save(); ctx.strokeStyle = '#ffb060'; ctx.lineWidth = 1.5; ctx.setLineDash([3, 3]); ctx.beginPath(); ctx.arc(fx, fy, fireS * 0.75, 0, Math.PI * 2); ctx.stroke(); ctx.restore(); }
17401+
}
17402+
}
1739217403
// NPCs: villager props at their true spots, then names stacked downward so
1739317404
// the tight camp clusters read as a clean list instead of a tangle.
1739417405
if (typeof WILDS_NPCS !== 'undefined') {
@@ -20376,6 +20387,8 @@ if (location.search.includes('testdrive=1')) {
2037620387
teleport(x, y) { if (me) { me.x = x; me.y = y; } },
2037720388
// Turn the camera round you (radians from its usual place behind you), to look at what stands at your back.
2037820389
look(yaw, pitch) { cameraYawOffset = +yaw || 0; if (pitch != null) cameraPitchOffset = +pitch || 0; return true; },
20390+
// Stand in the Manor's hall (the look of it only; the server keeps its own door).
20391+
manor() { swapToManorMap(); if (me) { me.room = 'manor'; me.x = MANOR_WORLD.spawn.x; me.y = MANOR_WORLD.spawn.y; } return activeScene === manorScene; },
2037920392
// Step straight into a town building's interior (the look of it; the server still keeps its own doors).
2038020393
enter(roomId) { if (me && world && world.buildings.some((b) => b.id === roomId)) { enterBuilding(roomId); return true; } return false; },
2038120394
kiosks() { return OUTDOOR_KIOSKS.map(k => ({ ...k })); },

‎test/old-ways.test.js‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,18 @@ check('the panel shows why a thing waits, asks before the brownie is clothed, an
146146
const dung = fs.readFileSync(path.join(root, 'lib/dungeons.js'), 'utf8'), delve = fs.readFileSync(path.join(root, 'lib/delve.js'), 'utf8'), cottage = fs.readFileSync(path.join(root, 'client/cottage-scene.js'), 'utf8');
147147
check('a bound boss drags its feet in a dungeon and on a Delve floor', /m\.boundUntil > now \? \{ \.\.\.base, speed: base\.speed \* \(m\.boundSlow \|\| 0\.6\) \} : base/.test(dung) && /\(m\.boundUntil > now \? \(m\.boundSlow \|\| 0\.6\) : 1\)/.test(delve) && /findBoss: \(p, range\) => \[\.\.\.dungeonMobs, \.\.\.allDelveMobs\(\)\]\.find\(\(m\) => m\.boss && !m\.dead && m\.room === p\.room/.test(server));
148148
check('her besom leans by the cottage door, and the cream stands on the hearthstone the night it is set', /besom: !!\(key && accounts\[key\] && accounts\[key\]\.oldWays && accounts\[key\]\.oldWays\.besom && accounts\[key\]\.oldWays\.besom\.made\)/.test(server) && /kkStatic\('wd_besom', 96, 'height'\)/.test(cottage) && /kkStatic\('wd_cream', 18, 'fit'\)/.test(cottage) && /wd_besom: 'kk\/home\/besom\.glb', wd_cream: 'kk\/home\/cream_bowl\.glb'/.test(main) && fs.existsSync(path.join(root, 'public/kk/home/besom.glb')) && fs.existsSync(path.join(root, 'public/kk/home/cream_bowl.glb')));
149+
// a bound boss, in the real dungeon tick: it covers six tenths of the ground it would
150+
{
151+
const ps = new Map();
152+
const dmod = require('../lib/dungeons')({ players: ps, send: () => {}, isEvading: () => false, absorbIncomingDamage: (_p, d) => d, noteAttacked: () => {}, DUNGEON_ROOMS: { 1: 'dungeon_t1', 2: 'dungeon_t2', 3: 'dungeon_t3', 4: 'dungeon_t4' }, DUNGEON_SIZE: 2400, dungeonAffix: () => null });
153+
const b = dmod.dungeonMobs.find((m) => m.boss && m.tier === 1);
154+
ps.set('z', { id: 'z', room: 'dungeon_t1', x: b.spawnX + 150, y: b.spawnY, health: 1e6, isDead: false, ws: null });
155+
const step = () => { b.x = b.spawnX; b.y = b.spawnY; dmod.tickDungeon(1); return Math.hypot(b.x - b.spawnX, b.y - b.spawnY); };
156+
const free = step();
157+
b.boundUntil = Date.now() + 60000; b.boundSlow = D.POPPET.bindSlow;
158+
const bound = step();
159+
b.boundUntil = 0;
160+
check('a bound boss covers six tenths of the ground in the same time, and its full stride again once the binding is off', free > 10 && Math.abs(bound / free - 0.6) < 0.01 && Math.abs(step() - free) < 0.01, { free, bound });
161+
}
149162
console.log(`\n${pass} passed, ${fail} failed`);
150163
process.exit(fail ? 1 : 0);

‎test/wilds-finds.test.js‎

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)