// ==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 // @downloadURL https://update.greasyfork.icu/scripts/559521/Torn%20Christmas%20Town%20D-Pad.user.js // @updateURL https://update.greasyfork.icu/scripts/559521/Torn%20Christmas%20Town%20D-Pad.meta.js // ==/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': ``, 'top': ``, 'right-top': ``, 'left': ``, 'right': ``, 'left-bottom': ``, 'bottom': ``, 'right-bottom': `` }; 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(); } })();