Compare commits

..

12 Commits

Author SHA1 Message Date
3359492f13 v0.5 fixes 2022-07-23 18:34:17 +02:00
676e6739a6 Merge pull request 'Fix import' (#545) from VincentVk/foundryvtt-reve-de-dragon:v1.5 into v1.5
Reviewed-on: #545
2022-07-23 18:33:32 +02:00
Vincent Vandemeulebrouck
872d3fff31 Fix import 2022-07-23 16:48:49 +02:00
9c71827baa Add Blurette 2022-07-22 22:45:41 +02:00
fc9ef06e7b Merge pull request 'Support des blurettes' (#544) from VincentVk/foundryvtt-reve-de-dragon:v1.5 into v1.5
Reviewed-on: #544
2022-07-22 22:44:49 +02:00
Vincent Vandemeulebrouck
9e63706de6 Support des blurettes
On peut définir Blurette comme type d'entité.
Pas de jet poour s'accorder aux blurettes.
2022-07-22 21:38:20 +02:00
3958b1bdc2 Add Vincent VK fixes 2022-07-22 10:46:39 +02:00
6d6843223b Merge pull request 'Petits fixes et petits conforts' (#543) from VincentVk/foundryvtt-reve-de-dragon:v1.5 into v1.5
Reviewed-on: #543
2022-07-22 10:45:44 +02:00
Vincent Vandemeulebrouck
46f5cb67f6 Créer un acteur depuis /nom 2022-07-22 01:34:15 +02:00
Vincent Vandemeulebrouck
d51243d74f Fix Bouton "prendre"
Le bouton devenait "Acheter" car le prix après la première prise était
récupéré sous forme de string (et le template fait une comparaison de
nombre)
2022-07-22 01:01:46 +02:00
Vincent Vandemeulebrouck
34cc671f12 Fix init Autre action 2022-07-22 00:36:16 +02:00
Vincent Vandemeulebrouck
16ce6a58dd Fix accorder entite de cauchemar
A priori vieille régression, pas vue depuis.

attaquant._id est devenu attaquant.id
2022-07-22 00:31:27 +02:00
10 changed files with 91 additions and 56 deletions

View File

@@ -33,7 +33,8 @@ import { RollDataAjustements } from "./rolldata-ajustements.js";
import { DialogItemAchat } from "./dialog-item-achat.js"; import { DialogItemAchat } from "./dialog-item-achat.js";
import { RdDItem } from "./item.js"; import { RdDItem } from "./item.js";
import { RdDPossession } from "./rdd-possession.js"; import { RdDPossession } from "./rdd-possession.js";
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
/** /**
@@ -98,7 +99,6 @@ export class RdDActor extends Actor {
* @param {Object} options (Unused) Additional options which customize the creation workflow. * @param {Object} options (Unused) Additional options which customize the creation workflow.
* *
*/ */
static async create(actorData, options) { static async create(actorData, options) {
// Case of compendium global import // Case of compendium global import
if (actorData instanceof Array) { if (actorData instanceof Array) {
@@ -135,13 +135,6 @@ export class RdDActor extends Actor {
this.encTotal = 0; this.encTotal = 0;
this.prixTotalEquipement = 0; this.prixTotalEquipement = 0;
/*
// Auto-resize token
if (this.isToken) {
let tokenSize = actorData.data.carac.taille.value/10;
this.token.update({height: tokenSize, width: tokenSize } );
}*/
// Make separate methods for each Actor type (character, npc, etc.) to keep // Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized. // things organized.
if (actorData.type === 'personnage') this._prepareCharacterData(actorData); if (actorData.type === 'personnage') this._prepareCharacterData(actorData);
@@ -247,7 +240,7 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getForce() { getForce() {
if (this.isEntiteCauchemar()) { if (this.isEntite()) {
return Misc.toInt(Misc.templateData(this).carac.reve?.value); return Misc.toInt(Misc.templateData(this).carac.reve?.value);
} }
return Misc.toInt(Misc.templateData(this).carac.force?.value); return Misc.toInt(Misc.templateData(this).carac.force?.value);
@@ -620,7 +613,10 @@ export class RdDActor extends Actor {
content: "Remise à neuf de " + this.name content: "Remise à neuf de " + this.name
}; };
const actorData = Misc.data(this); const actorData = Misc.data(this);
if (this.isEntiteCauchemar()) { if (this.isEntite([ENTITE_NONINCARNE])) {
return;
}
if (this.isEntite([ENTITE_INCARNE, ENTITE_BLURETTE])) {
await this.santeIncDec("endurance", actorData.data.sante.endurance.max - actorData.data.sante.endurance.value); await this.santeIncDec("endurance", actorData.data.sante.endurance.max - actorData.data.sante.endurance.value);
} }
else { else {
@@ -1630,7 +1626,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async setSonne(sonne = true) { async setSonne(sonne = true) {
if (this.isEntiteCauchemar()) { if (this.isEntite()) {
return; return;
} }
if (!game.combat && sonne) { if (!game.combat && sonne) {
@@ -1642,7 +1638,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getSConst() { getSConst() {
if (this.isEntiteCauchemar()) { if (this.isEntite()) {
return 0; return 0;
} }
return RdDCarac.calculSConst(Misc.templateData(this).carac.constitution.value); return RdDCarac.calculSConst(Misc.templateData(this).carac.constitution.value);
@@ -1759,7 +1755,7 @@ export class RdDActor extends Actor {
result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max)); result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max));
//console.log("New value ", inc, minValue, result.newValue); //console.log("New value ", inc, minValue, result.newValue);
let fatigue = 0; let fatigue = 0;
if (name == "endurance" && !this.isEntiteCauchemar()) { if (name == "endurance" && !this.isEntite()) {
if (result.newValue == 0 && inc < 0 && !isCritique) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie if (result.newValue == 0 && inc < 0 && !isCritique) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie
sante.vie.value--; sante.vie.value--;
result.perteVie = true; result.perteVie = true;
@@ -1796,7 +1792,7 @@ export class RdDActor extends Actor {
} }
isDead() { isDead() {
return !this.isEntiteCauchemar() && Misc.templateData(this).sante.vie.value < -this.getSConst() return !this.isEntite() && Misc.templateData(this).sante.vie.value < -this.getSConst()
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -3355,7 +3351,7 @@ export class RdDActor extends Actor {
let encaissement = await this.jetEncaissement(rollData); let encaissement = await this.jetEncaissement(rollData);
this.ajouterBlessure(encaissement); // Will upate the result table this.ajouterBlessure(encaissement); // Will upate the result table
const perteVie = this.isEntiteCauchemar() const perteVie = this.isEntite()
? { newValue: 0 } ? { newValue: 0 }
: await this.santeIncDec("vie", - encaissement.vie); : await this.santeIncDec("vie", - encaissement.vie);
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, encaissement.critiques > 0); const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, encaissement.critiques > 0);
@@ -3370,7 +3366,7 @@ export class RdDActor extends Actor {
sonne: perteEndurance.sonne, sonne: perteEndurance.sonne,
jetEndurance: perteEndurance.jetEndurance, jetEndurance: perteEndurance.jetEndurance,
endurance: santeOrig.endurance.value - perteEndurance.newValue, endurance: santeOrig.endurance.value - perteEndurance.newValue,
vie: this.isEntiteCauchemar() ? 0 : (santeOrig.vie.value - perteVie.newValue), vie: this.isEntite() ? 0 : (santeOrig.vie.value - perteVie.newValue),
show: defenderRoll?.show ?? {} show: defenderRoll?.show ?? {}
}); });
@@ -3560,8 +3556,8 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async accorder(entite, when = 'avant-encaissement') { async accorder(entite, when = 'avant-encaissement') {
if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar") if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
|| !entite.isEntiteCauchemar() || !entite.isEntite([ENTITE_INCARNE])
|| entite.isEntiteCauchemarAccordee(this)) { || entite.isEntiteAccordee(this)) {
return true; return true;
} }
const tplData = Misc.templateData(this); const tplData = Misc.templateData(this);
@@ -3585,29 +3581,30 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
isEntiteCauchemar() { isEntite(typeentite = [] ) {
return this.data.type == 'entite'; return this.data.type == 'entite' && (typeentite.length == 0 || typeentite.includes(this.data.data.typeentite));
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
isEntiteCauchemarAccordee(attaquant) { isEntiteAccordee(attaquant) {
if (!this.isEntiteCauchemar()) { return true; } if (!this.isEntite([ENTITE_INCARNE]))
{ return true; }
let resonnance = Misc.templateData(this).sante.resonnance; let resonnance = Misc.templateData(this).sante.resonnance;
return (resonnance.actors.find(it => it == attaquant._id)); return (resonnance.actors.find(it => it == attaquant.id));
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async setEntiteReveAccordee(attaquant) { async setEntiteReveAccordee(attaquant) {
if (!this.isEntiteCauchemar()) { if (!this.isEntite([ENTITE_INCARNE])) {
ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entite de cauchemer/rêve"); ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entite de cauchemer/rêve");
return; return;
} }
let resonnance = duplicate(Misc.templateData(this).sante.resonnance); let resonnance = duplicate(Misc.templateData(this).sante.resonnance);
if (resonnance.actors.find(it => it == attaquant._id)) { if (resonnance.actors.find(it => it == attaquant.id)) {
// déjà accordé // déjà accordé
return; return;
} }
resonnance.actors.push(attaquant._id); resonnance.actors.push(attaquant.id);
await this.update({ "data.sante.resonnance": resonnance }); await this.update({ "data.sante.resonnance": resonnance });
return; return;
} }
@@ -4161,7 +4158,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async setStatusEffect(label, status, updates = {}) { async setStatusEffect(label, status, updates = {}) {
if (this.isEntiteCauchemar() || this.data.type == 'vehicule') { if (this.isEntite() || this.data.type == 'vehicule') {
return; return;
} }
console.log("setStatusEffect", label, status, updates) console.log("setStatusEffect", label, status, updates)

View File

@@ -3,3 +3,7 @@ export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon';
export const HIDE_DICE = 'hide'; export const HIDE_DICE = 'hide';
export const SHOW_DICE = 'show'; export const SHOW_DICE = 'show';
export const ENTITE_INCARNE = 'incarne';
export const ENTITE_NONINCARNE = 'nonincarne';
export const ENTITE_BLURETTE = 'blurette';

View File

@@ -55,7 +55,7 @@ export class DialogItemAchat extends Dialog {
static prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur) { static prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur) {
const jsondata = buttonAcheter.attributes['data-jsondata']?.value; const jsondata = buttonAcheter.attributes['data-jsondata']?.value;
const prixLot = buttonAcheter.attributes['data-prixLot']?.value ?? 0; const prixLot = parseInt(buttonAcheter.attributes['data-prixLot']?.value ?? 0);
let venteData = { let venteData = {
item: JSON.parse(jsondata), item: JSON.parse(jsondata),
vendeurId: vendeurId, vendeurId: vendeurId,

View File

@@ -1,5 +1,5 @@
import { ChatUtility } from "./chat-utility.js"; import { ChatUtility } from "./chat-utility.js";
import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { RdDItemArme } from "./item-arme.js"; import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemCompetence } from "./item-competence.js";
@@ -320,7 +320,7 @@ export class RdDCombatManager extends Combat {
initOffset = 10; initOffset = 10;
caracForInit = combatant.actor.getReveActuel(); caracForInit = combatant.actor.getReveActuel();
initInfo = "Possession" initInfo = "Possession"
} else if (action.name == 'autre') { } else if (action.action == 'autre') {
initOffset = 2; initOffset = 2;
initInfo = "Autre Action" initInfo = "Autre Action"
} else if (action.action == 'haut-reve') { } else if (action.action == 'haut-reve') {
@@ -457,7 +457,7 @@ export class RdDCombat {
else { else {
const defender = target?.actor; const defender = target?.actor;
const defenderTokenId = target?.data._id; const defenderTokenId = target?.data._id;
if ( defender.type == 'entite' && defender.data.data.definition.typeentite == 'nonincarne') { if ( defender.type == 'entite' && defender.data.data.definition.typeentite == ENTITE_NONINCARNE) {
ui.notifications.warn("Vous ne pouvez pas cibler une entité non incarnée !!!!"); ui.notifications.warn("Vous ne pouvez pas cibler une entité non incarnée !!!!");
} else { } else {
return this.create(attacker, defender, defenderTokenId, target) return this.create(attacker, defender, defenderTokenId, target)
@@ -799,7 +799,7 @@ export class RdDCombat {
async _onAttaqueNormale(attackerRoll) { async _onAttaqueNormale(attackerRoll) {
console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll); console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll);
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar()); attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntite());
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
attackerRoll.show = { attackerRoll.show = {
cible: this.target ? this.defender.data.name : 'la cible', cible: this.target ? this.defender.data.name : 'la cible',
@@ -1249,8 +1249,8 @@ export class RdDCombat {
async accorderEntite(when = 'avant-encaissement') { async accorderEntite(when = 'avant-encaissement') {
if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar") if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
|| this.defender == undefined || this.defender == undefined
|| !this.defender.isEntiteCauchemar() || !this.defender.isEntite([ENTITE_INCARNE])
|| this.defender.isEntiteCauchemarAccordee(this.attacker)) { || this.defender.isEntiteAccordee(this.attacker)) {
return true; return true;
} }

View File

@@ -1,19 +1,29 @@
import { RdDActor } from "./actor.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js"; import { RdDDice } from "./rdd-dice.js";
const words = [ 'pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i', 'onse', 'iane', 'ane', 'zach', 'arri', 'ba', 'bo', 'bi', const words = ['pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i', 'onse', 'iane', 'ane', 'zach', 'arri', 'ba', 'bo', 'bi',
'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la', 'al' , 'pul', 'one', 'ner', 'nur', 'mac', 'mery', 'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la', 'al', 'pul', 'one', 'ner', 'nur', 'mac', 'mery',
'cat', 'do', 'di', 'der', 'er', 'el', 'far', 'fer', 'go', 'guer', 'hot', 'jor', 'jar', 'ji', 'kri', 'ket', 'lor', 'hur', 'cat', 'do', 'di', 'der', 'er', 'el', 'far', 'fer', 'go', 'guer', 'hot', 'jor', 'jar', 'ji', 'kri', 'ket', 'lor', 'hur',
'lar', 'lir', 'lu', 'pot', 'pro', 'pra', 'pit', 'qua', 'qui', 're', 'ral', 'sal', 'sen', 'ted', 'to', 'ta', 'lars', 'ver', 'lar', 'lir', 'lu', 'pot', 'pro', 'pra', 'pit', 'qua', 'qui', 're', 'ral', 'sal', 'sen', 'ted', 'to', 'ta', 'lars', 'ver',
'vin', 'ov', 'wal', 'ry', 'ly', '' ]; 'vin', 'ov', 'wal', 'ry', 'ly', ''];
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDNameGen { export class RdDNameGen {
static async getName( msg, params ) { static async getName(msg, params) {
let name = Misc.upperFirst( await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words) ) const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-command-nom.html`, {
//console.log(name); nom: Misc.upperFirst(await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words))
ChatMessage.create( { content: `Nom : ${name}`, whisper: ChatMessage.getWhisperRecipients("GM") } ); });
ChatMessage.create({ content: html, whisper: ChatMessage.getWhisperRecipients("GM") });
} }
static async onCreerActeur(event) {
const button = event.currentTarget;
await RdDActor.create({
name: button.attributes['data-nom'].value,
type: button.attributes['data-type'].value
},
{renderSheet: true});
}
} }

View File

@@ -1,3 +1,5 @@
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "./constants.js";
/** /**
* Extend the base Dialog entity by defining a custom window to perform roll. * Extend the base Dialog entity by defining a custom window to perform roll.
* @extends {Dialog} * @extends {Dialog}
@@ -7,15 +9,19 @@ export class RdDEncaisser extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
constructor(html, actor) { constructor(html, actor) {
// Common conf // Common conf
const buttonsCreatures = { let buttons = {};
"mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") }, if (!actor.isEntite()){
"non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") }, buttons = {
"sonne": { label: "Sonné", callback: html => this.actor.setSonne() }, "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
}; "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
const buttonsEntitesCauchemar = { "sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
"cauchemar": { label: "cauchemar", callback: html => this.performEncaisser("cauchemar") } };
}; }
const buttons = actor.isEntiteCauchemar() ? buttonsEntitesCauchemar : buttonsCreatures; else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])){
buttons = {
"cauchemar": { label: "cauchemar", callback: html => this.performEncaisser("cauchemar") }
}
}
let dialogConf = { let dialogConf = {
title: "Jet d'Encaissement", title: "Jet d'Encaissement",
@@ -24,7 +30,6 @@ export class RdDEncaisser extends Dialog {
default: "mortel" default: "mortel"
} }
let dialogOptions = { let dialogOptions = {
classes: ["rdddialog"], classes: ["rdddialog"],
width: 320, width: 320,

View File

@@ -11,6 +11,7 @@ import { RdDDice } from "./rdd-dice.js";
import { RdDItem } from "./item.js"; import { RdDItem } from "./item.js";
import { Monnaie } from "./item-monnaie.js"; import { Monnaie } from "./item-monnaie.js";
import { RdDPossession } from "./rdd-possession.js"; import { RdDPossession } from "./rdd-possession.js";
import { RdDNameGen } from "./rdd-namegen.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
// This table starts at 0 -> niveau -10 // This table starts at 0 -> niveau -10
@@ -704,6 +705,7 @@ export class RdDUtility {
// gestion bouton tchat Acheter // gestion bouton tchat Acheter
html.on("click", '.button-acheter', event => DialogItemAchat.onButtonAcheter(event)); html.on("click", '.button-acheter', event => DialogItemAchat.onButtonAcheter(event));
html.on("click", '.button-creer-acteur', event => RdDNameGen.onCreerActeur(event));
// Gestion du bouton payer // Gestion du bouton payer
html.on("click", '.payer-button', event => { html.on("click", '.payer-button', event => {

View File

@@ -29,7 +29,7 @@
"url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/", "url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/",
"license": "LICENSE.txt", "license": "LICENSE.txt",
"flags": {}, "flags": {},
"version": "1.5.82", "version": "1.5.85",
"minimumCoreVersion": "0.8.0", "minimumCoreVersion": "0.8.0",
"compatibleCoreVersion": "9", "compatibleCoreVersion": "9",
"scripts": [], "scripts": [],
@@ -500,7 +500,7 @@
"dependencies": [], "dependencies": [],
"socket": true, "socket": true,
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v1.5/system.json", "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v1.5/system.json",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-1.5.82.zip", "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-1.5.85.zip",
"protected": false, "protected": false,
"gridDistance": 1, "gridDistance": 1,
"gridUnits": "m", "gridUnits": "m",

View File

@@ -65,6 +65,7 @@
{{#select data.definition.typeentite}} {{#select data.definition.typeentite}}
<option value="incarne">Incarnée</option> <option value="incarne">Incarnée</option>
<option value="nonincarne">Non Incarnée</option> <option value="nonincarne">Non Incarnée</option>
<option value="blurette">Blurete</option>
{{/select}} {{/select}}
</select> </select>
</li> </li>

View File

@@ -0,0 +1,16 @@
<h4>Proposition de nom: {{nom}}</h4>
<span class="chat-card-button-area">
<a class="button-creer-acteur chat-card-button"
data-nom='{{nom}}'
data-type='personnage'
>
Créer un Personnage</a>
</span>
<span class="chat-card-button-area">
<a class="button-creer-acteur chat-card-button"
data-nom='{{nom}}'
data-type='creature'>
Créer une créature</a>
</span>