Killaura, dodging, ESP, zoom, auto‑respawn and much more. Buy me a coffee :) paypal.me/Izkuh
// ==UserScript==
// @name EvoWare
// @namespace http://tampermonkey.net/
// @version 2026-05-23.2
// @description Killaura, dodging, ESP, zoom, auto‑respawn and much more. Buy me a coffee :) paypal.me/Izkuh
// @author #Ex
// @match https://evowars.io/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=evowars.io
// @grant none
// @license GPL-3.0
// ==/UserScript==
(function() {
'use strict';
// UI – spacious, full‑size background, big toggles
const iframe = document.createElement('iframe');
iframe.id = 'evoware-frame';
iframe.style.cssText = `position:fixed!important;top:50px!important;left:50px!important;width:560px!important;height:600px!important;border:none!important;z-index:2147483647!important;background:transparent!important;pointer-events:auto!important;transition:opacity 0.15s!important;`;
document.body.appendChild(iframe);
const doc = iframe.contentDocument || iframe.contentWindow.document;
doc.open();
doc.write(`<!DOCTYPE html><html><head><style>
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;width:100%}
body{background:rgba(8,4,16,0.96);font-family:'Segoe UI',Arial,sans-serif;color:#b8a0d0;border-radius:12px;border:1px solid #4a2080;box-shadow:0 0 40px rgba(100,20,200,0.4);display:flex;flex-direction:column}
#drag-bar{height:42px;padding:0 16px;font-size:14px;font-weight:600;color:#c8b0f0;border-bottom:1px solid #4a2080;cursor:grab;display:flex;align-items:center;justify-content:space-between;user-select:none;background:linear-gradient(180deg,rgba(30,10,50,0.98),rgba(20,5,35,0.98));flex-shrink:0;border-radius:12px 12px 0 0}
#drag-bar:active{cursor:grabbing}.title{letter-spacing:0.5px}.hint{font-size:9px;color:#6040a0;font-weight:400}
.body{display:flex;flex:1;background:rgba(12,6,22,0.96);overflow:hidden;border-radius:0 0 12px 12px}
.content{display:flex;padding:14px;gap:14px;overflow-y:auto;flex:1}
.col{flex:1;display:flex;flex-direction:column;gap:10px;min-width:0}
.st{font-size:11px;font-weight:700;letter-spacing:1.5px;margin-bottom:4px;text-transform:uppercase;color:#7050b0}
.sec{background:rgba(18,10,30,0.9);border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:10px;border:1px solid #302050}
.row{display:flex;justify-content:space-between;align-items:center;font-size:13px;color:#c8b8e0;user-select:none;gap:12px}
.tgl{position:relative;width:56px;height:28px;display:inline-block;cursor:pointer;flex-shrink:0}
.tgl input{opacity:0;width:0;height:0;position:absolute}
.sld{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:#2a1840;transition:0.2s;border-radius:28px}
.sld:before{position:absolute;content:"";height:22px;width:22px;left:3px;bottom:3px;background:#6040a0;transition:0.2s;border-radius:50%}
input:checked+.sld{background:#7c3aed;box-shadow:0 0 8px rgba(124,58,237,0.5)}
input:checked+.sld:before{transform:translateX(28px);background:#fff}
.rw{display:flex;align-items:center;gap:8px;flex:1;position:relative}
.slider-wrap{position:relative;width:100%;height:22px}
.slider-wrap input[type=range]{position:absolute;width:100%;top:50%;transform:translateY(-50%);-webkit-appearance:none;appearance:none;background:transparent;pointer-events:none;z-index:2;height:6px}
.slider-wrap input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border-radius:50%;background:#7c3aed;cursor:pointer;pointer-events:auto;border:1px solid #a78bfa;box-shadow:0 0 6px rgba(124,58,237,0.4)}
.slider-track-bg{position:absolute;top:50%;transform:translateY(-50%);width:100%;height:4px;background:#2a1840;border-radius:3px;z-index:1}
.slider-track-fill{position:absolute;top:50%;transform:translateY(-50%);height:4px;background:#7c3aed;border-radius:3px;z-index:1;box-shadow:0 0 6px rgba(124,58,237,0.3)}
.val{color:#8060c0;font-size:11px;min-width:32px;text-align:right;flex-shrink:0;font-variant-numeric:tabular-nums}
.stat-val{font-weight:600;font-size:12px}
.help{display:inline-block;width:16px;height:16px;border-radius:50%;background:#4a2080;color:#c8b0f0;text-align:center;line-height:16px;font-size:11px;font-weight:700;cursor:help;margin-left:4px;position:relative}
.help:hover::after{content:attr(data-tip);position:absolute;left:22px;top:-6px;background:#1a0a2e;color:#fff;padding:6px 10px;border-radius:6px;font-size:11px;white-space:nowrap;z-index:10;border:1px solid #7c3aed;max-width:260px;white-space:normal}
::-webkit-scrollbar{width:4px}
::-webkit-scrollbar-track{background:#1a0a2e}
::-webkit-scrollbar-thumb{background:#4a2080;border-radius:4px}
</style></head><body>
<div id="drag-bar"><span class="title">⚔ EvoWare</span><span class="hint">INSERT toggle · Drag to move</span></div>
<div class="body"><div class="content">
<div class="col">
<div><div class="st">Combat</div><div class="sec">
<div class="row"><span>Killaura<span class="help" data-tip="Auto-aim & attack enemies in range">?</span></span><label class="tgl"><input type="checkbox" id="tgl-killaura"><span class="sld"></span></label></div>
<div class="row"><span>Target Level</span><span class="val" id="val-lvlrange">0-100</span></div>
<div class="slider-wrap"><div class="slider-track-bg"></div><div class="slider-track-fill" id="track-lvl"></div><input type="range" id="rng-lvlmin" min="0" max="100" value="0" step="1"><input type="range" id="rng-lvlmax" min="0" max="100" value="100" step="1"></div>
<div class="row"><span>Dodge<span class="help" data-tip="Turn & boost away from threat">?</span></span><label class="tgl"><input type="checkbox" id="tgl-dodgeatk"><span class="sld"></span></label></div>
<div class="row"><span>Dodge on CD<span class="help" data-tip="Dodge only while attack recharging">?</span></span><label class="tgl"><input type="checkbox" id="tgl-dodgecd"><span class="sld"></span></label></div>
<div class="row"><span>Auto Respawn<span class="help" data-tip="Automatically clicks 'Play' after death">?</span></span><label class="tgl"><input type="checkbox" id="tgl-autorespawn"><span class="sld"></span></label></div>
<div class="row"><span>Swing Angle<span class="help" data-tip="Aim offset from target direction">?</span></span><div class="rw"><div class="slider-wrap"><div class="slider-track-bg"></div><div class="slider-track-fill" id="track-offset"></div><input type="range" id="rng-offset" min="0" max="360" value="135"></div><span class="val" id="val-offset">135°</span></div></div>
</div></div>
<div><div class="st">Visuals</div><div class="sec">
<div class="row"><span>Enemy Range<span class="help" data-tip="Show enemy attack radius">?</span></span><label class="tgl"><input type="checkbox" id="tgl-enemyrange"><span class="sld"></span></label></div>
<div class="row"><span>Attack Timer<span class="help" data-tip="Show enemy attack cooldown">?</span></span><label class="tgl"><input type="checkbox" id="tgl-cooldown"><span class="sld"></span></label></div>
<div class="row"><span>Tracers<span class="help" data-tip="Line to each enemy">?</span></span><label class="tgl"><input type="checkbox" id="tgl-tracers"><span class="sld"></span></label></div>
<div class="row"><span>Hitboxes<span class="help" data-tip="Show enemy collision size">?</span></span><label class="tgl"><input type="checkbox" id="tgl-hitboxes"><span class="sld"></span></label></div>
<div class="row"><span>Target Glow<span class="help" data-tip="Highlight current target">?</span></span><label class="tgl"><input type="checkbox" id="tgl-killable"><span class="sld"></span></label></div>
</div></div>
</div>
<div class="col">
<div><div class="st">Settings</div><div class="sec">
<div class="row"><span>Zoom<span class="help" data-tip="Adjust camera zoom">?</span></span><div class="rw"><div class="slider-wrap"><div class="slider-track-bg"></div><div class="slider-track-fill" id="track-zoom"></div><input type="range" id="rng-zoom" min="0.2" max="3" step="0.05" value="0.5"></div><span class="val" id="val-zoom">0.50x</span></div></div>
</div></div>
<div><div class="st">Info</div><div class="sec">
<div class="row"><span>Level</span><span class="stat-val" style="color:#a78bfa" id="txt-level">--</span></div>
<div class="row"><span>Range</span><span class="stat-val" style="color:#c084fc" id="txt-range">--</span></div>
<div class="row"><span>Target</span><span class="stat-val" style="color:#e879f9" id="txt-target">--</span></div>
<div class="row"><span>Nearby</span><span class="stat-val" style="color:#a78bfa" id="txt-nearby">0</span></div>
<div class="row"><span>Dodge</span><span class="stat-val" style="color:#4ade80" id="txt-safe">--</span></div>
</div></div>
</div>
</div></div>
<script>
function S(t,d){window.parent.postMessage({evoware:1,type:t,data:d},'*')}
const D=document.getElementById('drag-bar');let dr=false,sx,sy,sl,st;
D.addEventListener('mousedown',function(e){if(e.target.tagName==='INPUT'||e.target.tagName==='LABEL')return;dr=true;sx=e.clientX;sy=e.clientY;const f=window.parent.document.getElementById('evoware-frame');sl=f.offsetLeft;st=f.offsetTop;e.preventDefault()});
window.addEventListener('mousemove',function(e){if(!dr)return;const f=window.parent.document.getElementById('evoware-frame');let nx=sl+(e.clientX-sx),ny=st+(e.clientY-sy);nx=Math.max(0,Math.min(nx,window.parent.innerWidth-f.offsetWidth));ny=Math.max(0,Math.min(ny,window.parent.innerHeight-f.offsetHeight));f.style.left=nx+'px';f.style.top=ny+'px'});
window.addEventListener('mouseup',function(){dr=false});
function UR(r,t,min,max,vel,suf,cb){const v=parseFloat(r.value);t.style.left='0%';t.style.width=((v-min)/(max-min)*100)+'%';vel.textContent=(suf==='°'?parseInt(v):v.toFixed(2))+suf;if(cb)cb(v);}
const rM=document.getElementById('rng-lvlmin'),rX=document.getElementById('rng-lvlmax'),tL=document.getElementById('track-lvl'),vL=document.getElementById('val-lvlrange');
function uL(){let mn=parseInt(rM.value),mx=parseInt(rX.value);if(mn>mx){[mn,mx]=[mx,mn];rM.value=mn;rX.value=mx;}tL.style.left=(mn/100*100)+'%';tL.style.width=((mx-mn)/100*100)+'%';vL.textContent=mn+'-'+mx;S('lvlrange',{min:mn,max:mx});}
rM.addEventListener('input',uL);rX.addEventListener('input',uL);uL();
const rO=document.getElementById('rng-offset'),tO=document.getElementById('track-offset'),vO=document.getElementById('val-offset');UR(rO,tO,0,360,vO,'°',function(v){S('offset',v)});rO.addEventListener('input',function(){UR(rO,tO,0,360,vO,'°',function(v){S('offset',v)})});
const rZ=document.getElementById('rng-zoom'),tZ=document.getElementById('track-zoom'),vZ=document.getElementById('val-zoom');UR(rZ,tZ,0.2,3,vZ,'x',function(v){S('zoom',v)});rZ.addEventListener('input',function(){UR(rZ,tZ,0.2,3,vZ,'x',function(v){S('zoom',v)})});
document.getElementById('tgl-killaura').addEventListener('change',function(){S('killaura',this.checked)});
document.getElementById('tgl-dodgeatk').addEventListener('change',function(){S('dodgeatk',this.checked)});
document.getElementById('tgl-dodgecd').addEventListener('change',function(){S('dodgecd',this.checked)});
document.getElementById('tgl-autorespawn').addEventListener('change',function(){S('autorespawn',this.checked)});
document.getElementById('tgl-enemyrange').addEventListener('change',function(){S('enemyrange',this.checked)});
document.getElementById('tgl-cooldown').addEventListener('change',function(){S('cooldown',this.checked)});
document.getElementById('tgl-tracers').addEventListener('change',function(){S('tracers',this.checked)});
document.getElementById('tgl-hitboxes').addEventListener('change',function(){S('hitboxes',this.checked)});
document.getElementById('tgl-killable').addEventListener('change',function(){S('killable',this.checked)});
window.addEventListener('message',function(e){if(!e.data||!e.data.evoware)return;if(e.data.type==='updateStats'){document.getElementById('txt-level').textContent=e.data.level;document.getElementById('txt-range').textContent=e.data.range;document.getElementById('txt-target').textContent=e.data.target;document.getElementById('txt-nearby').textContent=e.data.nearby;document.getElementById('txt-safe').textContent=e.data.safe}if(e.data.type==='updateKillaura')document.getElementById('tgl-killaura').checked=e.data.checked;if(e.data.type==='updateAutorespawn')document.getElementById('tgl-autorespawn').checked=e.data.checked});
<\/script></body></html>`);
doc.close();
// ──────────────────────────────────────────────────────────────
// GLOBALS
// ──────────────────────────────────────────────────────────────
let rt, pType, gameCanvas;
let showTracers = false, showHitboxes = false, showKillable = false, showEnemyRange = false, showCooldown = false;
let killaura = false, dodgeAttacks = false, dodgeOnCD = false;
let autoRespawn = false;
let offset = 135, zoomLevel = 0.5, lvlMin = 0, lvlMax = 100;
let target = null, targetLevel = 0, menuVisible = true;
let lastDodge = 0, dodgeCD = 2000;
let enemyTimers = new Map(), gameStartTime = 0;
let enemyPrevAngle = new Map();
let nc = 0, ss = '--';
let lastRespawnTry = 0;
let boostTimeout = null;
// ──────────────────────────────────────────────────────────────
// UTILITIES
// ──────────────────────────────────────────────────────────────
const getAttackCooldown = (level) => Math.max(100, level * 100);
function applyZoom() {
if (rt?.running_layout?.layers) {
for (const l of rt.running_layout.layers) {
if (l?.scale !== undefined) { l.scale = zoomLevel; if (l.setZIndicesStaleFrom) l.setZIndicesStaleFrom(0); }
}
rt.redraw = true;
}
}
function gs(obj) {
if (!obj) return { lv: 0, sz: 0, rng: 0 };
let lv = 0, sz = obj.width || 0;
try {
if (obj.instance_vars) {
let lvs = [];
for (let i = 0; i < obj.instance_vars.length; i++) {
const v = obj.instance_vars[i];
if (typeof v === 'number' && v >= 1 && v <= 200 && Number.isInteger(v)) lvs.push({ i, v });
}
if (lvs.length) {
lvs.sort((a, b) => b.v - a.v);
const early = lvs.filter(l => l.i < 15);
lv = early.length >= 2 ? early[1].v : (early.length === 1 ? early[0].v + 1 : lvs[0].v + 1);
}
}
} catch (e) {}
if (!lv && sz > 0) lv = Math.max(1, Math.floor(sz / 3.5));
return { lv, sz, rng: sz * 2.2 };
}
function getPlayer() {
if (!rt?.running_layout || !pType) return null;
const instances = pType.instances;
let self = null, md = Infinity;
for (let i = 0; i < instances.length; i++) {
const p = instances[i]; if (!p) continue;
const d = Math.hypot(p.x - rt.running_layout.scrollX, p.y - rt.running_layout.scrollY);
if (d < md && d < 500) { md = d; self = p; }
}
return self;
}
function sendStats() {
const self = getPlayer();
const ps = self ? gs(self) : null;
iframe.contentWindow.postMessage({
evoware: 1, type: 'updateStats',
level: 'Lv.' + (ps ? ps.lv : '--'),
range: ps ? Math.floor(ps.rng) + 'u' : '--',
target: targetLevel > 0 ? 'Lv.' + targetLevel : '--',
nearby: nc, safe: ss
}, '*');
}
function simMouse(type, clientX, clientY, button = 0, buttons = 0) {
if (!gameCanvas) return;
const opts = { bubbles: true, cancelable: true, view: window, clientX, clientY, button, buttons };
gameCanvas.dispatchEvent(new MouseEvent(type, opts));
document.dispatchEvent(new MouseEvent(type, opts));
}
// ──────────────────────────────────────────────────────────────
// KILLAURA – only when enemy is within range, aim+click, no teleport
// ──────────────────────────────────────────────────────────────
function killAll() {
const self = getPlayer(); if (!self) return;
const ps = gs(self); if (!ps) return;
const rect = gameCanvas.getBoundingClientRect();
const sc = self.layer.getScale();
const vx = rect.left + rect.width/2, vy = rect.top + rect.height/2;
const instances = pType.instances;
// Find the closest enemy within attack range
let bestTarget = null;
let bestDist = Infinity;
for (let i = 0; i < instances.length; i++) {
const p = instances[i]; if (!p || p.uid === self.uid) continue;
if (p.width <= 0) continue;
const dist = Math.hypot(p.x - self.x, p.y - self.y);
if (dist > ps.rng) continue; // only enemies in range
const es = gs(p);
if (es.lv < lvlMin || es.lv > lvlMax) continue;
if (dist < bestDist) {
bestDist = dist;
bestTarget = p;
}
}
if (!bestTarget) { target = null; targetLevel = 0; return; }
target = bestTarget;
targetLevel = gs(target).lv;
// Aim with offset
const dx = target.x - self.x, dy = target.y - self.y;
const angleToTarget = Math.atan2(dy, dx);
const offsetRad = (offset * Math.PI) / 180;
self.angle = ((angleToTarget + offsetRad) % (Math.PI * 2) + (Math.PI * 2)) % (Math.PI * 2);
// Click on target screen position
const sx = vx + (target.x - self.x) * sc;
const sy = vy + (target.y - self.y) * sc;
simMouse('mousedown', sx, sy, 0, 1);
simMouse('mouseup', sx, sy, 0, 0);
}
// ──────────────────────────────────────────────────────────────
// NATURAL DODGE – 180° turn + boost away (unchanged)
// ──────────────────────────────────────────────────────────────
function detectThreats(self) {
if (!self || !pType) return [];
const threats = []; const instances = pType.instances;
for (let i = 0; i < instances.length; i++) {
const p = instances[i]; if (!p || p.uid === self.uid) continue;
if (p.width <= 0) continue;
const dx = p.x - self.x, dy = p.y - self.y, dist = Math.hypot(dx, dy);
const es = gs(p);
if (dist > es.rng * 2.5) continue;
const angle = p.angle || 0; const prev = enemyPrevAngle.get(p.uid);
if (prev !== undefined) {
const angleDiff = Math.abs(angle - prev);
const ndiff = Math.min(angleDiff, Math.PI * 2 - angleDiff);
if (ndiff > 0.2) {
const angleToUs = Math.atan2(dy, dx);
const facingUs = Math.abs(angle - angleToUs) < 0.7;
if (facingUs || dist < es.rng * 1.2) {
threats.push({ dx, dy, dist, es });
}
}
}
enemyPrevAngle.set(p.uid, angle);
}
const alive = new Set(); for (let i = 0; i < instances.length; i++) { const p = instances[i]; if (p && p.uid && p.width > 0) alive.add(p.uid); }
for (const uid of enemyPrevAngle.keys()) { if (!alive.has(uid)) enemyPrevAngle.delete(uid); }
return threats;
}
function dodge(self) {
if (!self || !pType || !dodgeAttacks) { ss = '--'; return; }
const now = performance.now();
if (now - lastDodge < dodgeCD) { ss = '⏳ CD'; return; }
if (dodgeOnCD && now - lastDodge < 400) {} else if (dodgeOnCD) { ss = '✓ Ready'; return; }
const threats = detectThreats(self);
if (threats.length === 0) { ss = dodgeOnCD ? '✓ Waiting' : '✓ Safe'; return; }
let totalX = 0, totalY = 0;
for (const t of threats) {
const dist = Math.hypot(t.dx, t.dy);
if (dist < 0.01) continue;
const weight = Math.max(0, (t.es.rng * 1.3 - dist) / (t.es.rng * 1.3));
totalX += (t.dx / dist) * weight;
totalY += (t.dy / dist) * weight;
}
const threatMag = Math.hypot(totalX, totalY);
if (threatMag > 0.01) {
const escapeAngle = Math.atan2(-totalY, -totalX);
self.angle = escapeAngle;
const pushStrength = Math.min(12, threatMag * 8);
const pushX = -totalX / threatMag * pushStrength;
const pushY = -totalY / threatMag * pushStrength;
self.x += pushX;
self.y += pushY;
if (rt?.running_layout) {
rt.running_layout.scrollX += pushX;
rt.running_layout.scrollY += pushY;
}
}
if (boostTimeout) clearTimeout(boostTimeout);
const rect = gameCanvas.getBoundingClientRect();
const cx = rect.left + rect.width/2;
const cy = rect.top + rect.height/2;
simMouse('mousedown', cx, cy, 2, 2);
boostTimeout = setTimeout(() => {
simMouse('mouseup', cx, cy, 2, 0);
boostTimeout = null;
}, 250);
lastDodge = now;
ss = '💨 Boost away';
}
// ──────────────────────────────────────────────────────────────
// AUTO RESPAWN (unchanged)
// ──────────────────────────────────────────────────────────────
function tryRespawn() {
const now = performance.now();
if (now - lastRespawnTry < 2500) return;
lastRespawnTry = now;
const rect = gameCanvas.getBoundingClientRect();
const cx = rect.left + rect.width/2;
const cy = rect.top + rect.height/2;
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', keyCode: 13, bubbles: true }));
document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', keyCode: 13, bubbles: true }));
const offsets = [0, -30, 30, -60, 60];
offsets.forEach((offY, idx) => {
setTimeout(() => {
simMouse('mousedown', cx, cy + offY, 0, 1);
simMouse('mouseup', cx, cy + offY, 0, 0);
}, idx * 80);
});
}
// ──────────────────────────────────────────────────────────────
// TIMERS & ESP (unchanged)
// ──────────────────────────────────────────────────────────────
function updateTimers() {
if (!pType || !gameStartTime) return;
const instances = pType.instances;
for (let i = 0; i < instances.length; i++) {
const p = instances[i]; if (!p || !p.uid || p.width <= 0) continue;
if (!enemyTimers.has(p.uid)) {
const es = gs(p);
enemyTimers.set(p.uid, { cd: getAttackCooldown(es.lv) });
}
}
const alive = new Set(); for (let i = 0; i < instances.length; i++) { const p = instances[i]; if (p && p.uid && p.width > 0) alive.add(p.uid); }
for (const uid of enemyTimers.keys()) { if (!alive.has(uid)) enemyTimers.delete(uid); }
}
const esp = document.createElement('canvas');
const ctx = esp.getContext('2d');
esp.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:999998;';
esp.width = innerWidth; esp.height = innerHeight;
document.body.appendChild(esp);
window.addEventListener('resize', () => { esp.width = innerWidth; esp.height = innerHeight; });
function draw() {
if (!rt?.running_layout || !pType) return;
const now = performance.now(), instances = pType.instances;
const self = getPlayer(); if (!self) return;
const ps = gs(self), rect = gameCanvas.getBoundingClientRect();
const vx = rect.left + rect.width / 2, vy = rect.top + rect.height / 2, sc = self.layer.getScale();
ctx.clearRect(0, 0, esp.width, esp.height);
let nearby = 0;
if (dodgeAttacks) {
const sr = Math.max(ps.rng, 80) * 1.5 * sc;
ctx.beginPath(); ctx.arc(vx, vy, sr, 0, Math.PI * 2);
ctx.strokeStyle = dodgeOnCD ? "rgba(251,191,36,0.4)" : "rgba(74,222,128,0.4)";
ctx.lineWidth = 2; ctx.setLineDash([5, 5]); ctx.stroke(); ctx.setLineDash([]);
}
if (killaura) {
ctx.beginPath(); ctx.arc(vx, vy, ps.rng * sc, 0, Math.PI * 2);
ctx.strokeStyle = "rgba(124,58,237,0.3)"; ctx.lineWidth = 1.5;
ctx.setLineDash([4, 4]); ctx.stroke(); ctx.setLineDash([]);
}
if (killaura && target) {
const angle = self.angle || 0, bl2 = (ps.sz * 0.9) * sc;
const dx = target.x - self.x, dy = target.y - self.y, da = Math.atan2(dy, dx);
ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(vx + Math.cos(da) * bl2, vy + Math.sin(da) * bl2);
ctx.strokeStyle = "rgba(255,255,255,0.4)"; ctx.lineWidth = 1.5; ctx.setLineDash([2, 2]); ctx.stroke(); ctx.setLineDash([]);
ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(vx + Math.cos(angle) * bl2, vy + Math.sin(angle) * bl2);
ctx.strokeStyle = "#a855f7"; ctx.lineWidth = 3; ctx.stroke();
const or2 = (offset * Math.PI) / 180;
ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(vx + Math.cos(da + or2) * bl2, vy + Math.sin(da + or2) * bl2);
ctx.strokeStyle = "#22c55e"; ctx.lineWidth = 2; ctx.setLineDash([3, 3]); ctx.stroke(); ctx.setLineDash([]);
}
for (let i = 0; i < instances.length; i++) {
const p = instances[i]; if (!p || p.uid === self.uid) continue;
if (p.width <= 0) continue;
const es = gs(p);
if (es.lv <= 0) continue;
const px = vx + (p.x - self.x) * sc, py = vy + (p.y - self.y) * sc;
const dist = Math.hypot(p.x - self.x, p.y - self.y), inRng = dist <= ps.rng;
const killable = es.lv <= ps.lv, danger = es.lv > ps.lv * 1.3;
if (inRng) nearby++;
if (showCooldown) {
const t = enemyTimers.get(p.uid);
if (t) {
const elapsed = (now - gameStartTime) % t.cd;
const remaining = t.cd - elapsed, pct = elapsed / t.cd;
ctx.beginPath(); ctx.arc(px, py, 28, 0, Math.PI * 2);
ctx.strokeStyle = "rgba(255,255,255,0.08)"; ctx.lineWidth = 2.5; ctx.stroke();
ctx.beginPath(); ctx.arc(px, py, 28, -Math.PI / 2, -Math.PI / 2 + Math.PI * 2 * pct);
ctx.strokeStyle = pct < 0.15 ? "#22c55e" : "#f59e0b"; ctx.lineWidth = 2.5; ctx.stroke();
ctx.fillStyle = "#fff"; ctx.font = "bold 9px Arial"; ctx.textAlign = "center";
ctx.fillText((remaining / 1000).toFixed(1) + "s", px, py - 34);
}
}
if (showKillable && inRng) {
ctx.beginPath(); ctx.arc(px, py, 22, 0, Math.PI * 2);
if (killable) {
ctx.shadowColor = "#22c55e"; ctx.shadowBlur = 15;
ctx.strokeStyle = "#22c55e"; ctx.lineWidth = 3; ctx.stroke(); ctx.shadowBlur = 0;
} else if (danger) {
ctx.shadowColor = "#ef4444"; ctx.shadowBlur = 15;
ctx.strokeStyle = "#ef4444"; ctx.lineWidth = 3; ctx.setLineDash([4, 4]); ctx.stroke(); ctx.setLineDash([]); ctx.shadowBlur = 0;
}
}
if (showEnemyRange && es.rng > 0) {
ctx.beginPath(); ctx.arc(px, py, es.rng * sc, 0, Math.PI * 2);
ctx.strokeStyle = dist < es.rng ? "rgba(255,60,60,0.9)" : "rgba(255,60,60,0.5)";
ctx.lineWidth = 2;
ctx.setLineDash([2, 2]); ctx.stroke(); ctx.setLineDash([]);
}
if (showHitboxes) {
const r = (p.width / 2) * sc * 1.5;
ctx.beginPath(); ctx.arc(px, py, r, 0, Math.PI * 2);
ctx.fillStyle = killable ? "rgba(34,197,94,0.08)" : "rgba(124,58,237,0.08)"; ctx.fill();
ctx.strokeStyle = killable ? "#22c55e" : "#a855f7"; ctx.lineWidth = 1; ctx.stroke();
}
if (showTracers) {
ctx.beginPath(); ctx.moveTo(vx, vy); ctx.lineTo(px, py);
ctx.strokeStyle = inRng ? (killable ? "rgba(34,197,94,0.6)" : "rgba(168,85,247,0.5)") : "rgba(168,85,247,0.12)";
ctx.lineWidth = inRng ? 1.5 : 0.5; ctx.stroke();
}
if (killaura && target && p.uid === target.uid) {
ctx.beginPath(); ctx.arc(px, py, 26, 0, Math.PI * 2);
ctx.strokeStyle = "#a855f7"; ctx.lineWidth = 2.5; ctx.setLineDash([3, 3]); ctx.stroke(); ctx.setLineDash([]);
ctx.fillStyle = "#fff"; ctx.font = "bold 10px Arial"; ctx.textAlign = "center";
ctx.fillText("Lv." + es.lv, px, py - 30);
}
}
nc = nearby; sendStats();
}
// ──────────────────────────────────────────────────────────────
// MAIN LOOP
// ──────────────────────────────────────────────────────────────
function loop() {
try {
if (rt?.running_layout) {
if (!gameStartTime) gameStartTime = performance.now();
applyZoom();
updateTimers();
const needDraw = showTracers || showHitboxes || showKillable || showEnemyRange || showCooldown || killaura || dodgeAttacks;
if (needDraw) draw(); else ctx.clearRect(0, 0, esp.width, esp.height);
if (pType) {
const self = getPlayer();
if (self) {
if (killaura) killAll();
let enemiesRemain = false;
if (killaura && dodgeAttacks && self) {
const ps = gs(self);
const instances = pType.instances;
for (let i = 0; i < instances.length; i++) {
const p = instances[i];
if (!p || p.uid === self.uid) continue;
if (p.width <= 0) continue;
const dist = Math.hypot(p.x - self.x, p.y - self.y);
if (dist <= ps.rng) {
const es = gs(p);
if (es.lv >= lvlMin && es.lv <= lvlMax) {
enemiesRemain = true;
break;
}
}
}
}
if (dodgeAttacks && killaura && enemiesRemain) {
dodge(self);
}
} else {
if (autoRespawn) tryRespawn();
}
}
}
} catch (e) {}
requestAnimationFrame(loop);
}
// ──────────────────────────────────────────────────────────────
// INIT
// ──────────────────────────────────────────────────────────────
const init = setInterval(() => {
if (window.cr_getC2Runtime && (rt = window.cr_getC2Runtime())) {
clearInterval(init);
gameCanvas = rt.canvas;
for (const t of rt.types_by_index) {
if (t?.instvar_sids?.length === 72) { pType = t; break; }
}
if (!pType) {
for (const t of rt.types_by_index) {
if (t?.instances?.length > 0) {
const i = t.instances[0];
if (i.x !== undefined && i.y !== undefined && i.width !== undefined && i.angle !== undefined) {
pType = t; break;
}
}
}
}
loop();
}
}, 500);
// ──────────────────────────────────────────────────────────────
// MESSAGE HANDLER
// ──────────────────────────────────────────────────────────────
window.addEventListener('message', function(e) {
if (!e.data || !e.data.evoware) return;
switch (e.data.type) {
case 'killaura': killaura = e.data.data; if (!killaura) { target = null; targetLevel = 0; } break;
case 'dodgeatk': dodgeAttacks = e.data.data; break;
case 'dodgecd': dodgeOnCD = e.data.data; break;
case 'autorespawn': autoRespawn = e.data.data; break;
case 'lvlrange': lvlMin = e.data.data.min; lvlMax = e.data.data.max; break;
case 'enemyrange': showEnemyRange = e.data.data; break;
case 'cooldown': showCooldown = e.data.data; break;
case 'tracers': showTracers = e.data.data; break;
case 'hitboxes': showHitboxes = e.data.data; break;
case 'killable': showKillable = e.data.data; break;
case 'offset': offset = e.data.data; break;
case 'zoom': zoomLevel = e.data.data; break;
}
});
// ──────────────────────────────────────────────────────────────
// KEYBINDINGS (INSERT toggles menu)
// ──────────────────────────────────────────────────────────────
document.addEventListener('keydown', function(e) {
if (e.key === 'Insert') {
e.preventDefault(); e.stopPropagation();
menuVisible = !menuVisible;
iframe.style.opacity = menuVisible ? '1' : '0';
iframe.style.pointerEvents = menuVisible ? 'auto' : 'none';
}
}, true);
})();