[Pokeclicker] Farm Plot Editor

Adds edit mode button to farm modal for directly setting berries at Berry stage

当前为 2025-09-19 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name          [Pokeclicker] Farm Plot Editor
// @namespace     Pokeclicker Scripts
// @author        samfp
// @description   Adds edit mode button to farm modal for directly setting berries at Berry stage
// @copyright     https://github.com/Ephenia
// @license       GPL-3.0 License
// @version       1.0.0

// @match         https://www.pokeclicker.com/
// @icon          https://www.google.com/s2/favicons?domain=pokeclicker.com
// @grant         unsafeWindow
// @run-at        document-idle
// ==/UserScript==

function initFarmPlotEditor() {
    let editMode = false;

    function createEditButton() {
        const shovelList = document.getElementById('shovelList');
        if (!shovelList) return;

        const buttonDiv = document.createElement('div');
        buttonDiv.className = 'row justify-content-center py-1';

        const button = document.createElement('button');
        button.id = 'farm-edit-mode-toggle';
        button.className = 'btn btn-block btn-danger';
        button.textContent = 'Edit Mode [OFF]';
        button.onclick = toggleEditMode;

        buttonDiv.appendChild(button);
        shovelList.before(buttonDiv);
    }

    function toggleEditMode() {
        editMode = !editMode;
        console.log('Farm Edit Mode:', editMode ? 'ON' : 'OFF');
        const button = document.getElementById('farm-edit-mode-toggle');
        button.className = `btn btn-block btn-${editMode ? 'success' : 'danger'}`;
        button.textContent = `Edit Mode [${editMode ? 'ON' : 'OFF'}]`;
    }

    function setPlotBerryAtBerryStage(plotIndex, berryType) {
        console.log(`Setting plot ${plotIndex} to berry ${berryType} (${BerryType[berryType]})`);

        if (plotIndex >= App.game.farming.plotList.length) {
            console.log(`Invalid plot index ${plotIndex}, max is ${App.game.farming.plotList.length - 1}`);
            return;
        }

        const plot = App.game.farming.plotList[plotIndex];

        // If plot has a berry, advance to berry stage and harvest
        if (plot.berry !== -1) {
            const berryData = App.game.farming.berryData[plot.berry];
            if (berryData && berryData.growthTime) {
                let targetAge = 0;
                for (let i = 0; i < 4 && i < berryData.growthTime.length; i++) {
                    targetAge += berryData.growthTime[i];
                }
                plot.age = targetAge;
                console.log(`Advanced existing berry to harvest stage`);
            }
            App.game.farming.harvest(plotIndex);
            console.log(`Harvested plot ${plotIndex}`);
        }

        // Plant new berry and advance to berry stage
        App.game.farming.plant(plotIndex, berryType);
        console.log(`Planted ${BerryType[berryType]} at plot ${plotIndex}`);

        const berryData = App.game.farming.berryData[berryType];
        if (berryData && berryData.growthTime) {
            let targetAge = 0;
            for (let i = 0; i < 4 && i < berryData.growthTime.length; i++) {
                targetAge += berryData.growthTime[i];
            }
            plot.age = targetAge;
            console.log(`Advanced to Berry stage (age: ${targetAge})`);
        }
    }

    function addPlotClickListeners() {
        console.log('Starting to look for farm container...');
        const checkForPlots = setInterval(() => {
            const farmContainer = document.querySelector('#farmContainer');
            console.log('Checking for farmContainer:', farmContainer ? 'found' : 'not found');

            // Also try alternative selectors
            const farmView = document.querySelector('#farmView');
            const plotElements = document.querySelectorAll('[data-bind*="plotList"]');
            console.log('farmView:', farmView ? 'found' : 'not found');
            console.log('plot elements found:', plotElements.length);

            if (farmContainer || farmView || plotElements.length > 0) {
                clearInterval(checkForPlots);
                console.log('Farm elements found, adding click listeners');

                const targetElement = farmContainer || farmView || document.body;
                console.log('Adding listener to:', targetElement.id || targetElement.tagName);

                targetElement.addEventListener('click', (e) => {
                    console.log('Click detected, edit mode:', editMode);
                    if (!editMode) return;

                    let target = e.target;
                    console.log('Initial target:', target.tagName, target.className);

                    // Check if we're clicking on a farm plot
                    let isPlotClick = false;
                    for (let i = 0; i < 10 && target; i++) {
                        if (target.hasAttribute('data-bind')) {
                            const dataBind = target.getAttribute('data-bind');
                            if (dataBind.includes('$index()')) {
                                isPlotClick = true;
                                break;
                            }
                        }
                        target = target.parentElement;
                    }

                    if (!isPlotClick) {
                        console.log('Not a plot click, allowing normal behavior');
                        return;
                    }

                    e.preventDefault();
                    e.stopPropagation();
                    console.log('Plot click intercepted');

                    target = e.target;
                    console.log('Initial target:', target.tagName, target.className);

                    // Check multiple levels up
                    for (let i = 0; i < 10 && target; i++) {
                        console.log(`Level ${i}:`, target.tagName, target.getAttribute('data-bind'));
                        if (target.hasAttribute('data-bind')) {
                            const dataBind = target.getAttribute('data-bind');
                            console.log('Found data-bind:', dataBind);

                            // Look for $index() which indicates we're in the foreach loop
                            if (dataBind.includes('$index()')) {
                                // Find the foreach element to get the plot index
                                let foreachElement = target;
                                while (foreachElement && !foreachElement.getAttribute('data-bind')?.includes('foreach: App.game.farming.plotList')) {
                                    foreachElement = foreachElement.parentElement;
                                }

                                if (foreachElement) {
                                    // Get all plot elements and find which one this is
                                    const allPlots = Array.from(foreachElement.children);
                                    console.log(`Total children in foreach: ${allPlots.length}`);
                                    console.log(`Total plots in game: ${App.game.farming.plotList.length}`);

                                    let plotIndex = -1;

                                    // Find the plot container that contains our clicked element
                                    let plotContainer = target;
                                    while (plotContainer && plotContainer.parentElement !== foreachElement) {
                                        plotContainer = plotContainer.parentElement;
                                    }

                                    if (plotContainer) {
                                        plotIndex = allPlots.indexOf(plotContainer);
                                        console.log(`Found plot container at DOM index ${plotIndex}`);

                                        // The DOM might include non-plot elements, so let's count only actual plots
                                        let actualPlotIndex = 0;
                                        for (let j = 0; j < plotIndex; j++) {
                                            if (allPlots[j].querySelector('[data-bind*="$index()"]')) {
                                                actualPlotIndex++;
                                            }
                                        }
                                        plotIndex = actualPlotIndex;
                                        console.log(`Corrected to actual plot index ${plotIndex}`);
                                    }

                                    if (plotIndex >= 0) {
                                        const selectedBerry = FarmController.selectedBerry();
                                        console.log(`Plot ${plotIndex} clicked, selected berry: ${selectedBerry}`);
                                        if (selectedBerry !== undefined) {
                                            setPlotBerryAtBerryStage(plotIndex, selectedBerry);
                                        }
                                        return;
                                    }
                                }
                            }
                        }
                        target = target.parentElement;
                    }
                    console.log('No plot found in click hierarchy');
                }, true);
            }
        }, 1000);
    }

    // Initialize when the game is loaded
    const initInterval = setInterval(() => {
        if (typeof App !== 'undefined' && App.game && App.game.farming && typeof FarmController !== 'undefined') {
            clearInterval(initInterval);
            createEditButton();
            addPlotClickListeners();
        }
    }, 1000);
}

// Auto-start the script
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initFarmPlotEditor);
} else {
    initFarmPlotEditor();
}