IdlePixel Combat Presets Plus

CombatPresets (5x5) / Don't use with "Slap Chop".

当前为 2025-03-21 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         IdlePixel Combat Presets Plus
// @namespace    mippo.idle-pixel
// @version      1.0.0
// @description  CombatPresets (5x5) / Don't use with "Slap Chop".
// @author       mippo
// @license      MIT
// @match        *://idle-pixel.com/login/play*
// @grant        none
// @require      https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js?anticache=20220905
// ==/UserScript==

(function () {
    "use strict";

    // Overall Declarations for different variables used throughout the script
    let IPP, getVar, getThis;
    const IMAGE_URL_BASE = document
    .querySelector("itembox[data-item=copper] img")
    .src.replace(/\/[^/]+.png$/, "");
    let loaded = false;
    let onLoginLoaded = false;

    // Start New Code Base Const/Functions
    const misc = function () {
        return {
            initStyles: function () {
                var style = document.createElement("style");
                style.id = "styles-slapchop";
                style.innerHTML = `
                    #slapchop-quickpreset > .slapchop-quickpreset-buttons {
                        display: flex;
                        flex-direction: row;
                        justify-content: start;
                    }

                    #slapchop-quickpreset > .slapchop-quickpreset-buttons > div {
                        display: flex;
                        flex-direction: column;
                        justify-content: start;
                    }

                    #combat-stats #slapchop-quickpreset > .slapchop-quickpreset-buttons {
                        display: grid;
                        grid-template-columns: auto auto;
                        justify-content: start;
                        column-gap: 1em;
                    }

                    #combat-stats #slapchop-quickpreset > .slapchop-quickpreset-buttons > div {
                        display: flex;
                        flex-direction: row;
                        justify-content: flex-start;
                    }

                    #combat-stats #slapchop-quickpreset > .slapchop-quickpreset-buttons > div > div {
                        display: flex;
                        flex-direction: column;
                        justify-content: flex-start;
                    }

                    #slapchop-quickpreset-buttons-unlink,
                    #slapchop-quickpreset-buttons-unlink-lock {
                    font-size: 0.8em;
                    }

                    #slapchop-quickpreset-buttons-unlink.current-group-0,
                    #slapchop-quickpreset-buttons-unlink-lock.current-group-99,
                    #combat-stats #slapchop-quickpreset-buttons-groups.current-group-6 > .slapchop-quickpreset-buttons-group6 > button,
                    #combat-stats #slapchop-quickpreset-buttons-groups.current-group-7 > .slapchop-quickpreset-buttons-group7 > button,
                    #combat-stats #slapchop-quickpreset-buttons-groups.current-group-8 > .slapchop-quickpreset-buttons-group8 > button,
                    #combat-stats #slapchop-quickpreset-buttons-groups.current-group-9 > .slapchop-quickpreset-buttons-group9 > button,
                    #combat-stats #slapchop-quickpreset-buttons-groups.current-group-10 > .slapchop-quickpreset-buttons-group10 > button,
                    #in-combat-presets-icon-6.current,
                    #in-combat-presets-icon-7.current,
                    #in-combat-presets-icon-8.current,
                    #in-combat-presets-icon-9.current,
                    #in-combat-presets-icon-10.current {
                        background-color: limegreen;
                    }

                    #slapchop-quickpreset button {
                    margin: 0.125em;
                    }
                `;
                document.head.appendChild(style);
            },
        };
    };

    const combat = function () {
    window.SCUSERNAME = getVar("username", "", "string");

        // Define keys for localStorage in a centralized manner
        const COMBAT_PRESETS_KEY = SCUSERNAME + ".combat_presets";
        const COMBAT_PRESETS_LINK_KEY = SCUSERNAME + ".combat_presets_link";

    return {
        loadPresetGroups: function (buttonNum) {
            // Suppress popup "Combat preset saved"
            const openImageModalOriginal = Modals.open_image_modal;
            Modals.open_image_modal = (title, image_path, message, primary_button_text, secondary_button_text, command, force_unclosable) => {
                if (message === "Successfully saved preset based on what you are currently wearing.") {
                    return;
                }
                openImageModalOriginal(title, image_path, message, primary_button_text, secondary_button_text, command, force_unclosable);
            }

            // Set shortcut number presets to 1-5
            for (let combatpresetNum = 1; combatpresetNum < 6; combatpresetNum++) {
                let presetName = `CombatPreset ${buttonNum * 10 + combatpresetNum}`;

                // Retrieve all presets from local storage
                let allPresets =
                    JSON.parse(localStorage.getItem(COMBAT_PRESETS_KEY)) ||
                    {};

                // Check if the requested preset exists
                if (!allPresets[presetName]) {
                    console.error("Preset not found for button number:", presetName);
                    return;
                }

                // Load the preset and equip each item
                IdlePixelPlus.sendMessage("UNEQUIP_ALL");
                allPresets[presetName].forEach((item) => {
                    if (item) {
                        IdlePixelPlus.sendMessage("EQUIP=" + item);
                    }
                });
                IdlePixelPlus.sendMessage(`PRESET_SAVE=${combatpresetNum}`);
            }
            IdlePixelPlus.sendMessage('PRESET_LOAD=1~1');

            sCCombat().saveLinkedPresetNum(buttonNum);
        },

        savePresetGroups: function (buttonNum) {
            // Presets 1-5 are saved as shortcut numbers
            for (let combatpresetNum = 1; combatpresetNum < 6; combatpresetNum++) {
                let presetName = `CombatPreset ${buttonNum * 10 + combatpresetNum}`;

                // Retrieve all presets from local storage, or initialize a new object if none exist
                let allPresets =
                    JSON.parse(localStorage.getItem(COMBAT_PRESETS_KEY)) ||
                    {};

                // Save current equipment settings into the relevant key of the allPresets object
                allPresets[presetName] = [
                    getVar(`preset_head_${combatpresetNum}`, null, "string"),
                    getVar(`preset_body_${combatpresetNum}`, null, "string"),
                    getVar(`preset_legs_${combatpresetNum}`, null, "string"),
                    getVar(`preset_boots_${combatpresetNum}`, null, "string"),
                    getVar(`preset_gloves_${combatpresetNum}`, null, "string"),
                    getVar(`preset_amulet_${combatpresetNum}`, null, "string"),
                    getVar(`preset_weapon_${combatpresetNum}`, null, "string"),
                    getVar(`preset_shield_${combatpresetNum}`, null, "string"),
                    getVar(`preset_arrows_${combatpresetNum}`, null, "string"),
                ];

                // Update the single entry in local storage with the modified allPresets object
                localStorage.setItem(COMBAT_PRESETS_KEY, JSON.stringify(allPresets));
            }

            sCCombat().saveLinkedPresetNum(buttonNum);
        },

        saveCurrentPresets: function (buttonNum) {
            IdlePixelPlus.sendMessage(`PRESET_SAVE=${buttonNum}`)

            // Get linked preset numbers
            const LinkedPresetNum =
                  JSON.parse(localStorage.getItem(COMBAT_PRESETS_LINK_KEY)) ||
                  0;
            if (LinkedPresetNum === 0 || LinkedPresetNum === 99) {
                return;
            }

            sCCombat().savePresetGroups(LinkedPresetNum);

            let presetName = `CombatPreset ${LinkedPresetNum * 10 + buttonNum}`;

            // Retrieve all presets from local storage, or initialize a new object if none exist
            let allPresets =
                JSON.parse(localStorage.getItem(COMBAT_PRESETS_KEY)) ||
                {};

            // Save current equipment settings into the relevant key of the allPresets object
            allPresets[presetName] = [
                getVar("head", null, "string"),
                getVar("body", null, "string"),
                getVar("legs", null, "string"),
                getVar("boots", null, "string"),
                getVar("gloves", null, "string"),
                getVar("amulet", null, "string"),
                getVar("weapon", null, "string"),
                getVar("shield", null, "string"),
                getVar("arrows", null, "string"),
            ];

            // Update the single entry in local storage with the modified allPresets object
            localStorage.setItem(COMBAT_PRESETS_KEY, JSON.stringify(allPresets));
        },

        saveLinkedPresetNum: function (buttonNum) {
            const LinkedPresetNum =
                  JSON.parse(localStorage.getItem(COMBAT_PRESETS_LINK_KEY)) ||
                  0;

            // Lock button on/off switching
            if (LinkedPresetNum === 99) {
                if (buttonNum === 99) {
                    buttonNum = 0;
                } else {
                    return;
                }
            }

            localStorage.setItem(COMBAT_PRESETS_LINK_KEY, buttonNum);

            sCCombat().removeHighlightPresetButtons();
            sCCombat().highlightPresetButtons();
        },

        highlightPresetButtons: function () {
            // Retrieve the preset number from localStorage (default to 0 if not found)
            const LinkedPresetNum =
                  JSON.parse(localStorage.getItem(COMBAT_PRESETS_LINK_KEY)) || 0;

            if (LinkedPresetNum >= 6 && LinkedPresetNum <= 10) {
                // For numbers between 6 and 10, apply a highlight to the corresponding group and icon
                const groupElem = document.getElementById("slapchop-quickpreset-buttons-groups");
                if (groupElem) {
                    groupElem.className = "current-group-" + LinkedPresetNum;
                }
                const iconElem = document.getElementById("in-combat-presets-icon-" + LinkedPresetNum);
                if (iconElem) {
                    iconElem.classList.add("current");
                }
            } else {
                const unlinkElem = document.getElementById("slapchop-quickpreset-buttons-unlink");
                if (unlinkElem) {
                    // If LinkedPresetNum is 0, apply highlight to the unlink button
                    unlinkElem.className = "current-group-0";
                }
                if (LinkedPresetNum === 99) {
                    // If LinkedPresetNum is 99, apply highlight to the unlink-lock button
                    const unlinkLockElem = document.getElementById("slapchop-quickpreset-buttons-unlink-lock");
                    if (unlinkLockElem) {
                        unlinkLockElem.className = "current-group-99";
                    }
                }
            }
        },

        removeHighlightPresetButtons: function () {
            // Remove highlight for the entire preset group container
            const groupElem = document.getElementById("slapchop-quickpreset-buttons-groups");
            if (groupElem) {
                groupElem.className = ""; // Reset the container's class
            }

            // Remove highlights from preset icons for groups 6 to 10
            for (let i = 6; i <= 10; i++) {
                const iconElem = document.getElementById("in-combat-presets-icon-" + i);
                if (iconElem) {
                    iconElem.classList.remove("current");
                }
            }

            // Remove highlights from the unlink and unlink-lock buttons
            const unlinkElem = document.getElementById("slapchop-quickpreset-buttons-unlink");
            if (unlinkElem) {
                unlinkElem.className = "";
            }
            const unlinkLockElem = document.getElementById("slapchop-quickpreset-buttons-unlink-lock");
            if (unlinkLockElem) {
                unlinkLockElem.className = "";
            }
        },

        initQuickFight: async function () {
            let html = `
                    </div>
                    <hr>
                    </div>
                    <div id="slapchop-quickpreset">
						<div class="slapchop-quickpreset-buttons">
							<h5>Quick Current Presets:</h5>
							<h5>Current Preset Groups:
								<button id="slapchop-quickpreset-buttons-unlink" onclick="sCCombat().saveLinkedPresetNum(0)">Unlink Current Gr</button>
								≪
								<button id="slapchop-quickpreset-buttons-unlink-lock" onclick="sCCombat().saveLinkedPresetNum(99)">Lock</button>
							</h5>
							<div>
								<div>
									<button onclick="sCCombat().saveCurrentPresets(1);">Save 1</button>
									<button onclick="IdlePixelPlus.sendMessage('PRESET_LOAD=1~1')">Load 1</button>
								</div>
								<div>
									<button onclick="sCCombat().saveCurrentPresets(2);">Save 2</button>
									<button onclick="IdlePixelPlus.sendMessage('PRESET_LOAD=2~1')">Load 2</button>
								</div>
								<div>
									<button onclick="sCCombat().saveCurrentPresets(3);">Save 3</button>
									<button onclick="IdlePixelPlus.sendMessage('PRESET_LOAD=3~1')">Load 3</button>
								</div>
								<div>
									<button onclick="sCCombat().saveCurrentPresets(4);">Save 4</button>
									<button onclick="IdlePixelPlus.sendMessage('PRESET_LOAD=4~1')">Load 4</button>
								</div>
								<div>
									<button onclick="sCCombat().saveCurrentPresets(5);">Save 5</button>
									<button onclick="IdlePixelPlus.sendMessage('PRESET_LOAD=5~1')">Load 5</button>
								</div>
							</div>
							<div id="slapchop-quickpreset-buttons-groups" class="">
								<div class="slapchop-quickpreset-buttons-group6">
									<button onclick="sCCombat().savePresetGroups(6)">Save Gr6</button>
									<button onclick="sCCombat().loadPresetGroups(6)">Load Gr6</button>
								</div>
								<div class="slapchop-quickpreset-buttons-group7">
									<button onclick="sCCombat().savePresetGroups(7)">Save Gr7</button>
									<button onclick="sCCombat().loadPresetGroups(7)">Load Gr7</button>
								</div>
								<div class="slapchop-quickpreset-buttons-group8">
									<button onclick="sCCombat().savePresetGroups(8)">Save Gr8</button>
									<button onclick="sCCombat().loadPresetGroups(8)">Load Gr8</button>
								</div>
								<div class="slapchop-quickpreset-buttons-group9">
									<button onclick="sCCombat().savePresetGroups(9)">Save Gr9</button>
									<button onclick="sCCombat().loadPresetGroups(9)">Load Gr9</button>
								</div>
								<div class="slapchop-quickpreset-buttons-group10">
									<button onclick="sCCombat().savePresetGroups(10)">Save Gr10</button>
									<button onclick="sCCombat().loadPresetGroups(10)">Load Gr10</button>
								</div>
							</div>
                        </div>
                    </div>
                    <hr>
                `;
                const panelCombat = document.getElementById("combat-stats").querySelectorAll("div")[4];
                if (panelCombat) {
                    panelCombat.insertAdjacentHTML("afterend", html);
                }
            },

            initPresets: function () {
                const combatPresetsHtml = `
                    <br />
                    <br />
                    <img data-tooltip="Presets group 6" id="in-combat-presets-icon-6" onclick="sCCombat().loadPresetGroups(6)" class="combat-presets-combat-icon hover w30" src="${IMAGE_URL_BASE}/melee.png" />
                    <img data-tooltip="Presets group 7" id="in-combat-presets-icon-7" onclick="sCCombat().loadPresetGroups(7)" class="combat-presets-combat-icon hover w30" src="${IMAGE_URL_BASE}/melee.png" />
                    <img data-tooltip="Presets group 8" id="in-combat-presets-icon-8" onclick="sCCombat().loadPresetGroups(8)" class="combat-presets-combat-icon hover w30" src="${IMAGE_URL_BASE}/melee.png" />
                    <img data-tooltip="Presets group 9" id="in-combat-presets-icon-9" onclick="sCCombat().loadPresetGroups(9)" class="combat-presets-combat-icon hover w30" src="${IMAGE_URL_BASE}/melee.png" />
                    <img data-tooltip="Presets group 10" id="in-combat-presets-icon-10" onclick="sCCombat().loadPresetGroups(10)" class="combat-presets-combat-icon hover w30" src="${IMAGE_URL_BASE}/melee.png" />
                `;

                const combatPresetsArea = document.getElementById(
                    "combat-presets-area"
                );
                if (combatPresetsArea) {
                    combatPresetsArea.insertAdjacentHTML("beforeend", combatPresetsHtml);
                }
            },

            initPresetListener: function () {
                const KEY_ACTIONS = {
                    54: () => sCCombat().loadPresetGroups(6), //key [6]
                    55: () => sCCombat().loadPresetGroups(7), //key [7]
                    56: () => sCCombat().loadPresetGroups(8), //key [8]
                    57: () => sCCombat().loadPresetGroups(9), //key [9]
                    48: () => sCCombat().loadPresetGroups(10), //key [0]
                };

                document.addEventListener("keyup", (e) => {
                    const chatInput = document.getElementById("chat-area-input");
                    let chatFocused = chatInput && document.activeElement === chatInput;
                    let isRelevantPanel = [
                        "panel-combat-canvas",
                        "panel-combat",
                        "panel-combat-canvas-raids",
                    ].includes(Globals.currentPanel);

                    if (chatFocused || !isRelevantPanel) {
                        return; // Early exit if chat is focused or the panel is not relevant
                    }

                    const action = KEY_ACTIONS[e.keyCode];
                    if (action) {
                        action(); // Execute the action associated with the key code
                    }
                });
            },
        };
    };

    window.sCMisc = misc;
    window.sCCombat = combat;

    // End New Code Base Const/Functions

    class SlapChopPlugin extends IdlePixelPlusPlugin {
        constructor() {
            super("slapchop", {
                about: {
                    name: GM_info.script.name + " (ver: " + GM_info.script.version + ")",
                    version: GM_info.script.version,
                    author: GM_info.script.author,
                    description: GM_info.script.description,
                },
            });
        }

        onConfigsChanged() {
            if (onLoginLoaded) {
                const slapchopQuickPreset = document.querySelector(
                    "#slapchop-quickpreset"
                );

                const presetsUnlocked = IdlePixelPlus.getVar("combat_presets") == "1";
                if (presetsUnlocked) {
                    slapchopQuickPreset.style.display = "block";
                } else {
                    slapchopQuickPreset.style.display = "none";
                }
            }
        }

        onLogin() {
            IPP = IdlePixelPlus;
            getVar = IdlePixelPlus.getVarOrDefault;
            getThis = IdlePixelPlus.plugins.slapchop;
            sCMisc().initStyles();
            sCCombat().initQuickFight();
            sCCombat().initPresets();
            sCCombat().initPresetListener();
            sCCombat().highlightPresetButtons();

            setTimeout(function () {
                onLoginLoaded = true;
                IdlePixelPlus.plugins.slapchop.onConfigsChanged();
            }, 5000);
            loaded = true;
        }

        async delay() {
            await new Promise((resolve) => {
                const checkLoaded = () => {
                    if (loaded) {
                        resolve();
                    } else {
                        setTimeout(checkLoaded, 2000);
                    }
                };

                checkLoaded();
            });
        }
    }

    const plugin = new SlapChopPlugin();
    IdlePixelPlus.registerPlugin(plugin);
})();