This commit is contained in:
Cristian Deenen
2022-09-05 01:42:15 +02:00
parent 033a7351e4
commit 9a7088a310
40 changed files with 2161 additions and 1387 deletions

View File

@@ -1,6 +1,4 @@
import * as MODULE from "../MaterialDeck.js";
import {streamDeck, tokenControl} from "../MaterialDeck.js";
import {compatibleCore} from "./misc.js";
import { streamDeck, tokenControl, getPermission } from "../../MaterialDeck.js";
export class CombatTracker{
constructor(){
@@ -32,7 +30,7 @@ export class CombatTracker{
settings.icon = settings.displayIcon ? 'tokenIcon' : 'none';
if (mode == 'combatants'){
if (MODULE.getPermission('COMBAT','DISPLAY_COMBATANTS') == false) {
if (getPermission('COMBAT','DISPLAY_COMBATANTS') == false) {
streamDeck.noPermission(context,device,device,false,"combat tracker");
return;
}
@@ -44,7 +42,7 @@ export class CombatTracker{
const combatant = initiativeOrder[nr]
if (combatant != undefined){
const tokenId = compatibleCore("0.8.1") ? combatant.data.tokenId : combatant.tokenId;
const tokenId = combatant.data.tokenId;
tokenControl.pushData(tokenId,settings,context,device,combatantState,'#cccc00');
return;
}
@@ -59,12 +57,12 @@ export class CombatTracker{
}
}
else if (mode == 'currentCombatant'){
if (MODULE.getPermission('COMBAT','DISPLAY_COMBATANTS') == false) {
if (getPermission('COMBAT','DISPLAY_COMBATANTS') == false) {
streamDeck.noPermission(context,device,device);
return;
}
if (combat != null && combat != undefined && combat.started){
const tokenId = compatibleCore("0.8.1") ? combat.combatant.data.tokenId : combat.combatant.tokenId;
const tokenId = combat.combatant.data.tokenId;
tokenControl.pushData(tokenId,settings,context,device);
}
else {
@@ -74,15 +72,15 @@ export class CombatTracker{
}
else if (mode == 'function'){
if (ctFunction == 'turnDisplay' && MODULE.getPermission('COMBAT','TURN_DISPLAY') == false) {
if (ctFunction == 'turnDisplay' && getPermission('COMBAT','TURN_DISPLAY') == false) {
streamDeck.noPermission(context,device);
return;
}
else if (ctFunction == 'endTurn' && MODULE.getPermission('COMBAT','END_TURN') == false) {
else if (ctFunction == 'endTurn' && getPermission('COMBAT','END_TURN') == false) {
streamDeck.noPermission(context,device);
return;
}
else if (ctFunction != 'turnDisplay' && ctFunction != 'endTurn' && MODULE.getPermission('COMBAT','OTHER_FUNCTIONS') == false) {
else if (ctFunction != 'turnDisplay' && ctFunction != 'endTurn' && getPermission('COMBAT','OTHER_FUNCTIONS') == false) {
streamDeck.noPermission(context,device);
return;
}
@@ -130,6 +128,8 @@ export class CombatTracker{
if (settings.displayRound && settings.displayTurn) txt += "\n";
if (settings.displayTurn) txt += "Turn\n"+turn;
}
else if (ctFunction == 'rollInitiative' || ctFunction == 'rollInitiativeNPC')
src = "modules/MaterialDeck/img/token/init.png";
streamDeck.setIcon(context,device,src,{background:background});
streamDeck.setTitle(txt,context);
@@ -145,20 +145,19 @@ export class CombatTracker{
if (combat == null || combat == undefined) return;
const ctFunction = settings.combatTrackerFunction ? settings.combatTrackerFunction : 'startStop';
if (ctFunction == 'turnDisplay' && MODULE.getPermission('COMBAT','TURN_DISPLAY') == false) {
if (ctFunction == 'turnDisplay' && getPermission('COMBAT','TURN_DISPLAY') == false) {
streamDeck.noPermission(context,device);
return;
}
else if (ctFunction == 'endTurn' && MODULE.getPermission('COMBAT','END_TURN') == false) {
else if (ctFunction == 'endTurn' && getPermission('COMBAT','END_TURN') == false) {
streamDeck.noPermission(context,device);
return;
}
else if (ctFunction != 'turnDisplay' && ctFunction != 'endTurn' && MODULE.getPermission('COMBAT','OTHER_FUNCTIONS') == false) {
else if (ctFunction != 'turnDisplay' && ctFunction != 'endTurn' && getPermission('COMBAT','OTHER_FUNCTIONS') == false) {
streamDeck.noPermission(context,device);
return;
}
if (ctFunction == 'startStop'){
else if (ctFunction == 'startStop'){
let src;
let background;
if (game.combat.started){
@@ -169,8 +168,10 @@ export class CombatTracker{
}
return;
}
if (game.combat.started == false) return;
else if (ctFunction == 'rollInitiative' && getPermission('COMBAT','OTHER_FUNCTIONS')) game.combat.rollAll();
else if (ctFunction == 'rollInitiativeNPC' && getPermission('COMBAT','OTHER_FUNCTIONS')) game.combat.rollNPC();
if (game.combat.started == false) return;
if (ctFunction == 'nextTurn') await game.combat.nextTurn();
else if (ctFunction == 'prevTurn') await game.combat.previousTurn();
else if (ctFunction == 'nextRound') await game.combat.nextRound();
@@ -181,7 +182,6 @@ export class CombatTracker{
const token = canvas.tokens.placeables.filter(token => token.id == game.combat.combatant.token.id)[0];
if (token.can(game.userId,"control")) token.control();
}
}
else {
const onClick = settings.onClick ? settings.onClick : 'doNothing';
@@ -193,12 +193,12 @@ export class CombatTracker{
if (nr == undefined || nr < 1) nr = 0;
const combatant = initiativeOrder[nr]
if (combatant == undefined) return;
tokenId = compatibleCore("0.8.1") ? combatant.data.tokenId : combatant.tokenId;
tokenId = combatant.data.tokenId;
}
}
else if (mode == 'currentCombatant')
if (combat != null && combat != undefined && combat.started)
tokenId = compatibleCore("0.8.1") ? combat.combatant.data.tokenId : combat.combatant.tokenId;
tokenId = combat.combatant.data.tokenId;
let token = (canvas.tokens.children[0] != undefined) ? canvas.tokens.children[0].children.find(p => p.id == tokenId) : undefined;
if (token == undefined) return;
@@ -226,6 +226,12 @@ export class CombatTracker{
if (element == null) token.sheet.render(true);
else token.sheet.close();
}
else if (onClick == 'rollInitiative') {
token.actor.rollInitiative({rerollInitiative:true});
}
else if (onClick == 'target') {
token.setTarget(!token.isTargeted,{releaseOthers:false})
}
}
}

View File

@@ -1,4 +1,5 @@
import {streamDeck} from "../MaterialDeck.js";
import { streamDeck } from "../../MaterialDeck.js";
import { compatibleCore } from "../misc.js";
export class ExternalModules{
soundscapeSettings = {
@@ -113,14 +114,14 @@ export class ExternalModules{
let name = '';
if (type == 'weatherControls') {
const effect = (settings.weatherEffect == undefined) ? 'leaves' : settings.weatherEffect;
name = CONFIG.fxmaster.weather[effect].label;
icon = CONFIG.fxmaster.weather[effect].icon;
name = compatibleCore('10.0') ? game.i18n.localize(CONFIG.fxmaster.particleEffects[effect].label) : CONFIG.fxmaster.weather[effect].label;
icon = compatibleCore('10.0') ? CONFIG.fxmaster.particleEffects[effect].icon : CONFIG.fxmaster.weather[effect].icon;
ring = canvas.scene.getFlag("fxmaster", "effects")?.[`core_${effect}`] ? 2 : 1;
ringColor = ring < 2 ? '#000000' : "#00ff00";
}
else if (type == 'filters') {
const filter = (settings.fxMasterFilter == undefined) ? 'underwater' : settings.fxMasterFilter;
name = CONFIG.fxmaster.filters[filter].label;
name = compatibleCore('10.0') ? game.i18n.localize(CONFIG.fxmaster.filterEffects[filter].label) : CONFIG.fxmaster.filters[filter].label;
background = "#340057";
if (displayIcon){
if (filter == 'lightning') icon = "fas fa-bolt";
@@ -174,7 +175,7 @@ export class ExternalModules{
applyColor: (settings.fxWeatherEnColor == undefined) ? false : settings.fxWeatherEnColor
}
Hooks.call("fxmaster.switchWeather", {
Hooks.call(compatibleCore('10.0') ? "fxmaster.switchParticleEffect" : "fxmaster.switchWeather", {
name: `core_${effect}`,
type: effect,
options,

View File

@@ -1,6 +1,5 @@
import * as MODULE from "../MaterialDeck.js";
import {streamDeck} from "../MaterialDeck.js";
import {compatibleCore} from "./misc.js";
import { moduleName, streamDeck, getPermission, hotbarUses } from "../../MaterialDeck.js";
import { compatibleCore } from "../misc.js";
export class MacroControl{
constructor(){
@@ -39,7 +38,7 @@ export class MacroControl{
let uses = undefined;
if (mode == 'macroBoard') { //Macro board
if ((MODULE.getPermission('MACRO','MACROBOARD') == false )) {
if ((getPermission('MACRO','MACROBOARD') == false )) {
streamDeck.noPermission(context,device);
return;
}
@@ -57,8 +56,8 @@ export class MacroControl{
else { //Execute macro
macroNumber += this.offset - 1;
if (macroNumber < 0) macroNumber = 0;
macroId = game.settings.get(MODULE.moduleName,'macroSettings').macros[macroNumber];
background = game.settings.get(MODULE.moduleName,'macroSettings').color[macroNumber];
macroId = game.settings.get(moduleName,'macroSettings').macros[macroNumber];
background = game.settings.get(moduleName,'macroSettings').color[macroNumber];
if (background == undefined) background = '#000000';
ring = 0;
}
@@ -69,11 +68,11 @@ export class MacroControl{
macroId = macro?.id;
}
else { //Macro Hotbar
if ((MODULE.getPermission('MACRO','HOTBAR') == false )) {
if ((getPermission('MACRO','HOTBAR') == false )) {
streamDeck.noPermission(context,device);
return;
}
if (mode == 'hotbar') macroId = game.user.data.hotbar[macroNumber];
if (mode == 'hotbar') macroId = compatibleCore('10.0') ? game.user.hotbar[macroNumber] : game.user.data.hotbar[macroNumber];
else {
let macros;
if (mode == 'customHotbar' && game.modules.get('custom-hotbar') != undefined)
@@ -91,7 +90,7 @@ export class MacroControl{
if (macro != undefined) {
if (displayName) name = macro.name;
if (displayIcon) src = macro.img;
if (MODULE.hotbarUses && displayUses) uses = await this.getUses(macro);
if (hotbarUses && displayUses) uses = await this.getUses(macro);
}
}
else {
@@ -126,7 +125,7 @@ export class MacroControl{
let macroNumber = data.settings.macroNumber;
if(macroNumber == undefined || isNaN(parseInt(macroNumber))) macroNumber = 1;
if ((MODULE.getPermission('MACRO','HOTBAR') == false )) {
if ((getPermission('MACRO','HOTBAR') == false )) {
streamDeck.noPermission(context,device);
return;
}
@@ -150,7 +149,7 @@ export class MacroControl{
if (macro != undefined && macro != null) {
if (displayName) name += macro.name;
if (displayIcon) src += macro.img;
if (MODULE.hotbarUses && displayUses) uses = await this.getUses(macro);
if (hotbarUses && displayUses) uses = await this.getUses(macro);
}
streamDeck.setIcon(context,device,src,{background:background,uses:uses});
streamDeck.setTitle(name,context);
@@ -165,11 +164,11 @@ export class MacroControl{
let target = settings.target ? settings.target : undefined;
if (mode == 'hotbar' || mode == 'visibleHotbar' || mode == 'customHotbar'){
if ((MODULE.getPermission('MACRO','HOTBAR') == false )) return;
this.executeHotbar(macroNumber,mode);
if ((getPermission('MACRO','HOTBAR') == false )) return;
this.executeHotbar(macroNumber,mode,target);
}
else if (mode == 'name') {
if ((MODULE.getPermission('MACRO','BY_NAME') == false )) return;
if ((getPermission('MACRO','BY_NAME') == false )) return;
const macroName = settings.macroNumber;
const macro = game.macros.getName(macroName);
@@ -177,16 +176,13 @@ export class MacroControl{
const args = settings.macroArgs ? settings.macroArgs : "";
let furnaceEnabled = false;
let furnace = game.modules.get("furnace");
if (furnace != undefined && furnace.active && compatibleCore("0.8.1")==false) furnaceEnabled = true;
let advancedMacrosEnabled = false;
let advancedMacros = game.modules.get("advanced-macros");
if (advancedMacros != undefined && advancedMacros.active) furnaceEnabled = true;
if (advancedMacros != undefined && advancedMacros.active) advancedMacrosEnabled = true;
if (args == "" || args == " ") furnaceEnabled = false;
if (args == "" || args == " ") advancedMacrosEnabled = false;
if (furnaceEnabled == false) macro.execute({token:target});
if (advancedMacrosEnabled == false) macro.execute({token:target});
else {
let chatData = {
user: game.user._id,
@@ -198,7 +194,7 @@ export class MacroControl{
}
else {
if ((MODULE.getPermission('MACRO','MACROBOARD') == false )) return;
if ((getPermission('MACRO','MACROBOARD') == false )) return;
if (settings.macroBoardMode == 'offset') {
let macroOffset = settings.macroOffset;
if (macroOffset == undefined) macroOffset = 0;
@@ -210,9 +206,9 @@ export class MacroControl{
}
}
executeHotbar(macroNumber,mode){
executeHotbar(macroNumber,mode,target){
let macroId
if (mode == 'hotbar') macroId = game.user.data.hotbar[macroNumber];
if (mode == 'hotbar') macroId = compatibleCore('10.0') ? game.user.hotbar[macroNumber] : game.user.data.hotbar[macroNumber];
else {
let macros;
if (mode == 'customHotbar' && game.modules.get('custom-hotbar') != undefined) {
@@ -224,29 +220,26 @@ export class MacroControl{
}
if (macroId == undefined) return;
let macro = game.macros.get(macroId);
macro.execute();
macro.execute({token:target});
}
executeBoard(macroNumber){
macroNumber = parseInt(macroNumber);
macroNumber += this.offset - 1;
if (macroNumber < 0) macroNumber = 0;
var macroId = game.settings.get(MODULE.moduleName,'macroSettings').macros[macroNumber];
var macroId = game.settings.get(moduleName,'macroSettings').macros[macroNumber];
if (macroId != undefined){
let macro = game.macros.get(macroId);
if (macro != undefined && macro != null) {
const args = game.settings.get(MODULE.moduleName,'macroSettings').args;
let furnaceEnabled = false;
let furnace = game.modules.get("furnace");
if (furnace != undefined && furnace.active && compatibleCore("0.8.1")==false) furnaceEnabled = true;
const args = game.settings.get(moduleName,'macroSettings').args;
let advancedMacrosEnabled = false;
let advancedMacros = game.modules.get("advanced-macros");
if (advancedMacros != undefined && advancedMacros.active) furnaceEnabled = true;
if (advancedMacros != undefined && advancedMacros.active) advancedMacrosEnabled = true;
if (args == undefined || args[macroNumber] == undefined || args[macroNumber] == "") furnaceEnabled = false;
if (args == undefined || args[macroNumber] == undefined || args[macroNumber] == "") advancedMacrosEnabled = false;
if (furnaceEnabled == false) macro.execute();
if (advancedMacrosEnabled == false) macro.execute();
else {
let chatData = {
user: game.user._id,

View File

@@ -1,6 +1,5 @@
import * as MODULE from "../MaterialDeck.js";
import {streamDeck, gamingSystem} from "../MaterialDeck.js";
import {compatibleCore} from "./misc.js";
import { streamDeck, gamingSystem, getPermission } from "../../MaterialDeck.js";
import { compatibleCore } from "../misc.js";
export class OtherControls{
constructor(){
@@ -94,7 +93,7 @@ export class OtherControls{
//////////////////////////////////////////////////////////////////////////////////////////////////
updatePause(settings,context,device,options={}){
if (MODULE.getPermission('OTHER','PAUSE') == false ) {
if (getPermission('OTHER','PAUSE') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -119,7 +118,7 @@ export class OtherControls{
}
keyPressPause(settings){
if (MODULE.getPermission('OTHER','PAUSE') == false ) return;
if (getPermission('OTHER','PAUSE') == false ) return;
const pauseFunction = settings.pauseFunction ? settings.pauseFunction : 'pause';
@@ -186,7 +185,7 @@ export class OtherControls{
}
else {
let viewPosition = canvas.scene._viewPosition;
const gridSize = canvas.scene.data.grid;
const gridSize = compatibleCore('10.0') ? canvas.scene.grid.size : canvas.scene.data.grid;
viewPosition.duration = 100;
if (dir == 'up') viewPosition.y -= gridSize;
@@ -220,7 +219,7 @@ export class OtherControls{
//////////////////////////////////////////////////////////////////////////////////////////
updateControl(settings,context,device,options={}){
if (MODULE.getPermission('OTHER','CONTROL') == false ) {
if (getPermission('OTHER','CONTROL') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -241,19 +240,19 @@ export class OtherControls{
controlNr--;
controlNr += this.controlsOffset;
const selectedControl = ui.controls.controls[controlNr];
const selectedControl = ui.controls.controls[controlNr];
if (selectedControl != undefined){
if (selectedControl.visible == false) {
streamDeck.noPermission(context,device,false);
return;
}
if (tool == 'open'){ //open category
//if (tool == 'open'){ //open category
txt = game.i18n.localize(selectedControl.title);
src = selectedControl.icon;
if (activeControl == selectedControl.name)
ringColor = "#FF7B00";
}
//}
}
}
else if (control == 'dispTools'){ //displayed tools
@@ -330,7 +329,7 @@ export class OtherControls{
}
keyPressControl(settings){
if (MODULE.getPermission('OTHER','CONTROL') == false ) return;
if (getPermission('OTHER','CONTROL') == false ) return;
if (canvas.scene == null) return;
const control = settings.control ? settings.control : 'dispControls';
const tool = settings.tool ? settings.tool : 'open';
@@ -346,9 +345,12 @@ export class OtherControls{
streamDeck.noPermission(context,device,false);
return;
}
ui.controls.activeControl = selectedControl.name;
selectedControl.activeTool = selectedControl.activeTool;
if (compatibleCore("0.8.2")) {
if (compatibleCore('10.0')) {
ui.controls.initialize({layer: selectedControl.layer});
}
else {
ui.controls.activeControl = selectedControl.name;
selectedControl.activeTool = selectedControl.activeTool;
for (let layer of canvas.layers) {
if (layer.options == undefined) continue;
if (layer.options.name == selectedControl.layer) {
@@ -357,7 +359,6 @@ export class OtherControls{
}
}
}
else canvas.getLayer(selectedControl.layer).activate();
}
}
else if (control == 'dispTools'){ //displayed tools
@@ -383,8 +384,15 @@ export class OtherControls{
else if (selectedTool.button){
selectedTool.onClick();
}
else
selectedControl.activeTool = selectedTool.name;
else {
if (compatibleCore('10.0')) {
ui.controls.initialize({layer: selectedControl.layer, tool: selectedTool.name});
}
else {
selectedControl.activeTool = selectedTool.name;
}
}
}
}
}
@@ -406,9 +414,12 @@ export class OtherControls{
return;
}
if (tool == 'open'){ //open category
ui.controls.activeControl = control;
selectedControl.activeTool = selectedControl.activeTool;
if (compatibleCore("0.8.2")) {
if (compatibleCore('10.0')) {
ui.controls.initialize({layer: selectedControl.layer});
}
else {
ui.controls.activeControl = control;
selectedControl.activeTool = selectedControl.activeTool;
for (let layer of canvas.layers) {
if (layer.options == undefined) continue;
if (layer.options.name == selectedControl.layer) {
@@ -417,7 +428,7 @@ export class OtherControls{
}
}
}
else canvas.getLayer(selectedControl.layer).activate();
}
else {
const selectedTool = selectedControl.tools.find(t => t.name == tool);
@@ -426,8 +437,21 @@ export class OtherControls{
streamDeck.noPermission(context,device,false);
return;
}
ui.controls.activeControl = control;
if (compatibleCore("0.8.2")) {
if (compatibleCore('10.0')) {
if (selectedTool.toggle) {
ui.controls.initialize({layer: selectedControl.layer});
selectedTool.active = !selectedTool.active;
selectedTool.onClick(selectedTool.active);
}
else if (selectedTool.button){
ui.controls.initialize({layer: selectedControl.layer});
selectedTool.onClick();
}
else
ui.controls.initialize({layer: selectedControl.layer, tool: selectedTool.name});
}
else {
ui.controls.activeControl = control;
for (let layer of canvas.layers) {
if (layer.options == undefined) continue;
if (layer.options.name == selectedControl.layer) {
@@ -435,17 +459,17 @@ export class OtherControls{
break;
}
}
if (selectedTool.toggle) {
selectedTool.active = !selectedTool.active;
selectedTool.onClick(selectedTool.active);
}
else if (selectedTool.button){
selectedTool.onClick();
}
else
selectedControl.activeTool = tool;
}
else canvas.getLayer(selectedControl.layer).activate();
if (selectedTool.toggle) {
selectedTool.active = !selectedTool.active;
selectedTool.onClick(selectedTool.active);
}
else if (selectedTool.button){
selectedTool.onClick();
}
else
selectedControl.activeTool = tool;
}
}
}
@@ -456,7 +480,7 @@ export class OtherControls{
//////////////////////////////////////////////////////////////////////////////////////////
updateDarkness(settings,context,device,options={}){
if (MODULE.getPermission('OTHER','DARKNESS') == false ) {
if (getPermission('OTHER','DARKNESS') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -476,7 +500,7 @@ export class OtherControls{
}
else if (func == 'disp'){ //display darkness
src = 'modules/MaterialDeck/img/other/darkness/darkness.png';
const darkness = canvas.scene != null ? Math.floor(canvas.scene.data.darkness*100)/100 : '';
const darkness = canvas.scene != null ? compatibleCore('10.0') ? Math.floor(canvas.scene.darkness*100)/100 : Math.floor(canvas.scene.data.darkness*100)/100 : '';
txt += darkness;
}
streamDeck.setTitle(txt,context);
@@ -485,39 +509,48 @@ export class OtherControls{
keyPressDarkness(settings) {
if (canvas.scene == null) return;
if (MODULE.getPermission('OTHER','DARKNESS') == false ) return;
if (getPermission('OTHER','DARKNESS') == false ) return;
const func = settings.darknessFunction ? settings.darknessFunction : 'value';
const value = parseFloat(settings.darknessValue) ? parseFloat(settings.darknessValue) : 0;
const animateDarkness = parseInt(settings.darknessAnimation) ? parseInt(settings.darknessAnimation) : 500;
if (func == 'value') //value
canvas.scene.update({darkness: value});
canvas.scene.update({darkness: value}, {animateDarkness});
else if (func == 'incDec'){ //increase/decrease
let darkness = canvas.scene.data.darkness - value;
let darkness = compatibleCore('10.0') ? canvas.scene.darkness - value : canvas.scene.data.darkness - value;
if (darkness > 1) darkness = 1;
if (darkness < 0) darkness = 0;
canvas.scene.update({darkness: darkness});
canvas.scene.update({darkness: darkness}, {animateDarkness});
}
else if (func == 'transitionDay') {
canvas.scene.update({darkness: 0}, {animateDarkness: 10000})
}
else if (func == 'transitionNight') {
canvas.scene.update({darkness: 1}, {animateDarkness: 10000})
}
}
//////////////////////////////////////////////////////////////////////////////////////////
updateRollDice(settings,context,device,options={}){
if (MODULE.getPermission('OTHER','DICE') == false ) {
if (getPermission('OTHER','DICE') == false ) {
streamDeck.noPermission(context,device);
return;
}
const background = settings.background ? settings.background : '#000000';
let txt = '';
const formula = settings.rollDiceFormula ? settings.rollDiceFormula : '1d20 + 7';
if (settings.displayDiceName) txt = 'Roll: ' + settings.rollDiceFormula;
if (settings.displayDiceName) txt = 'Roll: ' + formula;
streamDeck.setTitle(txt,context);
streamDeck.setIcon(context,device,'',{background:background});
}
keyPressRollDice(settings,context,device){
if (MODULE.getPermission('OTHER','DICE') == false ) return;
if (settings.rollDiceFormula == undefined || settings.rollDiceFormula == '') return;
if (getPermission('OTHER','DICE') == false ) return;
const formula = settings.rollDiceFormula ? settings.rollDiceFormula : '1d20 + 7';
if (formula == '') return;
const rollFunction = settings.rollDiceFunction ? settings.rollDiceFunction : 'public';
let actor;
@@ -527,8 +560,8 @@ export class OtherControls{
if (actor != undefined) tokenControlled = true;
let r;
if (tokenControlled) r = new Roll(settings.rollDiceFormula,actor.getRollData());
else r = new Roll(settings.rollDiceFormula);
if (tokenControlled) r = new Roll(formula,actor.getRollData());
else r = new Roll(formula);
r.evaluate({async:false});
@@ -539,12 +572,12 @@ export class OtherControls{
r.toMessage(r,{rollMode:"selfroll"})
}
else if (rollFunction == 'sd'){
let txt = settings.displayDiceName ? 'Roll: '+settings.rollDiceFormula + '\nResult: ' : '';
let txt = settings.displayDiceName ? 'Roll: '+formula + '\nResult: ' : '';
txt += r.total;
streamDeck.setTitle(txt,context);
let data = this.rollData
data[context] = {
formula: settings.rollDiceFormula,
formula: formula,
result: txt
}
this.rollData = data;
@@ -556,7 +589,7 @@ export class OtherControls{
updateRollTable(settings,context,device,options={}){
const name = settings.rollTableName;
if (name == undefined) return;
if (MODULE.getPermission('OTHER','TABLES') == false ) {
if (getPermission('OTHER','TABLES') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -566,14 +599,14 @@ export class OtherControls{
if (table == undefined) return;
let txt = settings.displayRollName ? table.name : '';
let src = settings.displayRollIcon ? table.data.img : '';
let src = settings.displayRollIcon ? (compatibleCore('10.0') ? table.img : table.data.img) : '';
if (table == undefined) {
src = '';
txt = '';
}
else {
if (table.permission < 2 && MODULE.getPermission('OTHER','TABLES_ALL') == false ) {
if (table.permission < 2 && getPermission('OTHER','TABLES_ALL') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -584,7 +617,7 @@ export class OtherControls{
}
keyPressRollTable(settings){
if (MODULE.getPermission('OTHER','TABLES') == false ) return;
if (getPermission('OTHER','TABLES') == false ) return;
const name = settings.rollTableName;
if (name == undefined) return;
@@ -592,7 +625,7 @@ export class OtherControls{
const table = game.tables.getName(name);
if (table != undefined) {
if (table.permission < 2 && MODULE.getPermission('OTHER','TABLES_ALL') == false ) return;
if (table.permission < 2 && getPermission('OTHER','TABLES_ALL') == false ) return;
if (func == 'open'){ //open
const element = document.getElementById(table.sheet.id);
if (element == null) table.sheet.render(true);
@@ -609,18 +642,34 @@ export class OtherControls{
getSidebarName(nr){
let name;
if (nr == 'chat') name = game.i18n.localize("SIDEBAR.TabChat");
else if (nr == 'combat') name = game.i18n.localize("SIDEBAR.TabCombat");
else if (nr == 'scenes') name = game.i18n.localize("SIDEBAR.TabScenes");
else if (nr == 'actors') name = game.i18n.localize("SIDEBAR.TabActors");
else if (nr == 'items') name = game.i18n.localize("SIDEBAR.TabItems");
else if (nr == 'journal') name = game.i18n.localize("SIDEBAR.TabJournal");
else if (nr == 'tables') name = game.i18n.localize("SIDEBAR.TabTables");
else if (nr == 'cards') name = game.i18n.localize("SIDEBAR.TabCards");
else if (nr == 'playlists') name = game.i18n.localize("SIDEBAR.TabPlaylists");
else if (nr == 'compendium') name = game.i18n.localize("SIDEBAR.TabCompendium");
else if (nr == 'settings') name = game.i18n.localize("SIDEBAR.TabSettings");
else if (nr == 'collapse') name = game.i18n.localize("SIDEBAR.CollapseToggle");
if (compatibleCore('10.0')) {
if (nr == 'chat') name = game.i18n.localize("DOCUMENT.ChatMessages");
else if (nr == 'combat') name = game.i18n.localize("DOCUMENT.Combats");
else if (nr == 'scenes') name = game.i18n.localize("DOCUMENT.Scenes");
else if (nr == 'actors') name = game.i18n.localize("DOCUMENT.Actors");
else if (nr == 'items') name = game.i18n.localize("DOCUMENT.Items");
else if (nr == 'journal') name = game.i18n.localize("DOCUMENT.JournalEntries");
else if (nr == 'tables') name = game.i18n.localize("DOCUMENT.RollTables");
else if (nr == 'cards') name = game.i18n.localize("DOCUMENT.Cards");
else if (nr == 'playlists') name = game.i18n.localize("DOCUMENT.Playlists");
else if (nr == 'compendium') name = game.i18n.localize("SIDEBAR.TabCompendium");
else if (nr == 'settings') name = game.i18n.localize("SIDEBAR.TabSettings");
else if (nr == 'collapse') name = game.i18n.localize("SIDEBAR.CollapseToggle");
}
else {
if (nr == 'chat') name = game.i18n.localize("SIDEBAR.TabChat");
else if (nr == 'combat') name = game.i18n.localize("SIDEBAR.TabCombat");
else if (nr == 'scenes') name = game.i18n.localize("SIDEBAR.TabScenes");
else if (nr == 'actors') name = game.i18n.localize("SIDEBAR.TabActors");
else if (nr == 'items') name = game.i18n.localize("SIDEBAR.TabItems");
else if (nr == 'journal') name = game.i18n.localize("SIDEBAR.TabJournal");
else if (nr == 'tables') name = game.i18n.localize("SIDEBAR.TabTables");
else if (nr == 'cards') name = game.i18n.localize("SIDEBAR.TabCards");
else if (nr == 'playlists') name = game.i18n.localize("SIDEBAR.TabPlaylists");
else if (nr == 'compendium') name = game.i18n.localize("SIDEBAR.TabCompendium");
else if (nr == 'settings') name = game.i18n.localize("SIDEBAR.TabSettings");
else if (nr == 'collapse') name = game.i18n.localize("SIDEBAR.CollapseToggle");
}
return name;
}
@@ -629,11 +678,11 @@ export class OtherControls{
if (nr == 'chat') icon = window.CONFIG.ChatMessage.sidebarIcon;
else if (nr == 'combat') icon = window.CONFIG.Combat.sidebarIcon;
else if (nr == 'scenes') icon = window.CONFIG.Scene.sidebarIcon;
else if (nr == 'actors') icon = "fas fa-users";
else if (nr == 'actors') icon = window.CONFIG.Actor.sidebarIcon;
else if (nr == 'items') icon = window.CONFIG.Item.sidebarIcon;
else if (nr == 'journal') icon = window.CONFIG.JournalEntry.sidebarIcon;
else if (nr == 'tables') icon = window.CONFIG.RollTable.sidebarIcon;
else if (nr == 'cards') icon = "fas fa-id-badge";
else if (nr == 'cards') icon = window.CONFIG.Cards.sidebarIcon;
else if (nr == 'playlists') icon = window.CONFIG.Playlist.sidebarIcon;
else if (nr == 'compendium') icon = "fas fa-atlas";
else if (nr == 'settings') icon = "fas fa-cogs";
@@ -642,7 +691,7 @@ export class OtherControls{
}
updateSidebar(settings,context,device,options={}){
if (MODULE.getPermission('OTHER','SIDEBAR') == false ) {
if (getPermission('OTHER','SIDEBAR') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -666,7 +715,7 @@ export class OtherControls{
}
keyPressSidebar(settings){
if (MODULE.getPermission('OTHER','SIDEBAR') == false ) return;
if (getPermission('OTHER','SIDEBAR') == false ) return;
const sidebarTab = settings.sidebarTab ? settings.sidebarTab : 'chat';
const popOut = settings.sidebarPopOut ? settings.sidebarPopOut : false;
@@ -718,17 +767,17 @@ export class OtherControls{
updateCompendium(settings,context,device,options={}){
const name = settings.compendiumName;
if (name == undefined) return;
if (MODULE.getPermission('OTHER','COMPENDIUM') == false ) {
if (getPermission('OTHER','COMPENDIUM') == false ) {
streamDeck.noPermission(context,device);
return;
}
const compendium = game.packs.find(p=>p.metadata.label == name);
if (compendium == undefined) return;
if (compendium.private && MODULE.getPermission('OTHER','COMPENDIUM_ALL') == false) {
if (compendium.private && getPermission('OTHER','COMPENDIUM_ALL') == false) {
streamDeck.noPermission(context,device);
return;
}
const rendered = compatibleCore("0.8.5") ? compendium.apps[0].rendered : compendium.rendered;
const rendered = compendium.apps[0].rendered;
const background = settings.background ? settings.background : '#000000';
const ringOffColor = settings.offRing ? settings.offRing : '#000000';
const ringOnColor = settings.onRing ? settings.onRing : '#00FF00';
@@ -742,13 +791,13 @@ export class OtherControls{
keyPressCompendium(settings){
let name = settings.compendiumName;
if (name == undefined) return;
if (MODULE.getPermission('OTHER','COMPENDIUM') == false ) return;
if (getPermission('OTHER','COMPENDIUM') == false ) return;
const compendium = game.packs.find(p=>p.metadata.label == name);
const rendered = compatibleCore("0.8.5") ? compendium.apps[0].rendered : compendium.rendered;
const rendered = compendium.apps[0].rendered;
if (compendium == undefined) return;
if (compendium.private && MODULE.getPermission('OTHER','COMPENDIUM_ALL') == false) return;
else if (rendered) compatibleCore("0.8.5") ? compendium.apps[0].close() : compendium.close();
if (compendium.private && getPermission('OTHER','COMPENDIUM_ALL') == false) return;
else if (rendered) compendium.apps[0].close();
else compendium.render(true);
}
@@ -761,11 +810,11 @@ export class OtherControls{
const journal = game.journal.getName(name);
if (journal == undefined) return;
if (MODULE.getPermission('OTHER','JOURNAL') == false ) {
if (getPermission('OTHER','JOURNAL') == false ) {
streamDeck.noPermission(context,device);
return;
}
if (journal.permission < 2 && MODULE.getPermission('OTHER','JOURNAL_ALL') == false ) {
if (journal.permission < 2 && getPermission('OTHER','JOURNAL_ALL') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -795,8 +844,8 @@ export class OtherControls{
const journal = game.journal.getName(name);
if (journal == undefined) return;
if (MODULE.getPermission('OTHER','JOURNAL') == false ) return;
if (journal.permission < 2 && MODULE.getPermission('OTHER','JOURNAL_ALL') == false ) return;
if (getPermission('OTHER','JOURNAL') == false ) return;
if (journal.permission < 2 && getPermission('OTHER','JOURNAL_ALL') == false ) return;
if (journal.sheet.rendered == false) journal.sheet.render(true);
else journal.sheet.close();
@@ -805,7 +854,7 @@ export class OtherControls{
//////////////////////////////////////////////////////////////////////////////////////////
updateChatMessage(settings,context,device,options={}){
if (MODULE.getPermission('OTHER','CHAT') == false ) {
if (getPermission('OTHER','CHAT') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -815,7 +864,7 @@ export class OtherControls{
}
keyPressChatMessage(settings){
if (MODULE.getPermission('OTHER','CHAT') == false ) return;
if (getPermission('OTHER','CHAT') == false ) return;
const message = settings.chatMessage ? settings.chatMessage : '';
let chatData = {

View File

@@ -1,6 +1,4 @@
import * as MODULE from "../MaterialDeck.js";
import {streamDeck} from "../MaterialDeck.js";
import {compatibleCore} from "./misc.js";
import { moduleName, streamDeck, getPermission } from "../../MaterialDeck.js";
export class PlaylistControl{
constructor(){
@@ -22,7 +20,7 @@ export class PlaylistControl{
}
update(settings,context,device){
if (MODULE.getPermission('PLAYLIST','PLAY') == false ) {
if (getPermission('PLAYLIST','PLAY') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -84,7 +82,7 @@ export class PlaylistControl{
let playlistOffset = parseInt(settings.offset);
if (isNaN(playlistOffset)) playlistOffset = 0;
let number = parseInt(this.playlistOffset + playlistOffset);
const nrOfPlaylists = parseInt(game.settings.get(MODULE.moduleName,'playlists').playlistNumber);
const nrOfPlaylists = parseInt(game.settings.get(moduleName,'playlists').playlistNumber);
if (number < 0) number += nrOfPlaylists;
else if (number >= nrOfPlaylists) number -= nrOfPlaylists;
const targetPlaylist = this.getPlaylist(number);
@@ -116,7 +114,7 @@ export class PlaylistControl{
let playlist = this.getPlaylist(playlistNr);
if (playlist != undefined){
const track = compatibleCore("0.8.1") ? playlist.sounds.contents[trackNr] : playlist.sounds[trackNr];
const track = playlist.sounds.contents[trackNr];
if (track != undefined){
if (track.playing)
ringColor = ringOnColor;
@@ -157,7 +155,7 @@ export class PlaylistControl{
}
else {
let playing = game.playlists.playing;
let settings = game.settings.get(MODULE.moduleName,'playlists');
let settings = game.settings.get(moduleName,'playlists');
let selectedPlaylists = settings.selectedPlaylist;
for (let i=0; i<playing.length; i++){
const playlistNr = selectedPlaylists.findIndex(p => p == playing[i]._id);
@@ -189,14 +187,14 @@ export class PlaylistControl{
}
getPlaylist(num){
let selectedPlaylists = game.settings.get(MODULE.moduleName,'playlists').selectedPlaylist;
let selectedPlaylists = game.settings.get(moduleName,'playlists').selectedPlaylist;
if (selectedPlaylists != undefined)
return game.playlists.get(selectedPlaylists[num]);
else return undefined;
}
keyPress(settings,context,device){
if (MODULE.getPermission('PLAYLIST','PLAY') == false ) return;
if (getPermission('PLAYLIST','PLAY') == false ) return;
let playlistNr = settings.playlistNr;
if (playlistNr == undefined || playlistNr < 1) playlistNr = 1;
playlistNr--;
@@ -222,7 +220,7 @@ export class PlaylistControl{
if (playlistMode == 'playlist')
this.playPlaylist(playlist,playlistNr);
else {
const track = compatibleCore("0.8.1") ? playlist.sounds.contents[trackNr] : playlist.sounds[trackNr];
const track = playlist.sounds.contents[trackNr];
if (track != undefined){
this.playTrack(track,playlist,playlistNr);
}
@@ -251,7 +249,7 @@ export class PlaylistControl{
let playlistOffset = parseInt(settings.offset);
if (isNaN(playlistOffset)) playlistOffset = 0;
let number = parseInt(this.playlistOffset + playlistOffset);
const nrOfPlaylists = parseInt(game.settings.get(MODULE.moduleName,'playlists').playlistNumber);
const nrOfPlaylists = parseInt(game.settings.get(moduleName,'playlists').playlistNumber);
if (number < 0) number += nrOfPlaylists;
else if (number >= nrOfPlaylists) number -= nrOfPlaylists;
this.playlistOffset = number;
@@ -281,12 +279,15 @@ export class PlaylistControl{
playlist.stopAll();
return;
}
let mode = game.settings.get(MODULE.moduleName,'playlists').playlistMode[playlistNr];
let mode = game.settings.get(moduleName,'playlists').playlistMode[playlistNr];
const originalPlayMode = playlist.mode;
await playlist.update({mode: CONST.PLAYLIST_MODES.SEQUENTIAL});
if (mode == 0) {
mode = game.settings.get(MODULE.moduleName,'playlists').playMode;
if (mode == 2) await this.stopAll();
mode = game.settings.get(moduleName,'playlists').playMode;
if (mode == 2) await this.stopAll(true);
}
playlist.playAll();
await playlist.update({mode: originalPlayMode});
}
async playTrack(track,playlist,playlistNr){
@@ -301,23 +302,25 @@ export class PlaylistControl{
return;
}
let play;
const originalPlayMode = playlist.mode;
if (track.playing)
play = false;
else {
play = true;
let mode = game.settings.get(MODULE.moduleName,'playlists').playlistMode[playlistNr];
let mode = game.settings.get(moduleName,'playlists').playlistMode[playlistNr];
if (mode == 0) {
mode = game.settings.get(MODULE.moduleName,'playlists').playMode;
if (mode == 1) await playlist.stopAll();
else if (mode == 2) await this.stopAll();
mode = game.settings.get(moduleName,'playlists').playMode;
if (mode == 0) await playlist.update({mode: CONST.PLAYLIST_MODES.SIMULTANEOUS});
else if (mode == 1) await playlist.stopAll();
else if (mode == 2) await this.stopAll(true);
}
else if (mode == 2) await playlist.stopAll();
else if (mode == 2) await playlist.stopAll(true);
}
if (compatibleCore("0.8.1") && play) await playlist.playSound(track);
else if (compatibleCore("0.8.1")) await playlist.stopSound(track);
else await playlist.updateEmbeddedEntity("PlaylistSound", {_id: track._id, playing: play});
if (play) await playlist.playSound(track);
else await playlist.stopSound(track);
playlist.update({playing: play});
await playlist.update({mode: originalPlayMode});
}
}

View File

@@ -1,6 +1,5 @@
import * as MODULE from "../MaterialDeck.js";
import {streamDeck} from "../MaterialDeck.js";
import {compatibleCore} from "./misc.js";
import { streamDeck, getPermission } from "../../MaterialDeck.js";
import { compatibleCore } from "../misc.js";
export class SceneControl{
constructor(){
@@ -34,7 +33,7 @@ export class SceneControl{
let src = "";
let name = "";
if (func == 'visible') { //visible scenes
if (MODULE.getPermission('SCENE','VISIBLE') == false ) {
if (getPermission('SCENE','VISIBLE') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -47,12 +46,12 @@ export class SceneControl{
if (scene != undefined){
ringColor = scene.isView ? ringOnColor : ringOffColor;
if (settings.displaySceneName) name = scene.name;
if (settings.displaySceneIcon) src = scene.img;
if (settings.displaySceneIcon) src = compatibleCore('10.0') ? scene.background.src : scene.img;
if (scene.active) name += "\n(Active)";
}
}
else if (func == 'dir') { //from directory
if (MODULE.getPermission('SCENE','DIRECTORY') == false ) {
if (getPermission('SCENE','DIRECTORY') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -61,33 +60,39 @@ export class SceneControl{
nr--;
let sceneList = [];
for (let i=0; i<ui.scenes.tree.children.length; i++){
const scenesInFolder = compatibleCore("0.8.1") ? ui.scenes.tree.children[i].contents : ui.scenes.tree.children[i].entities;
for (let j=0; j<scenesInFolder.length; j++)
sceneList.push(scenesInFolder[j])
if (compatibleCore('10.0')) {
sceneList = ui.scenes.documents;
}
for (let i=0; i<ui.scenes.tree.content.length; i++)
sceneList.push(ui.scenes.tree.content[i])
else {
for (let i=0; i<ui.scenes.tree.children.length; i++){
const scenesInFolder = ui.scenes.tree.children[i].contents;
for (let j=0; j<scenesInFolder.length; j++)
sceneList.push(scenesInFolder[j])
}
for (let i=0; i<ui.scenes.tree.content.length; i++)
sceneList.push(ui.scenes.tree.content[i])
}
const scene = sceneList[nr+this.sceneOffset];
if (scene != undefined){
if (scene.isView)
ringColor = ringOnColor;
else if (scene.data.navigation && scene.data.permission.default == 0)
else if ((compatibleCore('10.0') && scene.navigation && scene.permission.default == 0) || (!compatibleCore('10.0') && scene.data.navigation && scene.data.permission.default == 0))
ringColor = '#000791';
else if (scene.data.navigation)
else if ((compatibleCore('10.0') && scene.navigation) || (!compatibleCore('10.0') && scene.data.navigation))
ringColor = '#2d2d2d';
else
ringColor = ringOffColor;
if (settings.displaySceneName) name = scene.name;
if (settings.displaySceneIcon) src = scene.img;
if (settings.displaySceneIcon) src = compatibleCore('10.0') ? scene.background.src : scene.img;
if (scene.active) name += "\n(Active)";
}
}
else if (func == 'any') { //by name
if (MODULE.getPermission('SCENE','NAME') == false ) {
if (getPermission('SCENE','NAME') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -97,19 +102,19 @@ export class SceneControl{
if (scene != undefined){
ringColor = scene.isView ? ringOnColor : ringOffColor;
if (settings.displaySceneName) name = scene.name;
if (settings.displaySceneIcon) src = scene.img;
if (settings.displaySceneIcon) src = compatibleCore('10.0') ? scene.background.src : scene.img;
if (scene.active) name += "\n(Active)";
}
}
else if (func == 'active'){
if (MODULE.getPermission('SCENE','ACTIVE') == false ) {
if (getPermission('SCENE','ACTIVE') == false ) {
streamDeck.noPermission(context,device);
return;
}
const scene = game.scenes.active;
if (scene == undefined) return;
if (settings.displaySceneName) name = scene.name;
if (settings.displaySceneIcon) src = scene.img;
if (settings.displaySceneIcon) src = compatibleCore('10.0') ? scene.background.src : scene.img;
ring = 0;
}
else if (func == 'offset'){
@@ -126,7 +131,7 @@ export class SceneControl{
const func = settings.sceneFunction ? settings.sceneFunction : 'visible';
if (func == 'visible'){ //visible scenes
if (MODULE.getPermission('SCENE','VISIBLE') == false ) return;
if (getPermission('SCENE','VISIBLE') == false ) return;
const viewFunc = settings.sceneViewFunction ? settings.sceneViewFunction : 'view';
let nr = parseInt(settings.sceneNr);
if (isNaN(nr) || nr < 1) nr = 1;
@@ -147,21 +152,26 @@ export class SceneControl{
}
}
else if (func == 'dir') { //from directory
if (MODULE.getPermission('SCENE','DIRECTORY') == false ) return;
if (getPermission('SCENE','DIRECTORY') == false ) return;
const viewFunc = settings.sceneViewFunction ? settings.sceneViewFunction : 'view';
let nr = parseInt(settings.sceneNr);
if (isNaN(nr) || nr < 1) nr = 1;
nr--;
let sceneList = [];
for (let i=0; i<ui.scenes.tree.children.length; i++){
const scenesInFolder = compatibleCore("0.8.1") ? ui.scenes.tree.children[i].contents : ui.scenes.tree.children[i].entities;
for (let j=0; j<scenesInFolder.length; j++)
sceneList.push(scenesInFolder[j])
if (compatibleCore('10.0')) {
sceneList = ui.scenes.documents;
}
for (let i=0; i<ui.scenes.tree.content.length; i++)
sceneList.push(ui.scenes.tree.content[i])
else {
for (let i=0; i<ui.scenes.tree.children.length; i++){
const scenesInFolder = ui.scenes.tree.children[i].contents;
for (let j=0; j<scenesInFolder.length; j++)
sceneList.push(scenesInFolder[j])
}
for (let i=0; i<ui.scenes.tree.content.length; i++)
sceneList.push(ui.scenes.tree.content[i])
}
const scene = sceneList[nr+this.sceneOffset];
if (scene != undefined){
@@ -179,7 +189,7 @@ export class SceneControl{
}
else if (func == 'any'){ //by name
if (MODULE.getPermission('SCENE','NAME') == false ) return;
if (getPermission('SCENE','NAME') == false ) return;
if (settings.sceneName == undefined || settings.sceneName == '') return;
const scenes = game.scenes.entries;
let scene = game.scenes.getName(settings.sceneName);
@@ -199,7 +209,7 @@ export class SceneControl{
}
}
else if (func == 'active'){
if (MODULE.getPermission('SCENE','ACTIVE') == false ) return;
if (getPermission('SCENE','ACTIVE') == false ) return;
const scene = game.scenes.active;
if (scene == undefined) return;
scene.view();

View File

@@ -1,6 +1,4 @@
import * as MODULE from "../MaterialDeck.js";
import {streamDeck} from "../MaterialDeck.js";
import {compatibleCore} from "./misc.js";
import { moduleName, streamDeck, getPermission } from "../../MaterialDeck.js";
export class SoundboardControl{
constructor(){
@@ -22,7 +20,7 @@ export class SoundboardControl{
}
update(settings,context,device){
if (MODULE.getPermission('SOUNDBOARD','PLAY') == false ) {
if (getPermission('SOUNDBOARD','PLAY') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -40,7 +38,7 @@ export class SoundboardControl{
soundNr--;
soundNr += this.offset;
let soundboardSettings = game.settings.get(MODULE.moduleName, 'soundboardSettings');
let soundboardSettings = game.settings.get(moduleName, 'soundboardSettings');
ringColor = (this.activeSounds[soundNr]==undefined) ? soundboardSettings.colorOff[soundNr] : soundboardSettings.colorOn[soundNr];
if (settings.displayName && soundboardSettings.name != undefined) txt = soundboardSettings.name[soundNr];
@@ -76,7 +74,7 @@ export class SoundboardControl{
}
keyPressDown(settings){
if (MODULE.getPermission('SOUNDBOARD','PLAY') == false ) return;
if (getPermission('SOUNDBOARD','PLAY') == false ) return;
const mode = settings.soundboardMode ? settings.soundboardMode : 'playSound';
if (mode == 'playSound') { //Play sound
@@ -85,7 +83,7 @@ export class SoundboardControl{
soundNr--;
soundNr += this.offset;
const playMode = game.settings.get(MODULE.moduleName,'soundboardSettings').mode[soundNr];
const playMode = game.settings.get(moduleName,'soundboardSettings').mode[soundNr];
const repeat = (playMode > 0) ? true : false;
const play = (this.activeSounds[soundNr] == undefined) ? true : false;
@@ -107,7 +105,7 @@ export class SoundboardControl{
}
keyPressUp(settings){
if (MODULE.getPermission('SOUNDBOARD','PLAY') == false ) return;
if (getPermission('SOUNDBOARD','PLAY') == false ) return;
const mode = settings.soundboardMode ? settings.soundboardMode : 'playSound';
if (mode != 'playSound') return;
@@ -117,14 +115,14 @@ export class SoundboardControl{
soundNr--;
soundNr += this.offset;
const playMode = game.settings.get(MODULE.moduleName,'soundboardSettings').mode[soundNr];
const playMode = game.settings.get(moduleName,'soundboardSettings').mode[soundNr];
if (playMode == 2)
this.prePlaySound(soundNr,false,false);
}
async prePlaySound(soundNr,repeat,play){
const soundBoardSettings = game.settings.get(MODULE.moduleName,'soundboardSettings');
const soundBoardSettings = game.settings.get(moduleName,'soundboardSettings');
const playlistId = (soundBoardSettings.selectedPlaylists != undefined) ? soundBoardSettings.selectedPlaylists[soundNr] : undefined;
let src;
if (playlistId == "" || playlistId == undefined) return;
@@ -144,12 +142,12 @@ export class SoundboardControl{
const soundId = soundBoardSettings.sounds[soundNr];
const sounds = game.playlists.get(playlistId).sounds;
if (sounds == undefined) return;
const sound = compatibleCore("0.8.1") ? sounds.find(p => p.id == soundId) : sounds.find(p => p._id == soundId);
const sound = sounds.find(p => p.id == soundId);
if (sound == undefined) return;
src = sound.path;
}
let volume = game.settings.get(MODULE.moduleName,'soundboardSettings').volume[soundNr]/100;
let volume = game.settings.get(moduleName,'soundboardSettings').volume[soundNr]/100;
volume = AudioHelper.inputToVolume(volume);
let payload = {
@@ -169,32 +167,16 @@ export class SoundboardControl{
if (play){
volume *= game.settings.get("core", "globalAmbientVolume");
if (compatibleCore("0.8.1")) {
let newSound = new Sound(src);
if(newSound.loaded == false) await newSound.load({autoplay:true});
newSound.on('end', ()=>{
if (repeat == false) {
this.activeSounds[soundNr] = undefined;
this.updateAll();
}
});
newSound.play({loop:repeat,volume:volume});
this.activeSounds[soundNr] = newSound;
}
else {
let howl = new Howl({src, volume, loop: repeat, onend: (id)=>{
if (repeat == false){
this.activeSounds[soundNr] = undefined;
this.updateAll();
}
},
onstop: ()=>{
let newSound = new Sound(src);
if(newSound.loaded == false) await newSound.load({autoplay:true});
newSound.on('end', ()=>{
if (repeat == false) {
this.activeSounds[soundNr] = undefined;
this.updateAll();
}});
howl.play();
this.activeSounds[soundNr] = howl;
}
}
});
newSound.play({loop:repeat,volume:volume});
this.activeSounds[soundNr] = newSound;
}
else {
if (this.activeSounds[soundNr] != undefined) this.activeSounds[soundNr].stop();

View File

@@ -1,11 +1,11 @@
import * as MODULE from "../MaterialDeck.js";
import {streamDeck, macroControl, otherControls, tokenHelper} from "../MaterialDeck.js";
import { compatibleCore } from "./misc.js";
import { streamDeck, macroControl, otherControls, tokenHelper, getPermission } from "../../MaterialDeck.js";
import { compatibleCore } from "../misc.js";
export class TokenControl{
constructor(){
this.active = false;
this.wildcardOffset = 0;
this.itemOffset = 0;
}
async update(tokenId=null){
@@ -29,7 +29,7 @@ export class TokenControl{
const tokenIdentifier = settings.tokenName ? settings.tokenName : '';
const prependTitle = settings.prependTitle ? settings.prependTitle : '';
const mode = settings.tokenMode ? settings.tokenMode : 'token';
let validToken = false;
let token;
if (settings.combatTrackerMode) token = tokenHelper.getTokenFromTokenId(tokenId);
@@ -43,11 +43,11 @@ export class TokenControl{
let uses = undefined;
let hp = undefined;
if (validToken) {
if (token.owner == false && token.observer == true && MODULE.getPermission('TOKEN','OBSERVER') == false ) {
if (token.owner == false && token.observer == true && getPermission('TOKEN','OBSERVER') == false ) {
streamDeck.noPermission(context,device);
return;
}
if (token.owner == false && token.observer == false && MODULE.getPermission('TOKEN','NON_OWNED') == false ) {
if (token.owner == false && token.observer == false && getPermission('TOKEN','NON_OWNED') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -58,16 +58,16 @@ export class TokenControl{
const permission = token.actor?.permission;
if (settings.combat){
if (permission == 0 && MODULE.getPermission('COMBAT','DISPLAY_ALL_NAMES') == false) txt = "";
else if (permission == 1 && MODULE.getPermission('COMBAT','DISPLAY_LIMITED_NAME') == false) txt = "";
else if (permission == 2 && MODULE.getPermission('COMBAT','DISPLAY_OBSERVER_NAME') == false) txt = "";
if (permission == 0 && getPermission('COMBAT','DISPLAY_ALL_NAMES') == false) txt = "";
else if (permission == 1 && getPermission('COMBAT','DISPLAY_LIMITED_NAME') == false) txt = "";
else if (permission == 2 && getPermission('COMBAT','DISPLAY_OBSERVER_NAME') == false) txt = "";
if (permission == 0 && stats == 'HP') stats = 'none';
else if (stats == 'HP' && permission == 1 && MODULE.getPermission('COMBAT','DISPLAY_LIMITED_HP') == false) stats = 'none';
else if (stats == 'HP' && permission == 2 && MODULE.getPermission('COMBAT','DISPLAY_OBSERVER_HP') == false) stats = 'none';
else if (stats != 'HP' && permission < 3 && MODULE.getPermission('COMBAT','DISPLAY_NON_OWNED_STATS') == false) stats = 'none';
else if (stats == 'HP' && permission == 1 && getPermission('COMBAT','DISPLAY_LIMITED_HP') == false) stats = 'none';
else if (stats == 'HP' && permission == 2 && getPermission('COMBAT','DISPLAY_OBSERVER_HP') == false) stats = 'none';
else if (stats != 'HP' && permission < 3 && getPermission('COMBAT','DISPLAY_NON_OWNED_STATS') == false) stats = 'none';
}
else if (MODULE.getPermission('TOKEN','STATS') == false) {
else if (getPermission('TOKEN','STATS') == false) {
statsOld = stats;
stats = 'none';
}
@@ -231,12 +231,12 @@ export class TokenControl{
}
if (settings.onClick == 'visibility') { //toggle visibility
if (MODULE.getPermission('TOKEN','VISIBILITY') == false ) {
if (getPermission('TOKEN','VISIBILITY') == false ) {
streamDeck.noPermission(context,device);
return;
}
ring = 1;
if (token.data.hidden){
if (compatibleCore('10.0') ? token.document.hidden : token.data.hidden){
ring = 2;
ringColor = "#FF7B00";
}
@@ -246,7 +246,7 @@ export class TokenControl{
}
}
else if (settings.onClick == 'combatState') { //toggle combat state
if (MODULE.getPermission('TOKEN','COMBAT') == false ) {
if (getPermission('TOKEN','COMBAT') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -271,7 +271,7 @@ export class TokenControl{
}
}
else if (settings.onClick == 'condition') { //handle condition
if (MODULE.getPermission('TOKEN','CONDITIONS') == false ) {
if (getPermission('TOKEN','CONDITIONS') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -286,7 +286,7 @@ export class TokenControl{
}
}
else if (settings.onClick == 'cubCondition') { //Combat Utility Belt conditions
if (MODULE.getPermission('TOKEN','CONDITIONS') == false ) {
if (getPermission('TOKEN','CONDITIONS') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -303,7 +303,7 @@ export class TokenControl{
}
}
else if (settings.onClick == 'wildcard') { //wildcard images
if (MODULE.getPermission('TOKEN','WILDCARD') == false ) {
if (getPermission('TOKEN','WILDCARD') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -316,7 +316,7 @@ export class TokenControl{
let currentImgNr = 0
let imgNr;
for (let i=0; i<images.length; i++)
if (images[i] == token.data.img){
if (images[i] == tokenHelper.getTokenIcon(token)){
currentImgNr = i;
break;
}
@@ -342,32 +342,61 @@ export class TokenControl{
else if (settings.onClick == 'initiative') //Initiative
iconSrc = "modules/MaterialDeck/img/token/init.png";
}
else if (mode == 'offset') {
iconSrc = "modules/MaterialDeck/img/black.png";
const itemOffset = settings.itemOffset ? settings.itemOffset : 0;
ringColor = settings.offRing ? settings.offRing : '#000000';
const ringOnColor = settings.onRing ? settings.onRing : '#00FF00';
ring = 1;
if (itemOffset == this.itemOffset) {
ring = 2;
ringColor = ringOnColor;
}
}
else if (mode == 'offsetRel') {
}
else if (mode == 'dispOffset') {
iconSrc = "modules/MaterialDeck/img/black.png";
const prependTitle = settings.offsetPrepend ? settings.offsetPrepend : '';
txt += prependTitle + this.itemOffset;
}
//Items
else {
txt += prependTitle;
const allItems = token.actor.items;
const itemNr = settings.itemNr ? settings.itemNr - 1 : 0;
let itemNr = settings.itemNr ? settings.itemNr - 1 : 0;
itemNr += this.itemOffset;
const displayUses = settings.displayUses ? settings.displayUses : false;
const displayName = settings.displayInventoryName ? settings.displayInventoryName : false;
const displayIcon = settings.displayInventoryIcon ? settings.displayInventoryIcon : false;
const selectionMode = settings.inventorySelection ? settings.inventorySelection : 'order';
let items = allItems;
let item;
if (mode == 'inventory') {
items = tokenHelper.getItems(token,settings.inventoryType);
items = this.sortItems(items);
item = items[itemNr];
if (selectionMode == 'order') item = items[itemNr];
else if (selectionMode == 'name') item = items.filter(i => i.name == settings.itemName)[0];
else if (selectionMode == 'id') item = items.filter(i => i.id == settings.itemName)[0];
if (item != undefined && displayUses) uses = tokenHelper.getItemUses(item);
}
else if (mode == 'features') {
items = tokenHelper.getFeatures(token,settings.featureType);
items = this.sortItems(items);
item = items[itemNr];
if (selectionMode == 'order') item = items[itemNr];
else if (selectionMode == 'name') item = items.filter(i => i.name == settings.itemName)[0];
else if (selectionMode == 'id') item = items.filter(i => i.id == settings.itemName)[0];
if (item != undefined && displayUses) uses = tokenHelper.getFeatureUses(item);
}
else if (mode == 'spellbook') {
items = tokenHelper.getSpells(token,settings.spellType);
items = this.sortItems(items);
item = items[itemNr];
if (selectionMode == 'order') item = items[itemNr];
else if (selectionMode == 'name') item = items.filter(i => i.name == settings.itemName)[0];
else if (selectionMode == 'id') item = items.filter(i => i.id == settings.itemName)[0];
if (displayUses && item != undefined) uses = tokenHelper.getSpellUses(token,settings.spellType,item);
}
if (item != undefined) {
@@ -382,7 +411,7 @@ export class TokenControl{
if (mode == 'token') {
iconSrc += "";
if (settings.onClick == 'visibility') { //toggle visibility
if (MODULE.getPermission('TOKEN','VISIBILITY') == false ) {
if (getPermission('TOKEN','VISIBILITY') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -393,7 +422,7 @@ export class TokenControl{
}
}
else if (settings.onClick == 'combatState') { //toggle combat state
if (MODULE.getPermission('TOKEN','COMBAT') == false ) {
if (getPermission('TOKEN','COMBAT') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -411,7 +440,7 @@ export class TokenControl{
}
}
else if (settings.onClick == 'condition') { //toggle condition
if (MODULE.getPermission('TOKEN','CONDITIONS') == false ) {
if (getPermission('TOKEN','CONDITIONS') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -420,7 +449,7 @@ export class TokenControl{
if (icon == 'stats') iconSrc = tokenHelper.getConditionIcon(settings.condition);
}
else if (settings.onClick == 'cubCondition') { //Combat Utility Belt conditions
if (MODULE.getPermission('TOKEN','CONDITIONS') == false ) {
if (getPermission('TOKEN','CONDITIONS') == false ) {
streamDeck.noPermission(context,device);
return;
}
@@ -434,9 +463,9 @@ export class TokenControl{
}
}
}
if (icon == 'stats'){
if (MODULE.getPermission('TOKEN','STATS') == false) stats = statsOld;
if (icon == 'stats' && mode != 'offset' && mode != 'offsetRel'){
if (getPermission('TOKEN','STATS') == false) stats = statsOld;
if (stats == 'HP') //HP
iconSrc = "modules/MaterialDeck/img/token/hp_empty.png";
if (stats == 'TempHP') //Temp HP
@@ -503,13 +532,15 @@ export class TokenControl{
iconSrc = "modules/MaterialDeck/img/move/rotateccw.png";
}
}
streamDeck.setIcon(context,device,iconSrc,{background:background,ring:ring,ringColor:ringColor,overlay:overlay,uses:uses,hp:hp});
streamDeck.setTitle(txt,context);
}
sortItems(items) {
let sorted = Object.values(items);
sorted.sort((a,b) => a.data.sort - b.data.sort);
if (compatibleCore('10.0')) sorted.sort((a,b) => a.sort - b.sort);
else sorted.sort((a,b) => a.data.sort - b.data.sort);
return sorted;
}
@@ -522,13 +553,11 @@ export class TokenControl{
const tokenIdentifier = settings.tokenName ? settings.tokenName : '';
const mode = settings.tokenMode ? settings.tokenMode : 'token';
let token;
if (selection == 'selected') token = canvas.tokens.controlled[0];
else token = tokenHelper.getToken(selection,tokenIdentifier);
let token = tokenHelper.getToken(selection,tokenIdentifier);
if (token == undefined) return;
if (token.owner == false && token.observer == true && MODULE.getPermission('TOKEN','OBSERVER') == false ) return;
if (token.owner == false && token.observer == false && MODULE.getPermission('TOKEN','NON_OWNED') == false ) return;
if (token.owner == false && token.observer == true && getPermission('TOKEN','OBSERVER') == false ) return;
if (token.owner == false && token.observer == false && getPermission('TOKEN','NON_OWNED') == false ) return;
if (mode == 'token') {
@@ -565,18 +594,18 @@ export class TokenControl{
else token.sheet.close();
}
else if (onClick == 'visibility') { //Toggle visibility
if (MODULE.getPermission('TOKEN','VISIBILITY') == false ) return;
if (getPermission('TOKEN','VISIBILITY') == false ) return;
token.toggleVisibility();
}
else if (onClick == 'combatState') { //Toggle combat state
if (MODULE.getPermission('TOKEN','COMBAT') == false ) return;
if (getPermission('TOKEN','COMBAT') == false ) return;
token.toggleCombat();
}
else if (onClick == 'target') { //Target token
token.setTarget(!token.isTargeted,{releaseOthers:false});
}
else if (onClick == 'condition') { //Handle condition
if (MODULE.getPermission('TOKEN','CONDITIONS') == false ) return;
if (getPermission('TOKEN','CONDITIONS') == false ) return;
const func = settings.conditionFunction ? settings.conditionFunction : 'toggle';
if (func == 'toggle'){ //toggle
@@ -594,7 +623,7 @@ export class TokenControl{
}
else if (onClick == 'cubCondition') { //Combat Utility Belt conditions
if (MODULE.getPermission('TOKEN','CONDITIONS') == false ) return;
if (getPermission('TOKEN','CONDITIONS') == false ) return;
const condition = settings.cubConditionName;
if (condition == undefined || condition == '') return;
const effect = CONFIG.statusEffects.find(e => e.label === condition);
@@ -602,57 +631,108 @@ export class TokenControl{
this.update(tokenId);
}
else if (onClick == 'vision'){
if (MODULE.getPermission('TOKEN','VISION') == false ) return;
const token = canvas.tokens.children[0].children.find(p => p.id == tokenId);
if (token == undefined) return;
let tokenData = token.data;
if (getPermission('TOKEN','VISION') == false ) return;
const dimVision = parseInt(settings.dimVision);
const brightVision = parseInt(settings.brightVision);
const sightAngle = parseInt(settings.sightAngle);
const dimRadius = parseInt(settings.dimRadius);
const brightRadius = parseInt(settings.brightRadius);
const emissionAngle = parseInt(settings.emissionAngle);
const lightColor = settings.lightColor ? settings.lightColor : '#000000';
const colorIntensity = isNaN(parseInt(settings.colorIntensity)) ? 0 : parseInt(settings.colorIntensity)/100;
const animationType = settings.animationType ? settings.animationType : 'none';
const animationSpeed = isNaN(parseInt(settings.animationSpeed)) ? 1 : parseInt(settings.animationSpeed);
const animationIntensity = isNaN(parseInt(settings.animationIntensity)) ? 1 : parseInt(settings.animationIntensity);
let data = {};
if (isNaN(dimVision)==false) data.dimSight = dimVision;
if (isNaN(brightVision)==false) data.brightSight = brightVision;
if (isNaN(sightAngle)==false) data.sightAngle = sightAngle;
let light = {};
if (isNaN(dimRadius)==false) light.dim = dimRadius;
if (isNaN(brightRadius)==false) light.bright = brightRadius;
if (isNaN(emissionAngle)==false) light.angle = emissionAngle;
light.color = lightColor;
light.alpha = Math.sqrt(colorIntensity).toNearest(0.05)
let animation = {
type: '',
speed: tokenData.light.animation.speed,
intensity: tokenData.light.animation.intensity
};
if (animationType != 'none'){
animation.type = animationType;
animation.intensity = animationIntensity;
animation.speed = animationSpeed;
let sight = {};
let light = {
animation: {}
}
light.animation = animation;
data.light = light;
if (compatibleCore('0.8.1')) token.document.update(data);
else token.update(data);
//Vision basic config
if (settings.visionEnabled && settings.visionEnabled != 'noChange') {
if (compatibleCore('10.0')) {
if (settings.visionEnabled == 'toggle')
sight.enabled = !token.document.sight.enabled;
else
sight.enabled = settings.visionEnabled == 'enable';
}
else {
if (settings.visionEnabled == 'toggle')
sight.vision = !token.data.vision;
else
sight.vision = settings.visionEnabled == 'enable';
}
}
if (settings.visionRange && isNaN(settings.visionRange) == false) sight.range = parseInt(settings.visionRange);
if (settings.visionDimRange && isNaN(settings.visionDimRange) == false) sight.dimSight = parseInt(settings.visionDimRange);
if (settings.visionBrightRange && isNaN(settings.visionBrightRange) == false) sight.brightSight = parseInt(settings.visionBrightRange);
if (compatibleCore('10.0') && settings.visionAngle && isNaN(settings.visionAngle) == false) sight.angle = parseInt(settings.visionAngle);
else if (!compatibleCore('10.0') && settings.visionAngle && isNaN(settings.visionAngle) == false) sight.sightAngle = parseInt(settings.visionAngle);
if (settings.visionMode && settings.visionMode != 'noChange') sight.visionMode = settings.visionMode;
//Vision detection modes
let detectionModes = token.document.detectionModes;
if (settings.visionDetectionModeEnable && settings.visionDetectionModeEnable != 'noChange' && settings.visionDetectionModeNumber && detectionModes[settings.visionDetectionModeNumber-1] != undefined) {
if (settings.visionDetectionModeEnable == 'toggle')
detectionModes[settings.visionDetectionModeNumber-1].enabled = !detectionModes[settings.visionDetectionModeNumber-1].enabled;
else if (settings.visionDetectionModeEnable == 'enable')
detectionModes[settings.visionDetectionModeNumber-1].enabled = true;
else if (settings.visionDetectionModeEnable == 'disable')
detectionModes[settings.visionDetectionModeNumber-1].enabled = false;
detectionModes = detectionModes;
}
//Vision advanced options
if (settings.visionColorEnable) sight.color = settings.visionColor ? (settings.visionColor == '#000000' ? null : settings.visionColor) : null;
if (settings.visionAttenuationEnable) sight.attenuation = settings.visionAttenuation ? parseFloat(settings.visionAttenuation) : 0;
if (settings.visionBrightnessEnable) sight.brightness = settings.visionBrightness ? parseFloat(settings.visionBrightness) : 0;
if (settings.visionSaturationEnable) sight.saturation = settings.visionSaturation ? parseFloat(settings.visionSaturation) : 0;
if (settings.visionContrastEnable) sight.contrast = settings.visionContrast ? parseFloat(settings.visionContrast) : 0;
//Light basic config
if (settings.lightDimRadius && isNaN(settings.lightDimRadius) == false) light.dim = parseInt(settings.lightDimRadius);
if (settings.lightBrightRadius && isNaN(settings.lightBrightRadius) == false) light.bright = parseInt(settings.lightBrightRadius);
if (settings.lightEmissionAngle && isNaN(settings.lightEmissionAngle) == false) light.angle = parseInt(settings.lightEmissionAngle);
if (settings.lightColorEnable) light.color = settings.lightColor ? (settings.lightColor == '#000000' ? null : settings.lightColor) : null;
if (settings.lightColorIntensityEnable) light.alpha = settings.lightColorIntensity ? parseFloat(settings.lightColorIntensity) : 0;
//Light animation
if (settings.lightAnimationType && settings.lightAnimationType != 'noChange') light.animation.type = settings.lightAnimationType == 'none' ? null : settings.lightAnimationType;
if (settings.lightAnimationSpeedEnable) light.animation.speed = settings.lightAnimationSpeed ? parseFloat(settings.lightAnimationSpeed) : 5;
if (settings.lightAnimationReverseDirection && settings.lightAnimationReverseDirection != 'noChange') {
if (settings.lightAnimationReverseDirection == 'toggle')
light.animation.reverse = compatibleCore('10.0') ? !token.document.light.animation.reverse : !token.data.light.animation.reverse;
else if (settings.lightAnimationReverseDirection == 'enable')
light.animation.reverse = true;
else if (settings.lightAnimationReverseDirection == 'disable')
light.animation.reverse = false;
}
if (settings.lightAnimationIntensityEnable) light.animation.intensity = settings.lightAnimationIntensity ? parseFloat(settings.lightAnimationIntensity) : 5;
//Light advanced options
if (settings.lightColorationTechnique && settings.lightColorationTechnique != 'noChange') light.coloration = parseInt(settings.lightColorationTechnique);
if (settings.lightLuminosityEnable) light.luminosity = settings.lightLuminosity ? parseFloat(settings.lightLuminosity) : 0.5;
if (settings.lightGradualIllumination && settings.lightGradualIllumination != 'noChange') {
if (settings.lightGradualIllumination == 'toggle')
light.gradual = !token.data.light.gradual;
else if (settings.lightGradualIllumination == 'enable')
light.gradual = true;
else if (settings.lightGradualIllumination == 'disable')
light.gradual = false;
}
if (settings.lightAttenuationEnable) light.attenuation = settings.lightAttenuation ? parseFloat(settings.lightAttenuation) : 0.5;
if (settings.lightSaturationEnable) light.saturation = settings.lightSaturation ? parseFloat(settings.lightSaturation) : 0;
if (settings.lightContrastEnable) light.contrast = settings.lightContrast ? parseFloat(settings.lightContrast) : 0;
if (settings.lightShadowsEnable) light.shadows = settings.lightShadows ? parseFloat(settings.lightShadows) : 0;
let data;
if (compatibleCore('10.0')) {
data = {
sight,
light
}
}
else {
data = sight;
data.light = light;
}
token.document.update(data);
}
else if (onClick == 'initiative'){
tokenHelper.toggleInitiative(token);
}
else if (onClick == 'wildcard') { //wildcard images
if (MODULE.getPermission('TOKEN','WILDCARD') == false ) return;
if (getPermission('TOKEN','WILDCARD') == false ) return;
const method = settings.wildcardMethod ? settings.wildcardMethod : 'iterate';
let value = parseInt(settings.wildcardValue);
if (isNaN(value)) value = 1;
@@ -663,7 +743,7 @@ export class TokenControl{
if (method == 'iterate'){
let currentImgNr = 0
for (let i=0; i<images.length; i++)
if (images[i] == token.data.img){
if (images[i] == tokenHelper.getTokenIcon(token)){
currentImgNr = i;
break;
}
@@ -684,8 +764,7 @@ export class TokenControl{
else return;
iconSrc = images[imgNr];
if (compatibleCore('0.8.1')) token.document.update({img: iconSrc});
else token.update({img: iconSrc})
token.document.update({img: iconSrc});
}
else if (onClick == 'macro') { //call a macro
const settingsNew = {
@@ -712,7 +791,7 @@ export class TokenControl{
if (otherControls.rollOption != 'dialog') otherControls.setRollOption('normal');
}
else if (onClick == 'custom') {//custom onClick function
if (MODULE.getPermission('TOKEN','CUSTOM') == false ) return;
if (getPermission('TOKEN','CUSTOM') == false ) return;
const formula = settings.customOnClickFormula ? settings.customOnClickFormula : '';
if (formula == '') return;
@@ -828,8 +907,7 @@ export class TokenControl{
if (path != '') path += '.';
path += targetArray[i][j];
}
if (compatibleCore('0.8.1')) await token.document.update({[path]:value});
else await token.update({[path]:value})
await token.document.update({[path]:value});
this.update(token.id);
}
@@ -837,9 +915,20 @@ export class TokenControl{
}
}
}
else if (mode == 'offset') {
const itemOffset = settings.itemOffset ? settings.itemOffset : 0;
this.itemOffset = parseInt(itemOffset);
this.update(tokenId);
}
else if (mode == 'offsetRel') {
const itemOffset = settings.itemOffset ? settings.itemOffset : 0;
this.itemOffset += parseInt(itemOffset);
this.update(tokenId);
}
else {
const allItems = token.actor.items;
const itemNr = settings.itemNr ? settings.itemNr - 1 : 0;
const selectionMode = settings.inventorySelection ? settings.inventorySelection : 'order';
let items = allItems;
if (mode == 'inventory') {
items = tokenHelper.getItems(token,settings.inventoryType);
@@ -851,10 +940,12 @@ export class TokenControl{
items = tokenHelper.getSpells(token,settings.spellType);
}
items = this.sortItems(items);
const item = items[itemNr];
let item;
if (selectionMode == 'order') item = items[itemNr];
else if (selectionMode == 'name') item = items.filter(i => i.name == settings.itemName)[0];
else if (selectionMode == 'id') item = items.filter(i => i.id == settings.itemName)[0];
if (item != undefined) {
tokenHelper.rollItem(item, settings);
tokenHelper.rollItem(item, settings, otherControls.rollOption);
}
}

View File

@@ -1,36 +1,35 @@
import {sdVersion, msVersion, moduleName, getPermission, enableModule, streamDeck} from "../MaterialDeck.js";
import {macroControl,soundboard,playlistControl} from "../MaterialDeck.js";
import { sdVersion, msVersion, moduleName, getPermission, enableModule, streamDeck, macroControl,soundboard,playlistControl, minimumMSversion, minimumSDversion } from "../MaterialDeck.js";
export function compareVersions(checkedVersion, requiredVersion) {
requiredVersion = requiredVersion.split(".");
checkedVersion = checkedVersion.split(".");
for (let i=0; i<3; i++) {
requiredVersion[i] = isNaN(parseInt(requiredVersion[i])) ? 0 : parseInt(requiredVersion[i]);
checkedVersion[i] = isNaN(parseInt(checkedVersion[i])) ? 0 : parseInt(checkedVersion[i]);
}
if (checkedVersion[0] > requiredVersion[0]) return false;
if (checkedVersion[0] < requiredVersion[0]) return true;
if (checkedVersion[1] > requiredVersion[1]) return false;
if (checkedVersion[1] < requiredVersion[1]) return true;
if (checkedVersion[2] > requiredVersion[2]) return false;
return true;
}
}
export function compatibleCore(compatibleVersion){
const split = compatibleVersion.split(".");
if (split.length == 2) compatibleVersion = `0.${compatibleVersion}`;
let coreVersion = game.version == undefined ? game.data.version : `0.${game.version}`;
return compareVersions(compatibleVersion, coreVersion);
/*
coreVersion = coreVersion.split(".");
compatibleVersion = compatibleVersion.split(".");
if (compatibleVersion[0] > coreVersion[0]) return false;
if (compatibleVersion[0] < coreVersion[0]) return true;
if (compatibleVersion[1] > coreVersion[1]) return false;
if (compatibleVersion[1] < coreVersion[1]) return true;
if (compatibleVersion[2] > coreVersion[2]) return false;
return true;
*/
}
}
export function compatibleSystem(compatibleVersion){
const split = compatibleVersion.split(".");
if (split.length == 2) compatibleVersion = `0.${compatibleVersion}`;
let coreVersion = game.system.data.version;
return compareVersions(compatibleVersion, coreVersion);
}
export class playlistConfigForm extends FormApplication {
constructor(data, options) {
@@ -97,7 +96,7 @@ export class playlistConfigForm extends FormApplication {
}
return {
playlists: compatibleCore("0.8.1") ? game.playlists.contents : game.playlists.entities,
playlists: game.playlists.contents,
numberOfPlaylists: numberOfPlaylists,
playlistData: playlistData,
playMode: playMode
@@ -175,7 +174,7 @@ export class macroConfigForm extends FormApplication {
*/
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "macro-config",
id: "materialDeck_macroConfig",
title: "Material Deck: "+game.i18n.localize("MaterialDeck.Sett.MacroConfig"),
template: "./modules/MaterialDeck/templates/macroConfig.html",
classes: ["sheet"]
@@ -201,12 +200,12 @@ export class macroConfigForm extends FormApplication {
if (args == undefined) args = [];
//Check if the Furnace is installed and enabled
let furnaceEnabled = false;
let height = 95;
let furnace = game.modules.get("furnace");
let advancedMacrosEnabled = false;
let advancedMacros = game.modules.get("advanced-macros");
if ((furnace != undefined && furnace.active && compatibleCore("0.8.1")==false) || (advancedMacros != undefined && advancedMacros.active)) {
furnaceEnabled = true;
if (advancedMacros != undefined && advancedMacros.active) advancedMacrosEnabled = true;
if (advancedMacrosEnabled) {
advancedMacrosEnabled = true;
height += 50;
}
@@ -245,7 +244,7 @@ export class macroConfigForm extends FormApplication {
macros: game.macros,
selectedMacros: selectedMacros,
macroData: macroData,
furnace: furnaceEnabled,
furnace: advancedMacrosEnabled,
macroRange: `${this.page*32 + 1} - ${this.page*32 + 32}`,
prevDisabled: this.page == 0 ? 'disabled' : '',
totalMacros: Math.max(Math.ceil(selectedMacros.length/32)*32, this.page*32 + 32)
@@ -263,12 +262,12 @@ export class macroConfigForm extends FormApplication {
activateListeners(html) {
super.activateListeners(html);
const navNext = html.find("button[id='navNext']");
const navPrev = html.find("button[id='navPrev']");
const clearAll = html.find("button[id='clearAll']");
const clearPage = html.find("button[id='clearPage']");
const importBtn = html.find("button[id='import']");
const exportBtn = html.find("button[id='export']");
const navNext = html.find("button[name='navNext']");
const navPrev = html.find("button[name='navPrev']");
const clearAll = html.find("button[name='clearAll']");
const clearPage = html.find("button[name='clearPage']");
const importBtn = html.find("button[name='import']");
const exportBtn = html.find("button[name='export']");
const macro = html.find("select[name='macros']");
const args = html.find("input[name='args']");
const color = html.find("input[name='colorPicker']");
@@ -359,21 +358,21 @@ export class macroConfigForm extends FormApplication {
})
macro.on("change", event => {
let id = event.target.id.replace('macros','');
let id = event.target.id.replace('materialDeck_macroConfig_macros','');
let settings = game.settings.get(moduleName,'macroSettings');
settings.macros[id-1]=event.target.value;
this.updateSettings(settings);
});
args.on("change", event => {
let id = event.target.id.replace('args','');
let id = event.target.id.replace('materialDeck_macroConfig_args','');
let settings = game.settings.get(moduleName,'macroSettings');
settings.args[id-1]=event.target.value;
this.updateSettings(settings);
});
color.on("change", event => {
let id = event.target.id.replace('colorpicker','');
let id = event.target.id.replace('materialDeck_macroConfig_colorpicker','');
let settings = game.settings.get(moduleName,'macroSettings');
settings.color[id-1]=event.target.value;
this.updateSettings(settings);
@@ -453,7 +452,7 @@ export class soundboardConfigForm extends FormApplication {
*/
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "soundboard-config",
id: "materialDeck_soundboardConfig",
title: "Material Deck: "+game.i18n.localize("MaterialDeck.Sett.SoundboardConfig"),
template: "./modules/MaterialDeck/templates/soundboardConfig.html",
classes: ["sheet"],
@@ -489,7 +488,7 @@ export class soundboardConfigForm extends FormApplication {
playlists.push({id:"none",name:game.i18n.localize("MaterialDeck.None")});
playlists.push({id:"FP",name:game.i18n.localize("MaterialDeck.FilePicker")})
const playlistArray = compatibleCore("0.8.1") ? game.playlists.contents : game.playlists.entities;
const playlistArray = game.playlists.contents;
for (let playlist of playlistArray)
playlists.push({id: playlist.id, name: playlist.name})
@@ -515,7 +514,7 @@ export class soundboardConfigForm extends FormApplication {
else if (this.settings.selectedPlaylists[iteration] == 'FP') selectedPlaylist = 'FP';
else {
//Get the playlist
const playlistArray = compatibleCore("0.8.1") ? game.playlists.contents : game.playlists.entities;
const playlistArray = game.playlists.contents;
let pl = playlistArray.find(p => p.id == this.settings.selectedPlaylists[iteration])
if (pl == undefined){
@@ -524,19 +523,12 @@ export class soundboardConfigForm extends FormApplication {
}
else {
//Add the sound name and id to the sounds array
if (compatibleCore("0.8.1"))
for (let sound of pl.sounds.contents)
sounds.push({
name: sound.name,
id: sound.id
});
else {
for (let sound of pl.sounds)
sounds.push({
name: sound.name,
id: sound._id
});
}
for (let sound of pl.sounds.contents)
sounds.push({
name: sound.name,
id: sound.id
});
//Get the playlist id
selectedPlaylist = pl.id;
}
@@ -557,8 +549,8 @@ export class soundboardConfigForm extends FormApplication {
sound: this.settings.sounds[iteration],
sounds: sounds,
srcPath: this.settings.src[iteration],
colorOn: this.settings.colorOn[iteration],
colorOff: this.settings.colorOff[iteration],
colorOn: this.settings.colorOn[iteration] == 0 ? '#000000' : this.settings.colorOn[iteration],
colorOff: this.settings.colorOff[iteration] == 0 ? '#000000' : this.settings.colorOff[iteration],
mode: this.settings.mode[iteration],
volume: this.settings.volume[iteration],
imgPath: this.settings.img[iteration],
@@ -576,7 +568,7 @@ export class soundboardConfigForm extends FormApplication {
//Push soundsThis (row array) to soundData (full data array)
soundData.push({dataThis: soundsThis});
}
return {
soundData: soundData,
playlists,
@@ -597,12 +589,12 @@ export class soundboardConfigForm extends FormApplication {
async activateListeners(html) {
super.activateListeners(html);
const navNext = html.find("button[id='navNext']");
const navPrev = html.find("button[id='navPrev']");
const clearAll = html.find("button[id='clearAll']");
const clearPage = html.find("button[id='clearPage']");
const importBtn = html.find("button[id='import']");
const exportBtn = html.find("button[id='export']");
const navNext = html.find("button[name='navNext']");
const navPrev = html.find("button[name='navPrev']");
const clearAll = html.find("button[name='clearAll']");
const clearPage = html.find("button[name='clearPage']");
const importBtn = html.find("button[name='import']");
const exportBtn = html.find("button[name='export']");
const nameField = html.find("input[name='namebox']");
const playlistSelect = html.find("select[name='playlist']");
const soundSelect = html.find("select[name='sounds']");
@@ -697,7 +689,7 @@ export class soundboardConfigForm extends FormApplication {
})
nameField.on("change",event => {
let id = event.target.id.replace('name','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_name','')-1;
this.settings.name[id]=event.target.value;
this.updateSettings(this.settings);
});
@@ -707,7 +699,7 @@ export class soundboardConfigForm extends FormApplication {
//Listener for when the playlist is changed
playlistSelect.on("change", event => {
//Get the sound number
const iteration = event.target.id.replace('playlists','');
const iteration = event.target.id.replace('materialDeck_sbConfig_playlists','');
//Get the selected playlist and the sounds of that playlist
let selectedPlaylist;
@@ -718,24 +710,24 @@ export class soundboardConfigForm extends FormApplication {
selectedPlaylist = 'FP';
//Show the file picker
document.querySelector(`#fp${iteration}`).style='';
document.querySelector(`#materialDeck_sbConfig_fp${iteration}`).style='';
//Hide the sound selector
document.querySelector(`#ss${iteration}`).style='display:none';
document.querySelector(`#materialDeck_sbConfig_ss${iteration}`).style='display:none';
}
else {
//Hide the file picker
document.querySelector(`#fp${iteration}`).style='display:none';
document.querySelector(`#materialDeck_sbConfig_fp${iteration}`).style='display:none';
//Show the sound selector
document.querySelector(`#ss${iteration}`).style='';
document.querySelector(`#materialDeck_sbConfig_ss${iteration}`).style='';
const playlistArray = compatibleCore("0.8.1") ? game.playlists.contents : game.playlists.entities;
const playlistArray = game.playlists.contents;
const pl = playlistArray.find(p => p.id == event.target.value)
selectedPlaylist = pl.id;
//Get the sound select element
let SSpicker = document.getElementById(`soundSelect${iteration}`);
let SSpicker = document.getElementById(`materialDeck_sbConfig_soundSelect${iteration}`);
//Empty ss element
SSpicker.options.length=0;
@@ -746,20 +738,12 @@ export class soundboardConfigForm extends FormApplication {
optionNone.innerHTML = game.i18n.localize("MaterialDeck.None");
SSpicker.appendChild(optionNone);
if (compatibleCore("0.8.1"))
for (let sound of pl.sounds.contents) {
let newOption = document.createElement('option');
newOption.value = sound.id;
newOption.innerHTML = sound.name;
SSpicker.appendChild(newOption);
}
else
for (let sound of pl.sounds) {
let newOption = document.createElement('option');
newOption.value = sound._id;
newOption.innerHTML = sound.name;
SSpicker.appendChild(newOption);
}
for (let sound of pl.sounds.contents) {
let newOption = document.createElement('option');
newOption.value = sound.id;
newOption.innerHTML = sound.name;
SSpicker.appendChild(newOption);
}
}
//Save the new playlist to this.settings, and update the settings
@@ -769,43 +753,43 @@ export class soundboardConfigForm extends FormApplication {
}
soundSelect.on("change", event => {
let id = event.target.id.replace('soundSelect','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_soundSelect','')-1;
this.settings.sounds[id]=event.target.value;
this.updateSettings(this.settings);
});
soundFP.on("change",event => {
let id = event.target.id.replace('srcPath','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_srcPath','')-1;
this.settings.src[id]=event.target.value;
this.updateSettings(this.settings);
});
imgFP.on("change",event => {
let id = event.target.id.replace('imgPath','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_imgPath','')-1;
this.settings.img[id]=event.target.value;
this.updateSettings(this.settings);
});
onCP.on("change",event => {
let id = event.target.id.replace('colorOn','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_colorOn','')-1;
this.settings.colorOn[id]=event.target.value;
this.updateSettings(this.settings);
});
offCP.on("change",event => {
let id = event.target.id.replace('colorOff','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_colorOff','')-1;
this.settings.colorOff[id]=event.target.value;
this.updateSettings(this.settings);
});
playMode.on("change",event => {
let id = event.target.id.replace('playmode','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_playmode','')-1;
this.settings.mode[id]=event.target.value;
this.updateSettings(this.settings);
});
volume.on("change",event => {
let id = event.target.id.replace('volume','')-1;
let id = event.target.id.replace('materialDeck_sbConfig_volume','')-1;
this.settings.volume[id]=event.target.value;
this.updateSettings(this.settings);
});
@@ -904,7 +888,7 @@ export class exportConfigForm extends FormApplication {
*/
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "MD_Export",
id: "materialDeck_Export",
title: "Material Deck: " + game.i18n.localize("MaterialDeck.ExportDialog.Title"),
template: "./modules/MaterialDeck/templates/exportDialog.html",
width: 500,
@@ -967,7 +951,7 @@ export class importConfigForm extends FormApplication {
*/
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "MD_Import",
id: "materialDeck_Import",
title: "Material Deck: " + game.i18n.localize("MaterialDeck.ImportDialog.Title"),
template: "./modules/MaterialDeck/templates/importDialog.html",
width: 500,
@@ -1005,7 +989,7 @@ export class importConfigForm extends FormApplication {
activateListeners(html) {
super.activateListeners(html);
const upload = html.find("input[id='uploadJson']");
const upload = html.find("input[id='materialDeck_import_uploadJson']");
upload.on('change',(event) => {
event.preventDefault();
@@ -1052,7 +1036,7 @@ export class downloadUtility extends FormApplication {
*/
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "MD_DownloadUtility",
id: "materialDeck_downloadUtility",
title: "Material Deck: " + game.i18n.localize("MaterialDeck.DownloadUtility.Title"),
template: "./modules/MaterialDeck/templates/downloadUtility.html",
width: 500,
@@ -1077,24 +1061,13 @@ export class downloadUtility extends FormApplication {
}
}
if (this.localMSversion == undefined) this.localMSversion = 'unknown';
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;
}
return {
minimumSdVersion,
minimumSdVersion: minimumSDversion,
localSdVersion: this.localSDversion,
masterSdVersion: this.masterSDversion,
sdDlDisable: this.masterSDversion == undefined,
minimumMsVersion,
minimumMsVersion: minimumMSversion,
localMsVersion: this.localMSversion,
masterMsVersion: this.masterMSversion,
msDlDisable: this.masterMSversion == undefined,
@@ -1115,20 +1088,20 @@ export class downloadUtility extends FormApplication {
activateListeners(html) {
super.activateListeners(html);
const downloadSd = html.find("button[id='downloadSd']");
const downloadMs = html.find("button[id='downloadMs']");
const downloadSd = html.find("button[id='materialDeck_dlUtil_downloadSd']");
const downloadMs = html.find("button[id='materialDeck_dlUtil_downloadMs']");
const downloadProfile = html.find("button[name='downloadProfile']")
const refresh = html.find("button[id='refresh']");
const refresh = html.find("button[id='materialDeck_dlUtil_refresh']");
downloadSd.on('click', () => {
const version = document.getElementById('masterSdVersion').innerHTML;
const version = document.getElementById('materialDeck_dlUtil_masterSdVersion').innerHTML;
if (version == '' || version == undefined || version == 'Error') return;
const url = `https://github.com/CDeenen/MaterialDeck_SD/releases/download/v${version}/com.cdeenen.materialdeck.streamDeckPlugin`;
this.downloadURI(url,'com.cdeenen.materialdeck.streamDeckPlugin')
})
downloadMs.on('click', () => {
const version = document.getElementById('masterMsVersion').innerHTML;
const os = document.getElementById('os').value;
const version = document.getElementById('materialDeck_dlUtil_masterMsVersion').innerHTML;
const os = document.getElementById('materialDeck_dlUtil_os').value;
if (version == '' || version == undefined || version == 'Error') return;
let name = `MaterialServer-${os}.zip`;
let url;
@@ -1137,13 +1110,13 @@ export class downloadUtility extends FormApplication {
this.downloadURI(url,name)
})
downloadProfile.on('click',(event) => {
let id = event.currentTarget.id.replace('dlProfile-','');
let id = event.currentTarget.id.replace('materialDeck_dlUtil_dlProfile-','');
this.downloadURI(this.profiles[id].url,`${this.profiles[id].label}.streamDeckProfile`);
})
refresh.on('click', () => {
document.getElementById('masterSdVersion').value = 'Getting data';
document.getElementById('materialDeck_dlUtil_masterSdVersion').value = 'Getting data';
this.checkForUpdate('SD');
document.getElementById('masterMsVersion').value = 'Getting data';
document.getElementById('materialDeck_dlUtil_masterMsVersion').value = 'Getting data';
this.checkForUpdate('MS');
this.getReleaseData();
})
@@ -1170,14 +1143,10 @@ export class downloadUtility extends FormApplication {
const data = JSON.parse(request.responseText);
parent.releaseAssets = data.assets;
parent.render(true);
if (type.indexOf("text") !== 1) {
return;
}
if (type.indexOf("text") !== 1) return;
}
}
request.onerror = function () {
}
request.onerror = function () {}
}
checkForUpdate(reqType) {
@@ -1185,7 +1154,7 @@ export class downloadUtility extends FormApplication {
let url;
if (reqType == 'SD') url = 'https://raw.githubusercontent.com/CDeenen/MaterialDeck_SD/master/Plugin/com.cdeenen.materialdeck.sdPlugin/manifest.json';
else if (reqType == 'MS') url = 'https://raw.githubusercontent.com/CDeenen/MaterialServer/master/package.json';
const elementId = reqType == 'SD' ? 'masterSdVersion' : 'masterMsVersion';
const elementId = reqType == 'SD' ? 'materialDeck_dlUtil_masterSdVersion' : 'materialDeck_dlUtil_masterMsVersion';
var request = new XMLHttpRequest();
request.open('GET', url, true);
@@ -1199,7 +1168,6 @@ export class downloadUtility extends FormApplication {
parent.render(true);
return;
}
}
}
request.onerror = function () {
@@ -1220,7 +1188,7 @@ export class deviceConfig extends FormApplication {
*/
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "MD_DeviceConfig",
id: "materialDeck_deviceConfig",
title: "Material Deck: " + game.i18n.localize("MaterialDeck.DeviceConfig.Title"),
template: "./modules/MaterialDeck/templates/deviceConfig.html",
width: 500,
@@ -1282,7 +1250,7 @@ export class deviceConfig extends FormApplication {
super.activateListeners(html);
html.find("input[name='enable']").on('change', (event) => {
const id = event.currentTarget.id;
const id = event.currentTarget.id.replace('materialDeck_devConf_','');;
for (let d of this.devices) {
if (d.id == id) {
let dConfig = game.settings.get(moduleName, 'devices');

View File

@@ -1,4 +1,4 @@
import * as MODULE from "../MaterialDeck.js";
import { moduleName, isEmpty } from "../MaterialDeck.js";
import { playlistConfigForm, macroConfigForm, soundboardConfigForm, downloadUtility, deviceConfig } from "./misc.js";
let userPermissions = {};
@@ -70,7 +70,7 @@ export const registerSettings = async function() {
//world,global,client
//Enabled the module
game.settings.register(MODULE.moduleName,'Enable', {
game.settings.register(moduleName,'Enable', {
name: "MaterialDeck.Sett.Enable",
scope: "client",
config: true,
@@ -82,20 +82,31 @@ export const registerSettings = async function() {
/**
* System override
*/
game.settings.register(MODULE.moduleName,'systemOverride', {
game.settings.register(moduleName,'systemOverride', {
name: "MaterialDeck.Sett.SystemOverride",
hint: "MaterialDeck.Sett.SystemOverrideHint",
scope: "client",
config: true,
default: "",
type: String,
choices: {
"": "Autodetect",
"D35E": "Dungeons & Dragons 3.5e",
"dnd5e": "Dungeons & Dragons 5e",
"forbidden-lands": "Forbidden Lands",
"pf1": "Pathfinder 1e",
"pf2e": "Pathfinder 2e",
"demonlord": "Shadow of the Demon Lord",
"sfrpg": "Starfinder",
"wfrp4e": "Warhammer Fantasy Roleplay 4e",
},
onChange: x => window.location.reload()
});
/**
* Sets the ip address of the server
*/
game.settings.register(MODULE.moduleName,'address', {
game.settings.register(moduleName,'address', {
name: "MaterialDeck.Sett.ServerAddr",
hint: "MaterialDeck.Sett.ServerAddrHint",
scope: "client",
@@ -105,7 +116,7 @@ export const registerSettings = async function() {
onChange: x => window.location.reload()
});
game.settings.register(MODULE.moduleName, 'imageBuffer', {
game.settings.register(moduleName, 'imageBuffer', {
name: "MaterialDeck.Sett.ImageBuffer",
hint: "MaterialDeck.Sett.ImageBufferHint",
default: 100,
@@ -116,7 +127,7 @@ export const registerSettings = async function() {
});
game.settings.register(MODULE.moduleName, 'imageBrightness', {
game.settings.register(moduleName, 'imageBrightness', {
name: "MaterialDeck.Sett.ImageBrightness",
hint: "MaterialDeck.Sett.ImageBrightnessHint",
default: 50,
@@ -127,7 +138,7 @@ export const registerSettings = async function() {
});
game.settings.register(MODULE.moduleName, 'nrOfConnMessages', {
game.settings.register(moduleName, 'nrOfConnMessages', {
name: "MaterialDeck.Sett.NrOfConnMessages",
hint: "MaterialDeck.Sett.NrOfConnMessagesHint",
default: 5,
@@ -139,59 +150,61 @@ export const registerSettings = async function() {
});
//Create the Help button
game.settings.registerMenu(MODULE.moduleName, 'helpMenu',{
game.settings.registerMenu(moduleName, 'helpMenu',{
name: "MaterialDeck.Sett.Help",
label: "MaterialDeck.Sett.Help",
type: helpMenu,
restricted: false
});
game.settings.registerMenu(MODULE.moduleName, 'downloadUtility',{
game.settings.registerMenu(moduleName, 'downloadUtility',{
name: "MaterialDeck.DownloadUtility.Title",
label: "MaterialDeck.DownloadUtility.Title",
type: downloadUtility,
restricted: false
});
game.settings.registerMenu(MODULE.moduleName, 'deviceConfig',{
game.settings.registerMenu(moduleName, 'deviceConfig',{
name: "MaterialDeck.DeviceConfig.Title",
label: "MaterialDeck.DeviceConfig.Title",
type: deviceConfig,
restricted: false
});
game.settings.register(MODULE.moduleName, 'devices', {
game.settings.register(moduleName, 'devices', {
name: "devices",
scope: "client",
type: Object,
config: false
});
game.settings.registerMenu(MODULE.moduleName, 'permissionConfig',{
game.settings.registerMenu(moduleName, 'permissionConfig',{
name: "MaterialDeck.Sett.Permission",
label: "MaterialDeck.Sett.Permission",
type: userPermission,
restricted: true
});
game.settings.register(MODULE.moduleName, 'userPermission', {
game.settings.register(moduleName, 'userPermission', {
name: "userPermission",
label: "",
scope: "world",
type: Object,
config: false
config: false,
default: {}
});
/**
* Playlist soundboard
*/
game.settings.registerMenu(MODULE.moduleName, 'playlistConfigMenu',{
game.settings.registerMenu(moduleName, 'playlistConfigMenu',{
name: "MaterialDeck.Sett.PlaylistConfig",
label: "MaterialDeck.Sett.PlaylistConfig",
type: playlistConfigForm,
restricted: false
});
game.settings.register(MODULE.moduleName, 'playlists', {
game.settings.register(moduleName, 'playlists', {
name: "selectedPlaylists",
scope: "world",
type: Object,
@@ -202,21 +215,22 @@ export const registerSettings = async function() {
/**
* Macro Board
*/
game.settings.registerMenu(MODULE.moduleName, 'macroConfigMenu',{
game.settings.registerMenu(moduleName, 'macroConfigMenu',{
name: "MaterialDeck.Sett.MacroConfig",
label: "MaterialDeck.Sett.MacroConfig",
type: macroConfigForm,
restricted: false
});
game.settings.register(MODULE.moduleName, 'macroSettings', {
game.settings.register(moduleName, 'macroSettings', {
name: "macroSettings",
scope: "world",
type: Object,
config: false
config: false,
default: {}
});
game.settings.register(MODULE.moduleName, 'macroArgs', {
game.settings.register(moduleName, 'macroArgs', {
name: "macroArgs",
scope: "world",
type: Object,
@@ -226,7 +240,7 @@ export const registerSettings = async function() {
/**
* Soundboard
*/
game.settings.register(MODULE.moduleName, 'soundboardSettings', {
game.settings.register(moduleName, 'soundboardSettings', {
name: "soundboardSettings",
scope: "world",
type: Object,
@@ -234,15 +248,16 @@ export const registerSettings = async function() {
config: false
});
game.settings.registerMenu(MODULE.moduleName, 'soundboardConfigMenu',{
game.settings.registerMenu(moduleName, 'soundboardConfigMenu',{
name: "MaterialDeck.Sett.SoundboardConfig",
label: "MaterialDeck.Sett.SoundboardConfig",
type: soundboardConfigForm,
restricted: false
});
let permissionSettings = game.settings.get(MODULE.moduleName,'userPermission');
if (permissionSettings == undefined || permissionSettings == null || MODULE.isEmpty(permissionSettings)) {
let permissionSettings = game.settings.get(moduleName,'userPermission');
if (permissionSettings == undefined || permissionSettings == null || isEmpty(permissionSettings)) {
permissionSettings = {
enable: defaultEnable,
permissions: defaultUserPermissions
@@ -254,7 +269,7 @@ export const registerSettings = async function() {
if (permissionSettings.permissions.MACRO.BY_NAME == undefined) permissionSettings.permissions.MACRO.BY_NAME = [false,false,true,true];
}
if (game.user.isGM)
game.settings.set(MODULE.moduleName,'userPermission',permissionSettings);
game.settings.set(moduleName,'userPermission',permissionSettings);
}
@@ -311,7 +326,7 @@ export class helpMenu extends FormApplication {
*/
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "userPermissionConfig",
id: "materialDeck_userPermissionConfig",
title: "Material Deck: "+game.i18n.localize("MaterialDeck.Sett.Permission"),
template: "./modules/MaterialDeck/templates/userPermissionConfig.html",
width: 660,
@@ -324,18 +339,23 @@ export class helpMenu extends FormApplication {
* Provide data to the template
*/
async getData() {
let settings = game.settings.get(MODULE.moduleName,'userPermission');
if (settings == undefined || settings == null || MODULE.isEmpty(settings)) {
let settings = game.settings.get(moduleName,'userPermission');
if (settings == undefined || settings == null || isEmpty(settings)) {
settings = {
enable: defaultEnable,
permissions: defaultUserPermissions
}
}
const actions = Object.entries(duplicate(settings.permissions)).reduce((arr, e) => {
const perms = Object.entries(duplicate(e[1])).reduce((arr, p) => {
let perm = {};
perm.roles = [p[1][0],p[1][1],p[1][2],p[1][3]]
perm.roles = [
{role:'player',en:p[1][0]},
{role:'trusted',en:p[1][1]},
{role:'assistent',en:p[1][2]},
{role:'gm',en:p[1][3]}
]
perm.id = p[0];
perm.label = game.i18n.localize("MaterialDeck.Perm."+e[0]+"."+p[0]+".label");
perm.hint = game.i18n.localize("MaterialDeck.Perm."+e[0]+"."+p[0]+".hint");
@@ -355,14 +375,21 @@ export class helpMenu extends FormApplication {
if (actions[i].id == 'MOVE')
actions.splice(i,1);
}
const enable = [
{role:'player',en:settings.enable[0]},
{role:'trusted',en:settings.enable[1]},
{role:'assistent',en:settings.enable[2]},
{role:'gm',en:settings.enable[3]}
]
return {
roles: Object.keys(CONST.USER_ROLES).reduce((obj, r) => {
if ( r === "NONE" ) return obj;
obj[r] = `USER.Role${r.titleCase()}`;
return obj;
}, {}),
actions: actions,
enable: settings.enable
actions,
enable
}
}
@@ -372,12 +399,28 @@ export class helpMenu extends FormApplication {
* @param {*} formData
*/
async _updateObject(event, formData) {
let permissions = expandObject(formData);
let settings = {};
settings.enable = permissions.ENABLE;
let permissions = expandObject(formData);
for (const [key, value] of Object.entries(permissions)) {
const val = value;
let conf = {};
if (key == 'ENABLE') {
settings.enable = [value.player, value.trusted, value.assistent, value.gm];
}
else {
conf = {};
for (const [key, value] of Object.entries(val)) {
const arr = [value.player, value.trusted, value.assistent, value.gm];
conf[key] = arr;
}
}
permissions[key] = conf;
}
delete permissions.ENABLE;
settings.permissions = permissions;
// game.settings.set(MODULE.moduleName,'userPermission',settings);
game.settings.set(moduleName,'userPermission',settings);
}
async activateListeners(html) {
@@ -396,7 +439,7 @@ export class helpMenu extends FormApplication {
enable: defaultEnable,
permissions: defaultUserPermissions
}
await game.settings.set(MODULE.moduleName,'userPermission',settings);
await game.settings.set(moduleName,'userPermission',settings);
this.render();
ui.notifications.info(game.i18n.localize("MaterialDeck.Perm.DefaultNotification"));
}

View File

@@ -1,4 +1,4 @@
import * as MODULE from "../MaterialDeck.js";
import { moduleName, sendWS, tokenControl, macroControl, combatTracker, playlistControl, soundboard, otherControls, externalModules, sceneControl } from "../MaterialDeck.js";
export class StreamDeck{
constructor() {
@@ -90,14 +90,14 @@ export class StreamDeck{
}
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;
else if (action == 'external') MODULE.externalModules.active = false;
else if (action == 'scene') MODULE.sceneControl.active = false;
if (action == 'token') tokenControl.active = false;
else if (action == 'macro') macroControl.active = false;
else if (action == 'combattracker') combatTracker.active = false;
else if (action == 'playlist') playlistControl.active = false;
else if (action == 'soundboard') soundboard.active = false;
else if (action == 'other') otherControls.active = false;
else if (action == 'external') externalModules.active = false;
else if (action == 'scene') sceneControl.active = false;
}
}
@@ -204,7 +204,7 @@ export class StreamDeck{
target: 0
}
};
MODULE.sendWS(JSON.stringify(msg));
sendWS(JSON.stringify(msg));
}
setColor(context,color = '#000000'){
@@ -216,7 +216,7 @@ export class StreamDeck{
format: 'color',
background: color
};
MODULE.sendWS(JSON.stringify(msg));
sendWS(JSON.stringify(msg));
}
setImage(image,context,device,nr,id){
@@ -232,7 +232,7 @@ export class StreamDeck{
target: 0
}
};
MODULE.sendWS(JSON.stringify(json));
sendWS(JSON.stringify(json));
}
setBufferImage(context,device,nr,id){
@@ -247,7 +247,7 @@ export class StreamDeck{
target: 0
}
};
MODULE.sendWS(JSON.stringify(json));
sendWS(JSON.stringify(json));
}
setIcon(context,device,src='',options = {}){
@@ -301,6 +301,8 @@ export class StreamDeck{
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 split2 = split[0].split('-');
if (split2[0] == 'fa') format = 'icon';
let msg = {
target: "SD",
event: 'setIcon',
@@ -326,7 +328,7 @@ export class StreamDeck{
action: action,
state: state
};
MODULE.sendWS(JSON.stringify(msg));
sendWS(JSON.stringify(msg));
}
setProfile(action,device){
@@ -343,7 +345,7 @@ export class StreamDeck{
profile: profile
}
};
MODULE.sendWS(JSON.stringify(json));
sendWS(JSON.stringify(json));
}
setPluginId(id){
@@ -439,7 +441,7 @@ export class StreamDeck{
img.onload = () => {
if (format == 'color') ctx.filter = "opacity(0)";
if (data.overlay == true) ctx.filter = "brightness(" + game.settings.get(MODULE.moduleName,'imageBrightness') + "%)";
if (data.overlay == true) ctx.filter = "brightness(" + game.settings.get(moduleName,'imageBrightness') + "%)";
//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;
@@ -564,7 +566,7 @@ export class StreamDeck{
addToImageBuffer(img,data){
const id = this.getImageBufferId(data);
const maxBufferSize = game.settings.get(MODULE.moduleName,'imageBuffer');
const maxBufferSize = game.settings.get(moduleName,'imageBuffer');
if (maxBufferSize == 0) return false;
if (this.imageBufferCounter > maxBufferSize) this.imageBufferCounter = 0;
@@ -581,7 +583,7 @@ export class StreamDeck{
}
checkImageBuffer(data){
if (game.settings.get(MODULE.moduleName,'imageBuffer') == 0) return false;
if (game.settings.get(moduleName,'imageBuffer') == 0) return false;
const id = this.getImageBufferId(data);
for (let i=0; i<this.imageBuffer.length; i++){

View File

@@ -1,12 +1,20 @@
import {compatibleCore} from "../misc.js";
import { compatibleCore } from "../misc.js";
export class demonlord{
constructor(){
console.log("Material Deck: Using system 'Shadow of the Demon Lord'");
}
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
getHP(token) {
const hp = token.actor.data.data.characteristics.health;
const hp = this.getActorData(token).characteristics.health;
return {
value: hp.value,
max: hp.max
@@ -18,7 +26,7 @@ export class demonlord{
}
getAC(token) {
return token.actor.data.data.characteristics.defense;
return this.getActorData(token).characteristics.defense;
}
getShieldHP(token) {
@@ -26,11 +34,11 @@ export class demonlord{
}
getSpeed(token) {
return token.actor.data.data.characteristics.speed;
return this.getActorData(token).characteristics.speed;
}
getInitiative(token) {
return token.actor.data.data.fastturn ? "FAST" : "SLOW";
return this.getActorData(token).fastturn ? "FAST" : "SLOW";
}
toggleInitiative(token) {
@@ -50,12 +58,12 @@ export class demonlord{
getAbility(token, ability) {
if (ability == undefined) ability = 'strength';
return token.actor.data.data.attributes?.[ability].value;
return this.getActorData(token).attributes?.[ability].value;
}
getAbilityModifier(token, ability) {
if (ability == undefined) ability = 'str';
let val = token.actor.data.data.attributes?.[ability].modifier;
let val = this.getActorData(token).attributes?.[ability].modifier;
return (val >= 0) ? `+${val}` : val;
}
@@ -65,7 +73,7 @@ export class demonlord{
getSkill(token, skill) {
if (skill == undefined) skill = 'acr';
const val = token.actor.data.data.skills?.[skill].total;
const val = this.getActorData(token).skills?.[skill].total;
return (val >= 0) ? `+${val}` : val;
}
@@ -114,7 +122,7 @@ export class demonlord{
}
getItemUses(item) {
return {available: item.data.data.quantity};
return {available: getItemData(item).quantity};
}
/**
@@ -124,7 +132,7 @@ export class demonlord{
if (level == undefined) level = 'any';
const allItems = token.actor.items;
if (level == 'any') return allItems.filter(i => i.type == 'spell')
else return allItems.filter(i => i.type == 'spell' && i.data.data.rank == level)
else return allItems.filter(i => i.type == 'spell' && getItemData(i).rank == level)
}
getSpellUses(token,level,item) {

View File

@@ -1,12 +1,20 @@
import {compatibleCore} from "../misc.js";
import { compatibleCore } from "../misc.js";
export class dnd35e{
constructor(){
console.log("Material Deck: Using system 'Dungeons & Dragons 3.5e'/'Pathfinder 1e'");
}
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
getHP(token) {
const hp = token.actor.data.data.attributes.hp;
const hp = this.getActorData(token).attributes.hp;
return {
value: hp.value,
max: hp.max
@@ -14,7 +22,7 @@ export class dnd35e{
}
getTempHP(token) {
const hp = token.actor.data.data.attributes.hp;
const hp = this.getActorData(token).attributes.hp;
return {
value: (hp.temp == null) ? 0 : hp.temp,
max: (hp.tempmax == null) ? 0 : hp.tempmax
@@ -22,7 +30,7 @@ export class dnd35e{
}
getAC(token) {
return token.actor.data.data.attributes.ac.normal.total;
return this.getActorData(token).attributes.ac.normal.total;
}
getShieldHP(token) {
@@ -30,7 +38,7 @@ export class dnd35e{
}
getSpeed(token) {
const movement = token.actor.data.data.attributes.speed;
const movement = this.getActorData(token).attributes.speed;
let speed = "";
if (movement.burrow.total > 0) speed += `Burrow: ${movement.burrow.total}Ft`;
if (movement.climb.total > 0) {
@@ -53,7 +61,7 @@ export class dnd35e{
}
getInitiative(token) {
let initiative = token.actor.data.data.attributes.init.total;
let initiative = this.getActorData(token).attributes.init.total;
return (initiative >= 0) ? `+${initiative}` : initiative;
}
@@ -71,29 +79,29 @@ export class dnd35e{
getAbility(token, ability) {
if (ability == undefined) ability = 'str';
return token.actor.data.data.abilities?.[ability].value;
return this.getActorData(token).abilities?.[ability].value;
}
getAbilityModifier(token, ability) {
if (ability == undefined) ability = 'str';
let val = token.actor.data.data.abilities?.[ability].mod;
let val = this.getActorData(token).abilities?.[ability].mod;
return (val >= 0) ? `+${val}` : val;
}
getAbilitySave(token, ability) {
if (ability == undefined) ability = 'fort';
let val = token.actor.data.data.attributes.savingThrows?.[ability].total;
let val = this.getActorData(token).attributes.savingThrows?.[ability].total;
return (val >= 0) ? `+${val}` : val;
}
getSkill(token, skill) {
if (skill == undefined) skill = 'apr';
const val = token.actor.data.data.skills?.[skill].mod;
const val = this.getActorData(token).skills?.[skill].mod;
return (val >= 0) ? `+${val}` : val;
}
getProficiency(token) {
const val = token.actor.data.data.attributes.prof;
const val = this.getActorData(token).attributes.prof;
return (val >= 0) ? `+${val}` : val;
}
@@ -133,7 +141,10 @@ export class dnd35e{
if (roll == 'ability') token.actor.rollAbilityTest(ability,options);
else if (roll == 'save') token.actor.rollSavingThrow(save, null, null,options);
else if (roll == 'skill') token.actor.rollSkill(skill,options);
else if (roll == 'initiative') token.actor.rollInitiative(options);
else if (roll == 'initiative') {
options.rerollInitiative = true;
token.actor.rollInitiative(options);
}
else if (roll == 'grapple') token.actor.rollGrapple(options);
else if (roll == 'bab') token.actor.rollBAB(options);
else if (roll == 'melee') token.actor.rollMelee(options);
@@ -147,16 +158,16 @@ export class dnd35e{
if (itemType == undefined) itemType = 'any';
const allItems = token.actor.items;
if (itemType == 'any') return allItems.filter(i => i.type == 'weapon' || i.type == 'equipment' || i.type == 'consumable' || i.type == 'loot' || i.type == 'container');
else if (game.system.id == 'D35E' && itemType == 'container') return allItems.filter(i => i.type == 'loot' && i.data.data.subType == itemType);
else if (game.system.id == 'D35E' && itemType == 'container') return allItems.filter(i => i.type == 'loot' && this.getItemData(i).subType == itemType);
else {
if (itemType == 'gear' || itemType == 'ammo' || itemType == 'misc' || itemType == 'tradeGoods')
return allItems.filter(i => i.type == 'loot' && i.data.data.subType == itemType);
return allItems.filter(i => i.type == 'loot' && this.getItemData(i).subType == itemType);
else return allItems.filter(i => i.type == itemType);
}
}
getItemUses(item) {
return {available: item.data.data.quantity};
return {available: this.getItemData(item).quantity};
}
/**
@@ -170,10 +181,10 @@ export class dnd35e{
}
getFeatureUses(item) {
if (item.data.type == 'class') return {available: item.data.data.levels};
if (item.data.type == 'class') return {available: this.getItemData(item).levels};
else return {
available: item.data.data.uses.value,
maximum: item.data.data.uses.max
available: this.getItemData(item).uses.value,
maximum: this.getItemData(item).uses.max
};
}
@@ -184,12 +195,12 @@ export class dnd35e{
if (level == undefined) level = 'any';
const allItems = token.actor.items;
if (level == 'any') return allItems.filter(i => i.type == 'spell')
else return allItems.filter(i => i.type == 'spell' && i.data.data.level == level)
else return allItems.filter(i => i.type == 'spell' && this.getItemData(i).level == level)
}
getSpellUses(token,level,item) {
if (level == undefined) level = 'any';
if (item.data.data.level == 0) return;
if (this.getItemData(item).level == 0) return;
return {
available: item.charges,
maximum: item.maxCharges

View File

@@ -1,4 +1,4 @@
import {compatibleCore} from "../misc.js";
import { compatibleCore } from "../misc.js";
const proficiencyColors = {
0: "#000000",
@@ -9,11 +9,19 @@ const proficiencyColors = {
export class dnd5e{
constructor(){
console.log("Material Deck: Using system 'Dungeons & Dragons 5e'");
}
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
getHP(token) {
const hp = token.actor.data.data.attributes.hp;
const hp = this.getActorData(token).attributes.hp;
return {
value: hp.value,
max: hp.max
@@ -21,7 +29,7 @@ export class dnd5e{
}
getTempHP(token) {
const hp = token.actor.data.data.attributes.hp;
const hp = this.getActorData(token).attributes.hp;
return {
value: (hp.temp == null) ? 0 : hp.temp,
max: (hp.tempmax == null) ? 0 : hp.tempmax
@@ -29,7 +37,7 @@ export class dnd5e{
}
getAC(token) {
return token.actor.data.data.attributes.ac.value;
return this.getActorData(token).attributes.ac.value;
}
getShieldHP(token) {
@@ -37,41 +45,36 @@ export class dnd5e{
}
getSpeed(token) {
const movement = token.actor.data.data.attributes.movement;
const movement = this.getActorData(token).attributes.movement;
let speed = "";
if (movement != undefined){
if (movement.burrow > 0) speed += `${game.i18n.localize("DND5E.MovementBurrow")}: ${movement.burrow + movement.units}`;
if (movement.climb > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementClimb")}: ${movement.climb + movement.units}`;
}
if (movement.fly > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementFly")}: ${movement.fly + movement.units}`;
}
if (movement.hover > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementHover")}: ${movement.hover + movement.units}`;
}
if (movement.swim > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementSwim")}: ${movement.swim + movement.units}`;
}
if (movement.walk > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementWalk")}: ${movement.walk + movement.units}`;
}
if (movement.burrow > 0) speed += `${game.i18n.localize("DND5E.MovementBurrow")}: ${movement.burrow + movement.units}`;
if (movement.climb > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementClimb")}: ${movement.climb + movement.units}`;
}
else {
const spd = token.actor.data.data.attributes.speed;
speed = spd.value;
if (spd.special.length > 0) speed + "\n" + spd.special;
if (movement.fly > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementFly")}: ${movement.fly + movement.units}`;
}
if (movement.hover > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementHover")}: ${movement.hover + movement.units}`;
}
if (movement.swim > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementSwim")}: ${movement.swim + movement.units}`;
}
if (movement.walk > 0) {
if (speed.length > 0) speed += '\n';
speed += `${game.i18n.localize("DND5E.MovementWalk")}: ${movement.walk + movement.units}`;
}
return speed;
}
getInitiative(token) {
let initiative = token.actor.data.data.attributes.init.total;
let initiative = this.getActorData(token).attributes.init.total;
return (initiative >= 0) ? `+${initiative}` : initiative;
}
@@ -80,38 +83,38 @@ export class dnd5e{
}
getPassivePerception(token) {
return token.actor.data.data.skills.prc.passive;
return this.getActorData(token).skills.prc.passive;
}
getPassiveInvestigation(token) {
return token.actor.data.data.skills.inv.passive;
return this.getActorData(token).skills.inv.passive;
}
getAbility(token, ability) {
if (ability == undefined) ability = 'str';
return token.actor.data.data.abilities?.[ability].value;
return this.getActorData(token).abilities?.[ability].value;
}
getAbilityModifier(token, ability) {
if (ability == undefined) ability = 'str';
let val = token.actor.data.data.abilities?.[ability].mod;
let val = this.getActorData(token).abilities?.[ability].mod;
return (val >= 0) ? `+${val}` : val;
}
getAbilitySave(token, ability) {
if (ability == undefined) ability = 'str';
let val = token.actor.data.data.abilities?.[ability].save;
let val = this.getActorData(token).abilities?.[ability].save;
return (val >= 0) ? `+${val}` : val;
}
getSkill(token, skill) {
if (skill == undefined) skill = 'acr';
const val = token.actor.data.data.skills?.[skill].total;
const val = this.getActorData(token).skills?.[skill].total;
return (val >= 0) ? `+${val}` : val;
}
getProficiency(token) {
const val = token.actor.data.data.attributes.prof;
const val = this.getActorData(token).attributes.prof;
return (val >= 0) ? `+${val}` : val;
}
@@ -151,7 +154,10 @@ export class dnd5e{
if (roll == 'ability') token.actor.rollAbilityTest(ability,options);
else if (roll == 'save') token.actor.rollAbilitySave(save,options);
else if (roll == 'skill') token.actor.rollSkill(skill,options);
else if (roll == 'initiative') token.actor.rollInitiative(options);
else if (roll == 'initiative') {
options.rerollInitiative = true;
token.actor.rollInitiative(options);
}
else if (roll == 'deathSave') token.actor.rollDeathSave(options);
}
@@ -166,7 +172,7 @@ export class dnd5e{
}
getItemUses(item) {
return {available: item.data.data.quantity};
return {available: this.getItemData(item).quantity};
}
/**
@@ -175,15 +181,18 @@ export class dnd5e{
getFeatures(token,featureType) {
if (featureType == undefined) featureType = 'any';
const allItems = token.actor.items;
if (featureType == 'any') return allItems.filter(i => i.type == 'class' || i.type == 'feat')
else return allItems.filter(i => i.type == featureType)
if (featureType == 'any') return allItems.filter(i => i.type == 'class' || i.type == 'feat')
else if (featureType == 'activeAbilities') return allItems.filter(i => i.type == 'feat' && i.labels.featType == 'Action')
else if (featureType == 'passiveAbilities') return allItems.filter(i => i.type == 'feat' && i.labels.featType == 'Passive')
else return allItems.filter(i => i.type == featureType)
}
getFeatureUses(item) {
if (item.data.type == 'class') return {available: item.data.data.levels};
if (item.type == 'class') return {available: this.getItemData(item).levels};
else return {
available: item.data.data.uses.value,
maximum: item.data.data.uses.max
available: this.getItemData(item).uses.value,
maximum: this.getItemData(item).uses.max
};
}
@@ -194,33 +203,65 @@ export class dnd5e{
if (level == undefined) level = 'any';
const allItems = token.actor.items;
if (level == 'any') return allItems.filter(i => i.type == 'spell')
else return allItems.filter(i => i.type == 'spell' && i.data.data.level == level)
else return allItems.filter(i => i.type == 'spell' && this.getItemData(i).level == level)
}
getSpellUses(token,level,item) {
if (level == undefined) level = 'any';
if (item.data.data.level == 0) return;
if (level == undefined || level == 'any') level = this.getItemData(item).level;
if (this.getItemData(item).level == 0) return;
return {
available: token.actor.data.data.spells?.[`spell${level}`].value,
maximum: token.actor.data.data.spells?.[`spell${level}`].max
available: this.getActorData(token).spells?.[`spell${level}`].value,
maximum: this.getActorData(token).spells?.[`spell${level}`].max
}
}
rollItem(item) {
return item.roll()
rollItem(item, settings, rollOption) {
let options = {
fastForward: rollOption != 'dialog',
advantage: rollOption == 'advantage',
disadvantage: rollOption == 'disadvantage'
}
if (settings.inventoryType == 'weapon') {
if (settings.weaponRollMode == 'attack') {
options.fastForward = true;
return item.rollAttack(options);
}
else if (settings.weaponRollMode == 'damage' || settings.weaponRollMode == 'versatile') {
options.fastForward = true;
return item.rollDamage({
options,
critical:false,
versatile: settings.weaponRollMode == 'versatile'
});
}
else if (settings.weaponRollMode == 'damageCrit' || settings.weaponRollMode == 'versatileCrit') {
options.fastForward = true;
return item.rollDamage({
options,
critical:true,
versatile: settings.weaponRollMode == 'versatile' || settings.weaponRollMode == 'versatileCrit'
});
}
else if (settings.weaponRollMode == 'otherFormula') {
return item.rollFormula(options);
}
}
if (compatibleCore('10.0')) item.use(options)
else item.roll(options)
}
/**
* Ring Colors
*/
getSkillRingColor(token, skill) {
const profLevel = token.actor.data.data?.skills[skill]?.proficient;
const profLevel = this.getActorData(token).skills[skill]?.proficient;
if (profLevel == undefined) return;
return proficiencyColors?.[profLevel];
}
getSaveRingColor(token, save) {
const profLevel = token.actor.data.data?.abilities[save]?.proficient;
const profLevel = this.getActorData(token).abilities[save]?.proficient;
if (profLevel == undefined) return;
return proficiencyColors?.[profLevel];
}

View File

@@ -1,30 +1,36 @@
import {compatibleCore} from "../misc.js";
import { compatibleCore } from "../misc.js";
export class forbiddenlands{
constructor(){
console.log("Material Deck: Using system 'Forbidden Lands'");
}
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
getHP(token) {
const hp = token.actor.data.data.attribute.strength;
const hp = this.getActorData(token).attribute.strength;
return {
value: hp.value,
max: hp.max
}
}
getAgility(token) {
const agility = token.actor.data.data.attribute.agility;
const agility = this.getActorData(token).attribute.agility;
return {
value: agility.value,
max: agility.max
}
}
getWits(token) {
const wits = token.actor.data.data.attribute.wits;
const wits = this.getActorData(token).attribute.wits;
return {
value: wits.value,
max: wits.max
@@ -32,7 +38,7 @@ export class forbiddenlands{
}
getEmpathy(token) {
const empathy = token.actor.data.data.attribute.empathy;
const empathy = this.getActorData(token).attribute.empathy;
return {
value: empathy.value,
max: empathy.max
@@ -40,7 +46,7 @@ export class forbiddenlands{
}
getWillPower(token) {
const wp = token.actor.data.data.bio.willpower;
const wp = this.getActorData(token).bio.willpower;
return {
value: wp.value,
max: wp.max
@@ -49,15 +55,9 @@ export class forbiddenlands{
getTempHP(token) {
return 0;
const hp = token.actor.data.data.attributes.hp;
return {
value: (hp.temp == null) ? 0 : hp.temp,
max: (hp.tempmax == null) ? 0 : hp.tempmax
}
}
getAC(token) {
const totalArmor = token.actor.itemTypes.armor.reduce((sum, armor) => {
if (armor.itemProperties.part === "shield") return sum;
const value = armor.itemProperties.bonus.value;
@@ -76,8 +76,6 @@ export class forbiddenlands{
getInitiative(token) {
return 0;
let initiative = token.actor.data.data.attributes.init.total;
return (initiative >= 0) ? `+${initiative}` : initiative;
}
toggleInitiative(token) {
@@ -86,17 +84,15 @@ export class forbiddenlands{
getPassivePerception(token) {
return 0;
return token.actor.data.data.skills.prc.passive;
}
getPassiveInvestigation(token) {
return;
return token.actor.data.data.skills.inv.passive;
}
getAbility(token, ability) {
if (ability == undefined) ability = 'strength';
return token.actor.data.data.attribute?.[ability].value;
return this.getActorData(token).attribute?.[ability].value;
}
getAbilityModifier(token, ability) {
@@ -116,8 +112,6 @@ export class forbiddenlands{
getProficiency(token) {
return;
const val = token.actor.data.data.attributes.prof;
return (val >= 0) ? `+${val}` : val;
}
getConditionIcon(condition) {
@@ -181,9 +175,9 @@ export class forbiddenlands{
getItemUses(item) {
if (item.type == 'monsterAttack') return;
if (item.type == 'rawMaterial') return {available: item.data.data.quantity};
return {available: item.data.data.bonus.value,
maximum: item.data.data.bonus.max};
if (item.type == 'rawMaterial') return {available: this.getItemData(item).quantity};
return {available: this.getItemData(item).bonus.value,
maximum: this.getItemData(item).bonus.max};
}
/**
@@ -197,10 +191,10 @@ export class forbiddenlands{
}
getFeatureUses(item) {
if (item.data.type == 'class') return {available: item.data.data.levels};
if (item.data.type == 'class') return {available: this.getItemData(item).levels};
else return {
available: item.data.data.uses.value,
maximum: item.data.data.uses.max
available: this.getItemData(item).uses.value,
maximum: this.getItemData(item).uses.max
};
}
@@ -211,15 +205,15 @@ export class forbiddenlands{
if (level == undefined) level = 'any';
const allItems = token.actor.items;
if (level == 'any') return allItems.filter(i => i.type == 'spell')
else return allItems.filter(i => i.type == 'spell' && i.data.data.level == level)
else return allItems.filter(i => i.type == 'spell' && this.getItemData(i).level == level)
}
getSpellUses(token,level,item) {
if (level == undefined) level = 'any';
if (item.data.data.level == 0) return;
if (this.getItemData(item).level == 0) return;
return {
available: token.actor.data.data.spells?.[`spell${level}`].value,
maximum: token.actor.data.data.spells?.[`spell${level}`].max
available: this.getActorData(token).spells?.[`spell${level}`].value,
maximum: this.getActorData(token).spells?.[`spell${level}`].max
}
}

View File

@@ -1,5 +1,5 @@
import {compatibleCore} from "../misc.js";
import {otherControls} from "../../MaterialDeck.js";
import { otherControls } from "../../MaterialDeck.js";
import { compatibleCore } from "../misc.js";
const limitedSheets = ['loot', 'vehicle'];
const proficiencyColors =
@@ -14,11 +14,19 @@ const proficiencyColors =
export class pf2e{
constructor(){
console.log("Material Deck: Using system 'Pathfinder 2e'");
}
tokenSpellData = new Map();
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
getHP(token) {
const hp = token.actor.attributes?.hp;
return {
@@ -48,7 +56,7 @@ export class pf2e{
getSpeed(token) {
if (this.isLimitedSheet(token.actor) || token.actor.type == 'hazard') {
if (token.actor.type == 'vehicle') {
return token.actor.data.data.details.speed;
return this.getActorData(token).details.speed;
} else return '';
}
let speed = `${token.actor.attributes.speed?.total}'`;
@@ -117,7 +125,7 @@ export class pf2e{
findSave(token, ability) {
if (this.isLimitedSheet(token.actor)) return;
return token.actor.data.data.saves?.[ability];
return this.getActorData(token).saves?.[ability];
}
fixSave(ability) {
@@ -151,12 +159,12 @@ export class pf2e{
return;
}
}
return token.actor.data.data.skills?.[skill];
return this.getActorData(token).skills?.[skill];
}
getLoreSkills(token) {
if (this.isLimitedSheet(token.actor)) return [];
const skills = token.actor.data.data.skills;
const skills = this.getActorData(token).skills;
return Object.keys(skills).map(key => skills[key]).filter(s => s.lore == true);
}
@@ -270,7 +278,7 @@ export class pf2e{
return;
}
}
let skillName = token.actor.data.data.skills?.[skill].name;
let skillName = this.getActorData(token).skills?.[skill].name;
skillName = skillName.charAt(0).toUpperCase() + skillName.slice(1);
this.checkRoll(`Skill Check: ${skillName}`, token.actor.skills?.[skill], 'skill-check', token.actor);
}
@@ -315,14 +323,14 @@ export class pf2e{
if (featureType == 'feat-gen') return allItems.filter(i => i.type == 'feat' && i.featType == 'general');
if (featureType == 'feat-ski') return allItems.filter(i => i.type == 'feat' && i.featType == 'skill');
if (featureType == 'action-any') return allItems.filter(i => i.type == 'action');
if (featureType == 'action-def') return allItems.filter(i => i.type == 'action' && i.data.data.actionCategory?.value == 'defensive');
if (featureType == 'action-int') return allItems.filter(i => i.type == 'action' && i.data.data.actionCategory?.value == 'interaction');
if (featureType == 'action-off') return allItems.filter(i => i.type == 'action' && i.data.data.actionCategory?.value == 'offensive');
if (featureType == 'action-def') return allItems.filter(i => i.type == 'action' && this.getItemData(i).actionCategory?.value == 'defensive');
if (featureType == 'action-int') return allItems.filter(i => i.type == 'action' && this.getItemData(i).actionCategory?.value == 'interaction');
if (featureType == 'action-off') return allItems.filter(i => i.type == 'action' && this.getItemData(i).actionCategory?.value == 'offensive');
if (featureType == 'strike') { //Strikes are not in the actor.items collection
if (token.actor.type == 'hazard' || token.actor.type == 'familiar') {
return allItems.filter(i => i.type == 'melee' || i.type == 'ranged');
}
let actions = token.actor.data.data.actions?.filter(a=>a.type == 'strike');
let actions = this.getActorData(token).actions?.filter(a=>a.type == 'strike');
for (let a of actions) {
a.img = a.imageUrl;
a.data = {
@@ -345,7 +353,7 @@ export class pf2e{
buildSpellData(token) {
let spellData = [[],[],[],[],[],[],[],[],[],[],[],[]];
let spellcastingEntries = token.actor.spellcasting;
const actorLevel = token.actor.data.data.details.level.value;
const actorLevel = this.getActorData(token).details.level.value;
spellcastingEntries.forEach(spellCastingEntry => {
let highestSpellSlot = Math.ceil(actorLevel/2);
while (spellCastingEntry.data.data.slots?.[`slot${highestSpellSlot}`]?.max <= 0) highestSpellSlot--;
@@ -413,15 +421,15 @@ export class pf2e{
if (level == undefined || level == 'any') level = item.level;
if (item.isCantrip == true) return;
if (item.isFocusSpell == true) return {
available: token.actor.data.data.resources.focus.value,
maximum: token.actor.data.data.resources.focus.max
available: this.getActorData(token).resources.focus.value,
maximum: this.getActorData(token).resources.focus.max
}
const spellbook = this.findSpellcastingEntry(token.actor, item);
if (spellbook == undefined) return;
if (spellbook.data.data.prepared.value == 'innate') {
return {
available: item.data.data.location.uses.value,
maximum: item.data.data.location.uses.max
available: this.getItemData(item).location.uses.value,
maximum: this.getItemData(item).location.uses.max
}
}
if (spellbook.data.data.prepared.value == 'prepared') {

View File

@@ -1,4 +1,4 @@
import {compatibleCore} from "../misc.js";
import { compatibleCore } from "../misc.js";
const proficiencyColors = {
0: "#000000",
@@ -9,11 +9,19 @@ const proficiencyColors = {
export class starfinder{
constructor(){
console.log("Material Deck: Using system 'Starfinder'");
}
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
getHP(token) {
const hp = token.actor.data.data.attributes.hp;
const hp = this.getActorData(token).attributes.hp;
return {
value: hp.value,
max: hp.max
@@ -25,7 +33,7 @@ export class starfinder{
}
getStamina(token) {
const stamina = token.actor.data.data.attributes.sp;
const stamina = this.getActorData(token).attributes.sp;
return {
value: stamina.value,
max: stamina.max
@@ -33,11 +41,11 @@ export class starfinder{
}
getAC(token) {
return token.actor.data.data.attributes.eac.value;
return this.getActorData(token).attributes.eac.value;
}
getKinAC(token) {
return token.actor.data.data.attributes.kac.value;
return this.getActorData(token).attributes.kac.value;
}
getShieldHP(token) {
@@ -45,7 +53,7 @@ export class starfinder{
}
getSpeed(token) {
const movement = token.actor.data.data.attributes.speed;
const movement = this.getActorData(token).attributes.speed;
let speed = "";
if (movement.burrowing.value > 0) speed += `Burrow: ${movement.burrowing.value}Ft`;
if (movement.climbing.value > 0) {
@@ -68,7 +76,7 @@ export class starfinder{
}
getInitiative(token) {
let initiative = token.actor.data.data.attributes.init.total;
let initiative = this.getActorData(token).attributes.init.total;
return (initiative >= 0) ? `+${initiative}` : initiative;
}
@@ -86,25 +94,25 @@ export class starfinder{
getAbility(token, ability) {
if (ability == undefined) ability = 'str';
return token.actor.data.data.abilities?.[ability].value;
return this.getActorData(token).abilities?.[ability].value;
}
getAbilityModifier(token, ability) {
if (ability == undefined) ability = 'str';
let val = token.actor.data.data.abilities?.[ability].mod;
let val = this.getActorData(token).abilities?.[ability].mod;
return (val >= 0) ? `+${val}` : val;
}
getAbilitySave(token, ability) {
if (ability == undefined) ability = 'fort';
else if (ability == 'ref') ability = 'reflex';
let val = token.actor.data.data.attributes?.[ability].bonus;
let val = this.getActorData(token).attributes?.[ability].bonus;
return (val >= 0) ? `+${val}` : val;
}
getSkill(token, skill) {
if (skill == undefined) skill = 'acr';
const val = token.actor.data.data.skills?.[skill].mod;
const val = this.getActorData(token).skills?.[skill].mod;
return (val >= 0) ? `+${val}` : val;
}
@@ -148,7 +156,10 @@ export class starfinder{
if (roll == 'ability') token.actor.rollAbilityTest(ability,options);
else if (roll == 'save') token.actor.rollAbilitySave(save,options);
else if (roll == 'skill') token.actor.rollSkill(skill,options);
else if (roll == 'initiative') token.actor.rollInitiative(options);
else if (roll == 'initiative') {
options.rerollInitiative = true;
token.actor.rollInitiative(options);
}
else if (roll == 'deathSave') token.actor.rollDeathSave(options);
}
@@ -164,7 +175,7 @@ export class starfinder{
}
getItemUses(item) {
return {available: item.data.data.quantity};
return {available: this.getItemData(item).quantity};
}
/**
@@ -183,10 +194,10 @@ export class starfinder{
}
getFeatureUses(item) {
if (item.data.type == 'class') return {available: item.data.data.levels};
if (item.data.type == 'class') return {available: this.getItemData(item).levels};
else return {
available: item.data.data.uses.value,
maximum: item.data.data.uses.max
available: this.getItemData(item).uses.value,
maximum: this.getItemData(item).uses.max
};
}
@@ -197,16 +208,16 @@ export class starfinder{
if (level == undefined) level = 'any';
const allItems = token.actor.items;
if (level == 'any') return allItems.filter(i => i.type == 'spell')
else if (level == 'innate') return allItems.filter(i => i.type == 'spell' && i.data.data.preparation.mode == 'innate');
else return allItems.filter(i => i.type == 'spell' && i.data.data.preparation.mode == '' && i.data.data.level == level)
else if (level == 'innate') return allItems.filter(i => i.type == 'spell' && this.getItemData(i).preparation.mode == 'innate');
else return allItems.filter(i => i.type == 'spell' && this.getItemData(i).preparation.mode == '' && this.getItemData(i).level == level)
}
getSpellUses(token,level,item) {
if (level == undefined) level = 'any';
if (item.data.data.level == 0) return;
if (this.getItemData(item).level == 0) return;
const spellSlots = token.actor.data.data.spells;
const allowedClasses = item.data.data.allowedClasses;
const spellSlots = this.getActorData(token).spells;
const allowedClasses = this.getItemData(item).allowedClasses;
let uses = {available: 0, maximum: 0};
if (allowedClasses.myst && spellSlots?.[`spell${level}`].perClass?.mystic?.max > uses.maximum)
@@ -229,13 +240,13 @@ export class starfinder{
* Ring Colors
*/
getSkillRingColor(token, skill) {
const profLevel = token.actor.data.data?.skills[skill]?.proficient;
const profLevel = this.getActorData(token)?.skills[skill]?.proficient;
if (profLevel == undefined) return;
return proficiencyColors?.[profLevel];
}
getSaveRingColor(token, save) {
const profLevel = token.actor.data.data?.abilities[save]?.proficient;
const profLevel = this.getActorData(token)?.abilities[save]?.proficient;
if (profLevel == undefined) return;
return proficiencyColors?.[profLevel];
}

325
src/systems/template.js Normal file
View File

@@ -0,0 +1,325 @@
/**
* This is a template for adding a new gaming system.
* Edit it to suit your system, for inspiration, look at other system files.
* Functions that are unused in your system can be left empty, but don't delete the function.
*
* Use the compatibleCore function to get the right value for the Foundry core:
* return compatibleCore('10.0') ? [value in v10+] : [value pre v10];
*
* Use the compatibleSystem function to get the right value for the gaming system version:
* return compatibleSystem('1.6.3') ? [value in v1.6.3+] : [value pre v1.6.3];
*/
import { compatibleCore, compatibleSystem } from "../misc";
/**
* Proficiency colors to show if a token is proficient in for example a skill
*/
const proficiencyColors = {
0: "#000000",
0.5: "#804A00",
1: "#C0C0C0",
2: "#FFD700"
}
//Rename 'template' to the name of your system
export class template{
constructor(){
console.log("Material Deck: Using system 'SystemName'");
}
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
/**
* Returns the HP of the token
* @param {Token} token Token instance to get the HP from
* @returns {object} Token hp value and max: {value: ##, max: ##}
*/
getHP(token) {
return;
}
/**
* Returns the temporary HP of the token
* @param {Token} token Token instance to get the temp HP from
* @returns {object} Token temp hp value and max: {value: ##, max: ##}
*/
getTempHP(token) {
return;
}
/**
* Returns the armor class of the token
* @param {Token} token Token instance to get the AC from
* @returns {number} AC value
*/
getAC(token) {
return;
}
/**
* Returns the shield HP of the token
* @param {Token} token Token instance to get the shield HP from
* @returns {number} Shield HP
*/
getShieldHP(token) {
return;
}
/**
* Returns a string with movement speeds of the token
* @param {Token} token Token instance to get the speed from
* @returns {string} Movement speed string
*/
getSpeed(token) {
return;
}
/**
* Returns the initiative of the token
* @param {Token} token Token instance to get the initiative from
* @returns {number} Initiative value
*/
getInitiative(token) {
return;
}
/**
* Toggles the initiative of the token
* @param {Token} token Token instance to toggle the initiative for
*/
toggleInitiative(token) {
}
/**
* Returns the passive perception of the token
* @param {Token} token Token instance to get the passive perception from
* @returns {number} Passive perception value
*/
getPassivePerception(token) {
return;
}
/**
* Returns the passive investigation of the token
* @param {Token} token Token instance to get the passive investigation from
* @returns {number} Passive investigation value
*/
getPassiveInvestigation(token) {
return;
}
/**
* Returns the ability value of the token
* @param {Token} token Token instance to get the ability value from
* @param {string} ability Ability to get the value from
* @returns {number} Ability value
*/
getAbility(token, ability) {
if (ability == undefined) ability = ''; //default ability
return;
}
/**
* Returns the ability modifier of the token
* @param {Token} token Token instance to get the ability modifier from
* @param {string} ability Ability to get the value from
* @returns {number} Ability modifier
*/
getAbilityModifier(token, ability) {
if (ability == undefined) ability = ''; //default ability
return;
}
/**
* Returns the ability save of the token
* @param {Token} token Token instance to get the ability save from
* @param {string} ability Ability to get the value from
* @returns {number} Ability save
*/
getAbilitySave(token, ability) {
if (ability == undefined) ability = ''; //default ability
return;
}
/**
* Returns the skill value of the token
* @param {Token} token Token instance to get the skill value from
* @param {string} skill Skill to get the value from
* @returns {number} Skill value
*/
getSkill(token, skill) {
if (skill == undefined) skill = '';
return;
}
/**
* Returns the proficiency value of the token
* @param {Token} token Token instance to get the proficiency from
* @returns {number} Proficiency value
*/
getProficiency(token) {
return;
}
/**
* Returns the icon location of a condition
* @param {string} condition Name of the condition
* @returns {string} Icon location
*/
getConditionIcon(condition) {
if (condition == undefined) condition = 'removeAll';
if (condition == 'removeAll') return;
else return;
}
/**
* Returns whether a condition is active on the token
* @param {Token} token Token instance to get the value from
* @param {string} condition Name of the condition
* @returns {boolean} Condition is active or not
*/
getConditionActive(token,condition) {
if (condition == undefined) condition = 'removeAll';
return;
}
/**
* Toggles a condition on a token
* @param {Token} token Token instance to get the value from
* @param {string} condition Name of the condition
*/
async toggleCondition(token,condition) {
if (condition == undefined) condition = 'removeAll';
}
/**
* Roll for a token
* @param {Token} token Token instance to roll for
* @param {string} roll Roll type (ability/save/skill/initiative/deathSave)
* @param {bbject} options Roll options
* @param {string} ability Name of the ability to roll
* @param {string} skill Name of the skill to roll
* @param {string} save Name of the save to roll
*/
roll(token,roll,options,ability,skill,save) {
if (roll == undefined) roll = 'ability';
if (ability == undefined) ability = ''; //default ability
if (skill == undefined) skill = ''; //default skill
if (save == undefined) save = ''; //default save
if (roll == 'ability')
else if (roll == 'save')
else if (roll == 'skill')
else if (roll == 'initiative')
else if (roll == 'deathSave')
}
/**
* Get array of items
* @param {Token} token Token instance to get the items from
* @param {string} itemType Item type
* @returns {array} Array of items
*/
getItems(token,itemType) {
if (itemType == undefined) itemType = 'any';
if (itemType == 'any') return ;
else return ;
}
/**
* Returns uses/quantity of an item
* @param {Item} item Item instance to get the uses/quantity from
* @returns {object} Uses/quantity available {available: ###, maximum: ###}
*/
getItemUses(item) {
return;
}
/**
* Returns the features of a token
* @param {Token} token Token instance to get the features from
* @param {string} featureType Feature types to return
* @returns {array} Array of features
*/
getFeatures(token,featureType) {
if (featureType == undefined) featureType = 'any';
if (featureType == 'any') return;
else return;
}
/**
* Returns uses/quantity of a feature
* @param {Item} item Item/feature instance to get the uses/quantity from
* @returns {object} Uses/quantity available {available: ###, maximum: ###}
*/
getFeatureUses(item) {
return {};
}
/**
* Returns the spells of a token
* @param {Token} token Token instance to get the spells from
* @param {string} level Spell level
* @returns {array} Array of spells
*/
getSpells(token,level) {
if (level == undefined) level = 'any';
if (level == 'any') return;
else return;
}
/**
* Returns the spell uses of a specific spell for a token
* @param {Token} token Token instance to get the spell uses from
* @param {string} level Spell level
* @param {Item} item Spell instance to get the uses from
* @returns {object} Spell uses left: {available: ###, maximum: ###}
*/
getSpellUses(token,level,item) {
return {
}
}
/**
* Roll an item
* @param {Token} item Item instance to roll
* @param {object} settings Settings of the action
* @param {object} rollOption Roll options
*/
rollItem(item, settings, rollOption) {
}
/**
* Returns a color to display proficiency for skills
* @param {Token} token Token instance to get the proficiency from
* @param {string} skill Skill name
* @returns {string} Hex color string from proficiencyColors array
*/
getSkillRingColor(token, skill) {
const profLevel = ;
if (profLevel == undefined) return;
return proficiencyColors?.[profLevel];
}
/**
* Returns a color to display proficiency for saves
* @param {Token} token Token instance to get the proficiency from
* @param {string} save Save name
* @returns {string} Hex color string from proficiencyColors array
*/
getSaveRingColor(token, save) {
const profLevel = ;
if (profLevel == undefined) return;
return proficiencyColors?.[profLevel];
}
}

View File

@@ -1,12 +1,12 @@
import {dnd5e} from "./dnd5e.js";
import {dnd35e} from "./dnd35e.js";
import {pf2e} from "./pf2e.js";
import {demonlord} from "./demonlord.js";
import {wfrp4e} from "./wfrp4e.js";
import {forbiddenlands} from "./forbidden-lands.js";
import {starfinder} from "./starfinder.js";
import {compatibleCore} from "../misc.js";
import {gamingSystem} from "../../MaterialDeck.js";
import { dnd5e } from "./dnd5e.js";
import { dnd35e } from "./dnd35e.js";
import { pf2e } from "./pf2e.js";
import { demonlord } from "./demonlord.js";
import { wfrp4e } from "./wfrp4e.js";
import { forbiddenlands } from "./forbidden-lands.js";
import { starfinder } from "./starfinder.js";
import { compatibleCore } from "../misc.js";
import { gamingSystem } from "../../MaterialDeck.js";
export class TokenHelper{
@@ -58,7 +58,7 @@ export class TokenHelper{
moveToken(token,dir){
if (dir == undefined) dir = 'up';
const gridSize = canvas.scene.data.grid;
const gridSize = compatibleCore('10.0') ? canvas.scene.grid.size : canvas.scene.data.grid;
let x = token.x;
let y = token.y;
@@ -88,8 +88,10 @@ export class TokenHelper{
}
if (game.user.isGM == false && game.paused) return;
if (game.user.isGM == false && (token.can(game.user,"control") == false || token.checkCollision(token.getCenter(x, y)))) return;
if (compatibleCore("0.8.1")) token.document.update({x:x,y:y});
else token.update({x:x,y:y});
let coords = canvas.grid.getCenter(x,y);
coords[0] -= canvas.grid.size/2;
coords[1] -= canvas.grid.size/2;
token.document.update({x:coords[0],y:coords[1]});
};
rotateToken(token,move,value) {
@@ -97,11 +99,10 @@ export class TokenHelper{
value = isNaN(parseInt(value)) ? 0 : parseInt(value);
let rotationVal;
if (move == 'by') rotationVal = token.data.rotation + value;
if (move == 'by') rotationVal = compatibleCore('10.0') ? token.document.rotation + value : token.data.rotation + value;
else rotationVal = value;
if (compatibleCore("0.8.1")) token.document.update({rotation: rotationVal});
else token.update({rotation: rotationVal});
token.document.update({rotation: rotationVal});
}
///////////////////////////////////////////////
@@ -127,11 +128,11 @@ export class TokenHelper{
////////////////////////////////////////////////////
getTokenIcon(token) {
return token.data.img;
return compatibleCore('10.0') ? token.document.texture.src : token.data.img;
}
getActorIcon(token) {
return token.actor.data.img;
return compatibleCore('10.0') ? token.actor.img : token.actor.data.img;
}
/***********************************************************************
@@ -328,8 +329,8 @@ export class TokenHelper{
return this.system.getSpellUses(token,level,item);
}
rollItem(item, settings) {
return this.system.rollItem(item, settings);
rollItem(item, settings, rollOption) {
return this.system.rollItem(item, settings, rollOption);
}
/**

View File

@@ -1,21 +1,28 @@
import {compatibleCore} from "../misc.js";
import { compatibleCore } from "../misc.js";
export class wfrp4e {
constructor(){
console.log("Material Deck: Using system 'Warhammer Fantasy Roleplaying 4e'");
}
getActorData(token) {
return compatibleCore('10.0') ? token.actor.system : token.actor.data.data;
}
getItemData(item) {
return compatibleCore('10.0') ? item.system : item.data.data;
}
getFate(token) {
return token.actor.data.data.status.fate.value
return this.getActorData(token).status.fate.value
}
getFortune(token) {
return token.actor.data.data.status.fortune.value
return this.getActorData(token).status.fortune.value
}
getWounds(token) {
const wounds = token.actor.data.data.status.wounds
const wounds = this.getActorData(token).status.wounds
return {
value: wounds.value,
max: wounds.max
@@ -24,7 +31,7 @@ export class wfrp4e {
}
getCriticalWounds(token) {
const criticalWounds = token.actor.data.data.status.criticalWounds
const criticalWounds = this.getActorData(token).status.criticalWounds
return {
value: criticalWounds.value,
max: criticalWounds.max
@@ -32,19 +39,19 @@ export class wfrp4e {
}
getCorruption(token) {
return token.actor.data.data.status.corruption.value
return this.getActorData(token).status.corruption.value
}
getAdvantage(token) {
return token.actor.data.data.status.advantage.value
return this.getActorData(token).status.advantage.value
}
getResolve(token) {
return token.actor.data.data.status.resolve.value
return this.getActorData(token).status.resolve.value
}
getResilience(token) {
return token.actor.data.data.status.resilience.value
return this.getActorData(token).status.resilience.value
}
getAbility(token, abilityName) {
@@ -53,7 +60,7 @@ export class wfrp4e {
getCharacteristics(token, characteristicName) {
if (characteristicName == undefined ) characteristicName = `AG`;
const characteristic = token.actor.data.data.characteristics[characteristicName.toLowerCase()]
const characteristic = this.getActorData(token).characteristics[characteristicName.toLowerCase()]
const val = characteristic.value;
return (val >= 0) ? `+${val}` : val;
}
@@ -74,7 +81,7 @@ export class wfrp4e {
}
getFeatureUses(item) {
return {available: `+${item.data.data.total.value}`};
return {available: `+${this.getItemData(item).total.value}`};
}
getHP(token) {
@@ -86,7 +93,7 @@ export class wfrp4e {
}
getSpeed(token) {
return token.actor.data.data.details.move.value;
return this.getActorData(token).details.move.value;
}
@@ -125,7 +132,7 @@ export class wfrp4e {
getItemUses(item) {
if ( item.type == 'ammunition') {
return {available: item.data.data.quantity.value};
return {available: this.getItemData(item).quantity.value};
}
else {
return;