Greasy Fork is available in English.

Diep.io Triflank v2

Doesn't work with a theme script. Press F to toggle and R and T to change modes.

// ==UserScript==
// @name         Diep.io Triflank v2
// @namespace    http://tampermonkey.net/
// @version      2024-12-15
// @description  Doesn't work with a theme script. Press F to toggle and R and T to change modes.
// @author       Mi300
// @match        https://diep.io/*
// @icon         https://upload.wikimedia.org/wikipedia/commons/2/25/Cube_Animation.gif
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==
const _window = typeof unsafeWindow === "undefined" ? window : unsafeWindow;
const canvas = document.getElementById("canvas");
const crc = CanvasRenderingContext2D.prototype;
let currentTransform;
let curTank = "";
let lastSwitch = Date.now();
let scriptActive = 0;
let mouseX = 0;
let mouseY = 0;
let invMouse = false;
let angleOffset = 0;
document.addEventListener("keydown", function(event) {
    if (event.code === "KeyF") {
        scriptActive ^= 1;
        diepAlert(`Toggled Script ${scriptActive ? "ON" : "OFF"}`);
    }
    if (event.code === "KeyR") {
        curRotation = rotations[++position % rotations.length];
        diepAlert(`Switched Type To ${curRotation.name}`);
    }
    if (event.code === "KeyT") {
        curRotation = rotations[--position % rotations.length];
        diepAlert(`Switched Type To ${curRotation.name}`);
    }
    if (event.code === "KeyX") {
        switchTank();
    }
});
document.addEventListener("mousemove", function(event) {
    [mouseX, mouseY] = [event.clientX, event.clientY];
});
const rotations = [{
        name: "Tri-Flank",
        toSwitch: ["Tri-Angle"],
        toUpgrade: ["Flank Guard"],
        upgradeIndex: 0,
    },
    {
        name: "Deathstar",
        toSwitch: ["Octo Tank"],
        toUpgrade: ["Quad Tank"],
        upgradeIndex: 0,
    },
    {
        name: "Twin-Basic",
        toSwitch: ["Twin"],
        toUpgrade: ["Tank"],
        upgradeIndex: 0,
    },
    {
        name: "Gunner Trapper",
        toSwitch: ["Gunner Trapper"],
        toUpgrade: ["Trapper"],
        upgradeIndex: 1,
    },
    {
        name: "Trapper Spam",
        toSwitch: ["Tri-Trapper", "Mega Trapper", "Overtrapper", "Gunner Trapper"],
        toUpgrade: ["Trapper"],
        upgradeIndex: 0,
    },
    {
        name: "Bomber",
        toSwitch: ["Destroyer", "Tri-Angle", "Flank Guard"],
        toUpgrade: ["Machine Gun"],
        upgradeIndex: 0,
    },
    {
        name: "Twin-Triplet",
        toSwitch: ["Triple Shot", "Triplet"],
        toUpgrade: ["Twin"],
        upgradeIndex: 0,
    },
]
const upgradeColors = ["#8efffb", "#b4ff8e", "#ff8e8e", "#ffeb8e", "#8eb2ff", "#b58eff"];
const upgradeColorTable = {
    "#8efffb": 0,
    "#b4ff8e": 1,
    "#ff8e8e": 2,
    "#ffeb8e": 3,
    "#8eb2ff": 4,
    "#b58eff": 5,
}

let upgradeButtonMap = new Map();
let position = rotations.length * 1000000;
let curRotation = rotations[position % rotations.length];

function diepAlert(c) {
    _window.extern && _window.extern.inGameNotification(c);
}

function getOffsetCoords(x, y) {
    //return [_window.innerWidth - x, _window.innerHeight - y];
    const cosine = Math.cos(angleOffset);
    const sine = Math.sin(angleOffset);
    const tank_x = _window.innerWidth / 2;
    const tank_y = _window.innerHeight / 2;

    const ox = mouseX - _window.innerWidth / 2;
    const oy = mouseY - _window.innerHeight / 2;
    const _rx = cosine * ox - sine * oy;
    const _ry = sine * ox + cosine * oy;
    const rotated_x = _rx + tank_x;
    const rotated_y = _ry + tank_y;
    return [rotated_x, rotated_y];
}

function setMousePos(x, y) {
    _window.extern.onTouchMove(-1, x, y);
}

function upgradeTank(index) {
    _window.extern.onTouchStart(0, ...upgradeButtonMap.get(index));
    _window.extern.onTouchEnd(0, ...upgradeButtonMap.get(index));
}

function switchTank() {
    _window.extern && _window.extern.onKeyDown(64);

    setTimeout(function() {
        _window.extern && _window.extern.onKeyUp(64);
    }, 100);
}

function onScriptTick() {
    if (!scriptActive || curRotation.name === "Gunner Trapper" || curRotation.name === "Deathstar") {
        return;
    }
    if (curRotation.toUpgrade.includes(curTank)) {
        upgradeTank(curRotation.upgradeIndex);
    } else if (curRotation.toSwitch.includes(curTank)) {
        switchTank();
    }
}
setInterval(onScriptTick, 200);

function gtrapper() {
    if (!scriptActive || curRotation.name !== "Gunner Trapper") {
        return;
    }

    if (curRotation.toUpgrade.includes(curTank)) {
        upgradeTank(curRotation.upgradeIndex);
    } else if (curRotation.toSwitch.includes(curTank)) {
        setTimeout(function() {
            switchTank()

            setTimeout(function() {
                angleOffset = Math.PI;
                setMousePos(...getOffsetCoords(mouseX, mouseY));
                invMouse = true;
            }, 40);
            setTimeout(function() {
                invMouse = false;
                setMousePos(mouseX, mouseY);
            }, 175);
        }, 75);
    }
}

function deathstar() {
    if (!scriptActive || curRotation.name !== "Deathstar") {
        return;
    }
    if (curRotation.toUpgrade.includes(curTank)) {
        upgradeTank(curRotation.upgradeIndex);
    } else if (curRotation.toSwitch.includes(curTank)) {
        setTimeout(function() {
            switchTank();

            setTimeout(function() {
                angleOffset = Math.PI / 4;
                setMousePos(...getOffsetCoords(mouseX, mouseY));
                invMouse = true;
            }, 100);
            setTimeout(function() {
                invMouse = false;
                setMousePos(mouseX, mouseY);
            }, 250);

            setTimeout(function() {
                angleOffset = Math.PI / 4;
                setMousePos(...getOffsetCoords(mouseX, mouseY));
                invMouse = true;
            }, 500);
            setTimeout(function() {
                invMouse = false;
                setMousePos(mouseX, mouseY);
            }, 650);
        }, 75);
    }
}
setInterval(gtrapper, 750);
setInterval(deathstar, 750);


const mouseHandler = {
    apply(method, thisArg, args) {
        if (invMouse) {
            args = [args[0], ...getOffsetCoords(args[1], args[2])];
        }
        return Reflect.apply(method, thisArg, args);
    }
}

let awaitGameLoad = setInterval(function() {
    if (!_window.extern) {
        return;
    }
    clearInterval(awaitGameLoad);
    _window.extern.onTouchStart = new Proxy(_window.extern.onTouchStart, mouseHandler);
    _window.extern.onTouchEnd = new Proxy(_window.extern.onTouchEnd, mouseHandler);
    _window.extern.onTouchMove = new Proxy(_window.extern.onTouchMove, mouseHandler);
}, 400);




crc.strokeText = new Proxy(crc.strokeText, {
    apply: function(m, c, [text, ...blah]) {
        if (text.startsWith("Lvl ")) {
            curTank = text[5] === " " ? text.slice(6) : text.slice(7);
        }
        return Reflect.apply(m, c, [text, ...blah]);
    }
});
crc.fillRect = new Proxy(crc.fillRect, {
    apply: function(m, c, [x, y, w, h]) {
        if (upgradeColors.includes(c.fillStyle)) {
            c.canvas.isUpgradeButton = true;
            c.canvas.upgradeButton = upgradeColorTable[c.fillStyle];
        }
        return Reflect.apply(m, c, [x, y, w, h]);
    }
});
crc.setTransform = new Proxy(crc.setTransform, {
    apply: function(m, c, args) {
        currentTransform = args;
        return Reflect.apply(m, c, args)
    }
});
crc.drawImage = new Proxy(crc.drawImage, {
    apply: function(m, c, [img, x, y, ...blah]) {
        const midpointX = (currentTransform[4] + x + img.width / 2) * (window.innerWidth / canvas.width);
        const midpointY = (currentTransform[5] + y + img.height / 2) * (window.innerHeight / canvas.height);
        if (img.isUpgradeButton && midpointX > 0 && midpointY > 0) {
            upgradeButtonMap.set(img.upgradeButton, [midpointX, midpointY]);
        }
        return Reflect.apply(m, c, [img, x, y, ...blah]);
    }
});
Object.freeze(crc);