Enhanced Bank Sorting for flatmmmo.com

Add better sorting features to bank storage

目前為 2025-08-01 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Enhanced Bank Sorting for flatmmmo.com
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  Add better sorting features to bank storage
// @author       Carlos
// @match        https://flatmmo.com/play.php
// @match        https://flatmmo.com/play.php*
// @grant        none
// ==/UserScript==
 
(function() {
    'use strict';
 
    console.log('Enhanced Bank Sorting script loaded!');
 
    let original_bank_items = [];
    let current_sort_method = 'original';
 
    // Wait for the page to load and bank to be available
    function init() {
        if (typeof bank_items === 'undefined' || typeof refresh_bank !== 'function') {
            setTimeout(init, 500);
            return;
        }
 
        // Store original order when first loaded
        if (original_bank_items.length === 0) {
            original_bank_items = [...bank_items];
        }
 
        addSortingControls();
    }
 
    function addSortingControls() {
        const storageWrapper = document.querySelector('.storage-wrapper');
        if (!storageWrapper) {
            setTimeout(addSortingControls, 500);
            return;
        }
 
        // Check if controls already exist
        if (document.getElementById('sorting-controls')) {
            return;
        }
 
        // Create sorting controls container
        const sortingControls = document.createElement('div');
        sortingControls.id = 'sorting-controls';
        sortingControls.style.cssText = `
            margin: 10px 0;
            padding: 15px;
            background: rgba(255,255,255,0.1);
            border: 1px solid #555;
            border-radius: 5px;
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
            align-items: center;
        `;
 
        // Sort label
        const sortLabel = document.createElement('span');
        sortLabel.textContent = 'Sort by: ';
        sortLabel.style.cssText = `
            color: white;
            font-weight: bold;
            font-size: 14pt;
        `;
 
        // Sort buttons container
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = `
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        `;
 
        // Sort options with their functions
        const sortOptions = [
            { id: 'original', text: 'Original', method: sortByOriginal },
            { id: 'name-asc', text: 'Name A-Z', method: () => sortByName(false) },
            { id: 'name-desc', text: 'Name Z-A', method: () => sortByName(true) },
            { id: 'amount-high', text: 'Amount ↓', method: () => sortByAmount(true) },
            { id: 'amount-low', text: 'Amount ↑', method: () => sortByAmount(false) },
            { id: 'type', text: 'Type', method: sortByType }
        ];
 
        // Create buttons
        sortOptions.forEach(option => {
            const button = document.createElement('button');
            button.id = `sort-${option.id}`;
            button.textContent = option.text;
            button.style.cssText = `
                padding: 8px 12px;
                border: 1px solid #666;
                border-radius: 3px;
                background-color: #333;
                color: white;
                cursor: pointer;
                font-size: 11pt;
                font-family: Courier;
                transition: all 0.2s;
            `;
 
            button.addEventListener('mouseenter', function() {
                if (current_sort_method !== option.id) {
                    this.style.backgroundColor = '#555';
                }
            });
 
            button.addEventListener('mouseleave', function() {
                if (current_sort_method !== option.id) {
                    this.style.backgroundColor = '#333';
                }
            });
 
            button.addEventListener('click', function() {
                // Prevent re-sorting if the same method is selected
                if (current_sort_method === option.id) {
                    return;
                }
 
                // Reset all buttons to default style
                document.querySelectorAll('[id^="sort-"]').forEach(btn => {
                    btn.style.backgroundColor = '#333';
                    btn.style.borderColor = '#666';
                });
 
                // Highlight the selected button
                this.style.backgroundColor = '#555';
                this.style.borderColor = '#888';
 
                current_sort_method = option.id;
                resetBankItems(); // Reset items and apply new sort method
                option.method();
            });
 
            buttonContainer.appendChild(button);
        });
 
        // Set initial active button
        setTimeout(() => {
            document.getElementById('sort-original').style.backgroundColor = '#555';
            document.getElementById('sort-original').style.borderColor = '#888';
        }, 100);
 
        // Assemble controls
        sortingControls.appendChild(sortLabel);
        sortingControls.appendChild(buttonContainer);
 
        // Insert after the search input
        const searchInput = storageWrapper.querySelector('input[type="text"]');
        if (searchInput && searchInput.parentNode) {
            searchInput.parentNode.insertBefore(sortingControls, searchInput.nextSibling);
        } else {
            storageWrapper.insertBefore(sortingControls, storageWrapper.firstChild);
        }
    }
 
    // Function to reset bank items to original state and ensure no conflicts
    function resetBankItems() {
        bank_items.splice(0, bank_items.length, ...original_bank_items);
    }
 
    // Sorting Functions
    function sortByOriginal() {
        resetBankItems();
        refresh_bank();
    }
 
    function sortByName(reverse = false) {
        resetBankItems();
        bank_items.sort((a, b) => {
            const nameA = a.name.toLowerCase();
            const nameB = b.name.toLowerCase();
            return reverse ? nameB.localeCompare(nameA) : nameA.localeCompare(b.name);
        });
        refresh_bank();
    }
 
    function sortByAmount(highToLow = true) {
        resetBankItems();
        bank_items.sort((a, b) => {
            return highToLow ? b.value - a.value : a.value - b.value;
        });
        refresh_bank();
    }
 
    function sortByType() {
        resetBankItems();
        // Define item type categories based on common naming patterns
        const itemTypes = {
            weapons: ['sword', 'bow', 'staff', 'knife', 'axe', 'pickaxe', 'mace', 'club', 'harpoon'],
            armor: ['helmet', 'body', 'legs', 'boots', 'gloves', 'mask'],
            arrows: ['arrow', 'heads'],
            orbs: ['orb'],
            seeds: ['seeds'],
            mushrooms: ['mushroom'],
            potions: ['potion'],
            food: ['cooked', 'cake', 'egg'],
            materials: ['fur', 'hide', 'skin', 'coal', 'ore', 'logs', 'bamboo', 'string', 'feathers', 'nails', 'glass'],
            leaf:['leaf'],
            misc: [] // everything else
        };
 
        function getItemType(itemName) {
            const name = itemName.toLowerCase();
            for (const [type, keywords] of Object.entries(itemTypes)) {
                if (type === 'misc') continue;
                if (keywords.some(keyword => name.includes(keyword))) {
                    return type;
                }
            }
            return 'misc';
        }
 
        bank_items.sort((a, b) => {
            const typeA = getItemType(a.name);
            const typeB = getItemType(b.name);
            if (typeA !== typeB) {
                return typeA.localeCompare(typeB);
            }
            return a.name.localeCompare(b.name);
        });
        refresh_bank();
    }
 
    // Override the original refresh_bank function to maintain sorting
    const originalRefreshBank = window.refresh_bank;
    window.refresh_bank = function() {
        // Store current items before refresh if they haven't been stored yet
        if (bank_items.length > 0 && original_bank_items.length === 0) {
            original_bank_items = [...bank_items];
        }
 
        // Call the original refresh_bank function
        originalRefreshBank.apply(this, arguments);
 
        // Reapply current sorting if not original
        if (current_sort_method !== 'original') {
            const sortButton = document.getElementById(`sort-${current_sort_method}`);
            if (sortButton) {
                setTimeout(() => {
                    sortButton.click();
                }, 100);  // Increased delay to make sure refresh is done before re-sorting
            }
        }
    };
 
    // Start initialization
    init();
 
    // Also run when bank is opened
    const originalIsBank = window.is_bank_open;
    if (originalIsBank) {
        setInterval(() => {
            if (is_bank_open() && !document.getElementById('sorting-controls')) {
                addSortingControls();
            }
        }, 1000);
    }
 
})();