Greasy Fork

Canadian100's client (survev.io)

Aimbot, Auto-Shoot, Spinbot, Explosive Warning, Red Lines, See Through Buildings, Enemy Health Bars for Survev.io with GUI toggle system, brightness changer, opacity changerr, fps regualtor, and other key features.

// ==UserScript==
// @name         Canadian100's client (survev.io)
// @namespace    http://tampermonkey.net/
// @version      4.5
// @description  Aimbot, Auto-Shoot, Spinbot, Explosive Warning, Red Lines, See Through Buildings, Enemy Health Bars for Survev.io with GUI toggle system, brightness changer, opacity changerr, fps regualtor, and other key features.
// @author       Canadian100
// @match        *://survev.io/*
// @grant        unsafeWindow
// @run-at       document-end
// ==/UserScript==
(function () {
    // Default feature states
    let espEnabled = false;
    let aimbotEnabled = false;
    let autoShootEnabled = false;
    let spinbotEnabled = false;
    let explosiveWarningEnabled = true;
    let drawEnemyLines = false;
    let seeThroughBuildingsEnabled = false;
    let showHealthBars = false;
    let meleeAimbotEnabled = false;

    // FPS and Ping variables
    let fps = 0;
    let ping = 0;
    let lastTime = performance.now();
    let frames = 0;

    // Canvas Overlay Setup
    const canvas = document.createElement('canvas');
    canvas.style.position = 'fixed';
    canvas.style.top = '0';
    canvas.style.left = '0';
    canvas.style.pointerEvents = 'none';
    canvas.style.zIndex = '9998';
    document.body.appendChild(canvas);
    const ctx = canvas.getContext('2d');

    // Update Canvas Size
    function updateCanvasSize() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
    window.addEventListener('resize', updateCanvasSize);
    updateCanvasSize();
    // FPS Calculation
    function updateFPS() {
        const currentTime = performance.now();
        frames++;
        if (currentTime - lastTime >= 1000) {
            fps = frames;
            frames = 0;
            lastTime = currentTime;
        }
    }

    // Ping Calculation
    function updatePing() {
        const startTime = performance.now();
        fetch("https://www.google.com/")
            .then(response => response.text())
            .then(() => {
                const endTime = performance.now();
                ping = endTime - startTime;
            })
            .catch(() => ping = 0);
    }

    // Stats Box Setup
    const statsBox = document.createElement('div');
    statsBox.style.position = 'fixed';
    statsBox.style.top = '300px';
    statsBox.style.left = '20px';
    statsBox.style.padding = '15px';
    statsBox.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
    statsBox.style.borderRadius = '10px';
    statsBox.style.color = 'white';
    statsBox.style.fontFamily = 'Arial, sans-serif';
    statsBox.style.zIndex = '9999';
    statsBox.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)';
    document.body.appendChild(statsBox);
    const fpsElement = document.createElement('div');
    const pingElement = document.createElement('div');
    const killsElement = document.createElement('div');

    fpsElement.style.fontSize = '18px';
    pingElement.style.fontSize = '18px';
    killsElement.style.fontSize = '18px';

    statsBox.appendChild(fpsElement);
    statsBox.appendChild(pingElement);
    statsBox.appendChild(killsElement);

    function updateStats() {
        fpsElement.textContent = `FPS: ${fps}`;
        pingElement.textContent = `Ping: ${ping.toFixed(2)} ms`;
        killsElement.textContent = `Kills: ${unsafeWindow.activePlayer?.kills || 0}`;
    }

    setInterval(() => {
        updateFPS();
        updatePing();
        updateStats();
    }, 1000 / 60);
    const popupWindow = document.createElement('div');
    popupWindow.style.position = 'fixed';
    popupWindow.style.top = '50%';
    popupWindow.style.left = '50%';
    popupWindow.style.transform = 'translate(-50%, -50%)';
    popupWindow.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
    popupWindow.style.color = 'white';
    popupWindow.style.padding = '20px';
    popupWindow.style.borderRadius = '10px';
    popupWindow.style.display = 'none';
    popupWindow.style.zIndex = '9999';
    document.body.appendChild(popupWindow);

    popupWindow.innerHTML = `
        <h2>Enable Features</h2>
        <label><input type="checkbox" id="aimbotCheckbox"> Aimbot [X]</label><br>
        <label><input type="checkbox" id="autoShootCheckbox"> Trigger Bot [Z]</label><br>
        <label><input type="checkbox" id="spinbotCheckbox"> Spinbot [C]</label><br>
        <label><input type="checkbox" id="explosiveWarningCheckbox"> Explosive Warning [I]</label><br>
        <label><input type="checkbox" id="enemyLinesCheckbox"> Red Lines to Enemies [K]</label><br>
        <label><input type="checkbox" id="seeThroughCheckbox"> See Through Buildings [Y]</label><br>
        <label><input type="checkbox" id="healthBarCheckbox"> Show Enemy Health Bars [H]</label><br>
        <label><input type="checkbox" id="espCheckbox"> ESP Line to Player [E]</label><br>
        <label><input type="checkbox" id="meleeAimbotCheckbox"> Melee Aimbot [M]</label><br>
        <button id="closePopupButton">Close</button>
    `;
    const espCheckbox = document.getElementById('espCheckbox');
    const aimbotCheckbox = document.getElementById('aimbotCheckbox');
    const autoShootCheckbox = document.getElementById('autoShootCheckbox');
    const spinbotCheckbox = document.getElementById('spinbotCheckbox');
    const explosiveWarningCheckbox = document.getElementById('explosiveWarningCheckbox');
    const enemyLinesCheckbox = document.getElementById('enemyLinesCheckbox');
    const seeThroughCheckbox = document.getElementById('seeThroughCheckbox');
    const healthBarCheckbox = document.getElementById('healthBarCheckbox');
    const meleeAimbotCheckbox = document.getElementById('meleeAimbotCheckbox');
    const closePopupButton = document.getElementById('closePopupButton');

    function togglePopup() {
        popupWindow.style.display = popupWindow.style.display === 'none' ? 'block' : 'none';
    }

    closePopupButton.addEventListener('click', togglePopup);

    window.addEventListener('keydown', (e) => {
        switch (e.key.toLowerCase()) {
            case 'e': espEnabled = !espEnabled; espCheckbox.checked = espEnabled; break;
            case 'x': aimbotEnabled = !aimbotEnabled; aimbotCheckbox.checked = aimbotEnabled; break;
            case 'z': autoShootEnabled = !autoShootEnabled; autoShootCheckbox.checked = autoShootEnabled; break;
            case 'c': spinbotEnabled = !spinbotEnabled; spinbotCheckbox.checked = spinbotEnabled; break;
            case 'i': explosiveWarningEnabled = !explosiveWarningEnabled; explosiveWarningCheckbox.checked = explosiveWarningEnabled; break;
            case 'k': drawEnemyLines = !drawEnemyLines; enemyLinesCheckbox.checked = drawEnemyLines; break;
            case 'y': seeThroughBuildingsEnabled = !seeThroughBuildingsEnabled; seeThroughCheckbox.checked = seeThroughBuildingsEnabled; break;
            case 'h': showHealthBars = !showHealthBars; healthBarCheckbox.checked = showHealthBars; break;
            case 'm': meleeAimbotEnabled = !meleeAimbotEnabled; meleeAimbotCheckbox.checked = meleeAimbotEnabled; break;
            case 't': togglePopup(); break;
        }
    });
    function triggerBot(player) {
        if (!autoShootEnabled || !player || !player.weapon || !player.weapon.canShoot) return;

        const enemies = unsafeWindow.players.filter(p =>
            p && p.isAlive && p.team !== player.team && isVisible(player, p)
        );

        const target = enemies.find(enemy => {
            const dist = distance(player.x, player.y, enemy.x, enemy.y);
            return dist < 400;
        });

        if (target) player.weapon.shoot();
    }
    function drawExplosiveWarning(ctx, player) {
        if (!explosiveWarningEnabled) return;

        unsafeWindow.projectiles.forEach(proj => {
            if (proj.type === 'explosive') {
                const dist = distance(player.x, player.y, proj.x, proj.y);
                if (dist < 200) {
                    ctx.beginPath();
                    ctx.arc(proj.x, proj.y, 30, 0, 2 * Math.PI);
                    ctx.strokeStyle = 'red';
                    ctx.lineWidth = 2;
                    ctx.stroke();
                }
            }
        });
    }
    function drawHealthBars(ctx, player) {
        if (!showHealthBars) return;

        unsafeWindow.players.forEach(enemy => {
            if (enemy.team !== player.team && enemy.isAlive) {
                ctx.fillStyle = 'green';
                ctx.fillRect(enemy.x - 20, enemy.y - 40, 40 * (enemy.health / enemy.maxHealth), 5);
                ctx.strokeStyle = 'black';
                ctx.strokeRect(enemy.x - 20, enemy.y - 40, 40, 5);
            }
        });
    }
    function drawESP(ctx, player) {
        if (!espEnabled) return;
        ctx.lineWidth = 2;
        ctx.strokeStyle = 'lime';

        unsafeWindow.players.forEach(enemy => {
            if (enemy.team !== player.team && enemy.isAlive) {
                ctx.beginPath();
                ctx.moveTo(player.x, player.y);
                ctx.lineTo(enemy.x, enemy.y);
                ctx.stroke();
            }
        });
    }
    function seeThroughBuildings() {
        if (!seeThroughBuildingsEnabled) return;

        const obstacles = document.querySelectorAll('.bunker, .building');
        obstacles.forEach(obs => {
            obs.style.opacity = '0.3';
        });
    }
    function aimbot(player) {
        if (!aimbotEnabled || !player || !player.weapon) return;

        const enemies = unsafeWindow.players.filter(p =>
            p && p.isAlive && p.team !== player.team && isVisible(player, p)
        );

        let closest = null;
        let closestDist = Infinity;

        enemies.forEach(enemy => {
            const dist = distance(player.x, player.y, enemy.x, enemy.y);
            if (dist < closestDist) {
                closestDist = dist;
                closest = enemy;
            }
        });

        if (closest) {
            const dx = closest.x - player.x;
            const dy = closest.y - player.y;
            const angle = Math.atan2(dy, dx);
            player.aimAngle = angle;
        }
    }
    function meleeAimbot(player) {
        if (!meleeAimbotEnabled || !player || !player.weapon || player.weapon.type !== 'melee') return;

        const enemies = unsafeWindow.players.filter(p =>
            p && p.isAlive && p.team !== player.team && isVisible(player, p)
        );

        let closest = null;
        let closestDist = Infinity;

        enemies.forEach(enemy => {
            const dist = distance(player.x, player.y, enemy.x, enemy.y);
            if (dist < closestDist) {
                closestDist = dist;
                closest = enemy;
            }
        });

        if (closest) {
            const dx = closest.x - player.x;
            const dy = closest.y - player.y;
            player.aimAngle = Math.atan2(dy, dx);

            player.moveX = Math.sign(dx);
            player.moveY = Math.sign(dy);

            if (closestDist < 50 && player.weapon.canAttack) {
                player.weapon.attack();
            }
        }
    }
    let spinAngle = 0;
    function spinbot(player) {
        if (!spinbotEnabled || !player) return;
        spinAngle += 0.3;
        player.aimAngle = spinAngle;
    }
    function drawTracerLines(ctx, player) {
        if (!drawEnemyLines) return;

        ctx.strokeStyle = 'red';
        ctx.lineWidth = 10;

        unsafeWindow.players.forEach(enemy => {
            if (enemy.isAlive && enemy.team !== player.team) {
                ctx.beginPath();
                ctx.moveTo(player.x, player.y);
                ctx.lineTo(enemy.x + enemy.vx * 3, enemy.y + enemy.vy * 3); // Predictive
                ctx.stroke();
            }
        });
    }
    function distance(x1, y1, x2, y2) {
        return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
    }

    function isVisible(player, enemy) {
        return true; // Placeholder: add raycast/visibility check here if needed
    }
    setInterval(() => {
        const player = unsafeWindow.activePlayer;
        if (!player) return;

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        aimbot(player);
        meleeAimbot(player);
        triggerBot(player);
        spinbot(player);
        seeThroughBuildings();
        drawESP(ctx, player);
        drawTracerLines(ctx, player);
        drawExplosiveWarning(ctx, player);
        drawHealthBars(ctx, player);
    }, 1000 / 60);
})(); // END of entire userscript

(function () {
    // Declare the GUI container but don't append it yet
    let guiContainer;

    // Function to create and display the GUI container when the 'L' key is pressed
    function createGUI() {
        // Create the draggable GUI container
        guiContainer = document.createElement('div');
        guiContainer.style.position = 'fixed';
        guiContainer.style.left = '50%';
        guiContainer.style.top = '50%';
        guiContainer.style.transform = 'translate(-50%, -50%)';
        guiContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
        guiContainer.style.padding = '20px';
        guiContainer.style.borderRadius = '10px';
        guiContainer.style.color = 'white';
        guiContainer.style.zIndex = '9999';
        guiContainer.style.display = 'none'; // Initially hidden
        guiContainer.style.display = 'flex';
        guiContainer.style.flexDirection = 'column'; // Stack elements vertically
        guiContainer.style.gap = '10px'; // Adds space between elements
        guiContainer.style.maxWidth = '150px'; // Max width of the HUD container
        guiContainer.style.width = '100%'; // Allows for responsive resizing while respecting max-width
        document.body.appendChild(guiContainer);

        // Add title to the GUI
        const title = document.createElement('h2');
        title.innerText = 'Game Settings';
        guiContainer.appendChild(title);

        // Brightness control label
        const brightnessLabel = document.createElement('label');
        brightnessLabel.innerText = 'Set Game Brightness: ';
        guiContainer.appendChild(brightnessLabel);

        // Create brightness slider
        const brightnessSlider = document.createElement('input');
        brightnessSlider.type = 'range';
        brightnessSlider.min = '0';
        brightnessSlider.max = '2';
        brightnessSlider.step = '0.01';
        brightnessSlider.value = '1'; // Default brightness
        guiContainer.appendChild(brightnessSlider);

        // Event listener for brightness slider
        brightnessSlider.addEventListener('input', function () {
            // Update the brightness of the game
            const brightnessValue = brightnessSlider.value;
            document.body.style.filter = `brightness(${brightnessValue})`;
        });

        // Opacity control label for environment elements (trees, buildings, containers, bushes)
        const opacityLabel = document.createElement('label');
        opacityLabel.innerText = 'Set Environment Opacity: ';
        guiContainer.appendChild(opacityLabel);

        // Create opacity slider
        const opacitySlider = document.createElement('input');
        opacitySlider.type = 'range';
        opacitySlider.min = '0';
        opacitySlider.max = '1';
        opacitySlider.step = '0.01';
        opacitySlider.value = '1'; // Default opacity
        guiContainer.appendChild(opacitySlider);

        // Event listener for opacity slider
        opacitySlider.addEventListener('input', function () {
            // Update opacity of in-game objects (trees, buildings, containers, bushes)
            const opacityValue = opacitySlider.value;
            const environmentObjects = document.querySelectorAll('.tree, .building, .container, .bush'); // Example classes
            environmentObjects.forEach(object => {
                object.style.opacity = opacityValue; // Apply opacity to each object
            });
        });

        // Max FPS control label
        const fpsLabel = document.createElement('label');
        fpsLabel.innerText = 'Set Max FPS: ';
        guiContainer.appendChild(fpsLabel);

        // Create FPS slider
        const fpsSlider = document.createElement('input');
        fpsSlider.type = 'range';
        fpsSlider.min = '0';
        fpsSlider.max = '500';
        fpsSlider.step = '1';
        fpsSlider.value = '60'; // Default FPS
        guiContainer.appendChild(fpsSlider);

        // Event listener for FPS slider
        fpsSlider.addEventListener('input', function () {
            // Set the max FPS based on slider value
            const fpsValue = fpsSlider.value;
            // Example FPS limiter (adjust as needed)
            document.querySelector('canvas').style['max-fps'] = fpsValue;
        });

        // Add Lock HUD checkbox (placed under the last slider)
        const lockHudLabel = document.createElement('label');
        lockHudLabel.innerText = 'Lock HUD in Place: ';
        guiContainer.appendChild(lockHudLabel);

        const lockHudCheckbox = document.createElement('input');
        lockHudCheckbox.type = 'checkbox';
        guiContainer.appendChild(lockHudCheckbox);

        // Draggable HUD logic
        let isDragging = false;
        let offsetX, offsetY;
        let isHudLocked = false;

        // Make the GUI container draggable (if not locked)
        guiContainer.addEventListener('mousedown', (e) => {
            if (!isHudLocked) {
                isDragging = true;
                offsetX = e.clientX - guiContainer.offsetLeft;
                offsetY = e.clientY - guiContainer.offsetTop;
            }
        });

        document.addEventListener('mousemove', (e) => {
            if (isDragging && !isHudLocked) {
                guiContainer.style.left = `${e.clientX - offsetX}px`;
                guiContainer.style.top = `${e.clientY - offsetY}px`;
            }
        });

        document.addEventListener('mouseup', () => {
            isDragging = false;
        });

        // Listen for lock/unlock checkbox change
        lockHudCheckbox.addEventListener('change', function () {
            isHudLocked = lockHudCheckbox.checked; // Lock or unlock the HUD based on checkbox state
        });
    }

    // Toggle GUI visibility with "L" key
    let guiVisible = false;
    function toggleGUI() {
        if (!guiVisible) {
            createGUI(); // Create the GUI if not already created
        }
        guiVisible = !guiVisible;
        guiContainer.style.display = guiVisible ? 'block' : 'none'; // Show/hide the container
    }

    // Keybind for showing/hiding the GUI
    window.addEventListener('keydown', (event) => {
        if (event.key.toLowerCase() === 'l') {
            toggleGUI();
        }
    });
})();
(function () {
    let locked = false;

    // 🧹 Remove any existing HUD first
    const existingHud = document.getElementById('customHud');
    if (existingHud) {
        existingHud.remove();
    }

    // Create the HUD
    const hud = document.createElement('div');
    hud.id = 'customHud'; // Unique ID to detect duplicates
    Object.assign(hud.style, {
        position: 'fixed',
        top: '50%',
        left: '50%',
        transform: 'translate(-50%, -50%)',
        backgroundColor: 'rgba(0, 0, 0, 0.8)',
        color: 'white',
        padding: '20px',
        borderRadius: '10px',
        zIndex: '9999',
        cursor: 'move',
        display: 'block'
    });
    document.body.appendChild(hud);

    // Draggable logic
    let isDragging = false;
    let offsetX = 0, offsetY = 0;

    hud.addEventListener('mousedown', (e) => {
        if (!locked) {
            isDragging = true;
            offsetX = e.clientX - hud.offsetLeft;
            offsetY = e.clientY - hud.offsetTop;
            document.addEventListener('mousemove', onMouseMove);
        }
    });

    document.addEventListener('mouseup', () => {
        isDragging = false;
        document.removeEventListener('mousemove', onMouseMove);
    });

    function onMouseMove(e) {
        if (isDragging && !locked) {
            hud.style.left = `${e.clientX - offsetX}px`;
            hud.style.top = `${e.clientY - offsetY}px`;
        }
    }

    // HUD content
    const naturalFeaturesElement = document.createElement('div');
    const featuresElement = document.createElement('div');
    const quickSwitchElement = document.createElement('div');
    const fpsElement = document.createElement('div');
    const pingElement = document.createElement('div');
    const devInfoElement = document.createElement('div');
    const disableTextElement = document.createElement('div');

    naturalFeaturesElement.textContent = 'L = Natural Game Features';
    featuresElement.textContent = 'T = Key Features 👀';
    quickSwitchElement.textContent = 'O = Quick Switch Feature';
    fpsElement.textContent = 'FPS Rate: Adjusts every 100ms';
    pingElement.textContent = 'Ping: Developing at the moment';
    devInfoElement.textContent = 'This client is still under development. Report bugs to canadian100.0 on Discord.';
    disableTextElement.textContent = "Press 'n' to disable this HUD";

    hud.appendChild(naturalFeaturesElement);
    hud.appendChild(featuresElement);
    hud.appendChild(quickSwitchElement);
    hud.appendChild(fpsElement);
    hud.appendChild(pingElement);
    hud.appendChild(devInfoElement);
    hud.appendChild(disableTextElement);

    // Lock checkbox
    const lockCheckbox = document.createElement('input');
    lockCheckbox.type = 'checkbox';
    lockCheckbox.id = 'lockHudCheckbox';
    const lockLabel = document.createElement('label');
    lockLabel.textContent = ' Lock HUD in Place';
    lockLabel.setAttribute('for', 'lockHudCheckbox');
    hud.appendChild(lockCheckbox);
    hud.appendChild(lockLabel);

    lockCheckbox.addEventListener('change', () => {
        locked = lockCheckbox.checked;
    });

    // FPS tracking
    let fps = 0;
    let frames = 0;
    let lastTime = performance.now();

    function updateFPS() {
        const currentTime = performance.now();
        frames++;
        if (currentTime - lastTime >= 100) {
            fps = frames;
            frames = 0;
            lastTime = currentTime;
            fpsElement.textContent = `FPS Rate: Adjusts every 100ms - ${fps}`;
        }
    }

    setInterval(updateFPS, 100);

    // Toggle HUD visibility with 'n'
    window.addEventListener('keydown', (e) => {
        if (e.key.toLowerCase() === 'n') {
            hud.style.display = hud.style.display === 'none' ? 'block' : 'none';
        }
    });
})();
(function () {
    let isHudVisible = false;
    let isLocked = false;
    let switchDelay = 1000;
    let singleShotEnabled = false;
    let outOfAmmoEnabled = false;

    // Create HUD
    const hud = document.createElement('div');
    Object.assign(hud.style, {
        position: 'fixed',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)',
        background: 'rgba(0,0,0,0.8)',
        color: '#fff',
        padding: '15px',
        borderRadius: '10px',
        maxWidth: '180px',
        zIndex: 9999,
        fontSize: '12px',
        userSelect: 'none',
        flexDirection: 'column',
        gap: '8px',
        cursor: 'move',
        display: 'none'
    });
    hud.style.display = 'none';
    hud.style.display = 'flex';
    hud.style.display = 'none'; // Make sure it starts hidden
    document.body.appendChild(hud);

    // Delay Slider
    const delayLabel = document.createElement('label');
    delayLabel.textContent = 'Switch Delay (ms)';
    const delaySlider = document.createElement('input');
    delaySlider.type = 'range';
    delaySlider.min = 100;
    delaySlider.max = 3000;
    delaySlider.step = 100;
    delaySlider.value = switchDelay;
    delaySlider.addEventListener('input', () => {
        switchDelay = parseInt(delaySlider.value);
    });

    // Checkbox: After Single Shot
    const singleShotBox = document.createElement('input');
    singleShotBox.type = 'checkbox';
    singleShotBox.addEventListener('change', () => {
        singleShotEnabled = singleShotBox.checked;
    });
    const singleShotLabel = document.createElement('label');
    singleShotLabel.textContent = 'After Single Shot';
    singleShotLabel.prepend(singleShotBox);

    // Checkbox: Out of Ammo
    const outOfAmmoBox = document.createElement('input');
    outOfAmmoBox.type = 'checkbox';
    outOfAmmoBox.addEventListener('change', () => {
        outOfAmmoEnabled = outOfAmmoBox.checked;
    });
    const outOfAmmoLabel = document.createElement('label');
    outOfAmmoLabel.textContent = 'Out of Ammo';
    outOfAmmoLabel.prepend(outOfAmmoBox);

    // Checkbox: Lock HUD
    const lockBox = document.createElement('input');
    lockBox.type = 'checkbox';
    lockBox.addEventListener('change', () => {
        isLocked = lockBox.checked;
    });
    const lockLabel = document.createElement('label');
    lockLabel.textContent = 'Lock HUD';
    lockLabel.prepend(lockBox);

    // Append to HUD
    hud.appendChild(delayLabel);
    hud.appendChild(delaySlider);
    hud.appendChild(singleShotLabel);
    hud.appendChild(outOfAmmoLabel);
    hud.appendChild(lockLabel);

    // Drag logic
    let isDragging = false, offsetX = 0, offsetY = 0;
    hud.addEventListener('mousedown', (e) => {
        if (isLocked) return;
        isDragging = true;
        offsetX = e.clientX - hud.offsetLeft;
        offsetY = e.clientY - hud.offsetTop;
    });
    document.addEventListener('mousemove', (e) => {
        if (isDragging && !isLocked) {
            hud.style.left = `${e.clientX - offsetX}px`;
            hud.style.top = `${e.clientY - offsetY}px`;
        }
    });
    document.addEventListener('mouseup', () => isDragging = false);

    // Toggle HUD with 'O'
    window.addEventListener('keydown', (e) => {
        if (e.key.toLowerCase() === 'o') {
            isHudVisible = !isHudVisible;
            hud.style.display = isHudVisible ? 'flex' : 'none';
        }
    });

    // Dummy game interaction simulation (replace with real logic)
    function switchWeaponSlot() {
        const slots = [1, 2, 3].filter(slot => true); // All usable
        let currentSlot = getCurrentSlot(); // Replace this
        let nextIndex = (slots.indexOf(currentSlot) + 1) % slots.length;
        simulateKeyPress(slots[nextIndex].toString());
    }

    function getCurrentSlot() {
        return 1; // Replace with actual game detection
    }

    function simulateKeyPress(key) {
        document.dispatchEvent(new KeyboardEvent('keydown', { key }));
    }

    function switchWeaponSlotWithDelay() {
        setTimeout(() => switchWeaponSlot(), switchDelay);
    }

    // Trigger test loop (replace with actual game events)
    setInterval(() => {
        if (singleShotEnabled || outOfAmmoEnabled) {
            switchWeaponSlotWithDelay();
        }
    }, 3000);
})();