Skip to content

Commit f9ca7b7

Browse files
update: v2.2.2
1 parent d990268 commit f9ca7b7

43 files changed

Lines changed: 1515 additions & 607 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ package/
1818
.kiro/
1919
.agents/
2020
AGENTS.md
21+
.cursor

package.json

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,74 @@
1-
{
2-
"private": true,
3-
"name": "anima-beyond-foundry",
4-
"version": "2.2.1",
5-
"description": "Unofficial Anima Beyond Fantasy system for Foundry VTT",
6-
"type": "module",
7-
"scripts": {
8-
"dev": "nodemon",
9-
"build:dev": "npm run build:prod && node scripts/copyDirectoryToFoundrySystem.cjs animabf",
10-
"build:prod": "npm run compendia:pack && npx vite build",
11-
"clean": "rimraf dist/",
12-
"release": "node scripts/release/release.cjs",
13-
"release:dry": "node scripts/release/release.cjs --dry",
14-
"test": "vitest",
15-
"test:run": "vitest run",
16-
"hook:pre-commit": "lint-staged",
17-
"cypress:open": "cd integration && cypress open",
18-
"compendia:pack": "node scripts/compendia/packCompendia.mjs",
19-
"compendia:unpack": "node scripts/compendia/unpackCompendia.mjs"
20-
},
21-
"engines": {
22-
"node": ">18.0.0"
23-
},
24-
"author": "",
25-
"license": "",
26-
"devDependencies": {
27-
"@digitak/tsc-esm": "^3.1.4",
28-
"@foundryvtt/foundryvtt-cli": "^1.0.3",
29-
"@league-of-foundry-developers/foundry-vtt-types": "github:League-of-Foundry-Developers/foundry-vtt-types#v12",
30-
"@types/faker": "^5.5.6",
31-
"@types/handlebars": "^4.1.0",
32-
"@types/jest": "^26.0.23",
33-
"@types/jquery": "^3.5.16",
34-
"@typescript-eslint/eslint-plugin": "^4.25.0",
35-
"@typescript-eslint/parser": "^4.25.0",
36-
"archiver": "^5.3.0",
37-
"chalk": "^4.1.0",
38-
"cypress": "^7.5.0",
39-
"eslint": "^7.27.0",
40-
"eslint-config-airbnb": "^18.2.1",
41-
"eslint-config-airbnb-typescript": "^12.3.1",
42-
"eslint-config-prettier": "^8.3.0",
43-
"eslint-plugin-cypress": "^2.11.3",
44-
"eslint-plugin-import": "^2.23.3",
45-
"eslint-plugin-prettier": "^3.4.0",
46-
"faker": "^5.5.3",
47-
"fs-extra": "^9.1.0",
48-
"husky": "^6.0.0",
49-
"jest": "^26.6.3",
50-
"lint-staged": "^11.0.0",
51-
"nodemon": "^2.0.21",
52-
"prettier": "^2.3.0",
53-
"readline-sync": "^1.4.10",
54-
"rimraf": "^3.0.2",
55-
"rollup-plugin-copy": "^3.5.0",
56-
"sass": "^1.32.8",
57-
"sass-lint": "^1.13.1",
58-
"typescript": "^5.6.2",
59-
"vite": "^5.0.0",
60-
"vitest": "^4.1.8",
61-
"yargs": "^16.2.0"
62-
},
63-
"dependencies": {
64-
"jquery": "^3.6.0",
65-
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
66-
},
67-
"lint-staged": {
68-
"src/**/*.ts": "eslint --fix --cache",
69-
"src/**/*.{ts,tsx}": [
70-
"bash -c \"tsc --noEmit --pretty\""
71-
]
72-
},
73-
"sasslintConfig": "./.sass-lint.yml"
74-
}
1+
{
2+
"private": true,
3+
"name": "anima-beyond-foundry",
4+
"version": "2.2.2",
5+
"description": "Unofficial Anima Beyond Fantasy system for Foundry VTT",
6+
"type": "module",
7+
"scripts": {
8+
"dev": "nodemon",
9+
"build:dev": "npm run build:prod && node scripts/copyDirectoryToFoundrySystem.cjs animabf",
10+
"build:prod": "npm run compendia:pack && npx vite build",
11+
"clean": "rimraf dist/",
12+
"release": "node scripts/release/release.cjs",
13+
"release:dry": "node scripts/release/release.cjs --dry",
14+
"test": "vitest",
15+
"test:run": "vitest run",
16+
"hook:pre-commit": "lint-staged",
17+
"cypress:open": "cd integration && cypress open",
18+
"compendia:pack": "node scripts/compendia/packCompendia.mjs",
19+
"compendia:unpack": "node scripts/compendia/unpackCompendia.mjs"
20+
},
21+
"engines": {
22+
"node": ">18.0.0"
23+
},
24+
"author": "",
25+
"license": "",
26+
"devDependencies": {
27+
"@digitak/tsc-esm": "^3.1.4",
28+
"@foundryvtt/foundryvtt-cli": "^1.0.3",
29+
"@league-of-foundry-developers/foundry-vtt-types": "github:League-of-Foundry-Developers/foundry-vtt-types#v12",
30+
"@types/faker": "^5.5.6",
31+
"@types/handlebars": "^4.1.0",
32+
"@types/jest": "^26.0.23",
33+
"@types/jquery": "^3.5.16",
34+
"@typescript-eslint/eslint-plugin": "^4.25.0",
35+
"@typescript-eslint/parser": "^4.25.0",
36+
"archiver": "^5.3.0",
37+
"chalk": "^4.1.0",
38+
"cypress": "^7.5.0",
39+
"eslint": "^7.27.0",
40+
"eslint-config-airbnb": "^18.2.1",
41+
"eslint-config-airbnb-typescript": "^12.3.1",
42+
"eslint-config-prettier": "^8.3.0",
43+
"eslint-plugin-cypress": "^2.11.3",
44+
"eslint-plugin-import": "^2.23.3",
45+
"eslint-plugin-prettier": "^3.4.0",
46+
"faker": "^5.5.3",
47+
"fs-extra": "^9.1.0",
48+
"husky": "^6.0.0",
49+
"jest": "^26.6.3",
50+
"lint-staged": "^11.0.0",
51+
"nodemon": "^2.0.21",
52+
"prettier": "^2.3.0",
53+
"readline-sync": "^1.4.10",
54+
"rimraf": "^3.0.2",
55+
"rollup-plugin-copy": "^3.5.0",
56+
"sass": "^1.32.8",
57+
"sass-lint": "^1.13.1",
58+
"typescript": "^5.6.2",
59+
"vite": "^5.0.0",
60+
"vitest": "^4.1.8",
61+
"yargs": "^16.2.0"
62+
},
63+
"dependencies": {
64+
"jquery": "^3.6.0",
65+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
66+
},
67+
"lint-staged": {
68+
"src/**/*.ts": "eslint --fix --cache",
69+
"src/**/*.{ts,tsx}": [
70+
"bash -c \"tsc --noEmit --pretty\""
71+
]
72+
},
73+
"sasslintConfig": "./.sass-lint.yml"
74+
}

src/animabf.mjs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { FormulaEvaluator } from './utils/formulaEvaluator.js';
3333
import { registerHandlebarsPartials } from './utils/handlebarsPartials.js';
3434

3535
import { macroCreators, macroExecutors } from './utils/macroCreatorRegistry.js';
36+
import { resolveHotbarMacroCreatorId } from './utils/resolveHotbarMacroCreatorId.js';
3637
import { ensureLinkedEffectForItem } from './module/actor/utils/ensureLinkedEffectForItem.js';
3738
import { inferAttributeFromFlavor } from './module/actor/utils/attributeDerivationMap.js';
3839
import { getActiveEffectsBreakdownForAttribute } from './module/actor/utils/activeEffectsBreakdown.js';
@@ -129,15 +130,16 @@ Hooks.once('ready', async () => {
129130

130131
game.animabf.macros ??= {};
131132

132-
game.animabf.macros.execute = async ({ id, actorUuid, itemUuid }) => {
133+
game.animabf.macros.execute = async payload => {
134+
const { id, actorUuid, itemUuid, ...extra } = payload;
133135
const exec = macroExecutors[id];
134136
if (typeof exec !== 'function') return;
135137

136138
const actor = await fromUuid(actorUuid);
137139
const item = await fromUuid(itemUuid);
138140
if (!actor || !item) return;
139141

140-
return exec({ actor, item });
142+
return exec({ actor, item, ...extra });
141143
};
142144

143145
// GM-side socket to update attack targets flag
@@ -477,24 +479,26 @@ Hooks.on('renderTokenHUD', async (hud, html) => {
477479
};
478480
});
479481

480-
Hooks.on('hotbarDrop', async (_bar, data, slot) => {
482+
Hooks.on('hotbarDrop', (_bar, data, slot) => {
481483
if (data?.type !== 'Item' || !data.uuid) return;
482484

483-
const item = await fromUuid(data.uuid);
484-
if (!item) return;
485-
486-
const actor = item.parent;
487-
if (!actor) return; // No actor -> no macro
485+
let item;
486+
try {
487+
item = fromUuidSync(data.uuid);
488+
} catch {
489+
return;
490+
}
488491

489-
const creatorId = item.system?.hotbarMacroCreatorId;
490-
if (!creatorId) return; // No reference -> do nothing (let Foundry default)
492+
const actor = item?.parent;
493+
if (!actor) return;
491494

492-
const creator = macroCreators[creatorId];
493-
if (typeof creator !== 'function') return; // Unknown id -> do nothing
495+
const creatorId = resolveHotbarMacroCreatorId(item);
496+
const creator = creatorId ? macroCreators[creatorId] : null;
497+
if (typeof creator !== 'function') return;
494498

495-
// Let the creator build+assign the macro. If it returns true => we handled it.
496-
const handled = await creator({ actor, item, slot });
497-
if (handled) return false; // Prevent default behavior
499+
// Return false synchronously so Foundry does not create its default "Display item" macro.
500+
void creator({ actor, item, slot });
501+
return false;
498502
});
499503

500504
// // Auto-number unlinked tokens as "{name} (n)" when dropped

src/lang/en.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
"anima.ui.combat.baseValues.wearArmor.title": "Wear armor",
8686
"anima.ui.combat.combatSpecialSkill.title": "Special Skills",
8787
"anima.ui.combat.combatTables.title": "Combat tables",
88+
"anima.ui.combat.defense.title": "Defense",
8889
"anima.ui.combat.finalArmor.title": "Final armor",
8990
"anima.ui.combat.weapon.manageabilityType.oneHand.title": "1 hand",
9091
"anima.ui.combat.weapon.manageabilityType.oneOrTwoHand.title": "1 or 2 hands",
@@ -149,6 +150,7 @@
149150
"anima.ui.combat.supernaturalShields.name.title": "Shield",
150151
"anima.ui.combat.supernaturalShields.title": "Supernatural shields",
151152
"anima.ui.combat.supernaturalShields.bonus.title": "Modifier",
153+
"anima.ui.combat.supernaturalShields.addedNotification": "Supernatural shield added: {name}",
152154
"anima.ui.combat.attack.modifier.title": "Modifier",
153155
"anima.ui.psychic.psychicPowers.castButton.title": "Cast Power",
154156
"anima.ui.contactSection.contactRow.description": "Description",
@@ -709,7 +711,7 @@
709711
"macros.combat.dialog.combatMod.poorVisibility.title": "Poor visibility",
710712
"macros.combat.dialog.combatMod.targetInCover.title": "Target in cover",
711713
"macros.combat.dialog.combatMod.secondaryCritic.title": "Secondary critic used",
712-
"macros.combat.dialog.combatMod.multipleDefensesPenalty.title": "Defense penalty",
714+
"macros.combat.dialog.combatMod.multipleDefensesPenalty.title": "Multiple defense penalty",
713715
"macros.combat.dialog.combatMod.fatigueUsed.title": "Used fatigue",
714716
"macros.combat.dialog.counterAttackBonus.title": "Counterattack bonus",
715717
"macros.combat.dialog.counterAttackButton.title": "Counterattack",
@@ -735,6 +737,12 @@
735737
"macros.combat.dialog.defense.title": "Defense",
736738
"macros.combat.dialog.defenseButton.title": "Send defense",
737739
"macros.combat.dialog.defenseCount.title": "Defense penalty",
740+
"macros.combat.dialog.defenseCount.current.title": "Current defense",
741+
"macros.combat.dialog.defenseCount.current.segment.1": "1st",
742+
"macros.combat.dialog.defenseCount.current.segment.2": "2nd",
743+
"macros.combat.dialog.defenseCount.current.segment.3": "3rd",
744+
"macros.combat.dialog.defenseCount.current.segment.4": "4th",
745+
"macros.combat.dialog.defenseCount.current.segment.5plus": "5th+",
738746
"macros.combat.dialog.defenseCount.exemption.supernaturalShield": "Supernatural shields do not apply the multiple-defenses penalty",
739747
"macros.combat.dialog.defenseSent.title": "Defense sent. Waiting for combat results...",
740748
"macros.combat.dialog.defenseType.block.title": "Block",

src/lang/es.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
"anima.ui.combat.baseValues.wearArmor.title": "Llevar armadura",
8686
"anima.ui.combat.combatSpecialSkill.title": "Habilidades especiales",
8787
"anima.ui.combat.combatTables.title": "Tablas de combate",
88+
"anima.ui.combat.defense.title": "Defensa",
8889
"anima.ui.combat.finalArmor.title": "Armadura final",
8990
"anima.ui.combat.weapon.manageabilityType.oneHand.title": "1 mano",
9091
"anima.ui.combat.weapon.manageabilityType.oneOrTwoHand.title": "1 ó 2 manos",
@@ -149,6 +150,7 @@
149150
"anima.ui.combat.supernaturalShields.name.title": "Escudo",
150151
"anima.ui.combat.supernaturalShields.title": "Escudos Sobrenaturales",
151152
"anima.ui.combat.supernaturalShields.bonus.title": "Modificador",
153+
"anima.ui.combat.supernaturalShields.addedNotification": "Escudo sobrenatural añadido: {name}",
152154
"anima.ui.combat.attack.modifier.title": "Modificador",
153155
"anima.ui.psychic.psychicPowers.castButton.title": "Lanzar Poder",
154156
"anima.ui.contactSection.contactRow.description": "Descripción",
@@ -709,7 +711,7 @@
709711
"macros.combat.dialog.combatMod.poorVisibility.title": "Escasa visibilidad",
710712
"macros.combat.dialog.combatMod.targetInCover.title": "Blanco en cobertura",
711713
"macros.combat.dialog.combatMod.secondaryCritic.title": "Usar crítico secundario",
712-
"macros.combat.dialog.combatMod.multipleDefensesPenalty.title": "Penalizador por defensa continua",
714+
"macros.combat.dialog.combatMod.multipleDefensesPenalty.title": "Penalizador por defensas adicionales",
713715
"macros.combat.dialog.combatMod.fatigueUsed.title": "Fatiga usada",
714716
"macros.combat.dialog.counterAttackBonus.title": "Bono al contraataque",
715717
"macros.combat.dialog.counterAttackButton.title": "Contraatacar",
@@ -735,6 +737,12 @@
735737
"macros.combat.dialog.defense.title": "Defensa",
736738
"macros.combat.dialog.defenseButton.title": "Enviar defensa",
737739
"macros.combat.dialog.defenseCount.title": "Penalizador por defensa continua",
740+
"macros.combat.dialog.defenseCount.current.title": "Defensa actual",
741+
"macros.combat.dialog.defenseCount.current.segment.1": "",
742+
"macros.combat.dialog.defenseCount.current.segment.2": "",
743+
"macros.combat.dialog.defenseCount.current.segment.3": "",
744+
"macros.combat.dialog.defenseCount.current.segment.4": "",
745+
"macros.combat.dialog.defenseCount.current.segment.5plus": "5ª+",
738746
"macros.combat.dialog.defenseCount.exemption.supernaturalShield": "Los escudos sobrenaturales no aplican penalizador por defensa continua",
739747
"macros.combat.dialog.defenseSent.title": "Defensa enviada. Esperando a los resultados del combate...",
740748
"macros.combat.dialog.defenseType.block.title": "Bloqueo",

src/lang/fr.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"anima.ui.combat.baseValues.wearArmor.title": "Port d'Armure",
8888
"anima.ui.combat.combatSpecialSkill.title": "Compétences Spéciales",
8989
"anima.ui.combat.combatTables.title": "Tables des Combats",
90+
"anima.ui.combat.defense.title": "Défense",
9091
"anima.ui.combat.finalArmor.title": "Armure Finale",
9192
"anima.ui.combat.weapon.manageabilityType.oneHand.title": "1 main",
9293
"anima.ui.combat.weapon.manageabilityType.oneOrTwoHand.title": "1 ou 2 mains",
@@ -119,6 +120,7 @@
119120
"anima.ui.combat.supernaturalShields.shieldPoints.title": "Life points",
120121
"anima.ui.combat.supernaturalShields.ability.title": "Ability",
121122
"anima.ui.combat.supernaturalShields.bonus.title": "Modifier",
123+
"anima.ui.combat.supernaturalShields.addedNotification": "Bouclier surnaturel ajouté : {name}",
122124
"anima.ui.combat.attack.modifier.title": "Modifier",
123125
"anima.ui.psychic.psychicPowers.castButton.title": "Lancer le pouvoir",
124126
"anima.ui.combat.weapons.equipped.title": "Equipé?",
@@ -664,6 +666,12 @@
664666
"macros.combat.dialog.defense.title": "Défense",
665667
"macros.combat.dialog.defenseButton.title": "Envoyer la défense",
666668
"macros.combat.dialog.defenseCount.title": "Malus de Défense",
669+
"macros.combat.dialog.defenseCount.current.title": "Défense actuelle",
670+
"macros.combat.dialog.defenseCount.current.segment.1": "1ère",
671+
"macros.combat.dialog.defenseCount.current.segment.2": "2ème",
672+
"macros.combat.dialog.defenseCount.current.segment.3": "3ème",
673+
"macros.combat.dialog.defenseCount.current.segment.4": "4ème",
674+
"macros.combat.dialog.defenseCount.current.segment.5plus": "5ème+",
667675
"macros.combat.dialog.defenseCount.exemption.supernaturalShield": "Les boucliers surnaturels n'appliquent pas le malus de défense multiple",
668676
"macros.combat.dialog.defenseSent.title": "Défense envoyée. Attente des résultats du combat...",
669677
"macros.combat.dialog.defenseType.block.title": "Parade",

0 commit comments

Comments
 (0)