Dynamic player recognition overlay with viewport center locking, instant account wipe button, and Vietnamese UI translations.
// ==UserScript==
// @name Cerox_YT HACK
// @namespace http://tampermonkey.net/
// @version 2.0
// @description Dynamic player recognition overlay with viewport center locking, instant account wipe button, and Vietnamese UI translations.
// @author Cerox_YT
// @match https://evowars.io/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
let currentZoom = 1.0;
let manualHitboxMultiplier = 1.00;
let currentMyLvl = 1;
let hitboxProfiles = {};
let isVietnamese = false;
let isEngineActive = true;
try {
const savedProfiles = localStorage.getItem('killer_hitbox_profiles');
if (savedProfiles) {
hitboxProfiles = JSON.parse(savedProfiles);
}
} catch (e) {
console.error("[KILLER Engine] Storage read error:", e);
}
const manualTeammates = new Set();
const forcedEnemies = new Set();
const STRICT_ORB_TYPES = new Set(["t151", "t453"]);
let INDEX_PLAYER_LEVEL = 24;
let INDEX_SWING_STATE = 25;
let INDEX_ANGLE_VAR = 15;
let INDEX_PLAYER_NAME = null;
const INDEX_TEAM_IDENTIFIER = 36;
const possibleTargetsList = new Array(120);
let possibleTargetsCount = 0;
let physicalMouseX = window.innerWidth / 2;
let physicalMouseY = window.innerHeight / 2;
let hoveredPlayerName = null;
let rt = null, pType = null, gameCanvas = null;
let engineMouseInstance = null;
let ctx = null, overlay = null;
let optLines = false, optBoxes = false, optText = false, optAttack = true, optRadius = false;
let optHideOrbs = true;
let optForceUnallyAll = false;
const translations = {
en: {
title: "cerox_YT hack",
autoWipe: "Instant Wipe",
autoAim: "Auto Attack",
clearOrbs: "no lags",
unallyAll: "Duel,deathmath mode",
espLines: "ESP Lines",
boxes: "Enemy Hitboxes",
radius: "Weapon Ring",
specs: "Show Specs",
hitboxTuning: "Hitbox Tuning",
fovZoom: "fov",
exitServer: "Out sever",
exitBtn: "Exit",
hotkeys: "Hover + [T] to Duel,deathmath mode<br>[1] Fine-Tune +0.05 | [2] Fine-Tune -0.05",
langBtn: "VN 🇻🇳"
},
vn: {
title: " Tú đẹp zai",
autoWipe: "Xóa tức thì",
autoAim: "Tự động ngắm",
clearOrbs: "Xóa quả cầu 🟢",
unallyAll: "Hủy đồng minh tất cả",
espLines: "Đường kẻ ESP",
boxes: "Khung va chạm",
radius: "Vòng vũ khí",
specs: "Hiện thông số",
hitboxTuning: "Chỉnh Hitbox",
fovZoom: "Thu phóng FOV",
exitServer: "Thoát Server",
exitBtn: "Thoát",
hotkeys: "Rê chuột + [T] để HỦY ĐỒNG MINH<br>[1] Tăng +0.05 | [2] Giảm -0.05",
langBtn: "EN 🇬🇧"
}
};
function t(key) {
const lang = isVietnamese ? 'vn' : 'en';
return translations[lang][key] || key;
}
function initUserInterface() {
const style = document.createElement('style');
style.id = 'cheat-menu-styles';
style.innerHTML = `
@keyframes borderChromatic {
0% { border-color: #ff0055; box-shadow: 0 0 10px rgba(255, 0, 85, 0.3); }
50% { border-color: #00ffcc; box-shadow: 0 0 10px rgba(0, 255, 204, 0.3); }
100% { border-color: #ff0055; box-shadow: 0 0 10px rgba(255, 0, 85, 0.3); }
}
#cheat-menu-container {
position: fixed; top: 12px; right: 12px; width: 230px;
background: rgba(13, 13, 19, 0.88); border: 2px solid #ff0055;
border-radius: 10px; z-index: 999999; font-family: sans-serif;
color: #ffffff; overflow: hidden; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.7);
backdrop-filter: blur(6px); animation: borderChromatic 5s ease infinite;
}
#cheat-menu-header {
padding: 8px 12px; background: rgba(0, 0, 0, 0.75);
border-bottom: 1px solid rgba(255, 255, 255, 0.15); display: flex;
justify-content: space-between; align-items: center; font-size: 10px;
font-weight: 900; letter-spacing: 0.5px;
}
.cheat-menu-body { padding: 8px; display: flex; flex-direction: column; gap: 5px; }
.cheat-row {
display: flex; justify-content: space-between; align-items: center;
background: rgba(20, 20, 28, 0.65); padding: 6px 8px; border-radius: 6px;
font-size: 11px; font-weight: 600; border: 1px solid rgba(255, 255, 255, 0.05);
}
.toggle-switch { position: relative; width: 30px; height: 15px; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.slider-round {
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
background: rgba(255, 255, 255, 0.2); border-radius: 15px; cursor: pointer;
}
.slider-round:before {
position: absolute; content: ""; width: 11px; height: 11px; left: 2px;
bottom: 2px; background: #e2e8f0; border-radius: 50%; transition: all 0.2s ease;
}
input:checked + .slider-round { background: #00ffcc; }
input:checked + .slider-round:before { transform: translateX(15px); background: #09090d; }
.btn-container { display: flex; align-items: center; gap: 5px; width: 45%; justify-content: flex-end; }
.menu-btn {
width: 20px; height: 20px; background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.2); color: #fff; border-radius: 5px; cursor: pointer;
}
.value-label { color: #00ffcc; min-width: 28px; text-align: center; font-size: 11px; font-weight: 900; }
#team-hotkey-info { font-size: 8.5px; color: #94a3b8; text-align: center; padding: 6px 0 2px 0; line-height: 1.3; }
#lang-toggle-btn {
background: rgba(0, 255, 204, 0.2); border: 1px solid #00ffcc; color: #00ffcc;
border-radius: 4px; padding: 2px 6px; font-size: 9px; font-weight: bold; cursor: pointer;
}
`;
document.head.appendChild(style);
const menu = document.createElement('div');
menu.id = 'cheat-menu-wrapper';
document.body.appendChild(menu);
renderMenuHTML();
}
function renderMenuHTML() {
const menuWrapper = document.getElementById('cheat-menu-wrapper');
if (!menuWrapper) return;
menuWrapper.innerHTML = `
<div id="cheat-menu-container">
<div id="cheat-menu-header">
<span id="txt-title">${t('title')}</span>
<div style="display:flex; gap:5px; align-items:center;">
<button id="lang-toggle-btn">${t('langBtn')}</button>
<button id="menu-toggle" style="background:transparent;border:none;color:white;cursor:pointer;font-weight:bold;">×</button>
</div>
</div>
<div class="cheat-menu-body" id="menu-body">
<div class="cheat-row" style="background: rgba(255, 0, 85, 0.15); border: 1px solid #ff0055;">
<span id="txt-autowipe" style="color: #ff0055; font-weight: 900;">${t('autoWipe')}</span>
<label class="toggle-switch"><input type="checkbox" id="chk-autowipe"><span class="slider-round"></span></label>
</div>
<div class="cheat-row"><span id="txt-attack">${t('autoAim')}</span><label class="toggle-switch"><input type="checkbox" id="chk-attack" checked><span class="slider-round"></span></label></div>
<div class="cheat-row"><span id="txt-orbs">${t('clearOrbs')}</span><label class="toggle-switch"><input type="checkbox" id="chk-orbs" checked><span class="slider-round"></span></label></div>
<div class="cheat-row"><span id="txt-unally">${t('unallyAll')}</span><label class="toggle-switch"><input type="checkbox" id="chk-unally-all"><span class="slider-round"></span></label></div>
<div class="cheat-row"><span id="txt-lines">${t('espLines')}</span><label class="toggle-switch"><input type="checkbox" id="chk-lines"><span class="slider-round"></span></label></div>
<div class="cheat-row"><span id="txt-boxes">${t('boxes')}</span><label class="toggle-switch"><input type="checkbox" id="chk-boxes"><span class="slider-round"></span></label></div>
<div class="cheat-row"><span id="txt-radius">${t('radius')}</span><label class="toggle-switch"><input type="checkbox" id="chk-radius"><span class="slider-round"></span></label></div>
<div class="cheat-row"><span id="txt-text">${t('specs')}</span><label class="toggle-switch"><input type="checkbox" id="chk-text"><span class="slider-round"></span></label></div>
<div class="cheat-row">
<span id="txt-hitbox">${t('hitboxTuning')}</span>
<div class="btn-container">
<button class="menu-btn" id="btn-hitbox-minus">-</button>
<div class="value-label" id="lbl-hitbox">${manualHitboxMultiplier.toFixed(2)}</div>
<button class="menu-btn" id="btn-hitbox-plus">+</button>
</div>
</div>
<div class="cheat-row">
<span id="txt-zoom">${t('fovZoom')}</span>
<div class="btn-container">
<button class="menu-btn" id="btn-zoom-minus">-</button>
<div class="value-label" id="lbl-zoom">${currentZoom.toFixed(1)}</div>
<button class="menu-btn" id="btn-zoom-plus">+</button>
</div>
</div>
<div class="cheat-row">
<span id="txt-exit">${t('exitServer')}</span>
<div class="btn-container">
<button class="menu-btn" id="btn-disconnect" style="width: 50px; background: rgba(255, 0, 85, 0.3);">${t('exitBtn')}</button>
</div>
</div>
<div id="team-hotkey-info">${t('hotkeys')}</div>
</div>
</div>`;
document.getElementById('lang-toggle-btn').onclick = () => {
isVietnamese = !isVietnamese;
renderMenuHTML();
};
const body = document.getElementById('menu-body');
const toggle = document.getElementById('menu-toggle');
let collapsed = false;
toggle.onclick = () => {
collapsed = !collapsed;
body.style.display = collapsed ? 'none' : 'flex';
toggle.textContent = collapsed ? '+' : '×';
};
document.getElementById('chk-autowipe').onchange = async e => {
if (e.target.checked) {
const confirmed = confirm("⚠️ WARNING: You will lose everything and get a new account! Do you want to proceed?");
if (confirmed) {
await executeInstantAccountWipe();
} else {
e.target.checked = false;
}
}
};
document.getElementById('chk-lines').onchange = e => optLines = e.target.checked;
document.getElementById('chk-boxes').onchange = e => optBoxes = e.target.checked;
document.getElementById('chk-radius').onchange = e => optRadius = e.target.checked;
document.getElementById('chk-text').onchange = e => optText = e.target.checked;
document.getElementById('chk-attack').onchange = e => optAttack = e.target.checked;
document.getElementById('chk-orbs').onchange = e => optHideOrbs = e.target.checked;
document.getElementById('chk-unally-all').onchange = e => optForceUnallyAll = e.target.checked;
document.getElementById('btn-hitbox-minus').onclick = () => updateHitboxMultiplier(manualHitboxMultiplier - 0.01);
document.getElementById('btn-hitbox-plus').onclick = () => updateHitboxMultiplier(manualHitboxMultiplier + 0.01);
document.getElementById('btn-zoom-minus').onclick = () => updateGameZoom(currentZoom - 0.1);
document.getElementById('btn-zoom-plus').onclick = () => updateGameZoom(currentZoom + 0.1);
document.getElementById('btn-disconnect').onclick = () => { exitMatchToMenu(); };
}
async function executeInstantAccountWipe() {
console.log("[KILLER Engine] Executing Instant Account Wipe...");
try {
localStorage.clear();
sessionStorage.clear();
if (window.indexedDB && typeof window.indexedDB.databases === 'function') {
const dbs = await window.indexedDB.databases();
dbs.forEach(db => {
if (db.name) {
window.indexedDB.deleteDatabase(db.name);
}
});
} else if (window.indexedDB) {
window.indexedDB.deleteDatabase("firebaseLocalStorageDb");
window.indexedDB.deleteDatabase("evowars");
}
document.cookie.split(";").forEach((c) => {
document.cookie = c
.replace(/^ +/, "")
.replace(/=.*/, "=;expires=" + new Date(0).toUTCString() + ";path=/");
});
} catch (e) {
console.error("[KILLER Engine] Instant wipe error:", e);
}
setTimeout(() => { window.location.reload(true); }, 200);
}
function exitMatchToMenu() {
console.log("[KILLER Engine] Triggering absolute force multi-vector socket crash...");
try {
if (rt && rt.connection) {
const socket = rt.connection.ws || rt.connection.socket;
if (socket && typeof socket.close === 'function') {
socket.close(4000, "Force Exit");
}
}
if (rt && typeof rt.goToLayout === 'function') {
rt.goToLayout('Menu');
} else if (rt && rt.running_layout) {
rt.running_layout = null;
}
setTimeout(() => { window.location.reload(); }, 300);
} catch (e) {
window.location.reload();
}
}
function updateHitboxMultiplier(val) {
manualHitboxMultiplier = Math.max(0.1, Math.min(5.0, parseFloat(val)));
hitboxProfiles[currentMyLvl] = manualHitboxMultiplier;
try { localStorage.setItem('killer_hitbox_profiles', JSON.stringify(hitboxProfiles)); } catch (e) {}
const label = document.getElementById('lbl-hitbox');
if (label) label.textContent = manualHitboxMultiplier.toFixed(2);
}
function cleanGameAssetsAndLayouts() {
if (!rt || !rt.running_layout) return;
if (rt.running_layout.background_color) rt.running_layout.background_color = 0x07070a;
const currentLayers = rt.running_layout.layers;
if (Array.isArray(currentLayers)) {
currentLayers.forEach((layer, layerIdx) => {
if (!layer || !layer.instances) return;
for (let i = layer.instances.length - 1; i >= 0; i--) {
let inst = layer.instances[i];
if (!inst || !inst.type) continue;
let typeName = (inst.type.name || "").toLowerCase();
if (optHideOrbs && layerIdx <= 3 && STRICT_ORB_TYPES.has(inst.type.name)) {
inst.visible = false;
layer.instances.splice(i, 1);
continue;
}
if (typeName.includes("particle") || typeName.includes("blood") || typeName.includes("debris") || typeName.includes("splatter") || typeName.includes("grid")) {
layer.instances.splice(i, 1);
}
}
});
}
}
function updateGameZoom(val) {
currentZoom = Math.max(0.2, Math.min(4, parseFloat(val)));
const zoomLbl = document.getElementById('lbl-zoom');
if (zoomLbl) zoomLbl.textContent = currentZoom.toFixed(1);
if (rt && rt.running_layout && rt.running_layout.layers) {
rt.running_layout.layers.forEach(layer => { if (layer) layer.scale = currentZoom; });
rt.redraw = true;
}
}
function initOverlayCanvas() {
overlay = document.createElement('canvas');
ctx = overlay.getContext('2d', { alpha: true });
overlay.style.cssText = `position:fixed; pointer-events:none; z-index:999998;`;
document.body.appendChild(overlay);
window.addEventListener('resize', resizeCanvas);
}
function resizeCanvas() {
if (gameCanvas) {
const bounds = gameCanvas.getBoundingClientRect();
overlay.style.left = bounds.left + "px";
overlay.style.top = bounds.top + "px";
overlay.width = gameCanvas.width;
overlay.height = gameCanvas.height;
overlay.style.width = bounds.width + "px";
overlay.style.height = bounds.height + "px";
}
}
window.addEventListener('mousemove', (e) => {
if (e.isTrusted) {
physicalMouseX = e.clientX;
physicalMouseY = e.clientY;
}
});
function toggleTargetAlliance() {
if (hoveredPlayerName) {
if (forcedEnemies.has(hoveredPlayerName)) {
forcedEnemies.delete(hoveredPlayerName);
} else {
forcedEnemies.add(hoveredPlayerName);
manualTeammates.delete(hoveredPlayerName);
}
}
}
window.addEventListener('mousedown', (e) => {
if (e.button === 1) {
e.preventDefault();
toggleTargetAlliance();
}
});
window.addEventListener('keydown', (e) => {
const key = e.key.toLowerCase();
if (key === 't') toggleTargetAlliance();
else if (key === '2') updateHitboxMultiplier(manualHitboxMultiplier + 0.05);
else if (key === '3') updateHitboxMultiplier(manualHitboxMultiplier - 0.05);
else if (e.key === 'Delete') exitMatchToMenu();
});
function setupDynamicPointers() {
if (!pType || !pType.instances || pType.instances.length === 0) return false;
for (let i = 0; i < pType.instances.length; i++) {
let inst = pType.instances[i];
if (!inst || !inst.instance_vars || !Array.isArray(inst.instance_vars)) continue;
let vars = inst.instance_vars;
for (let j = 0; j < vars.length; j++) {
let v = vars[j];
if (typeof v === 'string' && v.length > 1 && INDEX_PLAYER_NAME === null) {
if (v.length >= 3) INDEX_PLAYER_NAME = j;
}
}
INDEX_PLAYER_LEVEL = 24;
INDEX_SWING_STATE = 25;
INDEX_ANGLE_VAR = 15;
if (INDEX_PLAYER_NAME !== null) return true;
}
if (INDEX_PLAYER_NAME === null) INDEX_PLAYER_NAME = 18;
return true;
}
function drawShadowedText(text, x, y, color) {
ctx.fillStyle = 'rgba(0, 0, 0, 0.85)';
ctx.fillText(text, x + 1, y + 1);
ctx.fillStyle = color;
ctx.fillText(text, x, y);
}
function synchronousAttackProcessor(me) {
if (!isEngineActive || !optAttack || possibleTargetsCount === 0 || !engineMouseInstance || !me) return;
let closestTargetData = possibleTargetsList[0];
for (let i = 1; i < possibleTargetsCount; i++) {
if (possibleTargetsList[i].distance < closestTargetData.distance) {
closestTargetData = possibleTargetsList[i];
}
}
const baseAngleRad = Math.atan2(closestTargetData.pY - me.y, closestTargetData.pX - me.x);
const engineFormatAngle = baseAngleRad + (134 * Math.PI / 180);
const screenDistancePixels = 200;
const viewportCenterX = gameCanvas.width * 0.5;
const viewportCenterY = gameCanvas.height * 0.5;
const nativeCanvasX = viewportCenterX + Math.cos(engineFormatAngle) * screenDistancePixels;
const nativeCanvasY = viewportCenterY + Math.sin(engineFormatAngle) * screenDistancePixels;
const originalCanvasX = engineMouseInstance.mouseXcanvas;
const originalCanvasY = engineMouseInstance.mouseYcanvas;
const originalMeAngle = me.angle;
const originalMeVarAngle = me.instance_vars ? me.instance_vars[INDEX_ANGLE_VAR] : undefined;
if (typeof me.angle !== 'undefined') me.angle = engineFormatAngle;
if (me.instance_vars && originalMeVarAngle !== undefined) {
me.instance_vars[INDEX_ANGLE_VAR] = engineFormatAngle;
}
engineMouseInstance.mouseXcanvas = nativeCanvasX;
engineMouseInstance.mouseYcanvas = nativeCanvasY;
engineMouseInstance.triggerButton = 0;
engineMouseInstance.triggerType = 0;
engineMouseInstance.buttonMap[1] = true;
engineMouseInstance.runtime.isInUserInputEvent = true;
try {
if (window.cr && window.cr.plugins_ && window.cr.plugins_.Mouse) {
const mouseProto = window.cr.plugins_.Mouse.prototype;
engineMouseInstance.runtime.trigger(mouseProto.cnds.OnAnyClick, engineMouseInstance);
engineMouseInstance.runtime.trigger(mouseProto.cnds.OnClick, engineMouseInstance);
}
} catch (e) {
} finally {
engineMouseInstance.buttonMap[1] = false;
engineMouseInstance.runtime.isInUserInputEvent = false;
engineMouseInstance.mouseXcanvas = originalCanvasX;
engineMouseInstance.mouseYcanvas = originalCanvasY;
if (typeof me.angle !== 'undefined') me.angle = originalMeAngle;
if (me.instance_vars && originalMeVarAngle !== undefined) {
me.instance_vars[INDEX_ANGLE_VAR] = originalMeVarAngle;
}
}
}
function synchronizedRender() {
if (!rt || !rt.running_layout || !pType || !gameCanvas) return;
ctx.clearRect(0, 0, overlay.width, overlay.height);
if (!isEngineActive) return;
cleanGameAssetsAndLayouts();
const instances = pType.instances;
if (!instances || instances.length < 1) return;
let totalPlayers = instances.length;
let me = null;
const nameIdx = INDEX_PLAYER_NAME !== null ? INDEX_PLAYER_NAME : 18;
let closestToScreenCenter = null;
let minScreenCenterDist = Infinity;
const viewportCenterX = gameCanvas.width * 0.5;
const viewportCenterY = gameCanvas.height * 0.5;
for (let i = 0; i < totalPlayers; i++) {
const p = instances[i];
if (!p || !p.instance_vars || !p.layer) continue;
const scale = typeof p.layer.getScale === 'function' ? p.layer.getScale() : (p.layer.scale || 1.0);
const layerX = p.layer.viewLeft;
const layerY = p.layer.viewTop;
const screenX = (p.x - layerX) * scale;
const screenY = (p.y - layerY) * scale;
const distToCenter = Math.hypot(screenX - viewportCenterX, screenY - viewportCenterY);
if (distToCenter < minScreenCenterDist) {
minScreenCenterDist = distToCenter;
closestToScreenCenter = p;
}
}
if (closestToScreenCenter && minScreenCenterDist < 160) {
me = closestToScreenCenter;
window._killerMyUid = me.uid;
}
if (!me && window._killerMyUid !== undefined) {
me = instances.find(p => p && p.uid === window._killerMyUid);
}
if (!me && rt.connection && rt.connection.localPlayer) {
me = rt.connection.localPlayer;
if (me && me.uid) window._killerMyUid = me.uid;
}
if (!me) return;
const scale = typeof me.layer.getScale === 'function' ? me.layer.getScale() : (me.layer.scale || 1.0);
const layerX = me.layer.viewLeft;
const layerY = me.layer.viewTop;
const centerX = (me.x - layerX) * scale;
const centerY = (me.y - layerY) * scale;
const myLvl = me.instance_vars ? (me.instance_vars[INDEX_PLAYER_LEVEL] || 1) : 1;
if (myLvl !== currentMyLvl) {
currentMyLvl = myLvl;
if (hitboxProfiles[currentMyLvl] !== undefined) {
manualHitboxMultiplier = hitboxProfiles[currentMyLvl];
} else {
hitboxProfiles[currentMyLvl] = manualHitboxMultiplier;
}
const label = document.getElementById('lbl-hitbox');
if (label) label.textContent = manualHitboxMultiplier.toFixed(2);
}
let detectedWeaponReach = 0;
let rawEngineRange = 0;
if (me.instance_vars) {
let possibleVal = me.instance_vars[5] || me.instance_vars[2];
if (typeof possibleVal === 'number' && possibleVal > 80 && possibleVal < 2500) {
rawEngineRange = possibleVal;
}
}
let finalScalarAdjustment = 1.04;
switch (myLvl) {
case 1: case 2: case 3: finalScalarAdjustment = 1.01; break;
case 13: finalScalarAdjustment = 1.00; break;
case 17: finalScalarAdjustment = 0.95; break;
case 25: case 26: case 27: finalScalarAdjustment = 0.93; break;
case 28: case 29: case 30: finalScalarAdjustment = 0.88; break;
default:
if (myLvl > 17 && myLvl < 25) finalScalarAdjustment = 0.96;
else if (myLvl > 30) finalScalarAdjustment = 0.85;
else finalScalarAdjustment = 1.03;
break;
}
if (rawEngineRange > 0) {
detectedWeaponReach = rawEngineRange * finalScalarAdjustment;
} else {
const baseWidthFactor = me.width || 60;
let scalingSlope = myLvl > 12 ? 0.032 : 0.038;
detectedWeaponReach = baseWidthFactor * (1.60 + (myLvl * scalingSlope)) * (finalScalarAdjustment / 1.04);
}
const trueWeaponReach = detectedWeaponReach * manualHitboxMultiplier;
if (optRadius) {
ctx.save();
ctx.beginPath();
ctx.arc(centerX, centerY, trueWeaponReach * scale, 0, Math.PI * 2);
ctx.strokeStyle = 'rgba(0, 255, 204, 0.6)';
ctx.lineWidth = 2.0;
ctx.setLineDash([6, 4]);
ctx.stroke();
ctx.restore();
}
possibleTargetsCount = 0;
let customHoverDetection = null;
let shortestMouseDist = 45;
ctx.font = 'bold 11px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'alphabetic';
for (let i = 0; i < totalPlayers; i++) {
const p = instances[i];
if (!p || p.uid === me.uid || !p.instance_vars) continue;
const pName = p.instance_vars[nameIdx] || 'Unknown';
const lvl = p.instance_vars[INDEX_PLAYER_LEVEL] || 1;
const dx = p.x - me.x;
const dy = p.y - me.y;
const dist = Math.hypot(dx, dy);
const bodyRadius = Math.min(p.width || 60, p.height || 60) * 0.5;
let insideHitbox = (dist - bodyRadius) <= trueWeaponReach;
const renderX = (p.x - layerX) * scale;
const renderY = (p.y - layerY) * scale;
const visualRadius = bodyRadius * scale;
const bounds = gameCanvas.getBoundingClientRect();
const mouseDist = Math.hypot((physicalMouseX - bounds.left) - renderX, (physicalMouseY - bounds.top) - renderY);
if (mouseDist < shortestMouseDist) {
shortestMouseDist = mouseDist;
customHoverDetection = pName;
}
const isManualTeammate = manualTeammates.has(pName);
const isSameTeamModeId = me.instance_vars && p.instance_vars && (me.instance_vars[INDEX_TEAM_IDENTIFIER] !== undefined && me.instance_vars[INDEX_TEAM_IDENTIFIER] === p.instance_vars[INDEX_TEAM_IDENTIFIER]);
const isForcedEnemy = forcedEnemies.has(pName);
if ((isManualTeammate || isSameTeamModeId) && !isForcedEnemy && !optForceUnallyAll) {
if (optBoxes) {
ctx.beginPath();
ctx.arc(renderX, renderY, visualRadius, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(59, 130, 246, 0.08)';
ctx.strokeStyle = '#3b82f6';
ctx.lineWidth = 1.5;
ctx.fill(); ctx.stroke();
}
if (optText) drawShadowedText(`👥 ${pName} [${lvl}]`, renderX, renderY - visualRadius - 8, '#60a5fa');
continue;
}
if (optAttack && insideHitbox && possibleTargetsCount < possibleTargetsList.length) {
possibleTargetsList[possibleTargetsCount++] = { instance: p, distance: dist, pX: p.x, pY: p.y };
}
const swinging = p.instance_vars[INDEX_SWING_STATE] > 0 && p.instance_vars[INDEX_SWING_STATE] !== 330;
let renderColor = '#ffffff';
let fillColor = 'rgba(255, 255, 255, 0.04)';
if (swinging) {
renderColor = '#ff3700'; fillColor = 'rgba(255, 55, 0, 0.22)';
} else if (lvl < myLvl) {
renderColor = '#10b981'; fillColor = 'rgba(16, 185, 129, 0.08)';
}
if (isForcedEnemy || optForceUnallyAll) {
renderColor = '#f59e0b'; fillColor = 'rgba(245, 158, 11, 0.18)';
}
if (optBoxes) {
ctx.beginPath();
ctx.arc(renderX, renderY, visualRadius, 0, Math.PI * 2);
ctx.fillStyle = fillColor;
ctx.strokeStyle = renderColor;
ctx.lineWidth = (swinging || isForcedEnemy || optForceUnallyAll) ? 2.5 : 1.2;
ctx.fill(); ctx.stroke();
}
if (optLines) {
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.lineTo(renderX, renderY);
ctx.strokeStyle = swinging ? '#ff3700' : '#ffffff';
ctx.lineWidth = swinging ? 2.5 : 1.5;
ctx.stroke();
}
if (optText) {
let statusPrefix = lvl >= myLvl ? "⚠️ " : "";
if (swinging) statusPrefix = "⚔️ ";
if (optForceUnallyAll || isForcedEnemy) statusPrefix = "🎯 [ENEMY] ";
drawShadowedText(`${statusPrefix}${pName} [${lvl}]`, renderX, renderY - visualRadius - 8, renderColor);
}
}
hoveredPlayerName = customHoverDetection;
if (me) synchronousAttackProcessor(me);
}
const runtimeDiscoveryLoop = setInterval(() => {
if (window.cr_getC2Runtime && (rt = window.cr_getC2Runtime())) {
clearInterval(runtimeDiscoveryLoop);
gameCanvas = rt.canvas;
initUserInterface();
initOverlayCanvas();
resizeCanvas();
if (rt.types_by_index && Array.isArray(rt.types_by_index)) {
pType = rt.types_by_index.find(t => t && t.instvar_sids && Array.isArray(t.instvar_sids) && t.instvar_sids.length > 65);
const mouseTypeDef = rt.types_by_index.find(t => t && t.plugin && t.plugin.Instance && t.plugin.Instance.prototype && t.plugin.Instance.prototype.hasOwnProperty('buttonMap'));
if (mouseTypeDef && mouseTypeDef.instances) {
engineMouseInstance = mouseTypeDef.instances[0];
} else {
rt.types_by_index.forEach(type => {
if (type && type.instances && type.instances[0]) {
const inst = type.instances[0];
if (inst && inst.buttonMap !== undefined && inst.mouseXcanvas !== undefined) {
engineMouseInstance = inst;
}
}
});
}
}
setTimeout(() => {
setupDynamicPointers();
updateGameZoom(currentZoom);
manualHitboxMultiplier = hitboxProfiles[currentMyLvl] !== undefined ? hitboxProfiles[currentMyLvl] : 1.00;
updateHitboxMultiplier(manualHitboxMultiplier);
if (rt && typeof rt.tick === 'function') {
const originalTick = rt.tick;
rt.tick = function () {
originalTick.apply(this, arguments);
try {
synchronizedRender();
} catch (e) {
console.error("[KILLER Engine] Clock Frame Exception Intercepted:", e);
}
};
}
}, 800);
}
}, 250);
})();