Replaces the Train buttons in Torn Gym with 16 clickable, customizable train icons (Based on image reference).
// ==UserScript==
// @name Train button
// @namespace http://tampermonkey.net/
// @version 1.11
// @description Replaces the Train buttons in Torn Gym with 16 clickable, customizable train icons (Based on image reference).
// @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';
// --- ÚJ: Hang beállítások ---
const trainSoundUrl = "https://media.vocaroo.com/mp3/16iqFB1aQ7iP";
const trainAudio = new Audio(trainSoundUrl);
trainAudio.volume = 0.5;
let lastSoundPlayed = 0;
// Az alapértelmezett színek frissítve a csatolt kép alapján
const trainDefaultColors = {
train1: '#F1C40F',
train2: '#F1C40F',
train3: '#F1C40F',
train4: '#F1C40F',
train5: '#F1C40F',
train6: '#3498DB', // Világoskék metró
train7: '#ECF0F1', // Fehér maglev
train8: '#7F8C8D', // Szürke gőzös
train9: '#2980B9', // Kék dízel
train10: '#27AE60',// Zöld villanymozdony 1
train11: '#E74C3C',// Piros emeletes
train12: '#2ECC71',// Zöld gőzös
train13: '#ECF0F1',// Fehér shinkansen
train14: '#27AE60',// Zöld tolatómozdony
train15: '#95A5A6',// Szürke-piros modern
train16: '#229954' // Sötétzöld villanymozdony 2
};
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 = {
// --- Eredeti 1-5 vonatok ---
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>`,
// --- Új vonatok a kép alapján (6-16) ---
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"/>
<!-- Sárga korlát -->
<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>`
};
function addStyles() {
if (document.getElementById('train-custom-styles')) return;
const style = document.createElement('style');
style.id = 'train-custom-styles';
style.innerHTML = `
#train-settings-launcher { position: fixed; bottom: 20px; right: 20px; z-index: 99999; background-color: #333; color: #fff; border: 2px solid #555; padding: 10px 15px; border-radius: 8px; cursor: pointer; font-weight: bold; box-shadow: 0 4px 6px rgba(0,0,0,0.5); }
#train-settings-launcher:hover { background-color: #555; }
#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: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; color: #333; border-radius: 10px; padding: 20px; width: 380px; max-height: 85vh; overflow-y: auto; 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; }
.train-radio-group { display: grid; grid-template-columns: 1fr 1fr 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; }
#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; }
`;
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;
}
function createUI() {
if (!document.body || document.getElementById('train-settings-launcher')) return;
addStyles();
const launcher = document.createElement('button');
launcher.id = 'train-settings-launcher';
launcher.innerText = 'Train button setting';
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');
}
el.appendChild(iconWrapper);
}
});
updateDisabledStates();
}
// --- ÚJ: Hang lejátszásának figyelője ---
const domObserver = new MutationObserver((mutations) => {
for (const m of mutations) {
if (m.addedNodes.length > 0) {
m.addedNodes.forEach(node => {
if (node.nodeType === Node.ELEMENT_NODE) {
const text = node.textContent.toLowerCase();
if (text.includes("gained") && (text.includes("strength") || text.includes("speed") || text.includes("defense") || text.includes("dexterity"))) {
const now = Date.now();
if (now - lastSoundPlayed > 1000) {
trainAudio.play().catch(e => console.warn("Nem sikerült lejátszani a hangot:", e));
lastSoundPlayed = now;
}
}
}
});
}
}
});
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();
// --- ÚJ: Hang figyelő indítása ---
domObserver.observe(document.body, { childList: true, subtree: true });
}
startObserving();
setInterval(replaceTrainButtons, 2000);
})();