您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a very basic dice tab to the sidebar with various die sizes
// ==UserScript== // @name Add Multi-Dice Roller Tab to Panel Tabs // @namespace http://tampermonkey.net/ // @version 1.1 // @description Adds a very basic dice tab to the sidebar with various die sizes // @match https://ogres.app/play/* // @license MIT // @grant none // ==/UserScript== (function () { 'use strict'; const MAX_RETRIES = 100; const RETRY_INTERVAL_MS = 100; let attempts = 0; function tryAddDiceTab() { const ul = document.querySelector('ul.panel-tabs'); if (!ul) { if (attempts < MAX_RETRIES) { attempts++; if (attempts % 10 === 0) { console.log(`[DiceTab] Waiting... (attempt ${attempts})`); } setTimeout(tryAddDiceTab, RETRY_INTERVAL_MS); return; } else { console.warn('[DiceTab] ul.panel-tabs not found after max retries.'); return; } } console.log('[DiceTab] Found ul.panel-tabs, adding dice tab...'); const li = document.createElement('li'); li.className = 'panel-tabs-tab'; // option 2: li.style.cursor = 'pointer'; const label = document.createElement('label'); const input = document.createElement('input'); input.type = 'radio'; input.name = 'panel'; input.value = 'dice'; // SVG DICE const svgNS = 'http://www.w3.org/2000/svg'; const svg = document.createElementNS(svgNS, 'svg'); svg.setAttribute('width', '16'); svg.setAttribute('height', '16'); svg.setAttribute('viewBox', '0 0 16 16'); svg.setAttribute('fill', 'currentColor'); const die = document.createElementNS(svgNS, 'rect'); die.setAttribute('x', '1'); die.setAttribute('y', '1'); die.setAttribute('width', '14'); die.setAttribute('height', '14'); die.setAttribute('rx', '2'); die.setAttribute('ry', '2'); die.setAttribute('stroke', 'currentColor'); die.setAttribute('fill', 'none'); svg.appendChild(die); const createDot = (cx, cy) => { const dot = document.createElementNS(svgNS, 'circle'); dot.setAttribute('cx', cx); dot.setAttribute('cy', cy); dot.setAttribute('r', '1.2'); dot.setAttribute('fill', 'currentColor'); return dot; }; // D6 face with 6 dots const positions = [ [4, 4], [8, 4], [12, 4], [4, 12], [8, 12], [12, 12], ]; positions.forEach(([cx, cy]) => svg.appendChild(createDot(cx, cy))); // END SVG DICE label.appendChild(input); label.appendChild(svg); li.appendChild(label); //ul.appendChild(li); const lastItem = ul.lastElementChild; ul.insertBefore(li, lastItem); console.log('[DiceTab] Dice tab added. Setting up interaction...'); input.addEventListener('change', () => { if (!input.checked) return; console.log('[DiceTab] Dice tab selected — updating .form-body...'); const panel = document.querySelector('.form-body'); if (!panel) { console.warn('[DiceTab] .form-body not found.'); return; } // Setup other tabs to hide dice panel const otherTabs = [...ul.querySelectorAll('li.panel-tabs-tab')].filter(el => el !== li); otherTabs.forEach(tab => { tab.addEventListener('click', () => { const panel = document.querySelector('#form-panel'); if (!panel) return; const dicePanel = panel.querySelector('#dice-panel'); if (dicePanel) { dicePanel.style.display = 'none'; } }); }); // Hide all direct children of #form-panel [...panel.children].forEach(child => child.style.display = 'none'); // Create or show dice panel let dicePanel = document.querySelector('#dice-panel'); if (!dicePanel) { dicePanel = document.createElement('div'); dicePanel.id = 'dice-panel'; dicePanel.style.padding = '1em'; const result = document.createElement('div'); result.textContent = '🎲 Click a die to roll.'; result.style.marginTop = '1em'; // History display const historyTitle = document.createElement('div'); historyTitle.textContent = 'Last 100 rolls:'; historyTitle.style.marginTop = '1em'; historyTitle.style.fontWeight = 'bold'; const historyList = document.createElement('ul'); historyList.style.paddingLeft = '20px'; //historyList.style.maxHeight = '120px'; historyList.style.overflowY = 'auto'; historyList.style.fontSize = '0.9em'; // Rolling buffer array const rollHistory = []; const dice = [4, 6, 8, 10, 12, 20, 100]; dice.forEach(sides => { const btn = document.createElement('button'); btn.textContent = `d${sides}`; btn.style.marginRight = '0.5em'; btn.addEventListener('click', () => { const roll = Math.floor(Math.random() * sides) + 1; result.textContent = `🎲 You rolled a ${roll} on a d${sides}`; // Add to history rollHistory.unshift(`d${sides}: ${roll}`); if (rollHistory.length > 100) rollHistory.pop(); // Update history display historyList.innerHTML = ''; rollHistory.forEach(entry => { const li = document.createElement('li'); li.textContent = entry; historyList.appendChild(li); }); }); dicePanel.appendChild(btn); }); dicePanel.appendChild(result); dicePanel.appendChild(historyTitle); dicePanel.appendChild(historyList); const footer = document.querySelector('.form-footer'); if (footer) { footer.style.visibility = "hidden"; } panel.appendChild(dicePanel); } dicePanel.style.display = 'block'; // Show our dice panel dicePanel.style.display = 'block'; }); } console.log('[DiceTab] Starting tab insert with retry logic...'); tryAddDiceTab(); })();