Bash

grep -n "function drawTile\|function drawPlayer\|function drawItemIcon\|function slot\|crossbow' ){\|ranged === 'crossbow'\|by - 40\|drawFurnaceUI\|function drawMob\|function drawHUD" /home/tonda/svet.html

Locate function boundaries


984:function slot(x, y, s, hi){
990:function drawItemIcon(id, x, y, s, n, dur){
1029:  if (uiMode === 'furnace') drawFurnaceUI(p, invBottom);
1062:function drawFurnaceUI(p, top){
1216:function drawTile(tx, ty){
1255:function drawPlayer(){
1275:function drawMob(m){
1296:function drawHUD(){
1321:  if (it && it.ranged === 'crossbow'){
1323:    ctx.fillText(xbowLoaded ? 'kuše natažená – klikni' : 'kuše: drž levé = natáhnout', VW/2, by - 40);


<total_tokens>14986776 tokens left</total_tokens>


udělej pro každou věc jinou texturu a řekni čím mám jíst tak poznám jak jmenu je ta vec co držím v ruce


984	function slot(x, y, s, hi){
985	  ctx.fillStyle = hi ? 'rgba(92,200,255,.25)' : 'rgba(255,255,255,.06)';
986	  rr(x, y, 36, 36, 6); ctx.fill();
987	  ctx.strokeStyle = hi ? '#5cc8ff' : 'rgba(255,255,255,.14)'; ctx.lineWidth = 2; rr(x, y, 36, 36, 6); ctx.stroke();
988	  if (s) drawItemIcon(s.id, x + 4, y + 4, 28, s.n, s.dur);
989	}
990	function drawItemIcon(id, x, y, s, n, dur){
991	  const it = iget(id);
992	  ctx.fillStyle = (it && it.col) || '#aaa';
993	  if (it && (it.tool || it.ranged)){
994	    ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.7);
995	    ctx.fillStyle = 'rgba(0,0,0,.35)'; ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.18);
996	  } else if (it && it.food){
997	    ctx.beginPath(); ctx.arc(x + s/2, y + s/2, s*0.36, 0, 6.29); ctx.fill();
998	  } else {
999	    rr(x + s*0.1, y + s*0.1, s*0.8, s*0.8, 4); ctx.fill();
1000	  }
1001	  if (n > 1){
1002	    ctx.fillStyle = '#fff'; ctx.font = '700 12px system-ui'; ctx.textAlign = 'right'; ctx.textBaseline = 'alphabetic';
1003	    ctx.fillText(n, x + s + 2, y + s + 4);
1004	  }
1005	  if (dur && it && it.dur){
1006	    const f = dur / it.dur;
1007	    ctx.fillStyle = '#000'; ctx.fillRect(x, y + s + 3, s, 3);
1008	    ctx.fillStyle = f > 0.4 ? '#5fd35f' : '#d35f5f'; ctx.fillRect(x, y + s + 3, s * f, 3);
1009	  }
1010	}
1011
1012	function drawUI(){
1013	  uiRects.length = 0;

function slot(x, y, s, hi){
  ctx.fillStyle = hi ? 'rgba(92,200,255,.25)' : 'rgba(255,255,255,.06)';
  rr(x, y, 36, 36, 6); ctx.fill();
  ctx.strokeStyle = hi ? '#5cc8ff' : 'rgba(255,255,255,.14)'; ctx.lineWidth = 2; rr(x, y, 36, 36, 6); ctx.stroke();
  if (s) drawItemIcon(s.id, x + 4, y + 4, 28, s.n, s.dur);
}
function drawItemIcon(id, x, y, s, n, dur){
  const it = iget(id);
  ctx.fillStyle = (it && it.col) || '#aaa';
  if (it && (it.tool || it.ranged)){
    ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.7);
    ctx.fillStyle = 'rgba(0,0,0,.35)'; ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.18);
  } else if (it && it.food){
    ctx.beginPath(); ctx.arc(x + s/2, y + s/2, s*0.36, 0, 6.29); ctx.fill();
  } else {
    rr(x + s*0.1, y + s*0.1, s*0.8, s*0.8, 4); ctx.fill();
  }
  if (n > 1){
    ctx.fillStyle = '#fff'; ctx.font = '700 12px system-ui'; ctx.textAlign = 'right'; ctx.textBaseline = 'alphabetic';
    ctx.fillText(n, x + s + 2, y + s + 4);
  }
  if (dur && it && it.dur){
    const f = dur / it.dur;
    ctx.fillStyle = '#000'; ctx.fillRect(x, y + s + 3, s, 3);
    ctx.fillStyle = f > 0.4 ? '#5fd35f' : '#d35f5f'; ctx.fillRect(x, y + s + 3, s * f, 3);
  }
}

function drawUI(){
  uiRects.length = 0;


<total_tokens>14986396 tokens left</total_tokens>


Edit

function drawItemIcon(id, x, y, s, n, dur){
  const it = iget(id);
  ctx.fillStyle = (it && it.col) || '#aaa';
  if (it && (it.tool || it.ranged)){
    ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.7);
    ctx.fillStyle = 'rgba(0,0,0,.35)'; ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.18);
  } else if (it && it.food){
    ctx.beginPath(); ctx.arc(x + s/2, y + s/2, s*0.36, 0, 6.29); ctx.fill();
  } else {
    rr(x + s*0.1, y + s*0.1, s*0.8, s*0.8, 4); ctx.fill();
  }
  if (n > 1){

function blob(cx, cy, r){
  ctx.beginPath();
  for (let a = 0; a < 6.29; a += 0.7){
    const rr2 = r * (0.78 + ((Math.sin(a * 3) + 1) * 0.11));
    ctx.lineTo(cx + Math.cos(a) * rr2, cy + Math.sin(a) * rr2);
  }
  ctx.closePath(); ctx.fill();
}
function drawItemIcon(id, x, y, s, n, dur){
  const it = iget(id) || {};
  ctx.save();
  ctx.translate(x, y);
  ctx.lineCap = 'round'; ctx.lineJoin = 'round';
  const c = it.col || '#aaa', cx = s/2, cy = s/2;

  if (it.tool || it.ranged){
    drawToolIcon(id, it, s);
  } else if (it.place){
    paintTile(0, 0, s, it.place);
  } else if (id === 'apple'){
    ctx.fillStyle = '#e0463a'; ctx.beginPath(); ctx.arc(cx, cy + s*0.05, s*0.34, 0, 6.29); ctx.fill();
    ctx.strokeStyle = '#6b4a2c'; ctx.lineWidth = Math.max(1.5, s*0.07);
    ctx.beginPath(); ctx.moveTo(cx, cy - s*0.1); ctx.lineTo(cx + s*0.06, cy - s*0.36); ctx.stroke();
    ctx.fillStyle = '#4c8c3f'; ctx.beginPath(); ctx.ellipse(cx + s*0.16, cy - s*0.3, s*0.12, s*0.07, 0.6, 0, 6.29); ctx.fill();
  } else if (id === 'berries'){
    ctx.fillStyle = '#c7405e';
    for (const [dx,dy] of [[-.16,.1],[.16,.1],[0,-.12],[-.1,-.2],[.14,-.14]]){
      ctx.beginPath(); ctx.arc(cx + dx*s, cy + dy*s, s*0.13, 0, 6.29); ctx.fill();
    }
  } else if (id === 'rotten'){
    ctx.fillStyle = '#7a8a4a'; blob(cx, cy, s*0.36);
    ctx.fillStyle = '#5c6b34'; ctx.beginPath(); ctx.arc(cx - s*0.1, cy, s*0.06, 0, 6.29); ctx.fill();
  } else if (id === 'string'){
    ctx.strokeStyle = '#dfe3ea'; ctx.lineWidth = Math.max(1.5, s*0.08);
    ctx.beginPath();
    for (let i = 0; i <= s; i += 2) ctx.lineTo(i, cy + Math.sin(i * 0.5) * s*0.16);
    ctx.stroke();
  } else if (id === 'bone'){
    ctx.strokeStyle = '#e8e4d4'; ctx.lineWidth = s*0.16;
    ctx.beginPath(); ctx.moveTo(s*0.26, s*0.74); ctx.lineTo(s*0.74, s*0.26); ctx.stroke();
    ctx.fillStyle = '#e8e4d4';
    for (const [ex,ey] of [[.26,.74],[.74,.26]])
      for (const o of [-1,1]){ ctx.beginPath(); ctx.arc(s*ex + o*s*0.09, s*ey, s*0.09, 0, 6.29); ctx.fill(); }
  } else if (id === 'arrow'){
    ctx.strokeStyle = '#8a5f34'; ctx.lineWidth = Math.max(1.5, s*0.07);
    ctx.beginPath(); ctx.moveTo(s*0.15, s*0.85); ctx.lineTo(s*0.82, s*0.18); ctx.stroke();
    ctx.fillStyle = '#cbd0d8';
    ctx.beginPath(); ctx.moveTo(s*0.82, s*0.18); ctx.lineTo(s*0.6, s*0.24); ctx.lineTo(s*0.72, s*0.36); ctx.closePath(); ctx.fill();
    ctx.fillStyle = '#dfe3ea';
    ctx.beginPath(); ctx.moveTo(s*0.15, s*0.85); ctx.lineTo(s*0.3, s*0.78); ctx.lineTo(s*0.22, s*0.66); ctx.closePath(); ctx.fill();
  } else if (id === 'stick'){
    ctx.strokeStyle = '#a97c43'; ctx.lineWidth = s*0.15;
    ctx.beginPath(); ctx.moveTo(s*0.28, s*0.8); ctx.lineTo(s*0.72, s*0.2); ctx.stroke();
    ctx.strokeStyle = '#8a6239'; ctx.lineWidth = s*0.05;
    ctx.beginPath(); ctx.moveTo(s*0.4, s*0.62); ctx.lineTo(s*0.5, s*0.5); ctx.stroke();
  } else if (id === 'coal'){
    ctx.fillStyle = '#26282e'; blob(cx, cy, s*0.37);
    ctx.fillStyle = '#454a55'; ctx.fillRect(cx - s*0.08, cy - s*0.06, s*0.1, s*0.1);
  } else if (id === 'iron_ingot' || id === 'gold_ingot'){
    ctx.fillStyle = c;
    ctx.beginPath();
    ctx.moveTo(s*0.18, s*0.62); ctx.lineTo(s*0.82, s*0.62); ctx.lineTo(s*0.7, s*0.38); ctx.lineTo(s*0.3, s*0.38);
    ctx.closePath(); ctx.fill();
    ctx.fillStyle = 'rgba(255,255,255,.4)'; ctx.fillRect(s*0.34, s*0.42, s*0.32, s*0.06);
  } else if (id === 'diamond'){
    ctx.fillStyle = '#6be0d8';
    ctx.beginPath();
    ctx.moveTo(cx, s*0.16); ctx.lineTo(s*0.82, cy); ctx.lineTo(cx, s*0.84); ctx.lineTo(s*0.18, cy);
    ctx.closePath(); ctx.fill();
    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = 1;
    ctx.beginPath(); ctx.moveTo(s*0.18, cy); ctx.lineTo(s*0.82, cy); ctx.moveTo(cx, s*0.16); ctx.lineTo(cx, s*0.84); ctx.stroke();
  } else if (id === 'iron_ore' || id === 'gold_ore'){
    ctx.fillStyle = '#7b8290'; blob(cx, cy, s*0.4);
    ctx.fillStyle = it.col;
    for (const [dx,dy] of [[-.1,-.08],[.1,.04],[0,.14]]){
      ctx.beginPath(); ctx.arc(cx + dx*s, cy + dy*s, s*0.09, 0, 6.29); ctx.fill();
    }
  } else {
    ctx.fillStyle = c; rr(s*0.12, s*0.12, s*0.76, s*0.76, 3); ctx.fill();
  }
  ctx.restore();

  if (n > 1){


The file /home/tonda/svet.html has been updated successfully. (file state is current in your context — no need to Read it back)

function drawItemIcon(id, x, y, s, n, dur){
  const it = iget(id);
  ctx.fillStyle = (it && it.col) || '#aaa';
  if (it && (it.tool || it.ranged)){
    ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.7);
    ctx.fillStyle = 'rgba(0,0,0,.35)'; ctx.fillRect(x + s*0.15, y + s*0.15, s*0.7, s*0.18);
  } else if (it && it.food){
    ctx.beginPath(); ctx.arc(x + s/2, y + s/2, s*0.36, 0, 6.29); ctx.fill();
  } else {
    rr(x + s*0.1, y + s*0.1, s*0.8, s*0.8, 4); ctx.fill();
  }
  if (n > 1){

function blob(cx, cy, r){
  ctx.beginPath();
  for (let a = 0; a < 6.29; a += 0.7){
    const rr2 = r * (0.78 + ((Math.sin(a * 3) + 1) * 0.11));
    ctx.lineTo(cx + Math.cos(a) * rr2, cy + Math.sin(a) * rr2);
  }
  ctx.closePath(); ctx.fill();
}
function drawItemIcon(id, x, y, s, n, dur){
  const it = iget(id) || {};
  ctx.save();
  ctx.translate(x, y);
  ctx.lineCap = 'round'; ctx.lineJoin = 'round';
  const c = it.col || '#aaa', cx = s/2, cy = s/2;

  if (it.tool || it.ranged){
    drawToolIcon(id, it, s);
  } else if (it.place){
    paintTile(0, 0, s, it.place);
  } else if (id === 'apple'){
    ctx.fillStyle = '#e0463a'; ctx.beginPath(); ctx.arc(cx, cy + s*0.05, s*0.34, 0, 6.29); ctx.fill();
    ctx.strokeStyle = '#6b4a2c'; ctx.lineWidth = Math.max(1.5, s*0.07);
    ctx.beginPath(); ctx.moveTo(cx, cy - s*0.1); ctx.lineTo(cx + s*0.06, cy - s*0.36); ctx.stroke();
    ctx.fillStyle = '#4c8c3f'; ctx.beginPath(); ctx.ellipse(cx + s*0.16, cy - s*0.3, s*0.12, s*0.07, 0.6, 0, 6.29); ctx.fill();
  } else if (id === 'berries'){
    ctx.fillStyle = '#c7405e';
    for (const [dx,dy] of [[-.16,.1],[.16,.1],[0,-.12],[-.1,-.2],[.14,-.14]]){
      ctx.beginPath(); ctx.arc(cx + dx*s, cy + dy*s, s*0.13, 0, 6.29); ctx.fill();
    }
  } else if (id === 'rotten'){
    ctx.fillStyle = '#7a8a4a'; blob(cx, cy, s*0.36);
    ctx.fillStyle = '#5c6b34'; ctx.beginPath(); ctx.arc(cx - s*0.1, cy, s*0.06, 0, 6.29); ctx.fill();
  } else if (id === 'string'){
    ctx.strokeStyle = '#dfe3ea'; ctx.lineWidth = Math.max(1.5, s*0.08);
    ctx.beginPath();
    for (let i = 0; i <= s; i += 2) ctx.lineTo(i, cy + Math.sin(i * 0.5) * s*0.16);
    ctx.stroke();
  } else if (id === 'bone'){
    ctx.strokeStyle = '#e8e4d4'; ctx.lineWidth = s*0.16;
    ctx.beginPath(); ctx.moveTo(s*0.26, s*0.74); ctx.lineTo(s*0.74, s*0.26); ctx.stroke();
    ctx.fillStyle = '#e8e4d4';
    for (const [ex,ey] of [[.26,.74],[.74,.26]])
      for (const o of [-1,1]){ ctx.beginPath(); ctx.arc(s*ex + o*s*0.09, s*ey, s*0.09, 0, 6.29); ctx.fill(); }
  } else if (id === 'arrow'){
    ctx.strokeStyle = '#8a5f34'; ctx.lineWidth = Math.max(1.5, s*0.07);
    ctx.beginPath(); ctx.moveTo(s*0.15, s*0.85); ctx.lineTo(s*0.82, s*0.18); ctx.stroke();
    ctx.fillStyle = '#cbd0d8';
    ctx.beginPath(); ctx.moveTo(s*0.82, s*0.18); ctx.lineTo(s*0.6, s*0.24); ctx.lineTo(s*0.72, s*0.36); ctx.closePath(); ctx.fill();
    ctx.fillStyle = '#dfe3ea';
    ctx.beginPath(); ctx.moveTo(s*0.15, s*0.85); ctx.lineTo(s*0.3, s*0.78); ctx.lineTo(s*0.22, s*0.66); ctx.closePath(); ctx.fill();
  } else if (id === 'stick'){
    ctx.strokeStyle = '#a97c43'; ctx.lineWidth = s*0.15;
    ctx.beginPath(); ctx.moveTo(s*0.28, s*0.8); ctx.lineTo(s*0.72, s*0.2); ctx.stroke();
    ctx.strokeStyle = '#8a6239'; ctx.lineWidth = s*0.05;
    ctx.beginPath(); ctx.moveTo(s*0.4, s*0.62); ctx.lineTo(s*0.5, s*0.5); ctx.stroke();
  } else if (id === 'coal'){
    ctx.fillStyle = '#26282e'; blob(cx, cy, s*0.37);
    ctx.fillStyle = '#454a55'; ctx.fillRect(cx - s*0.08, cy - s*0.06, s*0.1, s*0.1);
  } else if (id === 'iron_ingot' || id === 'gold_ingot'){
    ctx.fillStyle = c;
    ctx.beginPath();
    ctx.moveTo(s*0.18, s*0.62); ctx.lineTo(s*0.82, s*0.62); ctx.lineTo(s*0.7, s*0.38); ctx.lineTo(s*0.3, s*0.38);
    ctx.closePath(); ctx.fill();
    ctx.fillStyle = 'rgba(255,255,255,.4)'; ctx.fillRect(s*0.34, s*0.42, s*0.32, s*0.06);
  } else if (id === 'diamond'){
    ctx.fillStyle = '#6be0d8';
    ctx.beginPath();
    ctx.moveTo(cx, s*0.16); ctx.lineTo(s*0.82, cy); ctx.lineTo(cx, s*0.84); ctx.lineTo(s*0.18, cy);
    ctx.closePath(); ctx.fill();
    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = 1;
    ctx.beginPath(); ctx.moveTo(s*0.18, cy); ctx.lineTo(s*0.82, cy); ctx.moveTo(cx, s*0.16); ctx.lineTo(cx, s*0.84); ctx.stroke();
  } else if (id === 'iron_ore' || id === 'gold_ore'){
    ctx.fillStyle = '#7b8290'; blob(cx, cy, s*0.4);
    ctx.fillStyle = it.col;
    for (const [dx,dy] of [[-.1,-.08],[.1,.04],[0,.14]]){
      ctx.beginPath(); ctx.arc(cx + dx*s, cy + dy*s, s*0.09, 0, 6.29); ctx.fill();
    }
  } else {
    ctx.fillStyle = c; rr(s*0.12, s*0.12, s*0.76, s*0.76, 3); ctx.fill();
  }
  ctx.restore();

  if (n > 1){

ctx.strokeStyle = hi ? '#5cc8ff' : 'rgba(255,255,255,.14)'; ctx.lineWidth = 2; rr(x, y, 36, 36, 6); ctx.stroke();

if (s) drawItemIcon(s.id, x + 4, y + 4, 28, s.n, s.dur);

+    ctx.lineTo(cx + Math.cos(a) * rr2, cy + Math.sin(a) * rr2);

-  ctx.fillStyle = (it && it.col) || '#aaa';

+  ctx.lineCap = 'round'; ctx.lineJoin = 'round';

+  const c = it.col || '#aaa', cx = s/2, cy = s/2;

+    ctx.fillStyle = '#e0463a'; ctx.beginPath(); ctx.arc(cx, cy + s*0.05, s*0.34, 0, 6.29); ctx.fill();

+    ctx.strokeStyle = '#6b4a2c'; ctx.lineWidth = Math.max(1.5, s*0.07);

+    ctx.beginPath(); ctx.moveTo(cx, cy - s*0.1); ctx.lineTo(cx + s*0.06, cy - s*0.36); ctx.stroke();

+      ctx.beginPath(); ctx.arc(cx + dx*s, cy + dy*s, s*0.13, 0, 6.29); ctx.fill();

+    ctx.fillStyle = '#7a8a4a'; blob(cx, cy, s*0.36);

+    ctx.fillStyle = '#5c6b34'; ctx.beginPath(); ctx.arc(cx - s*0.1, cy, s*0.06, 0, 6.29); ctx.fill();

+    ctx.strokeStyle = '#dfe3ea'; ctx.lineWidth = Math.max(1.5, s*0.08);

+    for (let i = 0; i <= s; i += 2) ctx.lineTo(i, cy + Math.sin(i * 0.5) * s*0.16);

+    ctx.strokeStyle = '#e8e4d4'; ctx.lineWidth = s*0.16;

+    ctx.beginPath(); ctx.moveTo(s*0.26, s*0.74); ctx.lineTo(s*0.74, s*0.26); ctx.stroke();

+    ctx.strokeStyle = '#8a5f34'; ctx.lineWidth = Math.max(1.5, s*0.07);

+    ctx.beginPath(); ctx.moveTo(s*0.15, s*0.85); ctx.lineTo(s*0.82, s*0.18); ctx.stroke();

+    ctx.beginPath(); ctx.moveTo(s*0.82, s*0.18); ctx.lineTo(s*0.6, s*0.24); ctx.lineTo(s*0.72, s*0.36); ctx.closePath(); ctx.fill();

+    ctx.beginPath(); ctx.moveTo(s*0.15, s*0.85); ctx.lineTo(s*0.3, s*0.78); ctx.lineTo(s*0.22, s*0.66); ctx.closePath(); ctx.fill();

+    ctx.strokeStyle = '#a97c43'; ctx.lineWidth = s*0.15;

+    ctx.beginPath(); ctx.moveTo(s*0.28, s*0.8); ctx.lineTo(s*0.72, s*0.2); ctx.stroke();

+    ctx.strokeStyle = '#8a6239'; ctx.lineWidth = s*0.05;

+    ctx.beginPath(); ctx.moveTo(s*0.4, s*0.62); ctx.lineTo(s*0.5, s*0.5); ctx.stroke();

+    ctx.fillStyle = '#26282e'; blob(cx, cy, s*0.37);

+  } else if (id === 'iron_ingot' || id === 'gold_ingot'){

+    ctx.moveTo(cx, s*0.16); ctx.lineTo(s*0.82, cy); ctx.lineTo(cx, s*0.84); ctx.lineTo(s*0.18, cy);

+    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = 1;

+    ctx.beginPath(); ctx.moveTo(s*0.18, cy); ctx.lineTo(s*0.82, cy); ctx.moveTo(cx, s*0.16); ctx.lineTo(cx, s*0.84); ctx.stroke();

+  } else if (id === 'iron_ore' || id === 'gold_ore'){

+    ctx.fillStyle = '#7b8290'; blob(cx, cy, s*0.4);

+      ctx.beginPath(); ctx.arc(cx + dx*s, cy + dy*s, s*0.09, 0, 6.29); ctx.fill();

ctx.fillStyle = '#fff'; ctx.font = '700 12px system-ui'; ctx.textAlign = 'right'; ctx.textBaseline = 'alphabetic';


<total_tokens>14982423 tokens left</total_tokens>


1272	    ctx.globalAlpha = clamp(toastT, 0, 1);
1273	    ctx.fillStyle = '#000'; rr(VW/2 - 130, 70, 260, 34, 8); ctx.fill();
1274	    ctx.fillStyle = '#fff'; ctx.font = '600 14px system-ui'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
1275	    ctx.fillText(toastMsg, VW/2, 87);
1276	    ctx.globalAlpha = 1;
1277	  }
1278	}
1279	function punchLight(x, y, r){
1280	  const g = nctx.createRadialGradient(x, y, r * 0.15, x, y, r);
1281	  g.addColorStop(0, 'rgba(0,0,0,1)');
1282	  g.addColorStop(1, 'rgba(0,0,0,0)');
1283	  nctx.fillStyle = g;
1284	  nctx.beginPath(); nctx.arc(x, y, r, 0, 6.29); nctx.fill();
1285	}
1286
1287	function drawTile(tx, ty){
1288	  const id = getTile(tx, ty);
1289	  if (id === T.air) return;
1290	  const td = tget(id);
1291	  const x = tx * TILE - camX, y = ty * TILE - camY;
1292	  const shade = ((tx * 7 + ty * 13) % 3) - 1;
1293	  ctx.fillStyle = shade < 0 ? td.col2 : td.col;
1294	  if (td.glass){ ctx.globalAlpha = 0.4; ctx.fillRect(x, y, TILE, TILE); ctx.globalAlpha = 1;
1295	                 ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = 1; ctx.strokeRect(x+1, y+1, TILE-2, TILE-2); return; }
1296	  ctx.fillRect(x, y, TILE, TILE);
1297
1298	  if (id === T.grass){ ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, TILE, 4); }
1299	  if (td.ore){
1300	    ctx.fillStyle = td.ore;
1301	    for (let i = 0; i < 3; i++){
1302	      const ox = x + 6 + ((tx*13 + i*11) % 18), oy = y + 6 + ((ty*7 + i*17) % 18);
1303	      ctx.fillRect(ox, oy, 5, 5);
1304	    }
1305	  }
1306	  if (id === T.log){ ctx.fillStyle = 'rgba(0,0,0,.18)'; ctx.fillRect(x + TILE/2 - 3, y, 6, TILE); }
1307	  if (id === T.torch){
1308	    ctx.fillStyle = '#8a5f34'; ctx.fillRect(x + TILE/2 - 2, y + 10, 4, 16);
1309	    ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(x + TILE/2, y + 8, 5, 0, 6.29); ctx.fill();
1310	  }
1311	  if (id === T.door){ ctx.fillStyle = 'rgba(0,0,0,.25)'; ctx.strokeRect(x+4, y+2, TILE-8, TILE-4); ctx.fillRect(x + TILE - 12, y + TILE/2 - 2, 4, 4); }
1312	  if (id === T.furnace){ ctx.fillStyle = '#1a1a1f'; ctx.fillRect(x + 8, y + 14, TILE - 16, TILE - 20); }
1313	  if (id === T.table){ ctx.fillStyle = 'rgba(0,0,0,.2)'; ctx.fillRect(x + 4, y + 4, TILE - 8, 3); ctx.fillRect(x + 4, y + 4, 3, TILE - 8); }
1314	  if (id === T.bed){ ctx.fillStyle = '#fff'; ctx.fillRect(x + 3, y + 3, 10, TILE - 6); }
1315	  if (id === T.cave){
1316	    ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(x + TILE/2, y + TILE/2, 11, 13, 0, 0, 6.29); ctx.fill();
1317	    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center';
1318	    ctx.fillText('jeskyně', x + TILE/2, y - 2);
1319	  }
1320	  if (id === T.bush){ ctx.fillStyle = '#c7405e';
1321	    for (let i=0;i<3;i++) ctx.fillRect(x + 6 + i*8, y + 10 + ((tx+i)%2)*6, 4, 4); }

    ctx.globalAlpha = clamp(toastT, 0, 1);
    ctx.fillStyle = '#000'; rr(VW/2 - 130, 70, 260, 34, 8); ctx.fill();
    ctx.fillStyle = '#fff'; ctx.font = '600 14px system-ui'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
    ctx.fillText(toastMsg, VW/2, 87);
    ctx.globalAlpha = 1;
  }
}
function punchLight(x, y, r){
  const g = nctx.createRadialGradient(x, y, r * 0.15, x, y, r);
  g.addColorStop(0, 'rgba(0,0,0,1)');
  g.addColorStop(1, 'rgba(0,0,0,0)');
  nctx.fillStyle = g;
  nctx.beginPath(); nctx.arc(x, y, r, 0, 6.29); nctx.fill();
}

function drawTile(tx, ty){
  const id = getTile(tx, ty);
  if (id === T.air) return;
  const td = tget(id);
  const x = tx * TILE - camX, y = ty * TILE - camY;
  const shade = ((tx * 7 + ty * 13) % 3) - 1;
  ctx.fillStyle = shade < 0 ? td.col2 : td.col;
  if (td.glass){ ctx.globalAlpha = 0.4; ctx.fillRect(x, y, TILE, TILE); ctx.globalAlpha = 1;
                 ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = 1; ctx.strokeRect(x+1, y+1, TILE-2, TILE-2); return; }
  ctx.fillRect(x, y, TILE, TILE);

  if (id === T.grass){ ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, TILE, 4); }
  if (td.ore){
    ctx.fillStyle = td.ore;
    for (let i = 0; i < 3; i++){
      const ox = x + 6 + ((tx*13 + i*11) % 18), oy = y + 6 + ((ty*7 + i*17) % 18);
      ctx.fillRect(ox, oy, 5, 5);
    }
  }
  if (id === T.log){ ctx.fillStyle = 'rgba(0,0,0,.18)'; ctx.fillRect(x + TILE/2 - 3, y, 6, TILE); }
  if (id === T.torch){
    ctx.fillStyle = '#8a5f34'; ctx.fillRect(x + TILE/2 - 2, y + 10, 4, 16);
    ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(x + TILE/2, y + 8, 5, 0, 6.29); ctx.fill();
  }
  if (id === T.door){ ctx.fillStyle = 'rgba(0,0,0,.25)'; ctx.strokeRect(x+4, y+2, TILE-8, TILE-4); ctx.fillRect(x + TILE - 12, y + TILE/2 - 2, 4, 4); }
  if (id === T.furnace){ ctx.fillStyle = '#1a1a1f'; ctx.fillRect(x + 8, y + 14, TILE - 16, TILE - 20); }
  if (id === T.table){ ctx.fillStyle = 'rgba(0,0,0,.2)'; ctx.fillRect(x + 4, y + 4, TILE - 8, 3); ctx.fillRect(x + 4, y + 4, 3, TILE - 8); }
  if (id === T.bed){ ctx.fillStyle = '#fff'; ctx.fillRect(x + 3, y + 3, 10, TILE - 6); }
  if (id === T.cave){
    ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(x + TILE/2, y + TILE/2, 11, 13, 0, 0, 6.29); ctx.fill();
    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center';
    ctx.fillText('jeskyně', x + TILE/2, y - 2);
  }
  if (id === T.bush){ ctx.fillStyle = '#c7405e';
    for (let i=0;i<3;i++) ctx.fillRect(x + 6 + i*8, y + 10 + ((tx+i)%2)*6, 4, 4); }


<total_tokens>14982129 tokens left</total_tokens>


1321	    for (let i=0;i<3;i++) ctx.fillRect(x + 6 + i*8, y + 10 + ((tx+i)%2)*6, 4, 4); }
1322	  if (id === T.sapling){ ctx.fillStyle = '#6b4a2c'; ctx.fillRect(x + TILE/2 - 1, y + TILE/2, 3, TILE/2);
1323	    ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(x + TILE/2, y + TILE/2, 5, 0, 6.29); ctx.fill(); }
1324	}
1325
1326	function drawPlayer(){
1327	  const x = player.x - camX, y = player.y - camY;
1328	  if (player.hurtT > 0 && Math.floor(player.hurtT * 20) % 2) ctx.globalAlpha = 0.4;
1329	  ctx.fillStyle = '#f2d3a8';
1330	  rr(x - player.w/2, y - player.h/2, player.w, player.h, 5); ctx.fill();

    for (let i=0;i<3;i++) ctx.fillRect(x + 6 + i*8, y + 10 + ((tx+i)%2)*6, 4, 4); }
  if (id === T.sapling){ ctx.fillStyle = '#6b4a2c'; ctx.fillRect(x + TILE/2 - 1, y + TILE/2, 3, TILE/2);
    ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(x + TILE/2, y + TILE/2, 5, 0, 6.29); ctx.fill(); }
}

function drawPlayer(){
  const x = player.x - camX, y = player.y - camY;
  if (player.hurtT > 0 && Math.floor(player.hurtT * 20) % 2) ctx.globalAlpha = 0.4;
  ctx.fillStyle = '#f2d3a8';
  rr(x - player.w/2, y - player.h/2, player.w, player.h, 5); ctx.fill();


<total_tokens>14980222 tokens left</total_tokens>


function drawTile(tx, ty){
  const id = getTile(tx, ty);
  if (id === T.air) return;
  const td = tget(id);
  const x = tx * TILE - camX, y = ty * TILE - camY;
  const shade = ((tx * 7 + ty * 13) % 3) - 1;
  ctx.fillStyle = shade < 0 ? td.col2 : td.col;
  if (td.glass){ ctx.globalAlpha = 0.4; ctx.fillRect(x, y, TILE, TILE); ctx.globalAlpha = 1;
                 ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = 1; ctx.strokeRect(x+1, y+1, TILE-2, TILE-2); return; }
  ctx.fillRect(x, y, TILE, TILE);

  if (id === T.grass){ ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, TILE, 4); }
  if (td.ore){
    ctx.fillStyle = td.ore;
    for (let i = 0; i < 3; i++){
      const ox = x + 6 + ((tx*13 + i*11) % 18), oy = y + 6 + ((ty*7 + i*17) % 18);
      ctx.fillRect(ox, oy, 5, 5);
    }
  }
  if (id === T.log){ ctx.fillStyle = 'rgba(0,0,0,.18)'; ctx.fillRect(x + TILE/2 - 3, y, 6, TILE); }
  if (id === T.torch){
    ctx.fillStyle = '#8a5f34'; ctx.fillRect(x + TILE/2 - 2, y + 10, 4, 16);
    ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(x + TILE/2, y + 8, 5, 0, 6.29); ctx.fill();
  }
  if (id === T.door){ ctx.fillStyle = 'rgba(0,0,0,.25)'; ctx.strokeRect(x+4, y+2, TILE-8, TILE-4); ctx.fillRect(x + TILE - 12, y + TILE/2 - 2, 4, 4); }
  if (id === T.furnace){ ctx.fillStyle = '#1a1a1f'; ctx.fillRect(x + 8, y + 14, TILE - 16, TILE - 20); }
  if (id === T.table){ ctx.fillStyle = 'rgba(0,0,0,.2)'; ctx.fillRect(x + 4, y + 4, TILE - 8, 3); ctx.fillRect(x + 4, y + 4, 3, TILE - 8); }
  if (id === T.bed){ ctx.fillStyle = '#fff'; ctx.fillRect(x + 3, y + 3, 10, TILE - 6); }
  if (id === T.cave){
    ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(x + TILE/2, y + TILE/2, 11, 13, 0, 0, 6.29); ctx.fill();
    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center';
    ctx.fillText('jeskyně', x + TILE/2, y - 2);
  }
  if (id === T.bush){ ctx.fillStyle = '#c7405e';
    for (let i=0;i<3;i++) ctx.fillRect(x + 6 + i*8, y + 10 + ((tx+i)%2)*6, 4, 4); }
  if (id === T.sapling){ ctx.fillStyle = '#6b4a2c'; ctx.fillRect(x + TILE/2 - 1, y + TILE/2, 3, TILE/2);
    ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(x + TILE/2, y + TILE/2, 5, 0, 6.29); ctx.fill(); }
}

function drawTile(tx, ty){
  const id = getTile(tx, ty);
  if (id === T.air) return;
  const x = tx * TILE - camX, y = ty * TILE - camY;
  paintTile(x, y, TILE, id);
  if (((tx + ty) & 1) && id !== T.glass && id !== T.cave && id !== T.water){
    ctx.fillStyle = 'rgba(0,0,0,.06)'; ctx.fillRect(x, y, TILE, TILE);
  }
  if (id === T.cave){
    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
    ctx.fillText('jeskyně', x + TILE/2, y - 2);
  }
}

/* Jedno místo pro vzhled každé dlaždice – používá svět i ikony v batohu. */
function paintTile(x, y, sz, id){
  const td = tget(id); if (!td || id === T.air) return;
  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
  const P = (a) => x + a * k, Q = (b) => y + b * k;

  if (id === T.glass){
    ctx.clearRect(x, y, sz, sz);
    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);
    ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = Math.max(1, 2*k); ctx.strokeRect(x+1, y+1, sz-2, sz-2);
    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = Math.max(1, 1.5*k);
    ctx.beginPath(); ctx.moveTo(P(6), Q(22)); ctx.lineTo(P(20), Q(6)); ctx.stroke();
    return;
  }

  ctx.fillStyle = base; ctx.fillRect(x, y, sz, sz);

  switch (id){
    case T.grass:
      ctx.fillStyle = dark;
      for (let i = 0; i < 8; i++){ const gx = P((i * 4.1) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (3 + (i % 3) * 3) * k); }
      ctx.fillStyle = '#5aa64b';
      for (let i = 0; i < 6; i++){ const gx = P((i * 5.7 + 2) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (2 + (i % 2) * 3) * k); }
      ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, sz, 3*k);
      break;
    case T.dirt:
      ctx.fillStyle = dark;
      for (const [a,b] of [[3,4],[14,7],[22,3],[7,17],[19,20],[26,13]]) ctx.fillRect(P(a), Q(b), 3.5*k, 3.5*k);
      ctx.fillStyle = '#5c3f25';
      for (const [a,b] of [[9,9],[24,24],[17,13]]) ctx.fillRect(P(a), Q(b), 2*k, 2*k);
      break;
    case T.sand:
      ctx.fillStyle = dark;
      for (let i = 0; i < 16; i++) ctx.fillRect(P((i * 7) % 30), Q((i * 11) % 30), 2*k, 2*k);
      break;
    case T.water: {
      ctx.fillStyle = dark;
      const ph = now() * 1.6;
      for (let r = 0; r < 3; r++){
        const wy = Q(6 + r * 10 + Math.sin(ph + r * 1.3) * 2);
        ctx.fillRect(x, wy, sz, 2*k);
      }
      ctx.fillStyle = 'rgba(255,255,255,.12)';
      ctx.fillRect(x, Q(3 + Math.sin(ph) * 1.5), sz, 1.5*k);
      break;
    }
    case T.stone: case T.cobble: case T.coal: case T.iron: case T.gold: case T.diamond: case T.furnace:
      ctx.strokeStyle = 'rgba(0,0,0,.22)'; ctx.lineWidth = Math.max(1, 1.4*k);
      ctx.beginPath();
      ctx.moveTo(x, Q(11)); ctx.lineTo(P(13), Q(11)); ctx.lineTo(P(18), Q(23)); ctx.lineTo(x + sz, Q(23));
      ctx.moveTo(P(13), Q(11)); ctx.lineTo(P(16), y);
      ctx.moveTo(P(18), Q(23)); ctx.lineTo(P(16), y + sz);
      ctx.stroke();
      if (id === T.cobble){
        ctx.fillStyle = 'rgba(0,0,0,.16)';
        for (const [a,b,w,h] of [[2,2,12,10],[16,3,13,8],[3,14,10,15],[15,13,14,16]])
          ctx.fillRect(P(a), Q(b), w*k, h*k);
      }
      if (td.ore){
        for (const [a,b] of [[8,9],[21,7],[13,21],[24,19]]){
          ctx.fillStyle = td.ore;
          ctx.beginPath(); ctx.arc(P(a), Q(b), 3.4*k, 0, 6.29); ctx.fill();
          ctx.fillStyle = 'rgba(255,255,255,.45)'; ctx.fillRect(P(a) - 1.2*k, Q(b) - 1.2*k, 1.6*k, 1.6*k);
        }
      }
      if (id === T.furnace){
        ctx.fillStyle = '#17181c'; ctx.fillRect(P(8), Q(13), sz - 16*k, sz - 20*k);
        ctx.fillStyle = '#ff8a3c'; ctx.fillRect(P(11), Q(20), sz - 22*k, 6*k);
      }
      break;
    case T.log:
      ctx.fillStyle = dark;
      ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * 0.42, 0, 6.29); ctx.fill();
      ctx.strokeStyle = '#4a3420'; ctx.lineWidth = Math.max(1, 1.3*k);
      for (const rad of [0.32, 0.22, 0.12]){ ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * rad, 0, 6.29); ctx.stroke(); }
      ctx.fillStyle = '#4a3420'; ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * 0.04, 0, 6.29); ctx.fill();
      break;
    case T.planks: case T.table: case T.door:
      ctx.fillStyle = dark;
      for (let i = 1; i < 3; i++) ctx.fillRect(x, y + i * sz/3, sz, Math.max(1, 1.4*k));
      ctx.fillStyle = 'rgba(0,0,0,.22)';
      for (const [a,b] of [[6,5],[22,5],[14,16],[26,16],[6,27],[20,27]]) ctx.fillRect(P(a), Q(b), 2*k, 2*k);
      if (id === T.table){
        ctx.strokeStyle = '#5c3f25'; ctx.lineWidth = Math.max(1, 2*k);
        ctx.strokeRect(P(2), Q(2), sz - 4*k, sz - 4*k);
        ctx.beginPath();
        ctx.moveTo(x + sz/2, Q(2)); ctx.lineTo(x + sz/2, y + sz - 2*k);
        ctx.moveTo(P(2), y + sz/2); ctx.lineTo(x + sz - 2*k, y + sz/2); ctx.stroke();
      }
      if (id === T.door){
        ctx.strokeStyle = 'rgba(0,0,0,.35)'; ctx.lineWidth = Math.max(1, 2*k);
        ctx.strokeRect(P(5), Q(2), sz - 10*k, sz - 4*k);
        ctx.fillStyle = '#3a2a18'; ctx.beginPath(); ctx.arc(P(23), y + sz/2, 2.5*k, 0, 6.29); ctx.fill();
      }
      break;
    case T.leaves: case T.bush:
      ctx.fillStyle = dark;
      for (const [a,b,r] of [[9,9,7],[21,10,6],[10,22,6],[22,22,7],[16,16,6]]){
        ctx.beginPath(); ctx.arc(P(a), Q(b), r*k, 0, 6.29); ctx.fill();
      }
      ctx.fillStyle = 'rgba(255,255,255,.08)';
      for (const [a,b] of [[9,9],[22,22]]){ ctx.beginPath(); ctx.arc(P(a), Q(b), 2.4*k, 0, 6.29); ctx.fill(); }
      if (id === T.bush){
        ctx.fillStyle = '#d43f5e';
        for (const [a,b] of [[11,14],[19,20],[23,11]]){ ctx.beginPath(); ctx.arc(P(a), Q(b), 2.6*k, 0, 6.29); ctx.fill(); }
      }
      break;
    case T.torch: {
      ctx.fillStyle = '#7a5430'; ctx.fillRect(P(14), Q(12), 4*k, 18*k);
      const fl = 0.85 + Math.sin(now() * 12) * 0.15;
      ctx.fillStyle = '#ff8a3c'; ctx.beginPath(); ctx.arc(P(16), Q(10), 5.5*k * fl, 0, 6.29); ctx.fill();
      ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(P(16), Q(10), 3*k * fl, 0, 6.29); ctx.fill();
      break;
    }
    case T.bed:
      ctx.fillStyle = '#c74d61'; ctx.fillRect(P(3), Q(3), sz - 6*k, sz - 6*k);
      ctx.fillStyle = '#f4f0e8'; ctx.fillRect(P(5), Q(5), sz - 10*k, 9*k);
      ctx.fillStyle = '#a83c4f'; ctx.fillRect(P(5), Q(16), sz - 10*k, sz - 21*k);
      break;
    case T.sapling:
      ctx.fillStyle = '#6b4a2c'; ctx.fillRect(P(15), Q(16), 3*k, 12*k);
      ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(P(16), Q(14), 6*k, 0, 6.29); ctx.fill();
      break;
    case T.cave:
      ctx.fillStyle = '#0c0910'; ctx.fillRect(x, y, sz, sz);
      ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(x + sz/2, y + sz * 0.56, sz * 0.32, sz * 0.4, 0, 0, 6.29); ctx.fill();
      ctx.fillStyle = '#2f2838';
      for (let i = 0; i < 4; i++) ctx.fillRect(P((i * 9) % 28), y, 3*k, (4 + i * 3) * k);
      break;
  }
}

/* Ikony nástrojů a zbraní – barva = tier (dřevo/kámen/železo/diamant). */
function drawToolIcon(id, it, s){
  const col = it.col || '#ccc';
  if (it.ranged === 'bow'){
    ctx.strokeStyle = '#a97c43'; ctx.lineWidth = Math.max(2, s * 0.13);
    ctx.beginPath(); ctx.arc(s * 0.32, s * 0.5, s * 0.42, -1.15, 1.15); ctx.stroke();
    ctx.strokeStyle = '#f0f0f0'; ctx.lineWidth = Math.max(1, s * 0.05);
    ctx.beginPath();
    ctx.moveTo(s * 0.32 + Math.cos(-1.15) * s * 0.42, s * 0.5 + Math.sin(-1.15) * s * 0.42);
    ctx.lineTo(s * 0.32 + Math.cos(1.15) * s * 0.42, s * 0.5 + Math.sin(1.15) * s * 0.42);
    ctx.stroke();
    return;
  }
  if (it.ranged === 'crossbow'){
    ctx.strokeStyle = '#8a5f34'; ctx.lineWidth = Math.max(2, s * 0.1);
    ctx.beginPath(); ctx.arc(s * 0.5, s * 0.38, s * 0.34, 0.25, Math.PI - 0.25); ctx.stroke();
    ctx.strokeStyle = '#5c3f25'; ctx.lineWidth = Math.max(2, s * 0.12);
    ctx.beginPath(); ctx.moveTo(s * 0.5, s * 0.2); ctx.lineTo(s * 0.5, s * 0.86); ctx.stroke();
    ctx.strokeStyle = '#f0f0f0'; ctx.lineWidth = Math.max(1, s * 0.05);
    ctx.beginPath(); ctx.moveTo(s * 0.17, s * 0.45); ctx.lineTo(s * 0.83, s * 0.45); ctx.stroke();
    return;
  }
  // násada
  ctx.strokeStyle = '#8a6239'; ctx.lineWidth = Math.max(2, s * 0.11);
  ctx.beginPath(); ctx.moveTo(s * 0.28, s * 0.84); ctx.lineTo(s * 0.6, s * 0.36); ctx.stroke();
  ctx.fillStyle = col;
  if (it.tool === 'pick'){
    ctx.beginPath();
    ctx.moveTo(s * 0.36, s * 0.22);
    ctx.quadraticCurveTo(s * 0.6, s * 0.06, s * 0.88, s * 0.2);
    ctx.lineTo(s * 0.82, s * 0.32);
    ctx.quadraticCurveTo(s * 0.6, s * 0.2, s * 0.5, s * 0.3);
    ctx.quadraticCurveTo(s * 0.42, s * 0.24, s * 0.32, s * 0.3);
    ctx.closePath(); ctx.fill();
  } else if (it.tool === 'axe'){
    ctx.beginPath();
    ctx.moveTo(s * 0.55, s * 0.14);
    ctx.quadraticCurveTo(s * 0.9, s * 0.2, s * 0.82, s * 0.5);
    ctx.quadraticCurveTo(s * 0.6, s * 0.42, s * 0.48, s * 0.32);
    ctx.closePath(); ctx.fill();
  } else { // meč
    ctx.strokeStyle = col; ctx.lineWidth = Math.max(2, s * 0.15);
    ctx.beginPath(); ctx.moveTo(s * 0.28, s * 0.82); ctx.lineTo(s * 0.78, s * 0.2); ctx.stroke();
    ctx.strokeStyle = '#6b4a2c'; ctx.lineWidth = Math.max(2, s * 0.12);
    ctx.beginPath(); ctx.moveTo(s * 0.2, s * 0.64); ctx.lineTo(s * 0.44, s * 0.88); ctx.stroke();
  }
}


function drawTile(tx, ty){
  const id = getTile(tx, ty);
  if (id === T.air) return;
  const td = tget(id);
  const x = tx * TILE - camX, y = ty * TILE - camY;
  const shade = ((tx * 7 + ty * 13) % 3) - 1;
  ctx.fillStyle = shade < 0 ? td.col2 : td.col;
  if (td.glass){ ctx.globalAlpha = 0.4; ctx.fillRect(x, y, TILE, TILE); ctx.globalAlpha = 1;
                 ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = 1; ctx.strokeRect(x+1, y+1, TILE-2, TILE-2); return; }
  ctx.fillRect(x, y, TILE, TILE);

  if (id === T.grass){ ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, TILE, 4); }
  if (td.ore){
    ctx.fillStyle = td.ore;
    for (let i = 0; i < 3; i++){
      const ox = x + 6 + ((tx*13 + i*11) % 18), oy = y + 6 + ((ty*7 + i*17) % 18);
      ctx.fillRect(ox, oy, 5, 5);
    }
  }
  if (id === T.log){ ctx.fillStyle = 'rgba(0,0,0,.18)'; ctx.fillRect(x + TILE/2 - 3, y, 6, TILE); }
  if (id === T.torch){
    ctx.fillStyle = '#8a5f34'; ctx.fillRect(x + TILE/2 - 2, y + 10, 4, 16);
    ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(x + TILE/2, y + 8, 5, 0, 6.29); ctx.fill();
  }
  if (id === T.door){ ctx.fillStyle = 'rgba(0,0,0,.25)'; ctx.strokeRect(x+4, y+2, TILE-8, TILE-4); ctx.fillRect(x + TILE - 12, y + TILE/2 - 2, 4, 4); }
  if (id === T.furnace){ ctx.fillStyle = '#1a1a1f'; ctx.fillRect(x + 8, y + 14, TILE - 16, TILE - 20); }
  if (id === T.table){ ctx.fillStyle = 'rgba(0,0,0,.2)'; ctx.fillRect(x + 4, y + 4, TILE - 8, 3); ctx.fillRect(x + 4, y + 4, 3, TILE - 8); }
  if (id === T.bed){ ctx.fillStyle = '#fff'; ctx.fillRect(x + 3, y + 3, 10, TILE - 6); }
  if (id === T.cave){
    ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(x + TILE/2, y + TILE/2, 11, 13, 0, 0, 6.29); ctx.fill();
    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center';
    ctx.fillText('jeskyně', x + TILE/2, y - 2);
  }
  if (id === T.bush){ ctx.fillStyle = '#c7405e';
    for (let i=0;i<3;i++) ctx.fillRect(x + 6 + i*8, y + 10 + ((tx+i)%2)*6, 4, 4); }
  if (id === T.sapling){ ctx.fillStyle = '#6b4a2c'; ctx.fillRect(x + TILE/2 - 1, y + TILE/2, 3, TILE/2);
    ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(x + TILE/2, y + TILE/2, 5, 0, 6.29); ctx.fill(); }
}

function drawTile(tx, ty){
  const id = getTile(tx, ty);
  if (id === T.air) return;
  const x = tx * TILE - camX, y = ty * TILE - camY;
  paintTile(x, y, TILE, id);
  if (((tx + ty) & 1) && id !== T.glass && id !== T.cave && id !== T.water){
    ctx.fillStyle = 'rgba(0,0,0,.06)'; ctx.fillRect(x, y, TILE, TILE);
  }
  if (id === T.cave){
    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
    ctx.fillText('jeskyně', x + TILE/2, y - 2);
  }
}

/* Jedno místo pro vzhled každé dlaždice – používá svět i ikony v batohu. */
function paintTile(x, y, sz, id){
  const td = tget(id); if (!td || id === T.air) return;
  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
  const P = (a) => x + a * k, Q = (b) => y + b * k;

  if (id === T.glass){
    ctx.clearRect(x, y, sz, sz);
    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);
    ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = Math.max(1, 2*k); ctx.strokeRect(x+1, y+1, sz-2, sz-2);
    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = Math.max(1, 1.5*k);
    ctx.beginPath(); ctx.moveTo(P(6), Q(22)); ctx.lineTo(P(20), Q(6)); ctx.stroke();
    return;
  }

  ctx.fillStyle = base; ctx.fillRect(x, y, sz, sz);

  switch (id){
    case T.grass:
      ctx.fillStyle = dark;
      for (let i = 0; i < 8; i++){ const gx = P((i * 4.1) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (3 + (i % 3) * 3) * k); }
      ctx.fillStyle = '#5aa64b';
      for (let i = 0; i < 6; i++){ const gx = P((i * 5.7 + 2) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (2 + (i % 2) * 3) * k); }
      ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, sz, 3*k);
      break;
    case T.dirt:
      ctx.fillStyle = dark;
      for (const [a,b] of [[3,4],[14,7],[22,3],[7,17],[19,20],[26,13]]) ctx.fillRect(P(a), Q(b), 3.5*k, 3.5*k);
      ctx.fillStyle = '#5c3f25';
      for (const [a,b] of [[9,9],[24,24],[17,13]]) ctx.fillRect(P(a), Q(b), 2*k, 2*k);
      break;
    case T.sand:
      ctx.fillStyle = dark;
      for (let i = 0; i < 16; i++) ctx.fillRect(P((i * 7) % 30), Q((i * 11) % 30), 2*k, 2*k);
      break;
    case T.water: {
      ctx.fillStyle = dark;
      const ph = now() * 1.6;
      for (let r = 0; r < 3; r++){
        const wy = Q(6 + r * 10 + Math.sin(ph + r * 1.3) * 2);
        ctx.fillRect(x, wy, sz, 2*k);
      }
      ctx.fillStyle = 'rgba(255,255,255,.12)';
      ctx.fillRect(x, Q(3 + Math.sin(ph) * 1.5), sz, 1.5*k);
      break;
    }
    case T.stone: case T.cobble: case T.coal: case T.iron: case T.gold: case T.diamond: case T.furnace:
      ctx.strokeStyle = 'rgba(0,0,0,.22)'; ctx.lineWidth = Math.max(1, 1.4*k);
      ctx.beginPath();
      ctx.moveTo(x, Q(11)); ctx.lineTo(P(13), Q(11)); ctx.lineTo(P(18), Q(23)); ctx.lineTo(x + sz, Q(23));
      ctx.moveTo(P(13), Q(11)); ctx.lineTo(P(16), y);
      ctx.moveTo(P(18), Q(23)); ctx.lineTo(P(16), y + sz);
      ctx.stroke();
      if (id === T.cobble){
        ctx.fillStyle = 'rgba(0,0,0,.16)';
        for (const [a,b,w,h] of [[2,2,12,10],[16,3,13,8],[3,14,10,15],[15,13,14,16]])
          ctx.fillRect(P(a), Q(b), w*k, h*k);
      }
      if (td.ore){
        for (const [a,b] of [[8,9],[21,7],[13,21],[24,19]]){
          ctx.fillStyle = td.ore;
          ctx.beginPath(); ctx.arc(P(a), Q(b), 3.4*k, 0, 6.29); ctx.fill();
          ctx.fillStyle = 'rgba(255,255,255,.45)'; ctx.fillRect(P(a) - 1.2*k, Q(b) - 1.2*k, 1.6*k, 1.6*k);
        }
      }
      if (id === T.furnace){
        ctx.fillStyle = '#17181c'; ctx.fillRect(P(8), Q(13), sz - 16*k, sz - 20*k);
        ctx.fillStyle = '#ff8a3c'; ctx.fillRect(P(11), Q(20), sz - 22*k, 6*k);
      }
      break;
    case T.log:
      ctx.fillStyle = dark;
      ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * 0.42, 0, 6.29); ctx.fill();
      ctx.strokeStyle = '#4a3420'; ctx.lineWidth = Math.max(1, 1.3*k);
      for (const rad of [0.32, 0.22, 0.12]){ ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * rad, 0, 6.29); ctx.stroke(); }
      ctx.fillStyle = '#4a3420'; ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * 0.04, 0, 6.29); ctx.fill();
      break;
    case T.planks: case T.table: case T.door:
      ctx.fillStyle = dark;
      for (let i = 1; i < 3; i++) ctx.fillRect(x, y + i * sz/3, sz, Math.max(1, 1.4*k));
      ctx.fillStyle = 'rgba(0,0,0,.22)';
      for (const [a,b] of [[6,5],[22,5],[14,16],[26,16],[6,27],[20,27]]) ctx.fillRect(P(a), Q(b), 2*k, 2*k);
      if (id === T.table){
        ctx.strokeStyle = '#5c3f25'; ctx.lineWidth = Math.max(1, 2*k);
        ctx.strokeRect(P(2), Q(2), sz - 4*k, sz - 4*k);
        ctx.beginPath();
        ctx.moveTo(x + sz/2, Q(2)); ctx.lineTo(x + sz/2, y + sz - 2*k);
        ctx.moveTo(P(2), y + sz/2); ctx.lineTo(x + sz - 2*k, y + sz/2); ctx.stroke();
      }
      if (id === T.door){
        ctx.strokeStyle = 'rgba(0,0,0,.35)'; ctx.lineWidth = Math.max(1, 2*k);
        ctx.strokeRect(P(5), Q(2), sz - 10*k, sz - 4*k);
        ctx.fillStyle = '#3a2a18'; ctx.beginPath(); ctx.arc(P(23), y + sz/2, 2.5*k, 0, 6.29); ctx.fill();
      }
      break;
    case T.leaves: case T.bush:
      ctx.fillStyle = dark;
      for (const [a,b,r] of [[9,9,7],[21,10,6],[10,22,6],[22,22,7],[16,16,6]]){
        ctx.beginPath(); ctx.arc(P(a), Q(b), r*k, 0, 6.29); ctx.fill();
      }
      ctx.fillStyle = 'rgba(255,255,255,.08)';
      for (const [a,b] of [[9,9],[22,22]]){ ctx.beginPath(); ctx.arc(P(a), Q(b), 2.4*k, 0, 6.29); ctx.fill(); }
      if (id === T.bush){
        ctx.fillStyle = '#d43f5e';
        for (const [a,b] of [[11,14],[19,20],[23,11]]){ ctx.beginPath(); ctx.arc(P(a), Q(b), 2.6*k, 0, 6.29); ctx.fill(); }
      }
      break;
    case T.torch: {
      ctx.fillStyle = '#7a5430'; ctx.fillRect(P(14), Q(12), 4*k, 18*k);
      const fl = 0.85 + Math.sin(now() * 12) * 0.15;
      ctx.fillStyle = '#ff8a3c'; ctx.beginPath(); ctx.arc(P(16), Q(10), 5.5*k * fl, 0, 6.29); ctx.fill();
      ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(P(16), Q(10), 3*k * fl, 0, 6.29); ctx.fill();
      break;
    }
    case T.bed:
      ctx.fillStyle = '#c74d61'; ctx.fillRect(P(3), Q(3), sz - 6*k, sz - 6*k);
      ctx.fillStyle = '#f4f0e8'; ctx.fillRect(P(5), Q(5), sz - 10*k, 9*k);
      ctx.fillStyle = '#a83c4f'; ctx.fillRect(P(5), Q(16), sz - 10*k, sz - 21*k);
      break;
    case T.sapling:
      ctx.fillStyle = '#6b4a2c'; ctx.fillRect(P(15), Q(16), 3*k, 12*k);
      ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(P(16), Q(14), 6*k, 0, 6.29); ctx.fill();
      break;
    case T.cave:
      ctx.fillStyle = '#0c0910'; ctx.fillRect(x, y, sz, sz);
      ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(x + sz/2, y + sz * 0.56, sz * 0.32, sz * 0.4, 0, 0, 6.29); ctx.fill();
      ctx.fillStyle = '#2f2838';
      for (let i = 0; i < 4; i++) ctx.fillRect(P((i * 9) % 28), y, 3*k, (4 + i * 3) * k);
      break;
  }
}

/* Ikony nástrojů a zbraní – barva = tier (dřevo/kámen/železo/diamant). */
function drawToolIcon(id, it, s){
  const col = it.col || '#ccc';
  if (it.ranged === 'bow'){
    ctx.strokeStyle = '#a97c43'; ctx.lineWidth = Math.max(2, s * 0.13);
    ctx.beginPath(); ctx.arc(s * 0.32, s * 0.5, s * 0.42, -1.15, 1.15); ctx.stroke();
    ctx.strokeStyle = '#f0f0f0'; ctx.lineWidth = Math.max(1, s * 0.05);
    ctx.beginPath();
    ctx.moveTo(s * 0.32 + Math.cos(-1.15) * s * 0.42, s * 0.5 + Math.sin(-1.15) * s * 0.42);
    ctx.lineTo(s * 0.32 + Math.cos(1.15) * s * 0.42, s * 0.5 + Math.sin(1.15) * s * 0.42);
    ctx.stroke();
    return;
  }
  if (it.ranged === 'crossbow'){
    ctx.strokeStyle = '#8a5f34'; ctx.lineWidth = Math.max(2, s * 0.1);
    ctx.beginPath(); ctx.arc(s * 0.5, s * 0.38, s * 0.34, 0.25, Math.PI - 0.25); ctx.stroke();
    ctx.strokeStyle = '#5c3f25'; ctx.lineWidth = Math.max(2, s * 0.12);
    ctx.beginPath(); ctx.moveTo(s * 0.5, s * 0.2); ctx.lineTo(s * 0.5, s * 0.86); ctx.stroke();
    ctx.strokeStyle = '#f0f0f0'; ctx.lineWidth = Math.max(1, s * 0.05);
    ctx.beginPath(); ctx.moveTo(s * 0.17, s * 0.45); ctx.lineTo(s * 0.83, s * 0.45); ctx.stroke();
    return;
  }
  // násada
  ctx.strokeStyle = '#8a6239'; ctx.lineWidth = Math.max(2, s * 0.11);
  ctx.beginPath(); ctx.moveTo(s * 0.28, s * 0.84); ctx.lineTo(s * 0.6, s * 0.36); ctx.stroke();
  ctx.fillStyle = col;
  if (it.tool === 'pick'){
    ctx.beginPath();
    ctx.moveTo(s * 0.36, s * 0.22);
    ctx.quadraticCurveTo(s * 0.6, s * 0.06, s * 0.88, s * 0.2);
    ctx.lineTo(s * 0.82, s * 0.32);
    ctx.quadraticCurveTo(s * 0.6, s * 0.2, s * 0.5, s * 0.3);
    ctx.quadraticCurveTo(s * 0.42, s * 0.24, s * 0.32, s * 0.3);
    ctx.closePath(); ctx.fill();
  } else if (it.tool === 'axe'){
    ctx.beginPath();
    ctx.moveTo(s * 0.55, s * 0.14);
    ctx.quadraticCurveTo(s * 0.9, s * 0.2, s * 0.82, s * 0.5);
    ctx.quadraticCurveTo(s * 0.6, s * 0.42, s * 0.48, s * 0.32);
    ctx.closePath(); ctx.fill();
  } else { // meč
    ctx.strokeStyle = col; ctx.lineWidth = Math.max(2, s * 0.15);
    ctx.beginPath(); ctx.moveTo(s * 0.28, s * 0.82); ctx.lineTo(s * 0.78, s * 0.2); ctx.stroke();
    ctx.strokeStyle = '#6b4a2c'; ctx.lineWidth = Math.max(2, s * 0.12);
    ctx.beginPath(); ctx.moveTo(s * 0.2, s * 0.64); ctx.lineTo(s * 0.44, s * 0.88); ctx.stroke();
  }
}

const x = tx * TILE - camX, y = ty * TILE - camY;

-  ctx.fillStyle = shade < 0 ? td.col2 : td.col;

-  if (td.glass){ ctx.globalAlpha = 0.4; ctx.fillRect(x, y, TILE, TILE); ctx.globalAlpha = 1;

-                 ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = 1; ctx.strokeRect(x+1, y+1, TILE-2, TILE-2); return; }

+  if (((tx + ty) & 1) && id !== T.glass && id !== T.cave && id !== T.water){

+    ctx.fillStyle = 'rgba(0,0,0,.06)'; ctx.fillRect(x, y, TILE, TILE);

+    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';

+    ctx.fillText('jeskyně', x + TILE/2, y - 2);

-  if (id === T.grass){ ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, TILE, 4); }

+/* Jedno místo pro vzhled každé dlaždice – používá svět i ikony v batohu. */

+  const td = tget(id); if (!td || id === T.air) return;

+  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;

+    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);

+    ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = Math.max(1, 2*k); ctx.strokeRect(x+1, y+1, sz-2, sz-2);

+    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = Math.max(1, 1.5*k);

+    ctx.beginPath(); ctx.moveTo(P(6), Q(22)); ctx.lineTo(P(20), Q(6)); ctx.stroke();

+  ctx.fillStyle = base; ctx.fillRect(x, y, sz, sz);

+      ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, sz, 3*k);

+      ctx.fillRect(x, Q(3 + Math.sin(ph) * 1.5), sz, 1.5*k);

+    case T.stone: case T.cobble: case T.coal: case T.iron: case T.gold: case T.diamond: case T.furnace:

+      ctx.strokeStyle = 'rgba(0,0,0,.22)'; ctx.lineWidth = Math.max(1, 1.4*k);

+      ctx.moveTo(x, Q(11)); ctx.lineTo(P(13), Q(11)); ctx.lineTo(P(18), Q(23)); ctx.lineTo(x + sz, Q(23));

+      ctx.moveTo(P(18), Q(23)); ctx.lineTo(P(16), y + sz);

+          ctx.fillRect(P(a), Q(b), w*k, h*k);

+          ctx.beginPath(); ctx.arc(P(a), Q(b), 3.4*k, 0, 6.29); ctx.fill();

+        ctx.fillStyle = '#ff8a3c'; ctx.fillRect(P(11), Q(20), sz - 22*k, 6*k);

+      ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * 0.42, 0, 6.29); ctx.fill();

+      ctx.strokeStyle = '#4a3420'; ctx.lineWidth = Math.max(1, 1.3*k);

+      for (const rad of [0.32, 0.22, 0.12]){ ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * rad, 0, 6.29); ctx.stroke(); }

+      ctx.fillStyle = '#4a3420'; ctx.beginPath(); ctx.arc(x + sz/2, y + sz/2, sz * 0.04, 0, 6.29); ctx.fill();

+    case T.planks: case T.table: case T.door:

+      for (let i = 1; i < 3; i++) ctx.fillRect(x, y + i * sz/3, sz, Math.max(1, 1.4*k));

+        ctx.strokeStyle = '#5c3f25'; ctx.lineWidth = Math.max(1, 2*k);

+        ctx.strokeRect(P(2), Q(2), sz - 4*k, sz - 4*k);

+        ctx.moveTo(x + sz/2, Q(2)); ctx.lineTo(x + sz/2, y + sz - 2*k);

+        ctx.moveTo(P(2), y + sz/2); ctx.lineTo(x + sz - 2*k, y + sz/2); ctx.stroke();

+        ctx.strokeStyle = 'rgba(0,0,0,.35)'; ctx.lineWidth = Math.max(1, 2*k);

+        ctx.strokeRect(P(5), Q(2), sz - 10*k, sz - 4*k);

+        ctx.fillStyle = '#3a2a18'; ctx.beginPath(); ctx.arc(P(23), y + sz/2, 2.5*k, 0, 6.29); ctx.fill();

+        ctx.beginPath(); ctx.arc(P(a), Q(b), r*k, 0, 6.29); ctx.fill();

+      ctx.fillStyle = '#ff8a3c'; ctx.beginPath(); ctx.arc(P(16), Q(10), 5.5*k * fl, 0, 6.29); ctx.fill();

+      ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(P(16), Q(10), 3*k * fl, 0, 6.29); ctx.fill();

+      ctx.fillStyle = '#c74d61'; ctx.fillRect(P(3), Q(3), sz - 6*k, sz - 6*k);

+      ctx.fillStyle = '#f4f0e8'; ctx.fillRect(P(5), Q(5), sz - 10*k, 9*k);

+      ctx.fillStyle = '#a83c4f'; ctx.fillRect(P(5), Q(16), sz - 10*k, sz - 21*k);

+      ctx.fillStyle = '#6b4a2c'; ctx.fillRect(P(15), Q(16), 3*k, 12*k);

+      ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(P(16), Q(14), 6*k, 0, 6.29); ctx.fill();

+      ctx.fillStyle = '#0c0910'; ctx.fillRect(x, y, sz, sz);

-  if (id === T.log){ ctx.fillStyle = 'rgba(0,0,0,.18)'; ctx.fillRect(x + TILE/2 - 3, y, 6, TILE); }

-    ctx.fillStyle = '#8a5f34'; ctx.fillRect(x + TILE/2 - 2, y + 10, 4, 16);

-    ctx.fillStyle = '#ffcf5c'; ctx.beginPath(); ctx.arc(x + TILE/2, y + 8, 5, 0, 6.29); ctx.fill();

+/* Ikony nástrojů a zbraní – barva = tier (dřevo/kámen/železo/diamant). */

+    ctx.strokeStyle = '#a97c43'; ctx.lineWidth = Math.max(2, s * 0.13);

+    ctx.strokeStyle = '#f0f0f0'; ctx.lineWidth = Math.max(1, s * 0.05);

-  if (id === T.door){ ctx.fillStyle = 'rgba(0,0,0,.25)'; ctx.strokeRect(x+4, y+2, TILE-8, TILE-4); ctx.fillRect(x + TILE - 12, y + TILE/2 - 2, 4, 4); }

-  if (id === T.furnace){ ctx.fillStyle = '#1a1a1f'; ctx.fillRect(x + 8, y + 14, TILE - 16, TILE - 20); }

-  if (id === T.table){ ctx.fillStyle = 'rgba(0,0,0,.2)'; ctx.fillRect(x + 4, y + 4, TILE - 8, 3); ctx.fillRect(x + 4, y + 4, 3, TILE - 8); }

-  if (id === T.bed){ ctx.fillStyle = '#fff'; ctx.fillRect(x + 3, y + 3, 10, TILE - 6); }

-    ctx.fillStyle = '#000'; ctx.beginPath(); ctx.ellipse(x + TILE/2, y + TILE/2, 11, 13, 0, 0, 6.29); ctx.fill();

-    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center';

-    ctx.fillText('jeskyně', x + TILE/2, y - 2);

+    ctx.strokeStyle = '#8a5f34'; ctx.lineWidth = Math.max(2, s * 0.1);

+    ctx.strokeStyle = '#5c3f25'; ctx.lineWidth = Math.max(2, s * 0.12);

+    ctx.beginPath(); ctx.moveTo(s * 0.5, s * 0.2); ctx.lineTo(s * 0.5, s * 0.86); ctx.stroke();

+    ctx.beginPath(); ctx.moveTo(s * 0.17, s * 0.45); ctx.lineTo(s * 0.83, s * 0.45); ctx.stroke();

-  if (id === T.bush){ ctx.fillStyle = '#c7405e';

-  if (id === T.sapling){ ctx.fillStyle = '#6b4a2c'; ctx.fillRect(x + TILE/2 - 1, y + TILE/2, 3, TILE/2);

-    ctx.fillStyle = '#5aa04a'; ctx.beginPath(); ctx.arc(x + TILE/2, y + TILE/2, 5, 0, 6.29); ctx.fill(); }

+  ctx.strokeStyle = '#8a6239'; ctx.lineWidth = Math.max(2, s * 0.11);

+  ctx.beginPath(); ctx.moveTo(s * 0.28, s * 0.84); ctx.lineTo(s * 0.6, s * 0.36); ctx.stroke();

+    ctx.strokeStyle = col; ctx.lineWidth = Math.max(2, s * 0.15);

+    ctx.beginPath(); ctx.moveTo(s * 0.28, s * 0.82); ctx.lineTo(s * 0.78, s * 0.2); ctx.stroke();

+    ctx.strokeStyle = '#6b4a2c'; ctx.lineWidth = Math.max(2, s * 0.12);

+    ctx.beginPath(); ctx.moveTo(s * 0.2, s * 0.64); ctx.lineTo(s * 0.44, s * 0.88); ctx.stroke();


<total_tokens>14972556 tokens left</total_tokens>


  } else if (it.place){
    paintTile(0, 0, s, it.place);
  } else if (id === 'apple'){

  } else if (it.place){
    paintTile(0, 0, s, it.place, true);
  } else if (id === 'apple'){


  } else if (it.place){
    paintTile(0, 0, s, it.place);
  } else if (id === 'apple'){

  } else if (it.place){
    paintTile(0, 0, s, it.place, true);
  } else if (id === 'apple'){

+    paintTile(0, 0, s, it.place, true);

ctx.fillStyle = '#e0463a'; ctx.beginPath(); ctx.arc(cx, cy + s*0.05, s*0.34, 0, 6.29); ctx.fill();

ctx.strokeStyle = '#6b4a2c'; ctx.lineWidth = Math.max(1.5, s*0.07);


<total_tokens>14971729 tokens left</total_tokens>


function paintTile(x, y, sz, id){
  const td = tget(id); if (!td || id === T.air) return;
  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
  const P = (a) => x + a * k, Q = (b) => y + b * k;

  if (id === T.glass){
    ctx.clearRect(x, y, sz, sz);
    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);

function paintTile(x, y, sz, id, icon){
  const td = tget(id); if (!td || id === T.air) return;
  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
  const P = (a) => x + a * k, Q = (b) => y + b * k;

  if (id === T.glass){
    if (!icon) ctx.clearRect(x, y, sz, sz);
    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);


function paintTile(x, y, sz, id){
  const td = tget(id); if (!td || id === T.air) return;
  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
  const P = (a) => x + a * k, Q = (b) => y + b * k;

  if (id === T.glass){
    ctx.clearRect(x, y, sz, sz);
    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);

function paintTile(x, y, sz, id, icon){
  const td = tget(id); if (!td || id === T.air) return;
  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
  const P = (a) => x + a * k, Q = (b) => y + b * k;

  if (id === T.glass){
    if (!icon) ctx.clearRect(x, y, sz, sz);
    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);

/* Jedno místo pro vzhled každé dlaždice – používá svět i ikony v batohu. */

+function paintTile(x, y, sz, id, icon){

+    if (!icon) ctx.clearRect(x, y, sz, sz);

ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = Math.max(1, 2*k); ctx.strokeRect(x+1, y+1, sz-2, sz-2);

ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = Math.max(1, 1.5*k);


<total_tokens>14971156 tokens left</total_tokens>


1296	    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
1297	    ctx.fillText('jeskyně', x + TILE/2, y - 2);
1298	  }
1299	}
1300
1301	/* Jedno místo pro vzhled každé dlaždice – používá svět i ikony v batohu. */
1302	function paintTile(x, y, sz, id, icon){
1303	  const td = tget(id); if (!td || id === T.air) return;
1304	  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
1305	  const P = (a) => x + a * k, Q = (b) => y + b * k;
1306
1307	  if (id === T.glass){
1308	    if (!icon) ctx.clearRect(x, y, sz, sz);
1309	    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);
1310	    ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = Math.max(1, 2*k); ctx.strokeRect(x+1, y+1, sz-2, sz-2);
1311	    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = Math.max(1, 1.5*k);
1312	    ctx.beginPath(); ctx.moveTo(P(6), Q(22)); ctx.lineTo(P(20), Q(6)); ctx.stroke();
1313	    return;
1314	  }
1315
1316	  ctx.fillStyle = base; ctx.fillRect(x, y, sz, sz);
1317
1318	  switch (id){
1319	    case T.grass:
1320	      ctx.fillStyle = dark;
1321	      for (let i = 0; i < 8; i++){ const gx = P((i * 4.1) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (3 + (i % 3) * 3) * k); }
1322	      ctx.fillStyle = '#5aa64b';
1323	      for (let i = 0; i < 6; i++){ const gx = P((i * 5.7 + 2) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (2 + (i % 2) * 3) * k); }
1324	      ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, sz, 3*k);
1325	      break;
1326	    case T.dirt:
1327	      ctx.fillStyle = dark;

    ctx.fillStyle = '#5cc8ff'; ctx.font = '9px system-ui'; ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
    ctx.fillText('jeskyně', x + TILE/2, y - 2);
  }
}

/* Jedno místo pro vzhled každé dlaždice – používá svět i ikony v batohu. */
function paintTile(x, y, sz, id, icon){
  const td = tget(id); if (!td || id === T.air) return;
  const k = sz / TILE, base = td.col, dark = td.col2 || td.col;
  const P = (a) => x + a * k, Q = (b) => y + b * k;

  if (id === T.glass){
    if (!icon) ctx.clearRect(x, y, sz, sz);
    ctx.fillStyle = 'rgba(191,230,255,.20)'; ctx.fillRect(x, y, sz, sz);
    ctx.strokeStyle = '#dff2ff'; ctx.lineWidth = Math.max(1, 2*k); ctx.strokeRect(x+1, y+1, sz-2, sz-2);
    ctx.strokeStyle = 'rgba(255,255,255,.55)'; ctx.lineWidth = Math.max(1, 1.5*k);
    ctx.beginPath(); ctx.moveTo(P(6), Q(22)); ctx.lineTo(P(20), Q(6)); ctx.stroke();
    return;
  }

  ctx.fillStyle = base; ctx.fillRect(x, y, sz, sz);

  switch (id){
    case T.grass:
      ctx.fillStyle = dark;
      for (let i = 0; i < 8; i++){ const gx = P((i * 4.1) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (3 + (i % 3) * 3) * k); }
      ctx.fillStyle = '#5aa64b';
      for (let i = 0; i < 6; i++){ const gx = P((i * 5.7 + 2) % 30); ctx.fillRect(gx, y, Math.max(1, 2*k), (2 + (i % 2) * 3) * k); }
      ctx.fillStyle = 'rgba(255,255,255,.05)'; ctx.fillRect(x, y, sz, 3*k);
      break;
    case T.dirt:
      ctx.fillStyle = dark;


<total_tokens>14970935 tokens left</total_tokens>


Bash

grep -n "function drawHUD\|kuše natažená\|by - 40\|natažená kuše\|// hodiny / den" /home/tonda/svet.html

Find drawHUD internals


1522:function drawHUD(){
1539:  // hodiny / den
1545:  // natažená kuše
1549:    ctx.fillText(xbowLoaded ? 'kuše natažená – klikni' : 'kuše: drž levé = natáhnout', VW/2, by - 40);


<total_tokens>14969819 tokens left</total_tokens>


1522	function drawHUD(){
1523	  // hotbar
1524	  const bw = 9 * 40, bx = (VW - bw) / 2, by = VH - 54;
1525	  for (let i = 0; i < 9; i++){
1526	    slot(bx + i * 40, by, inv[i], i === sel);
1527	  }
1528	  // srdíčka + hlad nad hotbarem
1529	  const hx = bx, hy = by - 24;
1530	  for (let i = 0; i < 10; i++){
1531	    ctx.fillStyle = '#3a1418'; heart(hx + i * 16, hy);
1532	    if (player.hp > i * 2){ ctx.fillStyle = player.hp >= (i + 1) * 2 ? '#e0463a' : '#e0463a99'; heart(hx + i * 16, hy); }
1533	  }
1534	  for (let i = 0; i < 10; i++){
1535	    const fx = bx + bw - 16 - i * 16;
1536	    ctx.fillStyle = '#2a2410'; drum(fx, hy);
1537	    if (player.hunger >= i + 1){ ctx.fillStyle = '#c8963c'; drum(fx, hy); }
1538	  }
1539	  // hodiny / den
1540	  ctx.fillStyle = 'rgba(0,0,0,.35)'; rr(12, 12, 128, 22, 6); ctx.fill();
1541	  ctx.fillStyle = '#e8ecf5'; ctx.font = '600 12px system-ui'; ctx.textAlign = 'left'; ctx.textBaseline = 'middle';
1542	  const night = dayT > 0.5 || dayT < 0.04;
1543	  ctx.fillText((night ? '🌙 Noc' : '☀ Den') + '  ·  seed ' + SEED, 20, 24);
1544
1545	  // natažená kuše
1546	  const s = held(); const it = s && iget(s.id);
1547	  if (it && it.ranged === 'crossbow'){
1548	    ctx.fillStyle = xbowLoaded ? '#4ade80' : '#8b93a7'; ctx.font = '600 12px system-ui'; ctx.textAlign = 'center';
1549	    ctx.fillText(xbowLoaded ? 'kuše natažená – klikni' : 'kuše: drž levé = natáhnout', VW/2, by - 40);
1550	  }
1551	}
1552	function heart(x, y){
1553	  ctx.beginPath();

function drawHUD(){
  // hotbar
  const bw = 9 * 40, bx = (VW - bw) / 2, by = VH - 54;
  for (let i = 0; i < 9; i++){
    slot(bx + i * 40, by, inv[i], i === sel);
  }
  // srdíčka + hlad nad hotbarem
  const hx = bx, hy = by - 24;
  for (let i = 0; i < 10; i++){
    ctx.fillStyle = '#3a1418'; heart(hx + i * 16, hy);
    if (player.hp > i * 2){ ctx.fillStyle = player.hp >= (i + 1) * 2 ? '#e0463a' : '#e0463a99'; heart(hx + i * 16, hy); }
  }
  for (let i = 0; i < 10; i++){
    const fx = bx + bw - 16 - i * 16;
    ctx.fillStyle = '#2a2410'; drum(fx, hy);
    if (player.hunger >= i + 1){ ctx.fillStyle = '#c8963c'; drum(fx, hy); }
  }
  // hodiny / den
  ctx.fillStyle = 'rgba(0,0,0,.35)'; rr(12, 12, 128, 22, 6); ctx.fill();
  ctx.fillStyle = '#e8ecf5'; ctx.font = '600 12px system-ui'; ctx.textAlign = 'left'; ctx.textBaseline = 'middle';
  const night = dayT > 0.5 || dayT < 0.04;
  ctx.fillText((night ? '🌙 Noc' : '☀ Den') + '  ·  seed ' + SEED, 20, 24);

  // natažená kuše
  const s = held(); const it = s && iget(s.id);
  if (it && it.ranged === 'crossbow'){
    ctx.fillStyle = xbowLoaded ? '#4ade80' : '#8b93a7'; ctx.font = '600 12px system-ui'; ctx.textAlign = 'center';
    ctx.fillText(xbowLoaded ? 'kuše natažená – klikni' : 'kuše: drž levé = natáhnout', VW/2, by - 40);
  }
}
function heart(x, y){
  ctx.beginPath();


<total_tokens>14969573 tokens left</total_tokens>


Edit

  // natažená kuše
  const s = held(); const it = s && iget(s.id);
  if (it && it.ranged === 'crossbow'){
    ctx.fillStyle = xbowLoaded ? '#4ade80' : '#8b93a7'; ctx.font = '600 12px system-ui'; ctx.textAlign = 'center';
    ctx.fillText(xbowLoaded ? 'kuše natažená – klikni' : 'kuše: drž levé = natáhnout', VW/2, by - 40);
  }
}

  // jméno drženého předmětu + nápověda
  const s = held(); const it = s && iget(s.id);
  ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
  if (s){
    const nm = it ? it.name : s.id;
    ctx.font = '600 13px system-ui';
    const tw = ctx.measureText(nm).width + 22;
    ctx.fillStyle = 'rgba(0,0,0,.5)'; rr(VW/2 - tw/2, by - 52, tw, 22, 6); ctx.fill();
    ctx.fillStyle = '#fff'; ctx.fillText(nm, VW/2, by - 37);

    let hint = '';
    if (it && it.food) hint = 'drž pravé tlačítko = sníst  (+' + it.food + ' hladu)';
    else if (it && it.ranged === 'bow') hint = 'drž levé = natáhnout luk, pusť = výstřel (potřebuješ šípy)';
    else if (it && it.ranged === 'crossbow') hint = xbowLoaded ? 'kuše natažená – klikni na cíl' : 'drž levé = natáhnout kuši';
    else if (it && it.tool === 'pick') hint = 'drž levé na kámen/rudu = těžit';
    else if (it && it.tool === 'axe') hint = 'drž levé na strom = kácet';
    else if (it && it.tool === 'sword') hint = 'klikni na nestvůru = útok';
    else if (it && it.place) hint = 'pravé tlačítko = položit';
    if (hint){
      ctx.font = '500 11px system-ui'; ctx.fillStyle = (it && it.food) ? '#9fd3a0' : '#9fb4d3';
      ctx.fillText(hint, VW/2, by - 58);
    }
    if (eatT > 0){
      ctx.fillStyle = 'rgba(0,0,0,.55)'; ctx.fillRect(VW/2 - 45, by - 74, 90, 6);
      ctx.fillStyle = '#c8963c'; ctx.fillRect(VW/2 - 45, by - 74, 90 * (eatT / 1.1), 6);
    }
  } else {
    ctx.font = '500 11px system-ui'; ctx.fillStyle = '#8b93a7';
    ctx.fillText('prázdná ruka – drž levé = kopat rukou (pomalé)', VW/2, by - 40);
  }
}


  // natažená kuše
  const s = held(); const it = s && iget(s.id);
  if (it && it.ranged === 'crossbow'){
    ctx.fillStyle = xbowLoaded ? '#4ade80' : '#8b93a7'; ctx.font = '600 12px system-ui'; ctx.textAlign = 'center';
    ctx.fillText(xbowLoaded ? 'kuše natažená – klikni' : 'kuše: drž levé = natáhnout', VW/2, by - 40);
  }
}

  // jméno drženého předmětu + nápověda
  const s = held(); const it = s && iget(s.id);
  ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
  if (s){
    const nm = it ? it.name : s.id;
    ctx.font = '600 13px system-ui';
    const tw = ctx.measureText(nm).width + 22;
    ctx.fillStyle = 'rgba(0,0,0,.5)'; rr(VW/2 - tw/2, by - 52, tw, 22, 6); ctx.fill();
    ctx.fillStyle = '#fff'; ctx.fillText(nm, VW/2, by - 37);

    let hint = '';
    if (it && it.food) hint = 'drž pravé tlačítko = sníst  (+' + it.food + ' hladu)';
    else if (it && it.ranged === 'bow') hint = 'drž levé = natáhnout luk, pusť = výstřel (potřebuješ šípy)';
    else if (it && it.ranged === 'crossbow') hint = xbowLoaded ? 'kuše natažená – klikni na cíl' : 'drž levé = natáhnout kuši';
    else if (it && it.tool === 'pick') hint = 'drž levé na kámen/rudu = těžit';
    else if (it && it.tool === 'axe') hint = 'drž levé na strom = kácet';
    else if (it && it.tool === 'sword') hint = 'klikni na nestvůru = útok';
    else if (it && it.place) hint = 'pravé tlačítko = položit';
    if (hint){
      ctx.font = '500 11px system-ui'; ctx.fillStyle = (it && it.food) ? '#9fd3a0' : '#9fb4d3';
      ctx.fillText(hint, VW/2, by - 58);
    }
    if (eatT > 0){
      ctx.fillStyle = 'rgba(0,0,0,.55)'; ctx.fillRect(VW/2 - 45, by - 74, 90, 6);
      ctx.fillStyle = '#c8963c'; ctx.fillRect(VW/2 - 45, by - 74, 90 * (eatT / 1.1), 6);
    }
  } else {
    ctx.font = '500 11px system-ui'; ctx.fillStyle = '#8b93a7';
    ctx.fillText('prázdná ruka – drž levé = kopat rukou (pomalé)', VW/2, by - 40);
  }
}

const night = dayT > 0.5 || dayT < 0.04;

ctx.fillText((night ? '🌙 Noc' : '☀ Den') + '  ·  seed ' + SEED, 20, 24);

+  // jméno drženého předmětu + nápověda

-    ctx.fillStyle = xbowLoaded ? '#4ade80' : '#8b93a7'; ctx.font = '600 12px system-ui'; ctx.textAlign = 'center';

-    ctx.fillText(xbowLoaded ? 'kuše natažená – klikni' : 'kuše: drž levé = natáhnout', VW/2, by - 40);

+  ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';

+    const tw = ctx.measureText(nm).width + 22;

+    ctx.fillStyle = '#fff'; ctx.fillText(nm, VW/2, by - 37);

+    if (it && it.food) hint = 'drž pravé tlačítko = sníst  (+' + it.food + ' hladu)';

+    else if (it && it.ranged === 'bow') hint = 'drž levé = natáhnout luk, pusť = výstřel (potřebuješ šípy)';

+    else if (it && it.ranged === 'crossbow') hint = xbowLoaded ? 'kuše natažená – klikni na cíl' : 'drž levé = natáhnout kuši';

+    else if (it && it.tool === 'pick') hint = 'drž levé na kámen/rudu = těžit';

+    else if (it && it.tool === 'axe') hint = 'drž levé na strom = kácet';

+    else if (it && it.tool === 'sword') hint = 'klikni na nestvůru = útok';

+    else if (it && it.place) hint = 'pravé tlačítko = položit';

+      ctx.font = '500 11px system-ui'; ctx.fillStyle = (it && it.food) ? '#9fd3a0' : '#9fb4d3';

+      ctx.fillText(hint, VW/2, by - 58);

+    ctx.font = '500 11px system-ui'; ctx.fillStyle = '#8b93a7';

+    ctx.fillText('prázdná ruka – drž levé = kopat rukou (pomalé)', VW/2, by - 40);


<total_tokens>14967474 tokens left</total_tokens>


Bash

grep -n "function drawUI\|function drawInvGrid\|uiRects.length = 0\|cursorStack) drawItemIcon" /home/tonda/svet.html

Find drawUI/drawInvGrid


965:function drawInvGrid(px, py){
1083:function drawUI(){
1084:  uiRects.length = 0;
1104:  if (cursorStack) drawItemIcon(cursorStack.id, mouse.x - 14, mouse.y - 14, 28, cursorStack.n, cursorStack.dur);


<total_tokens>14966849 tokens left</total_tokens>


965	function drawInvGrid(px, py){
966	  // 9 hotbar + 27 batoh
967	  for (let i = 0; i < 36; i++){
968	    const col = i % 9, row = Math.floor(i / 9);
969	    const gx = px + col * 40, gy = py + (row === 0 ? 0 : 12) + row * 40;
970	    slot(gx, gy, inv[i], i === sel && row === 0);
971	    const idx = i;
972	    uiRects.push({ x: gx, y: gy, w: 36, h: 36, fn: () => invSlotClick(idx) });
973	  }
974	}
975	let cursorStack = null;   // drag jeden stack
976	function invSlotClick(i){
977	  if (cursorStack){
978	    const s = inv[i];
979	    if (!s){ inv[i] = cursorStack; cursorStack = null; }
980	    else if (s.id === cursorStack.id){ s.n += cursorStack.n; cursorStack = null; }
981	    else { inv[i] = cursorStack; cursorStack = s; }
982	  } else if (inv[i]){ cursorStack = inv[i]; inv[i] = null; }

function drawInvGrid(px, py){
  // 9 hotbar + 27 batoh
  for (let i = 0; i < 36; i++){
    const col = i % 9, row = Math.floor(i / 9);
    const gx = px + col * 40, gy = py + (row === 0 ? 0 : 12) + row * 40;
    slot(gx, gy, inv[i], i === sel && row === 0);
    const idx = i;
    uiRects.push({ x: gx, y: gy, w: 36, h: 36, fn: () => invSlotClick(idx) });
  }
}
let cursorStack = null;   // drag jeden stack
function invSlotClick(i){
  if (cursorStack){
    const s = inv[i];
    if (!s){ inv[i] = cursorStack; cursorStack = null; }
    else if (s.id === cursorStack.id){ s.n += cursorStack.n; cursorStack = null; }
    else { inv[i] = cursorStack; cursorStack = s; }
  } else if (inv[i]){ cursorStack = inv[i]; inv[i] = null; }


<total_tokens>14966594 tokens left</total_tokens>


Edit

    slot(gx, gy, inv[i], i === sel && row === 0);
    const idx = i;
    uiRects.push({ x: gx, y: gy, w: 36, h: 36, fn: () => invSlotClick(idx) });

    slot(gx, gy, inv[i], i === sel && row === 0);
    const idx = i;
    if (inv[i] && mouse.x >= gx && mouse.x <= gx + 36 && mouse.y >= gy && mouse.y <= gy + 36)
      uiHover = (iget(inv[i].id) || {}).name || inv[i].id;
    uiRects.push({ x: gx, y: gy, w: 36, h: 36, fn: () => invSlotClick(idx) });


    slot(gx, gy, inv[i], i === sel && row === 0);
    const idx = i;
    uiRects.push({ x: gx, y: gy, w: 36, h: 36, fn: () => invSlotClick(idx) });

    slot(gx, gy, inv[i], i === sel && row === 0);
    const idx = i;
    if (inv[i] && mouse.x >= gx && mouse.x <= gx + 36 && mouse.y >= gy && mouse.y <= gy + 36)
      uiHover = (iget(inv[i].id) || {}).name || inv[i].id;
    uiRects.push({ x: gx, y: gy, w: 36, h: 36, fn: () => invSlotClick(idx) });

+    if (inv[i] && mouse.x >= gx && mouse.x <= gx + 36 && mouse.y >= gy && mouse.y <= gy + 36)

+      uiHover = (iget(inv[i].id) || {}).name || inv[i].id;


<total_tokens>14965768 tokens left</total_tokens>


1084
1085	function drawUI(){
1086	  uiRects.length = 0;
1087	  ctx.fillStyle = 'rgba(6,8,16,.72)'; ctx.fillRect(0, 0, VW, VH);
1088	  const p = panel();
1089	  ctx.fillStyle = '#12151f'; rr(p.x, p.y, p.w, p.h, 14); ctx.fill();
1090	  ctx.strokeStyle = 'rgba(255,255,255,.12)'; ctx.lineWidth = 2; rr(p.x, p.y, p.w, p.h, 14); ctx.stroke();
1091	  ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';
1092
1093	  ctx.fillStyle = '#e8ecf5'; ctx.font = '800 18px system-ui';
1094	  ctx.fillText(uiMode === 'furnace' ? 'PEC' : (nearTable() ? 'VÝROBA (u verpánku)' : 'BATOH + ZÁKLADNÍ VÝROBA'), p.x + 20, p.y + 30);
1095	  ctx.fillStyle = '#8b93a7'; ctx.font = '500 12px system-ui';
1096	  ctx.fillText('E / Esc zavřít  ·  klikni na předmět = vzít/položit', p.x + 20, p.y + 48);
1097
1098	  // batoh vlevo
1099	  drawInvGrid(p.x + 20, p.y + 66);
1100	  const invBottom = p.y + 66 + 12 + 4 * 40;
1101
1102	  if (uiMode === 'furnace') drawFurnaceUI(p, invBottom);
1103	  else drawCraftUI(p, invBottom);
1104
1105	  // kurzorový stack
1106	  if (cursorStack) drawItemIcon(cursorStack.id, mouse.x - 14, mouse.y - 14, 28, cursorStack.n, cursorStack.dur);
1107	}
1108	function drawCraftUI(p, top){
1109	  const listX = p.x + 20, listY = top + 16;

function drawUI(){
  uiRects.length = 0;
  ctx.fillStyle = 'rgba(6,8,16,.72)'; ctx.fillRect(0, 0, VW, VH);
  const p = panel();
  ctx.fillStyle = '#12151f'; rr(p.x, p.y, p.w, p.h, 14); ctx.fill();
  ctx.strokeStyle = 'rgba(255,255,255,.12)'; ctx.lineWidth = 2; rr(p.x, p.y, p.w, p.h, 14); ctx.stroke();
  ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';

  ctx.fillStyle = '#e8ecf5'; ctx.font = '800 18px system-ui';
  ctx.fillText(uiMode === 'furnace' ? 'PEC' : (nearTable() ? 'VÝROBA (u verpánku)' : 'BATOH + ZÁKLADNÍ VÝROBA'), p.x + 20, p.y + 30);
  ctx.fillStyle = '#8b93a7'; ctx.font = '500 12px system-ui';
  ctx.fillText('E / Esc zavřít  ·  klikni na předmět = vzít/položit', p.x + 20, p.y + 48);

  // batoh vlevo
  drawInvGrid(p.x + 20, p.y + 66);
  const invBottom = p.y + 66 + 12 + 4 * 40;

  if (uiMode === 'furnace') drawFurnaceUI(p, invBottom);
  else drawCraftUI(p, invBottom);

  // kurzorový stack
  if (cursorStack) drawItemIcon(cursorStack.id, mouse.x - 14, mouse.y - 14, 28, cursorStack.n, cursorStack.dur);
}
function drawCraftUI(p, top){
  const listX = p.x + 20, listY = top + 16;


<total_tokens>14965582 tokens left</total_tokens>


function drawUI(){
  uiRects.length = 0;
  ctx.fillStyle = 'rgba(6,8,16,.72)'; ctx.fillRect(0, 0, VW, VH);

let uiHover = null;
function drawUI(){
  uiRects.length = 0; uiHover = null;
  ctx.fillStyle = 'rgba(6,8,16,.72)'; ctx.fillRect(0, 0, VW, VH);


function drawUI(){
  uiRects.length = 0;
  ctx.fillStyle = 'rgba(6,8,16,.72)'; ctx.fillRect(0, 0, VW, VH);

let uiHover = null;
function drawUI(){
  uiRects.length = 0; uiHover = null;
  ctx.fillStyle = 'rgba(6,8,16,.72)'; ctx.fillRect(0, 0, VW, VH);

ctx.fillStyle = '#12151f'; rr(p.x, p.y, p.w, p.h, 14); ctx.fill();


<total_tokens>14964500 tokens left</total_tokens>


  // kurzorový stack
  if (cursorStack) drawItemIcon(cursorStack.id, mouse.x - 14, mouse.y - 14, 28, cursorStack.n, cursorStack.dur);
}

  // kurzorový stack
  if (cursorStack) drawItemIcon(cursorStack.id, mouse.x - 14, mouse.y - 14, 28, cursorStack.n, cursorStack.dur);

  // popisek předmětu pod myší
  if (uiHover && !cursorStack){
    ctx.font = '600 12px system-ui'; ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';
    const tw = ctx.measureText(uiHover).width + 14;
    ctx.fillStyle = 'rgba(0,0,0,.85)'; rr(mouse.x + 12, mouse.y + 6, tw, 20, 5); ctx.fill();
    ctx.fillStyle = '#fff'; ctx.fillText(uiHover, mouse.x + 19, mouse.y + 20);
  }
}


  // kurzorový stack
  if (cursorStack) drawItemIcon(cursorStack.id, mouse.x - 14, mouse.y - 14, 28, cursorStack.n, cursorStack.dur);
}

  // kurzorový stack
  if (cursorStack) drawItemIcon(cursorStack.id, mouse.x - 14, mouse.y - 14, 28, cursorStack.n, cursorStack.dur);

  // popisek předmětu pod myší
  if (uiHover && !cursorStack){
    ctx.font = '600 12px system-ui'; ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';
    const tw = ctx.measureText(uiHover).width + 14;
    ctx.fillStyle = 'rgba(0,0,0,.85)'; rr(mouse.x + 12, mouse.y + 6, tw, 20, 5); ctx.fill();
    ctx.fillStyle = '#fff'; ctx.fillText(uiHover, mouse.x + 19, mouse.y + 20);
  }
}

+    ctx.font = '600 12px system-ui'; ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';

+    const tw = ctx.measureText(uiHover).width + 14;

+    ctx.fillStyle = 'rgba(0,0,0,.85)'; rr(mouse.x + 12, mouse.y + 6, tw, 20, 5); ctx.fill();

+    ctx.fillStyle = '#fff'; ctx.fillText(uiHover, mouse.x + 19, mouse.y + 20);

const listX = p.x + 20, listY = top + 16;


<total_tokens>14963917 tokens left</total_tokens>


Bash

python3 - <<'EOF'
s=open('/home/tonda/svet.html').read()
js=s[s.index('<script>')+8:s.rindex('</script>')]
pairs={'(':')','[':']','{':'}'}
stack=[];instr=None;esc=False;line=1;i=0;incomment=None
while i<len(js):
    c=js[i]
    if c=='\n':line+=1
    if instr:
        if esc:esc=False
        elif c=='\\':esc=True
        elif c==instr:instr=None
        i+=1;continue
    if incomment=='line':
        if c=='\n':incomment=None
        i+=1;continue
    if incomment=='block':
        if c=='*' and js[i+1:i+2]=='/':incomment=None;i+=2;continue
        i+=1;continue
    if c=='/' and js[i+1:i+2]=='/':incomment='line';i+=2;continue
    if c=='/' and js[i+1:i+2]=='*':incomment='block';i+=2;continue
    if c in '"\'`':instr=c;i+=1;continue
    if c in pairs:stack.append((c,line))
    elif c in ')]}':
        if not stack:print('extra close',c,line);break
        o,ol=stack.pop()
        if pairs[o]!=c:print('mismatch',o,ol,'vs',c,line);break
    i+=1
print('unclosed:',stack if stack else 'none balanced')
print('bytes', len(s))
EOF
grep -n "T.log\b" /home/tonda/svet.html | head
curl -sf -o /dev/null -w "http %{http_code}\n" http://localhost:8000/svet.html

Bracket check + serve check


unclosed: none balanced
bytes 71787
162:  log:    { name:'Kláda',        place:T.log,    col:'#6b4a2c' },
259:  if (treeAnchor(x, y)) return T.log;
739:      setTile(g.x, g.y, T.log);
1382:    case T.log:
http 200


<total_tokens>14963137 tokens left</total_tokens>


Hotovo — **jen znovu načti stránku** (Ctrl+Shift+R kvůli cache): `http://192.168.5.32:8000/svet.html`

### Co je nové

**1. Vlastní textura pro každou věc**
- Bloky: tráva (stébla), hlína (hrudky), písek (zrna), kámen (praskliny), dlažba (kostky), kláda (letokruhy shora), prkna (fošny + hřebíky), listí/keř (chomáče, keř má bobule), rudy (barevná zrnka — uhlí černé, železo měděné, zlato žluté, diamant tyrkysové), sklo (průhledné s odleskem), pec (žhnoucí otvor), verpánek (mřížka), dveře, postel, pochodeň (plápolá), voda (vlnky).
- Předměty v ruce/batohu: nástroje mají tvar (krumpáč / sekera / meč) a **barvu podle tieru** (dřevo hnědá → kámen šedá → železo bílá → diamant tyrkys), luk = oblouk s tětivou, kuš = vodorovná, dále jablko, bobule, klacek, uhlí, ingoty, diamant (broušený), šíp, kost, nit…

**2. Poznáš, co držíš**
- Nad hotbarem se teď zobrazuje **jméno vybrané věci** + nápověda k použití.
- V batohu (E): **najeď myší na políčko** a ukáže se název.

### Jak jíst
1. Seber jídlo — **jablka** padají z listí, **bobule** z keřů (červené tečky), **shnilé maso** ze zombie.
2. Dej ho do hotbaru a vyber číslem **1–9** (nebo kolečkem) — nahoře uvidíš „Jablko / drž pravé tlačítko = sníst".
3. **Podrž pravé tlačítko myši** ~1 s — nad hotbarem naskočí oranžový proužek, pak se hlad doplní.

Hlad ubývá chůzí a při regeneraci života; když je hlad ≥ 7 dílků, život se sám doplňuje.


Building "svet.html", a top-down Minecraft-style prototype game per your design answers. Just added distinct textures for every block and item, held-item name labels, and eating (hold right mouse on food). Next: you reload the page and test, then tell me what to tune. (disable recaps in /config)