This commit is contained in:
CDeenen
2020-11-17 06:47:30 +01:00
parent 92f4db9e73
commit d1c059df7d
16 changed files with 401 additions and 110 deletions

View File

@@ -3,11 +3,12 @@ import {streamDeck, tokenControl} from "../MaterialDeck.js";
export class CombatTracker{
constructor(){
this.active = false;
this.combatantLength = 0;
}
async updateAll(){
if (this.active == false) return;
for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'combattracker') continue;
@@ -16,6 +17,7 @@ export class CombatTracker{
}
update(settings,context){
this.active = true;
let ctFunction = settings.combatTrackerFunction;
if (ctFunction == undefined) ctFunction == 0;

View File

@@ -3,10 +3,12 @@ import {streamDeck} from "../MaterialDeck.js";
export class MacroControl{
constructor(){
this.active = false;
this.offset = 0;
}
async updateAll(){
if (this.active == false) return;
for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'macro') continue;
@@ -15,10 +17,13 @@ export class MacroControl{
}
update(settings,context){
this.active = true;
let mode = settings.macroMode;
let displayName = settings.displayName;
let macroNumber = settings.macroNumber;
let background = settings.background;
let icon = false;
if (settings.displayIcon) icon = true;
let ringColor = "#000000";
let ring = 0;
if(macroNumber == undefined || isNaN(parseInt(macroNumber))){
@@ -53,15 +58,15 @@ export class MacroControl{
src += macro.img;
}
}
streamDeck.setIcon(1,context,src,background);
if (icon) streamDeck.setIcon(1,context,src,background);
else streamDeck.setIcon(0, context, "", background);
if (displayName == 0) name = "";
streamDeck.setTitle(name,context);
}
else {
else { //Macro board
let name = "";
let src = '';
if (settings.macroBoardMode == 0) {
if (settings.macroBoardMode == 0) { //Execute macro
macroNumber += this.offset - 1;
if (macroNumber < 0) macroNumber = 0;
var macroId = game.settings.get(MODULE.moduleName,'macroSettings').macros[macroNumber];
@@ -76,8 +81,8 @@ export class MacroControl{
src += macro.img;
}
}
}
else {
}
else { //Offset
let ringOffColor = settings.offRing;
if (ringOffColor == undefined) ringOffColor = '#000000';
@@ -92,7 +97,8 @@ export class MacroControl{
ring = 2;
}
streamDeck.setIcon(1, context,src,background,ring,ringColor);
if (icon) streamDeck.setIcon(1, context,src,background,ring,ringColor);
else streamDeck.setIcon(0, context, "", background,ring,ringColor);
if (displayName == 0) name = "";
streamDeck.setTitle(name,context);
}

View File

@@ -2,22 +2,37 @@ import * as MODULE from "../MaterialDeck.js";
export class Move{
constructor(){
this.active = false;
}
keyPress(settings){
console.log('move',settings)
let dir = settings.dir;
let mode = settings.mode;
if (mode == undefined) mode = 0;
if (dir == undefined) dir = 0;
if (settings.mode == '1')
this.moveToken(MODULE.selectedTokenId,dir);
else
this.moveCanvas(dir);
if (dir < 9){
if (settings.mode == '1')
this.moveToken(MODULE.selectedTokenId,dir);
else
this.moveCanvas(dir);
}
else if (dir == 9) {//zoom in
let viewPosition = canvas.scene._viewPosition;
viewPosition.scale = viewPosition.scale*1.05;
viewPosition.duration = 100;
canvas.animatePan(viewPosition);
}
else if (dir == 10) {//zoom out
let viewPosition = canvas.scene._viewPosition;
viewPosition.scale = viewPosition.scale*0.95;
viewPosition.duration = 100;
canvas.animatePan(viewPosition);
}
}
async moveToken(tokenId,dir){
if (tokenId == undefined) return;
const token = canvas.tokens.children[0].children.find(p => p.id == tokenId);
const gridSize = canvas.scene.data.grid;
let x = token.x;

View File

@@ -3,10 +3,12 @@ import {streamDeck} from "../MaterialDeck.js";
export class OtherControls{
constructor(){
this.active = false;
this.offset = 0;
}
async updateAll(){
if (this.active == false) return;
for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'other') continue;
@@ -15,6 +17,7 @@ export class OtherControls{
}
update(settings,context){
this.active = true;
let mode = settings.otherMode;
if (mode == undefined) mode = 0;
@@ -312,8 +315,10 @@ export class OtherControls{
if (selectedControl != undefined){
const selectedTool = selectedControl.tools[controlNr];
if (selectedTool != undefined){
if (selectedTool.toggle)
if (selectedTool.toggle) {
selectedTool.active = !selectedTool.active;
selectedTool.onClick(selectedTool.active);
}
else if (selectedTool.button){
selectedTool.onClick();
}
@@ -335,8 +340,10 @@ export class OtherControls{
if (selectedTool != undefined){
ui.controls.activeControl = controlName;
canvas.getLayer(selectedControl.layer).activate();
if (selectedTool.toggle)
if (selectedTool.toggle) {
selectedTool.active = !selectedTool.active;
selectedTool.onClick(selectedTool.active);
}
else if (selectedTool.button){
selectedTool.onClick();
}

View File

@@ -3,11 +3,13 @@ import {streamDeck} from "../MaterialDeck.js";
export class PlaylistControl{
constructor(){
this.active = false;
this.playlistOffset = 0;
this.trackOffset = 0;
}
async updateAll(){
if (this.active == false) return;
for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'playlist') continue;
@@ -16,6 +18,7 @@ export class PlaylistControl{
}
update(settings,context){
this.active = true;
if (settings.playlistMode == undefined) settings.playlistMode = 0;
if (settings.playlistMode == 0){
this.updatePlaylist(settings,context);

View File

@@ -17,13 +17,13 @@ export const registerSettings = function() {
});
game.settings.register(MODULE.moduleName,'streamDeckModel', {
name: "Stream Deck Model",
hint: "Reduces the amount of macros and sounds in the macro and soundboard configuration screens. Gives a better overview, but if desired it can be set to XL to get the maximum number. This doesn't influence the operation of the module.",
name: "MaterialDeck.Sett.Model",
hint: "MaterialDeck.Sett.Model_Hint",
scope: "world",
config: true,
type:Number,
default:1,
choices:["Mini","Normal or Mobile","XL"],
choices:["MaterialDeck.Sett.Model_Mini","MaterialDeck.Sett.Model_Normal","MaterialDeck.Sett.Model_XL"],
});
/**
@@ -35,12 +35,12 @@ export const registerSettings = function() {
config: false,
type:Number,
default:0,
choices:["Default","One track per playlist","One track in total"],
choices:["MaterialDeck.Playlist.Playmethod.Unrestricted","MaterialDeck.Playlist.Playmethod.OneTrackPlaylist","MaterialDeck.Playlist.Playmethod.OneTrackTotal"],
});
game.settings.registerMenu(MODULE.moduleName, 'playlistConfigMenu',{
name: "Playlist Configuration",
label: "Playlist Configuration",
name: "MaterialDeck.Sett.PlaylistConfig",
label: "MaterialDeck.Sett.PlaylistConfig",
type: playlistConfigForm,
restricted: true
});

View File

@@ -3,6 +3,7 @@ import {streamDeck} from "../MaterialDeck.js";
export class SoundboardControl{
constructor(){
this.active = false;
this.offset = 0;
this.activeSounds = [];
for (let i=0; i<64; i++)
@@ -10,6 +11,7 @@ export class SoundboardControl{
}
async updateAll(){
if (this.active == false) return;
for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'soundboard') continue;
@@ -18,6 +20,7 @@ export class SoundboardControl{
}
update(settings,context){
this.active = true;
let mode = settings.soundboardMode;
if (mode == undefined) mode = 0;

View File

@@ -23,6 +23,8 @@ export class StreamDeck{
let canvasBox = document.createElement('div');
canvasBox.id = 'sdCanvasBox';
document.body.appendChild(canvasBox); // adds the canvas to the body element
this.syllableRegex = /[^aeiouy]*[aeiouy]+(?:[^aeiouy]*$|[^aeiouy](?=[^aeiouy]))?/gi;
}
setScreen(action){
@@ -42,20 +44,90 @@ export class StreamDeck{
clearContext(action,coordinates = {column:0,row:0}){
let num = coordinates.column + coordinates.row*8;
this.buttonContext[num] = undefined;
if (this.getActive(action) == false){
if (action == 'token') MODULE.tokenControl.active = false;
else if (action == 'macro') MODULE.macroControl.active = false;
else if (action == 'combattracker') MODULE.combatTracker.active = false;
else if (action == 'playlist') MODULE.playlistControl.active = false;
else if (action == 'soundboard') MODULE.soundboard.active = false;
else if (action == 'other') MODULE.otherControls.active = false;
}
}
getActive(action){
for (let i=0; i<this.buttonContext.length; i++){
if (this.buttonContext[i] != undefined && this.buttonContext[i].action == action)
return true;
}
return false;
}
/*
* Get syllables of a word. Taken from: https://stackoverflow.com/a/49407494
*/
syllabify(words) {
return words.match(this.syllableRegex);
}
formatTitle(txt){
let txtArray = txt.split(" ");
let txtNew = "";
for (let i=0; i<txtArray.length; i++){
let txtNewPart = txtArray[i];
if (i<txtArray.length-1 && txtArray[i].length + txtArray[i+1].length < 8) {
txtNewPart = txtArray[i] + " " + txtArray[i+1];
i++;
let txtArrayOriginal = txt.split("\n");
let txtArray = [];
let counter = 0;
for (let i=0; i<txtArrayOriginal.length; i++){
let txtArrayTemp = txtArrayOriginal[i].split(" ");
for (let j=0; j<txtArrayTemp.length; j++){
txtArray[counter] = txtArrayTemp[j];
counter++;
}
}
let txtNew = "";
let newTxtArray = ['','','','','','','','','','','','','','','','','','','',''];
counter = 0;
for (let i=0; i<txtArray.length; i++){
let txtNewPart = txtArray[i];
if (txtNewPart != undefined && txtNewPart.length > 10){
let syllables = this.syllabify(txtNewPart);
for (let j=0; j<syllables.length; j++){
if (syllables.length == 0){
newTxtArray[counter] = txtNewPart;
counter++;
}
else if (syllables[j+1] == undefined){
newTxtArray[counter] = syllables[j];
counter++;
}
else if ((syllables[j].length+syllables[j+1].length) < 10){
newTxtArray[counter] = syllables[j]+syllables[j+1];
if (syllables.length-2 > j) newTxtArray[counter] += '-';
counter++;
j++;
}
else {
newTxtArray[counter] = syllables[j];
if (syllables.length > j) newTxtArray[counter] += '-';
counter++;
}
}
}
else{
newTxtArray[counter] = txtNewPart;
counter++;
}
}
for (let i=0; i<counter; i++){
if (txtNew.length > 0)
txtNew += "\n";
txtNew += txtNewPart;
if (i<counter-1 && newTxtArray[i].length + newTxtArray[i+1].length < 10) {
txtNew += newTxtArray[i] + " " + newTxtArray[i+1];
i++;
}
else
txtNew += newTxtArray[i];
}
return txtNew;
}
@@ -107,7 +179,7 @@ export class StreamDeck{
MODULE.sendWS(JSON.stringify(json));
}
setIcon(iconLocation, context,src,background = '#000000',ring=0,ringColor = "#000000"){
setIcon(iconLocation, context,src,background = '#000000',ring=0,ringColor = "#000000",overlay=false){
for (let i=0; i<32; i++){
if (this.buttonContext[i] == undefined) continue;
if (this.buttonContext[i].context == context) {
@@ -120,11 +192,11 @@ export class StreamDeck{
this.buttonContext[i].iconLocation = iconLocation;
}
}
let split = src.split('?');
split = split[0].split('.');
let format = split[split.length-1];
split = src.split(' ');
let split = src.split('.');
//filter out stuff from Tokenizer
let format = split[split.length-1].split('?')[0];
split = split[0].split(' ');
if (split[0] == 'fas' || split[0] == 'far' || split[0] == 'fal' || split[0] == 'fad') format = 'icon';
let msg = {
event: 'setIcon',
@@ -133,7 +205,8 @@ export class StreamDeck{
format: format,
background: background,
ring: ring,
ringColor: ringColor
ringColor: ringColor,
overlay: overlay
};
if (iconLocation == 0){
MODULE.sendWS(JSON.stringify(msg));
@@ -257,8 +330,10 @@ export class StreamDeck{
let resImageURL = url;
let img = new Image();
img.setAttribute('crossorigin', 'anonymous');
img.onload = () => {
if (format == 'color') ctx.filter = "opacity(0)";
if (data.overlay) ctx.filter = "brightness(60%)";
//ctx.filter = "brightness(0) saturate(100%) invert(38%) sepia(62%) saturate(2063%) hue-rotate(209deg) brightness(90%) contrast(95%)";
var imageAspectRatio = img.width / img.height;
var canvasAspectRatio = canvas.width / canvas.height;

View File

@@ -3,9 +3,11 @@ import {streamDeck} from "../MaterialDeck.js";
export class TokenControl{
constructor(){
this.active = false;
}
async update(tokenId){
if (this.active == false) return;
for (let i=0; i<32; i++){
let data = streamDeck.buttonContext[i];
if (data == undefined || data.action != 'token') continue;
@@ -73,10 +75,99 @@ export class TokenControl{
}
initiative = attributes.init.total;
}
else return;
else {
//Other systems
}
if (settings.onClick == 4) { //toggle visibility
ring = 1;
if (token.data.hidden){
ring = 2;
ringColor = "#FF7B00";
}
if (icon == false) {
iconSrc = window.CONFIG.controlIcons.visibility;
streamDeck.setIcon(1,context,iconSrc,background,ring,ringColor,true);
}
}
else if (settings.onClick == 5) { //toggle combat state
ring = 1;
if (token.inCombat){
ring = 2;
ringColor = "#FF7B00";
}
if (icon == false) {
iconSrc = window.CONFIG.controlIcons.combat;
streamDeck.setIcon(1,context,iconSrc,background,ring,ringColor,true);
}
}
else if (settings.onClick == 6) { //target token
ring = 1;
if (token.isTargeted){
ring = 2;
ringColor = "#FF7B00";
}
if (icon == false) {
iconSrc = "fas fa-bullseye";
streamDeck.setIcon(1,context,iconSrc,background,ring,ringColor);
}
}
else if (settings.onClick == 7) { //toggle condition
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";
}
}
streamDeck.setIcon(1,context,iconSrc,background,ring,ringColor,true);
}
}
else {
iconSrc += "";
if (settings.onClick == 4) { //toggle visibility
if (icon == false) {
iconSrc = window.CONFIG.controlIcons.visibility;
streamDeck.setIcon(1,context,iconSrc,background,1,'#000000',true);
}
}
else if (settings.onClick == 5) { //toggle combat state
if (icon == false) {
iconSrc = window.CONFIG.controlIcons.combat;
streamDeck.setIcon(1,context,iconSrc,background,1,'#000000',true);
}
}
else if (settings.onClick == 6) { //target token
if (icon == false) {
iconSrc = "fas fa-bullseye";
streamDeck.setIcon(1,context,iconSrc,background,1,'#000000');
}
}
else if (settings.onClick == 7) { //toggle condition
let condition = settings.condition;
if (condition == undefined) condition = 0;
if (condition == 0 && icon == false){
iconSrc = window.CONFIG.controlIcons.effects;
}
else if (icon == false) {
iconSrc = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition)).icon;
}
streamDeck.setIcon(1,context,iconSrc,background,1,'#000000',true);
}
}
if (icon) streamDeck.setIcon(1,context,iconSrc,background,ring,ringColor);
@@ -89,7 +180,7 @@ export class TokenControl{
streamDeck.setTitle(txt,context);
}
keyPress(settings){
async keyPress(settings){
if (MODULE.selectedTokenId == undefined) return;
const tokenId = MODULE.selectedTokenId;
@@ -108,8 +199,72 @@ export class TokenControl{
else if (onClick == 2){ //Open character sheet
token.actor.sheet.render(true);
}
else { //Open token config
else if (onClick == 3) { //Open token config
token.sheet._render(true);
}
else if (onClick == 4) { //Toggle visibility
token.toggleVisibility();
}
else if (onClick == 5) { //Toggle combat state
token.toggleCombat();
}
else if (onClick == 6) { //Target token
token.setTarget(!token.isTargeted,{releaseOthers:false});
}
else if (onClick == 7) { //Toggle condition
let condition = settings.condition;
if (condition == undefined) condition = 0;
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);
await token.toggleEffect(effect)
}
}
else {
const effect = CONFIG.statusEffects.find(e => e.id === this.getStatusId(condition));
token.toggleEffect(effect);
}
}
}
getStatusId(nr){
let id;
if (nr == 1) id = 'dead';
else if (nr == 2) id = 'unconscious';
else if (nr == 3) id = 'sleep';
else if (nr == 4) id = 'stun';
else if (nr == 5) id = 'prone';
else if (nr == 6) id = 'restrain';
else if (nr == 7) id = 'paralysis';
else if (nr == 8) id = 'fly';
else if (nr == 9) id = 'bind';
else if (nr == 10) id = 'deaf';
else if (nr == 11) id = 'silence';
else if (nr == 12) id = 'fear';
else if (nr == 13) id = 'burning';
else if (nr == 14) id = 'frozen';
else if (nr == 15) id = 'shock';
else if (nr == 16) id = 'corrode';
else if (nr == 17) id = 'bleeding';
else if (nr == 18) id = 'disease';
else if (nr == 19) id = 'poison';
else if (nr == 20) id = 'radiation';
else if (nr == 21) id = 'regen';
else if (nr == 22) id = 'degen';
else if (nr == 23) id = 'upgrade';
else if (nr == 24) id = 'downgrade';
else if (nr == 25) id = 'target';
else if (nr == 26) id = 'eye';
else if (nr == 27) id = 'curse';
else if (nr == 28) id = 'bless';
else if (nr == 29) id = 'fireShield';
else if (nr == 30) id = 'coldShield';
else if (nr == 31) id = 'magicShield';
else if (nr == 32) id = 'holyShield';
return id;
}
}