This commit is contained in:
CDeenen
2020-11-23 06:51:23 +01:00
parent fb26eacc8d
commit cd4c9e129e
13 changed files with 447 additions and 161 deletions

View File

@@ -265,6 +265,18 @@ Hooks.on('updateToken',(scene,token)=>{
tokenControl.update(selectedTokenId);
});
Hooks.on('updateActor',(scene,actor)=>{
if (enableModule == false || ready == false) return;
let children = canvas.tokens.children[0].children;
for (let i=0; i<children.length; i++){
if (children[i].actor.id == actor._id){
let tokenId = children[i].id;
if (tokenId == selectedTokenId)
tokenControl.update(selectedTokenId);
}
}
});
Hooks.on('controlToken',(token,controlled)=>{
if (enableModule == false || ready == false) return;
if (controlled) {

View File

@@ -1,5 +1,20 @@
# Changelog Material Deck Module
### v0.8.7 - 19-11-2020
### v0.9.1 - 23-11-2020
<ul>
<li>Fixed 'Playlist' action issue where 'TrackNr' wouldn't show</li>
<li>Fixed 'Soundboard Configuration' issue where changing the playlist would reset everything you've changed since last save</li>
<li>'Soundboard Configuration', 'Macro Configuration' and 'Playlist Configuration' now save after each change, and update the SD instantly</li>
<li>Save button has been removed from configuration screens, since it is now redundant</li>
</ul>
<b>Note1:</b> In 'Macro Configuration', previously saved Furnace arguments have to be filled in again.<br>
<b>Note2:</b> Any settings set in 'Playlist Configuration' have to be set again<br>
<br>
<b>Compatible server app and SD plugin:</b><br>
Material Server v1.0.1: https://github.com/CDeenen/MaterialServer/releases <br>
SD plugin v0.9.1 (unchanged): https://github.com/CDeenen/MaterialDeck_SD/releases<br>
### v0.9.0 - 19-11-2020
<ul>
<li>Added support for more playlists</li>
<li>Added playmode setting for each playlist, which overrides the default playmode</li>

View File

@@ -20,7 +20,7 @@
"MaterialDeck.PL.OneTrackTotal": "One track in total",
"MaterialDeck.PL.OneTrack": "One track",
"MaterialDeck.PL.Settings": "Settings",
"MaterialDeck.PL.Mode": "Default Playmode",
"MaterialDeck.PL.Mode": "Default Play Mode",
"MaterialDeck.PL.Nr": "Number of playlists",
"MaterialDeck.Playlists": "Playlists",

View File

@@ -2,7 +2,7 @@
"name": "MaterialDeck",
"title": "Material Deck",
"description": "",
"version": "0.9.0",
"version": "0.9.1",
"author": "CDeenen",
"esmodules": [
"./MaterialDeck.js"

View File

@@ -196,7 +196,7 @@ export class MacroControl{
if (macroId != undefined){
let macro = game.macros.get(macroId);
if (macro != undefined && macro != null) {
const args = game.settings.get(MODULE.moduleName,'macroArgs')[macroNumber];
const args = game.settings.get(MODULE.moduleName,'macroSettings').args[macroNumber];
let furnaceEnabled = false;
let furnace = game.modules.get("furnace");
if (furnace != undefined && furnace.active) furnaceEnabled = true;

View File

@@ -1,5 +1,5 @@
import * as MODULE from "../MaterialDeck.js";
import {macroControl} from "../MaterialDeck.js";
import {macroControl,soundboard,playlistControl} from "../MaterialDeck.js";
export class playlistConfigForm extends FormApplication {
constructor(data, options) {
@@ -26,33 +26,43 @@ export class playlistConfigForm extends FormApplication {
* Provide data to the template
*/
getData() {
let selectedPlaylists = game.settings.get(MODULE.moduleName,'selectedPlaylists');
let settings = game.settings.get(MODULE.moduleName,'playlists');
let selectedPlaylists = settings.selectedPlaylist;
if (selectedPlaylists == undefined) selectedPlaylists = [];
let selectedPlaylistMethod = game.settings.get(MODULE.moduleName, 'selectedPlaylistMethod');
if (selectedPlaylistMethod == undefined) selectedPlaylistMethod = [];
let playlistData = [];
let numberOfPlaylists = game.settings.get(MODULE.moduleName,'numberOfPlaylists');
let selectedPlaylistMode = settings.playlistMode;
if (selectedPlaylistMode == undefined) selectedPlaylistMode = [];
let numberOfPlaylists = settings.playlistNumber;
if (this.updatePlaylistNr) numberOfPlaylists = this.playlistNr;
if (numberOfPlaylists == undefined) numberOfPlaylists = 9;
let playMode = settings.playMode;
if (playMode == undefined) playMode = 0;
let playlistData = [];
this.updatePlaylistNr = false;
for (let i=0; i<numberOfPlaylists; i++){
if (selectedPlaylists[i] == undefined) selectedPlaylists[i] = 'none';
if (selectedPlaylistMethod[i] == undefined) selectedPlaylistMethod[i] = 0;
if (selectedPlaylistMode[i] == undefined) selectedPlaylistMode[i] = 0;
let dataThis = {
iteration: i+1,
playlist: selectedPlaylists[i],
playlistMethod: selectedPlaylistMethod[i],
playlistMode: selectedPlaylistMode[i],
playlists: game.playlists.entities
}
playlistData.push(dataThis);
}
if (!this.data && selectedPlaylists) {
this.data = selectedPlaylists;
this.data = {
playMode: playMode,
playlistNumber: numberOfPlaylists,
selectedPlaylist: selectedPlaylists,
playlistMode: selectedPlaylistMode
}
return {
playlists: game.playlists.entities,
numberOfPlaylists: numberOfPlaylists,
playlistData: playlistData,
playMethod: game.settings.get(MODULE.moduleName,'playlistMethod')
playMode: playMode
}
}
@@ -62,21 +72,48 @@ export class playlistConfigForm extends FormApplication {
* @param {*} formData
*/
async _updateObject(event, formData) {
await game.settings.set(MODULE.moduleName,'selectedPlaylists', formData["selectedPlaylist"]);
await game.settings.set(MODULE.moduleName,'playlistMethod',formData["playMethod"]);
await game.settings.set(MODULE.moduleName,'numberOfPlaylists',formData["plNum"]);
await game.settings.set(MODULE.moduleName,'selectedPlaylistMethod',formData["playlistMethod"]);
// await game.settings.set(MODULE.moduleName,'selectedPlaylists', formData["selectedPlaylist"]);
// await game.settings.set(MODULE.moduleName,'playlistMethod',formData["playMethod"]);
// await game.settings.set(MODULE.moduleName,'numberOfPlaylists',formData["plNum"]);
// await game.settings.set(MODULE.moduleName,'selectedPlaylistMode',formData["playlistMethod"]);
}
activateListeners(html) {
super.activateListeners(html);
const playMode = html.find("select[name='playMode']");
const numberOfPlaylists = html.find("input[name='plNum']");
const selectedPlaylist = html.find("select[name='selectedPlaylist']");
const playlistMode = html.find("select[name='playlistMode']");
playMode.on("change", event => {
this.data.playMode=event.target.value;
this.updateSettings(this.data);
});
numberOfPlaylists.on("change", event => {
this.playlistNr = event.target.value;
this.updatePlaylistNr = true;
this.render();
this.data.playlistNumber=event.target.value;
this.updateSettings(this.data);
});
selectedPlaylist.on("change", event => {
let id = event.target.id.replace('playlist','');
this.data.selectedPlaylist[id-1]=event.target.value;
this.updateSettings(this.data);
});
playlistMode.on("change", event => {
let id = event.target.id.replace('playlistMode','');
this.data.playlistMode[id-1]=event.target.value;
this.updateSettings(this.data);
});
}
async updateSettings(settings){
await game.settings.set(MODULE.moduleName,'playlists', settings);
if (MODULE.enableModule) playlistControl.updateAll();
this.render();
}
}
@@ -116,7 +153,7 @@ export class macroConfigForm extends FormApplication {
getData() {
var selectedMacros = game.settings.get(MODULE.moduleName,'macroSettings').macros;
var color = game.settings.get(MODULE.moduleName,'macroSettings').color;
var args = game.settings.get(MODULE.moduleName,'macroArgs');
var args = game.settings.get(MODULE.moduleName,'macroSettings').args;
if (selectedMacros == undefined) selectedMacros = [];
if (color == undefined) color = [];
if (args == undefined) args = [];
@@ -191,9 +228,11 @@ export class macroConfigForm extends FormApplication {
* @param {*} formData
*/
async _updateObject(event, formData) {
/*
await game.settings.set(MODULE.moduleName,'macroSettings',{
macros: formData["macros"],
color: formData["colorPicker"]
color: formData["colorPicker"],
args: formData["args"]
});
let furnace = game.modules.get("furnace");
@@ -201,10 +240,41 @@ export class macroConfigForm extends FormApplication {
await game.settings.set(MODULE.moduleName,'macroArgs', formData["args"]);
if (MODULE.enableModule)
macroControl.updateAll();
*/
}
activateListeners(html) {
super.activateListeners(html);
const macro = html.find("select[name='macros']");
const args = html.find("input[name='args']");
const color = html.find("input[name='colorPicker']");
macro.on("change", event => {
let id = event.target.id.replace('macros','');
let settings = game.settings.get(MODULE.moduleName,'macroSettings');
settings.macros[id-1]=event.target.value;
this.updateSettings(settings);
});
args.on("change", event => {
let id = event.target.id.replace('args','');
let settings = game.settings.get(MODULE.moduleName,'macroSettings');
settings.args[id-1]=event.target.value;
this.updateSettings(settings);
});
color.on("change", event => {
let id = event.target.id.replace('colorpicker','');
let settings = game.settings.get(MODULE.moduleName,'macroSettings');
settings.color[id-1]=event.target.value;
this.updateSettings(settings);
});
}
async updateSettings(settings){
await game.settings.set(MODULE.moduleName,'macroSettings',settings);
if (MODULE.enableModule) macroControl.updateAll();
this.render();
}
}
@@ -217,6 +287,9 @@ export class soundboardConfigForm extends FormApplication {
//this.soundData = {};
this.playlists = [];
this.updatePlaylist = false;
this.update = false;
this.iMax;
this.jMax;
}
/**
@@ -251,6 +324,10 @@ export class soundboardConfigForm extends FormApplication {
* Provide data to the template
*/
getData() {
if (this.update) {
this.update=false;
return {soundData: this.data};
}
let selectedSounds = game.settings.get(MODULE.moduleName,'soundboardSettings').sounds;
let colorOn = game.settings.get(MODULE.moduleName,'soundboardSettings').colorOn;
let colorOff = game.settings.get(MODULE.moduleName,'soundboardSettings').colorOff;
@@ -279,29 +356,25 @@ export class soundboardConfigForm extends FormApplication {
let soundData = [];
let streamDeckModel = game.settings.get(MODULE.moduleName,'streamDeckModel');
let iMax,jMax;
if (streamDeckModel == 0){
jMax = 6;
iMax = 3;
this.jMax = 6;
this.iMax = 3;
}
else if (streamDeckModel == 1){
jMax = 6;
iMax = 5;
this.jMax = 6;
this.iMax = 5;
}
else {
jMax = 8;
iMax = 8;
this.jMax = 8;
this.iMax = 8;
}
if (this.updatePlaylist) selectedPlaylists = this.playlists;
else this.playlists = selectedPlaylists;
this.updatePlaylist = false;
let iteration = 0;
for (let j=0; j<jMax; j++){
for (let j=0; j<this.jMax; j++){
let soundsThis = [];
for (let i=0; i<iMax; i++){
for (let i=0; i<this.iMax; i++){
let selectedPlaylist;
let sounds = [];
if (volume == undefined) volume = 50;
@@ -343,8 +416,10 @@ export class soundboardConfigForm extends FormApplication {
};
soundData.push(data);
}
this.data = soundData;
return {
soundData: soundData
soundData: this.data
}
}
@@ -354,6 +429,7 @@ export class soundboardConfigForm extends FormApplication {
* @param {*} formData
*/
async _updateObject(event, formData) {
/*
let length = formData["sounds"].length;
let img = [];
let soundSrc = []
@@ -375,23 +451,160 @@ export class soundboardConfigForm extends FormApplication {
mode: formData["mode"],
img: img,
volume: formData["volume"],
name: formData["name"],
name: formData["namebox"],
src: soundSrc
});
*/
}
async activateListeners(html) {
super.activateListeners(html);
const nameField = html.find("input[name='namebox']");
const playlistSelect = html.find("select[name='playlist']");
const soundSelect = html.find("select[name='sounds']");
const soundFP = html.find("input[name2='soundSrc']");
const imgFP = html.find("input[name2='imgSrc']");
const onCP = html.find("input[name='colorOn']");
const offCP = html.find("input[name='colorOff']");
const playMode = html.find("select[name='mode']");
const volume = html.find("input[name='volume']");
nameField.on("change",event => {
let id = event.target.id.replace('name','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].name=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.name[id-1]=event.target.value;
this.updateSettings(settings);
});
if (playlistSelect.length > 0) {
playlistSelect.on("change", event => {
let id = event.target.id.replace('playlists','');
this.playlists[id-1] = event.target.value;
this.updatePlaylist = true;
this.render();
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].selectedPlaylist=event.target.value;
let selectedPlaylist;
let sounds = [];
if (event.target.value==undefined) selectedPlaylist = 'none';
else if (event.target.value == 'none') selectedPlaylist = 'none';
else if (event.target.value == 'FP') selectedPlaylist = 'FP';
else {
const pl = game.playlists.entities.find(p => p._id == event.target.value);
selectedPlaylist = pl._id;
sounds = pl.sounds;
}
this.data[j].dataThis[i].sounds=sounds;
let styleSS = "";
let styleFP ="display:none";
if (selectedPlaylist == 'FP') {
styleSS = 'display:none';
styleFP = ''
}
this.data[j].dataThis[i].styleSS=styleSS;
this.data[j].dataThis[i].styleFP=styleFP;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.selectedPlaylists[id-1]=event.target.value;
this.updateSettings(settings);
});
}
soundSelect.on("change", event => {
let id = event.target.id.replace('soundSelect','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].sound=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.sounds[id-1]=event.target.value;
this.updateSettings(settings);
});
soundFP.on("change",event => {
let id = event.target.id.replace('srcPath','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].srcPath=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.src[id-1]=event.target.value;
this.updateSettings(settings);
});
imgFP.on("change",event => {
let id = event.target.id.replace('imgPath','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].imgPath=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.img[id-1]=event.target.value;
this.updateSettings(settings);
});
onCP.on("change",event => {
let id = event.target.id.replace('colorOn','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].colorOn=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.colorOn[id-1]=event.target.value;
this.updateSettings(settings);
});
offCP.on("change",event => {
let id = event.target.id.replace('colorOff','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].colorOff=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.colorOff[id-1]=event.target.value;
this.updateSettings(settings);
});
playMode.on("change",event => {
let id = event.target.id.replace('playmode','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].mode=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.mode[id-1]=event.target.value;
this.updateSettings(settings);
});
volume.on("change",event => {
let id = event.target.id.replace('volume','');
let j = Math.floor(id/this.jMax);
let i = id % this.jMax-1;
this.data[j].dataThis[i].volume=event.target.value;
this.update = true;
let settings = game.settings.get(MODULE.moduleName,'soundboardSettings');
settings.volume[id-1]=event.target.value;
this.updateSettings(settings);
});
}
async updateSettings(settings){
await game.settings.set(MODULE.moduleName,'soundboardSettings',settings);
if (MODULE.enableModule) soundboard.updateAll();
this.render();
}
}

View File

@@ -136,21 +136,19 @@ export class PlaylistControl{
}
else {
let playing = game.playlists.playing;
console.log(playing);
let selectedPlaylists = game.settings.get(MODULE.moduleName,'selectedPlaylists');
console.log(selectedPlaylists);
let settings = game.settings.get(MODULE.moduleName,'playlists');
let selectedPlaylists = settings.selectedPlaylist;
for (let i=0; i<playing.length; i++){
const playlistNr = selectedPlaylists.findIndex(p => p == playing[i]._id);
const mode = game.settings.get(MODULE.moduleName,'selectedPlaylistMethod')[playlistNr];
const mode = settings.playlistMode[playlistNr];
if (mode == 0) playing[i].stopAll();
console.log(playlistNr,mode);
}
}
}
getPlaylist(num){
let playlistId = game.settings.get(MODULE.moduleName,'selectedPlaylists')[num];
let playlistId = game.settings.get(MODULE.moduleName,'playlists').selectedPlaylist[num];
return game.playlists.entities.find(p => p._id == playlistId);
}
@@ -202,9 +200,9 @@ export class PlaylistControl{
playlist.stopAll();
return;
}
let mode = game.settings.get(MODULE.moduleName,'selectedPlaylistMethod')[playlistNr];
let mode = game.settings.get(MODULE.moduleName,'playlists').playlistMode[playlistNr];
if (mode == 0) {
mode = game.settings.get(MODULE.moduleName,'playlistMethod');
mode = game.settings.get(MODULE.moduleName,'playlists').playMode;
if (mode == 2) await this.stopAll();
}
playlist.playAll();
@@ -216,10 +214,9 @@ export class PlaylistControl{
play = false;
else {
play = true;
let mode = game.settings.get(MODULE.moduleName,'selectedPlaylistMethod')[playlistNr];
console.log('mode',mode);
let mode = game.settings.get(MODULE.moduleName,'playlists').playlistMode[playlistNr];
if (mode == 0) {
mode = game.settings.get(MODULE.moduleName,'playlistMethod');
mode = game.settings.get(MODULE.moduleName,'playlists').playMode;
if (mode == 1) await playlist.stopAll();
else if (mode == 2) await this.stopAll();
}

View File

@@ -42,15 +42,6 @@ export const registerSettings = function() {
/**
* Playlist soundboard
*/
game.settings.register(MODULE.moduleName,'playlistMethod', {
name: "Playlist play method",
scope: "world",
config: false,
type:Number,
default:0,
choices:["MaterialDeck.Playlist.Playmethod.Unrestricted","MaterialDeck.Playlist.Playmethod.OneTrackPlaylist","MaterialDeck.Playlist.Playmethod.OneTrackTotal"],
});
game.settings.registerMenu(MODULE.moduleName, 'playlistConfigMenu',{
name: "MaterialDeck.Sett.PlaylistConfig",
label: "MaterialDeck.Sett.PlaylistConfig",
@@ -58,7 +49,7 @@ export const registerSettings = function() {
restricted: true
});
game.settings.register(MODULE.moduleName, 'selectedPlaylists', {
game.settings.register(MODULE.moduleName, 'playlists', {
name: "selectedPlaylists",
scope: "world",
type: Object,
@@ -66,22 +57,6 @@ export const registerSettings = function() {
config: false
});
game.settings.register(MODULE.moduleName, 'selectedPlaylistMethod', {
name: "selectedPlaylistMethod",
scope: "world",
type: Object,
default: {},
config: false
});
game.settings.register(MODULE.moduleName, 'numberOfPlaylists', {
name: "numberOfPlaylists",
scope: "world",
type: Number,
default: 9,
config: false
});
/**
* Macro Board
*/

View File

@@ -75,7 +75,10 @@ export class StreamDeck{
let txtArray = [];
let counter = 0;
for (let i=0; i<txtArrayOriginal.length; i++){
if (i>0){
txtArray[counter] = '';
counter++;
}
let txtArrayTemp = txtArrayOriginal[i].split(" ");
for (let j=0; j<txtArrayTemp.length; j++){
txtArray[counter] = txtArrayTemp[j];

View File

@@ -16,64 +16,128 @@ export class TokenControl{
}
pushData(tokenId,settings,context,ring=0,ringColor='#000000'){
console.log('token',settings);
let name = false;
let icon = false;
let type = 0;
let stats = settings.stats;
let background = "#000000";
if (settings.displayIcon) icon = true;
if (settings.displayName) name = true;
if (settings.stats != undefined) type = settings.stats;
if (stats == undefined) stats = 0;
if (settings.background) background = settings.background;
let system = settings.system;
if (system == undefined) system = 'dnd5e';
let tokenName = "";
let hp = "";
let AC = "";
let speed = "";
let initiative = "";
let txt = "";
let iconSrc = "";
if (tokenId != undefined) {
let token = canvas.tokens.children[0].children.find(p => p.id == tokenId);
tokenName = token.data.name;
if (name) txt += tokenName;
if (name && stats != 0) txt += "\n";
iconSrc += token.data.img;
let actor = canvas.tokens.children[0].children.find(p => p.id == tokenId).actor;
let system = game.system.id;
if (system == 'dnd5e'){
if (system == 'dnd5e' && game.system.id == 'dnd5e'){
let attributes = actor.data.data.attributes;
let hpCurrent = attributes.hp.value;
let hpMax = attributes.hp.max;
hp = hpCurrent + "/" + hpMax;
AC = attributes.ac.value;
if (attributes.speed._deprecated){
if (attributes.movement.burrow > 0) speed += attributes.movement.burrow + attributes.movement.units + " burrow";
if (attributes.movement.climb > 0) {
if (speed.length > 0) speed += '\n';
speed += attributes.movement.climb + attributes.movement.units + " climb";
if (stats == 'HP') txt += attributes.hp.value + "/" + attributes.hp.max;
else if (stats == 'TempHP') {
txt += attributes.hp.temp;
if (attributes.hp.tempmax != null)
txt += "/" + attributes.hp.tempmax;
}
else if (stats == 'AC') txt += attributes.ac.value;
else if (stats == 'Speed'){
let speed = "";
if (attributes.speed._deprecated){
if (attributes.movement.burrow > 0) speed += game.i18n.localize("DND5E.MovementBurrow") + ': ' + attributes.movement.burrow + attributes.movement.units;
if (attributes.movement.climb > 0) {
if (speed.length > 0) speed += '\n';
speed += game.i18n.localize("DND5E.MovementClimb") + ': ' + attributes.movement.climb + attributes.movement.units;
}
if (attributes.movement.fly > 0) {
if (speed.length > 0) speed += '\n';
speed += game.i18n.localize("DND5E.MovementFly") + ': ' + attributes.movement.fly + attributes.movement.units;
}
if (attributes.movement.hover > 0) {
if (speed.length > 0) speed += '\n';
speed += game.i18n.localize("DND5E.MovementHover") + ': ' + attributes.movement.hover + attributes.movement.units;
}
if (attributes.movement.swim > 0) {
if (speed.length > 0) speed += '\n';
speed += game.i18n.localize("DND5E.MovementSwim") + ': ' + attributes.movement.swim + attributes.movement.units;
}
if (attributes.movement.walk > 0) {
if (speed.length > 0) speed += '\n';
speed += game.i18n.localize("DND5E.MovementWalk") + ': ' + attributes.movement.walk + attributes.movement.units;
}
}
if (attributes.movement.fly > 0) {
if (speed.length > 0) speed += '\n';
speed += attributes.movement.fly + attributes.movement.units + " fly";
else {
speed = attributes.speed.value;
if (attributes.speed.special.length > 0) speed + "\n" + attributes.speed.special;
}
if (attributes.movement.hover > 0) {
txt += speed;
}
else if (stats == 'Init') txt += attributes.init.total;
else if (stats == 'PassivePerception') txt += actor.data.data.skills.prc.passive;
else if (stats == 'PassiveInvestigation') txt += actor.data.data.skills.inv.passive;
}
else if (system == 'dnd3.5e' && game.system.id == 'D35E'){
let attributes = actor.data.data.attributes;
if (stats == 'HP') txt += attributes.hp.value + "/" + attributes.hp.max;
else if (stats == 'TempHP') {
if (attributes.hp.temp == null) txt += '0';
else txt += attributes.hp.temp;
}
else if (stats == 'AC') txt += attributes.ac.normal.total;
else if (stats == 'Speed'){
let speed = "";
if (attributes.speed.burrow.total > 0) speed += 'Burrow: ' + attributes.speed.burrow.total + 'Ft';
if (attributes.speed.climb.total > 0) {
if (speed.length > 0) speed += '\n';
speed += attributes.movement.hover + attributes.movement.units + " hover";
speed += 'Climb: ' + attributes.speed.climb.total + 'Ft';
}
if (attributes.movement.swim > 0) {
if (attributes.speed.fly.total > 0) {
if (speed.length > 0) speed += '\n';
speed += attributes.movement.swim + attributes.movement.units + " swim";
speed += 'Fly: ' + attributes.speed.fly.total + 'Ft';
}
if (attributes.movement.walk > 0) {
if (attributes.speed.land.total > 0) {
if (speed.length > 0) speed += '\n';
speed += attributes.movement.walk + attributes.movement.units + " walk";
speed += 'Land: ' + attributes.speed.land.total + 'Ft';
}
if (attributes.speed.swim.total > 0) {
if (speed.length > 0) speed += '\n';
speed += 'Swim: ' + attributes.speed.swim.total + 'Ft';
}
txt += speed;
}
else if (stats == 'Init') txt += attributes.init.total;
}
else if (system == 'pf2e' && game.system.id == 'pf2e'){
let attributes = actor.data.data.attributes;
if (stats == 'HP') txt += attributes.hp.value + "/" + attributes.hp.max;
else if (stats == 'TempHP') {
if (attributes.hp.temp == null) txt += '0';
else {
txt += attributes.hp.temp;
if (attributes.hp.tempmax > 0) txt += '/' + attributes.hp.tempmax;
}
}
else {
speed = attributes.speed.value;
if (attributes.speed.special.length > 0) speed + "\n" + attributes.speed.special;
else if (stats == 'AC') txt += attributes.ac.value;
else if (stats == 'Speed'){
let speed = "Land: " + attributes.speed.value.replace('feet','') + ' feet';
const otherSpeeds = attributes.speed.otherSpeeds;
if (otherSpeeds.length > 0)
for (let i=0; i<otherSpeeds.length; i++)
speed += '\n' + otherSpeeds[i].type + ": " + otherSpeeds[i].value;
txt += speed;
}
else if (stats == 'Init') {
let init = attributes.initiative.totalModifier;
if (init != undefined) txt += init;
}
initiative = attributes.init.total;
}
else {
//Other systems
@@ -82,6 +146,7 @@ export class TokenControl{
}
if (settings.onClick == 4) { //toggle visibility
ring = 1;
if (token.data.hidden){
@@ -119,18 +184,29 @@ export class TokenControl{
ring = 1;
let condition = settings.condition;
if (condition == undefined) condition = 0;
if (condition == 0 && icon == false){
iconSrc = window.CONFIG.controlIcons.effects;
}
else if (icon == false) {
let effect = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition));
iconSrc = effect.icon;
let effects = token.actor.effects.entries;
let active = effects.find(e => e.isTemporary === this.getStatusId(condition));
if (active != undefined){
ring = 2;
ringColor = "#FF7B00";
if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E')){
let effect = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition));
iconSrc = effect.icon;
let effects = token.actor.effects.entries;
let active = effects.find(e => e.isTemporary === this.getStatusId(condition));
if (active != undefined){
ring = 2;
ringColor = "#FF7B00";
}
}
else if (system == 'pf2e' && game.system.id == 'pf2e') {
let effects = token.data.effects;
for (let i=0; i<effects.length; i++){
if (CONFIG.statusEffects[condition-1] == effects[i]){
ring = 2;
ringColor = "#FF7B00";
}
}
iconSrc = CONFIG.statusEffects[condition-1];
}
}
streamDeck.setIcon(1,context,iconSrc,background,ring,ringColor,true);
@@ -164,19 +240,16 @@ export class TokenControl{
iconSrc = window.CONFIG.controlIcons.effects;
}
else if (icon == false) {
iconSrc = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition)).icon;
if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E'))
iconSrc = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition)).icon;
else if (system == 'pf2e' && game.system.id == 'pf2e')
iconSrc = CONFIG.statusEffects[condition-1];
}
streamDeck.setIcon(1,context,iconSrc,background,1,'#000000',true);
}
}
if (icon) streamDeck.setIcon(1,context,iconSrc,background,ring,ringColor);
if (name) txt += tokenName;
if (name && type > 0) txt += "\n";
if (type == 1) txt += hp;
else if (type == 2) txt += AC;
else if (type == 3) txt += speed;
else if (type == 4) txt += initiative;
streamDeck.setTitle(txt,context);
}
@@ -190,6 +263,9 @@ export class TokenControl{
const token = canvas.tokens.children[0].children.find(p => p.id == tokenId);
if (token == undefined) return;
let system = settings.system;
if (system == undefined) system = 'dnd5e';
if (onClick == 0) //Do nothing
return;
else if (onClick == 1){ //center on token
@@ -218,12 +294,20 @@ export class TokenControl{
if (condition == 0){
const effects = token.actor.effects.entries;
for (let i=0; i<effects.length; i++){
const effect = CONFIG.statusEffects.find(e => e.icon === effects[i].data.icon);
let effect;
if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E'))
effect = CONFIG.statusEffects.find(e => e.icon === effects[i].data.icon);
else if (system == 'pf2e' && game.system.id == 'pf2e')
effect = CONFIG.statusEffects[condition-1];
await token.toggleEffect(effect)
}
}
else {
const effect = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition));
let effect;
if ((system == 'dnd5e' && game.system.id == 'dnd5e') || (system == 'dnd3.5e' && game.system.id == 'D35E'))
effect = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition));
else if (system == 'pf2e' && game.system.id == 'pf2e')
effect = CONFIG.statusEffects[condition-1];
token.toggleEffect(effect);
}

View File

@@ -16,7 +16,7 @@
{{localize "MaterialDeck.Macro"}} {{this.iteration}}
</div>
<div>
<select name="macros" class="macros-select" default="" style="max-width:140px;">
<select name="macros" class="macros-select" id="macros{{this.iteration}}" default="" style="max-width:140px;">
{{#select this.macro}}
<option value="">{{localize "MaterialDeck.None"}}</option>
{{#each macros}}
@@ -27,19 +27,15 @@
</div>
{{#if this.furnace}}
<label>{{localize "MaterialDeck.FurnaceArgs"}}</label>
<input type="text" name="args" value="{{this.args}}">
<input type="text" name="args" id="args{{this.iteration}}" value="{{this.args}}">
{{/if}}
<div class="flex-container" style="display:flex;flex-direction:row;padding-top:10px">
<label style="flex:1">{{localize "MaterialDeck.Background"}}</label>
<input style="flex:1" type="color" name="colorPicker" data-dtype="String" value="{{this.color}}">
<input style="flex:1" type="color" name="colorPicker" id="colorpicker{{this.iteration}}" data-dtype="String" value="{{this.color}}">
</div>
</div>
{{/each}}
</div>
{{/each}}
<button type="submit" name="submit">
<i class="far fa-save"></i> {{localize "MaterialDeck.Save"}}
</button>
</form>

View File

@@ -4,8 +4,8 @@
</div>
<div class="form-group">
<label>{{localize "MaterialDeck.PL.Mode"}}</label>
<select name="playMethod" class="playMethod" default="">
{{#select playMethod}}
<select name="playMode" class="playMode" default="">
{{#select playMode}}
<option value="0">{{localize "MaterialDeck.PL.Unrestricted"}}</option>
<option value="1">{{localize "MaterialDeck.PL.OneTrackPlaylist"}}</option>
<option value="2">{{localize "MaterialDeck.PL.OneTrackTotal"}}</option>
@@ -22,7 +22,7 @@
{{#each playlistData}}
<div class="form-group">
<label>{{localize "MaterialDeck.Playlist"}} {{this.iteration}}</label>
<select name="selectedPlaylist" class="playlist-select" default="">
<select name="selectedPlaylist" class="playlist-select" id="playlist{{this.iteration}}" default="">
{{#select this.playlist}}
<option value="">{{localize "MaterialDeck.None"}}</option>
{{#each this.playlists}}
@@ -31,8 +31,8 @@
{{/select}}
</select>
&nbsp;
<select name="playlistMethod" class="playlistMethod" default="">
{{#select this.playlistMethod}}
<select name="playlistMode" class="playlistMode" id="playlistMode{{this.iteration}}" default="">
{{#select this.playlistMode}}
<option value="0">{{localize "MaterialDeck.PL.Mode"}}</option>
<option value="1">{{localize "MaterialDeck.PL.Unrestricted"}}</option>
<option value="2">{{localize "MaterialDeck.PL.OneTrack"}}</option>
@@ -40,9 +40,4 @@
</select>
</div>
{{/each}}
<button type="submit" name="submit">
<i class="far fa-save"></i> {{localize "MaterialDeck.Save"}}
</button>
</form>

View File

@@ -18,7 +18,7 @@
<div style="text-align:center;">
{{localize "MaterialDeck.Name"}}
</div>
<input type="text" name="name" value="{{this.name}}">
<input type="text" name="namebox" value="{{this.name}}" id="name{{this.iteration}}">
<div style="text-align:center;">
{{localize "MaterialDeck.Playlist"}}
@@ -50,7 +50,7 @@
<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>
</button>
<input class="image" type="text" name="src{{this.iteration}}" id="srcPath{{this.iteration}}" placeholder="path/audio.mp3" value={{this.srcPath}}>
<input class="image" type="text" name="src{{this.iteration}}" name2="soundSrc" id="srcPath{{this.iteration}}" placeholder="path/audio.mp3" value={{this.srcPath}}>
</div>
<div style="text-align:center;">
{{localize "MaterialDeck.Icon"}}
@@ -59,7 +59,7 @@
<button type="button" class="file-picker" data-type="image" data-target="img{{this.iteration}}" title="Browse Files" tabindex="-1">
<i class="fas fa-file-import fa-fw"></i>
</button>
<input class="image" type="text" name="img{{this.iteration}}" id="imgPath{{this.iteration}}" placeholder="path/image.png" value={{this.imgPath}}>
<input class="image" type="text" name="img{{this.iteration}}" name2="imgSrc" id="imgPath{{this.iteration}}" placeholder="path/image.png" value={{this.imgPath}}>
</div>
<div class="flex-container" style="display:flex;flex-direction:row;padding-top:5px">
<label style="flex:1">{{localize "MaterialDeck.On"}}&nbsp;&nbsp;&nbsp;</label>
@@ -70,7 +70,7 @@
<div class="form-group options">
<label>{{localize "MaterialDeck.Playback"}}</label>
<select name="mode" style="flex:1">
<select name="mode" id="playmode{{this.iteration}}" style="flex:1">
{{#select this.mode}}
<option value="0">{{localize "MaterialDeck.Once"}}</option>
<option value="1">{{localize "MaterialDeck.Repeat"}}</option>
@@ -87,8 +87,4 @@
{{/each}}
</div>
{{/each}}
<button type="submit" name="submit">
<i class="far fa-save"></i> {{localize "MaterialDeck.Save"}}
</button>
</form>