ActiveEffects: Add complete ActiveEffects management system

- New: modules/mournblade-cyd2-effects.js with utility methods for creating, applying, and managing effects
- New: templates/partial-active-effects.hbs for displaying actor effects
- New: templates/partial-item-effects.hbs for displaying item effects
- Update: modules/mournblade-cyd2-config.js with effect configuration (types, attribute keys, categories)
- Update: templates/actor-sheet.hbs and creature-sheet.hbs with Effects tab
- Update: templates/partial-item-nav.hbs with conditional Effects tab
- Update: templates/item-talent-sheet.hbs with Effects tab content
- Update: base-actor-sheet.mjs with effect action handlers (create, edit, delete, toggle)
- Update: base-item-sheet.mjs with effect action handlers and context
- Update: modules/mournblade-cyd2-main.js to import and expose MournbladeCYD2Effects
- Update: lang/fr.json with effect-related translations

Features:
- Support for creating permanent and temporary effects
- Support for attribute modifications (ADR, PUI, CLA, PRE, TRE, etc.)
- Support for health, soul, combat, and adversity modifications
- Support for status effects
- Support for runes (pronounced and traced) effects
- Toggle to enable/disable effects
- Duration tracking (rounds, turns, seconds, combat, scene)
- Display of all active modifications summary

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-06-06 22:51:31 +02:00
parent 5ab03920d6
commit 156672d853
12 changed files with 1291 additions and 2 deletions
@@ -60,6 +60,12 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
rollDesengager: MournbladeCYD2ActorSheetV2.#onRollDesengager,
rollInitiative: MournbladeCYD2ActorSheetV2.#onRollInitiative,
rollFuir: MournbladeCYD2ActorSheetV2.#onRollFuir,
// Actions pour les ActiveEffects
createEffect: MournbladeCYD2ActorSheetV2.#onCreateEffect,
editEffect: MournbladeCYD2ActorSheetV2.#onEditEffect,
deleteEffect: MournbladeCYD2ActorSheetV2.#onDeleteEffect,
toggleEffect: MournbladeCYD2ActorSheetV2.#onToggleEffect,
applyEffect: MournbladeCYD2ActorSheetV2.#onApplyEffect,
},
};
@@ -310,4 +316,118 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
static async #onRollFuir(event, target) {
await this.document.rollFuir();
}
// #region ActiveEffects Management
/**
* Crée un nouvel effet actif
* @param {Event} event - Événement
* @param {HTMLElement} target - Éléments cible
* @private
*/
static async #onCreateEffect(event, target) {
event.preventDefault();
// Créer les données par défaut pour un nouvel effet
const defaultEffectData = {
name: game.i18n.localize("MOURNBLADECYD2.effect.new") || "Nouvel Effet",
icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/effect.webp",
description: "",
changes: [],
disabled: false,
duration: {},
origin: this.document.uuid,
tint: "",
transfer: true,
flags: {}
};
// Utiliser la dialog native FoundryVTT pour créer l'effet
const effect = await foundry.applications.api.ActiveEffectDialog.create({
document: this.document,
effect: defaultEffectData
});
if (effect) {
await this.document.createEmbeddedDocuments("ActiveEffect", [effect.toObject()]);
}
}
/**
* Édite un effet actif existant
* @param {Event} event - Événement
* @param {HTMLElement} target - Éléments cible
* @private
*/
static async #onEditEffect(event, target) {
event.preventDefault();
const effectId = target?.dataset?.effectId;
if (!effectId) return;
const effect = this.document.effects.get(effectId);
if (effect) {
// Ouvrir la sheet de l'effet pour édition
effect.sheet.render(true);
}
}
/**
* Supprime un effet actif
* @param {Event} event - Événement
* @param {HTMLElement} target - Éléments cible
* @private
*/
static async #onDeleteEffect(event, target) {
event.preventDefault();
const effectId = target?.dataset?.effectId;
if (!effectId) return;
const effect = this.document.effects.get(effectId);
if (effect) {
const confirmed = await foundry.applications.api.DialogV2.confirm({
title: game.i18n.localize("MOURNBLADECYD2.effect.deleteConfirm") || "Supprimer l'effet",
content: game.i18n.localize("MOURNBLADECYD2.effect.deleteConfirmText") || `Êtes-vous sûr de vouloir supprimer l'effet "${effect.name}" ?`
});
if (confirmed) {
await this.document.deleteEmbeddedDocuments("ActiveEffect", [effectId]);
}
}
}
/**
* Toggle l'état actif/désactivé d'un effet
* @param {Event} event - Événement
* @param {HTMLElement} target - Éléments cible
* @private
*/
static async #onToggleEffect(event, target) {
event.preventDefault();
const effectId = target?.dataset?.effectId;
if (!effectId) return;
const effect = this.document.effects.get(effectId);
if (effect) {
await effect.update({ disabled: !effect.disabled });
}
}
/**
* Applique un effet à partir d'un item
* @param {Event} event - Événement
* @param {HTMLElement} target - Éléments cible
* @private
*/
static async #onApplyEffect(event, target) {
event.preventDefault();
const effectId = target?.dataset?.effectId;
if (!effectId) return;
const effect = this.document.effects.get(effectId);
if (effect) {
await effect.apply();
}
}
// #endregion
}