From 888b089e7b431a49bd267fa3c61fb5fa5c6ad85e Mon Sep 17 00:00:00 2001 From: CDeenen Date: Thu, 7 Jan 2021 05:38:16 +0100 Subject: [PATCH] v1.2.1 --- MaterialDeck.js | 27 +- README.md | 2 +- changelog.md | 27 ++ img/.thumb/black.png.jpg | Bin 0 -> 3346 bytes img/black.png | Bin 0 -> 1090 bytes img/move/.thumb/rotateccw.png.jpg | Bin 0 -> 8428 bytes img/move/.thumb/rotatecw.png.jpg | Bin 0 -> 8387 bytes img/move/SOURCES.txt | 3 +- img/move/rotateccw.png | Bin 0 -> 7299 bytes img/move/rotatecw.png | Bin 0 -> 7343 bytes lang/en.json | 2 + module.json | 2 +- src/combattracker.js | 53 ++-- src/external.js | 40 ++- src/move.js | 115 +++++--- src/othercontrols.js | 457 +++++++++++------------------- src/scene.js | 196 +++++++++++++ src/settings.js | 11 + src/streamDeck.js | 83 +++++- src/token.js | 74 ++++- 20 files changed, 690 insertions(+), 402 deletions(-) create mode 100644 img/.thumb/black.png.jpg create mode 100644 img/black.png create mode 100644 img/move/.thumb/rotateccw.png.jpg create mode 100644 img/move/.thumb/rotatecw.png.jpg create mode 100644 img/move/rotateccw.png create mode 100644 img/move/rotatecw.png create mode 100644 src/scene.js diff --git a/MaterialDeck.js b/MaterialDeck.js index 0a0ff14..f3d47f8 100644 --- a/MaterialDeck.js +++ b/MaterialDeck.js @@ -8,6 +8,7 @@ import {PlaylistControl} from "./src/playlist.js"; import {SoundboardControl} from "./src/soundboard.js"; import {OtherControls} from "./src/othercontrols.js"; import {ExternalModules} from "./src/external.js"; +import {SceneControl} from "./src/scene.js"; export var streamDeck; export var tokenControl; var move; @@ -17,6 +18,7 @@ export var playlistControl; export var soundboard; export var otherControls; export var externalModules; +export var sceneControl; export const moduleName = "MaterialDeck"; export var selectedTokenId; @@ -50,6 +52,7 @@ async function analyzeWSmessage(msg){ if (data.type == "connected" && data.data == "SD"){ console.log("streamdeck connected to server"); + streamDeck.resetImageBuffer(); } if (data == undefined || data.payload == undefined) return; @@ -86,6 +89,8 @@ async function analyzeWSmessage(msg){ otherControls.update(settings,context); else if (action == 'external') externalModules.update(settings,context); + else if (action == 'scene') + sceneControl.update(settings,context); } else if (event == 'willDisappear'){ @@ -106,9 +111,11 @@ async function analyzeWSmessage(msg){ else if (action == 'soundboard') soundboard.keyPressDown(settings); else if (action == 'other') - otherControls.keyPress(settings); + otherControls.keyPress(settings,context); else if (action == 'external') externalModules.keyPress(settings,context); + else if (action == 'scene') + sceneControl.keyPress(settings); } else if (event == 'keyUp'){ @@ -210,7 +217,7 @@ Hooks.once('ready', ()=>{ playlistControl = new PlaylistControl(); otherControls = new OtherControls(); externalModules = new ExternalModules(); - + sceneControl = new SceneControl(); let soundBoardSettings = game.settings.get(moduleName,'soundboardSettings'); let macroSettings = game.settings.get(moduleName, 'macroSettings'); @@ -294,18 +301,18 @@ Hooks.on('controlToken',(token,controlled)=>{ Hooks.on('renderHotbar', (hotbar)=>{ if (enableModule == false || ready == false) return; - macroControl.hotbar(hotbar.macros); + if (macroControl != undefined) macroControl.hotbar(hotbar.macros); }); Hooks.on('renderCombatTracker',()=>{ if (enableModule == false || ready == false) return; - combatTracker.updateAll(); - tokenControl.update(selectedTokenId); + if (combatTracker != undefined) combatTracker.updateAll(); + if (tokenControl != undefined) tokenControl.update(selectedTokenId); }); Hooks.on('renderPlaylistDirectory', (playlistDirectory)=>{ if (enableModule == false || ready == false) return; - playlistControl.updateAll(); + if (playlistControl != undefined) playlistControl.updateAll(); }); Hooks.on('closeplaylistConfigForm', (form)=>{ @@ -321,17 +328,19 @@ Hooks.on('pauseGame',()=>{ Hooks.on('renderSidebarTab',()=>{ if (enableModule == false || ready == false) return; - otherControls.updateAll(); + if (otherControls != undefined) otherControls.updateAll(); + if (sceneControl != undefined) sceneControl.updateAll(); }); Hooks.on('updateScene',()=>{ if (enableModule == false || ready == false) return; - otherControls.updateAll(); + sceneControl.updateAll(); externalModules.updateAll(); + otherControls.updateAll(); }); Hooks.on('renderSceneControls',()=>{ - if (enableModule == false || ready == false) return; + if (enableModule == false || ready == false || otherControls == undefined) return; otherControls.updateAll(); }); diff --git a/README.md b/README.md index 792dd66..f4c70ae 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ Instructions and more info can be found in the p.id == tokenId); + let token = (canvas.tokens.children[0] != undefined) ? canvas.tokens.children[0].children.find(p => p.id == tokenId) : undefined; if (token == undefined) return; if (onClick == 'doNothing') //Do nothing return; @@ -178,7 +163,7 @@ export class CombatTracker{ canvas.animatePan(location); } else if (onClick == 'centerSelect'){ //center on token and select - let location = token.getCenter(token.x,token.y); + const location = token.getCenter(token.x,token.y); canvas.animatePan(location); token.control(); } diff --git a/src/external.js b/src/external.js index 103d475..5278203 100644 --- a/src/external.js +++ b/src/external.js @@ -21,6 +21,7 @@ export class ExternalModules{ if (module == undefined) module = 'fxmaster'; if (module == 'fxmaster') this.updateFxMaster(settings,context); + else if (module == 'gmscreen') this.updateGMScreen(settings,context); } @@ -29,9 +30,17 @@ export class ExternalModules{ let module = settings.module; if (module == undefined) module = 'fxmaster'; - if (module == 'fxmaster') { //scene + if (module == 'fxmaster') this.keyPressFxMaster(settings,context); - } + else if (module == 'gmscreen') + this.keyPressGMScreen(settings,context); + + } + + getModuleEnable(moduleId){ + const module = game.modules.get(moduleId); + if (module == undefined || module.active == false) return false; + return true; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -231,4 +240,31 @@ export class ExternalModules{ } return undefined; } + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //GM Screen + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + updateGMScreen(settings,context){ + if (this.getModuleEnable("gm-screen") == false) return; + + const background = settings.gmScreenBackground ? settings.gmScreenBackground : '#000000'; + let ring = 1; + let ringColor = '#00FF00' + let src = ''; + let txt = ''; + + //if (document.getElementsByClassName("gm-screen-app gm-screen-drawer expanded")[0] != undefined) ring = 2; + + if (settings.displayGmScreenIcon) src = "fas fa-book-reader"; + streamDeck.setIcon(context,src,background,ring,ringColor); + if (settings.displayGmScreenName) txt = game.i18n.localize(`GMSCR.gmScreen.Open`); + streamDeck.setTitle(txt,context); + } + + keyPressGMScreen(settings,context){ + if (this.getModuleEnable("gm-screen") == false) return; + + document.getElementsByClassName("gm-screen-button")[0].click(); + } } \ No newline at end of file diff --git a/src/move.js b/src/move.js index dfbaa89..b47f5db 100644 --- a/src/move.js +++ b/src/move.js @@ -7,59 +7,84 @@ export class Move{ } update(settings,context){ - let background; - if (settings.background) background = settings.background; - else background = '#000000'; + const background = settings.background ? settings.background : '#000000'; + const mode = settings.mode ? settings.mode : 'canvas'; + const type = settings.type ? settings.type : 'move'; let url = ''; - if (settings.dir == 'center') //center - url = "modules/MaterialDeck/img/move/center.png"; - else if (settings.dir == 'up') //up - url = "modules/MaterialDeck/img/move/up.png"; - else if (settings.dir == 'down') //down - url = "modules/MaterialDeck/img/move/down.png"; - else if (settings.dir == 'right') //right - url = "modules/MaterialDeck/img/move/right.png"; - else if (settings.dir == 'left') //left - url = "modules/MaterialDeck/img/move/left.png"; - else if (settings.dir == 'upRight') - url = "modules/MaterialDeck/img/move/upright.png"; - else if (settings.dir == 'upLeft') - url = "modules/MaterialDeck/img/move/upleft.png"; - else if (settings.dir == 'downRight') - url = "modules/MaterialDeck/img/move/downright.png"; - else if (settings.dir == 'downLeft') - url = "modules/MaterialDeck/img/move/downleft.png"; - else if (settings.dir == 'zoomIn') - url = "modules/MaterialDeck/img/move/zoomin.png"; - else if (settings.dir == 'zoomOut') - url = "modules/MaterialDeck/img/move/zoomout.png"; + if (mode == 'canvas' || (mode == 'selectedToken' && type == 'move')){ + const dir = settings.dir ? settings.dir : 'center'; + if (dir == 'center') //center + url = "modules/MaterialDeck/img/move/center.png"; + else if (dir == 'up') //up + url = "modules/MaterialDeck/img/move/up.png"; + else if (dir == 'down') //down + url = "modules/MaterialDeck/img/move/down.png"; + else if (dir == 'right') //right + url = "modules/MaterialDeck/img/move/right.png"; + else if (dir == 'left') //left + url = "modules/MaterialDeck/img/move/left.png"; + else if (dir == 'upRight') + url = "modules/MaterialDeck/img/move/upright.png"; + else if (dir == 'upLeft') + url = "modules/MaterialDeck/img/move/upleft.png"; + else if (dir == 'downRight') + url = "modules/MaterialDeck/img/move/downright.png"; + else if (dir == 'downLeft') + url = "modules/MaterialDeck/img/move/downleft.png"; + else if (dir == 'zoomIn') + url = "modules/MaterialDeck/img/move/zoomin.png"; + else if (dir == 'zoomOut') + url = "modules/MaterialDeck/img/move/zoomout.png"; + } + else if (mode == 'selectedToken' && type == 'rotate'){ + const value = isNaN(parseInt(settings.rotValue)) ? 0 : parseInt(settings.rotValue); + if (value >= 0) + url = "modules/MaterialDeck/img/move/rotatecw.png"; + else + url = "modules/MaterialDeck/img/move/rotateccw.png"; + } streamDeck.setIcon(context,url,background); } + keyPress(settings){ if (canvas.scene == null) return; - let dir = settings.dir; - let mode = settings.mode; - if (mode == undefined) mode = 'canvas'; - if (dir == undefined) dir = 'center'; + const dir = settings.dir ? settings.dir : 'center'; + const mode = settings.mode ? settings.mode : 'canvas'; + const type = settings.type ? settings.type : 'move'; - if (dir == 'zoomIn') {//zoom in - let viewPosition = canvas.scene._viewPosition; - viewPosition.scale = viewPosition.scale*1.05; - viewPosition.duration = 100; - canvas.animatePan(viewPosition); + if (type == 'move'){ + if (dir == 'zoomIn') {//zoom in + let viewPosition = canvas.scene._viewPosition; + viewPosition.scale = viewPosition.scale*1.05; + viewPosition.duration = 100; + canvas.animatePan(viewPosition); + } + else if (dir == 'zoomOut') {//zoom out + let viewPosition = canvas.scene._viewPosition; + viewPosition.scale = viewPosition.scale*0.95; + viewPosition.duration = 100; + canvas.animatePan(viewPosition); + } + else { + if (settings.mode == 'selectedToken') + this.moveToken(MODULE.selectedTokenId,dir); + else + this.moveCanvas(dir); + } } - else if (dir == 'zoomOut') {//zoom out - let viewPosition = canvas.scene._viewPosition; - viewPosition.scale = viewPosition.scale*0.95; - viewPosition.duration = 100; - canvas.animatePan(viewPosition); - } - else { - if (settings.mode == 'selectedToken') - this.moveToken(MODULE.selectedTokenId,dir); - else - this.moveCanvas(dir); + else if (type == 'rotate' && mode == 'selectedToken'){ + const token = canvas.tokens.children[0].children.find(p => p.id == MODULE.selectedTokenId); + if (token == undefined) return; + + const rotType = settings.rot ? settings.rot : 'to'; + const value = isNaN(parseInt(settings.rotValue)) ? 0 : parseInt(settings.rotValue); + + let rotationVal; + if (rotType == 'by') rotationVal = token.data.rotation + value; + else if (rotType == 'to') rotationVal = value; + + token.update({rotation: rotationVal}); } } diff --git a/src/othercontrols.js b/src/othercontrols.js index 0074ffc..698ed35 100644 --- a/src/othercontrols.js +++ b/src/othercontrols.js @@ -4,7 +4,7 @@ import {streamDeck} from "../MaterialDeck.js"; export class OtherControls{ constructor(){ this.active = false; - this.offset = 0; + this.rollData = {}; } async updateAll(){ @@ -18,108 +18,75 @@ export class OtherControls{ update(settings,context){ this.active = true; - let mode = settings.otherMode; - if (mode == undefined) mode = 'pause'; + const mode = settings.otherMode ? settings.otherMode : 'pause'; - if (mode == 'pause') { //pause - this.updatePause(settings.pauseFunction,context); - } - else if (mode == 'sceneSelect') { //scene selection - this.updateScene(settings,context); - } - else if (mode == 'controlButtons'){ //control buttons + if (mode == 'pause') //pause + this.updatePause(settings,context); + else if (mode == 'controlButtons') //control buttons this.updateControl(settings,context); - } - else if (mode == 'darkness'){ //darkness + else if (mode == 'darkness') //darkness this.updateDarkness(settings,context); - } - else if (mode == 'rollTables'){ //roll tables + else if (mode == 'rollDice') //roll dice + this.updateRollDice(settings,context); + else if (mode == 'rollTables') //roll tables this.updateRollTable(settings,context); - } - else if (mode == 'sidebarTab') { //open sidebar tab + else if (mode == 'sidebarTab') //open sidebar tab this.updateSidebar(settings,context); - } - else if (mode == 'compendium') { //open compendium + else if (mode == 'compendium') //open compendium this.updateCompendium(settings,context); - } - else if (mode == 'journal') { //open journal + else if (mode == 'journal') //open journal this.updateJournal(settings,context); - } + else if (mode == 'chatMessage') + this.updateChatMessage(settings,context); } - keyPress(settings){ - let mode = settings.otherMode; - if (mode == undefined) mode = 'pause'; + keyPress(settings,context){ + const mode = settings.otherMode ? settings.otherMode : 'pause'; - if (mode == 'pause') { //pause - this.keyPressPause(settings.pauseFunction); - } - else if (mode == 'sceneSelect') { //scene - this.keyPressScene(settings); - } - else if (mode == 'controlButtons') { //control buttons + if (mode == 'pause') //pause + this.keyPressPause(settings); + else if (mode == 'controlButtons') //control buttons this.keyPressControl(settings); - } - else if (mode == 'darkness') { //darkness controll + else if (mode == 'darkness') //darkness controll this.keyPressDarkness(settings); - } - else if (mode == 'rollTables') { //roll tables + else if (mode == 'rollDice') //roll dice + this.keyPressRollDice(settings,context); + else if (mode == 'rollTables') //roll tables this.keyPressRollTable(settings); - } - else if (mode == 'sidebarTab') { //sidebar + else if (mode == 'sidebarTab') //sidebar this.keyPressSidebar(settings); - } - else if (mode == 'compendium') { //open compendium + else if (mode == 'compendium') //open compendium this.keyPressCompendium(settings); - } - else if (mode == 'journal') { //open journal + else if (mode == 'journal') //open journal this.keyPressJournal(settings); - } + else if (mode == 'chatMessage') + this.keyPressChatMessage(settings); } ////////////////////////////////////////////////////////////////////////////////////////////////// - updatePause(pauseFunction,context){ + updatePause(settings,context){ let src = ""; - if (pauseFunction == undefined) pauseFunction = 'pause'; - - let background = settings.background; - if(background == undefined) background = '#000000'; + const pauseFunction = settings.pauseFunction ? settings.pauseFunction : 'pause'; + const background = settings.background ? settings.background : '#000000'; + const ringOffColor = settings.offRing ? settings.offRing : '#000000'; + const ringOnColor = settings.onRing ? settings.onRing : '#00FF00'; + let ringColor = game.paused ? ringOnColor : ringOffColor; - let ringColor = "#000000"; - - let ringOffColor = settings.offRing; - if (ringOffColor == undefined) ringOffColor = '#000000'; - - let ringOnColor = settings.onRing; - if (ringOnColor == undefined) ringOnColor = '#00FF00'; - - let playlistType = settings.playlistType; - if (playlistType == undefined) playlistType = 0; - - if (pauseFunction == 'pause'){ //Pause game - if (game.paused) ringColor = ringOnColor; - else ringColor = ringOffColor; + if (pauseFunction == 'pause') //Pause game src = 'modules/MaterialDeck/img/other/pause/pause.png'; - //src = 'action/images/other/pause/pause.png'; - } else if (pauseFunction == 'resume'){ //Resume game - if (game.paused == false) ringColor = ringOnColor; - else ringColor = ringOffColor; + ringColor = game.paused ? ringOffColor : ringOnColor; src = 'modules/MaterialDeck/img/other/pause/resume.png'; - //src = 'action/images/other/pause/resume.png'; } - else if (pauseFunction == 'toggle') { //toggle - if (game.paused == false) ringColor = ringOnColor; - else ringColor = ringOffColor; + else if (pauseFunction == 'toggle') //toggle src = 'modules/MaterialDeck/img/other/pause/playpause.png'; - //src = 'action/images/other/pause/playpause.png'; - } streamDeck.setIcon(context,src,background,2,ringColor,true); } - keyPressPause(pauseFunction){ - if (pauseFunction == undefined) pauseFunction = 'pause'; + keyPressPause(settings){ + const pauseFunction = settings.pauseFunction ? settings.pauseFunction : 'pause'; + if (pauseFunction == 'pause'){ //Pause game if (game.paused) return; game.togglePause(); @@ -133,122 +100,13 @@ export class OtherControls{ } } - ////////////////////////////////////////////////////////////////////////////////////////////////// - - updateScene(settings,context){ - - if (canvas.scene == null) return; - let func = settings.sceneFunction; - if (func == undefined) func = 'visible'; - - let background = settings.background; - if(background == undefined) background = '#000000'; - - let ringColor = "#000000"; - - let ringOffColor = settings.offRing; - if (ringOffColor == undefined) ringOffColor = '#000000'; - - let ringOnColor = settings.onRing; - if (ringOnColor == undefined) ringOnColor = '#00FF00'; - - let src = ""; - let name = ""; - if (func == 'visible'){ //visible scenes - let nr = parseInt(settings.sceneNr); - if (isNaN(nr)) nr = 1; - nr--; - - let scene = game.scenes.apps[0].scenes[nr]; - - if (scene != undefined){ - if (scene.isView) - ringColor = ringOnColor; - else - ringColor = ringOffColor; - if (settings.displaySceneName) name = scene.name; - if (settings.displaySceneIcon) src = scene.img; - if (scene.active) name += "\n(Active)"; - } - } - else if (func == 'any') { //all scenes - if (settings.sceneName == undefined || settings.sceneName == '') return; - let scene = game.scenes.apps[1].entities.find(p=>p.data.name == settings.sceneName); - if (scene != undefined){ - if (scene.isView) - ringColor = ringOnColor; - else - ringColor = ringOffColor; - if (settings.displaySceneName) name = scene.name; - if (settings.displaySceneIcon) src = scene.img; - if (scene.active) name += "\n(Active)"; - } - } - streamDeck.setTitle(name,context); - streamDeck.setIcon(context,src,background,2,ringColor); - } - - keyPressScene(settings){ - let func = settings.sceneFunction; - if (func == undefined) func = 'visible'; - if (func == 'visible'){ //visible scenes - let viewFunc = settings.sceneViewFunction; - if (viewFunc == undefined) viewFunc = 'view'; - - let nr = parseInt(settings.sceneNr); - if (isNaN(nr)) nr = 1; - nr--; - let scene = game.scenes.apps[0].scenes[nr]; - - if (scene != undefined){ - if (viewFunc == 'view'){ - scene.view(); - } - else if (viewFunc == 'activate'){ - scene.activate(); - } - else { - if (scene.isView) scene.activate(); - scene.view(); - } - } - } - else if (func == 'any'){ //any scene - if (settings.sceneName == undefined || settings.sceneName == '') return; - const scenes = game.scenes.entries; - let scene = game.scenes.apps[1].entities.find(p=>p.data.name == settings.sceneName); - if (scene == undefined) return; - - let viewFunc = settings.sceneViewFunction; - if (viewFunc == undefined) viewFunc = 'view'; - - if (viewFunc == 'view'){ - scene.view(); - } - else if (viewFunc == 'activate'){ - scene.activate(); - } - else { - if (scene.isView) scene.activate(); - scene.view(); - } - } - } - ////////////////////////////////////////////////////////////////////////////////////////// updateControl(settings,context){ - let control = settings.control; - if (control == undefined) control = 'dispControls'; - - let tool = settings.tool; - if (tool == undefined) tool = 'open'; - - let background = settings.background; - if (background == undefined) background = '#000000'; - + const control = settings.control ? settings.control : 'dispControls'; + const tool = settings.tool ? settings.tool : 'open'; + let background = settings.background ? settings.background : '#000000'; let ringColor = '#000000' - let txt = ""; let src = ""; const activeControl = ui.controls.activeControl; @@ -282,10 +140,7 @@ export class OtherControls{ src = selectedTool.icon; if (selectedTool.toggle){ background = "#340057" - if (selectedTool.active) - ringColor = "#A600FF" - else - ringColor = "#340057"; + ringColor = selectedTool.active ? "#A600FF" : "#340057"; } else if (activeTool == selectedTool.name) ringColor = "#FF7B00"; @@ -307,11 +162,8 @@ export class OtherControls{ txt = game.i18n.localize(selectedTool.title); src = selectedTool.icon; if (selectedTool.toggle){ - background = "#340057" - if (selectedTool.active) - ringColor = "#A600FF" - else - ringColor = "#340057" + background = "#340057"; + ringColor = selectedTool.active ? "#A600FF" : "#340057"; } else if (activeTool == selectedTool.name && activeControl == selectedControl.name) ringColor = "#FF7B00"; @@ -325,11 +177,8 @@ export class OtherControls{ keyPressControl(settings){ if (canvas.scene == null) return; - let control = settings.control; - if (control == undefined) control = 'dispControls'; - - let tool = settings.tool; - if (tool == undefined) tool = 'open'; + const control = settings.control ? settings.control : 'dispControls'; + const tool = settings.tool ? settings.tool : 'open'; if (control == 'dispControls'){ //displayed controls let controlNr = parseInt(settings.controlNr); @@ -394,14 +243,9 @@ export class OtherControls{ ////////////////////////////////////////////////////////////////////////////////////////// updateDarkness(settings,context){ - let func = settings.darknessFunction; - if (func == undefined) func = 'value'; - - let value = settings.darknessValue; - if (value == undefined) value = 0; - - let background = settings.background; - if (background == undefined) background = "#000000"; + const func = settings.darknessFunction ? settings.darknessFunction : 'value'; + const value = parseFloat(settings.darknessValue) ? parseFloat(settings.darknessValue) : 0; + const background = settings.background ? settings.background : '#000000'; let src = ""; let txt = ""; @@ -415,8 +259,7 @@ export class OtherControls{ } else if (func == 'disp'){ //display darkness src = 'modules/MaterialDeck/img/other/darkness/darkness.png'; - let darkness = ''; - if (canvas.scene != null) darkness = Math.floor(canvas.scene.data.darkness*100)/100; + const darkness = canvas.scene != null ? Math.floor(canvas.scene.data.darkness*100)/100 : ''; txt += darkness; } streamDeck.setTitle(txt,context); @@ -425,17 +268,13 @@ export class OtherControls{ keyPressDarkness(settings) { if (canvas.scene == null) return; - let func = settings.darknessFunction; - if (func == undefined) func = 'value'; - - let value = parseFloat(settings.darknessValue); - if (value == undefined) value = 0; + const func = settings.darknessFunction ? settings.darknessFunction : 'value'; + const value = parseFloat(settings.darknessValue) ? parseFloat(settings.darknessValue) : 0; if (func == 'value') //value canvas.scene.update({darkness: value}); else if (func == 'incDec'){ //increase/decrease - let darkness = canvas.scene.data.darkness; - darkness += -1*value; + let darkness = canvas.scene.data.darkness - value; if (darkness > 1) darkness = 1; if (darkness < 0) darkness = 0; canvas.scene.update({darkness: darkness}); @@ -444,37 +283,77 @@ export class OtherControls{ ////////////////////////////////////////////////////////////////////////////////////////// + updateRollDice(settings,context){ + const background = settings.background ? settings.background : '#000000'; + let txt = ''; + + if (settings.displayDiceName) txt = 'Roll: ' + settings.rollDiceFormula; + + streamDeck.setTitle(txt,context); + streamDeck.setIcon(context,'',background); + } + + keyPressRollDice(settings,context){ + if (settings.rollDiceFormula == undefined || settings.rollDiceFormula == '') return; + const rollFunction = settings.rollDiceFunction ? settings.rollDiceFunction : 'public'; + + let actor; + let tokenControlled = false; + + if (MODULE.selectedTokenId != undefined) actor = canvas.tokens.children[0].children.find(p => p.id == MODULE.selectedTokenId).actor; + if (actor != undefined) tokenControlled = true; + + let r; + if (tokenControlled) r = new Roll(settings.rollDiceFormula,actor.getRollData()); + else r = new Roll(settings.rollDiceFormula); + + r.evaluate(); + + if (rollFunction == 'public') { + r.toMessage(r,{rollMode:"roll"}) + } + else if (rollFunction == 'private') { + r.toMessage(r,{rollMode:"selfroll"}) + } + else if (rollFunction == 'sd'){ + let txt = settings.displayDiceName ? 'Roll: '+settings.rollDiceFormula + '\nResult: ' : ''; + txt += r.total; + streamDeck.setTitle(txt,context); + let data = this.rollData + data[context] = { + formula: settings.rollDiceFormula, + result: txt + } + this.rollData = data; + } + } + + ////////////////////////////////////////////////////////////////////////////////////////// + updateRollTable(settings,context){ - let name = settings.rollTableName; + const name = settings.rollTableName; if (name == undefined) return; - let background = settings.background; - if (background == undefined) background = "#000000"; + const background = settings.background ? settings.background : '#000000'; + const table = game.tables.entities.find(p=>p.name == name); + let txt = settings.displayRollName ? table.name : ''; + let src = settings.displayRollIcon ? table.data.img : ''; - let table = game.tables.entities.find(p=>p.name == name); - - let txt = ""; - let src = ""; - - if (table != undefined) { - if (settings.displayRollIcon) src = table.data.img; - if (settings.displayRollName) txt = table.name; + if (table == undefined) { + src = ''; + txt = ''; } + streamDeck.setTitle(txt,context); streamDeck.setIcon(context,src,background); } keyPressRollTable(settings){ - let func = settings.rolltableFunction; - if (func == undefined) func = 'open'; - - let name = settings.rollTableName; + const name = settings.rollTableName; if (name == undefined) return; - let background = settings.background; - if (background == undefined) background = "#000000"; - - let table = game.tables.entities.find(p=>p.name == name); + const func = settings.rolltableFunction ? settings.rolltableFunction : 'open'; + const table = game.tables.entities.find(p=>p.name == name); if (table != undefined) { if (func == 'open'){ //open @@ -524,43 +403,24 @@ export class OtherControls{ } updateSidebar(settings,context){ - let sidebarTab = settings.sidebarTab; - if (sidebarTab == undefined) sidebarTab = 'chat'; + const sidebarTab = settings.sidebarTab ? settings.sidebarTab : 'chat'; + const background = settings.background ? settings.background : '#000000'; + const collapsed = ui.sidebar._collapsed; + const ringOffColor = settings.offRing ? settings.offRing : '#000000'; + const ringOnColor = settings.onRing ? settings.onRing : '#00FF00'; + const ringColor = (sidebarTab == 'collapse' && collapsed) ? ringOnColor : ringOffColor; + const name = settings.displaySidebarName ? this.getSidebarName(sidebarTab) : ''; + const icon = settings.displaySidebarIcon ? this.getSidebarIcon(sidebarTab) : ''; - let activeTab = ui.sidebar.activeTab; - let collapsed = ui.sidebar._collapsed; - - let name = ""; - let icon = ""; - - let background = settings.background; - if(background == undefined) background = '#000000'; - - let ringColor = "#000000"; - - let ringOffColor = settings.offRing; - if (ringOffColor == undefined) ringOffColor = '#000000'; - - let ringOnColor = settings.onRing; - if (ringOnColor == undefined) ringOnColor = '#00FF00'; - - if (settings.displaySidebarName) name = this.getSidebarName(sidebarTab); - if (settings.displaySidebarIcon) icon = this.getSidebarIcon(sidebarTab); - - if ((sidebarTab == 'collapse' && collapsed)) - ringColor = ringOnColor; - else - ringColor = ringOffColor; streamDeck.setTitle(name,context); streamDeck.setIcon(context,icon,background,2,ringColor); } keyPressSidebar(settings){ - let sidebarTab = settings.sidebarTab; - if (sidebarTab == undefined) sidebarTab = 'chat'; - let collapsed = ui.sidebar._collapsed; - + const sidebarTab = settings.sidebarTab ? settings.sidebarTab : 'chat'; + if (sidebarTab == 'collapse'){ + const collapsed = ui.sidebar._collapsed; if (collapsed) ui.sidebar.expand(); else if (collapsed == false) ui.sidebar.collapse(); } @@ -570,27 +430,19 @@ export class OtherControls{ ////////////////////////////////////////////////////////////////////////////////////////// updateCompendium(settings,context){ - let background = settings.background; - if(background == undefined) background = '#000000'; - - let name = settings.compendiumName; + const name = settings.compendiumName; if (name == undefined) return; const compendium = game.packs.entries.find(p=>p.metadata.label == name); if (compendium == undefined) return; - let ringColor = "#000000"; + const background = settings.background ? settings.background : '#000000'; + const ringOffColor = settings.offRing ? settings.offRing : '#000000'; + const ringOnColor = settings.onRing ? settings.onRing : '#00FF00'; + const ringColor = compendium.rendered ? ringOnColor : ringOffColor; + const txt = settings.displayCompendiumName ? name : ''; - let ringOffColor = settings.offRing; - if (ringOffColor == undefined) ringOffColor = '#000000'; - - let ringOnColor = settings.onRing; - if (ringOnColor == undefined) ringOnColor = '#00FF00'; - - if (compendium.rendered) ringColor = ringOnColor; - else ringColor = ringOffColor; - - if (settings.displayCompendiumName) streamDeck.setTitle(name,context); + streamDeck.setTitle(txt,context); streamDeck.setIcon(context,"",background,2,ringColor); } @@ -610,37 +462,50 @@ export class OtherControls{ //game.journal.entries[0].render(true) updateJournal(settings,context){ - let background = settings.background; - if(background == undefined) background = '#000000'; - - let name = settings.compendiumName; + const name = settings.compendiumName; if (name == undefined) return; + const journal = game.journal.entries.find(p=>p.name == name); if (journal == undefined) return; - let ringColor = "#000000"; + const background = settings.background ? settings.background : '#000000'; + const ringOffColor = settings.offRing ? settings.offRing : '#000000'; + const ringOnColor = settings.onRing ? settings.onRing : '#00FF00'; + const ringColor = journal.sheet.rendered ? ringOnColor : ringOffColor; + const txt = settings.displayCompendiumName ? name : ''; - let ringOffColor = settings.offRing; - if (ringOffColor == undefined) ringOffColor = '#000000'; - - let ringOnColor = settings.onRing; - if (ringOnColor == undefined) ringOnColor = '#00FF00'; - - if (journal.sheet.rendered) ringColor = ringOnColor; - else ringColor = ringOffColor; - - if (settings.displayCompendiumName) streamDeck.setTitle(name,context); + streamDeck.setTitle(txt,context); streamDeck.setIcon(context,"",background,2,ringColor); } keyPressJournal(settings){ - let name = settings.compendiumName; + const name = settings.compendiumName; if (name == undefined) return; const journal = game.journal.entries.find(p=>p.name == name); if (journal == undefined) return; + const element = document.getElementById("journal-"+journal.id); if (element == null) journal.render(true); else journal.sheet.close(); } + +////////////////////////////////////////////////////////////////////////////////////////// + + updateChatMessage(settings,context){ + const background = settings.background ? settings.background : '#000000'; + streamDeck.setTitle("",context); + streamDeck.setIcon(context,"",background); + } + + keyPressChatMessage(settings){ + const message = settings.chatMessage ? settings.chatMessage : ''; + + let chatData = { + user: game.user._id, + speaker: ChatMessage.getSpeaker(), + content: message + }; + ChatMessage.create(chatData, {}); + } } \ No newline at end of file diff --git a/src/scene.js b/src/scene.js new file mode 100644 index 0000000..e5de05c --- /dev/null +++ b/src/scene.js @@ -0,0 +1,196 @@ +import * as MODULE from "../MaterialDeck.js"; +import {streamDeck} from "../MaterialDeck.js"; + +export class SceneControl{ + constructor(){ + this.active = false; + this.rollData = {}; + this.sceneOffset = 0; + } + + async updateAll(){ + if (this.active == false) return; + for (let i=0; i<32; i++){ + let data = streamDeck.buttonContext[i]; + if (data == undefined || data.action != 'scene') continue; + await this.update(data.settings,data.context); + } + } + + update(settings,context){ + if (canvas.scene == null) return; + this.active = true; + const func = settings.sceneFunction ? settings.sceneFunction : 'visible'; + const background = settings.background ? settings.background : '#000000'; + const ringOffColor = settings.offRing ? settings.offRing : '#000000'; + const ringOnColor = settings.onRing ? settings.onRing : '#00FF00'; + let ringColor = "#000000"; + let ring = 2; + + let src = ""; + let name = ""; + if (func == 'visible'){ //visible scenes + let nr = parseInt(settings.sceneNr); + if (isNaN(nr) || nr < 1) nr = 1; + nr--; + + let scene = game.scenes.apps[0].scenes[nr]; + + if (scene != undefined){ + if (scene.isView) + ringColor = ringOnColor; + else + ringColor = ringOffColor; + if (settings.displaySceneName) name = scene.name; + if (settings.displaySceneIcon) src = scene.img; + if (scene.active) name += "\n(Active)"; + } + } + else if (func == 'dir') { //from directory + let nr = parseInt(settings.sceneNr); + if (isNaN(nr) || nr < 1) nr = 1; + nr--; + + let sceneList = []; + for (let i=0; ip.data.name == settings.sceneName); + if (scene != undefined){ + if (scene.isView) + ringColor = ringOnColor; + else + ringColor = ringOffColor; + if (settings.displaySceneName) name = scene.name; + if (settings.displaySceneIcon) src = scene.img; + if (scene.active) name += "\n(Active)"; + } + } + else if (func == 'active'){ + const scene = game.scenes.active; + if (scene == undefined) return; + if (settings.displaySceneName) name = scene.name; + if (settings.displaySceneIcon) src = scene.img; + ring = 0; + } + else if (func == 'offset'){ + let offset = parseInt(settings.sceneOffset); + if (isNaN(offset)) offset = 0; + if (offset == this.sceneOffset) ringColor = ringOnColor; + else ringColor = ringOffColor; + } + streamDeck.setTitle(name,context); + streamDeck.setIcon(context,src,background,ring,ringColor); + } + + keyPress(settings){ + const func = settings.sceneFunction ? settings.sceneFunction : 'visible'; + + if (func == 'visible'){ //visible scenes + const viewFunc = settings.sceneViewFunction ? settings.sceneViewFunction : 'view'; + let nr = parseInt(settings.sceneNr); + if (isNaN(nr) || nr < 1) nr = 1; + nr--; + let scene = game.scenes.apps[0].scenes[nr]; + + if (scene != undefined){ + if (viewFunc == 'view'){ + scene.view(); + } + else if (viewFunc == 'activate'){ + scene.activate(); + } + else { + if (scene.isView) scene.activate(); + scene.view(); + } + } + } + else if (func == 'dir') { //from directory + const viewFunc = settings.sceneViewFunction ? settings.sceneViewFunction : 'view'; + let nr = parseInt(settings.sceneNr); + if (isNaN(nr) || nr < 1) nr = 1; + nr--; + + let sceneList = []; + for (let i=0; ip.data.name == settings.sceneName); + if (scene == undefined) return; + + let viewFunc = settings.sceneViewFunction; + if (viewFunc == undefined) viewFunc = 'view'; + + if (viewFunc == 'view'){ + scene.view(); + } + else if (viewFunc == 'activate'){ + scene.activate(); + } + else { + if (scene.isView) scene.activate(); + scene.view(); + } + } + else if (func == 'active'){ + const scene = game.scenes.active; + if (scene == undefined) return; + scene.view(); + } + else if (func == 'offset'){ + let offset = parseInt(settings.sceneOffset); + if (isNaN(offset)) offset = 0; + this.sceneOffset = offset; + this.updateAll(); + } + } +} \ No newline at end of file diff --git a/src/settings.js b/src/settings.js index 9d4d78b..802f506 100644 --- a/src/settings.js +++ b/src/settings.js @@ -39,6 +39,17 @@ export const registerSettings = function() { onChange: x => window.location.reload() }); + game.settings.register(MODULE.moduleName, 'imageBuffer', { + name: "MaterialDeck.Sett.ImageBuffer", + hint: "MaterialDeck.Sett.ImageBufferHint", + default: 0, + type: Number, + scope: 'world', + range: { min: 0, max: 500, step: 10 }, + config: true + + }); + /** * Playlist soundboard */ diff --git a/src/streamDeck.js b/src/streamDeck.js index f083959..be1a0a1 100644 --- a/src/streamDeck.js +++ b/src/streamDeck.js @@ -25,6 +25,11 @@ export class StreamDeck{ document.body.appendChild(canvasBox); // adds the canvas to the body element this.syllableRegex = /[^aeiouy]*[aeiouy]+(?:[^aeiouy]*$|[^aeiouy](?=[^aeiouy]))?/gi; + + + this.imageBuffer = []; + this.imageBufferCounter = 0; + } setScreen(action){ @@ -52,6 +57,7 @@ export class StreamDeck{ else if (action == 'soundboard') MODULE.soundboard.active = false; else if (action == 'other') MODULE.otherControls.active = false; else if (action == 'external') MODULE.externalModules.active = false; + else if (action == 'scene') MODULE.sceneControl.active = false; } } @@ -171,14 +177,30 @@ export class StreamDeck{ MODULE.sendWS(JSON.stringify(msg)); } - setImage(image,context){ + setImage(image,context,nr,id){ var json = { target: "SD", event: "setImage", context: context, payload: { - image: "" + image, - target: 0 + nr: nr, + id: id, + image: "" + image, + target: 0 + } + }; + MODULE.sendWS(JSON.stringify(json)); + } + + setBufferImage(context,nr,id){ + var json = { + target: "SD", + event: "setBufferImage", + context: context, + payload: { + nr: nr, + id: id, + target: 0 } }; MODULE.sendWS(JSON.stringify(json)); @@ -198,6 +220,18 @@ export class StreamDeck{ this.buttonContext[i].background = background; } } + const data = { + url: src, + background:background, + ring:ring, + ringColor:ringColor, + overlay:overlay + } + const imgBuffer = this.checkImageBuffer(data); + if (imgBuffer != false) { + this.setBufferImage(context,imgBuffer,this.getImageBufferId(data)) + return; + } let split = src.split('.'); //filter out stuff from Tokenizer @@ -215,7 +249,7 @@ export class StreamDeck{ ringColor: ringColor, overlay: overlay }; - this.getImage(msg); + this.getImage(msg); } setState(state,context,action){ @@ -265,6 +299,7 @@ export class StreamDeck{ getImage(data){ if (data == undefined) return; + const context = data.context; var url = data.url; const format = data.format; @@ -367,8 +402,46 @@ export class StreamDeck{ ctx.drawImage(img, xStart+margin, yStart+margin, renderableWidth - 2*margin, renderableHeight - 2*margin); var dataURL = canvas.toDataURL(); canvas.remove(); - this.setImage(dataURL,data.context); + const nr = this.addToImageBuffer(dataURL,data); + this.setImage(dataURL,data.context,nr,this.getImageBufferId(data)); }; img.src = resImageURL; } + + getImageBufferId(data){ + return data.url+data.background+data.ring+data.ringColor+data.overlay; + } + + addToImageBuffer(img,data){ + const id = this.getImageBufferId(data); + const maxBufferSize = game.settings.get(MODULE.moduleName,'imageBuffer'); + if (maxBufferSize == 0) return false; + if (this.imageBufferCounter > maxBufferSize) this.imageBufferCounter = 0; + + const newData = { + id: id, + img: img + } + + if (this.imageBuffer[this.imageBufferCounter] == undefined) this.imageBuffer.push(newData); + else this.imageBuffer[this.imageBufferCounter] = newData; + this.imageBufferCounter++; + + return this.imageBufferCounter - 1; + } + + checkImageBuffer(data){ + if (game.settings.get(MODULE.moduleName,'imageBuffer') == 0) return false; + const id = this.getImageBufferId(data); + + for (let i=0; i p.id == tokenId).actor; - if (system == 'dnd5e' && game.system.id == 'dnd5e'){ + if (stats == 'custom'){ + const custom = settings.custom ? settings.custom : ''; + let split = custom.split('['); + for (let i=0; i p.id == tokenId); + if (token == undefined) return; + let tokenData = token.data; + + const dimVision = parseInt(settings.dimVision); + const brightVision = parseInt(settings.brightVision); + const sightAngle = parseInt(settings.sightAngle); + const dimRadius = parseInt(settings.dimRadius); + const brightRadius = parseInt(settings.brightRadius); + const emissionAngle = parseInt(settings.emissionAngle); + const lightColor = settings.lightColor ? settings.lightColor : '#000000'; + const colorIntensity = isNaN(parseInt(settings.colorIntensity)) ? 0 : parseInt(settings.colorIntensity)/100; + const animationType = settings.animationType ? settings.animationType : 'none'; + const animationSpeed = isNaN(parseInt(settings.animationSpeed)) ? 1 : parseInt(settings.animationSpeed); + const animationIntensity = isNaN(parseInt(settings.animationIntensity)) ? 1 : parseInt(settings.animationIntensity); + + let data = {}; + if (isNaN(dimVision)==false) data.dimSight = dimVision; + if (isNaN(brightVision)==false) data.brightSight = brightVision; + if (isNaN(sightAngle)==false) data.sightAngle = sightAngle; + if (isNaN(dimRadius)==false) data.dimLight = dimRadius; + if (isNaN(brightRadius)==false) data.brightLight = brightRadius; + if (isNaN(emissionAngle)==false) data.lightAngle = emissionAngle; + data.lightColor = lightColor; + data.lightAlpha = Math.sqrt(colorIntensity).toNearest(0.05) + let animation = { + type: '', + speed: tokenData.lightAnimation.speed, + intensity: tokenData.lightAnimation.intensity + }; + if (animationType != 'none'){ + animation.type = animationType; + animation.intensity = animationIntensity; + animation.speed = animationSpeed; + } + data.lightAnimation = animation; + + token.update(data); + } else if (system == 'demonlord' && game.system.id == 'demonlord' && onClick == 'initiative'){ token.actor.update({ 'data.fastturn': !token.actor.data?.data?.fastturn