Train button 1.12

Replaces the Train buttons in Torn Gym with 16 clickable, customizable train icons. Every train plays the same custom whistle sound (plays once per click), mobile-safe settings modal, and a monochrome settings icon placed next to the Gym title (with safe fallback).

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

// ==UserScript==
// @name         Train button 1.12
// @namespace    http://tampermonkey.net/
// @version      1.13
// @description  Replaces the Train buttons in Torn Gym with 16 clickable, customizable train icons. Every train plays the same custom whistle sound (plays once per click), mobile-safe settings modal, and a monochrome settings icon placed next to the Gym title (with safe fallback).
// @author       Slenk
// @match        https://www.torn.com/gym.php*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // --- Hangmotor: minden vonathoz UGYANAZ a saját (feltöltött) hang szól ---
    // Nincs többé szintetizált sípolás - egy közös mp3 fájlt játszunk le minden kattintásra.
    const TRAIN_SOUND_URL = 'https://media.vocaroo.com/mp3/16iqFB1aQ7iP';
    let trainAudio = null;

    function getTrainAudio() {
        if (!trainAudio) {
            trainAudio = new Audio(TRAIN_SOUND_URL);
            trainAudio.preload = 'auto';
        }
        return trainAudio;
    }

    function playTrainSound() {
        try {
            const audio = getTrainAudio();
            // Ha gyorsan egymás után kattintanak, mindig az elejéről szóljon újra.
            audio.currentTime = 0;
            const playPromise = audio.play();
            if (playPromise && typeof playPromise.catch === 'function') {
                playPromise.catch((e) => console.warn('Train sound play error:', e));
            }
        } catch (e) {
            console.warn('Train sound error:', e);
        }
    }

    // Az alapértelmezett színek a csatolt kép alapján
    const trainDefaultColors = {
        train1: '#F1C40F',
        train2: '#F1C40F',
        train3: '#F1C40F',
        train4: '#F1C40F',
        train5: '#F1C40F',
        train6: '#3498DB',
        train7: '#ECF0F1',
        train8: '#7F8C8D',
        train9: '#2980B9',
        train10: '#27AE60',
        train11: '#E74C3C',
        train12: '#2ECC71',
        train13: '#ECF0F1',
        train14: '#27AE60',
        train15: '#95A5A6',
        train16: '#229954'
    };

    function loadColors() {
        let saved = {};
        try { saved = JSON.parse(GM_getValue('trainColors', '{}')); } catch (e) { saved = {}; }
        return Object.assign({}, trainDefaultColors, saved);
    }

    let settings = {
        trainType: GM_getValue('trainType', 'train1'),
        trainColors: loadColors()
    };

    const trainIcons = {
        train1: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M10,45 L10,10 L40,10 L40,25 L75,25 L75,45 Z" fill="COLOR_PLACEHOLDER" stroke="#333" stroke-width="2"/>
          <rect x="8" y="5" width="34" height="5" fill="#C0392B" stroke="#333" stroke-width="2"/>
          <path d="M55,25 L55,8 L65,8 L65,25 Z" fill="#D35400" stroke="#333" stroke-width="2"/>
          <rect x="15" y="15" width="15" height="15" fill="#FFF" stroke="#333" stroke-width="2"/>
          <polygon points="75,45 90,45 85,35 75,35" fill="#C0392B" stroke="#333" stroke-width="2"/>
          <circle cx="25" cy="50" r="8" fill="#E74C3C" stroke="#333" stroke-width="2"/>
          <circle cx="45" cy="50" r="6" fill="#E74C3C" stroke="#333" stroke-width="2"/>
          <circle cx="65" cy="50" r="6" fill="#E74C3C" stroke="#333" stroke-width="2"/>
          <line x1="25" y1="50" x2="65" y2="50" stroke="#DDD" stroke-width="2"/>
        </svg>`,

        train2: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M10,40 L10,15 C10,10 15,10 20,10 L80,10 C90,10 95,20 95,40 Z" fill="#FFF" stroke="#333" stroke-width="2"/>
          <path d="M10,45 L95,45 C95,35 95,35 95,35 L10,35 Z" fill="COLOR_PLACEHOLDER" stroke="#333" stroke-width="2"/>
          <rect x="25" y="15" width="10" height="20" fill="COLOR_PLACEHOLDER" stroke="#333" stroke-width="2"/>
          <rect x="65" y="15" width="10" height="20" fill="COLOR_PLACEHOLDER" stroke="#333" stroke-width="2"/>
          <rect x="12" y="18" width="10" height="10" fill="#333" rx="1"/>
          <rect x="40" y="18" width="20" height="10" fill="#333" rx="1"/>
          <path d="M80,18 L88,18 C90,18 90,25 88,28 L80,28 Z" fill="#333"/>
          <circle cx="25" cy="50" r="6" fill="#555" stroke="#333" stroke-width="2"/>
          <circle cx="40" cy="50" r="6" fill="#555" stroke="#333" stroke-width="2"/>
          <circle cx="60" cy="50" r="6" fill="#555" stroke="#333" stroke-width="2"/>
          <circle cx="75" cy="50" r="6" fill="#555" stroke="#333" stroke-width="2"/>
        </svg>`,

        train3: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M10,40 L10,15 C10,12 12,10 15,10 L35,10 L35,25 L80,25 L80,40 Z" fill="COLOR_PLACEHOLDER" stroke="#333" stroke-width="2"/>
          <rect x="8" y="6" width="30" height="5" fill="#E74C3C" stroke="#333" stroke-width="2" rx="2"/>
          <rect x="45" y="25" width="4" height="15" fill="#F1C40F" stroke="#333" stroke-width="1"/>
          <rect x="65" y="25" width="4" height="15" fill="#F1C40F" stroke="#333" stroke-width="1"/>
          <path d="M68,25 L70,10 L82,10 L84,25 Z" fill="#2980B9" stroke="#333" stroke-width="2"/>
          <rect x="15" y="15" width="7" height="10" fill="#FFF" stroke="#333" stroke-width="2"/>
          <rect x="25" y="15" width="7" height="10" fill="#FFF" stroke="#333" stroke-width="2"/>
          <polygon points="80,40 95,50 80,50" fill="#E74C3C" stroke="#333" stroke-width="2"/>
          <circle cx="20" cy="45" r="9" fill="#CCC" stroke="#333" stroke-width="2"/>
          <circle cx="45" cy="48" r="6" fill="#CCC" stroke="#333" stroke-width="2"/>
          <circle cx="65" cy="48" r="6" fill="#CCC" stroke="#333" stroke-width="2"/>
          <circle cx="85" cy="48" r="6" fill="#CCC" stroke="#333" stroke-width="2"/>
          <line x1="20" y1="45" x2="85" y2="48" stroke="#777" stroke-width="2"/>
        </svg>`,

        train4: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M5,45 L10,15 L35,15 L40,5 L80,5 L85,25 L95,25 L95,45 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="3"/>
          <circle cx="15" cy="25" r="1.5" fill="#FFF"/><circle cx="25" cy="25" r="1.5" fill="#FFF"/><circle cx="35" cy="25" r="1.5" fill="#FFF"/>
          <rect x="50" y="12" width="10" height="8" fill="#111" stroke="#555" stroke-width="2"/>
          <rect x="65" y="12" width="10" height="8" fill="#111" stroke="#555" stroke-width="2"/>
          <path d="M95,45 L100,55 L85,55 L85,45 Z" fill="#444" stroke="#222" stroke-width="2"/>
          <circle cx="25" cy="50" r="7" fill="#555" stroke="#222" stroke-width="2"/>
          <circle cx="50" cy="50" r="7" fill="#555" stroke="#222" stroke-width="2"/>
          <circle cx="75" cy="50" r="7" fill="#555" stroke="#222" stroke-width="2"/>
          <line x1="25" y1="50" x2="75" y2="50" stroke="#888" stroke-width="3"/>
        </svg>`,

        train5: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M5,45 L5,25 C5,15 20,15 30,15 L70,15 C90,15 95,35 95,45 Z" fill="COLOR_PLACEHOLDER" stroke="#333" stroke-width="2"/>
          <path d="M25,20 L65,20 C80,20 85,28 85,30 L20,30 C20,25 22,20 25,20 Z" fill="#222"/>
          <line x1="5" y1="38" x2="92" y2="38" stroke="#FFF" stroke-width="1.5"/>
          <path d="M15,45 L25,45 A 5 5 0 0 1 35 45 L55,45 A 5 5 0 0 1 65 45 L75,45 A 5 5 0 0 1 85 45 L95,45 L95,50 L5,50 Z" fill="#444" stroke="#333" stroke-width="2"/>
          <circle cx="30" cy="48" r="4" fill="#111"/>
          <circle cx="60" cy="48" r="4" fill="#111"/>
          <circle cx="80" cy="48" r="4" fill="#111"/>
        </svg>`,

        train6: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M10,42 L10,12 C10,10 12,8 15,8 L85,8 C92,8 95,12 95,42 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="18" y="15" width="14" height="20" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="42" y="15" width="14" height="20" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="66" y="15" width="14" height="20" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="10" y="38" width="85" height="4" fill="#E67E22"/>
          <circle cx="28" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
          <circle cx="72" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
          <path d="M95,40 L100,40 L100,44 L95,44" fill="#555" stroke="#222"/>
        </svg>`,

        train7: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M15,40 L15,15 C15,10 25,10 40,10 L65,10 C85,10 95,25 95,40 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="22" y="18" width="8" height="10" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="35" y="18" width="8" height="10" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="48" y="18" width="8" height="10" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <path d="M61,18 L73,18 C76,18 80,25 80,28 L61,28 Z" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <line x1="20" y1="32" x2="85" y2="32" stroke="#E74C3C" stroke-width="1.5"/>
          <rect x="10" y="40" width="85" height="6" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
        </svg>`,

        train8: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <rect x="15" y="10" width="20" height="25" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="35" y="18" width="40" height="17" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="12" y="8" width="26" height="4" fill="#D35400" stroke="#222" stroke-width="1.5"/>
          <path d="M58,18 L58,8 L66,8 L66,18 Z" fill="#2980B9" stroke="#222" stroke-width="1.5"/>
          <rect x="20" y="16" width="10" height="10" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <polygon points="75,35 85,35 90,45 75,45" fill="#D35400" stroke="#222" stroke-width="1.5"/>
          <circle cx="28" cy="45" r="7" fill="#555" stroke="#222" stroke-width="2"/>
          <circle cx="48" cy="45" r="7" fill="#555" stroke="#222" stroke-width="2"/>
          <circle cx="68" cy="45" r="7" fill="#555" stroke="#222" stroke-width="2"/>
          <line x1="28" y1="45" x2="68" y2="45" stroke="#DDD" stroke-width="2"/>
        </svg>`,

        train9: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M12,38 L12,12 C12,10 14,10 16,10 L84,10 C86,10 88,10 88,12 L88,38 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="14" y="8" width="26" height="4" fill="#D35400" stroke="#222" stroke-width="1.5"/>
          <rect x="20" y="16" width="8" height="10" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="32" y="16" width="8" height="10" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <line x1="60" y1="16" x2="60" y2="30" stroke="#333" stroke-width="1.5"/>
          <line x1="66" y1="16" x2="66" y2="30" stroke="#333" stroke-width="1.5"/>
          <line x1="72" y1="16" x2="72" y2="30" stroke="#333" stroke-width="1.5"/>
          <line x1="78" y1="16" x2="78" y2="30" stroke="#333" stroke-width="1.5"/>
          <rect x="8" y="38" width="84" height="4" fill="#333"/>
          <circle cx="25" cy="48" r="6" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="45" cy="48" r="6" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="65" cy="48" r="6" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
        </svg>`,

        train10: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <polyline points="25,12 35,4 45,12" fill="none" stroke="#555" stroke-width="2"/>
          <polyline points="55,12 65,4 75,12" fill="none" stroke="#555" stroke-width="2"/>
          <path d="M15,40 L15,18 C15,14 18,12 22,12 L78,12 C82,12 85,14 85,18 L85,40 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="25" y="18" width="10" height="8" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="45" y="18" width="10" height="8" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="65" y="18" width="10" height="8" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="15" y="34" width="70" height="6" fill="#2C3E50"/>
          <polygon points="15,40 10,48 20,48" fill="#D35400" stroke="#222" stroke-width="1.5"/>
          <polygon points="85,40 90,48 80,48" fill="#D35400" stroke="#222" stroke-width="1.5"/>
          <circle cx="30" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="50" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="70" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
        </svg>`,

        train11: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M5,42 L5,10 L75,10 C90,10 95,30 95,42 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="12" y="18" width="8" height="18" fill="#FFF" stroke="#222" stroke-width="1.5"/>
          <rect x="25" y="14" width="10" height="8" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="40" y="14" width="10" height="8" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="55" y="14" width="10" height="8" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="25" y="28" width="10" height="8" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="40" y="28" width="10" height="8" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="55" y="28" width="10" height="8" fill="#333" stroke="#222" stroke-width="1"/>
          <path d="M75,20 L85,20 C88,20 90,28 90,32 L75,32 Z" fill="#333"/>
          <circle cx="20" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="50" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="80" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
        </svg>`,

        train12: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <rect x="55" y="18" width="35" height="18" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="15" y="10" width="40" height="26" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <path d="M80,18 L80,10 L88,10 L88,18 Z" fill="#2C3E50" stroke="#222" stroke-width="1.5"/>
          <rect x="20" y="14" width="8" height="12" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="32" y="14" width="8" height="12" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="44" y="14" width="8" height="12" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <polygon points="90,36 100,45 85,45" fill="#E74C3C" stroke="#222" stroke-width="1.5"/>
          <circle cx="28" cy="44" r="9" fill="#E74C3C" stroke="#222" stroke-width="2"/>
          <circle cx="55" cy="46" r="6" fill="#E74C3C" stroke="#222" stroke-width="1.5"/>
          <circle cx="72" cy="46" r="6" fill="#E74C3C" stroke="#222" stroke-width="1.5"/>
          <circle cx="89" cy="46" r="6" fill="#E74C3C" stroke="#222" stroke-width="1.5"/>
          <line x1="28" y1="44" x2="89" y2="46" stroke="#ECF0F1" stroke-width="2"/>
        </svg>`,

        train13: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M5,40 L5,20 C5,15 15,15 30,15 L60,15 C85,15 95,30 95,40 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <line x1="5" y1="32" x2="90" y2="32" stroke="#2980B9" stroke-width="3"/>
          <rect x="15" y="20" width="8" height="8" rx="2" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="30" y="20" width="8" height="8" rx="2" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="45" y="20" width="8" height="8" rx="2" fill="#333" stroke="#222" stroke-width="1"/>
          <rect x="60" y="20" width="8" height="8" rx="2" fill="#333" stroke="#222" stroke-width="1"/>
          <path d="M75,20 L85,20 C88,20 90,25 90,28 L75,28 Z" fill="#333"/>
          <circle cx="20" cy="48" r="4" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="45" cy="48" r="4" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="70" cy="48" r="4" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
        </svg>`,

        train14: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <rect x="15" y="25" width="70" height="15" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="35" y="10" width="30" height="15" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="40" y="14" width="8" height="8" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <rect x="52" y="14" width="8" height="8" fill="#AEE6FA" stroke="#222" stroke-width="1.5"/>
          <path d="M42,10 L45,5 L55,5 L58,10 Z" fill="#2C3E50" stroke="#222"/>
          <line x1="15" y1="20" x2="85" y2="20" stroke="#F1C40F" stroke-width="1.5"/>
          <line x1="20" y1="20" x2="20" y2="25" stroke="#F1C40F" stroke-width="1.5"/>
          <line x1="30" y1="20" x2="30" y2="25" stroke="#F1C40F" stroke-width="1.5"/>
          <line x1="70" y1="20" x2="70" y2="25" stroke="#F1C40F" stroke-width="1.5"/>
          <line x1="80" y1="20" x2="80" y2="25" stroke="#F1C40F" stroke-width="1.5"/>
          <rect x="10" y="40" width="80" height="4" fill="#E74C3C" stroke="#222" stroke-width="1.5"/>
          <circle cx="25" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
          <circle cx="50" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
          <circle cx="75" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
        </svg>`,

        train15: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <path d="M10,30 L10,15 C10,10 15,10 25,10 L75,10 C85,10 95,20 95,30 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <path d="M10,42 L10,30 L95,30 L95,42 Z" fill="#E74C3C" stroke="#222" stroke-width="2"/>
          <rect x="30" y="16" width="10" height="10" fill="#333" stroke="#222" stroke-width="1.5"/>
          <rect x="45" y="16" width="10" height="10" fill="#333" stroke="#222" stroke-width="1.5"/>
          <rect x="60" y="16" width="10" height="10" fill="#333" stroke="#222" stroke-width="1.5"/>
          <path d="M78,16 L88,16 C90,16 92,20 92,26 L78,26 Z" fill="#333"/>
          <rect x="15" y="16" width="10" height="20" fill="#FFF" stroke="#222" stroke-width="1.5"/>
          <circle cx="25" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
          <circle cx="45" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
          <circle cx="75" cy="48" r="5" fill="#555" stroke="#222" stroke-width="1.5"/>
        </svg>`,

        train16: `<svg class="train-icon-btn" viewBox="0 0 100 60" width="60" height="36">
          <polyline points="25,12 35,4 45,12" fill="none" stroke="#555" stroke-width="2"/>
          <polyline points="55,12 65,4 75,12" fill="none" stroke="#555" stroke-width="2"/>
          <path d="M15,40 L15,18 C15,12 18,12 25,12 L75,12 C82,12 85,15 90,25 L95,40 Z" fill="COLOR_PLACEHOLDER" stroke="#222" stroke-width="2"/>
          <rect x="25" y="18" width="40" height="8" fill="#333" stroke="#222" stroke-width="1.5"/>
          <line x1="15" y1="32" x2="92" y2="32" stroke="#E74C3C" stroke-width="3"/>
          <path d="M88,40 L95,40 L95,45 C95,48 90,48 85,45 Z" fill="#E74C3C" stroke="#222" stroke-width="1.5"/>
          <circle cx="30" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="50" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
          <circle cx="70" cy="48" r="5" fill="#7F8C8D" stroke="#222" stroke-width="1.5"/>
        </svg>`
    };

    // Monokróm vonat + fogaskerék ikon a beállítás gombhoz
    const settingsIconSvg = `<svg viewBox="0 0 64 64" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round" style="display:block;">
      <rect x="5" y="24" width="30" height="18" rx="3"/>
      <rect x="11" y="28" width="8" height="7"/>
      <rect x="23" y="28" width="8" height="7"/>
      <circle cx="13" cy="46" r="3.5"/>
      <circle cx="27" cy="46" r="3.5"/>
      <line x1="5" y1="24" x2="5" y2="18"/>
      <line x1="5" y1="18" x2="13" y2="18"/>
      <circle cx="49" cy="18" r="7"/>
      <circle cx="49" cy="18" r="2.3" fill="currentColor" stroke="none"/>
      <line x1="49" y1="7" x2="49" y2="11"/>
      <line x1="49" y1="25" x2="49" y2="29"/>
      <line x1="38" y1="18" x2="42" y2="18"/>
      <line x1="56" y1="18" x2="60" y2="18"/>
      <line x1="40.7" y1="9.7" x2="43.5" y2="12.5"/>
      <line x1="54.5" y1="23.5" x2="57.3" y2="26.3"/>
      <line x1="40.7" y1="26.3" x2="43.5" y2="23.5"/>
      <line x1="54.5" y1="12.5" x2="57.3" y2="9.7"/>
    </svg>`;

    function addStyles() {
        if (document.getElementById('train-custom-styles')) return;
        const style = document.createElement('style');
        style.id = 'train-custom-styles';
        style.innerHTML = `
            #train-settings-launcher {
                display: inline-flex; align-items: center; justify-content: center;
                width: 30px; height: 30px; box-sizing: border-box;
                background-color: rgba(60,60,60,0.85); color: #ddd;
                border: 1px solid rgba(255,255,255,0.25); border-radius: 6px;
                cursor: pointer; padding: 0; line-height: 0; margin-left: 6px;
            }
            #train-settings-launcher:hover { background-color: rgba(90,90,90,0.9); color:#fff; }
            /* Fallback pozíció, ha nem sikerül a Gym cím mellé illeszteni */
            #train-settings-launcher.train-launcher-fallback {
                position: fixed;
                right: max(12px, env(safe-area-inset-right));
                bottom: max(12px, env(safe-area-inset-bottom));
                z-index: 99999;
                box-shadow: 0 2px 6px rgba(0,0,0,0.5);
            }
            #train-modal-overlay {
                display: none; position: fixed; top: 0; left: 0;
                width: 100%; height: 100%; background: rgba(0,0,0,0.6); z-index: 100000;
            }
            #train-settings-modal {
                position: fixed; top: 50%; left: 50%;
                transform: translate(-50%, -50%);
                background: #fff; color: #333; border-radius: 10px; padding: 16px;
                width: min(380px, 92vw);
                max-height: 85vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
                box-sizing: border-box;
                box-shadow: 0 5px 15px rgba(0,0,0,0.7); font-family: Arial, sans-serif;
            }
            #train-settings-modal h3 { margin: 0 0 15px 0; text-align: center; border-bottom: 2px solid #ddd; padding-bottom: 10px; }
            #train-preview-wrapper { display: flex; justify-content: center; align-items: center; background: #f4f4f4; border: 1px solid #ddd; border-radius: 6px; padding: 10px; margin-bottom: 15px; }
            #train-preview svg { width: 120px; height: 72px; max-width: 100%; }
            .train-radio-group {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
                gap: 8px; margin-bottom: 15px;
            }
            .train-radio-group label { display: flex; align-items: center; cursor: pointer; font-size: 12px; }
            .train-radio-group input { margin-right: 5px; cursor: pointer; }
            .train-color-group { margin-bottom: 20px; }
            .train-color-group label { display: block; font-weight: bold; margin-bottom: 5px; }
            .train-color-row { display: flex; gap: 8px; }
            #train-color-picker { flex: 1; height: 40px; cursor: pointer; border: 1px solid #ccc; border-radius: 4px; min-width: 0; }
            #train-reset-color-btn { flex: 0 0 auto; background-color: #7f8c8d; color: #fff; border: none; border-radius: 4px; padding: 0 12px; cursor: pointer; font-weight: bold; font-size: 12px; }
            #train-reset-color-btn:hover { background-color: #95a5a6; }
            .train-modal-buttons { display: flex; gap: 10px; }
            .train-btn { flex: 1; padding: 10px; border: none; border-radius: 5px; cursor: pointer; font-weight: bold; color: #fff; }
            #train-save-btn { background-color: #27ae60; }
            #train-save-btn:hover { background-color: #2ecc71; }
            #train-cancel-btn { background-color: #c0392b; }
            #train-cancel-btn:hover { background-color: #e74c3c; }
            .train-icon-btn { transition: transform 0.1s ease-in-out, filter 0.1s ease-in-out; cursor: pointer; display: block; margin: 0 auto; overflow: visible; }
            .train-icon-btn:hover { transform: scale(1.15); filter: brightness(1.1); }
            .train-icon-btn:active { transform: scale(0.95); }
            .custom-train-wrapper { display: inline-flex; justify-content: center; align-items: center; width: 100%; height: 100%; }
            .custom-train-wrapper.train-disabled .train-icon-btn:hover { transform: none; filter: grayscale(1) brightness(0.85); }
            .custom-train-wrapper.train-disabled .train-icon-btn:active { transform: none; }
            .custom-train-wrapper.train-disabled { cursor: not-allowed; }
            @media (max-width: 420px) {
                #train-settings-modal { padding: 12px; }
                .train-radio-group { grid-template-columns: repeat(auto-fit, minmax(76px, 1fr)); font-size: 11px; }
            }
        `;
        document.head.appendChild(style);
    }

    function updatePreview() {
        const checked = document.querySelector('input[name="trainType"]:checked');
        const type = checked ? checked.value : settings.trainType;
        const color = document.getElementById('train-color-picker').value;
        const preview = document.getElementById('train-preview');
        if (preview) {
            preview.innerHTML = (trainIcons[type] || trainIcons.train1).replace(/COLOR_PLACEHOLDER/g, color);
        }
    }

    function buildRadioGroup() {
        let html = '';
        for (let i = 1; i <= 16; i++) {
            const type = 'train' + i;
            html += `<label><input type="radio" name="trainType" value="${type}" ${settings.trainType === type ? 'checked' : ''}> Train ${i}</label>`;
        }
        return html;
    }

    // Megpróbáljuk a Gym cím / City-tutorial gombok mellé illeszteni a launcher-t.
    // A Torn oldal DOM-ja időnként változik, ezért több lehetséges helyet is megnézünk,
    // és ha egyik sem található, marad a mobil-biztos, sarokba rögzített változat.
    function tryAttachToTitleBar(launcher) {
        const containerSelectors = [
            '.tutorial-button-icon',
            '[class*="titleButtons"]',
            '[class*="topButtons"]',
            '[class*="content-title"] [class*="right"]',
            '[class*="titleWrapper"] [class*="buttons"]'
        ];

        for (const sel of containerSelectors) {
            const container = document.querySelector(sel);
            if (container && container.parentElement) {
                container.parentElement.insertBefore(launcher, container);
                return true;
            }
        }

        // Fallback: keresünk egy elemet, aminek pontosan "Gym" a szövege (a cím maga)
        const candidates = document.querySelectorAll('div, span, h1, h2, h3, h4, h5');
        for (const el of candidates) {
            if (el.children.length === 0 && el.textContent.trim() === 'Gym') {
                el.insertAdjacentElement('afterend', launcher);
                return true;
            }
        }

        return false;
    }

    function createUI() {
        if (!document.body || document.getElementById('train-settings-launcher')) return;

        addStyles();

        const launcher = document.createElement('button');
        launcher.id = 'train-settings-launcher';
        launcher.type = 'button';
        launcher.title = 'Train button settings';
        launcher.setAttribute('aria-label', 'Train button settings');
        launcher.innerHTML = settingsIconSvg;

        const attached = tryAttachToTitleBar(launcher);
        if (!attached) {
            launcher.classList.add('train-launcher-fallback');
            document.body.appendChild(launcher);
        }

        const overlay = document.createElement('div');
        overlay.id = 'train-modal-overlay';

        const modal = document.createElement('div');
        modal.id = 'train-settings-modal';
        modal.innerHTML = `
            <h3>Train Settings</h3>
            <div id="train-preview-wrapper"><div id="train-preview"></div></div>
            <div class="train-radio-group">${buildRadioGroup()}</div>
            <div class="train-color-group">
                <label for="train-color-picker">Main Color:</label>
                <div class="train-color-row">
                    <input type="color" id="train-color-picker" value="${settings.trainColors[settings.trainType] || trainDefaultColors[settings.trainType] || '#F1C40F'}">
                    <button id="train-reset-color-btn" type="button">Reset to Default</button>
                </div>
            </div>
            <div class="train-modal-buttons">
                <button id="train-save-btn" class="train-btn">Save</button>
                <button id="train-cancel-btn" class="train-btn">Cancel</button>
            </div>
        `;
        overlay.appendChild(modal);
        document.body.appendChild(overlay);

        function openModal() {
            overlay.style.display = 'block';
            if (!trainIcons[settings.trainType]) {
                settings.trainType = 'train1';
                GM_setValue('trainType', 'train1');
            }
            const radio = document.querySelector(`input[name="trainType"][value="${settings.trainType}"]`);
            if (radio) radio.checked = true;
            document.getElementById('train-color-picker').value = settings.trainColors[settings.trainType] || trainDefaultColors[settings.trainType] || '#F1C40F';
            updatePreview();
        }

        function closeModal() {
            overlay.style.display = 'none';
        }

        launcher.addEventListener('click', openModal);
        document.getElementById('train-cancel-btn').addEventListener('click', closeModal);
        overlay.addEventListener('click', (e) => { if (e.target === overlay) closeModal(); });

        modal.querySelectorAll('input[name="trainType"]').forEach((input) => {
            input.addEventListener('change', () => {
                const type = input.value;
                document.getElementById('train-color-picker').value = settings.trainColors[type] || trainDefaultColors[type] || '#F1C40F';
                updatePreview();
            });
        });

        document.getElementById('train-color-picker').addEventListener('input', updatePreview);

        document.getElementById('train-reset-color-btn').addEventListener('click', () => {
            const checked = document.querySelector('input[name="trainType"]:checked');
            const type = checked ? checked.value : settings.trainType;
            document.getElementById('train-color-picker').value = trainDefaultColors[type] || '#F1C40F';
            updatePreview();
        });

        document.getElementById('train-save-btn').addEventListener('click', () => {
            const selectedTrain = document.querySelector('input[name="trainType"]:checked').value;
            const selectedColor = document.getElementById('train-color-picker').value;

            settings.trainColors[selectedTrain] = selectedColor;
            settings.trainType = selectedTrain;

            GM_setValue('trainType', selectedTrain);
            GM_setValue('trainColors', JSON.stringify(settings.trainColors));

            closeModal();

            document.querySelectorAll('.custom-train-wrapper').forEach((wrapper) => {
                wrapper.innerHTML = getIconHtml();
            });
        });

        if (typeof GM_registerMenuCommand !== 'undefined') {
            GM_registerMenuCommand('Open Train Button Settings', openModal);
        }
    }

    function getIconHtml() {
        const safeTrainType = trainIcons[settings.trainType] ? settings.trainType : 'train1';
        const color = settings.trainColors[safeTrainType] || trainDefaultColors[safeTrainType] || '#F1C40F';
        return trainIcons[safeTrainType].replace(/COLOR_PLACEHOLDER/g, color);
    }

    function isDisabled(el) {
        if (!el) return false;
        if (el.disabled) return true;
        if (el.getAttribute('aria-disabled') === 'true') return true;
        if (el.classList && el.classList.contains('disabled')) return true;
        if (typeof el.className === 'string' && el.className.toLowerCase().indexOf('disabled') !== -1) return true;
        return false;
    }

    function updateDisabledStates() {
        document.querySelectorAll('[data-train-replaced="true"]').forEach((el) => {
            const wrapper = el.querySelector('.custom-train-wrapper');
            if (!wrapper) return;
            if (isDisabled(el)) {
                wrapper.classList.add('train-disabled');
            } else {
                wrapper.classList.remove('train-disabled');
            }
        });
    }

    function replaceTrainButtons() {
        if (!document.body) return;
        createUI();

        const elements = document.querySelectorAll('button, a, [class*="btn"]');

        elements.forEach((el) => {
            if (el.textContent.trim().toUpperCase() === 'TRAIN' && !el.dataset.trainReplaced) {
                if (el.querySelectorAll('input, select, textarea').length > 0) return;

                el.dataset.trainReplaced = 'true';
                el.style.color = 'transparent';
                el.style.fontSize = '0px';
                el.style.backgroundColor = 'transparent';
                el.style.backgroundImage = 'none';
                el.style.border = 'none';
                el.style.boxShadow = 'none';
                el.style.padding = '0';
                el.setAttribute('aria-label', 'Train');

                const iconWrapper = document.createElement('span');
                iconWrapper.className = 'custom-train-wrapper';
                iconWrapper.title = 'Train';
                iconWrapper.innerHTML = getIconHtml();
                if (isDisabled(el)) {
                    iconWrapper.classList.add('train-disabled');
                }

                // Minden egyes kattintás pontosan egyszer szólaltatja meg a közös hangot,
                // így ha valaki többször nyom rá, annyiszor is hallható lesz.
                iconWrapper.addEventListener('click', () => {
                    if (isDisabled(el)) return;
                    playTrainSound();
                });

                el.appendChild(iconWrapper);
            }
        });

        updateDisabledStates();
    }

    let scanScheduled = false;
    function scheduleScan() {
        if (scanScheduled) return;
        scanScheduled = true;
        setTimeout(() => {
            scanScheduled = false;
            replaceTrainButtons();
        }, 150);
    }

    function startObserving() {
        if (!document.body) {
            setTimeout(startObserving, 100);
            return;
        }
        const observer = new MutationObserver(() => scheduleScan());
        observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'disabled', 'aria-disabled'] });
        replaceTrainButtons();
    }

    startObserving();
    setInterval(replaceTrainButtons, 2000);

})();