diff --git a/MaterialDeck.js b/MaterialDeck.js
index 6b53492..bd9c508 100644
--- a/MaterialDeck.js
+++ b/MaterialDeck.js
@@ -1,7 +1,6 @@
import {registerSettings} from "./src/settings.js";
import {StreamDeck} from "./src/streamDeck.js";
import {TokenControl} from "./src/token.js";
-import {Move} from "./src/move.js";
import {MacroControl} from "./src/macro.js";
import {CombatTracker} from "./src/combattracker.js";
import {PlaylistControl} from "./src/playlist.js";
@@ -9,10 +8,10 @@ import {SoundboardControl} from "./src/soundboard.js";
import {OtherControls} from "./src/othercontrols.js";
import {ExternalModules} from "./src/external.js";
import {SceneControl} from "./src/scene.js";
-import {compatibleCore} from "./src/misc.js";
+import {downloadUtility, compatibleCore} from "./src/misc.js";
+import {TokenHelper} from "./src/systems/tokenHelper.js";
export var streamDeck;
export var tokenControl;
-var move;
export var macroControl;
export var combatTracker;
export var playlistControl;
@@ -20,16 +19,19 @@ export var soundboard;
export var otherControls;
export var externalModules;
export var sceneControl;
+export var tokenHelper;
export const moduleName = "MaterialDeck";
let ready = false;
-let activeSounds = [];
export let hotbarUses = false;
export let calculateHotbarUses;
let controlTokenTimer;
+
+export let sdVersion;
+export let msVersion;
//CONFIG.debug.hooks = true;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -71,18 +73,28 @@ async function analyzeWSmessage(msg){
}
if (data.type == "version" && data.source == "SD") {
- const minimumSDversion = game.modules.get("MaterialDeck").data.minimumSDversion.replace('v','');
- const minimumMSversion = game.modules.get("MaterialDeck").data.minimumMSversion;
+ let minimumSDversion;
+ let minimumMSversion;
+ if (compatibleCore("0.8.5")) {
+ minimumSDversion = game.modules.get("MaterialDeck").data.flags.minimumSDversion.replace('v','');
+ minimumMSversion = game.modules.get("MaterialDeck").data.flags.minimumMSversion;
+ }
+ else {
+ minimumSDversion = game.modules.get("MaterialDeck").data.minimumSDversion.replace('v','');
+ minimumMSversion = game.modules.get("MaterialDeck").data.minimumMSversion;
+ }
+
+ sdVersion = data.version;
if (data.version < minimumSDversion) {
let d = new Dialog({
title: "Material Deck: Update Needed",
- content: "
The Stream Deck plugin version you're using is v" + data.version + ", which is outdated. Update to v" + minimumSDversion + " or newer.
",
+ content: "
The Stream Deck plugin version you're using is v" + data.version + ", which is incompatible with this verion of the module. Update to v" + minimumSDversion + " or newer.
",
buttons: {
download: {
icon: '',
- label: "Update",
- callback: () => window.open("https://github.com/CDeenen/MaterialDeck_SD/releases")
+ label: "Download Utility",
+ callback: () => new downloadUtility()
},
ignore: {
icon: '',
@@ -117,8 +129,6 @@ async function analyzeWSmessage(msg){
tokenControl.active = true;
tokenControl.pushData(canvas.tokens.controlled[0]?.id,settings,context,device);
}
- else if (action == 'move')
- move.update(settings,context,device);
else if (action == 'macro')
macroControl.update(settings,context,device);
else if (action == 'combattracker')
@@ -143,8 +153,6 @@ async function analyzeWSmessage(msg){
else if (event == 'keyDown'){
if (action == 'token')
tokenControl.keyPress(settings);
- else if (action == 'move')
- move.keyPress(settings);
else if (action == 'macro')
macroControl.keyPress(settings);
else if (action == 'combattracker')
@@ -189,6 +197,7 @@ function startWebsocket() {
}
ws.onopen = function() {
+ messageCount = 0;
WSconnected = true;
ui.notifications.info("Material Deck "+game.i18n.localize("MaterialDeck.Notifications.Connected") +": "+address);
wsOpen = true;
@@ -210,13 +219,23 @@ function startWebsocket() {
clearInterval(wsInterval);
wsInterval = setInterval(resetWS, 10000);
}
-
+let messageCount = 0;
/**
* Try to reset the websocket if a connection is lost
*/
function resetWS(){
- if (wsOpen) ui.notifications.warn("Material Deck: "+game.i18n.localize("MaterialDeck.Notifications.Disconnected"));
- else ui.notifications.warn("Material Deck: "+game.i18n.localize("MaterialDeck.Notifications.ConnectFail"));
+ const maxMessages = game.settings.get(moduleName, 'nrOfConnMessages');
+ if (maxMessages == 0 || maxMessages > messageCount) {
+ messageCount++;
+ const countString = maxMessages == 0 ? "" : " (" + messageCount + "/" + maxMessages + ")";
+ if (wsOpen) {
+ ui.notifications.warn("Material Deck: "+game.i18n.localize("MaterialDeck.Notifications.Disconnected"));
+ wsOpen = false;
+ messageCount = 0;
+ }
+ else ui.notifications.warn("Material Deck: "+game.i18n.localize("MaterialDeck.Notifications.ConnectFail") + countString);
+ }
+
WSconnected = false;
startWebsocket();
}
@@ -255,17 +274,19 @@ export function getPermission(action,func) {
Hooks.once('ready', async()=>{
registerSettings();
enableModule = (game.settings.get(moduleName,'Enable')) ? true : false;
+
+
soundboard = new SoundboardControl();
streamDeck = new StreamDeck();
tokenControl = new TokenControl();
- move = new Move();
macroControl = new MacroControl();
combatTracker = new CombatTracker();
playlistControl = new PlaylistControl();
otherControls = new OtherControls();
externalModules = new ExternalModules();
sceneControl = new SceneControl();
+ tokenHelper = new TokenHelper();
game.socket.on(`module.MaterialDeck`, async(payload) =>{
//console.log(payload);
@@ -313,9 +334,6 @@ Hooks.once('ready', async()=>{
});
- for (let i=0; i<64; i++)
- activeSounds[i] = false;
-
if (game.user.isGM) {
let soundBoardSettings = game.settings.get(moduleName,'soundboardSettings');
let macroSettings = game.settings.get(moduleName, 'macroSettings');
@@ -425,6 +443,11 @@ Hooks.on('renderCombatTracker',()=>{
if (tokenControl != undefined) tokenControl.update(canvas.tokens.controlled[0]?.id);
});
+Hooks.on('renderActorSheet',()=>{
+ if (enableModule == false || ready == false) return;
+ if (tokenControl != undefined) tokenControl.update();
+});
+
Hooks.on('renderPlaylistDirectory', (playlistDirectory)=>{
if (enableModule == false || ready == false) return;
if (playlistControl != undefined) playlistControl.updateAll();
diff --git a/README.md b/README.md
index 80219ef..a0fdde6 100644
--- a/README.md
+++ b/README.md
@@ -31,11 +31,6 @@ The functions are categorized into actions. Here is a list of the available acti
Besides installing this module, you also need to install and run some other things.
Installing the Stream Deck Software and Plugin
+ YOu have to download and install the Stream Deck software.
+ You then need to install the plugin. There is a delay between when the plugin get's updated and the update being pushed in the store.
+ If you try to install the plugin right after an update, you might not have the latest version. Manual installation is better in that case.
+
+
Download the latest plugin file (com.cdeenen.materialdeck.streamDeckPlugin) from here
+
Open the Stream Deck application
+
Press 'More Actions' in the lower right
+
Search (top right) or scroll to find Material Deck
+
Press the 'Install' button
+
+
+
Manually
+
+
Download the latest plugin file using the download utility in the module settings, or download it (com.cdeenen.materialdeck.streamDeckPlugin) from here
Double-click the file, this should open the Stream Deck software
Press 'Install' in the pop-up
-
Installing the Stream Deck Profile (optional)
+
Installing a Stream Deck Profile (optional)
You can create your own profile, but it is recommended to start with one of the pre-made profiles. Currently, there is a profile for the normal and XL Stream Deck variants.
-
Download the latest profile (ending with .streamDeckProfile) from here
+
Download the latest plugin file using the download utility in the module settings, or download one (ending with .streamDeckProfile) from here
Double-click the file, this should load the profile into the Stream Deck software
@@ -55,6 +68,8 @@
There are four buttons at the top:
Help
+
User Permission Configuration
+
Download Utility
Playlist Configuration
Macro Configuration
Soundboard Configuration
@@ -63,10 +78,7 @@
Below the buttons you will find the following settings:
-
Enable Module - Ticking this box enabled the module
-
Stream Deck Model - Select the model of your Stream Deck. This is optional, as it only changes the amount of macros and sounds that
- you can assign in the macro and soundboard configuration screens. If you have a smaller Stream Deck, you might not want to
- have a screen filled with 64 macros, since you probably won't use that many (you can, if you want to, though)
+
Enable Module - Ticking this box enabled the module for the client
Material Server Address - Fill in the address of Material Server (usually if you run it on the same computer as
you're using for Foundry, this can be localhost:3001). This is not necessarily the IP address of Foundry! It is the IP
address of the computer that's running Material Server. The default value will work for 99% of people, only change it if
@@ -75,6 +87,7 @@
This improves the update speed, but increases memory usage.
Image Brightness - Sets the brightness of the default white images for better readibility of the text. If Image Cache Size is large, it'll take a while for
the new brightness setting to be applied. A refresh will give instantaneous results.
+
Number of Connection Warnings - Sets the number of times you will get a warning when Material Deck cannot connect to Material Server. Will be unlimited if set to 0.
@@ -89,6 +102,17 @@
+
Download Utility
+
+ The download utility allows you to easily check the current version of the Stream Deck plugin and Material Server, and gives you the option to download the latest version.
+ Please note that the current version of Material Server is at the moment not supported.
+
+ At the bottom you can also download the default profiles from Github
+
+ The refresh button at the bottom refreshes the page in case there was a connection issue.
+
+
+
Playlist Configuration
The playlist configuration screen configures the playlists that you control using the Playlist action.
@@ -119,10 +143,11 @@
Note: While you can assign the same playlist to multiple playlists in this configuration screen, only the play method of the first instance will be applied.
Macro Configuration
- The Macro Configuration screen is to configure the macro board for the Macro action.
+ The Macro Configuration screen is to configure the macroboard for the Macro action.
- The screen is divided into a number of boxes, each labeled 'Macro #', where each represents a single macro and its settings. The number of macros you can see
- depends on what Stream Deck model you've set up in the module configuration.
+ The screen is divided into 32 boxes, each labeled 'Macro #', where each represents a single macro and its settings. This screen will be refered to as a page.
+ By pressing the arrows at the top right and top left, you can go to the next or previous page. There is no limit to the amount of pages you can add, but if you
+ have a lot of pages, at some point you might notice some performance issues.
For each macro there are 3 options:
@@ -134,13 +159,25 @@
Background - Color picker to set the background color of the Stream Deck button
+
+ At the bottom you have the following buttons:
+
+
Clear Page - Clears all the macros on the current page. Please note that this is irreversible.
+
Clear All - Clears all the macros. Please note that this is irreversible.
+
Import - Import the macroboard from a file. This will override your current macroboard, and is irreversible.
+
Export - Export your macroboard to a file.
+
+ When importing and exporting, you only import/export the metadata, not the actual macros. This means that you need to have the same macros in both the source and target Foundry client,
+ or you might run into issues.
+
Soundboard Configuration
The Soundboard Configuration screen is used to configure the soundboard for the Soundboard action.
- Similar to the Macro Configuration screen, the screen is divided into a number of boxes, each labeled 'Sound #', where each represents a single sound and its settings.
- The number of sounds you can see depends on what Stream Deck model you've set up in the module configuration.
+ Similar to the Macro Configuration screen, the screen is divided into boxes, each labeled 'Sound #', where each represents a single sound and its settings. This screen will be refered to as a page.
+ By pressing the arrows at the top right and top left, you can go to the next or previous page. There is no limit to the amount of pages you can add, but if you
+ have a lot of pages, at some point you might notice some performance issues.
For each sound there are multiple options:
@@ -166,6 +203,17 @@
Volume - The playback volume of the sound. The final playback volume is also determined by the Interface Volume slider in Foundry's 'Audio Playlists' tab.
+
+ At the bottom you have the following buttons:
+
+
Clear Page - Clears all the sounds on the current page. Please note that this is irreversible.
+
Clear All - Clears all the sounds. Please note that this is irreversible.
+
Import - Import the soundboard from a file. This will override your current soundboard, and is irreversible.
+
Export - Export your soundboard to a file.
+
+ When importing and exporting, you only import/export the metadata, not the actual audio files. This means that you need to have the same audio files in the same relative location in both the source and target Foundry client,
+ or you might run into issues.
+
If you have any suggestions or bugs to report, feel free to create an issue, contact me on Discord (Cris#6864), or send me an email: cdeenen@outlook.com.
diff --git a/templates/importDialog.html b/templates/importDialog.html
new file mode 100644
index 0000000..f414570
--- /dev/null
+++ b/templates/importDialog.html
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/templates/macroConfig.html b/templates/macroConfig.html
index b67b6a6..ebe39dc 100644
--- a/templates/macroConfig.html
+++ b/templates/macroConfig.html
@@ -6,8 +6,25 @@
max-width: 166px;
height: {{height}}px;
}
+ .navigation {
+ flex:1;
+ max-width: 8%;
+ }
+
\ No newline at end of file
diff --git a/wiki/img/DownloadUtility.png b/wiki/img/DownloadUtility.png
new file mode 100644
index 0000000..ed9fb23
Binary files /dev/null and b/wiki/img/DownloadUtility.png differ
diff --git a/wiki/img/MacroConfig.png b/wiki/img/MacroConfig.png
index 949246d..0b6b0fd 100644
Binary files a/wiki/img/MacroConfig.png and b/wiki/img/MacroConfig.png differ
diff --git a/wiki/img/ModuleSettings.png b/wiki/img/ModuleSettings.png
index 12beed6..b6a1795 100644
Binary files a/wiki/img/ModuleSettings.png and b/wiki/img/ModuleSettings.png differ
diff --git a/wiki/img/SoundboardConfig.png b/wiki/img/SoundboardConfig.png
index 6c09587..acb600a 100644
Binary files a/wiki/img/SoundboardConfig.png and b/wiki/img/SoundboardConfig.png differ