diff --git a/module/actor.js b/module/actor.js
index a97b6bfe..e97805d8 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -194,7 +194,7 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
isHautRevant() {
- return Misc.templateData(this).attributs.hautrevant.value != ""
+ return this.isPersonnage() && Misc.templateData(this).attributs.hautrevant.value != ""
}
/* -------------------------------------------- */
getFatigueActuelle() {
@@ -1089,10 +1089,16 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
computeIsHautRevant() {
- const tplData = Misc.templateData(this);
- tplData.attributs.hautrevant.value = this.listItemsData('tete').find(it => Grammar.toLowerCaseNoAccent(it.name) == 'don de haut-reve')
- ? "Haut rêvant"
- : "";
+ if (this.isPersonnage()){
+ Misc.templateData(this).attributs.hautrevant.value = this.hasItemNamed('tete', 'don de haut-reve')
+ ? "Haut rêvant"
+ : "";
+ }
+ }
+
+ hasItemNamed(type, name) {
+ name = Grammar.toLowerCaseNoAccent(name);
+ return this.listItemsData(type).find(it => Grammar.toLowerCaseNoAccent(it.name) == name);
}
/* -------------------------------------------- */
diff --git a/module/dialog-create-signedraconique-actors.js b/module/dialog-create-signedraconique-actors.js
new file mode 100644
index 00000000..7a475949
--- /dev/null
+++ b/module/dialog-create-signedraconique-actors.js
@@ -0,0 +1,114 @@
+import { ChatUtility } from "./chat-utility.js";
+import { HtmlUtility } from "./html-utility.js";
+import { RdDItemSigneDraconique } from "./item-signedraconique.js";
+import { Misc } from "./misc.js";
+import { TMRType, TMRUtility } from "./tmr-utility.js";
+
+export class DialogCreateSigneDraconiqueForActors extends Dialog {
+
+ static async createSigneForActors() {
+ let dialogData = {
+ signe: {
+ name: 'Un signe draconique',
+ type: "signedraconique",
+ img: 'systems/foundryvtt-reve-de-dragon/icons/tmr/gift.webp',
+ data: {
+ typesTMR: DialogCreateSigneDraconiqueForActors.selectRandomTmrs(),
+ ephemere: true,
+ duree: "1 round",
+ difficulte: -5,
+ valeur: { norm: 10, sign: 10, part: 15 },
+ }
+ },
+ actors: game.actors.filter(actor => actor.isHautRevant()).map(it => duplicate(Misc.data(it)))
+ };
+ dialogData.tmrs = TMRUtility.listSelectedTMR(dialogData.signe.data.typesTMR ?? []);
+ dialogData.actors.forEach(it => it.selected = false);
+
+ const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique-actors.html", dialogData);
+ new DialogCreateSigneDraconiqueForActors(dialogData, html)
+ .render(true);
+
+ }
+
+ static selectRandomTmrs() {
+ let tmrs = Object.values(TMRType).map(value => Misc.upperFirst(value.name));
+ const nbTmr = tmrs.length;
+ let remove = Math.floor(Math.random() * (nbTmr - 1));
+ for (let i = nbTmr; i > remove; i--) {
+ tmrs.splice(Math.floor(Math.random() * i), 1);
+ }
+ return tmrs;
+ }
+
+ constructor(dialogData, html, callback) {
+ let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 650, 'z-index': 99999 };
+
+ let conf = {
+ title: "Créer un signe pour les personnages",
+ content: html,
+ default: "Créer le signe",
+ buttons: { "Créer le signe": { label: "Créer le signe", callback: it => { this._onCreerSigne(); } } }
+ };
+ super(conf, options);
+ this.dialogData = dialogData;
+ }
+
+ async _onCreerSigne() {
+ this.dialogData.actors.filter(it => it.selected).map(it => game.actors.get(it._id))
+ .forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
+ }
+
+ async _createSigneForActor(actor, signe) {
+ actor.createEmbeddedDocuments("Item", [signe]);
+ ChatMessage.create({
+ whisper: ChatUtility.getWhisperRecipientsAndGMs(Misc.data(actor).name),
+ content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", {
+ signe: signe,
+ alias: Misc.data(actor).name
+ })
+ });
+ }
+
+
+ /* -------------------------------------------- */
+ activateListeners(html) {
+ super.activateListeners(html);
+ this.setEphemere(this.dialogData.signe.data.ephemere);
+ html.find(".signe-name").change((event) => this.dialogData.signe.name = event.currentTarget.value);
+ html.find(".signe-data-ephemere").change((event) => this.setEphemere(event.currentTarget.checked));
+ html.find(".select-tmr").change((event) => this.onSelectTmr(event));
+ html.find(".select-actor").change((event) => this.onSelectActor(event));
+ html.find(".valeur-xp-sort").change((event) => this.onValeurXpSort(event));
+ }
+ async setEphemere(ephemere){
+ this.dialogData.signe.data.ephemere = ephemere;
+ HtmlUtility._showControlWhen($(".signe-data-duree"), ephemere);
+ }
+
+ async onSelectTmr(event) {
+ event.preventDefault();
+ this.dialogData.signe.data.typesTMR = $(".select-tmr").val();
+ }
+
+ async onSelectActor(event) {
+ event.preventDefault();
+ let selectActor = $(".select-actor");
+ const options = event.currentTarget.options;
+ for (var i = 0; i < options.length; i++) { // looping over the options
+ const actorId = options[i].attributes["data-actor-id"].value;
+ const actor = this.dialogData.actors.find(it => it._id == actorId);
+ if (actor) {
+ actor.selected = options[i].selected;
+ }
+ };
+ }
+
+ onValeurXpSort(event) {
+ const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
+ const xp = Number(event.currentTarget.value);
+ const oldValeur = this.dialogData.signe.data.valeur;
+ this.dialogData.signe.data.valeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur);
+ }
+
+}
\ No newline at end of file
diff --git a/module/item-signedraconique-sheet.js b/module/item-signedraconique-sheet.js
index b597264d..703064be 100644
--- a/module/item-signedraconique-sheet.js
+++ b/module/item-signedraconique-sheet.js
@@ -1,5 +1,6 @@
+import { RdDItemSigneDraconique } from "./item-signedraconique.js";
import { Misc } from "./misc.js";
-import { TMRType } from "./tmr-utility.js";
+import { TMRType, TMRUtility } from "./tmr-utility.js";
/**
* Item sheet pour signes draconiques
@@ -48,16 +49,10 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
});
- formData.tmrs = RdDSigneDraconiqueItemSheet.listTMRTypes(formData.data.typesTMR ?? []);
+ formData.tmrs = TMRUtility.listSelectedTMR(formData.data.typesTMR ?? []);
return formData;
}
- static listTMRTypes(typesTMR) {
- return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
- .sort()
- .map(name => { return { name: name, selected: typesTMR.includes(name) } });
- }
-
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
@@ -75,28 +70,12 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
this.object.update({ 'data.typesTMR': selectedTMR });
}
- async onValeurXpSort(qualite, valeur) {
- let tplData = Misc.templateData(this.object);
- if (valeur != tplData.valeur[qualite])
- {
- await this.object.update({ [`data.valeur.${qualite}`]: valeur });
-
- tplData = Misc.templateData(this.object);
- switch (qualite) {
- case "norm":
- if (valeur > tplData.valeur.sign) await this.object.update({ 'data.valeur.sign': valeur });
- if (valeur > tplData.valeur.part) await this.object.update({ 'data.valeur.part': valeur });
- break;
- case "sign":
- if (valeur < tplData.valeur.norm) await this.object.update({ 'data.valeur.norm': valeur });
- if (valeur > tplData.valeur.part) await this.object.update({ 'data.valeur.part': valeur });
- break;
- case "part":
- if (valeur < tplData.valeur.norm) await this.object.update({ 'data.valeur.norm': valeur });
- if (valeur < tplData.valeur.sign) await this.object.update({ 'data.valeur.sign': valeur });
- break;
- }
- }
+ async onValeurXpSort(event) {
+ const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
+ const xp = Number(event.currentTarget.value);
+ const oldValeur = Misc.templateData(this.object).valeur;
+ const newValeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur);
+ await this.object.update({ 'data.valeur': newValeur });
}
/* -------------------------------------------- */
diff --git a/module/item-signedraconique.js b/module/item-signedraconique.js
index b2cad95c..e38e7b82 100644
--- a/module/item-signedraconique.js
+++ b/module/item-signedraconique.js
@@ -34,4 +34,27 @@ export class RdDItemSigneDraconique {
return Misc.data(signe).data.valeur[code] ?? 0;
}
+ static calculValeursXpSort(qualite, valeur, avant) {
+ switch (qualite) {
+ case "norm":
+ return {
+ norm: valeur,
+ sign: Math.max(valeur, avant.sign),
+ part: Math.max(valeur, avant.part)
+ }
+ case "sign":
+ return {
+ norm: Math.min(valeur, avant.norm),
+ sign: valeur,
+ part: Math.max(valeur, avant.part)
+ }
+ case "part":
+ return {
+ norm: Math.min(valeur, avant.norm),
+ sign: Math.min(valeur, avant.sign),
+ part: valeur
+ }
+ }
+ }
+
}
\ No newline at end of file
diff --git a/module/rdd-commands.js b/module/rdd-commands.js
index f8b44405..16bb4e7d 100644
--- a/module/rdd-commands.js
+++ b/module/rdd-commands.js
@@ -1,5 +1,6 @@
/* -------------------------------------------- */
+import { DialogCreateSigneDraconiqueForActors } from "./dialog-create-signedraconique-actors.js";
import { RdDItemCompetence } from "./item-competence.js";
import { Misc } from "./misc.js";
import { RdDCarac } from "./rdd-carac.js";
@@ -82,6 +83,17 @@ export class RdDCommands {
descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples:
/astro Lyre`
});
+
+ rddCommands.registerCommand({
+ path: ["/signe", "+"], func: (content, msg, params) => rddCommands.creerSignesDraconiques(),
+ descr: "Crée un signe draconique et l'ajoute aux haut-rêvants choisis."
+ });
+
+ rddCommands.registerCommand({
+ path: ["/signe", "-"], func: (content, msg, params) => rddCommands.supprimerSignesDraconiquesEphemeres(),
+ descr: "Supprime les signes draconiques éphémères"
+ });
+
game.system.rdd.commands = rddCommands;
}
}
@@ -312,5 +324,20 @@ export class RdDCommands {
}
}
+ async creerSignesDraconiques() {
+ DialogCreateSigneDraconiqueForActors.createSigneForActors();
+ return true;
+ }
+
+ async supprimerSignesDraconiquesEphemeres() {
+ game.actors.forEach(actor => {
+ const ephemeres = actor.filterItems(item => Misc.data(item).type = 'signedraconique' && Misc.data(item).data.ephemere)
+ .map(item => item.id);
+ if (ephemeres.length > 0) {
+ actor.deleteEmbeddedDocuments("Item", ephemeres);
+ }
+ });
+ return true;
+ }
}
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index a39c7135..ba46ca35 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -205,7 +205,8 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html',
- 'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html'
+ 'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html',
+ 'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html'
];
Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
diff --git a/module/tmr-utility.js b/module/tmr-utility.js
index 566d45a7..6d418776 100644
--- a/module/tmr-utility.js
+++ b/module/tmr-utility.js
@@ -346,6 +346,12 @@ export class TMRUtility {
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
}
+ static listSelectedTMR(typesTMR) {
+ return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
+ .sort()
+ .map(name => { return { name: name, selected: typesTMR.includes(name) } });
+ }
+
static isCaseHumide(tmr) {
return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
}
diff --git a/templates/chat-signe-draconique-actor.html b/templates/chat-signe-draconique-actor.html
new file mode 100644
index 00000000..f05b43fb
--- /dev/null
+++ b/templates/chat-signe-draconique-actor.html
@@ -0,0 +1,7 @@
+
Pour le lire ce signe draconique, rendez-vous dans les + Terres Médianes du Rêve et trouvez une case de résonnance. + {{#if signe.data.ephemere}}C'est un signe éphémère, qui ne restera présent que pour {{signe.data.duree}}{{/if}} +
diff --git a/templates/dialog-create-signedraconique-actors.html b/templates/dialog-create-signedraconique-actors.html new file mode 100644 index 00000000..9d4a6945 --- /dev/null +++ b/templates/dialog-create-signedraconique-actors.html @@ -0,0 +1,57 @@ + \ No newline at end of file diff --git a/templates/item-livre-sheet.html b/templates/item-livre-sheet.html index 8230103c..23f6345c 100644 --- a/templates/item-livre-sheet.html +++ b/templates/item-livre-sheet.html @@ -29,15 +29,15 @@