Fixes and enhancements, from issue list
This commit is contained in:
@@ -2818,11 +2818,13 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
border-top: 1px solid rgba(83, 81, 40, 0.4);
|
border-top: 1px solid rgba(83, 81, 40, 0.4);
|
||||||
background: rgba(83, 81, 40, 0.08);
|
border-bottom: 1px solid rgba(83, 81, 40, 0.4);
|
||||||
|
background: #f5ead0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
.oh-free-roll-bar .oh-frb-label {
|
.oh-free-roll-bar .oh-frb-label {
|
||||||
font-family: "BlueDragon", "Palatino Linotype", serif;
|
font-family: "BlueDragon", "Palatino Linotype", serif;
|
||||||
@@ -2849,6 +2851,7 @@
|
|||||||
border: 1px solid #535128;
|
border: 1px solid #535128;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
color: #2a1a0a;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.oh-free-roll-bar .oh-frb-controls .oh-frb-pool {
|
.oh-free-roll-bar .oh-frb-controls .oh-frb-pool {
|
||||||
|
|||||||
@@ -9,11 +9,13 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
border-top: 1px solid fade(@color-olive, 40%);
|
border-top: 1px solid fade(@color-olive, 40%);
|
||||||
background: fade(@color-olive, 8%);
|
border-bottom: 1px solid fade(@color-olive, 40%);
|
||||||
|
background: @color-paper;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
pointer-events: auto;
|
||||||
|
|
||||||
.oh-frb-label {
|
.oh-frb-label {
|
||||||
font-family: @font-secondary;
|
font-family: @font-secondary;
|
||||||
@@ -41,6 +43,7 @@
|
|||||||
border: 1px solid @color-olive;
|
border: 1px solid @color-olive;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
color: @color-dark;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,12 @@ import { _rollPool, _diceHtml } from "../rolls.mjs"
|
|||||||
* @param {HTMLElement} html
|
* @param {HTMLElement} html
|
||||||
*/
|
*/
|
||||||
export function injectFreeRollBar(_chatLog, html) {
|
export function injectFreeRollBar(_chatLog, html) {
|
||||||
|
// Normalise: renderChatLog may pass jQuery (AppV1) or HTMLElement (AppV2/v13)
|
||||||
|
const el = (html instanceof HTMLElement) ? html : (html[0] ?? html)
|
||||||
|
if (!el?.querySelector) return
|
||||||
|
|
||||||
// Avoid double-injection on re-renders
|
// Avoid double-injection on re-renders
|
||||||
if (html.querySelector(".oh-free-roll-bar")) return
|
if (el.querySelector(".oh-free-roll-bar")) return
|
||||||
|
|
||||||
const bar = document.createElement("div")
|
const bar = document.createElement("div")
|
||||||
bar.className = "oh-free-roll-bar"
|
bar.className = "oh-free-roll-bar"
|
||||||
@@ -49,20 +53,30 @@ export function injectFreeRollBar(_chatLog, html) {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
||||||
bar.querySelector(".oh-frb-roll-btn").addEventListener("click", () => {
|
// Use event delegation on the bar container — direct child listeners can be
|
||||||
|
// swallowed by Foundry's own delegated click handlers in the sidebar.
|
||||||
|
bar.addEventListener("click", async (ev) => {
|
||||||
|
if (!ev.target.closest(".oh-frb-roll-btn")) return
|
||||||
|
ev.stopPropagation()
|
||||||
const pool = parseInt(bar.querySelector(".oh-frb-pool").value) || 2
|
const pool = parseInt(bar.querySelector(".oh-frb-pool").value) || 2
|
||||||
const color = bar.querySelector(".oh-frb-color").value
|
const color = bar.querySelector(".oh-frb-color").value
|
||||||
const explode5 = bar.querySelector(".oh-frb-explode").checked
|
const explode5 = bar.querySelector(".oh-frb-explode").checked
|
||||||
rollFree(pool, color, explode5)
|
try {
|
||||||
|
await rollFree(pool, color, explode5)
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Oath Hammer | Free Roll error:", err)
|
||||||
|
ui.notifications?.error("Free Roll failed — see console")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Insert before the chat form — use chatForm.parentElement for AppV2 compatibility
|
// Insert before the chat form — try multiple selectors for v12/v13 compatibility
|
||||||
// (in v13 parts are nested inside the app element, not direct children)
|
const anchor = el.querySelector(".chat-form")
|
||||||
const chatForm = html.querySelector(".chat-form")
|
?? el.querySelector(".chat-message-form")
|
||||||
if (chatForm) {
|
?? el.querySelector("form")
|
||||||
chatForm.parentElement.insertBefore(bar, chatForm)
|
if (anchor) {
|
||||||
|
anchor.parentElement.insertBefore(bar, anchor)
|
||||||
} else {
|
} else {
|
||||||
html.appendChild(bar)
|
el.appendChild(bar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,22 +181,20 @@ export default class OathHammerNPCSheet extends OathHammerActorSheet {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: attack.name, resizable: true },
|
window: { title: attack.name, resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"],
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
position: { width: 420 },
|
rejectClose: false,
|
||||||
content,
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-burst",
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-burst" },
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
|
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = name => form.querySelector(`[name="${name}"]`)?.value
|
|
||||||
|
|
||||||
await rollNPCAttackDamage(this.document, attack, {
|
await rollNPCAttackDamage(this.document, attack, {
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,24 +234,22 @@ export default class OathHammerNPCSheet extends OathHammerActorSheet {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: spell.name, resizable: true },
|
window: { title: spell.name, resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"],
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
position: { width: 420 },
|
rejectClose: false,
|
||||||
content,
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-wand-sparkles",
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-wand-sparkles" },
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
|
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = name => form.querySelector(`[name="${name}"]`)?.value
|
|
||||||
|
|
||||||
await rollNPCSpell(this.document, spell, {
|
await rollNPCSpell(this.document, spell, {
|
||||||
dicePool: parseInt(getValue("dicePool")) || 3,
|
dicePool: parseInt(result.dicePool) || 3,
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
colorOverride: getValue("colorOverride") || null,
|
colorOverride: result.colorOverride || null,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,23 +278,21 @@ export default class OathHammerNPCSheet extends OathHammerActorSheet {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: miracle.name, resizable: true },
|
window: { title: miracle.name, resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"],
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
position: { width: 420 },
|
rejectClose: false,
|
||||||
content,
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-hands-praying",
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-hands-praying" },
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
|
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = name => form.querySelector(`[name="${name}"]`)?.value
|
|
||||||
|
|
||||||
await rollNPCMiracle(this.document, miracle, {
|
await rollNPCMiracle(this.document, miracle, {
|
||||||
dicePool: parseInt(getValue("dicePool")) || 3,
|
dicePool: parseInt(result.dicePool) || 3,
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,23 +329,21 @@ export default class OathHammerNPCSheet extends OathHammerActorSheet {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: game.i18n.localize("OATHHAMMER.Label.ArmorDice"), resizable: true },
|
window: { title: game.i18n.localize("OATHHAMMER.Label.ArmorDice"), resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"],
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
position: { width: 420 },
|
rejectClose: false,
|
||||||
content,
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6",
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6" },
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
|
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = name => form.querySelector(`[name="${name}"]`)?.value
|
|
||||||
|
|
||||||
await rollNPCArmor(actor, {
|
await rollNPCArmor(actor, {
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
colorOverride: getValue("colorOverride") || null,
|
colorOverride: result.colorOverride || null,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,23 +387,21 @@ export default class OathHammerNPCSheet extends OathHammerActorSheet {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: item.name, resizable: true },
|
window: { title: item.name, resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"],
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
position: { width: 420 },
|
rejectClose: false,
|
||||||
content,
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6",
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6" },
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
|
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = name => form.querySelector(`[name="${name}"]`)?.value
|
|
||||||
|
|
||||||
await rollNPCSkill(this.document, item, {
|
await rollNPCSkill(this.document, item, {
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
colorOverride: getValue("colorOverride") || null,
|
colorOverride: result.colorOverride || null,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,19 +163,20 @@ export default class OathHammerRegimentSheet extends OathHammerActorSheet {
|
|||||||
visibility: game.settings.get("core", "rollMode")
|
visibility: game.settings.get("core", "rollMode")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: `${doc.name} — ${game.i18n.localize("OATHHAMMER.Roll.ArmorRoll")}`, resizable: true },
|
window: { title: `${doc.name} — ${game.i18n.localize("OATHHAMMER.Roll.ArmorRoll")}`, resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6" },
|
rejectClose: false,
|
||||||
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6",
|
||||||
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = n => form.querySelector(`[name="${n}"]`)?.value
|
|
||||||
await rollNPCArmor(doc, {
|
await rollNPCArmor(doc, {
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
colorOverride: getValue("colorOverride") || null,
|
colorOverride: result.colorOverride || null,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,19 +201,20 @@ export default class OathHammerRegimentSheet extends OathHammerActorSheet {
|
|||||||
visibility: game.settings.get("core", "rollMode")
|
visibility: game.settings.get("core", "rollMode")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: `${skill.name} — ${game.i18n.localize("OATHHAMMER.Tab.Skills")}`, resizable: true },
|
window: { title: `${skill.name} — ${game.i18n.localize("OATHHAMMER.Tab.Skills")}`, resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6" },
|
rejectClose: false,
|
||||||
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6",
|
||||||
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = n => form.querySelector(`[name="${n}"]`)?.value
|
|
||||||
await rollNPCSkill(this.document, skill, {
|
await rollNPCSkill(this.document, skill, {
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
colorOverride: getValue("colorOverride") || null,
|
colorOverride: result.colorOverride || null,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,19 +246,20 @@ export default class OathHammerRegimentSheet extends OathHammerActorSheet {
|
|||||||
visibility: game.settings.get("core", "rollMode")
|
visibility: game.settings.get("core", "rollMode")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const result = await foundry.applications.api.DialogV2.prompt({
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
window: { title: `${attack.name} — ${game.i18n.localize("OATHHAMMER.Dialog.Damage")}`, resizable: true },
|
window: { title: `${attack.name} — ${game.i18n.localize("OATHHAMMER.Dialog.Damage")}`, resizable: true },
|
||||||
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
classes: ["fvtt-oath-hammer"], position: { width: 420 }, content,
|
||||||
ok: { label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6" },
|
rejectClose: false,
|
||||||
|
buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.Roll"), icon: "fa-solid fa-dice-d6",
|
||||||
|
callback: (_ev, btn) => { const o = {}; for (const el of btn.form.elements) { if (!el.name) continue; o[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return o }
|
||||||
|
}],
|
||||||
})
|
})
|
||||||
if (!result) return
|
if (!result) return
|
||||||
const form = new DOMParser().parseFromString(result, "text/html")
|
|
||||||
const getValue = n => form.querySelector(`[name="${n}"]`)?.value
|
|
||||||
await rollNPCAttackDamage(this.document, attack, {
|
await rollNPCAttackDamage(this.document, attack, {
|
||||||
bonus: parseInt(getValue("bonus")) || 0,
|
bonus: parseInt(result.bonus) || 0,
|
||||||
colorOverride: getValue("colorOverride") || null,
|
colorOverride: result.colorOverride || null,
|
||||||
explodeOn5: getValue("explodeOn5") === "true",
|
explodeOn5: result.explodeOn5 === "true",
|
||||||
visibility: getValue("visibility"),
|
visibility: result.visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export async function rollSkillCheck(actor, skillKey, dv, options = {}) {
|
|||||||
const allRolls = [roll]
|
const allRolls = [roll]
|
||||||
|
|
||||||
// Count successes — exploding dice produce additional dice
|
// Count successes — exploding dice produce additional dice
|
||||||
const explodeThreshold = explodeOn5 ? 5 : 6
|
const explodeThreshold = explodeOn5 ? 5 : 6 // default: always explode on 6
|
||||||
let successes = 0
|
let successes = 0
|
||||||
const diceResults = []
|
const diceResults = []
|
||||||
let extraDice = 0
|
let extraDice = 0
|
||||||
@@ -100,6 +100,7 @@ export async function rollSkillCheck(actor, skillKey, dv, options = {}) {
|
|||||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||||
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
||||||
if (supporters > 0) modParts.push(`+${supporters} ${game.i18n.localize("OATHHAMMER.Dialog.Supporters")}`)
|
if (supporters > 0) modParts.push(`+${supporters} ${game.i18n.localize("OATHHAMMER.Dialog.Supporters")}`)
|
||||||
|
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||||
if (explodedCount > 0) modParts.push(`💥 ${explodedCount} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
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 modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
@@ -184,7 +185,7 @@ export async function rollRarityCheck(actor, rarityKey, itemName) {
|
|||||||
* @returns {Promise<{roll: Roll, successes: number, diceResults: Array}>}
|
* @returns {Promise<{roll: Roll, successes: number, diceResults: Array}>}
|
||||||
*/
|
*/
|
||||||
export async function _rollPool(pool, threshold, explodeOn5 = false) {
|
export async function _rollPool(pool, threshold, explodeOn5 = false) {
|
||||||
const explodeThreshold = explodeOn5 ? 5 : 6
|
const explodeThreshold = explodeOn5 ? 5 : 6 // default: always explode on 6
|
||||||
const roll = await new Roll(`${Math.max(pool, 1)}d6`).evaluate()
|
const roll = await new Roll(`${Math.max(pool, 1)}d6`).evaluate()
|
||||||
const rolls = [roll]
|
const rolls = [roll]
|
||||||
let successes = 0
|
let successes = 0
|
||||||
@@ -274,6 +275,7 @@ export async function rollWeaponAttack(actor, weapon, options = {}) {
|
|||||||
if (autoAttackBonus > 0) modParts.push(`+${autoAttackBonus} auto`)
|
if (autoAttackBonus > 0) modParts.push(`+${autoAttackBonus} auto`)
|
||||||
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
||||||
const explodedCount = diceResults.filter(d => d.exploded).length
|
const explodedCount = diceResults.filter(d => d.exploded).length
|
||||||
|
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||||
if (explodedCount > 0) modParts.push(`💥 ${explodedCount} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
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 modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
@@ -473,6 +475,7 @@ export async function rollSpellCast(actor, spell, options = {}) {
|
|||||||
if (grimPenalty < 0) modParts.push(`${grimPenalty} ${game.i18n.localize("OATHHAMMER.Dialog.GrimoireNo")}`)
|
if (grimPenalty < 0) modParts.push(`${grimPenalty} ${game.i18n.localize("OATHHAMMER.Dialog.GrimoireNo")}`)
|
||||||
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
||||||
const explodedCountSpell = diceResults.filter(d => d.exploded).length
|
const explodedCountSpell = diceResults.filter(d => d.exploded).length
|
||||||
|
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||||
if (explodedCountSpell > 0) modParts.push(`💥 ${explodedCountSpell} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
if (explodedCountSpell > 0) modParts.push(`💥 ${explodedCountSpell} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
@@ -567,6 +570,7 @@ export async function rollMiracleCast(actor, miracle, options = {}) {
|
|||||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||||
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
||||||
const explodedCountMiracle = diceResults.filter(d => d.exploded).length
|
const explodedCountMiracle = diceResults.filter(d => d.exploded).length
|
||||||
|
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||||
if (explodedCountMiracle > 0) modParts.push(`💥 ${explodedCountMiracle} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
if (explodedCountMiracle > 0) modParts.push(`💥 ${explodedCountMiracle} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
@@ -753,6 +757,7 @@ export async function rollWeaponDefense(actor, weapon, options = {}) {
|
|||||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||||
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
||||||
const explodedCountWDef = diceResults.filter(d => d.exploded).length
|
const explodedCountWDef = diceResults.filter(d => d.exploded).length
|
||||||
|
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||||
if (explodedCountWDef > 0) modParts.push(`💥 ${explodedCountWDef} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
if (explodedCountWDef > 0) modParts.push(`💥 ${explodedCountWDef} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
@@ -851,6 +856,7 @@ export async function rollArmorSave(actor, armor, options = {}) {
|
|||||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||||
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
if (luckSpend > 0) modParts.push(`+${luckSpend * luckDicePerPoint} ${game.i18n.localize("OATHHAMMER.Dialog.LuckSpend")} (${luckSpend}LP${luckIsHuman ? " 👤" : ""})`)
|
||||||
const explodedCountArmor = armorDiceResults.filter(d => d.exploded).length
|
const explodedCountArmor = armorDiceResults.filter(d => d.exploded).length
|
||||||
|
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||||
if (explodedCountArmor > 0) modParts.push(`💥 ${explodedCountArmor} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
if (explodedCountArmor > 0) modParts.push(`💥 ${explodedCountArmor} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
@@ -936,6 +942,7 @@ export async function rollInitiativeCheck(actor, options = {}) {
|
|||||||
const modParts = []
|
const modParts = []
|
||||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
||||||
const explodedCountInit = diceResults.filter(d => d.exploded).length
|
const explodedCountInit = diceResults.filter(d => d.exploded).length
|
||||||
|
if (explodeOn5) modParts.push(`💥 ${game.i18n.localize("OATHHAMMER.Dialog.ExplodeOn5")}`)
|
||||||
if (explodedCountInit > 0) modParts.push(`💥 ${explodedCountInit} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
if (explodedCountInit > 0) modParts.push(`💥 ${explodedCountInit} ${game.i18n.localize("OATHHAMMER.Roll.Exploded")}`)
|
||||||
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
const modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
@@ -990,6 +997,7 @@ export async function rollNPCSkill(actor, skillItem, options = {}) {
|
|||||||
const explodedCount = diceResults.filter(d => d.exploded).length
|
const explodedCount = diceResults.filter(d => d.exploded).length
|
||||||
const modParts = []
|
const modParts = []
|
||||||
if (bonus !== 0) modParts.push(`${bonus > 0 ? "+" : ""}${bonus} ${game.i18n.localize("OATHHAMMER.Dialog.Modifier")}`)
|
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")}`)
|
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 modLine = modParts.length ? `<div class="oh-roll-mods">${modParts.join(" · ")}</div>` : ""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user