Skip to content

Instantly share code, notes, and snippets.

@EncodeTheCode
Created December 20, 2025 13:23
Show Gist options
  • Select an option

  • Save EncodeTheCode/b0507b1d94657c537c77187e529b1d98 to your computer and use it in GitHub Desktop.

Select an option

Save EncodeTheCode/b0507b1d94657c537c77187e529b1d98 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WoW-Style Rogue Talent Mock</title>
<style>
body { margin:0; background:#081018; color:#e6eef6; font-family:Arial }
canvas { background:#0b1324; display:block; margin:10px auto; border-radius:8px }
.overlay { position:fixed; inset:0; background:rgba(0,0,0,.6); display:none; align-items:center; justify-content:center }
.window { background:#0e1628; padding:16px; width:1000px; border-radius:12px; display:flex; gap:12px }
.tree { flex:1; background:#0b1220; padding:10px; border-radius:8px }
.grid { display:grid; grid-template-columns:repeat(3,1fr); grid-template-rows:repeat(6,70px); gap:8px; margin-top:8px }
.node { background:#121a30; border-radius:8px; position:relative; cursor:pointer; padding:6px; text-align:center }
.node.locked { opacity:.35; cursor:not-allowed }
.count { position:absolute; top:4px; right:6px; font-size:11px }
button { background:#1e293b; color:white; border:none; padding:4px 8px; border-radius:6px; cursor:pointer }
button:disabled { opacity:.3 }
h3 { margin:0 }
</style>
</head>
<body>
<canvas id="game" width="900" height="500"></canvas>
<div class="overlay" id="overlay">
<div class="window">
<div class="tree"><h3>Stalker</h3><div id="grid0" class="grid"></div></div>
<div class="tree"><h3>Duelist</h3><div id="grid1" class="grid"></div></div>
<div class="tree"><h3>Nightblade</h3><div id="grid2" class="grid"></div></div>
</div>
</div>
<script>
/* =========================
TALENT SYSTEM (FIXED)
========================= */
const TOTAL_POINTS = 51;
let available = TOTAL_POINTS;
const trees = [];
const ROWS = 6, COLS = 3;
// Build trees
for (let t = 0; t < 3; t++) {
const talents = [];
for (let r = 0; r < ROWS; r++) {
for (let c = 0; c < COLS; c++) {
talents.push({
id:`t${t}_${r}_${c}`,
row:r,
col:c,
spent:0,
max:(c === 1 ? 2 : 1) // center talents are multi-rank
});
}
}
trees.push(talents);
}
// Points in tree
function pointsInTree(t) {
return trees[t].reduce((s,x)=>s+x.spent,0);
}
// WoW-style tier unlock (FIX)
function isRowUnlocked(tree,row) {
return pointsInTree(tree) >= row * 5;
}
// Spend point
function spend(tree,id) {
if (available <= 0) return;
const t = trees[tree].find(x=>x.id===id);
if (!t || t.spent >= t.max) return;
if (!isRowUnlocked(tree,t.row)) return;
t.spent++;
available--;
render();
}
// Reset function (required by you)
window.reset_talents = function() {
if (!confirm("Reset all talents?")) return;
trees.flat().forEach(t=>t.spent=0);
available = TOTAL_POINTS;
render();
};
// Render UI
function render() {
for (let ti = 0; ti < 3; ti++) {
const grid = document.getElementById(`grid${ti}`);
grid.innerHTML = "";
trees[ti].forEach(t => {
const node = document.createElement("div");
node.className = "node";
if (!isRowUnlocked(ti,t.row)) node.classList.add("locked");
node.innerHTML = `
<div class="count">${t.spent}/${t.max}</div>
Tier ${t.row+1}
<br><button ${(!isRowUnlocked(ti,t.row)||t.spent>=t.max)?"disabled":""}>+</button>
`;
node.querySelector("button").onclick = ()=>spend(ti,t.id);
grid.appendChild(node);
});
}
}
render();
/* =========================
GAME (MOVEMENT + AIM)
========================= */
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const p = {x:450,y:250};
const keys = {};
let mx=450,my=250;
window.onkeydown=e=>{keys[e.key]=true;if(e.key==="k")toggle()};
window.onkeyup=e=>keys[e.key]=false;
canvas.onmousemove=e=>{
const r=canvas.getBoundingClientRect();
mx=e.clientX-r.left; my=e.clientY-r.top;
};
function toggle(){
const o=document.getElementById("overlay");
o.style.display=o.style.display==="flex"?"none":"flex";
}
function loop(){
if(keys.w)p.y-=3;if(keys.s)p.y+=3;if(keys.a)p.x-=3;if(keys.d)p.x+=3;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath(); ctx.moveTo(p.x,p.y); ctx.lineTo(mx,my); ctx.strokeStyle="#000"; ctx.lineWidth=3; ctx.stroke();
ctx.beginPath(); ctx.arc(p.x,p.y,14,0,Math.PI*2); ctx.fillStyle="#2ea3ff"; ctx.fill();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment