Nouvelles corrections sur la fiche
This commit is contained in:
@@ -2,6 +2,7 @@ export { default as AwECharacterSheet } from "./sheets/character-sheet.mjs"
|
||||
export { default as AwECreatureSheet } from "./sheets/creature-sheet.mjs"
|
||||
export { default as AwEAbilitySheet } from "./sheets/ability-sheet.mjs"
|
||||
export { default as AwEFieldSheet } from "./sheets/field-sheet.mjs"
|
||||
export { default as AwESpecializationSheet } from "./sheets/specialization-sheet.mjs"
|
||||
export { default as AwEArchetypeSheet } from "./sheets/archetype-sheet.mjs"
|
||||
export { default as AwEBackgroundSheet } from "./sheets/background-sheet.mjs"
|
||||
export { default as AwEKitSheet } from "./sheets/kit-sheet.mjs"
|
||||
|
||||
@@ -78,19 +78,39 @@ export default class AwECharacterSheet extends AwEActorSheet {
|
||||
case "main":
|
||||
context.tab = context.tabs.main
|
||||
context.abilities = doc.itemTypes.ability.map(item => ({
|
||||
...item,
|
||||
id: item.id,
|
||||
uuid: item.uuid,
|
||||
name: item.name,
|
||||
img: item.img,
|
||||
system: item.system,
|
||||
costLabel: game.i18n.localize(SYSTEM.ABILITY_COST[item.system.cost]?.label ?? item.system.cost)
|
||||
}))
|
||||
break
|
||||
case "biography":
|
||||
context.tab = context.tabs.biography
|
||||
context.fields = doc.itemTypes.field.map(item => ({
|
||||
...item,
|
||||
id: item.id,
|
||||
uuid: item.uuid,
|
||||
name: item.name,
|
||||
img: item.img,
|
||||
system: item.system,
|
||||
keyAttrLabel: game.i18n.localize(SYSTEM.ATTRIBUTES[item.system.keyAttribute]?.label ?? item.system.keyAttribute),
|
||||
keyAttr2Label: item.system.keyAttribute2
|
||||
? game.i18n.localize(SYSTEM.ATTRIBUTES[item.system.keyAttribute2]?.label ?? item.system.keyAttribute2)
|
||||
: null
|
||||
}))
|
||||
context.specializations = (doc.itemTypes.specialization ?? []).map(item => {
|
||||
const fieldMatch = doc.itemTypes.field.some(f =>
|
||||
AwECharacterSheet.#slugify(f.name) === AwECharacterSheet.#slugify(item.system.fieldName)
|
||||
)
|
||||
const attrOverrideLabel = item.system.keyAttributeOverride
|
||||
? game.i18n.localize(SYSTEM.ATTRIBUTES[item.system.keyAttributeOverride]?.label ?? item.system.keyAttributeOverride)
|
||||
: null
|
||||
return {
|
||||
id: item.id, uuid: item.uuid, name: item.name, img: item.img, system: item.system,
|
||||
fieldMatch, attrOverrideLabel
|
||||
}
|
||||
})
|
||||
context.archetypes = doc.itemTypes.archetype
|
||||
context.backgrounds = doc.itemTypes.background
|
||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
@@ -123,8 +143,8 @@ export default class AwECharacterSheet extends AwEActorSheet {
|
||||
/** @override */
|
||||
async _onDropItem(item) {
|
||||
if (!item) return
|
||||
// field/background: max 1 (replace existing); archetype: multiple allowed
|
||||
if (item.type === "field" || item.type === "background") {
|
||||
// field/background/specialization: max 1 (replace existing); archetype: multiple allowed
|
||||
if (item.type === "field" || item.type === "background" || item.type === "specialization") {
|
||||
const existing = this.document.itemTypes[item.type]
|
||||
if (existing.length > 0) await existing[0].delete()
|
||||
return this.document.createEmbeddedDocuments("Item", [item.toObject()])
|
||||
@@ -197,6 +217,7 @@ export default class AwECharacterSheet extends AwEActorSheet {
|
||||
|
||||
/**
|
||||
* Roll the key attribute check from a Field item.
|
||||
* If a matching Specialization has a keyAttributeOverride, it takes priority.
|
||||
* @param {PointerEvent} event The triggering event.
|
||||
* @param {HTMLElement} target The target element.
|
||||
*/
|
||||
@@ -204,7 +225,23 @@ export default class AwECharacterSheet extends AwEActorSheet {
|
||||
const itemId = target.closest("[data-item-id]")?.dataset.itemId
|
||||
const item = this.document.items.get(itemId)
|
||||
if (!item) return
|
||||
const attrId = target.dataset.attributeId ?? item.system.keyAttribute
|
||||
await this.document.rollAttribute(attrId)
|
||||
|
||||
// Check for a specialization that matches this field and overrides the key attribute
|
||||
const spec = this.document.itemTypes.specialization?.find(s =>
|
||||
AwECharacterSheet.#slugify(s.system.fieldName) === AwECharacterSheet.#slugify(item.name)
|
||||
)
|
||||
const attrId = spec?.system.keyAttributeOverride
|
||||
|| target.dataset.attributeId
|
||||
|| item.system.keyAttribute
|
||||
|
||||
await this.document.rollAttribute(attrId, {
|
||||
sourceItemName: item.name,
|
||||
sourceItemImg: item.img
|
||||
})
|
||||
}
|
||||
|
||||
/** Slugify a string for loose name matching (lowercase, trim, spaces→dash, strip non-alphanum). */
|
||||
static #slugify(str) {
|
||||
return (str ?? "").toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,7 @@ export default class AwEFieldSheet extends AwEItemSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["field"],
|
||||
position: { width: 620 },
|
||||
window: { contentClasses: ["field-content"] },
|
||||
actions: {
|
||||
addSpecialization: AwEFieldSheet.#onAddSpecialization,
|
||||
removeSpecialization: AwEFieldSheet.#onRemoveSpecialization
|
||||
}
|
||||
window: { contentClasses: ["field-content"] }
|
||||
}
|
||||
|
||||
/** @override */
|
||||
@@ -18,29 +14,4 @@ export default class AwEFieldSheet extends AwEItemSheet {
|
||||
template: "systems/fvtt-adventures-with-emmy/templates/field.hbs"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle adding a specialization.
|
||||
* @param {PointerEvent} event - The initiating event.
|
||||
* @param {HTMLElement} target - The input element.
|
||||
*/
|
||||
static async #onAddSpecialization(event, target) {
|
||||
const value = target.value.trim()
|
||||
if (!value) return
|
||||
const current = this.document.system.specializations ?? []
|
||||
await this.document.update({ "system.specializations": [...current, value] })
|
||||
target.value = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle removing a specialization.
|
||||
* @param {PointerEvent} event - The initiating click event.
|
||||
* @param {HTMLElement} target - The remove button.
|
||||
*/
|
||||
static async #onRemoveSpecialization(event, target) {
|
||||
const index = Number(target.dataset.index)
|
||||
const current = [...(this.document.system.specializations ?? [])]
|
||||
current.splice(index, 1)
|
||||
await this.document.update({ "system.specializations": current })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import AwEItemSheet from "./base-item-sheet.mjs"
|
||||
import { SYSTEM } from "../../config/system.mjs"
|
||||
|
||||
export default class AwESpecializationSheet extends AwEItemSheet {
|
||||
/** @override */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["specialization"],
|
||||
position: { width: 620 },
|
||||
window: { contentClasses: ["specialization-content"] }
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
main: {
|
||||
template: "systems/fvtt-adventures-with-emmy/templates/specialization.hbs"
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options)
|
||||
context.attributeChoices = {
|
||||
"": "—",
|
||||
...Object.fromEntries(Object.values(SYSTEM.ATTRIBUTES).map(a => [a.id, game.i18n.localize(a.label)]))
|
||||
}
|
||||
return context
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,11 @@ export default class AwERoll extends Roll {
|
||||
get knowledgeBonus() { return this.options.knowledgeBonus ?? 0 }
|
||||
get dc() { return this.options.dc }
|
||||
get outcome() { return this.options.outcome }
|
||||
get actorId() { return this.options.actorId }
|
||||
get actorName() { return this.options.actorName }
|
||||
get actorImage() { return this.options.actorImage }
|
||||
get actorId() { return this.options.actorId }
|
||||
get actorName() { return this.options.actorName }
|
||||
get actorImage() { return this.options.actorImage }
|
||||
get sourceItemName() { return this.options.sourceItemName }
|
||||
get sourceItemImg() { return this.options.sourceItemImg }
|
||||
|
||||
// --- Outcome calculation ---
|
||||
|
||||
@@ -153,9 +155,11 @@ export default class AwERoll extends Roll {
|
||||
bonus,
|
||||
knowledgeBonus,
|
||||
dc,
|
||||
actorId: options.actorId,
|
||||
actorName: options.actorName,
|
||||
actorImage: options.actorImage
|
||||
actorId: options.actorId,
|
||||
actorName: options.actorName,
|
||||
actorImage: options.actorImage,
|
||||
sourceItemName: options.sourceItemName,
|
||||
sourceItemImg: options.sourceItemImg
|
||||
})
|
||||
|
||||
await roll.evaluate()
|
||||
@@ -189,8 +193,10 @@ export default class AwERoll extends Roll {
|
||||
dice: this.dice,
|
||||
outcome: isPrivate ? null : this.outcome,
|
||||
dc: this.dc,
|
||||
actorName: this.actorName,
|
||||
actorImage: this.actorImage,
|
||||
actorName: this.actorName,
|
||||
actorImage: this.actorImage,
|
||||
sourceItemName: this.sourceItemName,
|
||||
sourceItemImg: this.sourceItemImg,
|
||||
isPrivate
|
||||
}
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ export { default as AwECharacter } from "./character.mjs"
|
||||
export { default as AwECreature } from "./creature.mjs"
|
||||
export { default as AwEAbility } from "./ability.mjs"
|
||||
export { default as AwEField } from "./field.mjs"
|
||||
export { default as AwESpecialization } from "./specialization.mjs"
|
||||
export { default as AwEArchetype } from "./archetype.mjs"
|
||||
export { default as AwEBackground } from "./background.mjs"
|
||||
export { default as AwEKit } from "./kit.mjs"
|
||||
|
||||
@@ -19,7 +19,6 @@ export default class AwEField extends foundry.abstract.TypeDataModel {
|
||||
blank: true,
|
||||
choices: { "": "—", ...Object.values(SYSTEM.ATTRIBUTES).reduce((o, a) => { o[a.id] = a.label; return o }, {}) }
|
||||
})
|
||||
schema.specializations = new fields.ArrayField(new fields.StringField())
|
||||
schema.knowledgeBonus = new fields.StringField({ initial: "", required: false, nullable: true })
|
||||
|
||||
return schema
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
|
||||
export default class AwESpecialization extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.fieldName = new fields.StringField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
initial: "",
|
||||
blank: true
|
||||
})
|
||||
|
||||
schema.keyAttributeOverride = new fields.StringField({
|
||||
required: false,
|
||||
nullable: true,
|
||||
initial: "",
|
||||
blank: true,
|
||||
choices: {
|
||||
"": "—",
|
||||
...Object.fromEntries(Object.values(SYSTEM.ATTRIBUTES).map(a => [a.id, a.label]))
|
||||
}
|
||||
})
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.traits = new fields.ArrayField(new fields.StringField())
|
||||
|
||||
return schema
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user