v1.4.9
This commit is contained in:
@@ -23,6 +23,8 @@ export var tokenHelper;
|
||||
|
||||
export const moduleName = "MaterialDeck";
|
||||
|
||||
export let gamingSystem = "dnd5e";
|
||||
|
||||
let ready = false;
|
||||
|
||||
export let hotbarUses = false;
|
||||
@@ -65,7 +67,7 @@ async function analyzeWSmessage(msg){
|
||||
const msg = {
|
||||
target: "SD",
|
||||
type: "init",
|
||||
system: game.system.id
|
||||
system: gamingSystem
|
||||
}
|
||||
ws.send(JSON.stringify(msg));
|
||||
|
||||
@@ -222,7 +224,7 @@ function startWebsocket() {
|
||||
const msg2 = {
|
||||
target: "SD",
|
||||
type: "init",
|
||||
system: game.system.id
|
||||
system: gamingSystem
|
||||
}
|
||||
ws.send(JSON.stringify(msg2));
|
||||
clearInterval(wsInterval);
|
||||
@@ -291,6 +293,9 @@ Hooks.once('ready', async()=>{
|
||||
registerSettings();
|
||||
enableModule = (game.settings.get(moduleName,'Enable')) ? true : false;
|
||||
|
||||
const systemOverride = game.settings.get(moduleName,'systemOverride');
|
||||
gamingSystem = systemOverride != '' ? systemOverride : game.system.id;
|
||||
|
||||
soundboard = new SoundboardControl();
|
||||
streamDeck = new StreamDeck();
|
||||
tokenControl = new TokenControl();
|
||||
@@ -391,6 +396,11 @@ Hooks.once('ready', async()=>{
|
||||
if (hotbarUsesTemp != undefined) hotbarUses = true;
|
||||
});
|
||||
|
||||
function updateActor(id) {
|
||||
const token = tokenHelper.getTokenFromActorId(id)
|
||||
tokenControl.update(token.id);
|
||||
}
|
||||
|
||||
Hooks.on('updateToken',(scene,token)=>{
|
||||
if (enableModule == false || ready == false) return;
|
||||
let tokenId = token._id;
|
||||
@@ -400,19 +410,28 @@ Hooks.on('updateToken',(scene,token)=>{
|
||||
|
||||
Hooks.on('updateActor',(actor)=>{
|
||||
if (enableModule == false || ready == false) return;
|
||||
let children = canvas.tokens.children[0].children;
|
||||
for (let i=0; i<children.length; i++){
|
||||
if (children[i].actor.id == actor._id){
|
||||
let tokenId = children[i].id;
|
||||
if (tokenId == canvas.tokens.controlled[0]?.id) {
|
||||
tokenControl.update(canvas.tokens.controlled[0]?.id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
updateActor(actor.id);
|
||||
if (macroControl != undefined) macroControl.updateAll();
|
||||
});
|
||||
|
||||
Hooks.on('createActiveEffect',(data)=>{
|
||||
if (enableModule == false || ready == false) return;
|
||||
updateActor(data.parent.id);
|
||||
return;
|
||||
});
|
||||
|
||||
Hooks.on('deleteActiveEffect',(data)=>{
|
||||
if (enableModule == false || ready == false) return;
|
||||
updateActor(data.parent.id);
|
||||
return;
|
||||
});
|
||||
|
||||
Hooks.on('onActorSetCondition',(data)=>{
|
||||
if (enableModule == false || ready == false) return;
|
||||
updateActor(data.actor.id);
|
||||
return;
|
||||
});
|
||||
|
||||
Hooks.on('controlToken',(token,controlled)=>{
|
||||
if (enableModule == false || ready == false) return;
|
||||
if (controlled) {
|
||||
@@ -583,6 +602,11 @@ Hooks.on('about-time.clockRunningStatus', ()=>{
|
||||
externalModules.updateAll();
|
||||
})
|
||||
|
||||
Hooks.on('updateTile',()=>{
|
||||
if (enableModule == false || ready == false) return;
|
||||
externalModules.updateAll();
|
||||
});
|
||||
|
||||
Hooks.once('init', ()=>{
|
||||
//CONFIG.debug.hooks = true;
|
||||
//registerSettings(); //in ./src/settings.js
|
||||
|
||||
16
changelog.md
16
changelog.md
@@ -1,4 +1,20 @@
|
||||
# Changelog Material Deck Module
|
||||
### v1.4.9 - 16-04-2022
|
||||
Fixes:
|
||||
<ul>
|
||||
<li>PF2e: Fixed rolls and conditions for compatibility with latest pf2e version. Thanks to Kyamsil</li>
|
||||
<li>Token Action => Set Vison: Setting light is working again</li>
|
||||
<li>Other Actions => Roll Dice: Roll result would show as 'NaN' in Foundry v9, this is fixed</li>
|
||||
</ul>
|
||||
|
||||
Additions:
|
||||
<ul>
|
||||
<li>Added support for the Starfinder system</li>
|
||||
<li>External Modules => Added support for 'Monks Active Tile Triggers'</li>
|
||||
<li>Added 'System Override' module setting. If your system is not supported, MD defaults to 5e. Here you can choose a supported system that is most similar to yours and have Material Deck use that system instead.</li>
|
||||
<li>Token Action => Displayed Stats: A colored border is drawn around certain skills, saves, etc to indicate proficiency (compatible systems: dnd5e, pf2e). Thanks to Kyamsil</li>
|
||||
</ul>
|
||||
|
||||
### v1.4.8 - 22-12-2021
|
||||
Fixes:
|
||||
<ul>
|
||||
|
||||
BIN
img/token/skills/.thumb/lor.png.jpg
Normal file
BIN
img/token/skills/.thumb/lor.png.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -21,6 +21,8 @@
|
||||
"MaterialDeck.Sett.ImageBrightnessHint": "Sets the brightness of the default white images. If the Image Cache Size is bigger than 0, perform a refresh for instant results.",
|
||||
"MaterialDeck.Sett.NrOfConnMessages": "Number of Connection Warnings",
|
||||
"MaterialDeck.Sett.NrOfConnMessagesHint": "Sets the number of times a connection warning is displayed if Material Deck cannot connect to Material Server. If set to 0, it will give not be limited.",
|
||||
"MaterialDeck.Sett.SystemOverride": "System Override",
|
||||
"MaterialDeck.Sett.SystemOverrideHint": "Overrides the automatic gaming system detection. Unsupported systems default to dnd5e, but if an unsupported system is similar to a different system you can specify that system here. Leave empty for system autodetection.",
|
||||
|
||||
"MaterialDeck.PL.Unrestricted": "Unrestricted",
|
||||
"MaterialDeck.PL.OneTrackPlaylist": "One track per playlist",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "MaterialDeck",
|
||||
"title": "Material Deck",
|
||||
"description": "Material Deck allows you to control Foundry using an Elgato Stream Deck",
|
||||
"version": "1.4.8",
|
||||
"version": "1.4.9",
|
||||
"author": "CDeenen",
|
||||
"authors": {
|
||||
"name": "CDeenen",
|
||||
|
||||
@@ -69,6 +69,7 @@ export class ExternalModules{
|
||||
else if (module == 'lockView') this.updateLockView(settings,context,device);
|
||||
else if (module == 'aboutTime') this.updateAboutTime(settings,context,device);
|
||||
else if (module == 'soundscape') this.updateSoundscape(settings,context,device);
|
||||
else if (module == 'monksActiveTiles') this.updateMonksActiveTiles(settings,context,device);
|
||||
}
|
||||
|
||||
keyPress(settings,context,device){
|
||||
@@ -84,6 +85,7 @@ export class ExternalModules{
|
||||
else if (module == 'lockView') this.keyPressLockView(settings,context,device);
|
||||
else if (module == 'aboutTime') this.keyPressAboutTime(settings,context,device);
|
||||
else if (module == 'soundscape') this.keyPressSoundscape(settings,context,device);
|
||||
else if (module == 'monksActiveTiles') this.keyPressMonksActiveTiles(settings,context,device);
|
||||
}
|
||||
|
||||
getModuleEnable(moduleId){
|
||||
@@ -990,6 +992,42 @@ export class ExternalModules{
|
||||
|
||||
this.updateAll();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Monks Active Tile Triggers
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
updateMonksActiveTiles(settings,context,device) {
|
||||
const id = settings.monksActiveTilesId;
|
||||
if (id == undefined || id == '') return;
|
||||
let tile = canvas.background.placeables.find(t => t.id == id);
|
||||
if (tile == undefined) return;
|
||||
const tileData = tile.data.flags?.['monks-active-tiles'];
|
||||
if (tileData == undefined) return;
|
||||
|
||||
let ring = 1;
|
||||
let ringColor = '#000000';
|
||||
let background = '#000000';
|
||||
if (tileData.active) {
|
||||
ring = 2;
|
||||
ringColor = '#00ff00'
|
||||
}
|
||||
let src = tile.data.img;
|
||||
|
||||
streamDeck.setTitle('',context);
|
||||
streamDeck.setIcon(context,device,src,{background:background,ring:ring,ringColor:ringColor});
|
||||
}
|
||||
|
||||
keyPressMonksActiveTiles(settings,context,device) {
|
||||
const mode = settings.monksActiveTilesMode ? settings.monksActiveTilesMode : 'toggle';
|
||||
const id = settings.monksActiveTilesId;
|
||||
if (id == undefined || id == '') return;
|
||||
let tile = canvas.background.placeables.find(t => t.id == id);
|
||||
if (tile == undefined) return;
|
||||
const tileData = tile.data.flags?.['monks-active-tiles'];
|
||||
if (tileData == undefined) return;
|
||||
|
||||
if (mode == 'toggle') tile.document.setFlag('monks-active-tiles','active',!tileData.active);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as MODULE from "../MaterialDeck.js";
|
||||
import {streamDeck} from "../MaterialDeck.js";
|
||||
import {streamDeck, gamingSystem} from "../MaterialDeck.js";
|
||||
import {compatibleCore} from "./misc.js";
|
||||
|
||||
export class OtherControls{
|
||||
@@ -530,7 +530,7 @@ export class OtherControls{
|
||||
if (tokenControlled) r = new Roll(settings.rollDiceFormula,actor.getRollData());
|
||||
else r = new Roll(settings.rollDiceFormula);
|
||||
|
||||
r.evaluate();
|
||||
r.evaluate({async:false});
|
||||
|
||||
if (rollFunction == 'public') {
|
||||
r.toMessage(r,{rollMode:"roll"})
|
||||
@@ -687,7 +687,7 @@ export class OtherControls{
|
||||
|
||||
updateCompendiumBrowser(settings,context,device,options={}){
|
||||
let rendered = options.renderCompendiumBrowser;
|
||||
if (rendered == undefined && game.system.id == "pf2e") rendered = (document.getElementById("app-1") != null);
|
||||
if (rendered == undefined && gamingSystem == "pf2e") rendered = (document.getElementById("app-1") != null);
|
||||
else if (rendered == undefined) rendered = (document.getElementById("compendium-popout") != null);
|
||||
const background = settings.background ? settings.background : '#000000';
|
||||
const ringOffColor = settings.offRing ? settings.offRing : '#000000';
|
||||
@@ -701,13 +701,13 @@ export class OtherControls{
|
||||
|
||||
keyPressCompendiumBrowser(settings){
|
||||
let element = null;
|
||||
if (game.system.id == "pf2e") element = document.getElementById("app-1")
|
||||
if (gamingSystem == "pf2e") element = document.getElementById("app-1")
|
||||
else element = document.getElementById("compendium-popout");
|
||||
const rendered = (element != null);
|
||||
|
||||
if (rendered)
|
||||
element.getElementsByClassName("close")[0].click();
|
||||
else if (game.system.id == "pf2e")
|
||||
else if (gamingSystem == "pf2e")
|
||||
document.getElementsByClassName("compendium-browser-btn")[0].click()
|
||||
else
|
||||
ui.compendium.renderPopout();
|
||||
|
||||
@@ -79,6 +79,19 @@ export const registerSettings = async function() {
|
||||
onChange: x => window.location.reload()
|
||||
});
|
||||
|
||||
/**
|
||||
* System override
|
||||
*/
|
||||
game.settings.register(MODULE.moduleName,'systemOverride', {
|
||||
name: "MaterialDeck.Sett.SystemOverride",
|
||||
hint: "MaterialDeck.Sett.SystemOverrideHint",
|
||||
scope: "client",
|
||||
config: true,
|
||||
default: "",
|
||||
type: String,
|
||||
onChange: x => window.location.reload()
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the ip address of the server
|
||||
*/
|
||||
|
||||
242
src/systems/starfinder.js
Normal file
242
src/systems/starfinder.js
Normal file
@@ -0,0 +1,242 @@
|
||||
import {compatibleCore} from "../misc.js";
|
||||
|
||||
const proficiencyColors = {
|
||||
0: "#000000",
|
||||
0.5: "#804A00",
|
||||
1: "#C0C0C0",
|
||||
2: "#FFD700"
|
||||
}
|
||||
|
||||
export class starfinder{
|
||||
constructor(){
|
||||
|
||||
}
|
||||
|
||||
getHP(token) {
|
||||
const hp = token.actor.data.data.attributes.hp;
|
||||
return {
|
||||
value: hp.value,
|
||||
max: hp.max
|
||||
}
|
||||
}
|
||||
|
||||
getTempHP(token) {
|
||||
return;
|
||||
}
|
||||
|
||||
getStamina(token) {
|
||||
const stamina = token.actor.data.data.attributes.sp;
|
||||
return {
|
||||
value: stamina.value,
|
||||
max: stamina.max
|
||||
}
|
||||
}
|
||||
|
||||
getAC(token) {
|
||||
return token.actor.data.data.attributes.eac.value;
|
||||
}
|
||||
|
||||
getKinAC(token) {
|
||||
return token.actor.data.data.attributes.kac.value;
|
||||
}
|
||||
|
||||
getShieldHP(token) {
|
||||
return;
|
||||
}
|
||||
|
||||
getSpeed(token) {
|
||||
const movement = token.actor.data.data.attributes.speed;
|
||||
let speed = "";
|
||||
if (movement.burrowing.value > 0) speed += `Burrow: ${movement.burrowing.value}Ft`;
|
||||
if (movement.climbing.value > 0) {
|
||||
if (speed.length > 0) speed += '\n';
|
||||
speed += `Climb: ${movement.climbing.value}Ft`;
|
||||
}
|
||||
if (movement.flying.value > 0) {
|
||||
if (speed.length > 0) speed += '\n';
|
||||
speed += `Fly: ${movement.flying.value}Ft`;
|
||||
}
|
||||
if (movement.land.value > 0) {
|
||||
if (speed.length > 0) speed += '\n';
|
||||
speed += `Land: ${movement.land.value}Ft`;
|
||||
}
|
||||
if (movement.swimming.value > 0) {
|
||||
if (speed.length > 0) speed += '\n';
|
||||
speed += `Swim: ${movement.swimming.value}Ft`;
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
getInitiative(token) {
|
||||
let initiative = token.actor.data.data.attributes.init.total;
|
||||
return (initiative >= 0) ? `+${initiative}` : initiative;
|
||||
}
|
||||
|
||||
toggleInitiative(token) {
|
||||
return;
|
||||
}
|
||||
|
||||
getPassivePerception(token) {
|
||||
return;
|
||||
}
|
||||
|
||||
getPassiveInvestigation(token) {
|
||||
return;
|
||||
}
|
||||
|
||||
getAbility(token, ability) {
|
||||
if (ability == undefined) ability = 'str';
|
||||
return token.actor.data.data.abilities?.[ability].value;
|
||||
}
|
||||
|
||||
getAbilityModifier(token, ability) {
|
||||
if (ability == undefined) ability = 'str';
|
||||
let val = token.actor.data.data.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;
|
||||
return (val >= 0) ? `+${val}` : val;
|
||||
}
|
||||
|
||||
getSkill(token, skill) {
|
||||
if (skill == undefined) skill = 'acr';
|
||||
const val = token.actor.data.data.skills?.[skill].mod;
|
||||
return (val >= 0) ? `+${val}` : val;
|
||||
}
|
||||
|
||||
getProficiency(token) {
|
||||
return;
|
||||
}
|
||||
|
||||
getConditionIcon(condition) {
|
||||
if (condition == undefined) condition = 'removeAll';
|
||||
if (condition == 'removeAll') return window.CONFIG.controlIcons.effects;
|
||||
else return CONFIG.statusEffects.find(e => e.id === condition).icon;
|
||||
}
|
||||
|
||||
getConditionActive(token,condition) {
|
||||
if (condition == undefined) condition = 'removeAll';
|
||||
return token.actor.effects.find(e => e.isTemporary === condition) != undefined;
|
||||
}
|
||||
|
||||
async toggleCondition(token,condition) {
|
||||
if (condition == undefined) condition = 'removeAll';
|
||||
if (condition == 'removeAll'){
|
||||
for( let effect of token.actor.effects)
|
||||
await effect.delete();
|
||||
}
|
||||
else {
|
||||
const effect = CONFIG.statusEffects.find(e => e.id === condition);
|
||||
await token.toggleEffect(effect);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll
|
||||
*/
|
||||
roll(token,roll,options,ability,skill,save) {
|
||||
if (roll == undefined) roll = 'ability';
|
||||
if (ability == undefined) ability = 'str';
|
||||
if (skill == undefined) skill = 'acr';
|
||||
if (save == undefined) save = 'str';
|
||||
|
||||
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 == 'deathSave') token.actor.rollDeathSave(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Items
|
||||
*/
|
||||
getItems(token,itemType) {
|
||||
if (itemType == undefined) itemType = 'any';
|
||||
const allItems = token.actor.items;
|
||||
if (itemType == 'any') return allItems.filter(i => i.type == 'weapon' || i.type == 'shield' || i.type == 'equipment' || i.type == 'consumable' || i.type == 'goods' || i.type == 'container' || i.type == 'technological' || i.type == 'fusion' || i.type == 'upgrade' || i.type == 'weaponAccessory' || i.type == 'augmentation');
|
||||
else if (itemType == 'enhancers') return allItems.filter(i => i.type == 'fusion' || i.type == 'upgrade' || i.type == 'weaponAccessory');
|
||||
else return allItems.filter(i => i.type == itemType);
|
||||
}
|
||||
|
||||
getItemUses(item) {
|
||||
return {available: item.data.data.quantity};
|
||||
}
|
||||
|
||||
/**
|
||||
* Features
|
||||
*/
|
||||
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 == 'race' || i.type == 'theme'|| i.type == 'asi' || i.type == 'archetype' || i.type == 'feat' || i.type == 'actorResource')
|
||||
else if (featureType == 'activeFeat' || featureType == 'passiveFeat') {
|
||||
const features = allItems.filter(i => i.type == 'feat');
|
||||
if (featureType == 'activeFeat') return features.filter(i => i.labels.featType == 'Action');
|
||||
else return features.filter(i => i.labels.featType == 'Passive');
|
||||
}
|
||||
return allItems.filter(i => i.type == featureType)
|
||||
}
|
||||
|
||||
getFeatureUses(item) {
|
||||
if (item.data.type == 'class') return {available: item.data.data.levels};
|
||||
else return {
|
||||
available: item.data.data.uses.value,
|
||||
maximum: item.data.data.uses.max
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Spells
|
||||
*/
|
||||
getSpells(token,level) {
|
||||
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)
|
||||
}
|
||||
|
||||
getSpellUses(token,level,item) {
|
||||
if (level == undefined) level = 'any';
|
||||
if (item.data.data.level == 0) return;
|
||||
|
||||
const spellSlots = token.actor.data.data.spells;
|
||||
const allowedClasses = item.data.data.allowedClasses;
|
||||
|
||||
let uses = {available: 0, maximum: 0};
|
||||
if (allowedClasses.myst && spellSlots?.[`spell${level}`].perClass?.mystic?.max > uses.maximum)
|
||||
uses = {available: spellSlots?.[`spell${level}`].perClass?.mystic.value, maximum: spellSlots?.[`spell${level}`].perClass?.mystic.max}
|
||||
if (allowedClasses.precog && spellSlots?.[`spell${level}`].perClass?.precog?.max > uses.maximum)
|
||||
uses = {available: spellSlots?.[`spell${level}`].perClass?.precog.value, maximum: spellSlots?.[`spell${level}`].perClass?.precog.max}
|
||||
if (allowedClasses.tech && spellSlots?.[`spell${level}`].perClass?.technomancer?.max > uses.maximum)
|
||||
uses = {available: spellSlots?.[`spell${level}`].perClass?.technomancer.value, maximum: spellSlots?.[`spell${level}`].perClass?.technomancer.max}
|
||||
if (allowedClasses.wysh && spellSlots?.[`spell${level}`].perClass?.witchwarper?.max > uses.maximum)
|
||||
uses = {available: spellSlots?.[`spell${level}`].perClass?.witchwarper.value, maximum: spellSlots?.[`spell${level}`].perClass?.witchwarper.max}
|
||||
|
||||
return uses;
|
||||
}
|
||||
|
||||
rollItem(item) {
|
||||
return item.roll()
|
||||
}
|
||||
|
||||
/**
|
||||
* Ring Colors
|
||||
*/
|
||||
getSkillRingColor(token, skill) {
|
||||
const profLevel = token.actor.data.data?.skills[skill]?.proficient;
|
||||
if (profLevel == undefined) return;
|
||||
return proficiencyColors?.[profLevel];
|
||||
}
|
||||
|
||||
getSaveRingColor(token, save) {
|
||||
const profLevel = token.actor.data.data?.abilities[save]?.proficient;
|
||||
if (profLevel == undefined) return;
|
||||
return proficiencyColors?.[profLevel];
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import {dnd5e} from "./dnd5e.js"
|
||||
import {dnd35e} from "./dnd35e.js"
|
||||
import {pf2e} from "./pf2e.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 {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{
|
||||
@@ -14,11 +16,12 @@ export class TokenHelper{
|
||||
}
|
||||
|
||||
setSystem() {
|
||||
if (game.system.id == 'D35E' || game.system.id == 'pf1') this.system = new dnd35e();
|
||||
else if (game.system.id == 'pf2e') this.system = new pf2e();
|
||||
else if (game.system.id == 'demonlord') this.system = new demonlord();
|
||||
else if (game.system.id == 'wfrp4e') this.system = new wfrp4e();
|
||||
else if (game.system.id == 'forbidden-lands') this.system = new forbiddenlands();
|
||||
if (gamingSystem == 'D35E' || gamingSystem == 'pf1') this.system = new dnd35e();
|
||||
else if (gamingSystem == 'pf2e') this.system = new pf2e();
|
||||
else if (gamingSystem == 'demonlord') this.system = new demonlord();
|
||||
else if (gamingSystem == 'wfrp4e') this.system = new wfrp4e();
|
||||
else if (gamingSystem == 'forbidden-lands') this.system = new forbiddenlands();
|
||||
else if (gamingSystem == 'sfrpg') this.system = new starfinder();
|
||||
else this.system = new dnd5e(); //default to dnd5e
|
||||
}
|
||||
|
||||
@@ -34,7 +37,7 @@ export class TokenHelper{
|
||||
else if (type == 'actorId') return this.getTokenFromActorId(identifier);
|
||||
}
|
||||
getTokenFromTokenId(id) {
|
||||
return canvas.tokens.children[0].children.find(p => p.id == id);
|
||||
return canvas.tokens.get(id);
|
||||
}
|
||||
|
||||
getTokenFromTokenName(name) {
|
||||
@@ -132,7 +135,7 @@ export class TokenHelper{
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* System agnostic functions
|
||||
* System specific functions
|
||||
***********************************************************************/
|
||||
getHP(token) {
|
||||
return this.system.getHP(token);
|
||||
@@ -245,9 +248,19 @@ export class TokenHelper{
|
||||
return this.system.getEmpathy(token)
|
||||
}
|
||||
/* forbidden-lands */
|
||||
getWillPower(token) {
|
||||
getWillPower(token) {
|
||||
return this.system.getWillPower(token)
|
||||
}
|
||||
|
||||
/* starfinder */
|
||||
getStamina(token) {
|
||||
return this.system.getStamina(token);
|
||||
}
|
||||
|
||||
/* starfinder */
|
||||
getKinAC(token) {
|
||||
return this.system.getKinAC(token);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -104,7 +104,6 @@ export class wfrp4e {
|
||||
}
|
||||
|
||||
roll(token,roll,options,ability,skill,save) {
|
||||
//console.log("roll(", token, roll, options, ability, skill, save, ")");
|
||||
if (ability == undefined) ability = 'ag';
|
||||
return game.wfrp4e.utility.rollItemMacro(ability, "characteristic", false);
|
||||
}
|
||||
@@ -125,7 +124,6 @@ export class wfrp4e {
|
||||
|
||||
|
||||
getItemUses(item) {
|
||||
//console.log("getItemUses(" , item , ")")
|
||||
if ( item.type == 'ammunition') {
|
||||
return {available: item.data.data.quantity.value};
|
||||
}
|
||||
|
||||
31
src/token.js
31
src/token.js
@@ -190,6 +190,13 @@ export class TokenControl{
|
||||
heart: "#00FF00"
|
||||
};
|
||||
}
|
||||
else if (stats == 'Stamina') { //starfinder
|
||||
const stamina = tokenHelper.getStamina(token);
|
||||
txt += `${stamina.value}/${stamina.max}`;
|
||||
}
|
||||
else if (stats == 'KinAC') { //starfinder
|
||||
txt += tokenHelper.getKinAC(token);
|
||||
}
|
||||
else if (stats == 'AC') txt += tokenHelper.getAC(token);
|
||||
else if (stats == 'ShieldHP') txt += tokenHelper.getShieldHP(token);
|
||||
else if (stats == 'Speed') txt += tokenHelper.getSpeed(token);
|
||||
@@ -434,7 +441,7 @@ export class TokenControl{
|
||||
iconSrc = "modules/MaterialDeck/img/token/hp_empty.png";
|
||||
if (stats == 'TempHP') //Temp HP
|
||||
iconSrc = "modules/MaterialDeck/img/token/temp_hp_empty.png";
|
||||
else if (stats == 'AC' || stats == 'ShieldHP') //AC
|
||||
else if (stats == 'AC' || stats == 'ShieldHP' || stats == 'KinAC') //AC
|
||||
iconSrc = "modules/MaterialDeck/img/token/ac.webp";
|
||||
else if (stats == 'Speed') //Speed
|
||||
iconSrc = "modules/MaterialDeck/img/token/speed.webp";
|
||||
@@ -616,22 +623,28 @@ export class TokenControl{
|
||||
if (isNaN(dimVision)==false) data.dimSight = dimVision;
|
||||
if (isNaN(brightVision)==false) data.brightSight = brightVision;
|
||||
if (isNaN(sightAngle)==false) data.sightAngle = sightAngle;
|
||||
if (isNaN(dimRadius)==false) data.dimLight = dimRadius;
|
||||
if (isNaN(brightRadius)==false) data.brightLight = brightRadius;
|
||||
if (isNaN(emissionAngle)==false) data.lightAngle = emissionAngle;
|
||||
data.lightColor = lightColor;
|
||||
data.lightAlpha = Math.sqrt(colorIntensity).toNearest(0.05)
|
||||
|
||||
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.lightAnimation.speed,
|
||||
intensity: tokenData.lightAnimation.intensity
|
||||
speed: tokenData.light.animation.speed,
|
||||
intensity: tokenData.light.animation.intensity
|
||||
};
|
||||
if (animationType != 'none'){
|
||||
animation.type = animationType;
|
||||
animation.intensity = animationIntensity;
|
||||
animation.speed = animationSpeed;
|
||||
}
|
||||
data.lightAnimation = animation;
|
||||
light.animation = animation;
|
||||
data.light = light;
|
||||
if (compatibleCore('0.8.1')) token.document.update(data);
|
||||
else token.update(data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user