[Pokeclicker] Farm Plot Editor

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

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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
// @license       GPL-3.0 License
// @version       1.0.2

// @homepageURL   https://github.com/Ephenia/Pokeclicker-Scripts/
// @supportURL    https://github.com/Ephenia/Pokeclicker-Scripts/issues

// @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];

        // Step 1: If there is a berry, advance it to berry stage
        if (plot.berry !== -1) {
            const existingBerry = plot.berry;
            console.log(`Found existing berry: ${existingBerry} (${BerryType[existingBerry]})`);
            const existingBerryData = App.game.farming.berryData[existingBerry];
            const existingTargetAge = existingBerryData.growthTime[3];
            console.log(`Existing berry data:`, existingBerryData.growthTime);
            plot.age = existingTargetAge;
            console.log(`Step 1: Advanced existing berry ${BerryType[existingBerry]} to harvest stage (age: ${existingTargetAge})`);

            setTimeout(() => {
                // Step 2: Harvest plot
                App.game.farming.harvest(plotIndex);
                console.log(`Step 2: Harvested plot ${plotIndex}`);

                setTimeout(() => {
                    // Step 3: Plant selected berry
                    App.game.farming.plant(plotIndex, berryType);
                    console.log(`Step 3: Planted ${BerryType[berryType]} at plot ${plotIndex}`);

                    setTimeout(() => {
                        // Step 4: Advance new berry to berry stage
                        const newBerryData = App.game.farming.berryData[berryType];
                        const newTargetAge = newBerryData.growthTime[3];
                        console.log(`New berry data:`, newBerryData.growthTime);
                        plot.age = newTargetAge;
                        console.log(`Step 4: Advanced new berry to Berry stage (age: ${newTargetAge})`);
                    }, 100);
                }, 100);
            }, 100);
        } else {
            // Step 3: Plant selected berry
            App.game.farming.plant(plotIndex, berryType);
            console.log(`Step 3: Planted ${BerryType[berryType]} at plot ${plotIndex}`);

            setTimeout(() => {
                // Step 4: Advance new berry to berry stage
                const newBerryData = App.game.farming.berryData[berryType];
                const newTargetAge = newBerryData.growthTime[3];
                console.log(`New berry data:`, newBerryData.growthTime);
                plot.age = newTargetAge;
                console.log(`Step 4: Advanced new berry to Berry stage (age: ${newTargetAge})`);
            }, 100);
        }
    }

    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();
}