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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -39,6 +39,12 @@ export default class MournbladeCYD2ItemSheetV2 extends HandlebarsApplicationMixi
|
||||
deletePredilection: MournbladeCYD2ItemSheetV2.#onDeletePredilection,
|
||||
addAutomation: MournbladeCYD2ItemSheetV2.#onAddAutomation,
|
||||
deleteAutomation: MournbladeCYD2ItemSheetV2.#onDeleteAutomation,
|
||||
// Actions pour les ActiveEffects
|
||||
createEffect: MournbladeCYD2ItemSheetV2.#onCreateEffect,
|
||||
editEffect: MournbladeCYD2ItemSheetV2.#onEditEffect,
|
||||
deleteEffect: MournbladeCYD2ItemSheetV2.#onDeleteEffect,
|
||||
toggleEffect: MournbladeCYD2ItemSheetV2.#onToggleEffect,
|
||||
applyEffect: MournbladeCYD2ItemSheetV2.#onApplyEffect,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -52,6 +58,7 @@ export default class MournbladeCYD2ItemSheetV2 extends HandlebarsApplicationMixi
|
||||
item: this.document,
|
||||
system: this.document.system,
|
||||
source: this.document.toObject(),
|
||||
config: game.system.mournbladecyd2.config,
|
||||
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
this.document.system.description || "", { async: true }
|
||||
),
|
||||
@@ -171,4 +178,118 @@ export default class MournbladeCYD2ItemSheetV2 extends HandlebarsApplicationMixi
|
||||
await this.document.update({ "system.isautomated": false });
|
||||
}
|
||||
}
|
||||
|
||||
// #region ActiveEffects Management
|
||||
|
||||
/**
|
||||
* Crée un nouvel effet actif sur l'item
|
||||
* @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: false,
|
||||
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 sur l'item
|
||||
* @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 de l'item
|
||||
* @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 sur l'item
|
||||
* @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 de l'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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user