This commit is contained in:
CDeenen
2021-02-04 05:03:34 +01:00
parent f0c1b0e1e0
commit f994e64fc7
17 changed files with 279 additions and 344 deletions

View File

@@ -40,6 +40,8 @@ let wsOpen = false; //Bool for checking if websocket has ever been o
let wsInterval; //Interval timer to detect disconnections let wsInterval; //Interval timer to detect disconnections
let WSconnected = false; let WSconnected = false;
//let furnace = game.modules.get("furnace");
/* /*
* Analyzes the message received * Analyzes the message received
* *
@@ -51,6 +53,17 @@ async function analyzeWSmessage(msg){
//console.log("Received",data); //console.log("Received",data);
if (data.type == "connected" && data.data == "SD"){ if (data.type == "connected" && data.data == "SD"){
/*
console.log(data);
const minimumSDversion = game.modules.get("MaterialDeck").data.minimumSDversion.replace('v','');
const minimumMSversion = game.modules.get("MaterialDeck").data.minimumMSversion;
console.log('SD',minimumSDversion,minimumMSversion)
if (data.SDversion < minimumSDversion) console.log('SD: nope')
else console.log('SD: yes');
if (data.MSversion < minimumMSversion) console.log('MS: nope')
else console.log('MS: yes');
*/
console.log("streamdeck connected to server"); console.log("streamdeck connected to server");
streamDeck.resetImageBuffer(); streamDeck.resetImageBuffer();
} }
@@ -133,7 +146,10 @@ async function analyzeWSmessage(msg){
*/ */
function startWebsocket() { function startWebsocket() {
const address = game.settings.get(moduleName,'address'); const address = game.settings.get(moduleName,'address');
ws = new WebSocket('ws://'+address+'/');
const url = address.startsWith('wss://') ? address : ('ws://'+address+'/');
ws = new WebSocket(url);
ws.onmessage = function(msg){ ws.onmessage = function(msg){
//console.log(msg); //console.log(msg);

View File

@@ -1,5 +1,19 @@
# Changelog Material Deck Module # Changelog Material Deck Module
### v1.2.2 - 07-01-2021 ### v1.2.3 - 03-02-2021
Fixes:
<ul>
<li>Fixed some issues for the Shadow of the Demon Lord system</li>
</ul>
Other Changes:
<ul>
<li>Improved performance of the 'Playlist Configuration', 'Macro Configuration' and 'Soundboard Configuration' screens</li>
<li>Minor code clean-up</li>
</ul>
<b>Compatible server app and SD plugin:</b><br>
Material Server v1.0.2 (unchanged): https://github.com/CDeenen/MaterialServer/releases <br>
SD plugin v1.2.2 (unchanged): https://github.com/CDeenen/MaterialDeck_SD/releases<br>
### v1.2.2 - 02-02-2021
Additions: Additions:
<ul> <ul>
<li>Added a help button in the module configuration</li> <li>Added a help button in the module configuration</li>

View File

@@ -2,7 +2,9 @@
"name": "MaterialDeck", "name": "MaterialDeck",
"title": "Material Deck", "title": "Material Deck",
"description": "Material Deck allows you to control Foundry using an Elgato Stream Deck", "description": "Material Deck allows you to control Foundry using an Elgato Stream Deck",
"version": "1.2.2", "version": "1.2.3",
"minimumSDversion": "1.2.2",
"minimumMSversion": "1.0.2",
"author": "CDeenen", "author": "CDeenen",
"esmodules": [ "esmodules": [
"./MaterialDeck.js" "./MaterialDeck.js"

View File

@@ -10,7 +10,7 @@ export class CombatTracker{
async updateAll(){ async updateAll(){
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'combattracker') continue; if (data == undefined || data.action != 'combattracker') continue;
await this.update(data.settings,data.context); await this.update(data.settings,data.context);
} }

View File

@@ -13,7 +13,7 @@ export class ExternalModules{
} }
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'external') continue; if (data == undefined || data.action != 'external') continue;
await this.update(data.settings,data.context); await this.update(data.settings,data.context);
} }
@@ -21,18 +21,15 @@ export class ExternalModules{
update(settings,context){ update(settings,context){
this.active = true; this.active = true;
let module = settings.module; const module = settings.module ? settings.module : 'fxmaster';
if (module == undefined) module = 'fxmaster';
if (module == 'fxmaster') this.updateFxMaster(settings,context); if (module == 'fxmaster') this.updateFxMaster(settings,context);
else if (module == 'gmscreen') this.updateGMScreen(settings,context); else if (module == 'gmscreen') this.updateGMScreen(settings,context);
} }
keyPress(settings,context){ keyPress(settings,context){
if (this.active == false) return; if (this.active == false) return;
let module = settings.module; const module = settings.module ? settings.module : 'fxmaster';
if (module == undefined) module = 'fxmaster';
if (module == 'fxmaster') if (module == 'fxmaster')
this.keyPressFxMaster(settings,context); this.keyPressFxMaster(settings,context);
@@ -254,7 +251,7 @@ export class ExternalModules{
const background = settings.gmScreenBackground ? settings.gmScreenBackground : '#000000'; const background = settings.gmScreenBackground ? settings.gmScreenBackground : '#000000';
let ring = 1; let ring = 1;
let ringColor = '#00FF00' const ringColor = '#00FF00'
let src = ''; let src = '';
let txt = ''; let txt = '';

View File

@@ -10,7 +10,7 @@ export class MacroControl{
async updateAll(){ async updateAll(){
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'macro') continue; if (data == undefined || data.action != 'macro') continue;
await this.update(data.settings,data.context); await this.update(data.settings,data.context);
} }
@@ -18,39 +18,28 @@ export class MacroControl{
update(settings,context){ update(settings,context){
this.active = true; this.active = true;
let mode = settings.macroMode; const mode = settings.macroMode ? settings.macroMode : 'hotbar';
let displayName = settings.displayName; const displayName = settings.displayName ? settings.displayName : false;
const displayIcon = settings.displayIcon ? settings.displayIcon : false;
let background = settings.background ? settings.background : '#000000';
let macroNumber = settings.macroNumber; let macroNumber = settings.macroNumber;
let background = settings.background; if (macroNumber == undefined || isNaN(parseInt(macroNumber))) macroNumber = 0;
let icon = false; macroNumber = parseInt(macroNumber);
if (settings.displayIcon) icon = true;
let ringColor = "#000000"; let ringColor = "#000000";
let ring = 0; let ring = 0;
if(macroNumber == undefined || isNaN(parseInt(macroNumber))){ let name = "";
macroNumber = 0; let src = "";
}
if (mode == undefined) mode = 'hotbar';
if (displayName == undefined) displayName = false;
if (background == undefined) background = '#000000';
macroNumber = parseInt(macroNumber);
if (mode == 'macroBoard') { //Macro board if (mode == 'macroBoard') { //Macro board
let name = "";
let src = '';
if (settings.macroBoardMode == 'offset') { //Offset if (settings.macroBoardMode == 'offset') { //Offset
let ringOffColor = settings.offRing; const ringOffColor = settings.offRing ? settings.offRing : '#000000';
if (ringOffColor == undefined) ringOffColor = '#000000'; const ringOnColor = settings.onRing ? settings.onRing : '#00FF00';
let ringOnColor = settings.onRing;
if (ringOnColor == undefined) ringOnColor = '#00FF00';
let macroOffset = parseInt(settings.macroOffset); let macroOffset = parseInt(settings.macroOffset);
if (macroOffset == undefined || isNaN(macroOffset)) macroOffset = 0; if (macroOffset == undefined || isNaN(macroOffset)) macroOffset = 0;
if (macroOffset == parseInt(this.offset)) ringColor = ringOnColor; ringColor = (macroOffset == parseInt(this.offset)) ? ringOnColor : ringOffColor;
else ringColor = ringOffColor;
ring = 2; ring = 2;
} }
else { //Execute macro else { //Execute macro
@@ -58,38 +47,32 @@ export class MacroControl{
if (macroNumber < 0) macroNumber = 0; if (macroNumber < 0) macroNumber = 0;
var macroId = game.settings.get(MODULE.moduleName,'macroSettings').macros[macroNumber]; var macroId = game.settings.get(MODULE.moduleName,'macroSettings').macros[macroNumber];
background = game.settings.get(MODULE.moduleName,'macroSettings').color[macroNumber]; background = game.settings.get(MODULE.moduleName,'macroSettings').color[macroNumber];
if (background == undefined) background = '#000000'; if (background == undefined) background = '#000000';
src = ""; src = "";
if (macroId != undefined){ if (macroId != undefined){
let macro = game.macros._source.find(p => p._id == macroId); let macro = game.macros._source.find(p => p._id == macroId);
if (macro != undefined) { if (macro != undefined) {
name += macro.name; if (displayName) name += macro.name;
src += macro.img; if (displayIcon) src += macro.img;
} }
} }
ring = 0; ring = 0;
} }
if (icon) streamDeck.setIcon(context,src,background,ring,ringColor);
else streamDeck.setIcon(context, "", background,ring,ringColor);
if (displayName == 0) name = "";
streamDeck.setTitle(name,context);
} }
else { //Macro Hotbar else { //Macro Hotbar
let macroId let macroId
if (mode == 'hotbar') macroId = game.user.data.hotbar[macroNumber]; if (mode == 'hotbar') macroId = game.user.data.hotbar[macroNumber];
else { else {
let macros; let macros;
if (mode == 'customHotbar' && game.modules.get('custom-hotbar') != undefined) { if (mode == 'customHotbar' && game.modules.get('custom-hotbar') != undefined)
macros = ui.customHotbar.macros; macros = ui.customHotbar.macros;
} else
else macros = game.macros.apps[0].macros; macros = game.macros.apps[0].macros;
if (macroNumber > 9) macroNumber = 0; if (macroNumber > 9) macroNumber = 0;
for (let j=0; j<10; j++){ for (let j=0; j<10; j++){
if (macros[j].key == macroNumber){ if (macros[j].key == macroNumber)
if (macros[j].macro == null) macroId == undefined; macroId = (macros[j].macro == null) ? undefined : macros[j].macro._id;
else macroId = macros[j].macro._id;
}
} }
} }
let src = ""; let src = "";
@@ -98,36 +81,32 @@ export class MacroControl{
if (macroId != undefined){ if (macroId != undefined){
let macro = game.macros._source.find(p => p._id == macroId); let macro = game.macros._source.find(p => p._id == macroId);
if (macro != undefined) { if (macro != undefined) {
name += macro.name; if (displayName) name += macro.name;
src += macro.img; if (displayIcon) src += macro.img;
} }
} }
if (icon) streamDeck.setIcon(context,src,background);
else streamDeck.setIcon(context, "", background);
if (displayName == 0) name = "";
streamDeck.setTitle(name,context);
} }
streamDeck.setIcon(context,src,background,ring,ringColor);
streamDeck.setTitle(name,context);
} }
hotbar(macros){ hotbar(macros){
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'macro' || data.settings.macroMode == 'macroBoard') continue; if (data == undefined || data.action != 'macro' || data.settings.macroMode == 'macroBoard') continue;
let context = data.context;
let mode = data.settings.macroMode; const context = data.context;
let displayName = data.settings.displayName; const mode = data.settings.macroMode ? data.settings.macroMode : 'hotbar';
const displayName = data.settings.displayName ? data.settings.displayName : false;
const displayIcon = data.settings.displayIcon ? data.settings.displayIcon : false;
let background = data.settings.background ? data.settings.background : '#000000';
let macroNumber = data.settings.macroNumber; let macroNumber = data.settings.macroNumber;
let background = data.settings.background; if(macroNumber == undefined || isNaN(parseInt(macroNumber))) macroNumber = 1;
let src = ""; let src = "";
let name = ""; let name = "";
if(macroNumber == undefined || isNaN(parseInt(macroNumber))){
macroNumber = 1;
}
if (mode == undefined) mode = 'hotbar';
if (mode == 'Macro Board') continue; if (mode == 'Macro Board') continue;
if (displayName == undefined) displayName = false;
if (background == undefined) background = '#000000';
let macroId; let macroId;
if (mode == 'hotbar'){ if (mode == 'hotbar'){
@@ -145,24 +124,19 @@ export class MacroControl{
let macro = undefined; let macro = undefined;
if (macroId != undefined) macro = game.macros._source.find(p => p._id == macroId); if (macroId != undefined) macro = game.macros._source.find(p => p._id == macroId);
if (macro != undefined && macro != null) { if (macro != undefined && macro != null) {
name += macro.name; if (displayName) name += macro.name;
src += macro.img; if (displayIcon) src += macro.img;
} }
streamDeck.setIcon(context,src,background); streamDeck.setIcon(context,src,background);
if (displayName == 0) name = "";
streamDeck.setTitle(name,context); streamDeck.setTitle(name,context);
} }
} }
keyPress(settings){ keyPress(settings){
let mode = settings.macroMode; const mode = settings.macroMode ? settings.macroMode : 'hotbar';
if (mode == undefined) mode = 'hotbar';
let macroNumber = settings.macroNumber; let macroNumber = settings.macroNumber;
if(macroNumber == undefined || isNaN(parseInt(macroNumber))){ if(macroNumber == undefined || isNaN(parseInt(macroNumber))) macroNumber = 0;
macroNumber = 0;
}
if (mode == 'hotbar' || mode == 'visibleHotbar' || mode == 'customHotbar') if (mode == 'hotbar' || mode == 'visibleHotbar' || mode == 'customHotbar')
this.executeHotbar(macroNumber,mode); this.executeHotbar(macroNumber,mode);
else { else {

View File

@@ -6,7 +6,6 @@ export class playlistConfigForm extends FormApplication {
super(data, options); super(data, options);
this.data = data; this.data = data;
this.playlistNr; this.playlistNr;
this.updatePlaylistNr = false;
} }
/** /**
@@ -26,7 +25,10 @@ export class playlistConfigForm extends FormApplication {
* Provide data to the template * Provide data to the template
*/ */
getData() { getData() {
//Get the playlist settings
let settings = game.settings.get(MODULE.moduleName,'playlists'); let settings = game.settings.get(MODULE.moduleName,'playlists');
//Get values from the settings, and check if they are defined
let selectedPlaylists = settings.selectedPlaylist; let selectedPlaylists = settings.selectedPlaylist;
if (selectedPlaylists == undefined) selectedPlaylists = []; if (selectedPlaylists == undefined) selectedPlaylists = [];
let selectedPlaylistMode = settings.playlistMode; let selectedPlaylistMode = settings.playlistMode;
@@ -36,17 +38,17 @@ export class playlistConfigForm extends FormApplication {
if (numberOfPlaylists == undefined) numberOfPlaylists = 9; if (numberOfPlaylists == undefined) numberOfPlaylists = 9;
let playMode = settings.playMode; let playMode = settings.playMode;
if (playMode == undefined) playMode = 0; if (playMode == undefined) playMode = 0;
//Create array to store all the data for each playlist
let playlistData = []; let playlistData = [];
this.updatePlaylistNr = false;
for (let i=0; i<numberOfPlaylists; i++){ for (let i=0; i<numberOfPlaylists; i++){
if (selectedPlaylists[i] == undefined) selectedPlaylists[i] = 'none'; if (selectedPlaylists[i] == undefined) selectedPlaylists[i] = 'none';
if (selectedPlaylistMode[i] == undefined) selectedPlaylistMode[i] = 0; if (selectedPlaylistMode[i] == undefined) selectedPlaylistMode[i] = 0;
let dataThis = { let dataThis = {
iteration: i+1, iteration: i+1,
playlist: selectedPlaylists[i], playlist: selectedPlaylists[i],
playlistMode: selectedPlaylistMode[i], playlistMode: selectedPlaylistMode[i]
playlists: game.playlists.entities
} }
playlistData.push(dataThis); playlistData.push(dataThis);
} }
@@ -57,7 +59,7 @@ export class playlistConfigForm extends FormApplication {
selectedPlaylist: selectedPlaylists, selectedPlaylist: selectedPlaylists,
playlistMode: selectedPlaylistMode playlistMode: selectedPlaylistMode
} }
return { return {
playlists: game.playlists.entities, playlists: game.playlists.entities,
numberOfPlaylists: numberOfPlaylists, numberOfPlaylists: numberOfPlaylists,
@@ -89,9 +91,8 @@ export class playlistConfigForm extends FormApplication {
numberOfPlaylists.on("change", event => { numberOfPlaylists.on("change", event => {
this.playlistNr = event.target.value; this.playlistNr = event.target.value;
this.updatePlaylistNr = true;
this.data.playlistNumber=event.target.value; this.data.playlistNumber=event.target.value;
this.updateSettings(this.data); this.updateSettings(this.data,true);
}); });
selectedPlaylist.on("change", event => { selectedPlaylist.on("change", event => {
@@ -106,10 +107,11 @@ export class playlistConfigForm extends FormApplication {
this.updateSettings(this.data); this.updateSettings(this.data);
}); });
} }
async updateSettings(settings){
async updateSettings(settings,render){
await game.settings.set(MODULE.moduleName,'playlists', settings); await game.settings.set(MODULE.moduleName,'playlists', settings);
if (MODULE.enableModule) playlistControl.updateAll(); if (MODULE.enableModule) playlistControl.updateAll();
this.render(); if (render) this.render();
} }
} }
@@ -125,16 +127,6 @@ export class macroConfigForm extends FormApplication {
* Default Options for this FormApplication * Default Options for this FormApplication
*/ */
static get defaultOptions() { static get defaultOptions() {
/*
let streamDeckModel = game.settings.get(MODULE.moduleName,'streamDeckModel');
let width;
if (streamDeckModel == 0)
width = 550;
else if (streamDeckModel == 1)
width= 1500;
else
width = 1400;
*/
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
id: "macro-config", id: "macro-config",
title: "Material Deck: "+game.i18n.localize("MaterialDeck.Sett.MacroConfig"), title: "Material Deck: "+game.i18n.localize("MaterialDeck.Sett.MacroConfig"),
@@ -147,19 +139,26 @@ export class macroConfigForm extends FormApplication {
* Provide data to the template * Provide data to the template
*/ */
getData() { getData() {
//Get the settings
var selectedMacros = game.settings.get(MODULE.moduleName,'macroSettings').macros; var selectedMacros = game.settings.get(MODULE.moduleName,'macroSettings').macros;
var color = game.settings.get(MODULE.moduleName,'macroSettings').color; var color = game.settings.get(MODULE.moduleName,'macroSettings').color;
var args = game.settings.get(MODULE.moduleName,'macroSettings').args; var args = game.settings.get(MODULE.moduleName,'macroSettings').args;
//Check if the settings are defined
if (selectedMacros == undefined) selectedMacros = []; if (selectedMacros == undefined) selectedMacros = [];
if (color == undefined) color = []; if (color == undefined) color = [];
if (args == undefined) args = []; if (args == undefined) args = [];
let macroData = [];
let furnaceEnabled = false;
let furnace = game.modules.get("furnace");
if (furnace != undefined && furnace.active) furnaceEnabled = true;
let height = 95;
if (furnaceEnabled) height += 50;
//Check if the Furnace is installed and enabled
let furnaceEnabled = false;
let height = 95;
let furnace = game.modules.get("furnace");
if (furnace != undefined && furnace.active) {
furnaceEnabled = true;
height += 50;
}
//Check what SD model the user is using, and set the number of rows and columns to correspond
let streamDeckModel = game.settings.get(MODULE.moduleName,'streamDeckModel'); let streamDeckModel = game.settings.get(MODULE.moduleName,'streamDeckModel');
let iMax,jMax; let iMax,jMax;
if (streamDeckModel == 0){ if (streamDeckModel == 0){
@@ -176,45 +175,42 @@ export class macroConfigForm extends FormApplication {
} }
let iteration = 0; let iteration = 0;
let macroData = [];
for (let j=0; j<jMax; j++){ for (let j=0; j<jMax; j++){
let macroThis = []; let macroThis = [];
for (let i=0; i<iMax; i++){ for (let i=0; i<iMax; i++){
let colorThis = color[iteration]; let colorData = color[iteration];
if (colorThis != undefined){ if (colorData != undefined){
let colorCorrect = true; let colorCorrect = true;
if (colorThis[0] != '#') colorCorrect = false; if (colorData[0] != '#') colorCorrect = false;
for (let k=0; k<6; k++){ for (let k=0; k<6; k++){
if (parseInt(colorThis[k+1],16)>15) if (parseInt(colorData[k+1],16)>15)
colorCorrect = false; colorCorrect = false;
} }
if (colorCorrect == false) colorThis = '#000000'; if (colorCorrect == false) colorData = '#000000';
} }
else else
colorThis = '#000000'; colorData = '#000000';
let dataThis = { let dataThis = {
iteration: iteration+1, iteration: iteration+1,
macro: selectedMacros[iteration], macro: selectedMacros[iteration],
color: colorThis, color: colorData,
macros:game.macros, args: args[iteration]
args: args[iteration],
furnace: furnaceEnabled
} }
macroThis.push(dataThis); macroThis.push(dataThis);
iteration++; iteration++;
} }
let data = { macroData.push({dataThis: macroThis});
dataThis: macroThis,
};
macroData.push(data);
} }
return { return {
height: height, height: height,
macros: game.macros, macros: game.macros,
selectedMacros: selectedMacros, selectedMacros: selectedMacros,
macroData: macroData, macroData: macroData,
furnace: furnaceEnabled
} }
} }
@@ -258,7 +254,6 @@ export class macroConfigForm extends FormApplication {
async updateSettings(settings){ async updateSettings(settings){
await game.settings.set(MODULE.moduleName,'macroSettings',settings); await game.settings.set(MODULE.moduleName,'macroSettings',settings);
if (MODULE.enableModule) macroControl.updateAll(); if (MODULE.enableModule) macroControl.updateAll();
this.render();
} }
} }
@@ -267,10 +262,7 @@ export class macroConfigForm extends FormApplication {
export class soundboardConfigForm extends FormApplication { export class soundboardConfigForm extends FormApplication {
constructor(data, options) { constructor(data, options) {
super(data, options); super(data, options);
this.data = data;
this.playlists = []; this.playlists = [];
this.updatePlaylist = false;
this.update = false;
this.iMax; this.iMax;
this.jMax; this.jMax;
this.settings = {}; this.settings = {};
@@ -280,16 +272,6 @@ export class soundboardConfigForm extends FormApplication {
* Default Options for this FormApplication * Default Options for this FormApplication
*/ */
static get defaultOptions() { static get defaultOptions() {
/*
let streamDeckModel = game.settings.get(MODULE.moduleName,'streamDeckModel');
let width;
if (streamDeckModel == 0)
width = 550;
else if (streamDeckModel == 1)
width= 885;
else
width = 1400;
*/
return mergeObject(super.defaultOptions, { return mergeObject(super.defaultOptions, {
id: "soundboard-config", id: "soundboard-config",
title: "Material Deck: "+game.i18n.localize("MaterialDeck.Sett.SoundboardConfig"), title: "Material Deck: "+game.i18n.localize("MaterialDeck.Sett.SoundboardConfig"),
@@ -298,28 +280,15 @@ export class soundboardConfigForm extends FormApplication {
height: 720 height: 720
}); });
} }
getArray(data){
let array = [data.a,data.b,data.c,data.d,data.e,data.f,data.g,data.h];
return array;
}
/** /**
* Provide data to the template * Provide data to the template
*/ */
getData() { getData() {
if (this.update) { //Get the settings
this.update=false;
return {soundData: this.data};
}
this.settings = game.settings.get(MODULE.moduleName,'soundboardSettings'); this.settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
let playlists = [];
playlists.push({id:"none",name:game.i18n.localize("MaterialDeck.None")});
playlists.push({id:"FP",name:game.i18n.localize("MaterialDeck.FilePicker")})
for (let i=0; i<game.playlists.entities.length; i++){
playlists.push({id:game.playlists.entities[i]._id,name:game.playlists.entities[i].name});
}
//Check if all settings are defined
if (this.settings.sounds == undefined) this.settings.sounds = []; if (this.settings.sounds == undefined) this.settings.sounds = [];
if (this.settings.colorOn == undefined) this.settings.colorOn = []; if (this.settings.colorOn == undefined) this.settings.colorOn = [];
if (this.settings.colorOff == undefined) this.settings.colorOff = []; if (this.settings.colorOff == undefined) this.settings.colorOff = [];
@@ -329,8 +298,17 @@ export class soundboardConfigForm extends FormApplication {
if (this.settings.name == undefined) this.settings.name = []; if (this.settings.name == undefined) this.settings.name = [];
if (this.settings.selectedPlaylists == undefined) this.settings.selectedPlaylists = []; if (this.settings.selectedPlaylists == undefined) this.settings.selectedPlaylists = [];
if (this.settings.src == undefined) this.settings.src = []; if (this.settings.src == undefined) this.settings.src = [];
let soundData = [];
//Create the playlist array
let playlists = [];
playlists.push({id:"none",name:game.i18n.localize("MaterialDeck.None")});
playlists.push({id:"FP",name:game.i18n.localize("MaterialDeck.FilePicker")})
for (let i=0; i<game.playlists.entities.length; i++){
playlists.push({id:game.playlists.entities[i]._id,name:game.playlists.entities[i].name});
}
this.playlists = playlists;
//Check what SD model the user is using, and set the number of rows and columns to correspond
let streamDeckModel = game.settings.get(MODULE.moduleName,'streamDeckModel'); let streamDeckModel = game.settings.get(MODULE.moduleName,'streamDeckModel');
if (streamDeckModel == 0){ if (streamDeckModel == 0){
@@ -346,37 +324,54 @@ export class soundboardConfigForm extends FormApplication {
this.iMax = 8; this.iMax = 8;
} }
let iteration = 0; let iteration = 0; //Sound number
let soundData = []; //Stores all the data for each sound
//Fill soundData. soundData is an array the size of jMax (nr of rows), with each array element containing an array the size of iMax (nr of columns)
for (let j=0; j<this.jMax; j++){ for (let j=0; j<this.jMax; j++){
let soundsThis = []; let soundsThis = []; //Stores row data
for (let i=0; i<this.iMax; i++){ for (let i=0; i<this.iMax; i++){
//Each iteration gets the data for each sound
//If the volume is undefined for this sound, define it and set it to its default value
if (this.settings.volume[iteration] == undefined) this.settings.volume[iteration] = 50;
//Get the selected playlist and the sounds of that playlist
let selectedPlaylist; let selectedPlaylist;
let sounds = []; let sounds = [];
if (this.settings.volume[iteration] == undefined) this.settings.volume[iteration] = 50;
if (this.settings.selectedPlaylists[iteration]==undefined) selectedPlaylist = 'none'; if (this.settings.selectedPlaylists[iteration]==undefined) selectedPlaylist = 'none';
else if (this.settings.selectedPlaylists[iteration] == 'none') selectedPlaylist = 'none'; else if (this.settings.selectedPlaylists[iteration] == 'none') selectedPlaylist = 'none';
else if (this.settings.selectedPlaylists[iteration] == 'FP') selectedPlaylist = 'FP'; else if (this.settings.selectedPlaylists[iteration] == 'FP') selectedPlaylist = 'FP';
else { else {
//Get the playlist
const pl = game.playlists.entities.find(p => p._id == this.settings.selectedPlaylists[iteration]); const pl = game.playlists.entities.find(p => p._id == this.settings.selectedPlaylists[iteration]);
if (pl == undefined){ if (pl == undefined){
selectedPlaylist = 'none'; selectedPlaylist = 'none';
sounds = []; sounds = [];
} }
else { else {
sounds = pl.sounds; //Add the sound name and id to the sounds array
for (let i=0; i<pl.sounds.length; i++)
sounds.push({
name: pl.sounds[i].name,
id: pl.sounds[i]._id
});
//Get the playlist id
selectedPlaylist = pl._id; selectedPlaylist = pl._id;
} }
} }
//Determine whether the sound selector or file picker should be displayed
let styleSS = ""; let styleSS = "";
let styleFP ="display:none"; let styleFP ="display:none";
if (selectedPlaylist == 'FP') { if (selectedPlaylist == 'FP') {
styleSS = 'display:none'; styleSS = 'display:none';
styleFP = '' styleFP = ''
} }
//Create and fill the data object for this sound
let dataThis = { let dataThis = {
iteration: iteration+1, iteration: iteration+1,
playlists: playlists,
selectedPlaylist: selectedPlaylist, selectedPlaylist: selectedPlaylist,
sound: this.settings.sounds[iteration], sound: this.settings.sounds[iteration],
sounds: sounds, sounds: sounds,
@@ -390,18 +385,20 @@ export class soundboardConfigForm extends FormApplication {
styleSS: styleSS, styleSS: styleSS,
styleFP: styleFP styleFP: styleFP
} }
//Push the data to soundsThis (row array)
soundsThis.push(dataThis); soundsThis.push(dataThis);
iteration++; iteration++;
} }
let data = {
dataThis: soundsThis, //Push soundsThis (row array) to soundData (full data array)
}; soundData.push({dataThis: soundsThis});
soundData.push(data);
} }
this.data = soundData;
return { return {
soundData: this.data soundData: soundData,
playlists
} }
} }
@@ -428,122 +425,105 @@ export class soundboardConfigForm extends FormApplication {
nameField.on("change",event => { nameField.on("change",event => {
let id = event.target.id.replace('name','')-1; let id = event.target.id.replace('name','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].name=event.target.value;
this.update = true;
this.settings.name[id]=event.target.value; this.settings.name[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
if (playlistSelect.length > 0) { if (playlistSelect.length > 0) {
playlistSelect.on("change", event => {
let id = event.target.id.replace('playlists','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].selectedPlaylist=event.target.value;
//Listener for when the playlist is changed
playlistSelect.on("change", event => {
//Get the sound number
const iteration = event.target.id.replace('playlists','');
//Get the selected playlist and the sounds of that playlist
let selectedPlaylist; let selectedPlaylist;
let sounds = []; //let sounds = [];
if (event.target.value==undefined) selectedPlaylist = 'none'; if (event.target.value==undefined) selectedPlaylist = 'none';
else if (event.target.value == 'none') selectedPlaylist = 'none'; else if (event.target.value == 'none') selectedPlaylist = 'none';
else if (event.target.value == 'FP') selectedPlaylist = 'FP'; else if (event.target.value == 'FP') {
selectedPlaylist = 'FP';
//Show the file picker
document.querySelector(`#fp${iteration}`).style='';
//Hide the sound selector
document.querySelector(`#ss${iteration}`).style='display:none';
}
else { else {
//Hide the file picker
document.querySelector(`#fp${iteration}`).style='display:none';
//Show the sound selector
document.querySelector(`#ss${iteration}`).style='';
const pl = game.playlists.entities.find(p => p._id == event.target.value); const pl = game.playlists.entities.find(p => p._id == event.target.value);
selectedPlaylist = pl._id; selectedPlaylist = pl._id;
sounds = pl.sounds;
}
this.data[j].dataThis[i].sounds=sounds;
let styleSS = ""; //Get the sound select element
let styleFP ="display:none"; let SSpicker = document.getElementById(`soundSelect${iteration}`);
if (selectedPlaylist == 'FP') {
styleSS = 'display:none';
styleFP = ''
}
this.data[j].dataThis[i].styleSS=styleSS;
this.data[j].dataThis[i].styleFP=styleFP;
this.update = true;
this.settings.selectedPlaylists[id]=event.target.value; //Empty ss element
SSpicker.options.length=0;
//Create new options and append them
let optionNone = document.createElement('option');
optionNone.value = "";
optionNone.innerHTML = game.i18n.localize("MaterialDeck.None");
SSpicker.appendChild(optionNone);
for (let i=0; i<pl.sounds.length; i++){
let newOption = document.createElement('option');
newOption.value = pl.sounds[i]._id;
newOption.innerHTML = pl.sounds[i].name;
SSpicker.appendChild(newOption);
}
}
//Save the new playlist to this.settings, and update the settings
this.settings.selectedPlaylists[iteration-1]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
} }
soundSelect.on("change", event => { soundSelect.on("change", event => {
let id = event.target.id.replace('soundSelect','')-1; let id = event.target.id.replace('soundSelect','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].sound=event.target.value;
this.update = true;
this.settings.sounds[id]=event.target.value; this.settings.sounds[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
soundFP.on("change",event => { soundFP.on("change",event => {
let id = event.target.id.replace('srcPath','')-1; let id = event.target.id.replace('srcPath','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].srcPath=event.target.value;
this.update = true;
this.settings.src[id]=event.target.value; this.settings.src[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
imgFP.on("change",event => { imgFP.on("change",event => {
let id = event.target.id.replace('imgPath','')-1; let id = event.target.id.replace('imgPath','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].imgPath=event.target.value;
this.update = true;
this.settings.img[id]=event.target.value; this.settings.img[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
onCP.on("change",event => { onCP.on("change",event => {
let id = event.target.id.replace('colorOn','')-1; let id = event.target.id.replace('colorOn','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].colorOn=event.target.value;
this.update = true;
this.settings.colorOn[id]=event.target.value; this.settings.colorOn[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
offCP.on("change",event => { offCP.on("change",event => {
let id = event.target.id.replace('colorOff','')-1; let id = event.target.id.replace('colorOff','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].colorOff=event.target.value;
this.update = true;
this.settings.colorOff[id]=event.target.value; this.settings.colorOff[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
playMode.on("change",event => { playMode.on("change",event => {
let id = event.target.id.replace('playmode','')-1; let id = event.target.id.replace('playmode','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].mode=event.target.value;
this.update = true;
this.settings.mode[id]=event.target.value; this.settings.mode[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
volume.on("change",event => { volume.on("change",event => {
let id = event.target.id.replace('volume','')-1; let id = event.target.id.replace('volume','')-1;
let j = Math.floor(id/this.jMax);
let i = id % this.jMax;
this.data[j].dataThis[i].volume=event.target.value;
this.update = true;
this.settings.volume[id]=event.target.value; this.settings.volume[id]=event.target.value;
this.updateSettings(this.settings); this.updateSettings(this.settings);
}); });
@@ -552,7 +532,5 @@ export class soundboardConfigForm extends FormApplication {
async updateSettings(settings){ async updateSettings(settings){
await game.settings.set(MODULE.moduleName,'soundboardSettings',settings); await game.settings.set(MODULE.moduleName,'soundboardSettings',settings);
if (MODULE.enableModule) soundboard.updateAll(); if (MODULE.enableModule) soundboard.updateAll();
this.render();
} }
} }

View File

@@ -10,7 +10,7 @@ export class OtherControls{
async updateAll(){ async updateAll(){
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'other') continue; if (data == undefined || data.action != 'other') continue;
await this.update(data.settings,data.context); await this.update(data.settings,data.context);
} }

View File

@@ -11,7 +11,7 @@ export class PlaylistControl{
async updateAll(){ async updateAll(){
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'playlist') continue; if (data == undefined || data.action != 'playlist') continue;
await this.update(data.settings,data.context); await this.update(data.settings,data.context);
} }

View File

@@ -11,7 +11,7 @@ export class SceneControl{
async updateAll(){ async updateAll(){
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'scene') continue; if (data == undefined || data.action != 'scene') continue;
await this.update(data.settings,data.context); await this.update(data.settings,data.context);
} }
@@ -29,7 +29,7 @@ export class SceneControl{
let src = ""; let src = "";
let name = ""; let name = "";
if (func == 'visible'){ //visible scenes if (func == 'visible') { //visible scenes
let nr = parseInt(settings.sceneNr); let nr = parseInt(settings.sceneNr);
if (isNaN(nr) || nr < 1) nr = 1; if (isNaN(nr) || nr < 1) nr = 1;
nr--; nr--;
@@ -37,10 +37,7 @@ export class SceneControl{
let scene = game.scenes.apps[0].scenes[nr]; let scene = game.scenes.apps[0].scenes[nr];
if (scene != undefined){ if (scene != undefined){
if (scene.isView) ringColor = scene.isView ? ringOnColor : ringOffColor;
ringColor = ringOnColor;
else
ringColor = ringOffColor;
if (settings.displaySceneName) name = scene.name; if (settings.displaySceneName) name = scene.name;
if (settings.displaySceneIcon) src = scene.img; if (settings.displaySceneIcon) src = scene.img;
if (scene.active) name += "\n(Active)"; if (scene.active) name += "\n(Active)";
@@ -81,10 +78,7 @@ export class SceneControl{
if (settings.sceneName == undefined || settings.sceneName == '') return; if (settings.sceneName == undefined || settings.sceneName == '') return;
let scene = game.scenes.apps[1].entities.find(p=>p.data.name == settings.sceneName); let scene = game.scenes.apps[1].entities.find(p=>p.data.name == settings.sceneName);
if (scene != undefined){ if (scene != undefined){
if (scene.isView) ringColor = scene.isView ? ringOnColor : ringOffColor;
ringColor = ringOnColor;
else
ringColor = ringOffColor;
if (settings.displaySceneName) name = scene.name; if (settings.displaySceneName) name = scene.name;
if (settings.displaySceneIcon) src = scene.img; if (settings.displaySceneIcon) src = scene.img;
if (scene.active) name += "\n(Active)"; if (scene.active) name += "\n(Active)";
@@ -167,8 +161,7 @@ export class SceneControl{
let scene = game.scenes.apps[1].entities.find(p=>p.data.name == settings.sceneName); let scene = game.scenes.apps[1].entities.find(p=>p.data.name == settings.sceneName);
if (scene == undefined) return; if (scene == undefined) return;
let viewFunc = settings.sceneViewFunction; const viewFunc = settings.sceneViewFunction ? settings.sceneViewFunction : 'view';
if (viewFunc == undefined) viewFunc = 'view';
if (viewFunc == 'view'){ if (viewFunc == 'view'){
scene.view(); scene.view();

View File

@@ -13,7 +13,7 @@ export class SoundboardControl{
async updateAll(){ async updateAll(){
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'soundboard') continue; if (data == undefined || data.action != 'soundboard') continue;
await this.update(data.settings,data.context); await this.update(data.settings,data.context);
} }
@@ -21,17 +21,13 @@ export class SoundboardControl{
update(settings,context){ update(settings,context){
this.active = true; this.active = true;
let mode = settings.soundboardMode; const mode = settings.soundboardMode ? settings.soundboardMode : 'playSound';
if (mode == undefined) mode = 'playSound'; const background = settings.background ? settings.background : '#000000';
let ringColor = "#000000"
let txt = ""; let txt = "";
let src = ""; let src = "";
let background = settings.background;
if (background == undefined) background = '#000000';
let ringColor = "#000000"
if (mode == 'playSound'){ //play sound if (mode == 'playSound'){ //play sound
let soundNr = parseInt(settings.soundNr); let soundNr = parseInt(settings.soundNr);
if (isNaN(soundNr)) soundNr = 1; if (isNaN(soundNr)) soundNr = 1;
@@ -39,28 +35,23 @@ export class SoundboardControl{
soundNr += this.offset; soundNr += this.offset;
let soundboardSettings = game.settings.get(MODULE.moduleName, 'soundboardSettings'); let soundboardSettings = game.settings.get(MODULE.moduleName, 'soundboardSettings');
ringColor = (this.activeSounds[soundNr]==false) ? soundboardSettings.colorOff[soundNr] : soundboardSettings.colorOn[soundNr];
if (this.activeSounds[soundNr]==false)
ringColor = soundboardSettings.colorOff[soundNr];
else
ringColor = soundboardSettings.colorOn[soundNr];
if (settings.displayName && soundboardSettings.name != undefined) txt = soundboardSettings.name[soundNr]; if (settings.displayName && soundboardSettings.name != undefined) txt = soundboardSettings.name[soundNr];
if (settings.displayIcon && soundboardSettings.img != undefined) src = soundboardSettings.img[soundNr]; if (settings.displayIcon && soundboardSettings.img != undefined) src = soundboardSettings.img[soundNr];
streamDeck.setTitle(txt,context); streamDeck.setTitle(txt,context);
streamDeck.setIcon(context,src,background,2,ringColor); streamDeck.setIcon(context,src,background,2,ringColor);
} }
else if (mode == 'offset') { //Offset else if (mode == 'offset') { //Offset
let ringOffColor = settings.offRing; const ringOffColor = settings.offRing ? settings.offRing : '#000000';
if (ringOffColor == undefined) ringOffColor = '#000000'; const ringOnColor = settings.onRing ? settings.onRing : '#00FF00';
let ringOnColor = settings.onRing;
if (ringOnColor == undefined) ringOnColor = '#00FF00';
let offset = parseInt(settings.offset); let offset = parseInt(settings.offset);
if (isNaN(offset)) offset = 0; if (isNaN(offset)) offset = 0;
if (offset == this.offset) ringColor = ringOnColor; if (offset == this.offset) ringColor = ringOnColor;
else ringColor = ringOffColor; else ringColor = ringOffColor;
streamDeck.setTitle(txt,context); streamDeck.setTitle(txt,context);
streamDeck.setIcon(context,"",background,2,ringColor); streamDeck.setIcon(context,"",background,2,ringColor);
} }
@@ -68,7 +59,8 @@ export class SoundboardControl{
let src = 'modules/MaterialDeck/img/playlist/stop.png'; let src = 'modules/MaterialDeck/img/playlist/stop.png';
let soundPlaying = false; let soundPlaying = false;
for (let i=0; i<this.activeSounds.length; i++) for (let i=0; i<this.activeSounds.length; i++)
if (this.activeSounds[i]) soundPlaying = true; if (this.activeSounds[i])
soundPlaying = true;
if (soundPlaying) if (soundPlaying)
streamDeck.setIcon(context,src,settings.background,2,'#00FF00',true); streamDeck.setIcon(context,src,settings.background,2,'#00FF00',true);
else else
@@ -77,8 +69,8 @@ export class SoundboardControl{
} }
keyPressDown(settings){ keyPressDown(settings){
let mode = settings.soundboardMode; const mode = settings.soundboardMode ? settings.soundboardMode : 'playSound';
if (mode == undefined) mode = 'playSound';
if (mode == 'playSound') { //Play sound if (mode == 'playSound') { //Play sound
let soundNr = parseInt(settings.soundNr); let soundNr = parseInt(settings.soundNr);
if (isNaN(soundNr)) soundNr = 1; if (isNaN(soundNr)) soundNr = 1;
@@ -86,11 +78,9 @@ export class SoundboardControl{
soundNr += this.offset; soundNr += this.offset;
const playMode = game.settings.get(MODULE.moduleName,'soundboardSettings').mode[soundNr]; const playMode = game.settings.get(MODULE.moduleName,'soundboardSettings').mode[soundNr];
const repeat = (playMode > 0) ? true : false;
const play = (this.activeSounds[soundNr] == false) ? true : false;
let repeat = false;
if (playMode > 0) repeat = true;
let play = false;
if (this.activeSounds[soundNr] == false) play = true;
this.playSound(soundNr,repeat,play); this.playSound(soundNr,repeat,play);
} }
else if (mode == 'offset') { //Offset else if (mode == 'offset') { //Offset
@@ -109,9 +99,10 @@ export class SoundboardControl{
} }
keyPressUp(settings){ keyPressUp(settings){
let mode = settings.soundboardMode; const mode = settings.soundboardMode ? settings.soundboardMode : 'playSound';
if (mode == undefined) mode = 'playSound';
if (mode != 'playSound') return; if (mode != 'playSound') return;
let soundNr = parseInt(settings.soundNr); let soundNr = parseInt(settings.soundNr);
if (isNaN(soundNr)) soundNr = 1; if (isNaN(soundNr)) soundNr = 1;
soundNr--; soundNr--;
@@ -125,8 +116,7 @@ export class SoundboardControl{
async playSound(soundNr,repeat,play){ async playSound(soundNr,repeat,play){
const soundBoardSettings = game.settings.get(MODULE.moduleName,'soundboardSettings'); const soundBoardSettings = game.settings.get(MODULE.moduleName,'soundboardSettings');
let playlistId; const playlistId = (soundBoardSettings.selectedPlaylists != undefined) ? soundBoardSettings.selectedPlaylists[soundNr] : undefined;
if (soundBoardSettings.selectedPlaylists != undefined) playlistId = soundBoardSettings.selectedPlaylists[soundNr];
let src; let src;
if (playlistId == "" || playlistId == undefined) return; if (playlistId == "" || playlistId == undefined) return;
if (playlistId == 'none') return; if (playlistId == 'none') return;
@@ -134,7 +124,8 @@ export class SoundboardControl{
src = soundBoardSettings.src[soundNr]; src = soundBoardSettings.src[soundNr];
const ret = await FilePicker.browse("data", src, {wildcard:true}); const ret = await FilePicker.browse("data", src, {wildcard:true});
const files = ret.files; const files = ret.files;
if (files.length == 1) src = files; if (files.length == 1)
src = files;
else { else {
let value = Math.floor(Math.random() * Math.floor(files.length)); let value = Math.floor(Math.random() * Math.floor(files.length));
src = files[value]; src = files[value];

View File

@@ -10,37 +10,32 @@ export class TokenControl{
async update(tokenId){ async update(tokenId){
if (this.active == false) return; if (this.active == false) return;
for (let i=0; i<32; i++){ for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i]; const data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'token') continue; if (data == undefined || data.action != 'token') continue;
await this.pushData(tokenId,data.settings,data.context); await this.pushData(tokenId,data.settings,data.context);
} }
} }
async pushData(tokenId,settings,context,ring=0,ringColor='#000000'){ async pushData(tokenId,settings,context,ring=0,ringColor='#000000'){
let name = false; const name = settings.displayName ? settings.displayName : false;
let icon = false; const icon = settings.displayIcon ? settings.displayIcon : false;
let stats = settings.stats; const background = settings.background ? settings.background : "#000000";
let background = "#000000"; const system = settings.system ? settings.system : 'dnd5e';
if (settings.displayIcon) icon = true; let stats = (system == 'demonlord') ? settings.statsDemonlord : settings.stats;
if (settings.displayName) name = true;
let system = settings.system;
if (system == undefined) system = 'dnd5e';
if (system == 'demonlord') stats = settings.statsDemonlord;
if (stats == undefined) stats = 'none'; if (stats == undefined) stats = 'none';
if (settings.background) background = settings.background;
let tokenName = ""; let tokenName = "";
let txt = ""; let txt = "";
let iconSrc = ""; let iconSrc = "";
let overlay = false; let overlay = false;
if (tokenId != undefined) { if (tokenId != undefined) {
let token = canvas.tokens.children[0].children.find(p => p.id == tokenId); const token = canvas.tokens.children[0].children.find(p => p.id == tokenId);
tokenName = token.data.name; tokenName = token.data.name;
if (name) txt += tokenName; if (name) txt += tokenName;
if (name && stats != 'none') txt += "\n"; if (name && stats != 'none') txt += "\n";
iconSrc = token.data.img; iconSrc = token.data.img;
let actor = canvas.tokens.children[0].children.find(p => p.id == tokenId).actor;
if (stats == 'custom'){ if (stats == 'custom'){
const custom = settings.custom ? settings.custom : ''; const custom = settings.custom ? settings.custom : '';
let split = custom.split('['); let split = custom.split('[');
@@ -60,7 +55,7 @@ export class TokenControl{
} }
} }
else if (system == 'dnd5e' && game.system.id == 'dnd5e'){ else if (system == 'dnd5e' && game.system.id == 'dnd5e'){
let attributes = actor.data.data.attributes; let attributes = token.actor.data.data.attributes;
if (stats == 'HP') { if (stats == 'HP') {
txt += attributes.hp.value + "/" + attributes.hp.max; txt += attributes.hp.value + "/" + attributes.hp.max;
} }
@@ -102,11 +97,11 @@ export class TokenControl{
txt += speed; txt += speed;
} }
else if (stats == 'Init') txt += attributes.init.total; else if (stats == 'Init') txt += attributes.init.total;
else if (stats == 'PassivePerception') txt += actor.data.data.skills.prc.passive; else if (stats == 'PassivePerception') txt += token.actor.data.data.skills.prc.passive;
else if (stats == 'PassiveInvestigation') txt += actor.data.data.skills.inv.passive; else if (stats == 'PassiveInvestigation') txt += token.actor.data.data.skills.inv.passive;
} }
else if ((system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){ else if ((system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){
let attributes = actor.data.data.attributes; let attributes = token.actor.data.data.attributes;
if (stats == 'HP') txt += attributes.hp.value + "/" + attributes.hp.max; if (stats == 'HP') txt += attributes.hp.value + "/" + attributes.hp.max;
else if (stats == 'TempHP') { else if (stats == 'TempHP') {
if (attributes.hp.temp == null) txt += '0'; if (attributes.hp.temp == null) txt += '0';
@@ -137,7 +132,7 @@ export class TokenControl{
else if (stats == 'Init') txt += attributes.init.total; else if (stats == 'Init') txt += attributes.init.total;
} }
else if (system == 'pf2e' && game.system.id == 'pf2e'){ else if (system == 'pf2e' && game.system.id == 'pf2e'){
let attributes = actor.data.data.attributes; let attributes = token.actor.data.data.attributes;
if (stats == 'HP') txt += attributes.hp.value + "/" + attributes.hp.max; if (stats == 'HP') txt += attributes.hp.value + "/" + attributes.hp.max;
else if (stats == 'TempHP') { else if (stats == 'TempHP') {
if (attributes.hp.temp == null) txt += '0'; if (attributes.hp.temp == null) txt += '0';
@@ -161,11 +156,11 @@ export class TokenControl{
} }
} }
else if (system == 'demonlord' && game.system.id == 'demonlord'){ else if (system == 'demonlord' && game.system.id == 'demonlord'){
let characteristics = actor.data.data.characteristics; let characteristics = token.actor.data.data.characteristics;
if (statsDemonlord == 'HP') txt += characteristics.health.value + "/" + characteristics.health.max; if (stats == 'HP') txt += characteristics.health.value + "/" + characteristics.health.max;
else if (statsDemonlord == 'AC') txt += characteristics.defense; else if (stats == 'AC') txt += characteristics.defense;
else if (statsDemonlord == 'Speed') txt += characteristics.speed; else if (stats == 'Speed') txt += characteristics.speed;
else if (statsDemonlord == 'Init') txt += actor.data.data.fastturn ? "FAST" : "SLOW"; else if (stats == 'Init') txt += token.actor.data.data.fastturn ? "FAST" : "SLOW";
} }
else { else {
//Other systems //Other systems
@@ -210,8 +205,7 @@ export class TokenControl{
else if (settings.onClick == 'condition') { //toggle condition else if (settings.onClick == 'condition') { //toggle condition
ring = 1; ring = 1;
if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){ if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){
let condition = settings.condition; const condition = settings.condition ? settings.condition : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll' && icon == false) if (condition == 'removeAll' && icon == false)
iconSrc = window.CONFIG.controlIcons.effects; iconSrc = window.CONFIG.controlIcons.effects;
else if (icon == false) { else if (icon == false) {
@@ -226,8 +220,7 @@ export class TokenControl{
} }
} }
else if (system == 'pf2e' && game.system.id == 'pf2e') { else if (system == 'pf2e' && game.system.id == 'pf2e') {
let condition = settings.conditionPF2E; const condition = settings.conditionPF2E ? settings.conditionPF2E : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll' && icon == false) if (condition == 'removeAll' && icon == false)
iconSrc = window.CONFIG.controlIcons.effects; iconSrc = window.CONFIG.controlIcons.effects;
else if (icon == false) { else if (icon == false) {
@@ -242,8 +235,7 @@ export class TokenControl{
} }
} }
else if (system == 'demonlord' && game.system.id == 'demonlord'){ else if (system == 'demonlord' && game.system.id == 'demonlord'){
let condition = settings.conditionDemonlord; const condition = settings.conditionDemonlord ? settings.conditionDemonlord : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll' && icon == false) if (condition == 'removeAll' && icon == false)
iconSrc = window.CONFIG.controlIcons.effects; iconSrc = window.CONFIG.controlIcons.effects;
else if (icon == false) { else if (icon == false) {
@@ -321,27 +313,21 @@ export class TokenControl{
} }
else if (settings.onClick == 'condition') { //toggle condition else if (settings.onClick == 'condition') { //toggle condition
if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){ if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){
let condition = settings.condition; const condition = settings.condition ? settings.condition : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll' && icon == false) if (condition == 'removeAll' && icon == false)
iconSrc = window.CONFIG.controlIcons.effects; iconSrc = window.CONFIG.controlIcons.effects;
else if (icon == false) else if (icon == false)
iconSrc = CONFIG.statusEffects.find(e => e.id === condition).icon; iconSrc = CONFIG.statusEffects.find(e => e.id === condition).icon;
} }
else if (system == 'pf2e' && game.system.id == 'pf2e') { else if (system == 'pf2e' && game.system.id == 'pf2e') {
let condition = settings.conditionPF2E; const condition = settings.conditionPF2E ? settings.conditionPF2E : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll' && icon == false) if (condition == 'removeAll' && icon == false)
iconSrc = window.CONFIG.controlIcons.effects; iconSrc = window.CONFIG.controlIcons.effects;
else if (icon == false) else if (icon == false)
iconSrc = this.pf2eCondition(condition); iconSrc = this.pf2eCondition(condition);
} }
else if (system == 'demonlord' && game.system.id == 'demonlord'){ else if (system == 'demonlord' && game.system.id == 'demonlord'){
let condition = settings.conditionDemonlord; const condition = settings.conditionDemonlord ? settings.conditionDemonlord : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll' && icon == false) if (condition == 'removeAll' && icon == false)
iconSrc = window.CONFIG.controlIcons.effects; iconSrc = window.CONFIG.controlIcons.effects;
else if (icon == false) else if (icon == false)
@@ -366,7 +352,6 @@ export class TokenControl{
iconSrc = "modules/MaterialDeck/img/black.png"; iconSrc = "modules/MaterialDeck/img/black.png";
} }
streamDeck.setIcon(context,iconSrc,background,ring,ringColor,overlay); streamDeck.setIcon(context,iconSrc,background,ring,ringColor,overlay);
streamDeck.setTitle(txt,context); streamDeck.setTitle(txt,context);
} }
@@ -374,15 +359,14 @@ export class TokenControl{
if (MODULE.selectedTokenId == undefined) return; if (MODULE.selectedTokenId == undefined) return;
const tokenId = MODULE.selectedTokenId; const tokenId = MODULE.selectedTokenId;
let onClick = settings.onClick;
if (onClick == undefined) onClick = 'doNothing';
const token = canvas.tokens.children[0].children.find(p => p.id == tokenId); const token = canvas.tokens.children[0].children.find(p => p.id == tokenId);
if (token == undefined) return; if (token == undefined) return;
let system = settings.system; let system = settings.system ? settings.system : 'dnd5e';
if (system == undefined) system = 'dnd5e';
let onClick = (system == 'demonlord') ? settings.onClickDemonlord : settings.onClick;
if (onClick == undefined) onClick = 'doNothing';
if (onClick == 'doNothing') //Do nothing if (onClick == 'doNothing') //Do nothing
return; return;
else if (onClick == 'center'){ //center on token else if (onClick == 'center'){ //center on token
@@ -410,15 +394,10 @@ export class TokenControl{
} }
else if (onClick == 'condition') { //Toggle condition else if (onClick == 'condition') { //Toggle condition
if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){ if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E') || (system == 'pf1e' && game.system.id == 'pf1')){
let condition = settings.condition; const condition = settings.condition ? settings.condition : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll'){ if (condition == 'removeAll'){
const effects = token.actor.effects.entries; for( let effect of token.actor.effects)
for (let i=0; i<effects.length; i++){ await effect.delete();
const effect = CONFIG.statusEffects.find(e => e.icon === effects[i].data.icon);
await token.toggleEffect(effect)
}
} }
else { else {
const effect = CONFIG.statusEffects.find(e => e.id === condition); const effect = CONFIG.statusEffects.find(e => e.id === condition);
@@ -426,14 +405,10 @@ export class TokenControl{
} }
} }
else if (system == 'pf2e' && game.system.id == 'pf2e'){ else if (system == 'pf2e' && game.system.id == 'pf2e'){
let condition = settings.conditionPF2E; const condition = settings.conditionPF2E ? settings.conditionPF2E : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll'){ if (condition == 'removeAll'){
const effects = token.actor.effects.entries; for( let effect of token.actor.effects)
for (let i=0; i<effects.length; i++){ await effect.delete();
const effect = this.pf2eCondition(condition);
await token.toggleEffect(effect)
}
} }
else { else {
const effect = this.pf2eCondition(condition); const effect = this.pf2eCondition(condition);
@@ -441,15 +416,10 @@ export class TokenControl{
} }
} }
else if (system == 'demonlord' && game.system.id == 'demonlord'){ else if (system == 'demonlord' && game.system.id == 'demonlord'){
let condition = settings.conditionDemonlord; const condition = settings.conditionDemonlord ? settings.conditionDemonlord : 'removeAll';
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll'){ if (condition == 'removeAll'){
const effects = token.actor.effects.entries; for( let effect of token.actor.effects)
for (let i=0; i<effects.length; i++){ await effect.delete();
const effect = CONFIG.statusEffects.find(e => e.icon === effects[i].data.icon);
await token.toggleEffect(effect)
}
} }
else { else {
const effect = CONFIG.statusEffects.find(e => e.id === condition); const effect = CONFIG.statusEffects.find(e => e.id === condition);
@@ -504,7 +474,7 @@ export class TokenControl{
}) })
} }
else if (settings.onClick == 'wildcard') { //wildcard images else if (onClick == 'wildcard') { //wildcard images
const method = settings.wildcardMethod ? settings.wildcardMethod : 'iterate'; const method = settings.wildcardMethod ? settings.wildcardMethod : 'iterate';
let value = parseInt(settings.wildcardValue); let value = parseInt(settings.wildcardValue);
if (isNaN(value)) value = 1; if (isNaN(value)) value = 1;
@@ -538,7 +508,7 @@ export class TokenControl{
iconSrc = images[imgNr]; iconSrc = images[imgNr];
token.update({img: iconSrc}) token.update({img: iconSrc})
} }
else if (settings.onClick == 'custom') {//custom onClick function else if (onClick == 'custom') {//custom onClick function
const formula = settings.customOnClickFormula ? settings.customOnClickFormula : ''; const formula = settings.customOnClickFormula ? settings.customOnClickFormula : '';
if (formula == '') return; if (formula == '') return;

View File

@@ -19,13 +19,13 @@
<select name="macros" class="macros-select" id="macros{{this.iteration}}" default="" style="max-width:140px;"> <select name="macros" class="macros-select" id="macros{{this.iteration}}" default="" style="max-width:140px;">
{{#select this.macro}} {{#select this.macro}}
<option value="">{{localize "MaterialDeck.None"}}</option> <option value="">{{localize "MaterialDeck.None"}}</option>
{{#each macros}} {{#each ../../macros}}
<option value="{{this._id}}">{{this.name}}</option> <option value="{{this._id}}">{{this.name}}</option>
{{/each}} {{/each}}
{{/select}} {{/select}}
</select> </select>
</div> </div>
{{#if this.furnace}} {{#if ../../furnace}}
<label>{{localize "MaterialDeck.FurnaceArgs"}}</label> <label>{{localize "MaterialDeck.FurnaceArgs"}}</label>
<input type="text" name="args" id="args{{this.iteration}}" value="{{this.args}}"> <input type="text" name="args" id="args{{this.iteration}}" value="{{this.args}}">
{{/if}} {{/if}}

View File

@@ -25,7 +25,7 @@
<select name="selectedPlaylist" class="playlist-select" id="playlist{{this.iteration}}" default=""> <select name="selectedPlaylist" class="playlist-select" id="playlist{{this.iteration}}" default="">
{{#select this.playlist}} {{#select this.playlist}}
<option value="">{{localize "MaterialDeck.None"}}</option> <option value="">{{localize "MaterialDeck.None"}}</option>
{{#each this.playlists}} {{#each ../playlists}}
<option value="{{this._id}}">{{this.name}}</option> <option value="{{this._id}}">{{this.name}}</option>
{{/each}} {{/each}}
{{/select}} {{/select}}

View File

@@ -26,7 +26,7 @@
<div> <div>
<select name="playlist" class="playlist-select" default="" style="width:100%;" id="playlists{{this.iteration}}"> <select name="playlist" class="playlist-select" default="" style="width:100%;" id="playlists{{this.iteration}}">
{{#select this.selectedPlaylist}} {{#select this.selectedPlaylist}}
{{#each playlists}} {{#each ../../playlists}}
<option value="{{this.id}}">{{this.name}}</option> <option value="{{this.id}}">{{this.name}}</option>
{{/each}} {{/each}}
{{/select}} {{/select}}
@@ -36,17 +36,17 @@
<div style="text-align:center;"> <div style="text-align:center;">
{{localize "MaterialDeck.Sound"}} {{localize "MaterialDeck.Sound"}}
</div> </div>
<div class="form-fields" style={{this.styleSS}}> <div class="form-fields" id="ss{{this.iteration}}" style="{{this.styleSS}}">
<select name="sounds" class="sounds-select" default="" style="width:100%;" id="soundSelect{{this.iteration}}"> <select name="sounds" class="sounds-select" default="" style="width:100%;" id="soundSelect{{this.iteration}}">
{{#select this.sound}} {{#select this.sound}}
<option value="">{{localize "MaterialDeck.None"}}</option> <option value="">{{localize "MaterialDeck.None"}}</option>
{{#each sounds}} {{#each sounds}}
<option value="{{this._id}}">{{this.name}}</option> <option value="{{this.id}}">{{this.name}}</option>
{{/each}} {{/each}}
{{/select}} {{/select}}
</select> </select>
</div> </div>
<div class="form-fields" style={{this.styleFP}}> <div class="form-fields" id="fp{{this.iteration}}" style="{{this.styleFP}}">
<button type="button" class="file-picker" data-type="audio" data-target="src{{this.iteration}}" title="Browse Files" tabindex="-1"> <button type="button" class="file-picker" data-type="audio" data-target="src{{this.iteration}}" title="Browse Files" tabindex="-1">
<i class="fas fa-file-import fa-fw"></i> <i class="fas fa-file-import fa-fw"></i>
</button> </button>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB