Greasy Fork

来自缓存

Greasy Fork is available in English.

Torn Christmas Town D-Pad

Adds an 8-direction D-pad controller for navigating Christmas Town

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Torn Christmas Town D-Pad
// @namespace    https://torn.com
// @version      2.1
// @description  Adds an 8-direction D-pad controller for navigating Christmas Town
// @author       ANITABURN
// @match        https://www.torn.com/christmas_town.php*
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    function triggerKeyEvent(key, type) {
        const event = new KeyboardEvent(type, {
            key: key,
            code: key,
            keyCode: { 'ArrowUp': 38, 'ArrowDown': 40, 'ArrowLeft': 37, 'ArrowRight': 39 }[key],
            bubbles: true,
            cancelable: true,
            composed: true
        });
        document.dispatchEvent(event);
    }

    const directionKeys = {
        'left-top': ['ArrowLeft', 'ArrowUp'],
        'top': ['ArrowUp'],
        'right-top': ['ArrowRight', 'ArrowUp'],
        'left': ['ArrowLeft'],
        'right': ['ArrowRight'],
        'left-bottom': ['ArrowLeft', 'ArrowDown'],
        'bottom': ['ArrowDown'],
        'right-bottom': ['ArrowRight', 'ArrowDown']
    };

    GM_addStyle(`
        .ct-dpad-container {
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 10px;
            background: linear-gradient(180deg, #333 0%, #333 100%);
            border-top: 1px solid #333;
        }

        .ct-dpad {
            display: grid;
            grid-template-columns: 42px 42px 42px;
            grid-template-rows: 42px 42px 42px;
            gap: 6px;
        }

        .ct-dpad-btn {
            width: 42px;
            height: 42px;
            border: none;
            border-radius: 6px;
            background: linear-gradient(180deg, #666 0%, #666 100%);
            color: #fff;
            font-size: 16px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 2px 4px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.2);
            user-select: none;
            opacity: 0.9;
        }

        .ct-dpad-btn:active {
            opacity: 1.0;
            background: linear-gradient(180deg, #666 0%, #666 100%);
        }

        .ct-dpad-btn svg {
            width: 22px;
            height: 22px;
            fill: currentColor;
        }

        .ct-dpad-btn.ct-dpad-center {
            visibility: hidden;
        }

        .ct-dpad-left-top { grid-column: 1; grid-row: 1; }
        .ct-dpad-top { grid-column: 2; grid-row: 1; }
        .ct-dpad-right-top { grid-column: 3; grid-row: 1; }
        .ct-dpad-left { grid-column: 1; grid-row: 2; }
        .ct-dpad-center { grid-column: 2; grid-row: 2; }
        .ct-dpad-right { grid-column: 3; grid-row: 2; }
        .ct-dpad-left-bottom { grid-column: 1; grid-row: 3; }
        .ct-dpad-bottom { grid-column: 2; grid-row: 3; }
        .ct-dpad-right-bottom { grid-column: 3; grid-row: 3; }
    `);

    function createDpad() {
        const container = document.createElement('div');
        container.className = 'ct-dpad-container';

        const dpad = document.createElement('div');
        dpad.className = 'ct-dpad';

        const arrows = {
            'left-top': `<svg viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" transform="rotate(-45 12 12)"/></svg>`,
            'top': `<svg viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"/></svg>`,
            'right-top': `<svg viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" transform="rotate(45 12 12)"/></svg>`,
            'left': `<svg viewBox="0 0 24 24"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6z"/></svg>`,
            'right': `<svg viewBox="0 0 24 24"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6z"/></svg>`,
            'left-bottom': `<svg viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" transform="rotate(-135 12 12)"/></svg>`,
            'bottom': `<svg viewBox="0 0 24 24"><path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z"/></svg>`,
            'right-bottom': `<svg viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" transform="rotate(135 12 12)"/></svg>`
        };

        const directions = [
            'left-top', 'top', 'right-top',
            'left', 'center', 'right',
            'left-bottom', 'bottom', 'right-bottom'
        ];

        directions.forEach(dir => {
            const btn = document.createElement('div');
            btn.className = `ct-dpad-btn ct-dpad-${dir}`;

            if (dir !== 'center') {
                btn.innerHTML = arrows[dir];

                const keys = directionKeys[dir];

                btn.addEventListener('touchstart', (e) => {
                    e.preventDefault();
                    keys.forEach(key => triggerKeyEvent(key, 'keydown'));
                });
                btn.addEventListener('touchend', (e) => {
                    e.preventDefault();
                    keys.forEach(key => triggerKeyEvent(key, 'keyup'));
                });

                btn.addEventListener('mousedown', () => {
                    keys.forEach(key => triggerKeyEvent(key, 'keydown'));
                });
                btn.addEventListener('mouseup', () => {
                    keys.forEach(key => triggerKeyEvent(key, 'keyup'));
                });
                btn.addEventListener('mouseleave', () => {
                    keys.forEach(key => triggerKeyEvent(key, 'keyup'));
                });
            }

            dpad.appendChild(btn);
        });

        container.appendChild(dpad);
        return container;
    }

    function insertDpad() {
        const itemsContainer = document.querySelector('.items-container.itemsContainer___HEW8n') ||
                              document.querySelector('.items-container');

            if (itemsContainer && !document.querySelector('.ct-dpad-container')) {
            const dpad = createDpad();
            itemsContainer.parentNode.insertBefore(dpad, itemsContainer);
            console.log('[CT D-Pad] D-pad inserted successfully');
        }
    }

    function init() {
        insertDpad();

        const observer = new MutationObserver(() => {
            if (!document.querySelector('.ct-dpad-container')) {
                insertDpad();
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });

        let attempts = 0;
        const interval = setInterval(() => {
            if (document.querySelector('.ct-dpad-container') || attempts > 20) {
                clearInterval(interval);
            } else {
                insertDpad();
                attempts++;
            }
        }, 500);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();