Migration datamodels !

This commit is contained in:
2026-01-11 22:40:06 +01:00
parent 8d3fdbd009
commit fc7c51e369
238 changed files with 16947 additions and 2539 deletions

View File

@@ -0,0 +1,27 @@
/**
* Index des applications AppV2 pour Yggdrasill
* Ce fichier centralise tous les exports des applications
*/
// Applications de feuilles d'acteurs
export { default as YggdrasillPersonnageSheet } from './yggdrasill-personnage-sheet.mjs';
export { default as YggdrasillFigurantSheet } from './yggdrasill-figurant-sheet.mjs';
// Applications de feuilles d'items
export { default as YggdrasillCompetenceSheet } from './yggdrasill-competence-sheet.mjs';
export { default as YggdrasillDonSheet } from './yggdrasill-don-sheet.mjs';
export { default as YggdrasillFaiblesseSheet } from './yggdrasill-faiblesse-sheet.mjs';
export { default as YggdrasillBlessureSheet } from './yggdrasill-blessure-sheet.mjs';
export { default as YggdrasillMaladieSheet } from './yggdrasill-maladie-sheet.mjs';
export { default as YggdrasillPoisonSheet } from './yggdrasill-poison-sheet.mjs';
export { default as YggdrasillProuesseSheet } from './yggdrasill-prouesse-sheet.mjs';
export { default as YggdrasillSortsejdrSheet } from './yggdrasill-sortsejdr-sheet.mjs';
export { default as YggdrasillSortgaldrSheet } from './yggdrasill-sortgaldr-sheet.mjs';
export { default as YggdrasillRuneSheet } from './yggdrasill-rune-sheet.mjs';
export { default as YggdrasillArmeccSheet } from './yggdrasill-armecc-sheet.mjs';
export { default as YggdrasillArmedistSheet } from './yggdrasill-armedist-sheet.mjs';
export { default as YggdrasillArmureSheet } from './yggdrasill-armure-sheet.mjs';
export { default as YggdrasillBouclierSheet } from './yggdrasill-bouclier-sheet.mjs';
export { default as YggdrasillEquipementSheet } from './yggdrasill-equipement-sheet.mjs';
export { default as YggdrasillMonnaieSheet } from './yggdrasill-monnaie-sheet.mjs';
export { default as YggdrasillEffetmagiqueSheet } from './yggdrasill-effetmagique-sheet.mjs';

View File

@@ -0,0 +1,449 @@
const { HandlebarsApplicationMixin } = foundry.applications.api
import { YggdrasillUtility } from "../../yggdrasill-utility.js"
export default class YggdrasillActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
/**
* Different sheet modes.
* @enum {number}
*/
static SHEET_MODES = { EDIT: 0, PLAY: 1 }
constructor(options = {}) {
super(options)
this.#dragDrop = this.#createDragDropHandlers()
this._sheetMode = this.constructor.SHEET_MODES.PLAY
}
#dragDrop
/** @override */
static DEFAULT_OPTIONS = {
classes: ["fvtt-yggdrasill", "sheet", "actor"],
position: {
width: 750,
height: 720,
},
form: {
submitOnChange: true,
closeOnSubmit: false,
},
window: {
resizable: true,
},
tabs: [
{
navSelector: 'nav[data-group="primary"]',
contentSelector: "section.sheet-body",
initial: "principal",
},
],
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
actions: {
editImage: YggdrasillActorSheet.#onEditImage,
toggleSheet: YggdrasillActorSheet.#onToggleSheet,
editItem: YggdrasillActorSheet.#onEditItem,
deleteItem: YggdrasillActorSheet.#onDeleteItem,
createItem: YggdrasillActorSheet.#onCreateItem,
equipItem: YggdrasillActorSheet.#onEquipItem,
rollCarac: YggdrasillActorSheet.#onRollCarac,
rollCompetence: YggdrasillActorSheet.#onRollCompetence,
rollArme: YggdrasillActorSheet.#onRollArme,
rollSort: YggdrasillActorSheet.#onRollSort,
rollProuesse: YggdrasillActorSheet.#onRollProuesse,
rollDamage: YggdrasillActorSheet.#onRollDamage,
lockUnlock: YggdrasillActorSheet.#onLockUnlock,
incrementPV: YggdrasillActorSheet.#onIncrementPV,
decrementPV: YggdrasillActorSheet.#onDecrementPV,
updateCompetence: YggdrasillActorSheet.#onUpdateCompetence,
},
}
/**
* Is the sheet currently in 'Play' mode?
* @type {boolean}
*/
get isPlayMode() {
if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY
return this._sheetMode === this.constructor.SHEET_MODES.PLAY
}
/**
* Is the sheet currently in 'Edit' mode?
* @type {boolean}
*/
get isEditMode() {
if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY
return this._sheetMode === this.constructor.SHEET_MODES.EDIT
}
/**
* Tab groups state
* @type {object}
*/
tabGroups = {
primary: "principal",
}
/** @override */
async _prepareContext() {
const context = {
fields: this.document.schema.fields,
systemFields: this.document.system.schema.fields,
actor: this.document,
system: this.document.system,
source: this.document.toObject(),
isEditMode: this.isEditMode,
isPlayMode: this.isPlayMode,
isEditable: this.isEditable,
isGM: game.user.isGM,
config: game.system.yggdrasill.config,
editScore: this.isEditMode,
}
return context
}
/** @override */
_onRender(context, options) {
super._onRender(context, options)
// Activate tab navigation manually
const nav = this.element.querySelector('nav.tabs[data-group], nav.sheet-tabs[data-group]')
if (nav) {
const group = nav.dataset.group
// Activate the current tab
const activeTab = this.tabGroups[group] || "principal"
nav.querySelectorAll('[data-tab]').forEach(link => {
const tab = link.dataset.tab
link.classList.toggle('active', tab === activeTab)
link.addEventListener('click', (event) => {
event.preventDefault()
this.tabGroups[group] = tab
this.render()
})
})
// Show/hide tab content
this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => {
content.classList.toggle('active', content.dataset.tab === activeTab)
})
}
// Add change listener for competence niveau selects
this.element.querySelectorAll('select.competence-niveau').forEach(select => {
select.addEventListener('change', async (event) => {
const itemId = event.target.dataset.itemId
const item = this.document.items.get(itemId)
if (item) {
const newNiveau = parseInt(event.target.value)
await item.update({ "system.niveau": newNiveau })
}
})
})
}
/**
* Creates drag-and-drop handlers for this application
* @returns {DragDrop[]} An array of DragDrop handlers
* @private
*/
#createDragDropHandlers() {
return []
}
/**
* Handle changing a Document's image
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onEditImage(event, target) {
const attr = target.dataset.edit
const current = foundry.utils.getProperty(this.document, attr)
const fp = new FilePicker({
current,
type: "image",
callback: (path) => {
this.document.update({ [attr]: path })
},
})
return fp.browse()
}
/**
* Toggle sheet mode between Edit and Play
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onToggleSheet(event, target) {
this._sheetMode = this.isEditMode
? this.constructor.SHEET_MODES.PLAY
: this.constructor.SHEET_MODES.EDIT
this.render()
}
/**
* Handle item editing
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onEditItem(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
const item = this.document.items.get(itemId)
if (item) item.sheet.render(true)
}
/**
* Handle item deletion
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onDeleteItem(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
const item = this.document.items.get(itemId)
if (item) {
await item.delete()
}
}
/**
* Handle item creation
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onCreateItem(event, target) {
const itemType = target.dataset.itemType
const itemData = {
name: `Nouveau ${itemType}`,
type: itemType,
}
await this.document.createEmbeddedDocuments("Item", [itemData])
}
/**
* Handle item equip toggle
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onEquipItem(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
const item = this.document.items.get(itemId)
if (item && item.system.equipe !== undefined) {
await item.update({ "system.equipe": !item.system.equipe })
}
}
/**
* Handle characteristic roll
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onRollCarac(event, target) {
const caracCateg = target.dataset.caracCateg
const caracKey = target.dataset.caracKey
this.document.rollCarac(caracCateg, caracKey)
}
/**
* Handle competence roll
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onRollCompetence(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
this.document.rollCompetence(itemId)
}
/**
* Handle weapon roll
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onRollArme(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
this.document.rollArme(itemId)
}
/**
* Handle lock/unlock toggle
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onLockUnlock(event, target) {
this._sheetMode = this.isEditMode
? this.constructor.SHEET_MODES.PLAY
: this.constructor.SHEET_MODES.EDIT
this.render()
}
/**
* Handle incrementing PV
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onIncrementPV(event, target) {
const currentPV = this.document.system.caracsecondaire.pv.value || 0
const maxPV = this.document.system.caracsecondaire.pv.max || 0
const newPV = Math.min(currentPV + 1, maxPV)
await this.document.update({ "system.caracsecondaire.pv.value": newPV })
}
/**
* Handle decrementing PV
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onDecrementPV(event, target) {
const currentPV = this.document.system.caracsecondaire.pv.value || 0
const newPV = Math.max(currentPV - 1, 0)
await this.document.update({ "system.caracsecondaire.pv.value": newPV })
}
/**
* Handle competence niveau update
* @this {YggdrasillActorSheet}
* @param {Event} event - The triggering event
* @param {HTMLElement} target - The select element
*/
static async #onUpdateCompetence(event, target) {
const itemId = target.dataset.itemId
const item = this.document.items.get(itemId)
if (!item) return
const newNiveau = parseInt(target.value)
await item.update({ "system.niveau": newNiveau })
}
/**
* Handle sort roll
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onRollSort(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
const sortType = target.dataset.sortType || "sejdr"
this.document.rollSort(itemId, sortType)
}
/**
* Handle prouesse roll
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onRollProuesse(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
this.document.rollProuesse(itemId)
}
/**
* Handle damage roll
* @this {YggdrasillActorSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static #onRollDamage(event, target) {
const itemId = target.closest("[data-item-id]").dataset.itemId
const weapon = this.document.items.get(itemId)
if (weapon) {
this.document.rollDamage(weapon, 'damage')
}
}
/**
* Handle beginning of a drag operation
* @param {DragEvent} event - The originating drag event
* @protected
*/
_onDragStart(event) {
const li = event.currentTarget
const itemId = li.dataset.itemId
const item = this.document.items.get(itemId)
if (!item) return
const dragData = item.toDragData()
event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
}
/**
* Handle a drop event
* @param {DragEvent} event - The originating drop event
* @protected
*/
async _onDrop(event) {
const data = TextEditor.getDragEventData(event)
const actor = this.document
// Handle different data types
switch (data.type) {
case "Item":
return this._onDropItem(event, data)
case "ActiveEffect":
return this._onDropActiveEffect(event, data)
}
}
/**
* Handle dropping an Item on the sheet
* @param {DragEvent} event - The originating drop event
* @param {object} data - The dropped data
* @protected
*/
async _onDropItem(event, data) {
if (!this.isEditable) return false
const item = await Item.implementation.fromDropData(data)
const itemData = item.toObject()
// Handle item from same actor
if (this.document.uuid === item.parent?.uuid) return this._onSortItem(event, itemData)
// Create the item
return this._onDropItemCreate(itemData)
}
/**
* Handle creating an owned item from drop data
* @param {object} itemData - The item data to create
* @protected
*/
async _onDropItemCreate(itemData) {
itemData = itemData instanceof Array ? itemData : [itemData]
return this.document.createEmbeddedDocuments("Item", itemData)
}
/**
* Handle sorting items
* @param {DragEvent} event - The originating drop event
* @param {object} itemData - The item data being sorted
* @protected
*/
_onSortItem(event, itemData) {
// Implement sorting logic if needed
return Promise.resolve()
}
/**
* Handle dropping an ActiveEffect on the sheet
* @param {DragEvent} event - The originating drop event
* @param {object} data - The dropped data
* @protected
*/
async _onDropActiveEffect(event, data) {
const effect = await ActiveEffect.implementation.fromDropData(data)
if (!this.isEditable || !effect) return false
if (this.document.uuid === effect.parent?.uuid) return false
return ActiveEffect.create(effect.toObject(), { parent: this.document })
}
}

View File

@@ -0,0 +1,178 @@
const { HandlebarsApplicationMixin } = foundry.applications.api
export default class YggdrasillItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
constructor(options = {}) {
super(options)
this.#dragDrop = this.#createDragDropHandlers()
}
#dragDrop
/** @override */
static DEFAULT_OPTIONS = {
classes: ["fvtt-yggdrasill", "item"],
position: {
width: 620,
height: 600,
},
form: {
submitOnChange: true,
},
window: {
resizable: true,
},
tabs: [
{
navSelector: 'nav[data-group="primary"]',
contentSelector: "section.sheet-body",
initial: "description",
},
],
dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }],
actions: {
editImage: YggdrasillItemSheet.#onEditImage,
postItem: YggdrasillItemSheet.#onPostItem,
},
}
/**
* Tab groups state
* @type {object}
*/
tabGroups = { primary: "description" }
/** @override */
async _prepareContext() {
// Import config
const YGGDRASILL_CONFIG = game.system.yggdrasill?.config || game.system.config || {};
// Create options for niveau 0-5
const optionsNiveaux4 = {};
for (let i = 0; i <= 5; i++) {
optionsNiveaux4[`${i}`] = `${i}`;
}
// Create options for base (0-20)
const optionsBase = {};
for (let i = 0; i <= 20; i++) {
optionsBase[`${i}`] = `${i}`;
}
const context = {
fields: this.document.schema.fields,
systemFields: this.document.system.schema.fields,
item: this.document,
system: this.document.system,
data: this.document.system,
source: this.document.toObject(),
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description || "", { async: true }),
enrichedEffet: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.effet || "", { async: true }),
isEditMode: true,
isEditable: this.isEditable,
editable: this.isEditable,
isGM: game.user.isGM,
config: YGGDRASILL_CONFIG,
optionsBase: optionsBase,
optionsNiveaux4: optionsNiveaux4,
}
return context
}
/** @override */
_onRender(context, options) {
super._onRender(context, options)
// Activate tab navigation manually
const nav = this.element.querySelector('nav.tabs[data-group]')
if (nav) {
const group = nav.dataset.group
// Activate the current tab
const activeTab = this.tabGroups[group] || "description"
nav.querySelectorAll('[data-tab]').forEach(link => {
const tab = link.dataset.tab
link.classList.toggle('active', tab === activeTab)
link.addEventListener('click', (event) => {
event.preventDefault()
this.tabGroups[group] = tab
this.render()
})
})
// Show/hide tab content
const body = this.element.querySelector('section.sheet-body')
if (body) {
body.querySelectorAll('[data-tab]').forEach(content => {
const tab = content.dataset.tab
content.style.display = tab === activeTab ? 'block' : 'none'
})
}
}
}
/**
* Creates drag-and-drop handlers for this application
* @returns {DragDrop[]} An array of DragDrop handlers
* @private
*/
#createDragDropHandlers() {
return []
}
/**
* Handle changing a Document's image
* @this {YggdrasillItemSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onEditImage(event, target) {
const attr = target.dataset.edit || "img"
const current = foundry.utils.getProperty(this.document, attr)
const fp = new FilePicker({
current,
type: "image",
callback: (path) => {
this.document.update({ [attr]: path })
},
})
return fp.browse()
}
/**
* Handle posting item to chat
* @this {YggdrasillItemSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onPostItem(event, target) {
const item = this.document
const chatData = {
user: game.user.id,
speaker: ChatMessage.getSpeaker(),
content: await foundry.applications.handlebars.renderTemplate("systems/fvtt-yggdrasill/templates/chat-item-card.hbs", {
item: item,
system: item.system,
description: await TextEditor.enrichHTML(item.system.description || "", { async: true })
})
}
ChatMessage.create(chatData)
}
/**
* Handle beginning of a drag operation
* @param {DragEvent} event - The originating drag event
* @protected
*/
_onDragStart(event) {
const dragData = this.document.toDragData()
event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
}
/**
* Handle a drop event
* @param {DragEvent} event - The originating drop event
* @protected
*/
async _onDrop(event) {
// Items generally don't handle drops, but method exists for extensibility
return false
}
}

View File

@@ -0,0 +1,44 @@
#!/bin/bash
# Liste des types d'items restants à créer
items=(
"poison:Poison"
"prouesse:Prouesse"
"sortsejdr:Sortsejdr"
"sortgaldr:Sortgaldr"
"rune:Rune"
"armecc:Armecc"
"armedist:Armedist"
"armure:Armure"
"bouclier:Bouclier"
"equipement:Equipement"
"monnaie:Monnaie"
"effetmagique:Effetmagique"
)
for item in "${items[@]}"; do
type="${item%%:*}"
class="${item##*:}"
cat > "yggdrasill-${type}-sheet.mjs" << EOF
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class Yggdrasill${class}Sheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "${type}"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-${type}-sheet.hbs",
},
}
}
EOF
done
echo "Created all item sheets"
ls -1 yggdrasill-*-sheet.mjs | wc -l

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillArmeccSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "armecc"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-armecc-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillArmedistSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "armedist"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-armedist-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillArmureSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "armure"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-armure-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillBlessureSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "blessure"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-blessure-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillBouclierSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "bouclier"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-bouclier-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,21 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillCompetenceSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "competence"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-competence-sheet.hbs",
},
}
/** @override */
tabGroups = {
primary: "details",
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillDonSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "don"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-don-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillEffetmagiqueSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "effetmagique"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-effetmagique-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillEquipementSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "equipement"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-equipement-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillFaiblesseSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "faiblesse"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-faiblesse-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,40 @@
import YggdrasillActorSheet from "./base-actor-sheet.mjs"
export default class YggdrasillFigurantSheet extends YggdrasillActorSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "figurant"],
window: {
...super.DEFAULT_OPTIONS.window,
title: "Feuille de Figurant",
},
}
/** @override */
static PARTS = {
sheet: {
template: "systems/fvtt-yggdrasill/templates/actor-figurant-sheet.hbs",
},
}
/** @override */
tabGroups = {
primary: "principal",
}
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
const actor = this.document
// System fields for formInput helpers
context.systemFields = actor.system.schema.fields
// Enrich HTML fields
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.description || "", { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.notes || "", { async: true })
return context
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillMaladieSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "maladie"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-maladie-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillMonnaieSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "monnaie"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-monnaie-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,99 @@
import YggdrasillActorSheet from "./base-actor-sheet.mjs"
export default class YggdrasillPersonnageSheet extends YggdrasillActorSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "personnage"],
window: {
...super.DEFAULT_OPTIONS.window,
title: "Feuille de Personnage",
},
}
/** @override */
static PARTS = {
sheet: {
template: "systems/fvtt-yggdrasill/templates/actor-personnage-sheet-new.hbs",
},
}
/** @override */
tabGroups = {
primary: "principal",
}
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
const actor = this.document
// Prepare items by type
context.competencesGenerales = actor.items.filter(i => i.type === 'competence' && i.system.categorie === 'generale')
context.competencesMartiales = actor.items.filter(i => i.type === 'competence' && i.system.categorie === 'martiale')
context.competencesMagiques = actor.items.filter(i => i.type === 'competence' && i.system.categorie === 'magique')
context.dons = actor.items.filter(i => i.type === 'don')
context.faiblesses = actor.items.filter(i => i.type === 'faiblesse')
context.blessures = actor.items.filter(i => i.type === 'blessure')
context.maladies = actor.items.filter(i => i.type === 'maladie')
context.poisons = actor.items.filter(i => i.type === 'poison')
context.prouesses = actor.items.filter(i => i.type === 'prouesse')
context.sortsSejdr = actor.items.filter(i => i.type === 'sortsejdr')
context.sortsGaldr = actor.items.filter(i => i.type === 'sortgaldr')
context.runes = actor.items.filter(i => i.type === 'rune')
context.armesCC = actor.items.filter(i => i.type === 'armecc')
context.armesDist = actor.items.filter(i => i.type === 'armedist')
context.armures = actor.items.filter(i => i.type === 'armure')
context.boucliers = actor.items.filter(i => i.type === 'bouclier')
context.equipements = actor.items.filter(i => i.type === 'equipement')
context.monnaies = actor.items.filter(i => i.type === 'monnaie')
context.effetsMagiques = actor.items.filter(i => i.type === 'effetmagique')
// Prepare equipped items
context.armesEquipees = actor.items.filter(i => (i.type === 'armecc' || i.type === 'armedist') && i.system.equipe)
context.armureEquipee = actor.items.find(i => i.type === 'armure' && i.system.equipe)
context.bouclierEquipe = actor.items.find(i => i.type === 'bouclier' && i.system.equipe)
// Calculate total protection from equipped armors
context.protectionTotal = context.armures
.filter(a => a.system.equipe)
.reduce((sum, a) => sum + (parseInt(a.system.protection) || 0), 0)
// Calculate shield defense bonus from equipped shield
context.dpBouclier = context.boucliers
.filter(b => b.system.equipe)
.reduce((sum, b) => sum + (parseInt(b.system.defensebonus) || 0), 0)
// Calculate total encumbrance from equipements
context.encTotal = context.equipements
.reduce((sum, e) => sum + ((parseInt(e.system.quantite) || 0) * (parseInt(e.system.enc) || 0)), 0)
// Options for selects
context.optionsCarac = {}
for (let i = 0; i <= 10; i++) {
context.optionsCarac[i] = i.toString()
}
context.optionsBase = {}
for (let i = 0; i <= 5; i++) {
context.optionsBase[i] = i.toString()
}
// Options for bonus/malus (-10 to +10)
context.optionsDMDP = []
for (let i = -10; i <= 10; i++) {
context.optionsDMDP.push({ value: i, text: i >= 0 ? `+${i}` : i.toString() })
}
// System fields for formInput helpers
context.systemFields = actor.system.schema.fields
// Enrich HTML fields
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.description || "", { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.notes || "", { async: true })
context.enrichedGMNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.gmnotes || "", { async: true })
context.enrichedTirageRunes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.tiragerunes || "", { async: true })
return context
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillPoisonSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "poison"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-poison-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillProuesseSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "prouesse"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-prouesse-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillRuneSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "rune"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-rune-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillSortgaldrSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "sortgaldr"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-sortgaldr-sheet.hbs",
},
}
}

View File

@@ -0,0 +1,16 @@
import YggdrasillItemSheet from "./base-item-sheet.mjs"
export default class YggdrasillSortsejdrSheet extends YggdrasillItemSheet {
/** @override */
static DEFAULT_OPTIONS = {
...super.DEFAULT_OPTIONS,
classes: [...super.DEFAULT_OPTIONS.classes, "sortsejdr"],
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-yggdrasill/templates/item-sortsejdr-sheet.hbs",
},
}
}