Identify ores with the cursor: pinged veins, ores-only label, vein outline (t77)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 17:43:49 -04:00
co-authored by Claude Opus 5.5
parent f4ca1cae57
commit f193b1c76c
11 changed files with 214 additions and 23 deletions
+52
View File
@@ -76,6 +76,58 @@ with sync_playwright() as p:
check('built solids get no loose-grain outline', ground['built'][0] == ground['built'][1], ground['built'])
check('smooth: a thin darker seam separates ground and rubble', ground['smooth'][0] < ground['smooth'][1] * 0.9, ground['smooth'])
check('smooth: packed rubble keeps pebble shading', ground['texture'] > 30, ground['texture'])
# Cursor labels and outlines use a paused scene and the real drawing functions.
cursor = ev("""() => {
SET.look='pixel'; SET.cursorLabel='ores'; SET.fog=false; SET.zoom=8;
resizeRender(); GAME.tool=0; GAME.mouse.in=true; GAME.usingPad=false;
bot.x=118; bot.y=114; snapCamera(); player.lens=false; R.lens=false;
for(let y=110;y<130;y++)for(let x=110;x<140;x++) {
const i=y*W+x; setCell(i,STONE,22,F_NAT); part[i]=0; mach[i]=0; occ[i]=0; bgm[i]=0;
blockP[(y>>2)*BW+(x>>2)]=0;
}
for(let y=118;y<126;y++)for(let x=120;x<132;x++)
if(x+y>239 && x+y<255)setCell(y*W+x,CUV,22,F_NAT);
setCell(116*W+116,SAND,22,0);
GAME.aim={x:124,y:122}; cursorLabelKey=null;
const ctx=R.ctx,text=ctx.fillText,stroke=ctx.stroke,now=performance.now.bind(performance);
let time=1000,calls=[],strokes=0;
performance.now=()=>time;
ctx.fillText=function(t){calls.push([t,this.globalAlpha,this.fillStyle]);};
ctx.stroke=function(){strokes++;};
const label=()=>{calls=[];drawCursorLabel(500,300,1);return calls.slice();};
try {
GAME.aim={x:116,y:116};const sand=label();
GAME.aim={x:124,y:122};const copper=label();drawHoveredVein();const outlined=strokes;
const vein=cursorVeinCache;
GAME.aim={x:125,y:122};time=3200;const fading=label();
const reused=cursorVeinCache===vein;
time=3400;const faded=label();
setCell(116*W+117,FEV,22,F_NAT); GAME.aim={x:117,y:116};
const hard=label();time=6000;const warning=label();
GAME.aim={x:124,y:122}; SET.fog=true;fog.fill(0);
GAME.ping={x:124,y:122,t0:6000,r:48,cells:[122*W+124]};
const ping=hoverInfo(124,122),pingLabel=label();renderInfo();
const panel=$('info').textContent;
time=8000;const hidden=hoverInfo(124,122).t1;
GAME.ping=null;SET.fog=false; SET.cursorLabel='off';
const off=label();strokes=0;drawHoveredVein();
return {sand,copper,outlined,reused,fading,faded,hard,warning,ping,pingLabel,panel,hidden,off,offStrokes:strokes};
} finally {ctx.fillText=text;ctx.stroke=stroke;performance.now=now;}
}""")
check('ores mode skips sand and draws the copper vein name', not cursor['sand'] and any(t[0] == 'Copper ore vein' for t in cursor['copper']), cursor['copper'])
check('hovering a vein draws an outline and reuses it within the vein', cursor['outlined'] > 0 and cursor['reused'])
check('the name fades then disappears while staying on the vein', any(0 < t[1] < 1 for t in cursor['fading']) and not cursor['faded'], cursor['fading'])
check('the needed bit stays red after the name fades', any(t[0].startswith('needs ') and t[1] == 1 and t[2] == '#ef6a55' for t in cursor['warning']), cursor['warning'])
check('a pinged vein under fog names itself in the label and corner panel', cursor['ping']['t1'] == 'Copper ore vein' and 'found by the ping' in cursor['panel'] and any('found by the ping' in t[0] for t in cursor['pingLabel']), cursor['pingLabel'])
check('a faded ping hides the vein again', cursor['hidden'] == 'Unexplored')
check('off hides both label and vein outline', not cursor['off'] and cursor['offStrokes'] == 0)
for look in ['pixel', 'smooth']:
ev("""look => {
SET.look=look; SM.scale=1; SET.cursorLabel='ores'; GAME.aim={x:124,y:122}; cursorLabelKey=null;
$('cards').replaceChildren(); renderInfo(); drawWorld(); drawHoveredVein(); drawBot();
const p=worldToScreenPx(124,122); drawCursorLabel(p.x,p.y,1);
}""", look)
pg.screenshot(path=str(root / 'shots' / ('t77-vein.png' if look == 'pixel' else 't77-vein-smooth.png')))
wall = pg.evaluate('''() => {
GAME.paused = true; R.lens = false; SET.fog = false;
SET.lighting = 'off'; SET.glow = 'off'; SET.grain = false;