diff --git a/lang/fr.json b/lang/fr.json index bd99fd0..1e80f7f 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -515,6 +515,12 @@ "quote": "Citation", "resistances": "Résistances", "rituals": "Rituels", + "amateur": "Amateur", + "competent": "Compétent", + "expert": "Expert", + "effects": "Effets", + "information": "Informations", + "newSortilege": "Nouveau sortilège", "rollView": "Vue de jet", "satanicSuccess": "Succès satanique", "scars": "Cicatrices", @@ -577,30 +583,58 @@ "Sortilege": { "FIELDS": { "categorie": { - "label": "Catégorie" + "label": "Type" }, - "cost": { - "label": "Coût" + "niveauRequis": { + "label": "Niveau requis" }, "description": { "label": "Description" }, - "difficulty": { - "label": "Difficulté" + "portee": { + "label": "Portée" }, - "ingredients": { - "label": "Ingrédients" + "duree": { + "label": "Durée" }, - "limit": { - "label": "Limite" + "conditions": { + "label": "Conditions" }, - "nbAttempts": { - "label": "Nombre de tentatives" + "effetAmateur": { + "label": "Effet Amateur" }, - "threshold": { - "label": "Seuil" + "effetCompetent": { + "label": "Effet Compétent" + }, + "effetExpert": { + "label": "Effet Expert" + }, + "concentration": { + "label": "Concentration" } - } + }, + "cast": "Lancer le sort", + "noAtout": "Vous n'avez pas d'atout en main", + "noCoupe": "Vous n'avez pas de carte Coupe disponible", + "drawCard": "Tirer une carte", + "cardDrawn": "Carte tirée", + "cardValue": "Valeur de la carte", + "modifier": "Modificateur", + "totalDifficulty": "Difficulté totale", + "selectAtouts": "Choisir les atouts", + "atoutHint": "Sélectionnez un ou plusieurs atouts (lames majeures) à jouer. Leurs valeurs s'additionnent.", + "atoutTotal": "Total des atouts", + "selectCoupe": "Cartes Coupe bonus", + "coupeHint": "En tant que thaumaturge, vous pouvez ajouter des cartes Coupe.", + "coupeTotal": "Total Coupe", + "total": "Total", + "playerTotal": "Total du joueur", + "difficulty": "Difficulté du sort", + "rang": "Rang", + "atoutsUsed": "Atouts utilisés", + "coupeUsed": "Cartes Coupe utilisées", + "failureNormal": "Échec normal", + "failureCritical": "Échec critique" }, "Roll": { "cancel": "Annuler", @@ -732,6 +766,7 @@ "addTalent": "Ajouter un talent", "addTrait": "Ajouter un trait", "addWeapon": "Ajouter une arme", + "addSortilege": "Ajouter un sortilège", "damages": "Entrer les dégâts actuels subis" }, "ViewDetails": "Voir les détails", diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index f2c1905..a6d9409 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -13,3 +13,4 @@ export { default as HamalronTarotSheet } from "./sheets/tarot-sheet.mjs" export { default as HamalronItemSheet } from "./sheets/base-item-sheet.mjs" export { default as HamalronActorSheet } from "./sheets/base-actor-sheet.mjs" export { default as HamalronTarotDeckManager } from "./tarot-deck-manager.mjs" +export { default as HamalronSortilegeCasting } from "./sortilege-casting.mjs" diff --git a/module/applications/sheets/personnage-sheet.mjs b/module/applications/sheets/personnage-sheet.mjs index 1bd89e3..112c836 100644 --- a/module/applications/sheets/personnage-sheet.mjs +++ b/module/applications/sheets/personnage-sheet.mjs @@ -21,6 +21,7 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet { modifyResistance: HamalronPersonnageSheet.#onModifyResistance, discardCard: HamalronPersonnageSheet.#onDiscardCard, rollCompetence: HamalronPersonnageSheet.#onRollCompetence, + castSortilege: HamalronPersonnageSheet.#onCastSortilege, drawCard: HamalronPersonnageSheet.#onDrawCard, selectCard: HamalronPersonnageSheet.#onSelectCard, discardAndDraw: HamalronPersonnageSheet.#onDiscardAndDraw, @@ -345,6 +346,17 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet { } } + static async #onCastSortilege(event, target) { + const itemId = $(target).data("item-id") + const item = this.document.items.get(itemId) + if (!item || item.type !== "sortilege") { + console.warn(`HamalronPersonnageSheet: Sortilege with ID ${itemId} not found`) + return + } + const { default: HamalronSortilegeCasting } = await import("../sortilege-casting.mjs") + await HamalronSortilegeCasting.prompt(item, this.document) + } + static async #onRollCompetence(event, target) { const itemId = $(target).data("item-id") const item = this.document.items.get(itemId) diff --git a/module/applications/sheets/sortilege-sheet.mjs b/module/applications/sheets/sortilege-sheet.mjs index 0a7941a..6421ff3 100644 --- a/module/applications/sheets/sortilege-sheet.mjs +++ b/module/applications/sheets/sortilege-sheet.mjs @@ -23,7 +23,9 @@ export default class HamalronSortilegeSheet extends HamalronItemSheet { async _prepareContext() { const context = await super._prepareContext() context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) - + context.enrichedEffetAmateur = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.effetAmateur, { async: true }) + context.enrichedEffetCompetent = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.effetCompetent, { async: true }) + context.enrichedEffetExpert = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.effetExpert, { async: true }) return context } } diff --git a/module/applications/sortilege-casting.mjs b/module/applications/sortilege-casting.mjs new file mode 100644 index 0000000..7454104 --- /dev/null +++ b/module/applications/sortilege-casting.mjs @@ -0,0 +1,290 @@ +import { SYSTEM } from "../config/system.mjs" +import HamalronUtils from "../utils.mjs" + +export default class HamalronSortilegeCasting { + static CHAT_TEMPLATE = "systems/fvtt-hamalron/templates/chat-sortilege.hbs" + static DIALOG_TEMPLATE = "systems/fvtt-hamalron/templates/dialog-sortilege-casting.hbs" + + static getModificateur(categorie, niveau) { + const mods = SYSTEM.SORTILEGE_MODIFICATEURS[niveau] + return mods?.[categorie] ?? 0 + } + + static getRangMagie(actor) { + return actor.system.rangMagie || "initie" + } + + static getEchecMagique(valeurCarteMJ, rang) { + const rangs = ["ensorceleur", "initie", "thaumaturge"] + const idx = rangs.indexOf(rang) + if (idx === -1) return "normal" + const paliers = [ + { max: 10, resultats: ["normal", "normal", "normal"] }, + { max: 13, resultats: ["critique", "normal", "normal"] }, + { max: 16, resultats: ["critique", "normal", "normal"] }, + { max: 19, resultats: ["critique", "critique", "normal"] }, + { max: 23, resultats: ["critique", "critique", "critique"] }, + ] + for (const palier of paliers) { + if (valeurCarteMJ <= palier.max) { + return palier.resultats[idx] + } + } + return "critique" + } + + static async prompt(spellItem, actor) { + const atouts = actor.items.filter(i => i.type === "tarot" && i.system.type === "atout") + const rang = HamalronSortilegeCasting.getRangMagie(actor) + const peutUtiliserCoupe = rang === "thaumaturge" + const cartesCoupe = peutUtiliserCoupe + ? actor.items.filter(i => i.type === "tarot" && i.system.symbole === "coupe" && i.system.type !== "atout") + : [] + + if (atouts.length === 0) { + ui.notifications.warn(game.i18n.localize("HAMALRON.Sortilege.noAtout")) + return + } + + const niveauData = SYSTEM.NIVEAU_COMPETENCES[spellItem.system.niveauRequis] + const niveau = niveauData?.id || spellItem.system.niveauRequis + const modificateur = HamalronSortilegeCasting.getModificateur(spellItem.system.categorie, niveau) + + const categorieLabel = SYSTEM.SORTILEGE_CATEGORIES[spellItem.system.categorie]?.label || spellItem.system.categorie + const niveauLabel = niveauData?.name || spellItem.system.niveauRequis + const dialogContext = { + spell: spellItem, + actorName: actor.name, + actorImage: actor.img, + rang: rang, + rangLabel: SYSTEM.RANG_MAGICIEN[rang]?.label || rang, + categorieLabel, + niveauLabel, + modificateur: modificateur >= 0 ? `+${modificateur}` : modificateur, + peutUtiliserCoupe, + atouts: atouts.map(c => ({ + id: c.id, + name: c.name, + img: c.img, + valeur: c.system.valeur, + valeurNumerique: HamalronSortilegeCasting.#valeurNumerique(c.system.valeur), + })), + cartesCoupe: cartesCoupe.map(c => ({ + id: c.id, + name: c.name, + img: c.img, + valeur: c.system.valeur, + valeurNumerique: HamalronSortilegeCasting.#valeurNumerique(c.system.valeur), + })), + } + + const content = await foundry.applications.handlebars.renderTemplate( + HamalronSortilegeCasting.DIALOG_TEMPLATE, dialogContext + ) + + const result = await foundry.applications.api.DialogV2.wait({ + window: { title: `${game.i18n.localize("HAMALRON.Sortilege.cast")}: ${spellItem.name}` }, + classes: ["fvtt-hamalron"], + position: { width: 520 }, + content, + buttons: [ + { + action: "cancel", + label: game.i18n.localize("Cancel"), + default: false, + }, + { + action: "cast", + label: game.i18n.localize("HAMALRON.Sortilege.cast"), + default: true, + disabled: true, + callback: (event, button, dialog) => { + const form = button.form.elements + const carteMJ = Number(form["carte-mj"].value) || 0 + const selectedAtouts = Array.from(form.querySelectorAll('input[name="atout"]:checked')) + .map(el => atouts.find(c => c.id === el.value)) + .filter(Boolean) + const selectedCoupe = Array.from(form.querySelectorAll('input[name="coupe"]:checked')) + .map(el => cartesCoupe.find(c => c.id === el.value)) + .filter(Boolean) + return { carteMJ, selectedAtouts, selectedCoupe } + }, + }, + ], + actions: {}, + rejectClose: false, + render: (event, dialog) => { + const calcTotal = () => { + const carteMJ = Number(document.getElementById("carte-mj")?.value || 0) + const atoutTotal = Array.from(document.querySelectorAll('input[name="atout"]:checked')) + .reduce((sum, el) => sum + (Number(el.dataset.value) || 0), 0) + const coupeTotal = Array.from(document.querySelectorAll('input[name="coupe"]:checked')) + .reduce((sum, el) => sum + (Number(el.dataset.value) || 0), 0) + const total = atoutTotal + coupeTotal + const difficulte = carteMJ + modificateur + document.getElementById("total-atouts").textContent = String(atoutTotal) + document.getElementById("total-coupe").textContent = String(coupeTotal) + document.getElementById("total-joueur").textContent = String(total) + document.getElementById("difficulte-totale").textContent = String(difficulte) + const castBtn = document.querySelector("button[data-action='cast']") + const peutLancer = atoutTotal > 0 && carteMJ > 0 + castBtn.disabled = !peutLancer + } + + document.querySelectorAll('input[name="atout"], input[name="coupe"], #carte-mj') + .forEach(el => el.addEventListener("change", calcTotal)) + + document.getElementById("draw-card-btn")?.addEventListener("click", async () => { + const module = await import("./tarot-deck-manager.mjs") + const HamalronTarotDeckManager = module.default + if (!HamalronTarotDeckManager._instance) { + HamalronTarotDeckManager._instance = new HamalronTarotDeckManager() + } + const cards = HamalronTarotDeckManager._instance.drawCards(1) + if (cards.length > 0) { + const valeurData = SYSTEM.TAROT_VALEURS[cards[0].valeur] + const value = valeurData?.value || 0 + document.getElementById("carte-mj").value = String(value) + document.getElementById("carte-mj-nom").textContent = `${cards[0].name} (${value})` + calcTotal() + } + }) + + calcTotal() + }, + }) + + if (!result) return + if (result.carteMJ === 0 || result.selectedAtouts.length === 0) return + + const totalAtouts = result.selectedAtouts.reduce((sum, c) => { + return sum + (HamalronSortilegeCasting.#valeurNumerique(c.system.valeur) || 0) + }, 0) + const totalCoupe = result.selectedCoupe.reduce((sum, c) => { + return sum + (HamalronSortilegeCasting.#valeurNumerique(c.system.valeur) || 0) + }, 0) + const totalJoueur = totalAtouts + totalCoupe + const difficulte = result.carteMJ + modificateur + const isSuccess = totalJoueur >= difficulte + + const deckModule = await import("./tarot-deck-manager.mjs") + const HamalronTarotDeckManager = deckModule.default + if (!HamalronTarotDeckManager._instance) { + HamalronTarotDeckManager._instance = new HamalronTarotDeckManager() + } + const deckManager = HamalronTarotDeckManager._instance + + if (!isSuccess) { + const echecType = HamalronSortilegeCasting.getEchecMagique(result.carteMJ, rang) + const nbCartesADefausser = Math.max(1, result.selectedAtouts.length) + + for (let i = 0; i < nbCartesADefausser && i < result.selectedAtouts.length; i++) { + const cardToDiscard = result.selectedAtouts[i] + deckManager.addToDiscard({ + id: cardToDiscard.id, + name: cardToDiscard.name, + img: cardToDiscard.img, + symbole: cardToDiscard.system.symbole, + valeur: cardToDiscard.system.valeur, + type: cardToDiscard.system.type, + }) + const cardItem = actor.items.get(cardToDiscard.id) + if (cardItem) { + await actor.deleteEmbeddedDocuments("Item", [cardItem.id]) + } + } + + const chatDataFail = { + cssClass: [SYSTEM.id, "sortilege-roll"].join(" "), + isSuccess: false, + isNormal: echecType === "normal", + isCritique: echecType === "critique", + actingCharImg: actor.img, + actingCharName: actor.name, + spell: spellItem, + categorieLabel, + niveauLabel, + atoutsUtilises: result.selectedAtouts, + cartesCoupeUtilisees: result.selectedCoupe, + carteMJ: result.carteMJ, + modificateur, + difficulte, + totalJoueur, + } + const failContent = await foundry.applications.handlebars.renderTemplate( + HamalronSortilegeCasting.CHAT_TEMPLATE, chatDataFail + ) + await ChatMessage.create({ + user: game.user.id, + speaker: ChatMessage.getSpeaker({ actor }), + content: failContent, + type: CONST.CHAT_MESSAGE_TYPES.OTHER, + }) + + await deckManager.saveDeckState() + deckManager.render() + return + } + + for (const card of [...result.selectedAtouts, ...result.selectedCoupe]) { + deckManager.addToDiscard({ + id: card.id, + name: card.name, + img: card.img, + symbole: card.system.symbole, + valeur: card.system.valeur, + type: card.system.type, + }) + const cardItem = actor.items.get(card.id) + if (cardItem) { + await actor.deleteEmbeddedDocuments("Item", [card.id]) + } + } + + const nbCartesAPiocher = result.selectedAtouts.length + result.selectedCoupe.length + for (let i = 0; i < nbCartesAPiocher; i++) { + if (deckManager.deck.length > 0) { + const drawn = deckManager.drawCards(1) + if (drawn.length > 0) { + const originalItem = await HamalronUtils.findTarotItem(drawn[0]) + if (originalItem) { + await actor.createEmbeddedDocuments("Item", [originalItem.toObject()]) + } + } + } + } + + const chatDataSuccess = { + cssClass: [SYSTEM.id, "sortilege-roll"].join(" "), + isSuccess: true, + actingCharImg: actor.img, + actingCharName: actor.name, + spell: spellItem, + categorieLabel, + niveauLabel, + atoutsUtilises: result.selectedAtouts, + cartesCoupeUtilisees: result.selectedCoupe, + carteMJ: result.carteMJ, + modificateur, + difficulte, + totalJoueur, + } + const chatContent = await foundry.applications.handlebars.renderTemplate( + HamalronSortilegeCasting.CHAT_TEMPLATE, chatDataSuccess + ) + await ChatMessage.create({ + user: game.user.id, + speaker: ChatMessage.getSpeaker({ actor }), + content: chatContent, + type: CONST.CHAT_MESSAGE_TYPES.OTHER, + }) + + await deckManager.saveDeckState() + deckManager.render() + } + + static #valeurNumerique(valeur) { + const data = SYSTEM.TAROT_VALEURS[valeur] + return data?.value ?? (Number.parseInt(valeur) || 0) + } +} diff --git a/module/config/system.mjs b/module/config/system.mjs index 2414667..6f072e1 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -80,8 +80,21 @@ export const ENEMY_TYPES = { } export const SORTILEGE_CATEGORIES = { - "malefica": { id: "malefica", label: "Maléfica" }, - "ritual": { id: "ritual", label: "Rituel" }, + "domestique": { id: "domestique", label: "Domestique" }, + "specialise": { id: "specialise", label: "Spécialisé" }, + "miraculeux": { id: "miraculeux", label: "Miraculeux" }, +} + +export const SORTILEGE_MODIFICATEURS = { + amateur: { domestique: 2, specialise: 6, miraculeux: 9 }, + competent: { domestique: 0, specialise: 4, miraculeux: 7 }, + expert: { domestique: -2, specialise: 2, miraculeux: 5 }, +} + +export const RANG_MAGICIEN = { + ensorceleur: { id: "ensorceleur", label: "Ensorceleur" }, + initie: { id: "initie", label: "Initié" }, + thaumaturge: { id: "thaumaturge", label: "Thaumaturge" }, } export const NIVEAU_COMPETENCES = { @@ -141,6 +154,8 @@ export const SYSTEM = { COMPETENCE_TYPES: COMPETENCE_TYPES, ENEMY_TYPES: ENEMY_TYPES, SORTILEGE_CATEGORIES: SORTILEGE_CATEGORIES, + SORTILEGE_MODIFICATEURS: SORTILEGE_MODIFICATEURS, + RANG_MAGICIEN: RANG_MAGICIEN, NIVEAU_COMPETENCES: NIVEAU_COMPETENCES, CHOICE_ADVANTAGES_DISADVANTAGES, ASCII diff --git a/module/models/personnage.mjs b/module/models/personnage.mjs index 43078d3..93c09db 100644 --- a/module/models/personnage.mjs +++ b/module/models/personnage.mjs @@ -34,6 +34,7 @@ export default class HamalronPersonnage extends foundry.abstract.TypeDataModel { schema.historial = new fields.HTMLField({ required: true, textSearch: true }) schema.progression = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) + schema.rangMagie = new fields.StringField({ required: true, initial: "initie", choices: Object.fromEntries(Object.entries(SYSTEM.RANG_MAGICIEN).map(([key, val]) => [key, val.label])) }) schema.biodata = new fields.SchemaField({ age: new fields.StringField({ required: true, nullable: false, initial: "" }), diff --git a/module/models/sortilege.mjs b/module/models/sortilege.mjs index d660e85..7fa8475 100644 --- a/module/models/sortilege.mjs +++ b/module/models/sortilege.mjs @@ -4,15 +4,20 @@ export default class HamalronSortilege extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields const schema = {} - const requiredInteger = { required: true, nullable: false, integer: true } schema.description = new fields.HTMLField({ required: true, textSearch: true }) - - schema.categorie = new fields.StringField({ required: true, initial: "malefica", choices: Object.fromEntries(Object.entries(SYSTEM.SORTILEGE_CATEGORIES).map(([key, val]) => [key, val.label])) }) + schema.categorie = new fields.StringField({ required: true, initial: "domestique", choices: Object.fromEntries(Object.entries(SYSTEM.SORTILEGE_CATEGORIES).map(([key, val]) => [key, val.label])) }) + schema.niveauRequis = new fields.StringField({ required: true, initial: "amateur", choices: Object.fromEntries(Object.entries(SYSTEM.NIVEAU_COMPETENCES).map(([key, val]) => [key, val.name])) }) + schema.portee = new fields.StringField({ required: false, initial: "" }) + schema.duree = new fields.StringField({ required: false, initial: "" }) + schema.conditions = new fields.StringField({ required: false, initial: "" }) + schema.effetAmateur = new fields.HTMLField({ required: false, textSearch: true }) + schema.effetCompetent = new fields.HTMLField({ required: false, textSearch: true }) + schema.effetExpert = new fields.HTMLField({ required: false, textSearch: true }) + schema.concentration = new fields.BooleanField({ required: true, initial: false }) return schema } /** @override */ static LOCALIZATION_PREFIXES = ["HAMALRON.Sortilege"] - } diff --git a/templates/chat-sortilege.hbs b/templates/chat-sortilege.hbs new file mode 100644 index 0000000..8241c6d --- /dev/null +++ b/templates/chat-sortilege.hbs @@ -0,0 +1,55 @@ +
+
+ +
+

{{spell.name}}

+ {{categorieLabel}} · {{niveauLabel}} +
+
+ +
+

{{localize "HAMALRON.Sortilege.atoutsUsed"}}

+
+ {{#each atoutsUtilises}} +
+ + {{this.name}} +
+ {{/each}} +
+ {{#if cartesCoupeUtilisees.length}} +

{{localize "HAMALRON.Sortilege.coupeUsed"}}

+
+ {{#each cartesCoupeUtilisees}} +
+ + {{this.name}} +
+ {{/each}} +
+ {{/if}} +
+ +
+
+ {{localize "HAMALRON.Sortilege.playerTotal"}} + {{totalJoueur}} +
+
+ {{localize "HAMALRON.Sortilege.totalDifficulty"}} + {{difficulte}} (carte {{carteMJ}} + {{modificateur}}) +
+
+
+ + {{#if isSuccess}} + {{localize "HAMALRON.Label.success"}} + {{else if isCritique}} + {{localize "HAMALRON.Sortilege.failureCritical"}} + {{else}} + {{localize "HAMALRON.Sortilege.failureNormal"}} + {{/if}} + +
+
+
diff --git a/templates/dialog-sortilege-casting.hbs b/templates/dialog-sortilege-casting.hbs new file mode 100644 index 0000000..8049736 --- /dev/null +++ b/templates/dialog-sortilege-casting.hbs @@ -0,0 +1,84 @@ +
+
+ {{actorName}} +
+

{{spell.name}}

+ {{categorieLabel}} · {{niveauLabel}} + {{localize "HAMALRON.Sortilege.rang"}} : {{rangLabel}} +
+
+ +
+ {{localize "HAMALRON.Sortilege.difficulty"}} +
+ +
+
+ + - +
+
+ + +
+
+ + {{modificateur}} +
+
+ + 0 +
+
+ +
+ {{localize "HAMALRON.Sortilege.selectAtouts"}} +

{{localize "HAMALRON.Sortilege.atoutHint"}}

+
+ {{#each atouts}} + + {{else}} +

{{localize "HAMALRON.Sortilege.noAtout"}}

+ {{/each}} +
+
+ + 0 +
+
+ + {{#if peutUtiliserCoupe}} +
+ {{localize "HAMALRON.Sortilege.selectCoupe"}} +

{{localize "HAMALRON.Sortilege.coupeHint"}}

+
+ {{#each cartesCoupe}} + + {{else}} +

{{localize "HAMALRON.Sortilege.noCoupe"}}

+ {{/each}} +
+
+ + 0 +
+
+ {{/if}} + +
+ {{localize "HAMALRON.Sortilege.total"}} +
+ {{localize "HAMALRON.Sortilege.playerTotal"}} : 0 +
+
+
diff --git a/templates/personnage-sortileges.hbs b/templates/personnage-sortileges.hbs index ca9f60c..8978a90 100644 --- a/templates/personnage-sortileges.hbs +++ b/templates/personnage-sortileges.hbs @@ -36,8 +36,17 @@ {{upperFirst item.system.categorie }} + {{upperFirst + item.system.niveauRequis + }}
+
+ {{localize "HAMALRON.Label.information"}} {{formField systemFields.categorie value=system.categorie localize=true}} + {{formField systemFields.niveauRequis value=system.niveauRequis localize=true}} + {{formField systemFields.concentration value=system.concentration localize=true}} + {{formField systemFields.portee value=system.portee localize=true}} + {{formField systemFields.duree value=system.duree localize=true}} + {{formField systemFields.conditions value=system.conditions localize=true}}
@@ -25,4 +31,34 @@ }}
- \ No newline at end of file +
+ {{localize "HAMALRON.Label.effects"}} + + + {{formInput + systemFields.effetAmateur + enriched=enrichedEffetAmateur + value=system.effetAmateur + name="system.effetAmateur" + toggled=true + }} + + + {{formInput + systemFields.effetCompetent + enriched=enrichedEffetCompetent + value=system.effetCompetent + name="system.effetCompetent" + toggled=true + }} + + + {{formInput + systemFields.effetExpert + enriched=enrichedEffetExpert + value=system.effetExpert + name="system.effetExpert" + toggled=true + }} +
+