PokeRogue - Autoplay (basic)

Autoplay helper for PokeRogue: auto-progress and basic auto-battle. Use responsibly (single-player / local saves only).

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

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

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

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

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         PokeRogue - Autoplay (basic)
// @namespace    http://tampermonkey.net/
// @version      0.9
// @description  Autoplay helper for PokeRogue: auto-progress and basic auto-battle. Use responsibly (single-player / local saves only).
// @author       Generated with ChatGPT
// @match        https://pokerogue.net/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    // CONFIG
    const CONFIG = {
        pollInterval: 300,        // ms between checks
        thinkDelay: 300,          // delay before making a move (ms)
        preferHighestPower: true, // choose move with highest power if data available
        autoUseItems: false,      // whether to try to auto-use items from menu
        stopOnLevelUp: false,     // pause autoplay if party levels up
    };

    // internal state
    let running = false;
    let loopHandle = null;

    function log(...args){ console.log('[ARBOT]',...args); }

    // try to safely find the main scene/game object
    function findScene(){
        // common places found by community scripts
        if (window.scene) return window.scene;
        if (window.game && window.game.scene) return window.game.scene;
        if (globalThis?.pokerogue?.getScene) return globalThis.pokerogue.getScene();
        // scan globals for an object that looks like starterData/dexData
        for (const k of Object.keys(window)){
            try{
                const v = window[k];
                if (v && typeof v === 'object'){
                    if ('starterData' in v && 'dexData' in v) return v;
                }
            }catch(e){}
        }
        return null;
    }

    // helpers to simulate clicks on UI elements (buttons that appear in the DOM)
    function clickElement(el){ if(!el) return false; el.dispatchEvent(new MouseEvent('mousedown',{bubbles:true})); el.dispatchEvent(new MouseEvent('mouseup',{bubbles:true})); el.click(); return true; }

    // try to advance dialogue / continue screens
    function tryAdvanceUI(){
        // Usually the game shows "Next" or continues on space/enter; try to click primary button
        const primary = document.querySelector('.dialogue-button, .primary, button.primary, button');
        if(primary){ clickElement(primary); return true; }
        // fallback: press space
        const evt = new KeyboardEvent('keydown', { key: ' ', code: 'Space', bubbles: true });
        document.dispatchEvent(evt);
        return false;
    }

    // basic battle decision logic - best-effort: inspect party and active battle object
    function autoBattle(scene){
        try{
            // community scripts expose scene.fight or scene.battle or scene.battleData
            const battle = scene.fight || scene.battle || scene.battleData || (scene.scene && (scene.scene.fight||scene.scene.battle));
            if(!battle) return false;

            // find active pokemon and available moves
            const active = battle.activePokemon || battle.activePoke || (battle.player && battle.player.active);
            const options = battle.moves || active?.moves || (battle.moveOptions);

            // if there are DOM buttons for moves, try to click best one
            const moveButtons = Array.from(document.querySelectorAll('.move-button, .battle-move, button.move')).filter(Boolean);
            if(moveButtons.length>0){
                // choose button index using simple heuristic
                let bestIndex = 0;
                if(options && options.length === moveButtons.length){
                    let bestScore = -Infinity;
                    for(let i=0;i<options.length;i++){
                        const m = options[i];
                        // estimate power from fields 'power' 'damage' or 'basePower'
                        const power = Number(m?.power ?? m?.damage ?? m?.basePower ?? 0);
                        const acc = Number(m?.accuracy ?? 100);
                        let score = power * (acc/100);
                        // prefer non-damaging moves less
                        if(m?.category === 'status') score *= 0.5;
                        if(score>bestScore){ bestScore = score; bestIndex = i; }
                    }
                }
                // click chosen move after small delay
                setTimeout(()=> clickElement(moveButtons[bestIndex]), CONFIG.thinkDelay);
                return true;
            }

            // fallback: if battle has a method to choose move, call it
            if(typeof battle.chooseMove === 'function'){
                // try to select by highest power
                const moves = battle.moves || active?.moves || [];
                let idx = 0;
                if(moves.length){
                    let best = -Infinity;
                    for(let i=0;i<moves.length;i++){
                        const m = moves[i];
                        const p = Number(m?.power ?? m?.damage ?? 0);
                        if(p>best){ best = p; idx = i; }
                    }
                }
                setTimeout(()=> { try{ battle.chooseMove(idx); }catch(e){/*ignore*/} }, CONFIG.thinkDelay);
                return true;
            }

        }catch(e){ /* ignore */ }
        return false;
    }

    function mainLoop(){
        const scene = findScene();
        if(!scene){ return; }

        // If currently in battle/selection, try to auto-battle
        if(autoBattle(scene)){ return; }

        // otherwise try to advance UI (menus, dialogue, shop screens)
        tryAdvanceUI();
    }

    // public controls (exposed on window for quick toggling)
    function start(){ if(running) return; running = true; log('autoplay started'); loopHandle = setInterval(mainLoop, CONFIG.pollInterval); }
    function stop(){ if(!running) return; running = false; clearInterval(loopHandle); loopHandle = null; log('autoplay stopped'); }

    // expose controls
    globalThis.PokeRogueAutoplay = { start, stop, running: () => running, CONFIG };

    // small UI hint on page
    const badge = document.createElement('div');
    badge.textContent = 'AR-BOT';
    Object.assign(badge.style, {position:'fixed',right:'8px',bottom:'8px',padding:'6px 8px',background:'#111',color:'#fff',zIndex:99999,fontSize:'12px',borderRadius:'6px',opacity:0.6,cursor:'pointer'});
    badge.title = 'Click to toggle autoplay (or use PokeRogueAutoplay.start()/stop() in console)';
    badge.onclick = ()=>{ running? stop():start(); badge.style.background = running? '#a00' : '#111'; };
    document.body.appendChild(badge);

    log('Autoplay helper injected. Use PokeRogueAutoplay.start() to begin.');

})();