miketrethewey / Super Metroid Map Rando Generation Randomizer

// ==UserScript==
// @name        Super Metroid Map Rando Generation Randomizer
// @namespace   https://openuserjs.org/users/miketrethewey
// @version     1.0.1
// @description Randomizes the form options in SM Map Rando
// @author      Minnie A. Trethewey
// @match       https://maprando.com/generate*
// @match       https://dev.maprando.com/generate*
// @require     https://code.jquery.com/jquery-3.7.1.slim.min.js
// @copyright   2023, miketrethewey (https://openuserjs.org/users/miketrethewey)
// @license     MIT
// @grant       none
// ==/UserScript==

// ==OpenUserJS==
// @author  miketrethewey
// ==/OpenUserJS==

(function() {
    let ignoredOptions = [
        // QOL
            // Map
            "Item markers",
            "Map stations always visible on map",
            "Guaranteed early save station",

            // End game
            "Mother Brain fight (phases 2 and 3)",
            "Supers do double damage to Mother Brain",
            "Hyper Beam gives all movement items",
            "Refill energy for escape",
            "Enemies cleared during escape",

            // Faster transitions
            "Fast elevators",
            "Fast doors",
            "Fast pause menu",

            // Samus control
            "Respin",
            "Lenient Space Jump",
            "Momentum conservation",

            // Other
            "All items spawn at start of game",
            "Acid Chozo usable without Space Jump",
            "Enemy drops are buffed",

        // Other Options
        "Wall jump",
        "E-Tank energy refill",
        "Area assignment",
        "Item dots after collection",
        "Area transition markers on map",
        "Maps revealed from start",
        "Ultra-low quality of life",
        "Race mode"
    ];

    // Select a random option
    function randomizeOption(inputs) {
        let randomize = true;
        if(randomize) {
            // Get a random number within the size of the available options
            let randomID = Math.floor(Math.random() * (inputs.length - 1));

            // If we chose the selected option, return -1 to indicate that
            if(inputs[randomID].checked) {
                randomID = -1;
            } else {
                // If we chose something other than the selection option, choose it
                inputs[randomID].checked = true;
            }
            return randomID;
        }
    }

    // List the options and indicate what is selected
    function buildOptionList(inputs, randomID) {
        let msg = "";
        for (let input of inputs) {
            // If it's checked
            // If it's something other than what was initially selected
            //  Add a square bracket
            // Else, if it's what was initially selected
            //  Add an asterisk
            if(input.checked) {
                msg += randomID !== -1 ? "[" : "*";
            }
            msg += (input.value);
            if(input.checked) {
                msg += randomID !== -1 ? "]" : "*";
            }
            msg += ",";
        }
        return msg;
    }

    function doTheThing() {
        let passedOptions = [];
        let skippedOptions = [];
        // Cycle through .form-group
        let formGroups = $(".form-group");
        for (let formGroup of formGroups) {
            let modals = $(formGroup).find(".modal");
            // If it's got a modal (in this case, a ? help dialogue)
            if(modals.length) {
                let labels = $(formGroup).find("label");
                let inputs = $(formGroup).find("input");
                let optionSections = $(formGroup).find(".mt-0");
                // If it's got styled options
                if(optionSections.length) {
                    for (let optionSection of optionSections) {
                        // If it's got a <label>
                        if(labels) {
                            let msg = "";
                            let label = labels[0].innerText;
                            // If it's got <input>s
                            if(inputs) {
                                // If it's not something we're ignoring
                                if(ignoredOptions.indexOf(labels[0].innerText) == -1) {
                                    // Save that we looked at it
                                    passedOptions.push(label);
                                    msg += (labels[0].innerText) + ": ";
                                    // Pick a random option
                                    let randomID = randomizeOption(inputs);
                                    // List the options
                                    msg += buildOptionList(inputs, randomID);
                                } else {
                                    // Save that we skipped it
                                    skippedOptions.push(label);
                                }
                            }
                            console.log(msg);
                        }
                    }
                } else if(inputs.length) {
                    if(inputs[0].type == "radio") {
                        let msg = "";
                        let label = labels[0].innerText;
                        // If it's not something we're ignoring
                        if(ignoredOptions.indexOf(labels[0].innerText) == -1) {
                            // Save that we looked at it
                            passedOptions.push(label);
                            msg += (labels[0].innerText) + ": ";
                            // Pick a random option
                            let randomID = randomizeOption(inputs);
                            // List the options
                            msg += buildOptionList(inputs, randomID);
                        } else {
                            // Save that we skipped it
                            skippedOptions.push(label);
                        }
                        console.log(msg);
                    }
                }
            }
        }
        console.log(passedOptions);
        console.log(skippedOptions);
    }

    // Build a button to Randomize settings
    let button = document.createElement("button");
    button.className = "btn btn-primary my-3";
    button.style = "float:right";
    button.innerText = "Randomize Settings!";
    button.onclick = doTheThing;

    // Add it to the header
    let headers = null;
    let header = null;
    headers = document.getElementsByTagName("h3");
    header = headers[0];
    header.appendChild(button);
})();