[ Zorr.PRO ] Auto Craft

Autocraft for zorr.pro with different modes

// ==UserScript==
// @name         [ Zorr.PRO ] Auto Craft
// @version      1.8
// @description  Autocraft for zorr.pro with different modes
// @author       Pixey Fr
// @match        https://zorr.pro/*
// @license      GNU GPLv3
// @grant        none
// @namespace https://greasyfork.org/users/1107724
// ==/UserScript==

/*
INFO:
 This is the simplistic version of the script, if you experience any bugs while using please report them to me on discord,
 username : `pixeyfr`, you can ping me in the zorr discord server if i dont respond to ur dm!
/*
Modes:
- conservative: Only craft petals that are mythic or lower and with a total count above a set threshold (default: >10).
- bruteForce: Craft any petal. (USE AT YOUR OWN RISK. WILL CRAFT EVERYTHING.)
- simulate: Simulate success probability using P(success)=1-(1-p)^n, craft if the probability is >= a set threshold (default: 50%).
- adaptive: Blends brute force and simulate logic; requires a minimum count and meets a probability threshold.
*/

(async function() {
    'use strict';

    const settings = {
        desiredCount: 50,
        cooldown: 250,
        mode: 'conservative', // options: 'conservative', 'bruteForce', 'simulate', 'adaptive'
        conservativeMinCount: 10,
        conservativeMaxRarityLevel: 5,
        simulateProbabilityThreshold: 0.5,
        adaptiveMinCount: 5,
        adaptiveProbabilityThreshold: 0.5
    };

    const wait = ms => new Promise(res => setTimeout(res, ms));

    const rarityMap = {
        'rarity-bg-0': { level: 0, chance: 0.4 }, // common
        'rarity-bg-1': { level: 1, chance: 0.3 }, // uncommon
        'rarity-bg-2': { level: 2, chance: 0.2 }, // rare
        'rarity-bg-3': { level: 3, chance: 0.1 }, // epic
        'rarity-bg-4': { level: 4, chance: 0.03 }, // legendary
        'rarity-bg-5': { level: 5, chance: 0.02 }, // mythic
        'rarity-bg-6': { level: 6, chance: 0.01 }, // ultra
        'rarity-bg-7': { level: 7, chance: 0 } // super ( does not craft supers currently )
    };

    const modes = {
        conservative: p => p.rarity.level < settings.conservativeMaxRarityLevel && p.count > settings.conservativeMinCount,
        bruteForce: _ => true,
        simulate: p => 1 - Math.pow(1 - p.rarity.chance, p.count) >= settings.simulateProbabilityThreshold,
        adaptive: p => p.count >= settings.adaptiveMinCount &&
                       1 - Math.pow(1 - p.rarity.chance, p.count) >= settings.adaptiveProbabilityThreshold
    };

    const getPetals = () =>
        [...document.querySelectorAll('.dialog-content .petal')].map(el => {
            const rClass = [...el.classList].find(c => c.startsWith('rarity-bg-'));
            const count = parseInt((el.querySelector('.petal-count')?.getAttribute('stroke') || 'x0').replace('x',''));
            return { el, count, rarity: rarityMap[rClass] || rarityMap['rarity-bg-0'] };
        });

    const saveData = () => {
        try {
            localStorage.setItem("autocraft_data", JSON.stringify(getPetals()));
        } catch (e) {}
    };

    const craft = async () => {
        const petals = getPetals();
        const candidates = petals.filter(p => modes[settings.mode](p))
                                 .sort((a, b) => a.rarity.level - b.rarity.level);
        if (!candidates.length) return false;
        const petal = candidates[0];
        const clicks = Math.ceil(settings.desiredCount / 5);
        for (let i = 0; i < clicks; i++) {
            petal.el.click();
            await wait(settings.cooldown);
        }
        const btn = document.querySelector('.btn.craft-btn');
        if (btn) {
            btn.click();
            await wait(settings.cooldown);
        }
        let result = document.querySelector('.craft-result');
        while (result) {
            const style = getComputedStyle(result);
            if (style.transform === 'none') break;
            const match = style.transform.match(/matrix\(([^)]+)\)/);
            if (match) {
                const [a, b] = match[1].split(',').map(parseFloat);
                const scale = Math.sqrt(a * a + b * b);
                if (scale === 0) break;
            }
            result.click();
            await wait(settings.cooldown);
            result = document.querySelector('.craft-result');
        }
        saveData();
        return true;
    };

    const loop = async () => {
        while (true) {
            const crafted = await craft();
            if (!crafted) await wait(5000);
        }
    };

    console.log("[Auto Craft] Running immediately.");
    loop();
})();