ParkourUtilsTemp

Parkour Utilities

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         ParkourUtilsTemp
// @namespace    http://tampermonkey.net/
// @version      1.2.1
// @description  Parkour Utilities
// @author       Clarifi
// @license      MIT
// @match        https://bonk.io/gameframe-release.html
// @run-at       document-end
// @grant        none
// ==/UserScript==

window.pkrUtils = {}; // Namespace for encapsulating the UI functions and variables

// Use 'strict' mode for safer code by managing silent errors
'use strict';

pkrUtils.windowConfigs = {
    windowName: "pkrUtils",
    windowId: "pkr_utils_window",
    modVersion: "1.2.1",
    bonkLIBVersion: "1.1.3",
    bonkVersion: "49",
};

pkrUtils.currentData = {};

pkrUtils.positionElement = 0;
pkrUtils.velocityElement = 0;
pkrUtils.specialElement = 0;
pkrUtils.vtolAngle = 0;
pkrUtils.vtolAnglev = 0;
pkrUtils.arrowCharge = 0;
pkrUtils.arrowAngle = 0;

pkrUtils.scale = 1;

pkrUtils.screenWidth = 1;
pkrUtils.gScale = 1;
pkrUtils.goResize = false;

pkrUtils.gCtx = 0;
pkrUtils.markerIndex = 0;
pkrUtils.markers = new Map();

pkrUtils.hasPrecision = false;

pkrUtils.currentMode = -1;

pkrUtils.currentPlayerID = 0;

// Event listener function to change the player selected in the player selector
pkrUtils.select_player = () => {
    let player_selector = document.getElementById("pkrutils_player_selector");
    let player_id = player_selector.options[player_selector.selectedIndex].value;
    pkrUtils.currentPlayerID = player_id;
    //console.log("current Player ID: " + player_id);
};

// Create a new option in the player selector
pkrUtils.create_option = (userID) => {
    //console.log("userID:" + userID);
    let playerName = bonkAPI.getPlayerNameByID(userID);
    let player_selector = document.getElementById("pkrutils_player_selector");
    let newOption = document.createElement("option");
    newOption.innerText = playerName;
    newOption.value = userID;
    newOption.id = "selector_option_" + userID;
    player_selector.appendChild(newOption);
    //console.log("selector_option_" + userID + " added to player_selector");
};

// Remove an option from the player selector
pkrUtils.remove_option = (userID) => {
    let player_selector = document.getElementById("pkrutils_player_selector");
    let option = document.getElementById("selector_option_" + userID);
    player_selector.removeChild(option);
};

// Reset the player selector to the default state
pkrUtils.reset_selector = () => {
    // Remove all options except the default one
    let player_selector = document.getElementById("pkrutils_player_selector");
    Array.from(player_selector.options).forEach((option) => {
        if (option.id !== "pkrutils_selector_option_user") {
            player_selector.removeChild(option);
        }
        // Reset the current player ID
        pkrUtils.currentPlayerID = bonkAPI.getMyID();
        // Set the selector to the first option as default
        player_selector.selectedIndex = bonkAPI.getMyID();
    });
};

// Update the player list in the player selector
pkrUtils.update_players = () => {
    // Get the list of players and the current player ID
    let playerList = bonkAPI.getPlayerList();
    let myID = bonkAPI.getMyID();
    // Reset the player selector
    pkrUtils.reset_selector();
    // Add all player to the player selector
    playerList.forEach((player, id) => {
        if (player && id !== myID) {
            pkrUtils.create_option(id);
        }
    });
};

pkrUtils.generateMarker = (xInput, yInput, rInput) => {
    let markerHold = document.getElementById("pkrutils_marker_hold");

    let markerGraphic = new window.PIXI.Graphics();
    markerGraphic.beginFill(0xffffff);
    markerGraphic.drawCircle((xInput + 365) * pkrUtils.gScale,(yInput + 250) * pkrUtils.gScale, rInput * pkrUtils.gScale);
    markerGraphic.endFill();
    pkrUtils.gCtx.addChild(markerGraphic);

    let resizeFunc = 0;

    let obj = {
        resize: resizeFunc,
        x: xInput,
        y: yInput,
        r: rInput,
    };
    let thisIndex = pkrUtils.markerIndex;
    pkrUtils.markers.set(thisIndex, obj);
    pkrUtils.markerIndex++;

    resizeFunc = function () {
        markerGraphic.clear();
        markerGraphic.beginFill(0xffffff);
        markerGraphic.drawCircle((pkrUtils.markers.get(thisIndex).x + 365) * pkrUtils.gScale, (pkrUtils.markers.get(thisIndex).y + 250) * pkrUtils.gScale, pkrUtils.markers.get(thisIndex).r * pkrUtils.gScale);
        markerGraphic.endFill();
    }
    Object.assign(obj, {resize: resizeFunc})

    pkrUtils.goResize = true;

    let markerDiv = document.createElement("div");
    markerDiv.classList.add("bonkhud-border-color");
    markerDiv.style.height = "3rem";
    markerDiv.style.display = "flex";
    markerDiv.style.borderBottom = "1px solid";
    markerDiv.style.alignItems = "center";
    markerDiv.style.justifyContent = "space-between";
    markerDiv.style.flexWrap = "wrap";
    let nameSpan = document.createElement("span");
    nameSpan.innerText = "(" + xInput + ", " + yInput + ")";
    let markerButton = bonkHUD.generateButton("Delete");
    markerButton.style.width = "3rem";
    markerButton.style.float = "right";

    markerDiv.appendChild(nameSpan);
    markerDiv.appendChild(markerButton);
    markerHold.appendChild(markerDiv);

    markerButton.addEventListener('click', (e) => {
        pkrUtils.markers.delete(thisIndex);
        markerGraphic.destroy();
        markerHold.removeChild(markerDiv);
        pkrUtils.goResize = true;
    });
}

bonkAPI.addEventListener("graphicsReady", (e) => {
    console.log("Readying Graphics");
    pkrUtils.gCtx = new window.PIXI.Container();
    pkrUtils.markers.forEach((val, key, map) => {
        val.resize();
    });
    bonkAPI.pixiCtx.addChild(pkrUtils.gCtx);
    pkrUtils.goResize = true;
});

bonkAPI.addEventListener("modeChange", (e) => {
    currentMode = e.mode;
    let arrowdivs = document.getElementsByClassName("pkrutils-arrows-div");
    let vtoldivs = document.getElementsByClassName("pkrutils-vtol-div");
    if(currentMode == "ar" || currentMode == "ard") {
        for(let i = 0; i < arrowdivs.length; i++) {
            arrowdivs[i].style.display = "block";
        }
        for(let i = 0; i < vtoldivs.length; i++) {
            vtoldivs[i].style.display = "none";
        }
    }
    else if(currentMode == "v") {
        for(let i = 0; i < arrowdivs.length; i++) {
            arrowdivs[i].style.display = "none";
        }
        for(let i = 0; i < vtoldivs.length; i++) {
            vtoldivs[i].style.display = "block";
        }
    }
    else {
        for(let i = 0; i < arrowdivs.length; i++) {
            arrowdivs[i].style.display = "none";
        }
        for(let i = 0; i < vtoldivs.length; i++) {
            vtoldivs[i].style.display = "none";
        }
    }
});

bonkAPI.addEventListener("stepEvent", (e) => {
    if(bonkAPI.isInGame()) {
        let inputState = e.inputState;
        try {
            pkrUtils.currentData = inputState.discs[pkrUtils.currentPlayerID];

            let specialCD = pkrUtils.currentData.a1a;
            let xPos = pkrUtils.currentData.x * pkrUtils.scale - 365;
            let yPos = pkrUtils.currentData.y * pkrUtils.scale - 250;
            let xVel = pkrUtils.currentData.xv * pkrUtils.scale;
            let yVel = pkrUtils.currentData.yv * pkrUtils.scale;
            if(!pkrUtils.hasPrecision) {
                xPos = xPos.toFixed(2);
                yPos = yPos.toFixed(2);
                xVel = xVel.toFixed(2);
                yVel = yVel.toFixed(2);
            }

            pkrUtils.positionElement.textContent = "(" + xPos + ", " + yPos + ")";
            pkrUtils.velocityElement.textContent = "(" + xVel + ", " + yVel + ")";
            pkrUtils.specialElement.textContent = specialCD / 10;
            pkrUtils.vtolAngle.textContent = pkrUtils.currentData.a;
            pkrUtils.vtolAnglev.textContent = pkrUtils.currentData.av;
            pkrUtils.arrowCharge.textContent = pkrUtils.currentData.ds;
            pkrUtils.arrowAngle.textContent = pkrUtils.currentData.da;
        } catch (err) {}
    }
});

bonkAPI.addEventListener('gameStart', (e) => {
    try {
        pkrUtils.scale = e.mapData.physics.ppm;
        pkrUtils.goResize = true;
    } catch(er) {console.log(er)}
});

bonkAPI.addEventListener("graphicsUpdate", (e) => {
    //console.log("g");
    if(pkrUtils.screenWidth != e.width || pkrUtils.goResize) {
        pkrUtils.screenWidth = e.width;
        pkrUtils.gScale = e.width / 730;
        pkrUtils.markers.forEach((val, key, map) => {
            val.resize();
        });
        pkrUtils.goResize = false;
    }
});

// Event listener for when a user joins the game
bonkAPI.addEventListener("userJoin", (e) => {
    //console.log("User join event received", e);
    //console.log("User ID", e.userID);
    // Add the player to the player selector
    pkrUtils.create_option(e.userID);
});

// Event listener for when a user leaves the game
bonkAPI.addEventListener("userLeave", (e) => {
    //console.log("User Leave event received", e);
    //console.log("User ID", e.userID);
    // Remove the player from the player selector
    let playerName = bonkAPI.getPlayerNameByID(e.userID);
    let player_selector = document.getElementById("pkrutils_player_selector");
    // If the player is the current player, set the current player to 0 and reset the selector
    if (player_selector.options[player_selector.selectedIndex].value === playerName) {
        pkrUtils.currentPlayerID = bonkAPI.getMyID();
        // Set the selector to the first option as default
        player_selector.selectedIndex = 0;
    }

    pkrUtils.remove_option(e.userID);
});

// Event listener for when user(mod user) creates a room
bonkAPI.addEventListener("createRoom", (e) => {
    //console.log("create Room event received", e);
    //console.log("User ID", e);
    // Set the player name in the player selector to the current user
    let option = document.getElementById("pkrutils_selector_option_user");
    let playerName = bonkAPI.getPlayerNameByID(e.userID);
    option.innerText = playerName;
    option.value = e.userID;
    pkrUtils.currentPlayerID = e.userID;
    // Reset the player selector to the default state
    pkrUtils.reset_selector();
});

// Event listener for when user(mod user) joins a room
bonkAPI.addEventListener("joinRoom", (e) => {
    //console.log("on Join event received", e);
    //console.log("User ID", e.userID);
    // Set the player name in the player selector to the current user
    let option = document.getElementById("pkrutils_selector_option_user");
    let playerName = bonkAPI.getPlayerNameByID(bonkAPI.getMyID());
    option.innerText = playerName;
    option.value = bonkAPI.getMyID();
    pkrUtils.currentPlayerID = bonkAPI.getMyID();
    // Update the player list in the player selector
    pkrUtils.update_players();
});

// Main function to construct and add the key table UI to the DOM
const addPkrDiv = () => {
    // Create the key table
    let pkrDiv = document.createElement("div");

    pkrDiv.innerHTML = `
        <div class="bonkhud-settings-row">
            <div>
                <span class="bonkhud-settings-label">Position: </span>
                <span id="pkrutils_position"></span>
            </div>
            <div>
                <span class="bonkhud-settings-label">Velocity: </span>
                <span id="pkrutils_velocity"></span>
            </div>
            <div>
                <span class="bonkhud-settings-label">Special: </span>
                <span id="pkrutils_special"></span>
            </div>
            <div class="pkrutils-vtol-div" style="display:none">
                <span class="bonkhud-settings-label">Angle: </span>
                <span id="pkrutils_a"></span>
            </div>
            <div class="pkrutils-vtol-div" style="display:none">
                <span class="bonkhud-settings-label">Angle 2: </span>
                <span id="pkrutils_av"></span>
            </div>
            <div class="pkrutils-arrows-div" style="display:none">
                <span class="bonkhud-settings-label">Charge: </span>
                <span id="pkrutils_ds"></span>
            </div>
            <div class="pkrutils-arrows-div" style="display:none">
                <span class="bonkhud-settings-label">Angle: </span>
                <span id="pkrutils_da"></span>
            </div>
        </div>
        <div class="bonkhud-settings-row">
            <select id="pkrutils_player_selector">
                <option id="pkrutils_selector_option_user">......</option>
            </select>
            <div>
                <span class="bonkhud-settings-label" style="margin-right:5px;vertical-align:middle;">Precision</span>
                <input type="checkbox" id="pkrutils_precision_toggle">
            </div>
        </div>
        <div id="pkrutils_marker_maker" class="bonkhud-settings-row">
            <div>
                <span class="bonkhud-settings-label">x </span>
                <input id="pkrutils_x_marker" type="number" value="0" style="width:100%">
            </div>
            <div>
                <span class="bonkhud-settings-label">y </span>
                <input id="pkrutils_y_marker" type="number" value="0" style="width:100%">
            </div>
            <div style="margin-bottom: 5px;">
                <span class="bonkhud-settings-label">Radius </span>
                <input id="pkrutils_r_marker" type="number" min="1" value="1" style="width:100%">
            </div>
        </div>
        <div id="pkrutils_marker_hold" style="padding:10px"></div>`;

    let pkrIndex = bonkHUD.createWindow(
        pkrUtils.windowConfigs.windowName,
        pkrDiv,
        pkrUtils.windowConfigs);
    /*let keytable_window = document.getElementById("keytable_window");
    keytable_window.style.width = "100%";
    keytable_window.style.height = "calc(100% - 32px)";
    keytable_window.style.padding = "0";
    keytable_window.style.display = "flex";
    keytable_window.style.flexFlow = "column";*/

    let precisionCheck = document.getElementById("pkrutils_precision_toggle");
    precisionCheck.checked = false;
    precisionCheck.oninput = function () {
        pkrUtils.hasPrecision = precisionCheck.checked;
    };

    let markerMaker = document.getElementById("pkrutils_marker_maker");
    let markerGenerator = bonkHUD.generateButton("Create Marker");
    markerGenerator.style.marginBottom = "5px";
    markerGenerator.addEventListener('click', (e) => {
        pkrUtils.generateMarker(parseInt(document.getElementById("pkrutils_x_marker").value), parseInt(document.getElementById("pkrutils_y_marker").value), parseInt(document.getElementById("pkrutils_r_marker").value));
    });

    let markerGenerator2 = bonkHUD.generateButton("Marker At Position");
    markerGenerator2.style.marginBottom = "5px";
    markerGenerator2.addEventListener('click', (e) => {
        try {
            pkrUtils.generateMarker(Math.trunc(pkrUtils.currentData.x * pkrUtils.scale - 365), Math.trunc(pkrUtils.currentData.y * pkrUtils.scale - 250), parseInt(document.getElementById("pkrutils_r_marker").value));
        } catch(er) {
            console.log("Unable to create marker");
        }
    });

    markerMaker.appendChild(markerGenerator);
    markerMaker.appendChild(markerGenerator2);

    pkrUtils.positionElement = document.getElementById("pkrutils_position");
    pkrUtils.velocityElement = document.getElementById("pkrutils_velocity");
    pkrUtils.specialElement = document.getElementById("pkrutils_special");
    pkrUtils.vtolAngle = document.getElementById("pkrutils_a");
    pkrUtils.vtolAnglev = document.getElementById("pkrutils_av");
    pkrUtils.arrowCharge = document.getElementById("pkrutils_ds");
    pkrUtils.arrowAngle = document.getElementById("pkrutils_da");

    bonkHUD.loadUISetting(pkrIndex);
};

// Initialization logic to set up the UI once the document is ready
const init = () => {
    addPkrDiv();
    let playerSelector = document.getElementById("pkrutils_player_selector");
    if (playerSelector) {
        playerSelector.addEventListener("change", pkrUtils.select_player);
    } else {
        console.error("pkrutils_player_selector element not found!");
    }
};

if (document.readyState === "complete" || document.readyState === "interactive") {
    init();
} else {
    document.addEventListener("DOMContentLoaded", init);
}