This commit is contained in:
@@ -108,6 +108,10 @@
|
||||
}
|
||||
],
|
||||
"description": "Possible Flawless or Legendary Defense or Add D20E to Defense"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "save_auto_success",
|
||||
"description": "Saving Throw Succeeds Regardless of Opposing Roll"
|
||||
}
|
||||
},
|
||||
"29": {
|
||||
@@ -145,6 +149,11 @@
|
||||
"type": "gain_grit",
|
||||
"amount": 1,
|
||||
"description": "Gain 1 Grit"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "gain_grit",
|
||||
"amount": 1,
|
||||
"description": "Gain 1 Grit"
|
||||
}
|
||||
},
|
||||
"28": {
|
||||
@@ -199,6 +208,12 @@
|
||||
"amount": 1,
|
||||
"target": "skill",
|
||||
"description": "Add 1 to Skill Roll"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "bonus_flat",
|
||||
"amount": 1,
|
||||
"target": "save",
|
||||
"description": "Add 1 to Saving Throw"
|
||||
}
|
||||
},
|
||||
"21": {
|
||||
@@ -239,6 +254,12 @@
|
||||
"ranged_defense": {
|
||||
"type": "recover_pain",
|
||||
"description": "Defender Recovers or ignores any flash of pain"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "bonus_dice",
|
||||
"dice": "D6",
|
||||
"target": "save",
|
||||
"description": "Granted D6 (1-6) Saving Throw Modifier for this Saving Throw Attempt"
|
||||
}
|
||||
},
|
||||
"20": {
|
||||
@@ -349,6 +370,12 @@
|
||||
}
|
||||
],
|
||||
"description": "Possible 20/20 defense that avoids Any Attack Except a Lethal Strike or adds D12 to defense"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "bonus_flat",
|
||||
"amount": 20,
|
||||
"target": "save",
|
||||
"description": "20 Added to Saving Throw"
|
||||
}
|
||||
},
|
||||
"15": {
|
||||
@@ -391,6 +418,12 @@
|
||||
"shield_bash"
|
||||
],
|
||||
"description": "Kick, Punch or Shield Bash"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "bonus_flat",
|
||||
"amount": 1,
|
||||
"target": "save",
|
||||
"description": "Add 1 to Saving Throw"
|
||||
}
|
||||
},
|
||||
"13": {},
|
||||
@@ -445,6 +478,12 @@
|
||||
"shield_bash"
|
||||
],
|
||||
"description": "Kick, Punch or Shield Bash"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "bonus_flat",
|
||||
"amount": 1,
|
||||
"target": "save",
|
||||
"description": "Add 1 to Saving Throw"
|
||||
}
|
||||
},
|
||||
"8": {
|
||||
@@ -475,6 +514,10 @@
|
||||
"ranged_defense": {
|
||||
"type": "mulligan",
|
||||
"description": "Mulligan, Can Choose to Re-Roll This Defense"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "mulligan",
|
||||
"description": "Mulligan, Can Re-Roll This Saving Throw"
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
@@ -528,6 +571,12 @@
|
||||
"shield_bash"
|
||||
],
|
||||
"description": "Kick, Punch, or Shield Bash"
|
||||
},
|
||||
"saving_throws": {
|
||||
"type": "bonus_flat",
|
||||
"amount": 1,
|
||||
"target": "save",
|
||||
"description": "Add 1 to Saving Throw"
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
|
||||
@@ -25,7 +25,8 @@ export default class D30Roll {
|
||||
RANGED_DEFENSE: "ranged_defense",
|
||||
ARCANE_SPELL_ATTACK: "arcane_spell_attack",
|
||||
ARCANE_SPELL_DEFENSE: "arcane_spell_defense",
|
||||
SKILL_ROLLS: "skill_rolls"
|
||||
SKILL_ROLLS: "skill_rolls",
|
||||
SAVING_THROWS: "saving_throws"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,11 +138,15 @@ export default class D30Roll {
|
||||
}
|
||||
|
||||
// Skill types
|
||||
if (externalType === "skill" || externalType === "monster-skill" ||
|
||||
externalType === "save" || externalType === "challenge") {
|
||||
if (externalType === "skill" || externalType === "monster-skill" || externalType === "challenge") {
|
||||
return this.ROLL_TYPES.SKILL_ROLLS
|
||||
}
|
||||
|
||||
// Saving throw types
|
||||
if (externalType === "save") {
|
||||
return options.isSpellSave ? this.ROLL_TYPES.ARCANE_SPELL_DEFENSE : this.ROLL_TYPES.SAVING_THROWS
|
||||
}
|
||||
|
||||
// If no match, return null
|
||||
console.warn(`D30Roll | Unknown external roll type: ${externalType}`)
|
||||
return null
|
||||
|
||||
@@ -609,7 +609,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
rollD30.total,
|
||||
options.rollType,
|
||||
options.rollTarget?.weapon,
|
||||
{ isRanged: isRangedForD30 }
|
||||
{ isRanged: isRangedForD30, isSpellSave: saveSpell }
|
||||
)
|
||||
options.D30message = d30Message
|
||||
}
|
||||
@@ -787,9 +787,18 @@ export default class LethalFantasyRoll extends Roll {
|
||||
let buttons = []
|
||||
if (currentAction) {
|
||||
if (currentAction.type === "weapon") {
|
||||
let weaponLabel = "Roll progression dice"
|
||||
if (currentAction.rangedMode) {
|
||||
// Compute loading count from the speed formula (e.g. "3+1d6" → load=3)
|
||||
const speedStr = currentAction.system?.speed?.[currentAction.rangedMode] ?? ""
|
||||
const rangedLoad = currentAction.rangedLoad ?? (Number(speedStr.split("+")[0]) || 0)
|
||||
if (rangedLoad > 0 && !currentAction.weaponLoaded) {
|
||||
weaponLabel = "Load weapon"
|
||||
}
|
||||
}
|
||||
buttons.push({
|
||||
action: "roll",
|
||||
label: "Roll progression dice",
|
||||
label: weaponLabel,
|
||||
callback: (event, button) => {
|
||||
let pos = $('#combat-action-dialog').position()
|
||||
game.user.setFlag(SYSTEM.id, "combat-action-dialog-pos", pos)
|
||||
@@ -908,14 +917,15 @@ export default class LethalFantasyRoll extends Roll {
|
||||
if (rollContext === "rollLethargyDice") {
|
||||
if (currentAction.spellStatus === "castingTime") {
|
||||
let time = currentAction.type === "spell" ? currentAction.system.castingTime : currentAction.system.prayerTime
|
||||
if (currentAction.castingTime <= time) {
|
||||
if (currentAction.castingTime < time) {
|
||||
let message = `Casting time : ${currentAction.name}, count : ${currentAction.castingTime}/${time}`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
currentAction.castingTime += 1
|
||||
await combatant.setFlag(SYSTEM.id, "currentAction", foundry.utils.duplicate(currentAction))
|
||||
return
|
||||
} else {
|
||||
let message = `Spell/Miracle ${currentAction.name} ready to be cast on next second !`
|
||||
// Last counting second — announce ready and transition immediately (no extra second consumed)
|
||||
let message = `Casting time : ${currentAction.name}, count : ${time}/${time} — ready to cast next second !`
|
||||
ChatMessage.create({ content: message, speaker: ChatMessage.getSpeaker({ actor: combatant.actor }) })
|
||||
currentAction.castingTime = 1
|
||||
currentAction.spellStatus = "toBeCasted"
|
||||
|
||||
Reference in New Issue
Block a user