diff --git a/src/systems/forbidden-lands.js b/src/systems/forbidden-lands.js new file mode 100644 index 0000000..0eb1a00 --- /dev/null +++ b/src/systems/forbidden-lands.js @@ -0,0 +1,238 @@ +import {compatibleCore} from "../misc.js"; + +export class forbiddenlands{ + constructor(){ + + } + + getHP(token) { + const hp = token.actor.data.data.attribute.strength; + return { + value: hp.value, + max: hp.max + } + } + + + getAgility(token) { + const agility = token.actor.data.data.attribute.agility; + return { + value: agility.value, + max: agility.max + } + } + + + getWits(token) { + const wits = token.actor.data.data.attribute.wits; + return { + value: wits.value, + max: wits.max + } + } + + getEmpathy(token) { + const empathy = token.actor.data.data.attribute.empathy; + return { + value: empathy.value, + max: empathy.max + } + } + + getWillPower(token) { + const wp = token.actor.data.data.bio.willpower; + return { + value: wp.value, + max: wp.max + } + } + + 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; + return (sum += value); + }, 0); + return totalArmor; + } + + getShieldHP(token) { + return; + } + + getSpeed(token) { + return 1; + } + + getInitiative(token) { + return 0; + let initiative = token.actor.data.data.attributes.init.total; + return (initiative >= 0) ? `+${initiative}` : initiative; + } + + toggleInitiative(token) { + return; + } + + 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; + } + + getAbilityModifier(token, ability) { + return; + } + + getAbilitySave(token, ability) { + return this.getAbility(token, ability); + } + + getSkill(token, skill) { + if (skill == undefined) skill = 'might'; + let skillComp = token.actor.sheet.getSkill(skill); + const val = skillComp.skill.value + skillComp.attribute.value; + return game.i18n.localize(skillComp.skill.label)+`-${val}`; + } + + getProficiency(token) { + return; + const val = token.actor.data.data.attributes.prof; + return (val >= 0) ? `+${val}` : val; + } + + 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 = 'strength'; + if (skill == undefined) skill = 'might'; + if (save == undefined) save = 'strength'; + + if (roll == 'ability') token.actor.sheet.rollAttribute(ability); + else if (roll == 'save') token.actor.sheet.rollAttribute(save); + else if (roll == 'skill') token.actor.sheet.rollSkill(skill); + else if (roll == 'rollFood') token.actor.sheet.rollConsumable('food'); + else if (roll == 'rollWater') token.actor.sheet.rollConsumable('water'); + else if (roll == 'rollArrows') token.actor.sheet.rollConsumable('arrows'); + else if (roll == 'rollTorches') token.actor.sheet.rollConsumable('torches'); + else if (roll == 'rollArmor') token.actor.sheet.rollArmor(); + else if (roll == 'monsterAttack') token.actor.sheet.rollAttack(); + //else if (roll == 'initiative') token.actor.rollInitiative(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 == 'armor' || i.type == 'gear' || i.type == 'rawMaterial'); + else if (token.actor.type == 'monster' && itemType == 'weapon') + { + return allItems.filter(i => i.type == 'monsterAttack'); + } + return allItems.filter(i => i.type == itemType); + } + + 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}; + } + + /** + * Features + */ + getFeatures(token,featureType) { + if (featureType == undefined) featureType = 'any'; + const allItems = token.actor.items; + if (featureType == 'any') return allItems.filter(i => i.type == 'talent') + else 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 return allItems.filter(i => i.type == 'spell' && i.data.data.level == level) + } + + getSpellUses(token,level,item) { + if (level == undefined) level = 'any'; + if (item.data.data.level == 0) return; + return { + available: token.actor.data.data.spells?.[`spell${level}`].value, + maximum: token.actor.data.data.spells?.[`spell${level}`].max + } + } + + rollItem(item) { + const sheet = item.actor.sheet; + if (item.type === "armor") + return sheet.rollSpecificArmor(item.id); + else if (item.type === "weapon") + return sheet.rollGear(item.id); + else if (item.type === "spell") + return sheet.rollSpell(item.id); + else if (item.type === "monsterAttack") + sheet.rollSpecificAttack(item.id); + return item.sendToChat(); + } +} \ No newline at end of file diff --git a/src/systems/tokenHelper.js b/src/systems/tokenHelper.js index aaa7618..eed2f70 100644 --- a/src/systems/tokenHelper.js +++ b/src/systems/tokenHelper.js @@ -3,8 +3,10 @@ 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 {compatibleCore} from "../misc.js"; + export class TokenHelper{ constructor(){ this.system; @@ -16,6 +18,7 @@ export class TokenHelper{ 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(); else this.system = new dnd5e(); //default to dnd5e } @@ -227,6 +230,26 @@ export class TokenHelper{ return this.system.getPerception(token) } + /* forbidden-lands */ + getAgility(token) { + return this.system.getAgility(token) + } + + /* forbidden-lands */ + getWits(token) { + return this.system.getWits(token) + } + + /* forbidden-lands */ + getEmpathy(token) { + return this.system.getEmpathy(token) + } + /* forbidden-lands */ + getWillPower(token) { + return this.system.getWillPower(token) + } + + /** * Conditions */ diff --git a/src/token.js b/src/token.js index 617644a..5c0a197 100644 --- a/src/token.js +++ b/src/token.js @@ -106,6 +106,59 @@ export class TokenControl{ }; } + + if (stats == 'Agility') { /* forbidden-lands */ + const wits = tokenHelper.getAgility(token); + txt += wits.value + "/" + wits.max; + + if (icon == 'stats') + uses = { + available: wits.value, + maximum: wits.max, + heart: "#FF0000" + }; + + } + + if (stats == 'Wits') { /* forbidden-lands */ + const wits = tokenHelper.getWits(token); + txt += wits.value + "/" + wits.max; + + if (icon == 'stats') + uses = { + available: wits.value, + maximum: wits.max, + heart: "#FF0000" + }; + + } + + if (stats == 'Empathy') { /* forbidden-lands */ + const wits = tokenHelper.getEmpathy(token); + txt += wits.value + "/" + wits.max; + + if (icon == 'stats') + uses = { + available: wits.value, + maximum: wits.max, + heart: "#FF0000" + }; + + } + + if (stats == 'WillPower') { /* forbidden-lands */ + const wits = tokenHelper.getWillPower(token); + txt += wits.value + "/" + wits.max; + + if (icon == 'stats') + uses = { + available: wits.value, + maximum: wits.max, + heart: "#FF0000" + }; + + } + if (stats == 'CriticalWounds') { /* WFRP4e */ const criticalWounds = tokenHelper.getCriticalWounds(token); txt += criticalWounds.value + "/" + criticalWounds.max;