diff --git a/lang/en.json b/lang/en.json
index 4fc898a..1f00952 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -723,6 +723,9 @@
},
"catalyst": {
"label": "Catalyst"
+ },
+ "damageDice": {
+ "label": "Damage dice"
}
}
},
diff --git a/lethal-fantasy.mjs b/lethal-fantasy.mjs
index 84a3cd8..39afb39 100644
--- a/lethal-fantasy.mjs
+++ b/lethal-fantasy.mjs
@@ -346,6 +346,36 @@ Hooks.on(hookName, (message, html, data) => {
return
}
+ // Pour les sorts, rouler les dés de dégâts avec option bypass DR
+ if (damageType === "spell" && damageFormula) {
+ const bypassArmor = await foundry.applications.api.DialogV2.confirm({
+ window: { title: "Spell Damage" },
+ classes: ["lethalfantasy"],
+ content: "
Does this spell's damage bypass armor DR?
",
+ yes: { label: "Yes (ignore armor)", icon: "fa-solid fa-wand-magic-sparkles" },
+ no: { label: "No (apply armor DR)", icon: "fa-solid fa-shield" }
+ })
+ const rollOpts = {
+ type: "spell-damage",
+ rollType: "spell-damage",
+ rollName: damageFormula,
+ isDamage: true,
+ rollData: { isDamage: true },
+ bypassArmor: bypassArmor ?? false,
+ defenderId,
+ defenderTokenId,
+ actorId: actor.id,
+ actorName: actor.name,
+ actorImage: actor.img
+ }
+ const roll = new LethalFantasyRoll(damageFormula, {}, rollOpts)
+ await roll.evaluate()
+ roll.options.rollTotal = roll.total
+ if (game?.dice3d) await game.dice3d.showForRoll(roll, game.user, true)
+ await roll.toMessage()
+ return
+ }
+
// Pour les boutons de résultat de combat (monster damage)
if (damageType === "monster" && attackKey) {
await actor.system.prepareMonsterRoll("monster-damage", attackKey, undefined, undefined, undefined, defenderId, defenderTokenId, extraShieldDr)
@@ -394,7 +424,7 @@ Hooks.on("preCreateChatMessage", (message) => {
const rollType = message.rolls[0]?.options?.rollType
// Si c'est un message de défense et qu'on a des données en attente
- if ((rollType === "weapon-defense" || rollType === "monster-defense") && game.lethalFantasy?.nextDefenseData) {
+ if ((rollType === "weapon-defense" || rollType === "monster-defense" || rollType === "save") && game.lethalFantasy?.nextDefenseData) {
// Ajouter les données dans les flags du message
message.updateSource({
[`flags.${SYSTEM.id}.attackData`]: game.lethalFantasy.nextDefenseData
@@ -414,7 +444,7 @@ Hooks.on("createChatMessage", async (message) => {
console.log("Defense hook checking message, rollType:", rollType)
// Vérifier si c'est un message de défense
- if (rollType !== "weapon-defense" && rollType !== "monster-defense") return
+ if (rollType !== "weapon-defense" && rollType !== "monster-defense" && rollType !== "save") return
// Récupérer les données d'attaque depuis les flags
const attackData = message.flags?.[SYSTEM.id]?.attackData
@@ -483,7 +513,9 @@ Hooks.on("createChatMessage", async (message) => {
// Seulement si l'utilisateur actuel est le propriétaire du défenseur
let defenderHandledBonus = false
let shieldReaction = null
- if (defender && defenseRoll < attackRoll && isPrimaryController(defender)) {
+ let shieldBlocked = false
+ const isSpellOrMiracle = attackRollType === "spell-attack" || attackRollType === "miracle-attack"
+ if (defender && defenseRoll < attackRoll && isPrimaryController(defender) && !isSpellOrMiracle) {
const shieldData = LethalFantasyUtils.getShieldReactionData(defender)
let canRerollDefense = LethalFantasyUtils.hasD30Reroll(defenseD30message)
let canShieldReact = !!shieldData
@@ -598,17 +630,30 @@ Hooks.on("createChatMessage", async (message) => {
if (choice === "shieldReact" && canShieldReact) {
const shieldBonus = await LethalFantasyUtils.rollBonusDie(shieldData.formula, defender)
- defenseRoll += shieldBonus
- shieldReaction = {
- damageReduction: shieldData.damageReduction,
- label: shieldData.label,
- bonus: shieldBonus
- }
+ const newDefenseTotal = defenseRoll + shieldBonus
+ defenseRoll = newDefenseTotal
canShieldReact = false
- await createReactionMessage(
- defender,
- `${defenderName} rolls ${shieldData.label} and adds ${shieldBonus} to defense.${defenseRoll < attackRoll ? ` The hit still lands, but shield DR ${shieldData.damageReduction} will reduce the damage.` : ""}
`
- )
+
+ if (newDefenseTotal >= attackRoll) {
+ // Shield roll tied or exceeded the attack — shield blocked
+ shieldBlocked = true
+ shieldReaction = {
+ damageReduction: shieldData.damageReduction,
+ label: shieldData.label,
+ bonus: shieldBonus
+ }
+ await createReactionMessage(
+ defender,
+ `${defenderName} rolls ${shieldData.label} and adds ${shieldBonus} to defense (${newDefenseTotal} ≥ ${attackRoll}). Shield blocked the attack! Both armor DR and shield DR ${shieldData.damageReduction} will apply to damage.
`
+ )
+ } else {
+ // Shield roll not enough — hit still lands, armor DR only
+ shieldReaction = null
+ await createReactionMessage(
+ defender,
+ `${defenderName} rolls ${shieldData.label} and adds ${shieldBonus} to defense (${newDefenseTotal} < ${attackRoll}). Shield did not block — normal hit, armor DR only.
`
+ )
+ }
}
}
}
@@ -704,8 +749,8 @@ Hooks.on("createChatMessage", async (message) => {
}
}
- const shieldDamageReduction = shieldReaction && attackRollFinal > defenseRoll ? shieldReaction.damageReduction : 0
- const outcome = shieldDamageReduction > 0 ? "shielded-hit" : (attackRollFinal > defenseRoll ? "hit" : "miss")
+ const shieldDamageReduction = shieldBlocked ? shieldReaction.damageReduction : 0
+ const outcome = shieldBlocked ? "shielded-hit" : (attackRollFinal > defenseRoll ? "hit" : "miss")
// Créer le message de comparaison - uniquement par le client qui a géré le dernier bonus
// Priorité: attaquant si il a géré le bonus, sinon défenseur si il a géré le bonus, sinon défenseur
@@ -788,7 +833,8 @@ Hooks.on("createChatMessage", async (message) => {
const attackerName = message.rolls[0]?.options?.actorName || "Unknown Attacker"
// Calculer les DR
- const armorDR = defender.computeDamageReduction() || 0
+ const bypassArmor = message.rolls[0]?.options?.bypassArmor || false
+ const armorDR = bypassArmor ? 0 : (defender.computeDamageReduction() || 0)
const extraShieldDr = Number(message.rolls[0]?.options?.extraShieldDr) || 0
const totalDR = armorDR + extraShieldDr
const finalDamage = Math.max(0, damageTotal - totalDR)
@@ -823,7 +869,7 @@ Hooks.on("createChatMessage", async (message) => {
{
targetName: defender.name,
damage: finalDamage,
- drText: totalDR > 0 ? `Armor DR: ${armorDR}${extraShieldDr > 0 ? ` + Shield DR: ${extraShieldDr}` : ""}` : "",
+ drText: bypassArmor ? "Armor DR bypassed (spell)" : (totalDR > 0 ? `Armor DR: ${armorDR}${extraShieldDr > 0 ? ` + Shield DR: ${extraShieldDr}` : ""}` : ""),
weaponName: weaponName,
attackerName: attackerName,
rawDamage: damageTotal
diff --git a/module/models/spell.mjs b/module/models/spell.mjs
index 612d42f..fb6be81 100644
--- a/module/models/spell.mjs
+++ b/module/models/spell.mjs
@@ -39,6 +39,7 @@ export default class LethalFantasySpell extends foundry.abstract.TypeDataModel {
schema.attackRoll = new fields.StringField({ required: true, initial: "" })
schema.powerRoll = new fields.StringField({ required: true, initial: "" })
+ schema.damageDice = new fields.StringField({ required: false, initial: "" })
return schema
}
diff --git a/module/utils.mjs b/module/utils.mjs
index 6c4a381..cd28d3b 100644
--- a/module/utils.mjs
+++ b/module/utils.mjs
@@ -235,6 +235,70 @@ export default class LethalFantasyUtils {
const isMonster = defender.type === "monster"
+ // Spell/miracle attacks use saving throws instead of weapon defense
+ const isSpellAttack = attackRollType === "spell-attack" || attackRollType === "miracle-attack"
+ if (isSpellAttack) {
+ const savesConfig = isMonster ? SYSTEM.MONSTER_SAVES : SYSTEM.SAVES
+ const combatSaves = ["will", "dodge", "toughness"]
+ const savesHTML = Object.values(savesConfig)
+ .filter(s => combatSaves.includes(s.id))
+ .map(s => `${game.i18n.localize(s.label)} `)
+ .join("")
+
+ const content = `
+
+
+
${attackerName} targets ${defenderName} with ${weaponName} !
+
Attack roll: ${attackRoll}
+
+
+ Choose saving throw:
+
+ ${savesHTML}
+
+
+
+ `
+
+ const result = await foundry.applications.api.DialogV2.wait({
+ window: { title: "Saving Throw vs Spell" },
+ classes: ["lethalfantasy"],
+ content,
+ buttons: [
+ {
+ label: "Roll Save",
+ icon: "fa-solid fa-person-running",
+ callback: (event, button) => button.form.elements.saveKey.value,
+ },
+ ],
+ rejectClose: false
+ })
+
+ if (result) {
+ game.lethalFantasy = game.lethalFantasy || {}
+ game.lethalFantasy.nextDefenseData = {
+ attackerId,
+ attackRoll,
+ attackerName,
+ defenderName,
+ attackWeaponId,
+ attackRollType,
+ attackRollKey,
+ attackD30result,
+ attackD30message,
+ attackRerollContext,
+ defenderId: defender.id,
+ defenderTokenId
+ }
+ if (isMonster) {
+ defender.system.prepareMonsterRoll("save", result)
+ } else {
+ defender.prepareRoll("save", result)
+ }
+ }
+ return
+ }
+
// Pour les monstres, récupérer les attaques activées
if (isMonster) {
const enabledAttacks = Object.entries(defender.system.attacks).filter(([key, attack]) => attack.enabled)
@@ -440,11 +504,16 @@ export default class LethalFantasyUtils {
content,
buttons: [
{
+ action: "roll",
label: "Roll Bonus Die",
icon: "fa-solid fa-dice",
- callback: (event, button, dialog) => button.form.elements.bonusDie.value
+ callback: (event, button) => {
+ const sel = button.form?.elements?.bonusDie ?? button.closest("form")?.elements?.bonusDie
+ return sel?.value ?? choices[0]
+ }
},
{
+ action: "cancel",
label: "Cancel",
icon: "fa-solid fa-xmark",
callback: () => null
@@ -684,6 +753,24 @@ export default class LethalFantasyUtils {
`
+ } else if (data.attackRollType === "spell-attack" || data.attackRollType === "miracle-attack") {
+ const attacker = game.actors.get(data.attackerId)
+ const spell = attacker?.items.get(data.attackWeaponId)
+ const damageDice = spell?.system?.damageDice
+ if (damageDice) {
+ damageButton = `
+
+
+ Spell Damage (${damageDice})
+
+
+ `
+ }
}
}
@@ -709,7 +796,7 @@ export default class LethalFantasyUtils {
${outcome === "shielded-hit"
- ? ` ${data.attackerName} still hits ${data.defenderName} , but shield DR ${data.shieldDamageReduction || 0} reduces the damage.`
+ ? ` ${data.attackerName} hits ${data.defenderName} , but the shield blocked — apply armor DR + shield DR ${data.shieldDamageReduction || 0} .`
: isAttackWin
? ` ${data.attackerName} hits ${data.defenderName} !`
: ` ${data.defenderName} parries the attack!`
diff --git a/packs-system/lf-equipment/000557.log b/packs-system/lf-equipment/000560.log
similarity index 100%
rename from packs-system/lf-equipment/000557.log
rename to packs-system/lf-equipment/000560.log
diff --git a/packs-system/lf-equipment/CURRENT b/packs-system/lf-equipment/CURRENT
index 9fee1a6..2093527 100644
--- a/packs-system/lf-equipment/CURRENT
+++ b/packs-system/lf-equipment/CURRENT
@@ -1 +1 @@
-MANIFEST-000555
+MANIFEST-000559
diff --git a/packs-system/lf-equipment/LOG b/packs-system/lf-equipment/LOG
index 71db33e..12ca81c 100644
--- a/packs-system/lf-equipment/LOG
+++ b/packs-system/lf-equipment/LOG
@@ -1,8 +1,3 @@
-2026/04/12-10:10:03.851531 7f20ed3fd6c0 Recovering log #553
-2026/04/12-10:10:03.861282 7f20ed3fd6c0 Delete type=3 #551
-2026/04/12-10:10:03.861341 7f20ed3fd6c0 Delete type=0 #553
-2026/04/12-11:08:03.389691 7f1e4ffff6c0 Level-0 table #558: started
-2026/04/12-11:08:03.389742 7f1e4ffff6c0 Level-0 table #558: 0 bytes OK
-2026/04/12-11:08:03.395757 7f1e4ffff6c0 Delete type=0 #556
-2026/04/12-11:08:03.415391 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
-2026/04/12-11:08:03.415438 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
+2026/04/14-20:54:14.172569 7fc1dafbf6c0 Recovering log #557
+2026/04/14-20:54:14.184089 7fc1dafbf6c0 Delete type=3 #555
+2026/04/14-20:54:14.184186 7fc1dafbf6c0 Delete type=0 #557
diff --git a/packs-system/lf-equipment/LOG.old b/packs-system/lf-equipment/LOG.old
index 41dda52..71db33e 100644
--- a/packs-system/lf-equipment/LOG.old
+++ b/packs-system/lf-equipment/LOG.old
@@ -1,8 +1,8 @@
-2026/04/12-00:56:41.816652 7f20ecbfc6c0 Recovering log #549
-2026/04/12-00:56:41.832396 7f20ecbfc6c0 Delete type=3 #547
-2026/04/12-00:56:41.832446 7f20ecbfc6c0 Delete type=0 #549
-2026/04/12-01:07:05.182307 7f1e4ffff6c0 Level-0 table #554: started
-2026/04/12-01:07:05.182364 7f1e4ffff6c0 Level-0 table #554: 0 bytes OK
-2026/04/12-01:07:05.188459 7f1e4ffff6c0 Delete type=0 #552
-2026/04/12-01:07:05.207103 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
-2026/04/12-01:07:05.207149 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
+2026/04/12-10:10:03.851531 7f20ed3fd6c0 Recovering log #553
+2026/04/12-10:10:03.861282 7f20ed3fd6c0 Delete type=3 #551
+2026/04/12-10:10:03.861341 7f20ed3fd6c0 Delete type=0 #553
+2026/04/12-11:08:03.389691 7f1e4ffff6c0 Level-0 table #558: started
+2026/04/12-11:08:03.389742 7f1e4ffff6c0 Level-0 table #558: 0 bytes OK
+2026/04/12-11:08:03.395757 7f1e4ffff6c0 Delete type=0 #556
+2026/04/12-11:08:03.415391 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
+2026/04/12-11:08:03.415438 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!ATr9wZhg5uTVTksM' @ 72057594037927935 : 1 .. '!items!zw9RQocTdz3HRjZK' @ 0 : 0; will stop at (end)
diff --git a/packs-system/lf-equipment/MANIFEST-000555 b/packs-system/lf-equipment/MANIFEST-000559
similarity index 71%
rename from packs-system/lf-equipment/MANIFEST-000555
rename to packs-system/lf-equipment/MANIFEST-000559
index 508d305..49ee343 100644
Binary files a/packs-system/lf-equipment/MANIFEST-000555 and b/packs-system/lf-equipment/MANIFEST-000559 differ
diff --git a/packs-system/lf-gifts/000554.log b/packs-system/lf-gifts/000557.log
similarity index 100%
rename from packs-system/lf-gifts/000554.log
rename to packs-system/lf-gifts/000557.log
diff --git a/packs-system/lf-gifts/CURRENT b/packs-system/lf-gifts/CURRENT
index f572191..12af886 100644
--- a/packs-system/lf-gifts/CURRENT
+++ b/packs-system/lf-gifts/CURRENT
@@ -1 +1 @@
-MANIFEST-000552
+MANIFEST-000556
diff --git a/packs-system/lf-gifts/LOG b/packs-system/lf-gifts/LOG
index 2b8d2ba..bdf55ff 100644
--- a/packs-system/lf-gifts/LOG
+++ b/packs-system/lf-gifts/LOG
@@ -1,8 +1,3 @@
-2026/04/12-10:10:03.864565 7f20ecbfc6c0 Recovering log #550
-2026/04/12-10:10:03.875268 7f20ecbfc6c0 Delete type=3 #548
-2026/04/12-10:10:03.875332 7f20ecbfc6c0 Delete type=0 #550
-2026/04/12-11:08:03.395874 7f1e4ffff6c0 Level-0 table #555: started
-2026/04/12-11:08:03.395896 7f1e4ffff6c0 Level-0 table #555: 0 bytes OK
-2026/04/12-11:08:03.401955 7f1e4ffff6c0 Delete type=0 #553
-2026/04/12-11:08:03.415404 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end)
-2026/04/12-11:08:03.415431 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end)
+2026/04/14-20:54:14.189613 7fc1d9fbd6c0 Recovering log #554
+2026/04/14-20:54:14.199454 7fc1d9fbd6c0 Delete type=3 #552
+2026/04/14-20:54:14.199515 7fc1d9fbd6c0 Delete type=0 #554
diff --git a/packs-system/lf-gifts/LOG.old b/packs-system/lf-gifts/LOG.old
index 53867d9..2b8d2ba 100644
--- a/packs-system/lf-gifts/LOG.old
+++ b/packs-system/lf-gifts/LOG.old
@@ -1,8 +1,8 @@
-2026/04/12-00:56:41.835571 7f20ee3ff6c0 Recovering log #546
-2026/04/12-00:56:41.850974 7f20ee3ff6c0 Delete type=3 #544
-2026/04/12-00:56:41.851033 7f20ee3ff6c0 Delete type=0 #546
-2026/04/12-01:07:05.194434 7f1e4ffff6c0 Level-0 table #551: started
-2026/04/12-01:07:05.194455 7f1e4ffff6c0 Level-0 table #551: 0 bytes OK
-2026/04/12-01:07:05.200694 7f1e4ffff6c0 Delete type=0 #549
-2026/04/12-01:07:05.207125 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end)
-2026/04/12-01:07:05.207165 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end)
+2026/04/12-10:10:03.864565 7f20ecbfc6c0 Recovering log #550
+2026/04/12-10:10:03.875268 7f20ecbfc6c0 Delete type=3 #548
+2026/04/12-10:10:03.875332 7f20ecbfc6c0 Delete type=0 #550
+2026/04/12-11:08:03.395874 7f1e4ffff6c0 Level-0 table #555: started
+2026/04/12-11:08:03.395896 7f1e4ffff6c0 Level-0 table #555: 0 bytes OK
+2026/04/12-11:08:03.401955 7f1e4ffff6c0 Delete type=0 #553
+2026/04/12-11:08:03.415404 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end)
+2026/04/12-11:08:03.415431 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!yPWGvxHJbDNHVSnY' @ 72057594037927935 : 1 .. '!items!x5gLtqlW4sdDmHTd' @ 0 : 0; will stop at (end)
diff --git a/packs-system/lf-gifts/MANIFEST-000552 b/packs-system/lf-gifts/MANIFEST-000556
similarity index 77%
rename from packs-system/lf-gifts/MANIFEST-000552
rename to packs-system/lf-gifts/MANIFEST-000556
index 93110c1..2d5326b 100644
Binary files a/packs-system/lf-gifts/MANIFEST-000552 and b/packs-system/lf-gifts/MANIFEST-000556 differ
diff --git a/packs-system/lf-skills/000559.log b/packs-system/lf-skills/000562.log
similarity index 100%
rename from packs-system/lf-skills/000559.log
rename to packs-system/lf-skills/000562.log
diff --git a/packs-system/lf-skills/CURRENT b/packs-system/lf-skills/CURRENT
index 7e963d6..22c53bf 100644
--- a/packs-system/lf-skills/CURRENT
+++ b/packs-system/lf-skills/CURRENT
@@ -1 +1 @@
-MANIFEST-000557
+MANIFEST-000561
diff --git a/packs-system/lf-skills/LOG b/packs-system/lf-skills/LOG
index 88c2a51..7e5c708 100644
--- a/packs-system/lf-skills/LOG
+++ b/packs-system/lf-skills/LOG
@@ -1,8 +1,3 @@
-2026/04/12-10:10:03.838632 7f20ee3ff6c0 Recovering log #555
-2026/04/12-10:10:03.848360 7f20ee3ff6c0 Delete type=3 #553
-2026/04/12-10:10:03.848406 7f20ee3ff6c0 Delete type=0 #555
-2026/04/12-11:08:03.402029 7f1e4ffff6c0 Level-0 table #560: started
-2026/04/12-11:08:03.402048 7f1e4ffff6c0 Level-0 table #560: 0 bytes OK
-2026/04/12-11:08:03.408790 7f1e4ffff6c0 Delete type=0 #558
-2026/04/12-11:08:03.415414 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
-2026/04/12-11:08:03.415454 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
+2026/04/14-20:54:14.156150 7fc1d97bc6c0 Recovering log #559
+2026/04/14-20:54:14.166976 7fc1d97bc6c0 Delete type=3 #557
+2026/04/14-20:54:14.167099 7fc1d97bc6c0 Delete type=0 #559
diff --git a/packs-system/lf-skills/LOG.old b/packs-system/lf-skills/LOG.old
index 598b9fd..88c2a51 100644
--- a/packs-system/lf-skills/LOG.old
+++ b/packs-system/lf-skills/LOG.old
@@ -1,8 +1,8 @@
-2026/04/12-00:56:41.797453 7f20ed3fd6c0 Recovering log #551
-2026/04/12-00:56:41.813315 7f20ed3fd6c0 Delete type=3 #549
-2026/04/12-00:56:41.813371 7f20ed3fd6c0 Delete type=0 #551
-2026/04/12-01:07:05.200810 7f1e4ffff6c0 Level-0 table #556: started
-2026/04/12-01:07:05.200837 7f1e4ffff6c0 Level-0 table #556: 0 bytes OK
-2026/04/12-01:07:05.207008 7f1e4ffff6c0 Delete type=0 #554
-2026/04/12-01:07:05.207134 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
-2026/04/12-01:07:05.207157 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
+2026/04/12-10:10:03.838632 7f20ee3ff6c0 Recovering log #555
+2026/04/12-10:10:03.848360 7f20ee3ff6c0 Delete type=3 #553
+2026/04/12-10:10:03.848406 7f20ee3ff6c0 Delete type=0 #555
+2026/04/12-11:08:03.402029 7f1e4ffff6c0 Level-0 table #560: started
+2026/04/12-11:08:03.402048 7f1e4ffff6c0 Level-0 table #560: 0 bytes OK
+2026/04/12-11:08:03.408790 7f1e4ffff6c0 Delete type=0 #558
+2026/04/12-11:08:03.415414 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
+2026/04/12-11:08:03.415454 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!7j8H7DbmBb9Uza2X' @ 72057594037927935 : 1 .. '!items!zt8s7564ep1La4XQ' @ 0 : 0; will stop at (end)
diff --git a/packs-system/lf-skills/MANIFEST-000557 b/packs-system/lf-skills/MANIFEST-000561
similarity index 71%
rename from packs-system/lf-skills/MANIFEST-000557
rename to packs-system/lf-skills/MANIFEST-000561
index b1c393a..240906a 100644
Binary files a/packs-system/lf-skills/MANIFEST-000557 and b/packs-system/lf-skills/MANIFEST-000561 differ
diff --git a/packs-system/lf-spells-miracles/000254.log b/packs-system/lf-spells-miracles/000257.log
similarity index 100%
rename from packs-system/lf-spells-miracles/000254.log
rename to packs-system/lf-spells-miracles/000257.log
diff --git a/packs-system/lf-spells-miracles/CURRENT b/packs-system/lf-spells-miracles/CURRENT
index b59f50e..0002b46 100644
--- a/packs-system/lf-spells-miracles/CURRENT
+++ b/packs-system/lf-spells-miracles/CURRENT
@@ -1 +1 @@
-MANIFEST-000252
+MANIFEST-000256
diff --git a/packs-system/lf-spells-miracles/LOG b/packs-system/lf-spells-miracles/LOG
index 0d5d52f..7352e07 100644
--- a/packs-system/lf-spells-miracles/LOG
+++ b/packs-system/lf-spells-miracles/LOG
@@ -1,8 +1,3 @@
-2026/04/12-10:10:03.889781 7f20ed3fd6c0 Recovering log #250
-2026/04/12-10:10:03.899549 7f20ed3fd6c0 Delete type=3 #248
-2026/04/12-10:10:03.899595 7f20ed3fd6c0 Delete type=0 #250
-2026/04/12-11:08:03.421462 7f1e4ffff6c0 Level-0 table #255: started
-2026/04/12-11:08:03.421486 7f1e4ffff6c0 Level-0 table #255: 0 bytes OK
-2026/04/12-11:08:03.427527 7f1e4ffff6c0 Delete type=0 #253
-2026/04/12-11:08:03.443589 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
-2026/04/12-11:08:03.443624 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
+2026/04/14-20:54:14.216969 7fc1d97bc6c0 Recovering log #254
+2026/04/14-20:54:14.226830 7fc1d97bc6c0 Delete type=3 #252
+2026/04/14-20:54:14.226876 7fc1d97bc6c0 Delete type=0 #254
diff --git a/packs-system/lf-spells-miracles/LOG.old b/packs-system/lf-spells-miracles/LOG.old
index 059ecd7..0d5d52f 100644
--- a/packs-system/lf-spells-miracles/LOG.old
+++ b/packs-system/lf-spells-miracles/LOG.old
@@ -1,8 +1,8 @@
-2026/04/12-00:56:41.870438 7f20ecbfc6c0 Recovering log #246
-2026/04/12-00:56:41.885745 7f20ecbfc6c0 Delete type=3 #244
-2026/04/12-00:56:41.885813 7f20ecbfc6c0 Delete type=0 #246
-2026/04/12-01:07:05.229253 7f1e4ffff6c0 Level-0 table #251: started
-2026/04/12-01:07:05.229286 7f1e4ffff6c0 Level-0 table #251: 0 bytes OK
-2026/04/12-01:07:05.235261 7f1e4ffff6c0 Delete type=0 #249
-2026/04/12-01:07:05.235386 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
-2026/04/12-01:07:05.245080 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
+2026/04/12-10:10:03.889781 7f20ed3fd6c0 Recovering log #250
+2026/04/12-10:10:03.899549 7f20ed3fd6c0 Delete type=3 #248
+2026/04/12-10:10:03.899595 7f20ed3fd6c0 Delete type=0 #250
+2026/04/12-11:08:03.421462 7f1e4ffff6c0 Level-0 table #255: started
+2026/04/12-11:08:03.421486 7f1e4ffff6c0 Level-0 table #255: 0 bytes OK
+2026/04/12-11:08:03.427527 7f1e4ffff6c0 Delete type=0 #253
+2026/04/12-11:08:03.443589 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
+2026/04/12-11:08:03.443624 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!37mu4dxsSuftlnmP' @ 72057594037927935 : 1 .. '!items!zKOpU34oLziGJW6y' @ 0 : 0; will stop at (end)
diff --git a/packs-system/lf-spells-miracles/MANIFEST-000252 b/packs-system/lf-spells-miracles/MANIFEST-000256
similarity index 72%
rename from packs-system/lf-spells-miracles/MANIFEST-000252
rename to packs-system/lf-spells-miracles/MANIFEST-000256
index dd852a9..d87809e 100644
Binary files a/packs-system/lf-spells-miracles/MANIFEST-000252 and b/packs-system/lf-spells-miracles/MANIFEST-000256 differ
diff --git a/packs-system/lf-vulnerabilities/000553.log b/packs-system/lf-vulnerabilities/000556.log
similarity index 100%
rename from packs-system/lf-vulnerabilities/000553.log
rename to packs-system/lf-vulnerabilities/000556.log
diff --git a/packs-system/lf-vulnerabilities/CURRENT b/packs-system/lf-vulnerabilities/CURRENT
index 536f6fc..9fee1a6 100644
--- a/packs-system/lf-vulnerabilities/CURRENT
+++ b/packs-system/lf-vulnerabilities/CURRENT
@@ -1 +1 @@
-MANIFEST-000551
+MANIFEST-000555
diff --git a/packs-system/lf-vulnerabilities/LOG b/packs-system/lf-vulnerabilities/LOG
index 23570af..4e90def 100644
--- a/packs-system/lf-vulnerabilities/LOG
+++ b/packs-system/lf-vulnerabilities/LOG
@@ -1,8 +1,3 @@
-2026/04/12-10:10:03.877445 7f20ee3ff6c0 Recovering log #549
-2026/04/12-10:10:03.887615 7f20ee3ff6c0 Delete type=3 #547
-2026/04/12-10:10:03.887678 7f20ee3ff6c0 Delete type=0 #549
-2026/04/12-11:08:03.408913 7f1e4ffff6c0 Level-0 table #554: started
-2026/04/12-11:08:03.408942 7f1e4ffff6c0 Level-0 table #554: 0 bytes OK
-2026/04/12-11:08:03.415303 7f1e4ffff6c0 Delete type=0 #552
-2026/04/12-11:08:03.415422 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
-2026/04/12-11:08:03.415446 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
+2026/04/14-20:54:14.202677 7fc1da7be6c0 Recovering log #553
+2026/04/14-20:54:14.213358 7fc1da7be6c0 Delete type=3 #551
+2026/04/14-20:54:14.213482 7fc1da7be6c0 Delete type=0 #553
diff --git a/packs-system/lf-vulnerabilities/LOG.old b/packs-system/lf-vulnerabilities/LOG.old
index ace657c..23570af 100644
--- a/packs-system/lf-vulnerabilities/LOG.old
+++ b/packs-system/lf-vulnerabilities/LOG.old
@@ -1,8 +1,8 @@
-2026/04/12-00:56:41.853085 7f20ed3fd6c0 Recovering log #545
-2026/04/12-00:56:41.867862 7f20ed3fd6c0 Delete type=3 #543
-2026/04/12-00:56:41.867925 7f20ed3fd6c0 Delete type=0 #545
-2026/04/12-01:07:05.188580 7f1e4ffff6c0 Level-0 table #550: started
-2026/04/12-01:07:05.188606 7f1e4ffff6c0 Level-0 table #550: 0 bytes OK
-2026/04/12-01:07:05.194367 7f1e4ffff6c0 Delete type=0 #548
-2026/04/12-01:07:05.207115 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
-2026/04/12-01:07:05.207142 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
+2026/04/12-10:10:03.877445 7f20ee3ff6c0 Recovering log #549
+2026/04/12-10:10:03.887615 7f20ee3ff6c0 Delete type=3 #547
+2026/04/12-10:10:03.887678 7f20ee3ff6c0 Delete type=0 #549
+2026/04/12-11:08:03.408913 7f1e4ffff6c0 Level-0 table #554: started
+2026/04/12-11:08:03.408942 7f1e4ffff6c0 Level-0 table #554: 0 bytes OK
+2026/04/12-11:08:03.415303 7f1e4ffff6c0 Delete type=0 #552
+2026/04/12-11:08:03.415422 7f1e4ffff6c0 Manual compaction at level-0 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
+2026/04/12-11:08:03.415446 7f1e4ffff6c0 Manual compaction at level-1 from '!folders!mnO9OzE7BEE2KDfh' @ 72057594037927935 : 1 .. '!items!zkK6ixtCsCw3RH9X' @ 0 : 0; will stop at (end)
diff --git a/packs-system/lf-vulnerabilities/MANIFEST-000551 b/packs-system/lf-vulnerabilities/MANIFEST-000555
similarity index 72%
rename from packs-system/lf-vulnerabilities/MANIFEST-000551
rename to packs-system/lf-vulnerabilities/MANIFEST-000555
index 08e31cb..972e26a 100644
Binary files a/packs-system/lf-vulnerabilities/MANIFEST-000551 and b/packs-system/lf-vulnerabilities/MANIFEST-000555 differ
diff --git a/templates/spell.hbs b/templates/spell.hbs
index f3e64ab..7ebba5f 100644
--- a/templates/spell.hbs
+++ b/templates/spell.hbs
@@ -30,6 +30,7 @@
{{formField systemFields.savingThrow value=system.savingThrow}}
{{formField systemFields.extraAetherPoints value=system.extraAetherPoints}}
{{formField systemFields.criticalType value=system.criticalType}}
+ {{formField systemFields.damageDice value=system.damageDice}}