diff --git a/languages/br.json b/languages/br.json
index 4fbf2cd..1e88b72 100644
--- a/languages/br.json
+++ b/languages/br.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "Atributos",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "Ações de bônus",
"cantrips": "Truques",
+ "channelDivinity": "Channel Divinity",
"checks": "Testes",
+ "classFeatures": "Class Features",
"conditions": "Condições",
"crewActions": "Ações da tripulação",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "Covil",
"lairActions": "Ações de covil",
"legendary": "Lendária",
"legendaryActions": "Ações Lendárias",
"magicItems": "Itens Mágicos",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "Outras ações",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "Descansos",
"rollInitiative": "Rolar Iniciativa",
+ "runes": "Runes",
"saves": "Salvaguarda",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"skills": "Pericias",
"settings": {
"abbreviateSkills": {
diff --git a/languages/cn.json b/languages/cn.json
index 5c5484a..52abfe2 100644
--- a/languages/cn.json
+++ b/languages/cn.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "属性",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "獎勵行動",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "检定",
+ "classFeatures": "Class Features",
"conditions": "状态",
"crewActions": "船員行動",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "巢穴",
"lairActions": "巢穴行動",
"legendary": "传奇",
"legendaryActions": "傳奇動作",
"magicItems": "魔法物品",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "其他行為",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "休息",
"rollInitiative": "先攻掷骰",
+ "runes": "Runes",
"skills": "技能",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "启用后,技能和属性都会用其三字母缩写。",
diff --git a/languages/de.json b/languages/de.json
index e01abb4..a2dd45a 100644
--- a/languages/de.json
+++ b/languages/de.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "Abilities",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "Bonus Actions",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "Checks",
+ "classFeatures": "Class Features",
"conditions": "Conditions",
"crewActions": "Crew Actions",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "Lair",
"lairActions": "Lair Actions",
"legendary": "Legendär",
"legendaryActions": "Legendary Actions",
"magicItems": "Magische Gegenstände",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "Other Actions",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "Rests",
"rollInitiative": "Initiativewurf",
+ "runes": "Runes",
"skills": "Skills",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "Display skill and ability names as a three-character abbreviation",
diff --git a/languages/en.json b/languages/en.json
index cf5b059..e0d91a0 100644
--- a/languages/en.json
+++ b/languages/en.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "Abilities",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "Bonus Actions",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "Checks",
+ "classFeatures": "Class Features",
"conditions": "Conditions",
"crewActions": "Crew Actions",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "Lair",
"lairActions": "Lair Actions",
"legendary": "Legendary",
"legendaryActions": "Legendary Actions",
"magicItems": "Magic Items",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "Other Actions",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "Rests",
"rollInitiative": "Roll Initiative",
+ "runes": "Runes",
"skills": "Skills",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "Display skill and ability names as a three-character abbreviation",
diff --git a/languages/es.json b/languages/es.json
index 711451c..830d48e 100644
--- a/languages/es.json
+++ b/languages/es.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "Características",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "Acciones de bonificación",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "Pruebas",
+ "classFeatures": "Class Features",
"conditions": "Estados",
"crewActions": "Acciones de la tripulación",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "Guarida",
"lairActions": "Acciones de guarida",
"legendary": "Legendario",
"legendaryActions": "Acciones legendarias",
"magicItems": "Objetos mágicos",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "Otras acciones",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "Descansos",
"rollInitiative": "Tirar iniciativa",
+ "runes": "Runes",
"skills": "Habilidades",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "Si se activa, las habilidades y características utilizarán una abreviatura de tres letras.",
diff --git a/languages/fr.json b/languages/fr.json
index 75548ad..c3f8248 100644
--- a/languages/fr.json
+++ b/languages/fr.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "Abilités",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "Actions bonus",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "Tests",
+ "classFeatures": "Class Features",
"conditions": "Conditions",
"crewActions": "Actions de l'équipage",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "Antre",
"lairActions": "Actions de antre",
"legendary": "Légendaire",
"legendaryActions": "Actions légendaires",
"magicItems": "Objets magiques",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "D'autres actions",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "Repos",
"rollInitiative": "Lancer l'initiative",
+ "runes": "Runes",
"skills": "Compétences",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "Si activée les caractéristiques et les compétences utiliserons une abréviation de 3 caractères.",
diff --git a/languages/it.json b/languages/it.json
index b81901e..5a3bc7c 100644
--- a/languages/it.json
+++ b/languages/it.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "Capacità",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "Azioni bonus",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "Caratteristiche",
+ "classFeatures": "Class Features",
"conditions": "Condizioni",
"crewActions": "Azioni dell'equipaggio",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "Tana",
"lairActions": "Azioni di Tana",
"legendary": "Leggendarie",
"legendaryActions": "Azioni Leggendarie",
"magicItems": "Oggetti Magici",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "Altre azioni",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "Riposi",
"rollInitiative": "Tira Iniziativa",
+ "runes": "Runes",
"skills": "Abilità",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "If enabled, skills and abilities will use a three-character abbreviation.",
diff --git a/languages/ja.json b/languages/ja.json
index 25fb48e..5ac541d 100644
--- a/languages/ja.json
+++ b/languages/ja.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "能力値",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "ボーナス・アクション",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "判定",
+ "classFeatures": "Class Features",
"conditions": "状態",
"crewActions": "乗組員の行動",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "住処",
"lairActions": "住処アクション",
"legendary": "伝説",
"legendaryActions": "伝説的アクション",
"magicItems": "魔法アイテム",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "その他のアクション",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "休憩",
"rollInitiative": "イニシアチブロール",
+ "runes": "Runes",
"skills": "技能",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "技能や能力名をすべて3文字に省略します",
diff --git a/languages/ko.json b/languages/ko.json
index 5a10d97..54cd1bd 100644
--- a/languages/ko.json
+++ b/languages/ko.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "능력치",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "보너스 액션",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "판정",
+ "classFeatures": "Class Features",
"conditions": "상태",
"crewActions": "승무원 조치",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "소굴",
"lairActions": "소굴 액션",
"legendary": "전설적",
"legendaryActions": "전설적 액션",
"magicItems": "매직 아이템",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "다른 행동",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "휴식",
"rollInitiative": "우선권 굴림",
+ "runes": "Runes",
"skills": "기술",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "활성화할 경우 기술 및 능력치는 3 글자 약어로 표시된다.",
diff --git a/languages/pl.json b/languages/pl.json
index 3227c87..1567172 100644
--- a/languages/pl.json
+++ b/languages/pl.json
@@ -12,24 +12,44 @@
"9thLevelSpells": "9th Level Spells",
"abilities": "Zdolności",
"activeFeatures": "Active Features",
+ "artificerInfusions": "Artificer Infusions",
"atWillSpells": "At-Will Spells",
+ "backgroundFeatures": "Background Features",
"bonusActions": "Akcje bonusowe",
"cantrips": "Cantrips",
+ "channelDivinity": "Channel Divinity",
"checks": "Sprawdzenie",
+ "classFeatures": "Class Features",
"conditions": "Stany",
"crewActions": "Akcje załogi",
+ "defensiveTactics": "Defensive Tactics",
+ "eldritchInvocations": "Eldritch Invocations",
+ "elementalDisciplines": "Elemental Disciplines",
+ "feats": "Feats",
+ "fightingStyles": "Fighting Styles",
+ "huntersPrey": "Hunter's Prey",
"innateSpells": "Innate Spells",
+ "kiAbilities": "Ki Abilities",
"lair": "Matecznik",
"lairActions": "Matecznik akcje",
"legendary": "Legendarny",
"legendaryActions": "Legendarny akcje",
"magicItems": "Magiczne Przedmioty",
+ "maneuvers": "Maneuvers",
+ "metamagicOptions": "Metamagic Options",
+ "monsterFeatures": "Monster Features",
+ "multiattacks": "Multiattacks",
"otherActions": "Inne akcje",
+ "pactBoons": "Pact Boons",
"pactSpells": "Pact Spells",
"passiveFeatures": "Passive Features",
+ "psionicPowers": "Psionic Powers",
+ "raceFeatures": "Race Features",
"rests": "Odpoczynki",
"rollInitiative": "Rzut na Inicjatywę",
+ "runes": "Runes",
"skills": "Umiejętności",
+ "superiorHuntersDefense": "Superior Hunter's Defense",
"settings": {
"abbreviateSkills": {
"hint": "Display skill and ability names as a three-character abbreviation",
diff --git a/module.json b/module.json
index 2bd0370..a61102a 100644
--- a/module.json
+++ b/module.json
@@ -16,7 +16,7 @@
],
"url": "https://github.com/Larkinabout/fvtt-token-action-hud-dnd5e",
"flags": {},
- "version": "1.1.0",
+ "version": "1.2.0",
"compatibility": {
"minimum": "10",
"verified": "10.291"
@@ -100,9 +100,9 @@
"type": "module",
"compatibility": [
{
- "minimum": "1.1.0",
- "maximum": "1.1",
- "verified": "1.1.0"
+ "minimum": "1.2.0",
+ "maximum": "1.2",
+ "verified": "1.2.0"
}
]
}
@@ -113,7 +113,7 @@
}
},
"socket": false,
- "manifest": "https://github.com/Larkinabout/fvtt-token-action-hud-dnd5e/releases/download/1.1.0/module.zip",
+ "manifest": "https://github.com/Larkinabout/fvtt-token-action-hud-dnd5e/releases/download/1.2.0/module.zip",
"download": "https://github.com/Larkinabout/fvtt-token-action-hud-dnd5e/releases/latest/download/module.zip",
"readme": "https://github.com/Larkinabout/fvtt-token-action-hud-dnd5e#readme",
"protected": false,
diff --git a/scripts/action-handler.js b/scripts/action-handler.js
index cca668e..d65be26 100644
--- a/scripts/action-handler.js
+++ b/scripts/action-handler.js
@@ -1,6 +1,6 @@
// System Module Imports
import { ACTIVATION_TYPE_ICON, PREPARED_ICON, PROFICIENCY_LEVEL_ICON } from './constants.js'
-import { getSetting } from './utils.js'
+import { Utils } from './utils.js'
// Core Module Imports
import { CoreActionHandler, CoreUtils, Logger } from './config.js'
@@ -65,12 +65,12 @@ export class ActionHandler extends CoreActionHandler {
}
// Set settings variables
- this.abbreviateSkills = getSetting('abbreviateSkills')
- this.displaySpellInfo = getSetting('displaySpellInfo')
- this.showItemsWithoutActivationCosts = getSetting('showItemsWithoutActivationCosts')
- this.showUnchargedItems = getSetting('showUnchargedItems')
- this.showUnequippedItems = getSetting('showUnequippedItems')
- this.showUnpreparedSpells = getSetting('showUnpreparedSpells')
+ this.abbreviateSkills = Utils.getSetting('abbreviateSkills')
+ this.displaySpellInfo = Utils.getSetting('displaySpellInfo')
+ this.showItemsWithoutActivationCosts = Utils.getSetting('showItemsWithoutActivationCosts')
+ this.showUnchargedItems = Utils.getSetting('showUnchargedItems')
+ this.showUnequippedItems = Utils.getSetting('showUnequippedItems')
+ this.showUnpreparedSpells = Utils.getSetting('showUnpreparedSpells')
// Set subcategory variables
this.subcategoryIds = subcategoryIds
@@ -92,7 +92,27 @@ export class ActionHandler extends CoreActionHandler {
this.featureSubcategoryIds = subcategoryIds.filter((subcategoryId) =>
subcategoryId === 'active-features' ||
- subcategoryId === 'passive-features'
+ subcategoryId === 'passive-features' ||
+ subcategoryId === 'background-features' ||
+ subcategoryId === 'class-features' ||
+ subcategoryId === 'feats' ||
+ subcategoryId === 'monster-features' ||
+ subcategoryId === 'race-features' ||
+ subcategoryId === 'artificer-infusions' ||
+ subcategoryId === 'channel-divinity' ||
+ subcategoryId === 'defensive-tactics' ||
+ subcategoryId === 'eldritch-invocations' ||
+ subcategoryId === 'elemental-disciplines' ||
+ subcategoryId === 'fighting-styles' ||
+ subcategoryId === 'hunters-prey' ||
+ subcategoryId === 'ki-abilities' ||
+ subcategoryId === 'maneuvers' ||
+ subcategoryId === 'metamagic-options' ||
+ subcategoryId === 'multiattacks' ||
+ subcategoryId === 'pact-boons' ||
+ subcategoryId === 'psionic-powers' ||
+ subcategoryId === 'runes' ||
+ subcategoryId === 'superior-hunters-defense'
)
this.spellSubcategoryIds = subcategoryIds.filter((subcategoryId) =>
@@ -416,7 +436,7 @@ export class ActionHandler extends CoreActionHandler {
? ' active'
: ''
const cssClass = `toggle${active}`
- const img = condition.icon
+ const img = CoreUtils.getImage(condition)
return {
id,
name,
@@ -499,44 +519,87 @@ export class ActionHandler extends CoreActionHandler {
if (feats.size === 0) return
// Map active and passive features to new maps
- const activeFeatures = new Map()
- const passiveFeatures = new Map()
+ const featuresMap = new Map()
+
+ const featureTypes = [
+ { type: 'background', subcategoryId: 'background-features' },
+ { type: 'class', subcategoryId: 'class-features' },
+ { type: 'monster', subcategoryId: 'monster-features' },
+ { type: 'race', subcategoryId: 'race-features' },
+ { type: 'feats', subcategoryId: 'feats' }
+ ]
+
+ const classFeatureTypes = [
+ { type: 'artificerInfusion', subcategoryId: 'artificer-infusions' },
+ { type: 'channelDivinity', subcategoryId: 'channel-divinity' },
+ { type: 'defensiveTactic', subcategoryId: 'defensive-tactics' },
+ { type: 'eldritchInvocation', subcategoryId: 'eldritch-invocations' },
+ { type: 'elementalDiscipline', subcategoryId: 'elemental-disciplines' },
+ { type: 'fightingStyle', subcategoryId: 'fighting-styles' },
+ { type: 'huntersPrey', subcategoryId: 'hunters-prey' },
+ { type: 'ki', subcategoryId: 'ki-abilities' },
+ { type: 'maneuver', subcategoryId: 'maneuvers' },
+ { type: 'metamagic', subcategoryId: 'metamagic-options' },
+ { type: 'multiattack', subcategoryId: 'multiattacks' },
+ { type: 'pact', subcategoryId: 'pact-boons' },
+ { type: 'psionicPower', subcategoryId: 'psionic-powers' },
+ { type: 'rune', subcategoryId: 'runes' },
+ { type: 'superiorHuntersDefense', subcategoryId: 'superior-hunters-defense' }
+ ]
for (const [key, value] of feats) {
const activationType = value.system.activation?.type
+ const type = value.system.type.value
+ const subType = value.system.type?.subtype
const excludedActivationTypes = ['', 'lair', 'legendary']
- if (activationType && !excludedActivationTypes.includes(activationType)) activeFeatures.set(key, value)
- if (!activationType || activationType === '') passiveFeatures.set(key, value)
- }
-
- // Build active features
- if (this.featureSubcategoryIds.includes('active-features')) {
- const subcategoryData = {
- id: 'active-features',
- name: CoreUtils.i18n('tokenActionHud.dnd5e.activeFeatures'),
- type: 'system'
+ if (activationType && !excludedActivationTypes.includes(activationType)) {
+ if (!featuresMap.has('active-features')) featuresMap.set('active-features', new Map())
+ featuresMap.get('active-features').set(key, value)
}
+ if (!activationType || activationType === '') {
+ if (!featuresMap.has('passive-features')) featuresMap.set('passive-features', new Map())
+ featuresMap.get('passive-features').set(key, value)
+ }
+ for (const featureType of featureTypes) {
+ const subcategoryId = featureType.subcategoryId
+ if (featureType.type === type) {
+ if (!featuresMap.has(subcategoryId)) featuresMap.set(subcategoryId, new Map())
+ featuresMap.get(subcategoryId).set(key, value)
+ }
+ }
+ for (const featureType of classFeatureTypes) {
+ const subcategoryId = featureType.subcategoryId
+ if (subType && featureType.type === subType) {
+ if (!featuresMap.has(subcategoryId)) featuresMap.set(subcategoryId, new Map())
+ featuresMap.get(subcategoryId).set(key, value)
+ }
+ }
+ }
- // Build actions
- this._buildActions(activeFeatures, subcategoryData, actionType)
-
- // Build activations
- if (this.activationSubcategoryIds) this.buildActivations(activeFeatures, subcategoryData, actionType)
+ // Create subcategory name mappings
+ const subcategoryNameMappings = {
+ 'active-features': CoreUtils.i18n('tokenActionHud.dnd5e.activeFeatures'),
+ 'passive-features': CoreUtils.i18n('tokenActionHud.dnd5e.passiveFeatures')
}
- // Build passive features
- if (this.featureSubcategoryIds.includes('passive-features')) {
+ // Loop through inventory subcateogry ids
+ for (const subcategoryId of this.featureSubcategoryIds) {
+ if (!featuresMap.has(subcategoryId)) continue
+
+ // Create subcategory data
const subcategoryData = {
- id: 'passive-features',
- name: CoreUtils.i18n('tokenActionHud.dnd5e.passiveFeatures'),
+ id: subcategoryId,
+ name: subcategoryNameMappings[subcategoryId] ?? '',
type: 'system'
}
+ const features = featuresMap.get(subcategoryId)
+
// Build actions
- this._buildActions(passiveFeatures, subcategoryData, actionType)
+ this._buildActions(features, subcategoryData, actionType)
// Build activations
- if (this.activationSubcategoryIds) this.buildActivations(passiveFeatures, subcategoryData, actionType)
+ if (subcategoryNameMappings[subcategoryId]) this.buildActivations(features, subcategoryData, actionType)
}
}
@@ -1210,7 +1273,7 @@ export class ActionHandler extends CoreActionHandler {
*/
_discardSlowItems (items) {
// Get setting
- const showSlowActions = getSetting('showSlowActions')
+ const showSlowActions = Utils.getSetting('showSlowActions')
// Return all items
if (showSlowActions) return items
diff --git a/scripts/constants.js b/scripts/constants.js
index a1bc5a2..8567232 100644
--- a/scripts/constants.js
+++ b/scripts/constants.js
@@ -5,6 +5,13 @@ export const MODULE = {
ID: 'token-action-hud-dnd5e'
}
+/**
+ * Core module
+ */
+export const CORE_MODULE = {
+ ID: 'token-action-hud-core'
+}
+
/**
* Core module version required by the system module
*/
diff --git a/scripts/defaults.js b/scripts/defaults.js
index 942b612..41c7271 100644
--- a/scripts/defaults.js
+++ b/scripts/defaults.js
@@ -279,29 +279,49 @@ Hooks.on('i18nInit', async () => {
{ id: 'abilities', name: game.i18n.localize('tokenActionHud.dnd5e.abilities'), type: 'system', hasDerivedSubcategories: false },
{ id: 'actions', name: game.i18n.localize('DND5E.ActionPl'), type: 'system', hasDerivedSubcategories: true },
{ id: 'active-features', name: game.i18n.localize('tokenActionHud.dnd5e.activeFeatures'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'artificer-infusions', name: game.i18n.localize('tokenActionHud.dnd5e.artificerInfusions'), type: 'system', hasDerivedSubcategories: false },
{ id: 'at-will-spells', name: game.i18n.localize('tokenActionHud.dnd5e.atWillSpells'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'background-features', name: game.i18n.localize('tokenActionHud.dnd5e.backgroundFeatures'), type: 'system', hasDerivedSubcategories: false },
{ id: 'bonus-actions', name: game.i18n.localize('tokenActionHud.dnd5e.bonusActions'), type: 'system', hasDerivedSubcategories: true },
{ id: 'cantrips', name: game.i18n.localize('tokenActionHud.dnd5e.cantrips'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'channel-divinity', name: game.i18n.localize('tokenActionHud.dnd5e.channelDivinity'), type: 'system', hasDerivedSubcategories: false },
{ id: 'checks', name: game.i18n.localize('tokenActionHud.dnd5e.checks'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'class-features', name: game.i18n.localize('tokenActionHud.dnd5e.classFeatures'), type: 'system', hasDerivedSubcategories: false },
{ id: 'combat', name: game.i18n.localize('tokenActionHud.combat'), type: 'system', hasDerivedSubcategories: false },
{ id: 'conditions', name: game.i18n.localize('tokenActionHud.dnd5e.conditions'), type: 'system', hasDerivedSubcategories: false },
{ id: 'consumables', name: game.i18n.localize('ITEM.TypeConsumablePl'), type: 'system', hasDerivedSubcategories: false },
{ id: 'containers', name: game.i18n.localize('ITEM.TypeContainerPl'), type: 'system', hasDerivedSubcategories: false },
{ id: 'crew-actions', name: game.i18n.localize('tokenActionHud.dnd5e.crewActions'), type: 'system', hasDerivedSubcategories: true },
+ { id: 'defensive-tactics', name: game.i18n.localize('tokenActionHud.dnd5e.defensiveTactics'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'eldritch-invocations', name: game.i18n.localize('tokenActionHud.dnd5e.eldritchInvocations'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'elemental-disciplines', name: game.i18n.localize('tokenActionHud.dnd5e.elementalDisciplines'), type: 'system', hasDerivedSubcategories: false },
{ id: 'equipment', name: game.i18n.localize('ITEM.TypeEquipmentPl'), type: 'system', hasDerivedSubcategories: false },
{ id: 'equipped', name: game.i18n.localize('DND5E.Equipped'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'feats', name: game.i18n.localize('tokenActionHud.dnd5e.feats'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'fighting-styles', name: game.i18n.localize('tokenActionHud.dnd5e.fightingStyles'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'hunters-prey', name: game.i18n.localize('tokenActionHud.dnd5e.huntersPrey'), type: 'system', hasDerivedSubcategories: false },
{ id: 'innate-spells', name: game.i18n.localize('tokenActionHud.dnd5e.innateSpells'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'ki-abilities', name: game.i18n.localize('tokenActionHud.dnd5e.kiAbilities'), type: 'system', hasDerivedSubcategories: false },
{ id: 'lair-actions', name: game.i18n.localize('tokenActionHud.dnd5e.lairActions'), type: 'system', hasDerivedSubcategories: true },
{ id: 'legendary-actions', name: game.i18n.localize('tokenActionHud.dnd5e.legendaryActions'), type: 'system', hasDerivedSubcategories: true },
{ id: 'loot', name: game.i18n.localize('ITEM.TypeLootPl'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'maneuvers', name: game.i18n.localize('tokenActionHud.dnd5e.maneuvers'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'metamagic-options', name: game.i18n.localize('tokenActionHud.dnd5e.metamagicOptions'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'monster-features', name: game.i18n.localize('tokenActionHud.dnd5e.monsterFeatures'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'multiattacks', name: game.i18n.localize('tokenActionHud.dnd5e.multiattacks'), type: 'system', hasDerivedSubcategories: false },
{ id: 'other-actions', name: game.i18n.localize('tokenActionHud.dnd5e.otherActions'), type: 'system', hasDerivedSubcategories: true },
+ { id: 'pact-boons', name: game.i18n.localize('tokenActionHud.dnd5e.pactBoons'), type: 'system', hasDerivedSubcategories: false },
{ id: 'pact-spells', name: game.i18n.localize('tokenActionHud.dnd5e.pactSpells'), type: 'system', hasDerivedSubcategories: false },
{ id: 'passive-effects', name: game.i18n.localize('DND5E.EffectPassive'), type: 'system', hasDerivedSubcategories: false },
{ id: 'passive-features', name: game.i18n.localize('tokenActionHud.dnd5e.passiveFeatures'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'psionic-powers', name: game.i18n.localize('tokenActionHud.dnd5e.psionicPowers'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'race-features', name: game.i18n.localize('tokenActionHud.dnd5e.raceFeatures'), type: 'system', hasDerivedSubcategories: false },
{ id: 'reactions', name: game.i18n.localize('DND5E.ReactionPl'), type: 'system', hasDerivedSubcategories: true },
{ id: 'rests', name: game.i18n.localize('tokenActionHud.dnd5e.rests'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'runes', name: game.i18n.localize('tokenActionHud.dnd5e.runes'), type: 'system', hasDerivedSubcategories: false },
{ id: 'saves', name: game.i18n.localize('DND5E.ClassSaves'), type: 'system', hasDerivedSubcategories: false },
{ id: 'skills', name: game.i18n.localize('tokenActionHud.dnd5e.skills'), type: 'system', hasDerivedSubcategories: false },
+ { id: 'superior-hunters-defense', name: game.i18n.localize('tokenActionHud.dnd5e.superiorHuntersDefense'), type: 'system', hasDerivedSubcategories: false },
{ id: 'temporary-effects', name: game.i18n.localize('DND5E.EffectTemporary'), type: 'system', hasDerivedSubcategories: false },
{ id: 'token', name: game.i18n.localize('tokenActionHud.token'), type: 'system', hasDerivedSubcategories: false },
{ id: 'tools', name: game.i18n.localize('ITEM.TypeToolPl'), type: 'system', hasDerivedSubcategories: false },
@@ -310,4 +330,4 @@ Hooks.on('i18nInit', async () => {
{ id: 'weapons', name: game.i18n.localize('ITEM.TypeWeaponPl'), type: 'system', hasDerivedSubcategories: false }
]
}
-})
\ No newline at end of file
+})
diff --git a/scripts/settings.js b/scripts/settings.js
index be6f982..4ac88d5 100644
--- a/scripts/settings.js
+++ b/scripts/settings.js
@@ -1,7 +1,7 @@
-export function register (updateFunc) {
- const appName = 'token-action-hud-dnd5e'
+import { MODULE } from './constants.js'
- game.settings.register(appName, 'abbreviateSkills', {
+export function register (updateFunc) {
+ game.settings.register(MODULE.ID, 'abbreviateSkills', {
name: game.i18n.localize(
'tokenActionHud.dnd5e.settings.abbreviateSkills.name'
),
@@ -17,7 +17,7 @@ export function register (updateFunc) {
}
})
- game.settings.register(appName, 'showSlowActions', {
+ game.settings.register(MODULE.ID, 'showSlowActions', {
name: game.i18n.localize(
'tokenActionHud.dnd5e.settings.showSlowActions.name'
),
@@ -33,7 +33,7 @@ export function register (updateFunc) {
}
})
- game.settings.register(appName, 'displaySpellInfo', {
+ game.settings.register(MODULE.ID, 'displaySpellInfo', {
name: game.i18n.localize(
'tokenActionHud.dnd5e.settings.displaySpellInfo.name'
),
@@ -49,7 +49,7 @@ export function register (updateFunc) {
}
})
- game.settings.register(appName, 'showUnchargedItems', {
+ game.settings.register(MODULE.ID, 'showUnchargedItems', {
name: game.i18n.localize(
'tokenActionHud.dnd5e.settings.showUnchargedItems.name'
),
@@ -65,7 +65,7 @@ export function register (updateFunc) {
}
})
- game.settings.register(appName, 'showUnequippedItems', {
+ game.settings.register(MODULE.ID, 'showUnequippedItems', {
name: game.i18n.localize(
'tokenActionHud.dnd5e.settings.showUnequippedItems.name'
),
@@ -81,7 +81,7 @@ export function register (updateFunc) {
}
})
- game.settings.register(appName, 'showUnpreparedSpells', {
+ game.settings.register(MODULE.ID, 'showUnpreparedSpells', {
name: game.i18n.localize(
'tokenActionHud.dnd5e.settings.showUnpreparedSpells.name'
),
@@ -97,7 +97,7 @@ export function register (updateFunc) {
}
})
- game.settings.register(appName, 'showItemsWithoutActivationCosts', {
+ game.settings.register(MODULE.ID, 'showItemsWithoutActivationCosts', {
name: game.i18n.localize(
'tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.name'
),
diff --git a/scripts/system-manager.js b/scripts/system-manager.js
index 89c018f..cf0c8ab 100644
--- a/scripts/system-manager.js
+++ b/scripts/system-manager.js
@@ -63,6 +63,6 @@ export class SystemManager extends CoreSystemManager {
defaults.subcategories.push({ id: 'magic-items', name: CoreUtils.i18n('tokenActionHud.dnd5e.magicItems'), type: 'system', hasDerivedSubcategories: true })
defaults.subcategories.sort((a, b) => a.id.localeCompare(b.id))
}
- await CoreUtils.setUserFlag('default', defaults)
+ return defaults
}
}
diff --git a/scripts/token-action-hud-dnd5e.min.js b/scripts/token-action-hud-dnd5e.min.js
index 531e184..9bcaaff 100644
--- a/scripts/token-action-hud-dnd5e.min.js
+++ b/scripts/token-action-hud-dnd5e.min.js
@@ -1 +1 @@
-const e=await import("../../token-action-hud-core/scripts/token-action-hud-core.min.js"),t=e.ActionHandler,s=e.ActionListExtender,i=e.CategoryManager,n=e.PreRollHandler,l=e.RollHandler,a=e.SystemManager,o=e.Utils,c=e.Logger;class MagicItemActionListExtender extends s{constructor(e){super(e.categoryManager),this.actionHandler=e,this.categoryManager=e.categoryManager}extendActionList(e){const t=this.actionHandler.actorId,s=this.actionHandler.tokenId;if(!t)return;const i=MagicItems.actor(t);if(!i)return;const n=i.items??[];if(0===n.length)return;const l={id:"magic-items",type:"system"};n.forEach((e=>{if(e.attuned&&!this._isItemAttuned(e))return;if(e.equipped&&!this._isItemEquipped(e))return;const i={id:`magic-items_${e.id}`,name:e.name,type:"system-derived",info1:`${e.uses}/${e.charges}`};this.actionHandler.addSubcategoryToActionList(l,i);const n=e.ownedEntries.map((i=>{const n=i.item,l=n.id;return{id:l,name:n.name,encodedValue:["magicItem",t,s,`${e.id}>${l}`].join("|"),img:o.getImage(n),info1:n.consumption,info2:n.baseLevel?`${o.i18n("DND5E.AbbreviationLevel")} ${n.baseLevel}`:"",selected:!0}}));this.actionHandler.addActionsToActionList(n,i)}))}_isItemEquipped(e){return e.item.system.equipped}_isItemAttuned(e){return e.item.system.attunment!==(CONFIG.DND5E.attunementTypes?.REQUIRED??1)}}const d={ID:"token-action-hud-dnd5e"},r="1.1",u={bonus:"fas fa-plus",crew:"fas fa-users",day:"fas fa-hourglass-end",hour:"fas fa-hourglass-half",lair:"fas fa-home",minute:"fas fa-hourglass-start",legendary:"fas fas fa-dragon",reaction:"fas fa-bolt",special:"fas fa-star"},p="fas fa-circle-c",m="fas fa-sun",h="fas fa-circle-r",g={.5:"fas fa-adjust",1:"fas fa-check",2:"fas fa-check-double"};let y=null;Hooks.on("i18nInit",(async()=>{y={categories:[{nestId:"inventory",id:"inventory",name:game.i18n.localize("DND5E.Inventory"),subcategories:[{nestId:"inventory_weapons",id:"weapons",name:game.i18n.localize("ITEM.TypeWeaponPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_equipment",id:"equipment",name:game.i18n.localize("ITEM.TypeEquipmentPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_consumables",id:"consumables",name:game.i18n.localize("ITEM.TypeConsumablePl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_tools",id:"tools",name:game.i18n.localize("ITEM.TypeToolPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_containers",id:"containers",name:game.i18n.localize("ITEM.TypeContainerPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_loot",id:"loot",name:game.i18n.localize("ITEM.TypeLootPl"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"features",id:"features",name:game.i18n.localize("DND5E.Features"),subcategories:[{nestId:"features_active-features",id:"active-features",name:game.i18n.localize("tokenActionHud.dnd5e.activeFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"passive-features",nestId:"features_passive-features",name:game.i18n.localize("tokenActionHud.dnd5e.passiveFeatures"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"spells",id:"spells",name:game.i18n.localize("ITEM.TypeSpellPl"),subcategories:[{nestId:"spells_at-will-spells",id:"at-will-spells",name:game.i18n.localize("tokenActionHud.dnd5e.atWillSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_innate-spells",id:"innate-spells",name:game.i18n.localize("tokenActionHud.dnd5e.innateSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_pact-spells",id:"pact-spells",name:game.i18n.localize("tokenActionHud.dnd5e.pactSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_cantrips",id:"cantrips",name:game.i18n.localize("tokenActionHud.dnd5e.cantrips"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_1st-level-spells",id:"1st-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.1stLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_2nd-level-spells",id:"2nd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.2ndLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_3rd-level-spells",id:"3rd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.3rdLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_4th-level-spells",id:"4th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.4thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_5th-level-spells",id:"5th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.5thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_6th-level-spells",id:"6th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.6thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_7th-level-spells",id:"7th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.7thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_8th-level-spells",id:"8th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.8thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_9th-level-spells",id:"9th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.9thLevelSpells"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"attributes",id:"attributes",name:game.i18n.localize("DND5E.Attributes"),subcategories:[{nestId:"attributes_abilities",id:"abilities",name:game.i18n.localize("tokenActionHud.dnd5e.abilities"),type:"system",hasDerivedSubcategories:!1},{nestId:"attributes_skills",id:"skills",name:game.i18n.localize("tokenActionHud.dnd5e.skills"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"effects",id:"effects",name:game.i18n.localize("DND5E.Effects"),subcategories:[{nestId:"effects_temporary-effects",id:"temporary-effects",name:game.i18n.localize("DND5E.EffectTemporary"),type:"system",hasDerivedSubcategories:!1},{nestId:"effects_passive-effects",id:"passive-effects",name:game.i18n.localize("DND5E.EffectPassive"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"conditions",id:"conditions",name:game.i18n.localize("tokenActionHud.dnd5e.conditions"),subcategories:[{nestId:"conditions_conditions",id:"conditions",name:game.i18n.localize("tokenActionHud.dnd5e.conditions"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"utility",id:"utility",name:game.i18n.localize("tokenActionHud.utility"),subcategories:[{nestId:"utility_combat",id:"combat",name:game.i18n.localize("tokenActionHud.combat"),type:"system",hasDerivedSubcategories:!1},{nestId:"utility_token",id:"token",name:game.i18n.localize("tokenActionHud.token"),type:"system",hasDerivedSubcategories:!1},{nestId:"utility_rests",id:"rests",name:game.i18n.localize("tokenActionHud.dnd5e.rests"),type:"system",hasDerivedSubcategories:!1},{nestId:"utility_utility",id:"utility",name:game.i18n.localize("tokenActionHud.utility"),type:"system",hasDerivedSubcategories:!1}]}],subcategories:[{id:"1st-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.1stLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"2nd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.2ndLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"3rd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.3rdLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"4th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.4thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"5th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.5thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"6th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.6thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"7th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.7thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"8th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.8thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"9th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.9thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"abilities",name:game.i18n.localize("tokenActionHud.dnd5e.abilities"),type:"system",hasDerivedSubcategories:!1},{id:"actions",name:game.i18n.localize("DND5E.ActionPl"),type:"system",hasDerivedSubcategories:!0},{id:"active-features",name:game.i18n.localize("tokenActionHud.dnd5e.activeFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"at-will-spells",name:game.i18n.localize("tokenActionHud.dnd5e.atWillSpells"),type:"system",hasDerivedSubcategories:!1},{id:"bonus-actions",name:game.i18n.localize("tokenActionHud.dnd5e.bonusActions"),type:"system",hasDerivedSubcategories:!0},{id:"cantrips",name:game.i18n.localize("tokenActionHud.dnd5e.cantrips"),type:"system",hasDerivedSubcategories:!1},{id:"checks",name:game.i18n.localize("tokenActionHud.dnd5e.checks"),type:"system",hasDerivedSubcategories:!1},{id:"combat",name:game.i18n.localize("tokenActionHud.combat"),type:"system",hasDerivedSubcategories:!1},{id:"conditions",name:game.i18n.localize("tokenActionHud.dnd5e.conditions"),type:"system",hasDerivedSubcategories:!1},{id:"consumables",name:game.i18n.localize("ITEM.TypeConsumablePl"),type:"system",hasDerivedSubcategories:!1},{id:"containers",name:game.i18n.localize("ITEM.TypeContainerPl"),type:"system",hasDerivedSubcategories:!1},{id:"crew-actions",name:game.i18n.localize("tokenActionHud.dnd5e.crewActions"),type:"system",hasDerivedSubcategories:!0},{id:"equipment",name:game.i18n.localize("ITEM.TypeEquipmentPl"),type:"system",hasDerivedSubcategories:!1},{id:"equipped",name:game.i18n.localize("DND5E.Equipped"),type:"system",hasDerivedSubcategories:!1},{id:"innate-spells",name:game.i18n.localize("tokenActionHud.dnd5e.innateSpells"),type:"system",hasDerivedSubcategories:!1},{id:"lair-actions",name:game.i18n.localize("tokenActionHud.dnd5e.lairActions"),type:"system",hasDerivedSubcategories:!0},{id:"legendary-actions",name:game.i18n.localize("tokenActionHud.dnd5e.legendaryActions"),type:"system",hasDerivedSubcategories:!0},{id:"loot",name:game.i18n.localize("ITEM.TypeLootPl"),type:"system",hasDerivedSubcategories:!1},{id:"other-actions",name:game.i18n.localize("tokenActionHud.dnd5e.otherActions"),type:"system",hasDerivedSubcategories:!0},{id:"pact-spells",name:game.i18n.localize("tokenActionHud.dnd5e.pactSpells"),type:"system",hasDerivedSubcategories:!1},{id:"passive-effects",name:game.i18n.localize("DND5E.EffectPassive"),type:"system",hasDerivedSubcategories:!1},{id:"passive-features",name:game.i18n.localize("tokenActionHud.dnd5e.passiveFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"reactions",name:game.i18n.localize("DND5E.ReactionPl"),type:"system",hasDerivedSubcategories:!0},{id:"rests",name:game.i18n.localize("tokenActionHud.dnd5e.rests"),type:"system",hasDerivedSubcategories:!1},{id:"saves",name:game.i18n.localize("DND5E.ClassSaves"),type:"system",hasDerivedSubcategories:!1},{id:"skills",name:game.i18n.localize("tokenActionHud.dnd5e.skills"),type:"system",hasDerivedSubcategories:!1},{id:"temporary-effects",name:game.i18n.localize("DND5E.EffectTemporary"),type:"system",hasDerivedSubcategories:!1},{id:"token",name:game.i18n.localize("tokenActionHud.token"),type:"system",hasDerivedSubcategories:!1},{id:"tools",name:game.i18n.localize("ITEM.TypeToolPl"),type:"system",hasDerivedSubcategories:!1},{id:"unequipped",name:game.i18n.localize("DND5E.Unequipped"),type:"system",hasDerivedSubcategories:!1},{id:"utility",name:game.i18n.localize("tokenActionHud.utility"),type:"system",hasDerivedSubcategories:!1},{id:"weapons",name:game.i18n.localize("ITEM.TypeWeaponPl"),type:"system",hasDerivedSubcategories:!1}]}}));const b="token-action-hud-dnd5e";function getSetting(e,t=null){let s=t??null;try{s=game.settings.get(b,e)}catch{c.debug(`Setting '${e}' not found`)}return s}async function setSetting(e,t){game.settings.settings.get(`${b}.${e}`)?(t=await game.settings.set(b,e,t),c.debug(`Setting '${e}' set to '${t}'`)):c.debug(`Setting '${e}' not found`)}class ActionHandler extends t{actor=null;actors=null;actorId=null;actorType=null;character=null;token=null;tokenId=null;items=null;abbreviateSkills=null;displaySpellInfo=null;showItemsWithoutActivationCosts=null;showUnchargedItems=null;showUnequippedItems=null;showUnpreparedSpells=null;subcategoryIds=null;activationSubcategoryIds=null;effectSubcategoryIds=null;featureSubcategoryIds=null;inventorySubcategoryIds=null;spellSubcategoryIds=null;featureActions=null;inventoryActions=null;spellActions=null;async buildSystemActions(e,t){if(this.actor=e?.actor,this.actorId=this.actor?.id??"multi",this.actors="multi"===this.actorId?this._getActors():[this.actor],this.actorType=this.actor?.type,this.token=e?.token,this.tokenId=this.token?.id??"multi","multi"!==this.actorId){let e=this.actor.items;e=this._discardSlowItems(e),e=this.sortItemsByName(e),this.items=e}this.abbreviateSkills=getSetting("abbreviateSkills"),this.displaySpellInfo=getSetting("displaySpellInfo"),this.showItemsWithoutActivationCosts=getSetting("showItemsWithoutActivationCosts"),this.showUnchargedItems=getSetting("showUnchargedItems"),this.showUnequippedItems=getSetting("showUnequippedItems"),this.showUnpreparedSpells=getSetting("showUnpreparedSpells"),this.subcategoryIds=t,this.activationSubcategoryIds=t.filter((e=>"actions"===e||"bonus-actions"===e||"crew-actions"===e||"lair-actions"===e||"legendary-actions"===e||"reactions"===e||"other-actions"===e)),this.effectSubcategoryIds=t.filter((e=>"passive-effects"===e||"temporary-effects"===e)),this.featureSubcategoryIds=t.filter((e=>"active-features"===e||"passive-features"===e)),this.spellSubcategoryIds=t.filter((e=>"cantrips"===e||"1st-level-spells"===e||"2nd-level-spells"===e||"3rd-level-spells"===e||"4th-level-spells"===e||"5th-level-spells"===e||"6th-level-spells"===e||"7th-level-spells"===e||"8th-level-spells"===e||"9th-level-spells"===e||"at-will-spells"===e||"innate-spells"===e||"pact-spells"===e)),this.activationSubcategoryIds.length>0&&(this.featureSubcategoryIds=["active-features","passive-features"],this.spellSubcategoryIds=["cantrips","1st-level-spells","2nd-level-spells","3rd-level-spells","4th-level-spells","5th-level-spells","6th-level-spells","7th-level-spells","8th-level-spells","9th-level-spells","at-will-spells","innate-spells","pact-spells"]),"character"!==this.actorType&&"npc"!==this.actorType||(this.inventorySubcategoryIds=t.filter((e=>"equipped"===e||"consumables"===e||"containers"===e||"equipment"===e||"loot"===e||"tools"===e||"weapons"===e||"unequipped"===e)),this.activationSubcategoryIds.length>0&&(this.inventorySubcategoryIds=["consumables","containers","equipment","loot","tools","weapons"]),this._buildCharacterActions()),"vehicle"===this.actorType&&(this.inventorySubcategoryIds=this.subcategoryIds.filter((e=>"consumables"===e||"equipment"===e||"tools"===e||"weapons"===e)),this.activationSubcategoryIds.length>0&&(this.inventorySubcategoryIds=["consumables","equipment","tools","weapons"]),this._buildVehicleActions()),this.actor||this._buildMultipleTokenActions()}async _buildCharacterActions(){this._buildAbilities("ability","abilities"),this._buildAbilities("abilityCheck","checks"),this._buildAbilities("abilitySave","saves"),this._buildCombat(),this._buildConditions(),this._buildEffects(),this._buildFeatures(),this._buildInventory(),this._buildRests(),this._buildSkills(),this._buildSpells(),this._buildUtility()}async _buildVehicleActions(){this._buildAbilities("ability","abilities"),this._buildAbilities("abilityCheck","checks"),this._buildAbilities("abilitySave","saves"),this._buildCombat(),this._buildConditions(),this._buildEffects(),this._buildFeatures(),this._buildInventory(),this._buildUtility()}async _buildMultipleTokenActions(){this._buildAbilities("ability","abilities"),this._buildAbilities("abilityCheck","checks"),this._buildAbilities("abilitySave","saves"),this._buildCombat(),this._buildConditions(),this._buildRests(),this._buildSkills(),this._buildUtility()}_buildAbilities(e,t){if(!this.subcategoryIds.includes(t))return;const s="multi"===this.actorId?game.dnd5e.config.abilities:this.actor.system.abilities;if(0===s.length)return;const i=Object.entries(s).filter((e=>0!==s[e[0]].value)).map((i=>{const n=i[0],l=n.charAt(0).toUpperCase()+n.slice(1),a=this.abbreviateSkills?l:game.dnd5e.config.abilities[n],o=[e,this.actorId,this.tokenId,n].join(this.delimiter);return{id:n,name:a,encodedValue:o,icon:"checks"!==t?this._getProficiencyIcon(s[n].proficient):"",selected:!0}})),n={id:t,type:"system"};this.addActionsToActionList(i,n)}async buildActivations(e,t,s="item"){const i=new Map,n={actions:"action","bonus-actions":"bonus","crew-actions":"crew","lair-actions":"lair","legendary-actions":"legendary",reactions:"reaction","other-actions":"other"},l=["action","bonus","crew","lair","legendary","reaction"];for(const[t,s]of e){const e=s.system?.activation?.type,n=l.includes(e)?e:"other";i.has(n)||i.set(n,new Map),i.get(n).set(t,s)}for(const e of this.activationSubcategoryIds){const l=n[e];if(!i.has(l))continue;const a={...t,id:`${e}+${t.id}`,type:"system-derived"},o={id:e,type:"system"};await this.addSubcategoryToActionList(o,a),this.addSubcategoryInfo(t),this._buildActions(i.get(l),a,s)}}_buildCombat(){if(!this.subcategoryIds.includes("combat"))return;const e="utility",t={initiative:{id:"initiative",name:o.i18n("tokenActionHud.dnd5e.rollInitiative")},endTurn:{id:"endTurn",name:o.i18n("tokenActionHud.endTurn")}};game.combat?.current?.tokenId!==this.tokenId&&delete t.endTurn;const s=Object.entries(t).map((t=>{const s=t[1].id,i=t[1].name,n=[e,this.actorId,this.tokenId,s].join(this.delimiter),l={};let a="";if("initiative"===t[0]&&game.combat){const e=canvas.tokens.controlled.map((e=>e.id)),t=game.combat.combatants.filter((t=>e.includes(t.tokenId)));if(1===t.length){const e=t[0].initiative;l.class="tah-spotlight",l.text=e}a=`toggle${t.length>0&&t.every((e=>e?.initiative))?" active":""}`}return{id:s,name:i,encodedValue:n,info1:l,cssClass:a,selected:!0}}));this.addActionsToActionList(s,{id:"combat",type:"system"})}_buildConditions(){if(!this.subcategoryIds.includes("conditions"))return;if(!this.token)return;const e="condition",t=CONFIG.statusEffects.filter((e=>""!==e.id));if(0===t.length)return;const s=t.map((t=>{const s=t.id,i=o.i18n(t.label),n=[e,this.actorId,this.tokenId,s].join(this.delimiter),l=`toggle${this.actors.every((e=>e.effects.map((e=>e.flags?.core?.statusId)).some((e=>e===s))))?" active":""}`,a=t.icon;return{id:s,name:i,encodedValue:n,img:a,cssClass:l,selected:!0}}));this.addActionsToActionList(s,{id:"conditions",type:"system"})}_buildEffects(){if(!this.effectSubcategoryIds)return;const e="effect",t=this.actor.effects;if(0===t.size)return;const s=new Map,i=new Map;for(const e of t){const t=e.id;e.isTemporary?i.set(t,e):s.set(t,e)}if(this.effectSubcategoryIds.includes("passive-effects")){const t={id:"passive-effects",type:"system"};this._buildActions(s,t,e)}if(this.effectSubcategoryIds.includes("temporary-effects")){const t={id:"temporary-effects",type:"system"};this._buildActions(i,t,e)}}_buildFeatures(){if(!this.featureSubcategoryIds)return;const e="feature",t=new Map;for(const[e,s]of this.items){"feat"===s.type&&t.set(e,s)}if(0===t.size)return;const s=new Map,i=new Map;for(const[e,n]of t){const t=n.system.activation?.type,l=["","lair","legendary"];t&&!l.includes(t)&&s.set(e,n),t&&""!==t||i.set(e,n)}if(this.featureSubcategoryIds.includes("active-features")){const t={id:"active-features",name:o.i18n("tokenActionHud.dnd5e.activeFeatures"),type:"system"};this._buildActions(s,t,e),this.activationSubcategoryIds&&this.buildActivations(s,t,e)}if(this.featureSubcategoryIds.includes("passive-features")){const t={id:"passive-features",name:o.i18n("tokenActionHud.dnd5e.passiveFeatures"),type:"system"};this._buildActions(i,t,e),this.activationSubcategoryIds&&this.buildActivations(i,t,e)}}_buildInventory(){if(!this.inventorySubcategoryIds)return;if(0===this.items.size)return;const e=new Map;for(const[t,s]of this.items){const i=s.system.equipped,n=s.system?.quantity>0,l=this._isActiveItem(s),a=this._isUsableItem(s),o=this._isEquippedItem(s),c=s.type;n&&l&&(i&&(e.has("equipped")||e.set("equipped",new Map),e.get("equipped").set(t,s)),i||(e.has("unequipped")||e.set("unequipped",new Map),e.get("unequipped").set(t,s)),a&&"consumable"===c&&(e.has("consumables")||e.set("consumables",new Map),e.get("consumables").set(t,s)),o&&("backpack"===c&&(e.has("containers")||e.set("containers",new Map),e.get("containers").set(t,s)),"equipment"===c&&(e.has("equipment")||e.set("equipment",new Map),e.get("equipment").set(t,s)),"loot"===c&&(e.has("loot")||e.set("loot",new Map),e.get("loot").set(t,s)),"tool"===c&&(e.has("tools")||e.set("tools",new Map),e.get("tools").set(t,s)),"weapon"===c&&(e.has("weapons")||e.set("weapons",new Map),e.get("weapons").set(t,s))))}const t={equipped:o.i18n("DND5E.Equipped"),unequipped:o.i18n("DND5E.Unequipped"),consumables:o.i18n("ITEM.TypeConsumablePl"),containers:o.i18n("ITEM.TypeContainerPl"),equipment:o.i18n("ITEM.TypeEquipmentPl"),loot:o.i18n("ITEM.TypeLootPl"),tools:o.i18n("ITEM.TypeToolPl"),weapons:o.i18n("ITEM.TypeWeaponPl")};for(const s of this.inventorySubcategoryIds){if(!e.has(s))continue;const i={id:s,name:t[s],type:"system"},n=e.get(s);this._buildActions(n,i),this.activationSubcategoryIds&&this.buildActivations(n,i)}}_buildRests(){if(!this.subcategoryIds.includes("rests"))return;if(!this.actors.every((e=>"character"===e.type)))return;const e="utility",t={shortRest:{name:o.i18n("DND5E.ShortRest")},longRest:{name:o.i18n("DND5E.LongRest")}},s=Object.entries(t).map((t=>{const s=t[0],i=t[1].name,n=[e,this.actorId,this.tokenId,s].join(this.delimiter);return{id:s,name:i,encodedValue:n,selected:!0}}));this.addActionsToActionList(s,{id:"rests",type:"system"})}_buildSkills(){if(!this.subcategoryIds.includes("skills"))return;const e="skill",t="multi"===this.actorId?game.dnd5e.config.skills:this.actor.system.skills;if(0===t.length)return;const s=Object.entries(t).map((s=>{try{const i=s[0],n=i.charAt(0).toUpperCase()+i.slice(1),l=this.abbreviateSkills?n:game.dnd5e.config.skills[i].label,a=[e,this.actorId,this.tokenId,i].join(this.delimiter);return{id:i,name:l,encodedValue:a,icon:this._getProficiencyIcon(t[i].value)}}catch(e){return c.error(s),null}})).filter((e=>!!e));this.addActionsToActionList(s,{id:"skills",type:"system"})}_buildSpells(){if(!this.spellSubcategoryIds)return;const e="spell",t=new Map;for(const[e,s]of this.items){if("spell"===s.type){const i=this._isUsableItem(s),n=this._isUsableSpell(s);if(i&&n){switch(s.system.preparation.mode){case"atwill":t.has("at-will-spells")||t.set("at-will-spells",new Map),t.get("at-will-spells").set(e,s);break;case"innate":t.has("innate-spells")||t.set("innate-spells",new Map),t.get("innate-spells").set(e,s);break;case"pact":t.has("pact-spells")||t.set("pact-spells",new Map),t.get("pact-spells").set(e,s);break;default:switch(s.system.level){case 0:t.has("cantrips")||t.set("cantrips",new Map),t.get("cantrips").set(e,s);break;case 1:t.has("1st-level-spells")||t.set("1st-level-spells",new Map),t.get("1st-level-spells").set(e,s);break;case 2:t.has("2nd-level-spells")||t.set("2nd-level-spells",new Map),t.get("2nd-level-spells").set(e,s);break;case 3:t.has("3rd-level-spells")||t.set("3rd-level-spells",new Map),t.get("3rd-level-spells").set(e,s);break;case 4:t.has("4th-level-spells")||t.set("4th-level-spells",new Map),t.get("4th-level-spells").set(e,s);break;case 5:t.has("5th-level-spells")||t.set("5th-level-spells",new Map),t.get("5th-level-spells").set(e,s);break;case 6:t.has("6th-level-spells")||t.set("6th-level-spells",new Map),t.get("6th-level-spells").set(e,s);break;case 7:t.has("7th-level-spells")||t.set("7th-level-spells",new Map),t.get("7th-level-spells").set(e,s);break;case 8:t.has("8th-level-spells")||t.set("8th-level-spells",new Map),t.get("8th-level-spells").set(e,s);break;case 9:t.has("9th-level-spells")||t.set("9th-level-spells",new Map),t.get("9th-level-spells").set(e,s)}}}}}const s=Object.entries(this.actor.system.spells).reverse();let i=null;const n=[];let l=this.showUnchargedItems,a=this.showUnchargedItems;for(const[e,t]of s){const s=t.value>0,o=t.max>0,c=t.level>0;"pact"===e&&(!a&&s&&o&&c&&(a=!0),c||(a=!1),t.slotAvailable=a,i=[e,t]),e.startsWith("spell")&&"spell0"!==e?(!l&&s&&o&&(l=!0),t.slotAvailable=l,n.push([e,t])):s&&(t.slotsAvailable=!0,n.push(e,t))}if(i[1].slotAvailable){const e=n.findIndex((e=>e[0]==="spell"+i[1].level));n[e][1].slotsAvailable=!0}const c={"1st-level-spells":{spellMode:1,name:o.i18n("tokenActionHud.dnd5e.1stLevelSpells")},"2nd-level-spells":{spellMode:2,name:o.i18n("tokenActionHud.dnd5e.2ndLevelSpells")},"3rd-level-spells":{spellMode:3,name:o.i18n("tokenActionHud.dnd5e.3rdLevelSpells")},"4th-level-spells":{spellMode:4,name:o.i18n("tokenActionHud.dnd5e.4thLevelSpells")},"5th-level-spells":{spellMode:5,name:o.i18n("tokenActionHud.dnd5e.5thLevelSpells")},"6th-level-spells":{spellMode:6,name:o.i18n("tokenActionHud.dnd5e.6thLevelSpells")},"7th-level-spells":{spellMode:7,name:o.i18n("tokenActionHud.dnd5e.7thLevelSpells")},"8th-level-spells":{spellMode:8,name:o.i18n("tokenActionHud.dnd5e.8thLevelSpells")},"9th-level-spells":{spellMode:9,name:o.i18n("tokenActionHud.dnd5e.9thLevelSpells")},"at-will-spells":{spellMode:"atwill",name:o.i18n("tokenActionHud.dnd5e.atWillSpells")},cantrips:{spellMode:0,name:o.i18n("tokenActionHud.dnd5e.cantrips")},"innate-spells":{spellMode:"innate",name:o.i18n("tokenActionHud.dnd5e.innateSpells")},"pact-spells":{spellMode:"pact",name:o.i18n("tokenActionHud.dnd5e.pactSpells")}},d=["1","2","3","4","5","6","7","8","9","pact"];for(const s of this.spellSubcategoryIds){const l=c[s].spellMode,a=c[s].name;if(!t.has(s))continue;const o="pact"===l?i[1]:n.find((e=>e[0]===`spell${l}`))?.[1],r=o?.value,u=o?.max,p=o?.slotAvailable;if(!p&&d.includes(l))continue;const m={};m.info1={class:"tah-spotlight",text:u>=0?`${r}/${u}`:""};const h={id:s,name:a,type:"system",info:m};this.addSubcategoryInfo(h);const g=t.get(s);this._buildActions(g,h,e),this.activationSubcategoryIds&&this.buildActivations(g,h,e)}}_buildUtility(){if(!this.subcategoryIds.includes("utility"))return;if(!this.actors.every((e=>"character"===e.type)))return;const e="utility",t={deathSave:{name:o.i18n("DND5E.DeathSave")},inspiration:{name:o.i18n("DND5E.Inspiration")}};("multi"===this.actorId||this.actor.system.attributes.hp.value>0)&&delete t.deathSave;const s=Object.entries(t).map((t=>{const s=t[0],i=t[1].name,n=[e,this.actorId,this.tokenId,s].join(this.delimiter);let l="";if("inspiration"===t[0]){l=`toggle${this.actors.every((e=>e.system.attributes?.inspiration))?" active":""}`}return{id:s,name:i,encodedValue:n,cssClass:l,selected:!0}}));this.addActionsToActionList(s,{id:"utility",type:"system"})}_buildActions(e,t,s="item"){if(0===e.size)return;if(!("string"==typeof t?t:t?.id))return;const i=[...e].map((e=>this._getAction(s,e[1])));this.addActionsToActionList(i,t)}_getAction(e,t){const s=t.id??t._id;let i=t?.name??t?.label;t?.system?.recharge&&!t?.system?.recharge?.charged&&t?.system?.recharge?.value&&(i+=` (${o.i18n("DND5E.Recharge")})`);let n="";if(Object.hasOwn(t,"disabled")){n=`toggle${t.disabled?"":" active"}`}const l=[e,this.actorId,this.tokenId,s].join(this.delimiter),a=o.getImage(t),c=this._getActivationTypeIcon(t?.system?.activation?.type);let d=null,r=null;"spell"===t.type?(d=this._getPreparedIcon(t),this.displaySpellInfo&&(r=this._getSpellInfo(t))):r=this._getItemInfo(t);const u=r?.info1,p=r?.info2,m=r?.info3;return{id:s,name:i,encodedValue:l,cssClass:n,img:a,icon1:c,icon2:d,info1:u,info2:p,info3:m,selected:!0}}_isActiveItem(e){if(this.showItemsWithoutActivationCosts)return!0;const t=Object.keys(game.dnd5e.config.abilityActivationTypes).filter((e=>"none"!==e)),s=e.system.activation,i=s?.type;return!(!s||!t.includes(i))}_isEquippedItem(e){const t=e.type;if(this.showUnequippedItems&&!["consumable","spell","feat"].includes(t))return!0;return!(!e.system.equipped||"consumable"===t)}_isUsableItem(e){if(this.showUnchargedItems)return!0;return!!e.system.uses}_isUsableSpell(e){if("character"!==this.actorType&&this.showUnequippedItems)return!0;const t=e.system.preparation.prepared;if(this.showUnpreparedSpells)return!0;const s=e.system.level,i=Object.keys(game.dnd5e.config.spellPreparationModes).filter((e=>"prepared"!==e)),n=e.system.preparation.mode;return!(0!==s&&!i.includes(n)&&!t)}_getItemInfo(e){return{info1:{text:this._getQuantityData(e)},info2:{text:this._getUsesData(e)},info3:{text:this._getConsumeData(e)}}}_getSpellInfo(e){const t=e.system.components,s=[],i={},n={},l={};if(t?.vocal&&s.push(o.i18n("DND5E.ComponentVerbal")),t?.somatic&&s.push(o.i18n("DND5E.ComponentSomatic")),t?.material&&s.push(o.i18n("DND5E.ComponentMaterial")),s.length&&(i.title=s.join(", "),i.text=s.map((e=>e.charAt(0).toUpperCase())).join("")),t?.concentration){const e=o.i18n("DND5E.Concentration");n.title=e,n.text=e.charAt(0).toUpperCase()}if(t?.ritual){const e=o.i18n("DND5E.Ritual");l.title=e,l.text=e.charAt(0).toUpperCase()}return{info1:i,info2:n,info3:l}}_getActors(){const e=["character","npc"],t=canvas.tokens.controlled.map((e=>e.actor));if(t.every((t=>e.includes(t.type))))return t}_getQuantityData(e){const t=e?.system?.quantity??0;return t>1?t:""}_getUsesData(e){const t=e?.system?.uses;return t&&(t.value>0||t.max>0)?`${t.value??"0"}${t.max>0?`/${t.max}`:""}`:""}_getConsumeData(e){const t=e?.system?.consume?.target,s=e?.system?.consume?.type;if("attribute"===s){const e=t.substr(0,t.lastIndexOf(".")),s=this.actor.system[e];return s?`${s.value??"0"}${s.max?`/${s.max}`:""}`:""}const i=this.items.get(t);if("charges"===s){const e=i?.system.uses;return e?.value?`${e.value}${e.max?`/${e.max}`:""}`:""}return i?.system?.quantity??""}_discardSlowItems(e){if(getSetting("showSlowActions"))return e;const t=["minute","hour","day"],s=new Map;for(const[i,n]of e.entries()){const e=n.system.activation,l=n.system.activation?.type;e&&!t.includes(l)&&s.set(i,n)}return s}_getProficiencyIcon(e){const t=CONFIG.DND5E.proficiencyLevels[e]??"",s=g[e];if(s)return``}_getActivationTypeIcon(e){const t=CONFIG.DND5E.abilityActivationTypes[e]??"",s=u[e];if(s)return``}_getPreparedIcon(e){const t=e.system.level,s=e.system.preparation.mode,i=e.system.preparation.prepared,n=i?"fas fa-sun":"fas fa-sun tah-icon-disabled",l=i?o.i18n("DND5E.SpellPrepared"):o.i18n("DND5E.SpellUnprepared");return"prepared"===s&&0!==t?``:""}}class RollHandler extends l{async doHandleActionEvent(e,t){const s=t.split("|");4!==s.length&&super.throwInvalidValueErr();const i=s[0],n=s[1],l=s[2],a=s[3];if("multi"===l&&"toggleCombat"!==a)for(const t of canvas.tokens.controlled){const s=t.actor?.id,n=t.id;await this._handleMacros(e,i,s,n,a)}else await this._handleMacros(e,i,n,l,a)}async _handleMacros(e,t,s,i,n){switch(t){case"ability":this._rollAbility(e,s,i,n);break;case"abilityCheck":this._rollAbilityTest(e,s,i,n);break;case"abilitySave":this._rollAbilitySave(e,s,i,n);break;case"condition":if(!i)return;await this._toggleCondition(e,i,n);break;case"effect":await this._toggleEffect(e,s,i,n);break;case"feature":case"item":case"spell":case"weapon":this.isRenderItem()?this.doRenderItem(s,i,n):this._useItem(e,s,i,n);break;case"magicItem":this._rollMagicItem(e,s,i,n);break;case"skill":this._rollSkill(e,s,i,n);break;case"utility":await this._performUtilityMacro(e,s,i,n)}}_rollAbility(e,t,s,i){o.getActor(t,s).rollAbility(i,{event:e})}_rollAbilitySave(e,t,s,i){o.getActor(t,s).rollAbilitySave(i,{event:e})}_rollAbilityTest(e,t,s,i){o.getActor(t,s).rollAbilityTest(i,{event:e})}_rollMagicItem(e,t,s,i){const n=o.getActor(t,s),l=i.split(">"),a=l[0],c=l[1];MagicItems.actor(n.id).roll(a,c),Hooks.callAll("forceUpdateTokenActionHud")}_rollSkill(e,t,s,i){o.getActor(t,s).rollSkill(i,{event:e})}_useItem(e,t,s,i){const n=o.getActor(t,s),l=o.getItem(n,i);if(!this._needsRecharge(l))return l.use({event:e});l.rollRecharge()}_needsRecharge(e){return e.system.recharge&&!e.system.recharge.charged&&e.system.recharge.value}async _performUtilityMacro(e,t,s,i){const n=o.getActor(t,s),l=o.getToken(s);switch(i){case"deathSave":n.rollDeathSave({event:e});break;case"endTurn":if(!l)break;game.combat?.current?.tokenId===s&&await(game.combat?.nextTurn());break;case"initiative":await this._rollInitiative(t);break;case"inspiration":{const e=!n.system.attributes.inspiration;n.update({"data.attributes.inspiration":e});break}case"longRest":n.longRest();break;case"shortRest":n.shortRest();break;case"toggleCombat":if(0===canvas.tokens.controlled.length)break;await canvas.tokens.controlled[0].toggleCombat();break;case"toggleVisibility":if(!l)break;l.toggleVisibility()}Hooks.callAll("forceUpdateTokenActionHud")}async _rollInitiative(e,t){const s=o.getActor(e,t);await s.rollInitiative({createCombatants:!0}),Hooks.callAll("forceUpdateTokenActionHud")}async _toggleCondition(e,t,s,i=null){const n=o.getToken(t),l=this.isRightClick(e);if(game.dfreds&&i?.flags?.isConvenient){const e=i.label;game.dfreds.effectInterface._toggleEffect(e)}else{const e=this.findCondition(s);if(!e)return;l?await n.toggleEffect(e,{overlay:!0}):await n.toggleEffect(e)}Hooks.callAll("forceUpdateTokenActionHud")}findCondition(e){return CONFIG.statusEffects.find((t=>t.id===e))}async _toggleEffect(e,t,s,i){const n=o.getActor(t,s),l=("find"in n.effects.entries?n.effects.entries:n.effects).find((e=>e.id===i));if(!l)return;this.isRightClick(e)?await l.delete():await l.update({disabled:!l.disabled}),Hooks.callAll("forceUpdateTokenActionHud")}}class RollHandlerObsidian extends RollHandler{_rollAbilityTest(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"abl",abl:i})}_rollAbilitySave(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"save",save:i})}_rollSkill(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"skl",skl:i})}_useItem(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"item",id:i})}}function register(e){const t="token-action-hud-dnd5e";game.settings.register(t,"abbreviateSkills",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:t=>{e(t)}}),game.settings.register(t,"showSlowActions",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:t=>{e(t)}}),game.settings.register(t,"displaySpellInfo",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:t=>{e(t)}}),game.settings.register(t,"showUnchargedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:t=>{e(t)}}),game.settings.register(t,"showUnequippedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:t=>{e(t)}}),game.settings.register(t,"showUnpreparedSpells",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:t=>{e(t)}}),game.settings.register(t,"showItemsWithoutActivationCosts",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:t=>{e(t)}})}class SystemManager extends a{doGetCategoryManager(){return new i}doGetActionHandler(e){const t=new ActionHandler(e);return o.isModuleActive("magicitems")&&t.addFurtherActionHandler(new MagicItemActionListExtender(t)),t}getAvailableRollHandlers(){let e="Core D&D5e";o.isModuleActive("midi-qol")&&(e+=` [supports ${o.getModuleTitle("midi-qol")}]`);const t={core:e};return a.addHandler(t,"obsidian"),t}doGetRollHandler(e){let t;if("obsidian"===e)t=new RollHandlerObsidian;else t=new RollHandler;return t}doRegisterSettings(e){register(e)}async doRegisterDefaultFlags(){const e=y;game.modules.get("magicitems")?.active&&(e.subcategories.push({id:"magic-items",name:o.i18n("tokenActionHud.dnd5e.magicItems"),type:"system",hasDerivedSubcategories:!0}),e.subcategories.sort(((e,t)=>e.id.localeCompare(t.id)))),await o.setUserFlag("default",e)}}Hooks.once("ready",(async()=>{const e=game.modules.get(d.ID);e.api={requiredCoreModuleVersion:"1.1",SystemManager:SystemManager},Hooks.call("tokenActionHudSystemReady",e)}));export{u as ACTIVATION_TYPE_ICON,ActionHandler,p as CONCENTRATION_ICON,t as CoreActionHandler,s as CoreActionListExtender,i as CoreCategoryManager,n as CorePreRollHandler,l as CoreRollHandler,a as CoreSystemManager,o as CoreUtils,y as DEFAULTS,c as Logger,d as MODULE,MagicItemActionListExtender,m as PREPARED_ICON,g as PROFICIENCY_LEVEL_ICON,r as REQUIRED_CORE_MODULE_VERSION,h as RITUAL_ICON,RollHandler,RollHandlerObsidian,SystemManager,getSetting,register,setSetting};
+const e={ID:"token-action-hud-dnd5e"},t={ID:"token-action-hud-core"},s="1.1",i={bonus:"fas fa-plus",crew:"fas fa-users",day:"fas fa-hourglass-end",hour:"fas fa-hourglass-half",lair:"fas fa-home",minute:"fas fa-hourglass-start",legendary:"fas fas fa-dragon",reaction:"fas fa-bolt",special:"fas fa-star"},n="fas fa-circle-c",a="fas fa-sun",l="fas fa-circle-r",o={.5:"fas fa-adjust",1:"fas fa-check",2:"fas fa-check-double"},c=await import("../../token-action-hud-core/scripts/token-action-hud-core.min.js"),d=c.ActionHandler,r=c.ActionListExtender,u=c.CategoryManager,p=c.PreRollHandler,m=c.RollHandler,g=c.SystemManager,h=c.Utils,y=c.Logger;class Utils{static getSetting(t,s=null){let i=s??null;try{i=game.settings.get(e.ID,t)}catch{y.debug(`Setting '${t}' not found`)}return i}static async setSetting(t,s){try{s=await game.settings.set(e.ID,t,s),y.debug(`Setting '${t}' set to '${s}'`)}catch{y.debug(`Setting '${t}' not found`)}}}class ActionHandler extends d{actor=null;actors=null;actorId=null;actorType=null;character=null;token=null;tokenId=null;items=null;abbreviateSkills=null;displaySpellInfo=null;showItemsWithoutActivationCosts=null;showUnchargedItems=null;showUnequippedItems=null;showUnpreparedSpells=null;subcategoryIds=null;activationSubcategoryIds=null;effectSubcategoryIds=null;featureSubcategoryIds=null;inventorySubcategoryIds=null;spellSubcategoryIds=null;featureActions=null;inventoryActions=null;spellActions=null;async buildSystemActions(e,t){if(this.actor=e?.actor,this.actorId=this.actor?.id??"multi",this.actors="multi"===this.actorId?this._getActors():[this.actor],this.actorType=this.actor?.type,this.token=e?.token,this.tokenId=this.token?.id??"multi","multi"!==this.actorId){let e=this.actor.items;e=this._discardSlowItems(e),e=this.sortItemsByName(e),this.items=e}this.abbreviateSkills=Utils.getSetting("abbreviateSkills"),this.displaySpellInfo=Utils.getSetting("displaySpellInfo"),this.showItemsWithoutActivationCosts=Utils.getSetting("showItemsWithoutActivationCosts"),this.showUnchargedItems=Utils.getSetting("showUnchargedItems"),this.showUnequippedItems=Utils.getSetting("showUnequippedItems"),this.showUnpreparedSpells=Utils.getSetting("showUnpreparedSpells"),this.subcategoryIds=t,this.activationSubcategoryIds=t.filter((e=>"actions"===e||"bonus-actions"===e||"crew-actions"===e||"lair-actions"===e||"legendary-actions"===e||"reactions"===e||"other-actions"===e)),this.effectSubcategoryIds=t.filter((e=>"passive-effects"===e||"temporary-effects"===e)),this.featureSubcategoryIds=t.filter((e=>"active-features"===e||"passive-features"===e||"background-features"===e||"class-features"===e||"feats"===e||"monster-features"===e||"race-features"===e||"artificer-infusions"===e||"channel-divinity"===e||"defensive-tactics"===e||"eldritch-invocations"===e||"elemental-disciplines"===e||"fighting-styles"===e||"hunters-prey"===e||"ki-abilities"===e||"maneuvers"===e||"metamagic-options"===e||"multiattacks"===e||"pact-boons"===e||"psionic-powers"===e||"runes"===e||"superior-hunters-defense"===e)),this.spellSubcategoryIds=t.filter((e=>"cantrips"===e||"1st-level-spells"===e||"2nd-level-spells"===e||"3rd-level-spells"===e||"4th-level-spells"===e||"5th-level-spells"===e||"6th-level-spells"===e||"7th-level-spells"===e||"8th-level-spells"===e||"9th-level-spells"===e||"at-will-spells"===e||"innate-spells"===e||"pact-spells"===e)),this.activationSubcategoryIds.length>0&&(this.featureSubcategoryIds=["active-features","passive-features"],this.spellSubcategoryIds=["cantrips","1st-level-spells","2nd-level-spells","3rd-level-spells","4th-level-spells","5th-level-spells","6th-level-spells","7th-level-spells","8th-level-spells","9th-level-spells","at-will-spells","innate-spells","pact-spells"]),"character"!==this.actorType&&"npc"!==this.actorType||(this.inventorySubcategoryIds=t.filter((e=>"equipped"===e||"consumables"===e||"containers"===e||"equipment"===e||"loot"===e||"tools"===e||"weapons"===e||"unequipped"===e)),this.activationSubcategoryIds.length>0&&(this.inventorySubcategoryIds=["consumables","containers","equipment","loot","tools","weapons"]),this._buildCharacterActions()),"vehicle"===this.actorType&&(this.inventorySubcategoryIds=this.subcategoryIds.filter((e=>"consumables"===e||"equipment"===e||"tools"===e||"weapons"===e)),this.activationSubcategoryIds.length>0&&(this.inventorySubcategoryIds=["consumables","equipment","tools","weapons"]),this._buildVehicleActions()),this.actor||this._buildMultipleTokenActions()}async _buildCharacterActions(){this._buildAbilities("ability","abilities"),this._buildAbilities("abilityCheck","checks"),this._buildAbilities("abilitySave","saves"),this._buildCombat(),this._buildConditions(),this._buildEffects(),this._buildFeatures(),this._buildInventory(),this._buildRests(),this._buildSkills(),this._buildSpells(),this._buildUtility()}async _buildVehicleActions(){this._buildAbilities("ability","abilities"),this._buildAbilities("abilityCheck","checks"),this._buildAbilities("abilitySave","saves"),this._buildCombat(),this._buildConditions(),this._buildEffects(),this._buildFeatures(),this._buildInventory(),this._buildUtility()}async _buildMultipleTokenActions(){this._buildAbilities("ability","abilities"),this._buildAbilities("abilityCheck","checks"),this._buildAbilities("abilitySave","saves"),this._buildCombat(),this._buildConditions(),this._buildRests(),this._buildSkills(),this._buildUtility()}_buildAbilities(e,t){if(!this.subcategoryIds.includes(t))return;const s="multi"===this.actorId?game.dnd5e.config.abilities:this.actor.system.abilities;if(0===s.length)return;const i=Object.entries(s).filter((e=>0!==s[e[0]].value)).map((i=>{const n=i[0],a=n.charAt(0).toUpperCase()+n.slice(1),l=this.abbreviateSkills?a:game.dnd5e.config.abilities[n],o=[e,this.actorId,this.tokenId,n].join(this.delimiter);return{id:n,name:l,encodedValue:o,icon:"checks"!==t?this._getProficiencyIcon(s[n].proficient):"",selected:!0}})),n={id:t,type:"system"};this.addActionsToActionList(i,n)}async buildActivations(e,t,s="item"){const i=new Map,n={actions:"action","bonus-actions":"bonus","crew-actions":"crew","lair-actions":"lair","legendary-actions":"legendary",reactions:"reaction","other-actions":"other"},a=["action","bonus","crew","lair","legendary","reaction"];for(const[t,s]of e){const e=s.system?.activation?.type,n=a.includes(e)?e:"other";i.has(n)||i.set(n,new Map),i.get(n).set(t,s)}for(const e of this.activationSubcategoryIds){const a=n[e];if(!i.has(a))continue;const l={...t,id:`${e}+${t.id}`,type:"system-derived"},o={id:e,type:"system"};await this.addSubcategoryToActionList(o,l),this.addSubcategoryInfo(t),this._buildActions(i.get(a),l,s)}}_buildCombat(){if(!this.subcategoryIds.includes("combat"))return;const e="utility",t={initiative:{id:"initiative",name:h.i18n("tokenActionHud.dnd5e.rollInitiative")},endTurn:{id:"endTurn",name:h.i18n("tokenActionHud.endTurn")}};game.combat?.current?.tokenId!==this.tokenId&&delete t.endTurn;const s=Object.entries(t).map((t=>{const s=t[1].id,i=t[1].name,n=[e,this.actorId,this.tokenId,s].join(this.delimiter),a={};let l="";if("initiative"===t[0]&&game.combat){const e=canvas.tokens.controlled.map((e=>e.id)),t=game.combat.combatants.filter((t=>e.includes(t.tokenId)));if(1===t.length){const e=t[0].initiative;a.class="tah-spotlight",a.text=e}l=`toggle${t.length>0&&t.every((e=>e?.initiative))?" active":""}`}return{id:s,name:i,encodedValue:n,info1:a,cssClass:l,selected:!0}}));this.addActionsToActionList(s,{id:"combat",type:"system"})}_buildConditions(){if(!this.subcategoryIds.includes("conditions"))return;if(!this.token)return;const e="condition",t=CONFIG.statusEffects.filter((e=>""!==e.id));if(0===t.length)return;const s=t.map((t=>{const s=t.id,i=h.i18n(t.label),n=[e,this.actorId,this.tokenId,s].join(this.delimiter),a=`toggle${this.actors.every((e=>e.effects.map((e=>e.flags?.core?.statusId)).some((e=>e===s))))?" active":""}`,l=h.getImage(t);return{id:s,name:i,encodedValue:n,img:l,cssClass:a,selected:!0}}));this.addActionsToActionList(s,{id:"conditions",type:"system"})}_buildEffects(){if(!this.effectSubcategoryIds)return;const e="effect",t=this.actor.effects;if(0===t.size)return;const s=new Map,i=new Map;for(const e of t){const t=e.id;e.isTemporary?i.set(t,e):s.set(t,e)}if(this.effectSubcategoryIds.includes("passive-effects")){const t={id:"passive-effects",type:"system"};this._buildActions(s,t,e)}if(this.effectSubcategoryIds.includes("temporary-effects")){const t={id:"temporary-effects",type:"system"};this._buildActions(i,t,e)}}_buildFeatures(){if(!this.featureSubcategoryIds)return;const e="feature",t=new Map;for(const[e,s]of this.items){"feat"===s.type&&t.set(e,s)}if(0===t.size)return;const s=new Map,i=[{type:"background",subcategoryId:"background-features"},{type:"class",subcategoryId:"class-features"},{type:"monster",subcategoryId:"monster-features"},{type:"race",subcategoryId:"race-features"},{type:"feats",subcategoryId:"feats"}],n=[{type:"artificerInfusion",subcategoryId:"artificer-infusions"},{type:"channelDivinity",subcategoryId:"channel-divinity"},{type:"defensiveTactic",subcategoryId:"defensive-tactics"},{type:"eldritchInvocation",subcategoryId:"eldritch-invocations"},{type:"elementalDiscipline",subcategoryId:"elemental-disciplines"},{type:"fightingStyle",subcategoryId:"fighting-styles"},{type:"huntersPrey",subcategoryId:"hunters-prey"},{type:"ki",subcategoryId:"ki-abilities"},{type:"maneuver",subcategoryId:"maneuvers"},{type:"metamagic",subcategoryId:"metamagic-options"},{type:"multiattack",subcategoryId:"multiattacks"},{type:"pact",subcategoryId:"pact-boons"},{type:"psionicPower",subcategoryId:"psionic-powers"},{type:"rune",subcategoryId:"runes"},{type:"superiorHuntersDefense",subcategoryId:"superior-hunters-defense"}];for(const[e,a]of t){const t=a.system.activation?.type,l=a.system.type.value,o=a.system.type?.subtype,c=["","lair","legendary"];t&&!c.includes(t)&&(s.has("active-features")||s.set("active-features",new Map),s.get("active-features").set(e,a)),t&&""!==t||(s.has("passive-features")||s.set("passive-features",new Map),s.get("passive-features").set(e,a));for(const t of i){const i=t.subcategoryId;t.type===l&&(s.has(i)||s.set(i,new Map),s.get(i).set(e,a))}for(const t of n){const i=t.subcategoryId;o&&t.type===o&&(s.has(i)||s.set(i,new Map),s.get(i).set(e,a))}}const a={"active-features":h.i18n("tokenActionHud.dnd5e.activeFeatures"),"passive-features":h.i18n("tokenActionHud.dnd5e.passiveFeatures")};for(const t of this.featureSubcategoryIds){if(!s.has(t))continue;const i={id:t,name:a[t]??"",type:"system"},n=s.get(t);this._buildActions(n,i,e),a[t]&&this.buildActivations(n,i,e)}}_buildInventory(){if(!this.inventorySubcategoryIds)return;if(0===this.items.size)return;const e=new Map;for(const[t,s]of this.items){const i=s.system.equipped,n=s.system?.quantity>0,a=this._isActiveItem(s),l=this._isUsableItem(s),o=this._isEquippedItem(s),c=s.type;n&&a&&(i&&(e.has("equipped")||e.set("equipped",new Map),e.get("equipped").set(t,s)),i||(e.has("unequipped")||e.set("unequipped",new Map),e.get("unequipped").set(t,s)),l&&"consumable"===c&&(e.has("consumables")||e.set("consumables",new Map),e.get("consumables").set(t,s)),o&&("backpack"===c&&(e.has("containers")||e.set("containers",new Map),e.get("containers").set(t,s)),"equipment"===c&&(e.has("equipment")||e.set("equipment",new Map),e.get("equipment").set(t,s)),"loot"===c&&(e.has("loot")||e.set("loot",new Map),e.get("loot").set(t,s)),"tool"===c&&(e.has("tools")||e.set("tools",new Map),e.get("tools").set(t,s)),"weapon"===c&&(e.has("weapons")||e.set("weapons",new Map),e.get("weapons").set(t,s))))}const t={equipped:h.i18n("DND5E.Equipped"),unequipped:h.i18n("DND5E.Unequipped"),consumables:h.i18n("ITEM.TypeConsumablePl"),containers:h.i18n("ITEM.TypeContainerPl"),equipment:h.i18n("ITEM.TypeEquipmentPl"),loot:h.i18n("ITEM.TypeLootPl"),tools:h.i18n("ITEM.TypeToolPl"),weapons:h.i18n("ITEM.TypeWeaponPl")};for(const s of this.inventorySubcategoryIds){if(!e.has(s))continue;const i={id:s,name:t[s],type:"system"},n=e.get(s);this._buildActions(n,i),this.activationSubcategoryIds&&this.buildActivations(n,i)}}_buildRests(){if(!this.subcategoryIds.includes("rests"))return;if(!this.actors.every((e=>"character"===e.type)))return;const e="utility",t={shortRest:{name:h.i18n("DND5E.ShortRest")},longRest:{name:h.i18n("DND5E.LongRest")}},s=Object.entries(t).map((t=>{const s=t[0],i=t[1].name,n=[e,this.actorId,this.tokenId,s].join(this.delimiter);return{id:s,name:i,encodedValue:n,selected:!0}}));this.addActionsToActionList(s,{id:"rests",type:"system"})}_buildSkills(){if(!this.subcategoryIds.includes("skills"))return;const e="skill",t="multi"===this.actorId?game.dnd5e.config.skills:this.actor.system.skills;if(0===t.length)return;const s=Object.entries(t).map((s=>{try{const i=s[0],n=i.charAt(0).toUpperCase()+i.slice(1),a=this.abbreviateSkills?n:game.dnd5e.config.skills[i].label,l=[e,this.actorId,this.tokenId,i].join(this.delimiter);return{id:i,name:a,encodedValue:l,icon:this._getProficiencyIcon(t[i].value)}}catch(e){return y.error(s),null}})).filter((e=>!!e));this.addActionsToActionList(s,{id:"skills",type:"system"})}_buildSpells(){if(!this.spellSubcategoryIds)return;const e="spell",t=new Map;for(const[e,s]of this.items){if("spell"===s.type){const i=this._isUsableItem(s),n=this._isUsableSpell(s);if(i&&n){switch(s.system.preparation.mode){case"atwill":t.has("at-will-spells")||t.set("at-will-spells",new Map),t.get("at-will-spells").set(e,s);break;case"innate":t.has("innate-spells")||t.set("innate-spells",new Map),t.get("innate-spells").set(e,s);break;case"pact":t.has("pact-spells")||t.set("pact-spells",new Map),t.get("pact-spells").set(e,s);break;default:switch(s.system.level){case 0:t.has("cantrips")||t.set("cantrips",new Map),t.get("cantrips").set(e,s);break;case 1:t.has("1st-level-spells")||t.set("1st-level-spells",new Map),t.get("1st-level-spells").set(e,s);break;case 2:t.has("2nd-level-spells")||t.set("2nd-level-spells",new Map),t.get("2nd-level-spells").set(e,s);break;case 3:t.has("3rd-level-spells")||t.set("3rd-level-spells",new Map),t.get("3rd-level-spells").set(e,s);break;case 4:t.has("4th-level-spells")||t.set("4th-level-spells",new Map),t.get("4th-level-spells").set(e,s);break;case 5:t.has("5th-level-spells")||t.set("5th-level-spells",new Map),t.get("5th-level-spells").set(e,s);break;case 6:t.has("6th-level-spells")||t.set("6th-level-spells",new Map),t.get("6th-level-spells").set(e,s);break;case 7:t.has("7th-level-spells")||t.set("7th-level-spells",new Map),t.get("7th-level-spells").set(e,s);break;case 8:t.has("8th-level-spells")||t.set("8th-level-spells",new Map),t.get("8th-level-spells").set(e,s);break;case 9:t.has("9th-level-spells")||t.set("9th-level-spells",new Map),t.get("9th-level-spells").set(e,s)}}}}}const s=Object.entries(this.actor.system.spells).reverse();let i=null;const n=[];let a=this.showUnchargedItems,l=this.showUnchargedItems;for(const[e,t]of s){const s=t.value>0,o=t.max>0,c=t.level>0;"pact"===e&&(!l&&s&&o&&c&&(l=!0),c||(l=!1),t.slotAvailable=l,i=[e,t]),e.startsWith("spell")&&"spell0"!==e?(!a&&s&&o&&(a=!0),t.slotAvailable=a,n.push([e,t])):s&&(t.slotsAvailable=!0,n.push(e,t))}if(i[1].slotAvailable){const e=n.findIndex((e=>e[0]==="spell"+i[1].level));n[e][1].slotsAvailable=!0}const o={"1st-level-spells":{spellMode:1,name:h.i18n("tokenActionHud.dnd5e.1stLevelSpells")},"2nd-level-spells":{spellMode:2,name:h.i18n("tokenActionHud.dnd5e.2ndLevelSpells")},"3rd-level-spells":{spellMode:3,name:h.i18n("tokenActionHud.dnd5e.3rdLevelSpells")},"4th-level-spells":{spellMode:4,name:h.i18n("tokenActionHud.dnd5e.4thLevelSpells")},"5th-level-spells":{spellMode:5,name:h.i18n("tokenActionHud.dnd5e.5thLevelSpells")},"6th-level-spells":{spellMode:6,name:h.i18n("tokenActionHud.dnd5e.6thLevelSpells")},"7th-level-spells":{spellMode:7,name:h.i18n("tokenActionHud.dnd5e.7thLevelSpells")},"8th-level-spells":{spellMode:8,name:h.i18n("tokenActionHud.dnd5e.8thLevelSpells")},"9th-level-spells":{spellMode:9,name:h.i18n("tokenActionHud.dnd5e.9thLevelSpells")},"at-will-spells":{spellMode:"atwill",name:h.i18n("tokenActionHud.dnd5e.atWillSpells")},cantrips:{spellMode:0,name:h.i18n("tokenActionHud.dnd5e.cantrips")},"innate-spells":{spellMode:"innate",name:h.i18n("tokenActionHud.dnd5e.innateSpells")},"pact-spells":{spellMode:"pact",name:h.i18n("tokenActionHud.dnd5e.pactSpells")}},c=["1","2","3","4","5","6","7","8","9","pact"];for(const s of this.spellSubcategoryIds){const a=o[s].spellMode,l=o[s].name;if(!t.has(s))continue;const d="pact"===a?i[1]:n.find((e=>e[0]===`spell${a}`))?.[1],r=d?.value,u=d?.max,p=d?.slotAvailable;if(!p&&c.includes(a))continue;const m={};m.info1={class:"tah-spotlight",text:u>=0?`${r}/${u}`:""};const g={id:s,name:l,type:"system",info:m};this.addSubcategoryInfo(g);const h=t.get(s);this._buildActions(h,g,e),this.activationSubcategoryIds&&this.buildActivations(h,g,e)}}_buildUtility(){if(!this.subcategoryIds.includes("utility"))return;if(!this.actors.every((e=>"character"===e.type)))return;const e="utility",t={deathSave:{name:h.i18n("DND5E.DeathSave")},inspiration:{name:h.i18n("DND5E.Inspiration")}};("multi"===this.actorId||this.actor.system.attributes.hp.value>0)&&delete t.deathSave;const s=Object.entries(t).map((t=>{const s=t[0],i=t[1].name,n=[e,this.actorId,this.tokenId,s].join(this.delimiter);let a="";if("inspiration"===t[0]){a=`toggle${this.actors.every((e=>e.system.attributes?.inspiration))?" active":""}`}return{id:s,name:i,encodedValue:n,cssClass:a,selected:!0}}));this.addActionsToActionList(s,{id:"utility",type:"system"})}_buildActions(e,t,s="item"){if(0===e.size)return;if(!("string"==typeof t?t:t?.id))return;const i=[...e].map((e=>this._getAction(s,e[1])));this.addActionsToActionList(i,t)}_getAction(e,t){const s=t.id??t._id;let i=t?.name??t?.label;t?.system?.recharge&&!t?.system?.recharge?.charged&&t?.system?.recharge?.value&&(i+=` (${h.i18n("DND5E.Recharge")})`);let n="";if(Object.hasOwn(t,"disabled")){n=`toggle${t.disabled?"":" active"}`}const a=[e,this.actorId,this.tokenId,s].join(this.delimiter),l=h.getImage(t),o=this._getActivationTypeIcon(t?.system?.activation?.type);let c=null,d=null;"spell"===t.type?(c=this._getPreparedIcon(t),this.displaySpellInfo&&(d=this._getSpellInfo(t))):d=this._getItemInfo(t);const r=d?.info1,u=d?.info2,p=d?.info3;return{id:s,name:i,encodedValue:a,cssClass:n,img:l,icon1:o,icon2:c,info1:r,info2:u,info3:p,selected:!0}}_isActiveItem(e){if(this.showItemsWithoutActivationCosts)return!0;const t=Object.keys(game.dnd5e.config.abilityActivationTypes).filter((e=>"none"!==e)),s=e.system.activation,i=s?.type;return!(!s||!t.includes(i))}_isEquippedItem(e){const t=e.type;if(this.showUnequippedItems&&!["consumable","spell","feat"].includes(t))return!0;return!(!e.system.equipped||"consumable"===t)}_isUsableItem(e){if(this.showUnchargedItems)return!0;return!!e.system.uses}_isUsableSpell(e){if("character"!==this.actorType&&this.showUnequippedItems)return!0;const t=e.system.preparation.prepared;if(this.showUnpreparedSpells)return!0;const s=e.system.level,i=Object.keys(game.dnd5e.config.spellPreparationModes).filter((e=>"prepared"!==e)),n=e.system.preparation.mode;return!(0!==s&&!i.includes(n)&&!t)}_getItemInfo(e){return{info1:{text:this._getQuantityData(e)},info2:{text:this._getUsesData(e)},info3:{text:this._getConsumeData(e)}}}_getSpellInfo(e){const t=e.system.components,s=[],i={},n={},a={};if(t?.vocal&&s.push(h.i18n("DND5E.ComponentVerbal")),t?.somatic&&s.push(h.i18n("DND5E.ComponentSomatic")),t?.material&&s.push(h.i18n("DND5E.ComponentMaterial")),s.length&&(i.title=s.join(", "),i.text=s.map((e=>e.charAt(0).toUpperCase())).join("")),t?.concentration){const e=h.i18n("DND5E.Concentration");n.title=e,n.text=e.charAt(0).toUpperCase()}if(t?.ritual){const e=h.i18n("DND5E.Ritual");a.title=e,a.text=e.charAt(0).toUpperCase()}return{info1:i,info2:n,info3:a}}_getActors(){const e=["character","npc"],t=canvas.tokens.controlled.map((e=>e.actor));if(t.every((t=>e.includes(t.type))))return t}_getQuantityData(e){const t=e?.system?.quantity??0;return t>1?t:""}_getUsesData(e){const t=e?.system?.uses;return t&&(t.value>0||t.max>0)?`${t.value??"0"}${t.max>0?`/${t.max}`:""}`:""}_getConsumeData(e){const t=e?.system?.consume?.target,s=e?.system?.consume?.type;if("attribute"===s){const e=t.substr(0,t.lastIndexOf(".")),s=this.actor.system[e];return s?`${s.value??"0"}${s.max?`/${s.max}`:""}`:""}const i=this.items.get(t);if("charges"===s){const e=i?.system.uses;return e?.value?`${e.value}${e.max?`/${e.max}`:""}`:""}return i?.system?.quantity??""}_discardSlowItems(e){if(Utils.getSetting("showSlowActions"))return e;const t=["minute","hour","day"],s=new Map;for(const[i,n]of e.entries()){const e=n.system.activation,a=n.system.activation?.type;e&&!t.includes(a)&&s.set(i,n)}return s}_getProficiencyIcon(e){const t=CONFIG.DND5E.proficiencyLevels[e]??"",s=o[e];if(s)return``}_getActivationTypeIcon(e){const t=CONFIG.DND5E.abilityActivationTypes[e]??"",s=i[e];if(s)return``}_getPreparedIcon(e){const t=e.system.level,s=e.system.preparation.mode,i=e.system.preparation.prepared,n=i?"fas fa-sun":"fas fa-sun tah-icon-disabled",a=i?h.i18n("DND5E.SpellPrepared"):h.i18n("DND5E.SpellUnprepared");return"prepared"===s&&0!==t?``:""}}class MagicItemActionListExtender extends r{constructor(e){super(e.categoryManager),this.actionHandler=e,this.categoryManager=e.categoryManager}extendActionList(e){const t=this.actionHandler.actorId,s=this.actionHandler.tokenId;if(!t)return;const i=MagicItems.actor(t);if(!i)return;const n=i.items??[];if(0===n.length)return;const a={id:"magic-items",type:"system"};n.forEach((e=>{if(e.attuned&&!this._isItemAttuned(e))return;if(e.equipped&&!this._isItemEquipped(e))return;const i={id:`magic-items_${e.id}`,name:e.name,type:"system-derived",info1:`${e.uses}/${e.charges}`};this.actionHandler.addSubcategoryToActionList(a,i);const n=e.ownedEntries.map((i=>{const n=i.item,a=n.id;return{id:a,name:n.name,encodedValue:["magicItem",t,s,`${e.id}>${a}`].join("|"),img:h.getImage(n),info1:n.consumption,info2:n.baseLevel?`${h.i18n("DND5E.AbbreviationLevel")} ${n.baseLevel}`:"",selected:!0}}));this.actionHandler.addActionsToActionList(n,i)}))}_isItemEquipped(e){return e.item.system.equipped}_isItemAttuned(e){return e.item.system.attunment!==(CONFIG.DND5E.attunementTypes?.REQUIRED??1)}}class RollHandler extends m{async doHandleActionEvent(e,t){const s=t.split("|");4!==s.length&&super.throwInvalidValueErr();const i=s[0],n=s[1],a=s[2],l=s[3];if("multi"===a&&"toggleCombat"!==l)for(const t of canvas.tokens.controlled){const s=t.actor?.id,n=t.id;await this._handleMacros(e,i,s,n,l)}else await this._handleMacros(e,i,n,a,l)}async _handleMacros(e,t,s,i,n){switch(t){case"ability":this._rollAbility(e,s,i,n);break;case"abilityCheck":this._rollAbilityTest(e,s,i,n);break;case"abilitySave":this._rollAbilitySave(e,s,i,n);break;case"condition":if(!i)return;await this._toggleCondition(e,i,n);break;case"effect":await this._toggleEffect(e,s,i,n);break;case"feature":case"item":case"spell":case"weapon":this.isRenderItem()?this.doRenderItem(s,i,n):this._useItem(e,s,i,n);break;case"magicItem":this._rollMagicItem(e,s,i,n);break;case"skill":this._rollSkill(e,s,i,n);break;case"utility":await this._performUtilityMacro(e,s,i,n)}}_rollAbility(e,t,s,i){h.getActor(t,s).rollAbility(i,{event:e})}_rollAbilitySave(e,t,s,i){h.getActor(t,s).rollAbilitySave(i,{event:e})}_rollAbilityTest(e,t,s,i){h.getActor(t,s).rollAbilityTest(i,{event:e})}_rollMagicItem(e,t,s,i){const n=h.getActor(t,s),a=i.split(">"),l=a[0],o=a[1];MagicItems.actor(n.id).roll(l,o),Hooks.callAll("forceUpdateTokenActionHud")}_rollSkill(e,t,s,i){h.getActor(t,s).rollSkill(i,{event:e})}_useItem(e,t,s,i){const n=h.getActor(t,s),a=h.getItem(n,i);if(!this._needsRecharge(a))return a.use({event:e});a.rollRecharge()}_needsRecharge(e){return e.system.recharge&&!e.system.recharge.charged&&e.system.recharge.value}async _performUtilityMacro(e,t,s,i){const n=h.getActor(t,s),a=h.getToken(s);switch(i){case"deathSave":n.rollDeathSave({event:e});break;case"endTurn":if(!a)break;game.combat?.current?.tokenId===s&&await(game.combat?.nextTurn());break;case"initiative":await this._rollInitiative(t);break;case"inspiration":{const e=!n.system.attributes.inspiration;n.update({"data.attributes.inspiration":e});break}case"longRest":n.longRest();break;case"shortRest":n.shortRest();break;case"toggleCombat":if(0===canvas.tokens.controlled.length)break;await canvas.tokens.controlled[0].toggleCombat();break;case"toggleVisibility":if(!a)break;a.toggleVisibility()}Hooks.callAll("forceUpdateTokenActionHud")}async _rollInitiative(e,t){const s=h.getActor(e,t);await s.rollInitiative({createCombatants:!0}),Hooks.callAll("forceUpdateTokenActionHud")}async _toggleCondition(e,t,s,i=null){const n=h.getToken(t),a=this.isRightClick(e);if(game.dfreds&&i?.flags?.isConvenient){const e=i.label;game.dfreds.effectInterface._toggleEffect(e)}else{const e=this.findCondition(s);if(!e)return;a?await n.toggleEffect(e,{overlay:!0}):await n.toggleEffect(e)}Hooks.callAll("forceUpdateTokenActionHud")}findCondition(e){return CONFIG.statusEffects.find((t=>t.id===e))}async _toggleEffect(e,t,s,i){const n=h.getActor(t,s),a=("find"in n.effects.entries?n.effects.entries:n.effects).find((e=>e.id===i));if(!a)return;this.isRightClick(e)?await a.delete():await a.update({disabled:!a.disabled}),Hooks.callAll("forceUpdateTokenActionHud")}}class RollHandlerObsidian extends RollHandler{_rollAbilityTest(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"abl",abl:i})}_rollAbilitySave(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"save",save:i})}_rollSkill(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"skl",skl:i})}_useItem(e,t,s,i){const n=super.getActor(t,s);OBSIDIAN.Items.roll(n,{roll:"item",id:i})}}function register(t){game.settings.register(e.ID,"abbreviateSkills",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.abbreviateSkills.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showSlowActions",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showSlowActions.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"displaySpellInfo",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.displaySpellInfo.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnchargedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnchargedItems.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnequippedItems",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnequippedItems.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showUnpreparedSpells",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showUnpreparedSpells.hint"),scope:"client",config:!0,type:Boolean,default:!0,onChange:e=>{t(e)}}),game.settings.register(e.ID,"showItemsWithoutActivationCosts",{name:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.name"),hint:game.i18n.localize("tokenActionHud.dnd5e.settings.showItemsWithoutActivationCosts.hint"),scope:"client",config:!0,type:Boolean,default:!1,onChange:e=>{t(e)}})}let b=null;Hooks.on("i18nInit",(async()=>{b={categories:[{nestId:"inventory",id:"inventory",name:game.i18n.localize("DND5E.Inventory"),subcategories:[{nestId:"inventory_weapons",id:"weapons",name:game.i18n.localize("ITEM.TypeWeaponPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_equipment",id:"equipment",name:game.i18n.localize("ITEM.TypeEquipmentPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_consumables",id:"consumables",name:game.i18n.localize("ITEM.TypeConsumablePl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_tools",id:"tools",name:game.i18n.localize("ITEM.TypeToolPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_containers",id:"containers",name:game.i18n.localize("ITEM.TypeContainerPl"),type:"system",hasDerivedSubcategories:!1},{nestId:"inventory_loot",id:"loot",name:game.i18n.localize("ITEM.TypeLootPl"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"features",id:"features",name:game.i18n.localize("DND5E.Features"),subcategories:[{nestId:"features_active-features",id:"active-features",name:game.i18n.localize("tokenActionHud.dnd5e.activeFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"passive-features",nestId:"features_passive-features",name:game.i18n.localize("tokenActionHud.dnd5e.passiveFeatures"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"spells",id:"spells",name:game.i18n.localize("ITEM.TypeSpellPl"),subcategories:[{nestId:"spells_at-will-spells",id:"at-will-spells",name:game.i18n.localize("tokenActionHud.dnd5e.atWillSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_innate-spells",id:"innate-spells",name:game.i18n.localize("tokenActionHud.dnd5e.innateSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_pact-spells",id:"pact-spells",name:game.i18n.localize("tokenActionHud.dnd5e.pactSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_cantrips",id:"cantrips",name:game.i18n.localize("tokenActionHud.dnd5e.cantrips"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_1st-level-spells",id:"1st-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.1stLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_2nd-level-spells",id:"2nd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.2ndLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_3rd-level-spells",id:"3rd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.3rdLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_4th-level-spells",id:"4th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.4thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_5th-level-spells",id:"5th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.5thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_6th-level-spells",id:"6th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.6thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_7th-level-spells",id:"7th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.7thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_8th-level-spells",id:"8th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.8thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{nestId:"spells_9th-level-spells",id:"9th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.9thLevelSpells"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"attributes",id:"attributes",name:game.i18n.localize("DND5E.Attributes"),subcategories:[{nestId:"attributes_abilities",id:"abilities",name:game.i18n.localize("tokenActionHud.dnd5e.abilities"),type:"system",hasDerivedSubcategories:!1},{nestId:"attributes_skills",id:"skills",name:game.i18n.localize("tokenActionHud.dnd5e.skills"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"effects",id:"effects",name:game.i18n.localize("DND5E.Effects"),subcategories:[{nestId:"effects_temporary-effects",id:"temporary-effects",name:game.i18n.localize("DND5E.EffectTemporary"),type:"system",hasDerivedSubcategories:!1},{nestId:"effects_passive-effects",id:"passive-effects",name:game.i18n.localize("DND5E.EffectPassive"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"conditions",id:"conditions",name:game.i18n.localize("tokenActionHud.dnd5e.conditions"),subcategories:[{nestId:"conditions_conditions",id:"conditions",name:game.i18n.localize("tokenActionHud.dnd5e.conditions"),type:"system",hasDerivedSubcategories:!1}]},{nestId:"utility",id:"utility",name:game.i18n.localize("tokenActionHud.utility"),subcategories:[{nestId:"utility_combat",id:"combat",name:game.i18n.localize("tokenActionHud.combat"),type:"system",hasDerivedSubcategories:!1},{nestId:"utility_token",id:"token",name:game.i18n.localize("tokenActionHud.token"),type:"system",hasDerivedSubcategories:!1},{nestId:"utility_rests",id:"rests",name:game.i18n.localize("tokenActionHud.dnd5e.rests"),type:"system",hasDerivedSubcategories:!1},{nestId:"utility_utility",id:"utility",name:game.i18n.localize("tokenActionHud.utility"),type:"system",hasDerivedSubcategories:!1}]}],subcategories:[{id:"1st-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.1stLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"2nd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.2ndLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"3rd-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.3rdLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"4th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.4thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"5th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.5thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"6th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.6thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"7th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.7thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"8th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.8thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"9th-level-spells",name:game.i18n.localize("tokenActionHud.dnd5e.9thLevelSpells"),type:"system",hasDerivedSubcategories:!1},{id:"abilities",name:game.i18n.localize("tokenActionHud.dnd5e.abilities"),type:"system",hasDerivedSubcategories:!1},{id:"actions",name:game.i18n.localize("DND5E.ActionPl"),type:"system",hasDerivedSubcategories:!0},{id:"active-features",name:game.i18n.localize("tokenActionHud.dnd5e.activeFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"artificer-infusions",name:game.i18n.localize("tokenActionHud.dnd5e.artificerInfusions"),type:"system",hasDerivedSubcategories:!1},{id:"at-will-spells",name:game.i18n.localize("tokenActionHud.dnd5e.atWillSpells"),type:"system",hasDerivedSubcategories:!1},{id:"background-features",name:game.i18n.localize("tokenActionHud.dnd5e.backgroundFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"bonus-actions",name:game.i18n.localize("tokenActionHud.dnd5e.bonusActions"),type:"system",hasDerivedSubcategories:!0},{id:"cantrips",name:game.i18n.localize("tokenActionHud.dnd5e.cantrips"),type:"system",hasDerivedSubcategories:!1},{id:"channel-divinity",name:game.i18n.localize("tokenActionHud.dnd5e.channelDivinity"),type:"system",hasDerivedSubcategories:!1},{id:"checks",name:game.i18n.localize("tokenActionHud.dnd5e.checks"),type:"system",hasDerivedSubcategories:!1},{id:"class-features",name:game.i18n.localize("tokenActionHud.dnd5e.classFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"combat",name:game.i18n.localize("tokenActionHud.combat"),type:"system",hasDerivedSubcategories:!1},{id:"conditions",name:game.i18n.localize("tokenActionHud.dnd5e.conditions"),type:"system",hasDerivedSubcategories:!1},{id:"consumables",name:game.i18n.localize("ITEM.TypeConsumablePl"),type:"system",hasDerivedSubcategories:!1},{id:"containers",name:game.i18n.localize("ITEM.TypeContainerPl"),type:"system",hasDerivedSubcategories:!1},{id:"crew-actions",name:game.i18n.localize("tokenActionHud.dnd5e.crewActions"),type:"system",hasDerivedSubcategories:!0},{id:"defensive-tactics",name:game.i18n.localize("tokenActionHud.dnd5e.defensiveTactics"),type:"system",hasDerivedSubcategories:!1},{id:"eldritch-invocations",name:game.i18n.localize("tokenActionHud.dnd5e.eldritchInvocations"),type:"system",hasDerivedSubcategories:!1},{id:"elemental-disciplines",name:game.i18n.localize("tokenActionHud.dnd5e.elementalDisciplines"),type:"system",hasDerivedSubcategories:!1},{id:"equipment",name:game.i18n.localize("ITEM.TypeEquipmentPl"),type:"system",hasDerivedSubcategories:!1},{id:"equipped",name:game.i18n.localize("DND5E.Equipped"),type:"system",hasDerivedSubcategories:!1},{id:"feats",name:game.i18n.localize("tokenActionHud.dnd5e.feats"),type:"system",hasDerivedSubcategories:!1},{id:"fighting-styles",name:game.i18n.localize("tokenActionHud.dnd5e.fightingStyles"),type:"system",hasDerivedSubcategories:!1},{id:"hunters-prey",name:game.i18n.localize("tokenActionHud.dnd5e.huntersPrey"),type:"system",hasDerivedSubcategories:!1},{id:"innate-spells",name:game.i18n.localize("tokenActionHud.dnd5e.innateSpells"),type:"system",hasDerivedSubcategories:!1},{id:"ki-abilities",name:game.i18n.localize("tokenActionHud.dnd5e.kiAbilities"),type:"system",hasDerivedSubcategories:!1},{id:"lair-actions",name:game.i18n.localize("tokenActionHud.dnd5e.lairActions"),type:"system",hasDerivedSubcategories:!0},{id:"legendary-actions",name:game.i18n.localize("tokenActionHud.dnd5e.legendaryActions"),type:"system",hasDerivedSubcategories:!0},{id:"loot",name:game.i18n.localize("ITEM.TypeLootPl"),type:"system",hasDerivedSubcategories:!1},{id:"maneuvers",name:game.i18n.localize("tokenActionHud.dnd5e.maneuvers"),type:"system",hasDerivedSubcategories:!1},{id:"metamagic-options",name:game.i18n.localize("tokenActionHud.dnd5e.metamagicOptions"),type:"system",hasDerivedSubcategories:!1},{id:"monster-features",name:game.i18n.localize("tokenActionHud.dnd5e.monsterFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"multiattacks",name:game.i18n.localize("tokenActionHud.dnd5e.multiattacks"),type:"system",hasDerivedSubcategories:!1},{id:"other-actions",name:game.i18n.localize("tokenActionHud.dnd5e.otherActions"),type:"system",hasDerivedSubcategories:!0},{id:"pact-boons",name:game.i18n.localize("tokenActionHud.dnd5e.pactBoons"),type:"system",hasDerivedSubcategories:!1},{id:"pact-spells",name:game.i18n.localize("tokenActionHud.dnd5e.pactSpells"),type:"system",hasDerivedSubcategories:!1},{id:"passive-effects",name:game.i18n.localize("DND5E.EffectPassive"),type:"system",hasDerivedSubcategories:!1},{id:"passive-features",name:game.i18n.localize("tokenActionHud.dnd5e.passiveFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"psionic-powers",name:game.i18n.localize("tokenActionHud.dnd5e.psionicPowers"),type:"system",hasDerivedSubcategories:!1},{id:"race-features",name:game.i18n.localize("tokenActionHud.dnd5e.raceFeatures"),type:"system",hasDerivedSubcategories:!1},{id:"reactions",name:game.i18n.localize("DND5E.ReactionPl"),type:"system",hasDerivedSubcategories:!0},{id:"rests",name:game.i18n.localize("tokenActionHud.dnd5e.rests"),type:"system",hasDerivedSubcategories:!1},{id:"runes",name:game.i18n.localize("tokenActionHud.dnd5e.runes"),type:"system",hasDerivedSubcategories:!1},{id:"saves",name:game.i18n.localize("DND5E.ClassSaves"),type:"system",hasDerivedSubcategories:!1},{id:"skills",name:game.i18n.localize("tokenActionHud.dnd5e.skills"),type:"system",hasDerivedSubcategories:!1},{id:"superior-hunters-defense",name:game.i18n.localize("tokenActionHud.dnd5e.superiorHuntersDefense"),type:"system",hasDerivedSubcategories:!1},{id:"temporary-effects",name:game.i18n.localize("DND5E.EffectTemporary"),type:"system",hasDerivedSubcategories:!1},{id:"token",name:game.i18n.localize("tokenActionHud.token"),type:"system",hasDerivedSubcategories:!1},{id:"tools",name:game.i18n.localize("ITEM.TypeToolPl"),type:"system",hasDerivedSubcategories:!1},{id:"unequipped",name:game.i18n.localize("DND5E.Unequipped"),type:"system",hasDerivedSubcategories:!1},{id:"utility",name:game.i18n.localize("tokenActionHud.utility"),type:"system",hasDerivedSubcategories:!1},{id:"weapons",name:game.i18n.localize("ITEM.TypeWeaponPl"),type:"system",hasDerivedSubcategories:!1}]}}));class SystemManager extends g{doGetCategoryManager(){return new u}doGetActionHandler(e){const t=new ActionHandler(e);return h.isModuleActive("magicitems")&&t.addFurtherActionHandler(new MagicItemActionListExtender(t)),t}getAvailableRollHandlers(){let e="Core D&D5e";h.isModuleActive("midi-qol")&&(e+=` [supports ${h.getModuleTitle("midi-qol")}]`);const t={core:e};return g.addHandler(t,"obsidian"),t}doGetRollHandler(e){let t;if("obsidian"===e)t=new RollHandlerObsidian;else t=new RollHandler;return t}doRegisterSettings(e){register(e)}async doRegisterDefaultFlags(){const e=b;return game.modules.get("magicitems")?.active&&(e.subcategories.push({id:"magic-items",name:h.i18n("tokenActionHud.dnd5e.magicItems"),type:"system",hasDerivedSubcategories:!0}),e.subcategories.sort(((e,t)=>e.id.localeCompare(t.id)))),e}}Hooks.once("ready",(async()=>{const t=game.modules.get(e.ID);t.api={requiredCoreModuleVersion:"1.1",SystemManager:SystemManager},Hooks.call("tokenActionHudSystemReady",t)}));export{i as ACTIVATION_TYPE_ICON,ActionHandler,n as CONCENTRATION_ICON,t as CORE_MODULE,d as CoreActionHandler,r as CoreActionListExtender,u as CoreCategoryManager,p as CorePreRollHandler,m as CoreRollHandler,g as CoreSystemManager,h as CoreUtils,b as DEFAULTS,y as Logger,e as MODULE,MagicItemActionListExtender,a as PREPARED_ICON,o as PROFICIENCY_LEVEL_ICON,s as REQUIRED_CORE_MODULE_VERSION,l as RITUAL_ICON,RollHandler,RollHandlerObsidian,SystemManager,Utils,register};
diff --git a/scripts/utils.js b/scripts/utils.js
index a53c971..70da86b 100644
--- a/scripts/utils.js
+++ b/scripts/utils.js
@@ -1,33 +1,34 @@
+import { MODULE } from './constants.js'
import { Logger } from './config.js'
-const namespace = 'token-action-hud-dnd5e'
-
-/**
- * Get setting value
- * @param {string} key The key
- * @param {string=null} defaultValue The default value
- * @returns The setting value
- */
-export function getSetting (key, defaultValue = null) {
- let value = defaultValue ?? null
- try {
- value = game.settings.get(namespace, key)
- } catch {
- Logger.debug(`Setting '${key}' not found`)
+export class Utils {
+ /**
+ * Get setting value
+ * @param {string} key The key
+ * @param {string=null} defaultValue The default value
+ * @returns The setting value
+ */
+ static getSetting (key, defaultValue = null) {
+ let value = defaultValue ?? null
+ try {
+ value = game.settings.get(MODULE.ID, key)
+ } catch {
+ Logger.debug(`Setting '${key}' not found`)
+ }
+ return value
}
- return value
-}
-/**
- * Set setting value
- * @param {string} key The key
- * @param {string} value The value
- */
-export async function setSetting (key, value) {
- if (game.settings.settings.get(`${namespace}.${key}`)) {
- value = await game.settings.set(namespace, key, value)
- Logger.debug(`Setting '${key}' set to '${value}'`)
- } else {
- Logger.debug(`Setting '${key}' not found`)
+ /**
+ * Set setting value
+ * @param {string} key The key
+ * @param {string} value The value
+ */
+ static async setSetting (key, value) {
+ try {
+ value = await game.settings.set(MODULE.ID, key, value)
+ Logger.debug(`Setting '${key}' set to '${value}'`)
+ } catch {
+ Logger.debug(`Setting '${key}' not found`)
+ }
}
}