您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Some silly fixes and 'improvements' to Roll20 because I'm impatient and a psycho
当前为
// ==UserScript== // @name Roll20 Fixes // @namespace http://statonions.com/ // @version 0.1 // @description Some silly fixes and 'improvements' to Roll20 because I'm impatient and a psycho // @author Justice Noon // @match https://app.roll20.net/editor/ // @grant none // ==/UserScript== (function() { 'use strict'; //Features var TMp = { clickShow: true, macroHide: true, fullButt: true, fixPing: true, css: { player: false, zoom: false, sidebar: false, quick: false, turns: false, macroTok: true }, pfCustomAttr: true, splitTokName: true }; //For *my* players specifically. Activates all css tweaks. I'm too lazy to maintain separate code (in-person touchpad view) ////_.each(TMp.css, (c,i,l) => l[i] = true); function checkLoaded() { if (Campaign.gameFullyLoaded) showtime(); else setTimeout(checkLoaded, 1000); }; checkLoaded(); function showtime() { //Display tokenname on touch if (TMp.clickShow) { var toks = []; var callback = function(mutationsList) { for(var mutation of mutationsList) { if (!_.isEmpty(mutation.addedNodes)) { let cct = currentcontexttarget.canvas.lastRenderedObjectWithControlsAboveOverlay.model.attributes; if (!cct.showname) { cct.showname = true; toks.push([cct.page_id, cct.id]); Campaign.activePage().loadPageIntoDOM(); } if (cct.gmnotes != 'blank' && TMp.css.macroTok) _.each(document.getElementsByClassName('tokenactions')[0].firstElementChild.children, ob => ob.setAttribute('data-blank', 'false')); } else if (!_.isEmpty(mutation.removedNodes)) { _.each(toks, tok => {if (tok[0] == Campaign.activePage().id) _.find(Campaign.activePage().thegraphics.models, tokk => tokk.attributes.id == tok[1]).attributes.showname = false}); toks = []; Campaign.activePage().loadPageIntoDOM(); } } }; var observer = new MutationObserver(callback); observer.observe(document.getElementById('editor-wrapper'), {childList: true}); } //Allow Macros to be hidden if (TMp.macroHide) { var toggleMacro = document.createElement('div'); toggleMacro.setAttribute('class', 'macrobox'); var toggleButton = document.createElement('button'); toggleButton.setAttribute('class', 'btn'); toggleButton.appendChild(document.createTextNode('Show/Hide')); toggleButton.id = 'toggleMacros'; toggleMacro.appendChild(toggleButton) //macrobar is defined by default macrobar.appendChild(toggleMacro); document.getElementById('toggleMacros').addEventListener('click', () => macrobar.style.left = (macrobar.style.left == '' ? (macrobar.offsetWidth * -1 + 100) + 'px' : '')); } //Create fullscreen button if (TMp.fullButt) { var fullScreenLi = document.createElement('li'); fullScreenLi.setAttribute('tip', 'Toggle Fullscreen'); fullScreenLi.id = 'fullscreener'; var fullScreenSpan = document.createElement('span'); fullScreenSpan.setAttribute('class', 'pictos'); fullScreenSpan.appendChild(document.createTextNode('`')); fullScreenLi.appendChild(fullScreenSpan); floatingtoolbar.childNodes[1].appendChild(fullScreenLi); fullScreenLi.addEventListener('click', toggleFullScreen); function toggleFullScreen() { var doc = window.document; var docEl = doc.documentElement; var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen; var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen; if(!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) { requestFullScreen.call(docEl); } else { cancelFullScreen.call(doc); } } } //Fix Pings if (TMp.fixPing) { JSON.parse2 = JSON.parse; JSON.parse = function(e) { var intercept = JSON.parse2(e); if (intercept.type == 'mapping') { intercept.currentLayer = 'objects'; if (intercept.pageid != Campaign.activePage().id) intercept.scrollto = false; } return intercept; }; } //CSS override block if (_.contains(TMp.css, true)) { var style = document.createElement('style'); style.type = 'text/css'; //Remove player names/ icons if (TMp.css.player) style.innerHTML = '.player.ui-droppable {display: none;} '; //Remove Zoom Slider if (TMp.css.zoom) style.innerHTML = '#zoomslider {display:none;} '; //Remove sidebar show/ hide button if (TMp.css.sidebar) style.innerHTML = '#sidebarcontrol {display: none;} '; //Increase quickmenu sizes if (TMp.css.quick) style.innerHTML += '.sheet-roll-cell>a{padding:.5em !important;} '; //Permanently hide turn order if (TMp.css.turns) style.innerHTML += 'div.ui-dialog-buttons[style*="width: 160px;"] {display: none !important;} '; //Hide macroTokens by default if (TMp.css.macroTok) style.innerHTML += 'button[data-type="macro"]:not([data-blank="false"]) {display: none !important;} '; document.getElementsByTagName('head')[0].appendChild(style); } //Character sheets display custom attributes as name if (TMp.pfCustomAttr) { function cssInjection(charId) { var list = [1,2,3,10,11,12]; var head = 'div.dialog.characterdialog[data-characterid=' + charId + '] {', foot = ''; _.each(list, function(cK) { cK = 'customa' + cK; let val = {}; if (!_.isUndefined(val = _.find(Campaign.characters._byId[charId].attribs.models, at => at.attributes.name == cK + '-name'))) head += `--${cK}: "${val.attributes.current}"; ` foot += `input[title="@{buff_${cK}-total}"] + span {visibility: hidden; top: -1.2rem;} input[title="@{buff_${cK}-total}"] + span::after {content: var(--${cK}, "${cK}"); visibility: visible; display: block;} ` }); return [head + '} ', foot]; } function newShow(that) { var customOver; var modCss = cssInjection(that.model.attributes.id); if (_.isNull(document.getElementById('customOver'))) { customOver = document.createElement('style'); customOver.type = 'text/css'; customOver.id = 'customOver'; customOver.innerHTML = modCss[1]; } else { customOver = document.getElementById('customOver'); } customOver.innerHTML += (modCss[0].indexOf('{}') > -1 ? '' : modCss[0]); if (that.childWindow) _.delay(function() {customOver.innerHTML = modCss.join(' '); window.allChildWindows[0].document.getElementsByTagName('head')[0].appendChild(customOver)}, 2000); else document.getElementsByTagName('head')[0].appendChild(customOver); }; _.each(Campaign.characters.models, ch => {ch.view.showDialog2 = ch.view.showDialog; ch.view.showDialog = function(e, t) {this.showDialog2(e, t); newShow(this)}}); _.each(Campaign.characters.models, ch => {ch.view.showPopout2 = ch.view.showPopout; ch.view.showPopout = function(e, t) {this.showPopout2(e, t); newShow(this)}}); _.each(window.allChildWindows, win => {newShow(Campaign.characters._byId[win.document.getElementsByClassName('dialog characterdialog')[0].getAttribute('data-characterid')].view)}); } //Tokens auto split their name to multiple lines if (TMp.splitTokName) { var can = document.getElementById('maincanvas').getContext('2d'); can.fillRect2 = can.fillRect; can.fillRect = function(x, y, w, h) {if (this.font != 'bold 14px Arial' && this.fillStyle.indexOf('rgba(255,255,255,0.5') == -1) this.fillRect2(x, y, w, h);}; can.fillText2 = can.fillText; can.fillText = function(t, x, y, m) { var g = 14, r = y - 22, n = m; var texes = t.split(' '); for (var k = 0; k < texes.length; k++) { n = this.measureText(texes[k]).width; while (this.measureText(texes[k] + ' ' + texes[k+1]).width < r*2 && k+1 < texes.length) { texes[k] += ' ' + texes[k+1]; n = this.measureText(texes[k]).width; texes.splice(k+1, 1); } this.fillStyle = 'rgba(255, 255, 255, 0.50)'; this.fillRect2(-1 * Math.floor((n + 6) / 2), r + 8 + (g+6)*k, n + 6, g + 6); this.fillStyle = 'rgb(0,0,0)'; this.fillText2(texes[k], x, y + (g+6)*k, n); } }; } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址