Various fixes and changes based on tester feedback
This commit is contained in:
@@ -60,6 +60,16 @@ export default class OathHammerActorSheet extends HandlebarsApplicationMixin(fou
|
||||
/** @override */
|
||||
_onRender(context, options) {
|
||||
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||
// ProseMirror "Save" dispatches a change event before committing its .value
|
||||
// to the element, so FormDataExtended may read stale HTML. Instead we
|
||||
// intercept the event here, stop it from bubbling to the submitOnChange
|
||||
// handler, and update the document directly with the current editor value.
|
||||
for (const pm of this.element.querySelectorAll("prose-mirror[name]")) {
|
||||
pm.addEventListener("change", async (event) => {
|
||||
event.stopPropagation()
|
||||
await this.document.update({ [pm.name]: pm.value ?? "" })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#createDragDropHandlers() {
|
||||
@@ -89,6 +99,10 @@ export default class OathHammerActorSheet extends HandlebarsApplicationMixin(fou
|
||||
|
||||
_onDragStart(event) {
|
||||
if ("link" in event.target.dataset) return
|
||||
const li = event.target.closest("[data-item-uuid]")
|
||||
if (!li) return
|
||||
const dragData = { type: "Item", uuid: li.dataset.itemUuid }
|
||||
event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
|
||||
}
|
||||
|
||||
_onDragOver(event) {}
|
||||
|
||||
@@ -81,6 +81,12 @@ export default class OathHammerItemSheet extends HandlebarsApplicationMixin(foun
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||
for (const pm of this.element.querySelectorAll("prose-mirror[name]")) {
|
||||
pm.addEventListener("change", async (event) => {
|
||||
event.stopPropagation()
|
||||
await this.document.update({ [pm.name]: pm.value ?? "" })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#createDragDropHandlers() {
|
||||
|
||||
@@ -4,7 +4,9 @@ import OathHammerRollDialog from "../roll-dialog.mjs"
|
||||
import OathHammerWeaponDialog from "../weapon-dialog.mjs"
|
||||
import OathHammerSpellDialog from "../spell-dialog.mjs"
|
||||
import OathHammerMiracleDialog from "../miracle-dialog.mjs"
|
||||
import { rollSkillCheck, rollWeaponAttack, rollWeaponDamage, rollSpellCast, rollMiracleCast } from "../../rolls.mjs"
|
||||
import OathHammerDefenseDialog from "../defense-dialog.mjs"
|
||||
import OathHammerArmorDialog from "../armor-dialog.mjs"
|
||||
import { rollSkillCheck, rollWeaponAttack, rollWeaponDamage, rollSpellCast, rollMiracleCast, rollArmorSave, rollWeaponDefense } from "../../rolls.mjs"
|
||||
|
||||
export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
/** @override */
|
||||
@@ -22,11 +24,15 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
createSpell: OathHammerCharacterSheet.#onCreateSpell,
|
||||
createMiracle: OathHammerCharacterSheet.#onCreateMiracle,
|
||||
createEquipment: OathHammerCharacterSheet.#onCreateEquipment,
|
||||
createTrait: OathHammerCharacterSheet.#onCreateTrait,
|
||||
rollSkill: OathHammerCharacterSheet.#onRollSkill,
|
||||
attackWeapon: OathHammerCharacterSheet.#onAttackWeapon,
|
||||
defendWeapon: OathHammerCharacterSheet.#onDefendWeapon,
|
||||
damageWeapon: OathHammerCharacterSheet.#onDamageWeapon,
|
||||
castSpell: OathHammerCharacterSheet.#onCastSpell,
|
||||
castMiracle: OathHammerCharacterSheet.#onCastMiracle,
|
||||
rollArmorSave: OathHammerCharacterSheet.#onRollArmorSave,
|
||||
resetMiracleBlocked: OathHammerCharacterSheet.#onResetMiracleBlocked,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -101,6 +107,7 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
_violated: o.system.violated
|
||||
}
|
||||
})
|
||||
context.enrichedBackground = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.background ?? "", { async: true })
|
||||
break
|
||||
case "skills": {
|
||||
context.tab = context.tabs.skills
|
||||
@@ -170,6 +177,10 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
}
|
||||
})
|
||||
context.ammunition = doc.itemTypes.ammunition
|
||||
// Slot tracking: max = 10 + (Might rank × 2); used = sum of all items' slots
|
||||
context.slotsMax = 10 + (doc.system.attributes.might.rank * 2)
|
||||
context.slotsUsed = doc.items.reduce((sum, item) => sum + (item.system.slots ?? 0), 0)
|
||||
context.slotsOver = context.slotsUsed > context.slotsMax
|
||||
break
|
||||
case "magic":
|
||||
context.tab = context.tabs.magic
|
||||
@@ -180,12 +191,14 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
context.tab = context.tabs.equipment
|
||||
context.equipment = doc.itemTypes.equipment
|
||||
context.magicItems = doc.itemTypes["magic-item"]
|
||||
context.slotsMax = 10 + (doc.system.attributes.might.rank * 2)
|
||||
context.slotsUsed = doc.items.reduce((sum, item) => sum + (item.system.slots ?? 0), 0)
|
||||
context.slotsOver = context.slotsUsed > context.slotsMax
|
||||
break
|
||||
case "notes":
|
||||
context.tab = context.tabs.notes
|
||||
context.enrichedBackground = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.background, { async: true })
|
||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.description, { async: true })
|
||||
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.notes, { async: true })
|
||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.description ?? "", { async: true })
|
||||
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.notes ?? "", { async: true })
|
||||
break
|
||||
}
|
||||
return context
|
||||
@@ -246,6 +259,10 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("OATHHAMMER.NewItem.Equipment"), type: "equipment" }])
|
||||
}
|
||||
|
||||
static #onCreateTrait(event, target) {
|
||||
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("OATHHAMMER.NewItem.Trait"), type: "trait" }])
|
||||
}
|
||||
|
||||
static async #onRollSkill(event, target) {
|
||||
const skillKey = target.dataset.skill
|
||||
if (!skillKey) return
|
||||
@@ -264,6 +281,16 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
await rollWeaponAttack(this.document, weapon, opts)
|
||||
}
|
||||
|
||||
static async #onDefendWeapon(event, target) {
|
||||
const weaponId = target.dataset.itemId
|
||||
if (!weaponId) return
|
||||
const weapon = this.document.items.get(weaponId)
|
||||
if (!weapon) return
|
||||
const opts = await OathHammerWeaponDialog.promptDefense(this.document, weapon)
|
||||
if (!opts) return
|
||||
await rollWeaponDefense(this.document, weapon, opts)
|
||||
}
|
||||
|
||||
static async #onDamageWeapon(event, target) {
|
||||
const weaponId = target.dataset.itemId
|
||||
if (!weaponId) return
|
||||
@@ -289,8 +316,26 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet {
|
||||
if (!miracleId) return
|
||||
const miracle = this.document.items.get(miracleId)
|
||||
if (!miracle) return
|
||||
if (this.document.system.miracleBlocked) {
|
||||
ui.notifications.warn(game.i18n.localize("OATHHAMMER.Warning.MiracleBlocked"))
|
||||
return
|
||||
}
|
||||
const opts = await OathHammerMiracleDialog.prompt(this.document, miracle)
|
||||
if (!opts) return
|
||||
await rollMiracleCast(this.document, miracle, opts)
|
||||
}
|
||||
|
||||
static async #onResetMiracleBlocked() {
|
||||
await this.document.update({ "system.miracleBlocked": false })
|
||||
}
|
||||
|
||||
static async #onRollArmorSave(event, target) {
|
||||
const armorId = target.dataset.itemId
|
||||
if (!armorId) return
|
||||
const armor = this.document.items.get(armorId)
|
||||
if (!armor) return
|
||||
const opts = await OathHammerArmorDialog.prompt(this.document, armor)
|
||||
if (!opts) return
|
||||
await rollArmorSave(this.document, armor, opts)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,15 +28,26 @@ export default class OathHammerClassSheet extends OathHammerItemSheet {
|
||||
return context
|
||||
}
|
||||
|
||||
/** @override — collect checkbox sets explicitly so unchecking all works */
|
||||
_prepareSubmitData(event, form, formData) {
|
||||
const data = super._prepareSubmitData(event, form, formData)
|
||||
data["system.armorProficiency"] = Array.from(
|
||||
form.querySelectorAll('input[name="system.armorProficiency"]:checked')
|
||||
).map(el => el.value)
|
||||
data["system.weaponProficiency"] = Array.from(
|
||||
form.querySelectorAll('input[name="system.weaponProficiency"]:checked')
|
||||
).map(el => el.value)
|
||||
return data
|
||||
/** @override */
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
// Handle proficiency checkboxes directly — FormDataExtended mishandles
|
||||
// multiple same-named checkboxes, so we intercept the change event,
|
||||
// collect all checked values ourselves, and stop propagation to prevent
|
||||
// the generic submitOnChange handler from clobbering the data.
|
||||
for (const cb of this.element.querySelectorAll('.proficiency-checkboxes input[type="checkbox"]')) {
|
||||
cb.addEventListener("change", this.#onProficiencyChange.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
async #onProficiencyChange(event) {
|
||||
event.stopPropagation()
|
||||
const root = this.element
|
||||
const armorProficiency = [...root.querySelectorAll('input[name="system.armorProficiency"]:checked')].map(e => e.value)
|
||||
const weaponProficiency = [...root.querySelectorAll('input[name="system.weaponProficiency"]:checked')].map(e => e.value)
|
||||
await this.document.update({
|
||||
"system.armorProficiency": armorProficiency,
|
||||
"system.weaponProficiency": weaponProficiency,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user