Fixes and enhancements, from issue list
This commit is contained in:
@@ -915,7 +915,15 @@ export async function rollInitiativeCheck(actor, options = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
// NPC: Fate rank + initiativeBonus
|
||||
// NPC: find Leadership skillnpc item, fall back to Fate rank + initiativeBonus
|
||||
const leadershipSkill = actor.items.find(
|
||||
i => i.type === "skillnpc" && i.name.toLowerCase() === "leadership"
|
||||
)
|
||||
if (leadershipSkill) {
|
||||
return rollNPCSkill(actor, leadershipSkill, { bonus, visibility })
|
||||
}
|
||||
|
||||
// Fallback: Fate rank + initiativeBonus
|
||||
const sys = actor.system
|
||||
const fateRank = sys.attributes?.fate?.rank ?? 1
|
||||
const initBonus = sys.initiativeBonus ?? 0
|
||||
@@ -967,7 +975,7 @@ export async function rollInitiativeCheck(actor, options = {}) {
|
||||
* @param {object} options
|
||||
*/
|
||||
export async function rollNPCSkill(actor, skillItem, options = {}) {
|
||||
const { bonus = 0, colorOverride, visibility } = options
|
||||
const { bonus = 0, colorOverride, visibility, explodeOn5 = false } = options
|
||||
const sys = skillItem.system
|
||||
|
||||
const colorType = colorOverride || sys.colorDiceType
|
||||
@@ -976,12 +984,14 @@ export async function rollNPCSkill(actor, skillItem, options = {}) {
|
||||
|
||||
const totalDice = Math.max(sys.dicePool + bonus, 1)
|
||||
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, false)
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, explodeOn5)
|
||||
const diceHtml = _diceHtml(diceResults, threshold)
|
||||
|
||||
const modLine = bonus !== 0
|
||||
? `<div class="oh-roll-mods">${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}</div>`
|
||||
: ""
|
||||
const explodedCount = diceResults.filter(d => d.exploded).length
|
||||
const modParts = []
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (explodedCount > 0) modParts.push(`💥 ${explodedCount} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||
|
||||
const content = `
|
||||
<div class="oh-roll-card">
|
||||
@@ -1025,6 +1035,7 @@ export async function rollNPCWeaponAttack(actor, weapon, options = {}) {
|
||||
|
||||
const modParts = []
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (diceResults.filter(d => d.exploded).length > 0) modParts.push(`💥 ${diceResults.filter(d => d.exploded).length} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||
|
||||
const content = `
|
||||
@@ -1067,6 +1078,7 @@ export async function rollNPCWeaponDamage(actor, weapon, options = {}) {
|
||||
|
||||
const modParts = []
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (diceResults.filter(d => d.exploded).length > 0) modParts.push(`💥 ${diceResults.filter(d => d.exploded).length} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||
|
||||
const content = `
|
||||
@@ -1098,7 +1110,7 @@ export async function rollNPCWeaponDamage(actor, weapon, options = {}) {
|
||||
* NPC armor dice roll — rolls actor's armorDice.value dice with armorDice.colorDiceType color.
|
||||
*/
|
||||
export async function rollNPCArmor(actor, options = {}) {
|
||||
const { bonus = 0, colorOverride, visibility } = options
|
||||
const { bonus = 0, colorOverride, visibility, explodeOn5 = false } = options
|
||||
const sys = actor.system
|
||||
|
||||
const basePool = sys.armorDice?.value ?? 0
|
||||
@@ -1107,12 +1119,15 @@ export async function rollNPCArmor(actor, options = {}) {
|
||||
const colorEmoji = colorType === "black" ? "⬛" : colorType === "red" ? "🔴" : "⬜"
|
||||
const totalDice = Math.max(basePool + bonus, 1)
|
||||
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, false)
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, explodeOn5)
|
||||
const diceHtml = _diceHtml(diceResults, threshold)
|
||||
|
||||
const modLine = bonus !== 0
|
||||
? `<div class="oh-roll-mods">${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}</div>`
|
||||
: ""
|
||||
const explodedCount = diceResults.filter(d => d.exploded).length
|
||||
const modParts = []
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||
if (explodedCount > 0) modParts.push(`💥 ${explodedCount} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||
|
||||
const label = game.i18n.localize("OATHHAMMER.Label.ArmorDice")
|
||||
const content = `
|
||||
@@ -1144,20 +1159,23 @@ export async function rollNPCArmor(actor, options = {}) {
|
||||
* NPC spell cast — flat dice pool, no arcane stress, posts DV success/failure to chat.
|
||||
*/
|
||||
export async function rollNPCSpell(actor, spell, options = {}) {
|
||||
const { dicePool = 3, bonus = 0, colorOverride, visibility } = options
|
||||
const { dicePool = 3, bonus = 0, colorOverride, visibility, explodeOn5 = false } = options
|
||||
const dv = spell.system.difficultyValue ?? 1
|
||||
const colorType = colorOverride || "white"
|
||||
const threshold = colorType === "black" ? 2 : colorType === "red" ? 3 : 4
|
||||
const colorEmoji = colorType === "black" ? "⬛" : colorType === "red" ? "🔴" : "⬜"
|
||||
const totalDice = Math.max(dicePool + bonus, 1)
|
||||
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, false)
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, explodeOn5)
|
||||
const diceHtml = _diceHtml(diceResults, threshold)
|
||||
const isSuccess = successes >= dv
|
||||
|
||||
const modLine = bonus !== 0
|
||||
? `<div class="oh-roll-mods">${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}</div>`
|
||||
: ""
|
||||
const explodedCount = diceResults.filter(d => d.exploded).length
|
||||
const modParts = []
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||
if (explodedCount > 0) modParts.push(`💥 ${explodedCount} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||
|
||||
const resultClass = isSuccess ? "roll-success" : "roll-failure"
|
||||
const resultLabel = isSuccess
|
||||
@@ -1193,19 +1211,22 @@ export async function rollNPCSpell(actor, spell, options = {}) {
|
||||
* NPC miracle invocation — flat dice pool, no blocked tracking, posts DV success/failure to chat.
|
||||
*/
|
||||
export async function rollNPCMiracle(actor, miracle, options = {}) {
|
||||
const { dicePool = 3, bonus = 0, visibility } = options
|
||||
const { dicePool = 3, bonus = 0, visibility, explodeOn5 = false } = options
|
||||
const dv = 1
|
||||
const threshold = 4
|
||||
const colorEmoji = "⬜"
|
||||
const totalDice = Math.max(dicePool + bonus, 1)
|
||||
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, false)
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, explodeOn5)
|
||||
const diceHtml = _diceHtml(diceResults, threshold)
|
||||
const isSuccess = successes >= dv
|
||||
|
||||
const modLine = bonus !== 0
|
||||
? `<div class="oh-roll-mods">${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}</div>`
|
||||
: ""
|
||||
const explodedCount = diceResults.filter(d => d.exploded).length
|
||||
const modParts = []
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||
if (explodedCount > 0) modParts.push(`💥 ${explodedCount} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||
|
||||
const resultClass = isSuccess ? "roll-success" : "roll-failure"
|
||||
const resultLabel = isSuccess
|
||||
@@ -1241,7 +1262,7 @@ export async function rollNPCMiracle(actor, miracle, options = {}) {
|
||||
* NPC attack damage roll — flat dice pool from the npcattack item, no Might.
|
||||
*/
|
||||
export async function rollNPCAttackDamage(actor, attack, options = {}) {
|
||||
const { bonus = 0, visibility } = options
|
||||
const { bonus = 0, visibility, explodeOn5 = false } = options
|
||||
const sys = attack.system
|
||||
const colorType = sys.colorDiceType || "white"
|
||||
const threshold = colorType === "black" ? 2 : colorType === "red" ? 3 : 4
|
||||
@@ -1249,12 +1270,15 @@ export async function rollNPCAttackDamage(actor, attack, options = {}) {
|
||||
const totalDice = Math.max((sys.damageDice ?? 1) + bonus, 1)
|
||||
const ap = sys.ap ?? 0
|
||||
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, false)
|
||||
const { roll, rolls, successes, diceResults } = await _rollPool(totalDice, threshold, explodeOn5)
|
||||
const diceHtml = _diceHtml(diceResults, threshold)
|
||||
|
||||
const explodedCount = diceResults.filter(d => d.exploded).length
|
||||
const modParts = []
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (ap > 0) modParts.push(`AP ${ap}`)
|
||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||
if (ap > 0) modParts.push(`AP ${ap}`)
|
||||
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||
if (explodedCount > 0) modParts.push(`💥 ${explodedCount} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||
|
||||
const content = `
|
||||
|
||||
Reference in New Issue
Block a user