Compare commits

...

29 Commits

Author SHA1 Message Date
a7e1ca0b07 Merge pull request 'Version 12.0.15' (#715) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: public/foundryvtt-reve-de-dragon#715
2024-10-17 07:53:59 +02:00
e2c4d93413 Version 12.0.15 2024-10-17 02:08:03 +02:00
3888efc6aa Correction dés dice-so-nice 2024-10-17 02:07:24 +02:00
5004774a15 Rendu des tables de compendiums 2024-10-16 23:32:19 +02:00
226afc1680 Fix: tooltip augmentation compétences 2024-10-16 23:32:19 +02:00
582df7e290 Simplify ChatMessage whispers
Les messages dans les TMRs sont envoyés au GM

Simplification des messages de tchat liés à un actor: on peut
utiliser les Owners (car les GMs sont owner).

Au lieu de passer le name de l'Actor (qui peut être incorrect si deux
actors ont le même, mais pas les mêmes propriétaires), on passe
directement l'actor pour déterminer mles destinataires de messages
2024-10-16 23:32:18 +02:00
501f1f2e4f Fix: Messages de maladies non publics
Les messages de maladies sont uniquement pour les "owners"
(ce qui inclut les MJs)
2024-10-16 23:32:18 +02:00
90d46c6a78 Init settings before sheets
Eviter que le chargement d'acteurs ait lieu avant le chargement
des settings
2024-10-14 03:47:13 +02:00
174ef4256a Merge pull request 'v11' (#714) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: public/foundryvtt-reve-de-dragon#714
2024-10-11 17:42:24 +02:00
be132a9ff1 Gestion esquive feuille simplifiée 2024-10-11 01:30:43 +02:00
b2037a852c Pas de lien sur la ligne titre 2024-10-11 01:25:08 +02:00
2137a6c403 Version 12.0.14 2024-10-11 01:20:01 +02:00
99f5578c4f Armes sur la fiche de PNJ 2024-10-11 01:19:28 +02:00
a6ae7babbe Feuille PNJ suite 2024-10-11 01:19:27 +02:00
814266e649 Fix carac roll 2024-10-10 23:17:55 +02:00
080d05d2cd Merge pull request 'Version 12.0.2' (#713) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: public/foundryvtt-reve-de-dragon#713
2024-10-06 17:03:41 +02:00
f8f889e9f9 Jets de vie/endurance/rêve actuel 2024-10-05 15:13:29 +02:00
ad80802af6 Remove log 2024-10-05 14:40:14 +02:00
0f7b9baf51 Amélioration liste de compétences 2024-10-05 14:39:56 +02:00
b866c95ebd Correction de la protection 2024-10-05 12:57:02 +02:00
689e287ac7 Bouton d'export si mode avancé 2024-10-05 12:50:29 +02:00
40b0d7e6dc Jets de carac/compétences sur feuille encart 2024-10-05 12:41:28 +02:00
d439d73636 Version 12.0.12 2024-10-05 00:42:32 +02:00
e91eea532d Ajout feuille encart
Feuille de PNJ au format des encarts Scriptarium.
Aucune possibilité de jets de dés pour l'instant.
2024-10-05 00:42:27 +02:00
f116003d6f Fix: vente depuis les compendiums/Objets
On peut de nouveau vendre des items sans propriétaire,
depuis les compendiums ou depuis l'onglet des Objets
2024-10-05 00:39:50 +02:00
c3a44665c5 Load handlebars dans app-personnage-aleatoire 2024-10-05 00:39:50 +02:00
40b57517d8 Merge pull request '12.0.11' (#712) from VincentVk/foundryvtt-reve-de-dragon:v11 into v11
Reviewed-on: public/foundryvtt-reve-de-dragon#712
2024-10-02 07:37:42 +02:00
e04586ba44 Ajout de génération aléatoire de description
Ajout d'un bouton pour générer aléatoirement les éléments de description:

- nom (pour le MJ seul)
- sexe
- age
- main directrice
- cheveux, yeux
- heure de naissance
- taille et poids (selon la caractéristique Taille)
2024-10-02 00:46:11 +02:00
611acd4d44 Version 12.0.11 2024-10-01 02:07:42 +02:00
74 changed files with 1279 additions and 466 deletions

View File

@@ -1,4 +1,39 @@
# 12.0 # 12.0
## 12.0.15 - Le messager d'Astrobazzarh
- Correction des faces de dés personalisés dice-so-nice
- Les messages de maladies ne sont plus publics
- Les messages privés dans les TMR sont aussi envoyés au GM
- Les informations de compétences pouvant augmenter s'affichent comme tooltips
- Amélioration du rendu des tables de compendiums (commande /table)
## 12.0.14 - Les légions d'Astrobazzarh
- Feuille de PNJ:
- boutons standard (encaissement, ...)
- boutons pour ajuster les compteurs
- visualisation des blessures
- click sur blessure pour ajouter/enlever
- gestion des armes
## 12.0.13 - La Chance d'Astrobazzarh
- Fix: jets de caractéristiques
## 12.0.12 - L'étalage d'Astrobazzarh
- Fix: On peut de nouveau vendre des items sans propriétaire, depuis les compendiums ou depuis l'onglet des Objets
- Début de Feuille PNJ au format des encarts Scriptarium
- support des jets de caractéristiques
- support des jets de compétences
## 12.0.11 - Le scriptorium d'Astrobazzarh
- ajout d'un bouton pour générer les éléments de description d'un personnage
- ajout du logo en background dans la liste des systèmes Foundry
- ajout d'un champ pour le métier
- export scriptarium
- encodage de l'export en windows-1252
- export de l'esquive avec armure et sans armure
## 12.0.10 - Le scriptorium d'Astrobazzarh
- corrections de l'export scriptarium
## 12.0.9 - Le scriptorium d'Astrobazzarh ## 12.0.9 - Le scriptorium d'Astrobazzarh
- ajout d'une fonction avancée pour exporter les personnages dans un format csv - ajout d'une fonction avancée pour exporter les personnages dans un format csv

View File

@@ -9,7 +9,7 @@ export class DialogItemVente extends Dialog {
const venteData = { const venteData = {
item: item, item: item,
alias: item.actor?.name ?? game.user.name, alias: item.actor?.name ?? game.user.name,
vendeurId: item.actor.id, vendeurId: item.actor?.id,
prixOrigine: item.calculerPrixCommercant(), prixOrigine: item.calculerPrixCommercant(),
prixUnitaire: item.calculerPrixCommercant(), prixUnitaire: item.calculerPrixCommercant(),
prixLot: item.calculerPrixCommercant(), prixLot: item.calculerPrixCommercant(),

View File

@@ -17,6 +17,7 @@ import { RdDItemBlessure } from "./item/blessure.js";
import { RdDEmpoignade } from "./rdd-empoignade.js"; import { RdDEmpoignade } from "./rdd-empoignade.js";
import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js"; import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js"; import { RdDCoeur } from "./coeur/rdd-coeur.js";
import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
/** /**
@@ -127,7 +128,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.render(true); this.render(true);
}); });
this.html.find('.visu-tmr').click(async event => this.actor.displayTMR("visu")) this.html.find('.button-tmr-visu').click(async event => this.actor.displayTMR("visu"))
// Everything below here is only needed if the sheet is editable // Everything below here is only needed if the sheet is editable
if (!this.options.editable) return; if (!this.options.editable) return;
@@ -185,7 +186,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.item-equip').click(async event => this.actor.equiperObjet(RdDSheetUtility.getItemId(event))) this.html.find('.item-equip').click(async event => this.actor.equiperObjet(RdDSheetUtility.getItemId(event)))
this.html.find('.chance-actuelle').click(async event => this.actor.rollCarac('chance-actuelle')) this.html.find('.chance-actuelle').click(async event => this.actor.rollCarac('chance-actuelle'))
this.html.find('.chance-appel').click(async event => this.actor.rollAppelChance()) this.html.find('.button-appel-chance').click(async event => this.actor.rollAppelChance())
this.html.find('[name="jet-astrologie"]').click(async event => this.actor.astrologieNombresAstraux()) this.html.find('[name="jet-astrologie"]').click(async event => this.actor.astrologieNombresAstraux())
this.html.find('.tache-label a').click(async event => this.actor.rollTache(RdDSheetUtility.getItemId(event))) this.html.find('.tache-label a').click(async event => this.actor.rollTache(RdDSheetUtility.getItemId(event)))
@@ -198,6 +199,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.jeu-label a').click(async event => this.actor.rollJeu(RdDSheetUtility.getItemId(event))) this.html.find('.jeu-label a').click(async event => this.actor.rollJeu(RdDSheetUtility.getItemId(event)))
this.html.find('.recettecuisine-label a').click(async event => this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event))) this.html.find('.recettecuisine-label a').click(async event => this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event)))
this.html.find('.description-aleatoire').click(async event => new AppPersonnageAleatoire(this.actor).render(true))
if (game.user.isGM) { if (game.user.isGM) {
// experience log // experience log
this.html.find('.experiencelog-delete').click(async event => { this.html.find('.experiencelog-delete').click(async event => {
@@ -216,9 +218,9 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
} }
// Points de reve actuel // Points de reve actuel
this.html.find('.ptreve-actuel a').click(async event => this.actor.rollCarac('reve-actuel', true)) this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', true))
this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
this.html.find('.arme-label a').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)))) this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event))))
// Initiative pour l'arme // Initiative pour l'arme
this.html.find('.arme-initiative a').click(async event => { this.html.find('.arme-initiative a').click(async event => {
@@ -232,10 +234,10 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
}); });
// Display TMR // Display TMR
this.html.find('.monte-tmr').click(async event => this.actor.displayTMR("normal")) this.html.find('.button-tmr').click(async event => this.actor.displayTMR("normal"))
this.html.find('.monte-tmr-rapide').click(async event => this.actor.displayTMR("rapide")) this.html.find('.button-tmr-rapide').click(async event => this.actor.displayTMR("rapide"))
this.html.find('.repos').click(async event => await this.actor.repos()) this.html.find('.button-repos').click(async event => await this.actor.repos())
this.html.find('.carac-xp-augmenter').click(async event => this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", ""))) this.html.find('.carac-xp-augmenter').click(async event => this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", "")))
this.html.find('.competence-xp-augmenter').click(async event => this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event))) this.html.find('.competence-xp-augmenter').click(async event => this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event)))
@@ -277,7 +279,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.moral-malheureux').click(async event => this.actor.jetDeMoral('malheureuse')) this.html.find('.moral-malheureux').click(async event => this.actor.jetDeMoral('malheureuse'))
this.html.find('.moral-neutre').click(async event => this.actor.jetDeMoral('neutre')) this.html.find('.moral-neutre').click(async event => this.actor.jetDeMoral('neutre'))
this.html.find('.moral-heureux').click(async event => this.actor.jetDeMoral('heureuse')) this.html.find('.moral-heureux').click(async event => this.actor.jetDeMoral('heureuse'))
this.html.find('.ethylisme-test').click(async event => this.actor.jetEthylisme()) this.html.find('.button-ethylisme').click(async event => this.actor.jetEthylisme())
this.html.find('.ptreve-actuel-plus').click(async event => this.actor.reveActuelIncDec(1)) this.html.find('.ptreve-actuel-plus').click(async event => this.actor.reveActuelIncDec(1))
this.html.find('.ptreve-actuel-moins').click(async event => this.actor.reveActuelIncDec(-1)) this.html.find('.ptreve-actuel-moins').click(async event => this.actor.reveActuelIncDec(-1))

View File

@@ -159,7 +159,7 @@ export class RdDActor extends RdDBaseActorSang {
const potionUpdates = await Promise.all(potions.map(async it => { const potionUpdates = await Promise.all(potions.map(async it => {
const nouveauReve = Math.max(it.system.pr - 1, 0) const nouveauReve = Math.max(it.system.pr - 1, 0)
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, { content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, {
pr: nouveauReve, pr: nouveauReve,
alias: this.name, alias: this.name,
@@ -210,7 +210,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async grisReve(nbJours) { async grisReve(nbJours) {
let message = { let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: `${nbJours} jours de gris rêve sont passés. ` content: `${nbJours} jours de gris rêve sont passés. `
}; };
for (let i = 0; i < nbJours; i++) { for (let i = 0; i < nbJours; i++) {
@@ -264,7 +264,7 @@ export class RdDActor extends RdDBaseActorSang {
async dormirChateauDormant() { async dormirChateauDormant() {
if (!ReglesOptionnelles.isUsing("chateau-dormant-gardien") || !this.system.sommeil || this.system.sommeil.nouveaujour) { if (!ReglesOptionnelles.isUsing("chateau-dormant-gardien") || !this.system.sommeil || this.system.sommeil.nouveaujour) {
const message = { const message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: "" content: ""
}; };
@@ -400,7 +400,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async remiseANeuf() { async remiseANeuf() {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: 'Remise à neuf de ' + this.name content: 'Remise à neuf de ' + this.name
}); });
await this.supprimerBlessures(it => true); await this.supprimerBlessures(it => true);
@@ -417,7 +417,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async dormir(heures, options = { grisReve: false, chateauDormant: false }) { async dormir(heures, options = { grisReve: false, chateauDormant: false }) {
const message = { const message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: this.name + ': ' content: this.name + ': '
}; };
const insomnie = this.system.sommeil?.insomnie || heures == 0; const insomnie = this.system.sommeil?.insomnie || heures == 0;
@@ -488,7 +488,7 @@ export class RdDActor extends RdDBaseActorSang {
else { else {
if (!ReglesOptionnelles.isUsing("recuperation-reve")) { if (!ReglesOptionnelles.isUsing("recuperation-reve")) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: `Pas de récupération de rêve (${reve} points ignorés)` content: `Pas de récupération de rêve (${reve} points ignorés)`
}); });
jetsReve.push(0); jetsReve.push(0);
@@ -919,7 +919,7 @@ export class RdDActor extends RdDBaseActorSang {
await this.createEmbeddedDocuments('Item', [souffle]); await this.createEmbeddedDocuments('Item', [souffle]);
if (options.chat) { if (options.chat) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: this.name + " subit un Souffle de Dragon : " + souffle.name content: this.name + " subit un Souffle de Dragon : " + souffle.name
}); });
} }
@@ -939,7 +939,7 @@ export class RdDActor extends RdDBaseActorSang {
await this.createEmbeddedDocuments('Item', [queue]); await this.createEmbeddedDocuments('Item', [queue]);
if (options.chat) { if (options.chat) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: this.name + " subit une Queue de Dragon : " + queue.name content: this.name + " subit une Queue de Dragon : " + queue.name
}); });
} }
@@ -977,7 +977,7 @@ export class RdDActor extends RdDBaseActorSang {
let tmr = await TMRUtility.getTMRAleatoire(tmr => accessible(tmr) && !innaccessible.includes(tmr.coord)); let tmr = await TMRUtility.getTMRAleatoire(tmr => accessible(tmr) && !innaccessible.includes(tmr.coord));
ChatMessage.create({ ChatMessage.create({
content: `${raison} : ré-insertion aléatoire.`, content: `${raison} : ré-insertion aléatoire.`,
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name) whisper: ChatUtility.getOwners(this)
}); });
await this.forcerPositionTMRInconnue(tmr); await this.forcerPositionTMRInconnue(tmr);
return tmr; return tmr;
@@ -1082,7 +1082,7 @@ export class RdDActor extends RdDBaseActorSang {
const jetMoral = await this._jetDeMoral(situation); const jetMoral = await this._jetDeMoral(situation);
const finMessage = (jetMoral.succes ? messageReussi : messageManque) ?? (jetMoral.ajustement == 0 ? "Vous gardez votre moral" : jetMoral.ajustement > 0 ? "Vous gagnez du moral" : "Vous perdez du moral"); const finMessage = (jetMoral.succes ? messageReussi : messageManque) ?? (jetMoral.ajustement == 0 ? "Vous gardez votre moral" : jetMoral.ajustement > 0 ? "Vous gagnez du moral" : "Vous perdez du moral");
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: `${finMessage} - jet ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}).` content: `${finMessage} - jet ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}).`
}); });
return jetMoral.ajustement; return jetMoral.ajustement;
@@ -1419,7 +1419,7 @@ export class RdDActor extends RdDBaseActorSang {
}; };
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData)
}); });
@@ -1505,7 +1505,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
if (display) { if (display) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html`, checkXp) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html`, checkXp)
}); });
} }
@@ -1537,7 +1537,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
if (display) { if (display) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html`, checkXp) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html`, checkXp)
}); });
} }
@@ -1563,7 +1563,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
else { else {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: content content: content
}); });
} }
@@ -1666,7 +1666,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
ChatMessage.create({ ChatMessage.create({
content: "Vous êtes sous le coup d'une Mauvaise Rencontre en Persective." + addMsg, content: "Vous êtes sous le coup d'une Mauvaise Rencontre en Persective." + addMsg,
whisper: ChatMessage.getWhisperRecipients(this.name) whisper: ChatUtility.getOwners(this)
}); });
} }
return rencSpecial; return rencSpecial;
@@ -1678,7 +1678,7 @@ export class RdDActor extends RdDBaseActorSang {
if (countInertieDraconique > 0) { if (countInertieDraconique > 0) {
ChatMessage.create({ ChatMessage.create({
content: `Vous êtes sous le coup d'Inertie Draconique : vous perdrez ${countInertieDraconique + 1} cases de Fatigue par déplacement au lieu d'une.`, content: `Vous êtes sous le coup d'Inertie Draconique : vous perdrez ${countInertieDraconique + 1} cases de Fatigue par déplacement au lieu d'une.`,
whisper: ChatMessage.getWhisperRecipients(this.name) whisper: ChatUtility.getOwners(this)
}); });
} }
return countInertieDraconique + 1; return countInertieDraconique + 1;
@@ -1690,7 +1690,7 @@ export class RdDActor extends RdDBaseActorSang {
await this.reveActuelIncDec(-1); await this.reveActuelIncDec(-1);
ChatMessage.create({ ChatMessage.create({
content: "Vous êtes sous le coup d'un Péage : l'entrée sur cette case vous a coûté 1 Point de Rêve (déduit automatiquement).", content: "Vous êtes sous le coup d'un Péage : l'entrée sur cette case vous a coûté 1 Point de Rêve (déduit automatiquement).",
whisper: ChatMessage.getWhisperRecipients(this.name) whisper: ChatUtility.getOwners(this)
}); });
} }
} }
@@ -2270,7 +2270,7 @@ export class RdDActor extends RdDBaseActorSang {
// Cas de désir lancinant, pas d'expérience sur particulière // Cas de désir lancinant, pas d'expérience sur particulière
ChatMessage.create({ ChatMessage.create({
content: `Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi`, content: `Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi`,
whisper: ChatMessage.getWhisperRecipients(this.name) whisper: ChatUtility.getOwners(this)
}); });
return [] return []
} }
@@ -2405,7 +2405,7 @@ export class RdDActor extends RdDBaseActorSang {
if (countMonteeLaborieuse > 0) { if (countMonteeLaborieuse > 0) {
ChatMessage.create({ ChatMessage.create({
content: `Vous êtes sous le coup d'une Montée Laborieuse : vos montées en TMR coûtent ${countMonteeLaborieuse} Point de Rêve de plus.`, content: `Vous êtes sous le coup d'une Montée Laborieuse : vos montées en TMR coûtent ${countMonteeLaborieuse} Point de Rêve de plus.`,
whisper: ChatMessage.getWhisperRecipients(this.name) whisper: ChatUtility.getOwners(this)
}); });
} }
return countMonteeLaborieuse; return countMonteeLaborieuse;
@@ -2453,7 +2453,7 @@ export class RdDActor extends RdDBaseActorSang {
if (this.getReveActuel() < minReveValue) { if (this.getReveActuel() < minReveValue) {
ChatMessage.create({ ChatMessage.create({
content: `Vous n'avez les ${minReveValue} Points de Reve nécessaires pour monter dans les Terres Médianes`, content: `Vous n'avez les ${minReveValue} Points de Reve nécessaires pour monter dans les Terres Médianes`,
whisper: ChatMessage.getWhisperRecipients(this.name) whisper: ChatUtility.getOwners(this)
}); });
return; return;
} }
@@ -2850,7 +2850,7 @@ export class RdDActor extends RdDBaseActorSang {
await this.setBonusPotionSoin(potionData.system.herbebonus); await this.setBonusPotionSoin(potionData.system.herbebonus);
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html`, potionData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html`, potionData)
}); });
} }
@@ -2887,7 +2887,7 @@ export class RdDActor extends RdDBaseActorSang {
this.bonusRepos = potionData.system.herbebonus; this.bonusRepos = potionData.system.herbebonus;
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html`, potionData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html`, potionData)
}); });
} }
@@ -2919,7 +2919,7 @@ export class RdDActor extends RdDBaseActorSang {
this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins); this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins);
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html`, messageData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html`, messageData)
}); });
} }
@@ -2944,7 +2944,7 @@ export class RdDActor extends RdDBaseActorSang {
} }
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.html`, potionData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.html`, potionData)
}); });
} }
@@ -3044,7 +3044,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
notifyGestionTeteSouffleQueue(item, manualMessage = true) { notifyGestionTeteSouffleQueue(item, manualMessage = true) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est"} géré(e) automatiquement. ${manualMessage ? manualMessage : ''}` content: `${this.name} a reçu un/une ${item.type}: ${item.name}, qui ${manualMessage ? "n'est pas" : "est"} géré(e) automatiquement. ${manualMessage ? manualMessage : ''}`
}); });
} }
@@ -3067,7 +3067,7 @@ export class RdDActor extends RdDBaseActorSang {
incarnation.name = 'Réincarnation de ' + incarnation.name incarnation.name = 'Réincarnation de ' + incarnation.name
incarnation.system = { incarnation.system = {
carac: foundry.utils.duplicate(this.system.carac), carac: foundry.utils.duplicate(this.system.carac),
heure: RdDTimestamp.defHeure(await RdDDice.rollTotal("1dh", { rollMode: "selfroll", showDice: SHOW_DICE })).key, heure: RdDTimestamp.defHeure(await RdDDice.rollHeure( { rollMode: "selfroll", showDice: SHOW_DICE })).key,
age: 18, age: 18,
biographie: '', biographie: '',
notes: '', notes: '',

View File

@@ -24,14 +24,15 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet {
// Everything below here is only needed if the sheet is editable // Everything below here is only needed if the sheet is editable
if (!this.options.editable) return; if (!this.options.editable) return;
this.html.find('.encaisser-direct').click(async event => this.actor.encaisser()) this.html.find('.button-encaissement').click(async event => this.actor.encaisser())
this.html.find('.carac-label a').click(async event => this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes.name.value))); this.html.find('.roll-carac').click(async event => {
this.html.find('a.competence-label').click(async event => this.actor.rollCompetence(RdDSheetUtility.getItemId(event))); this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes['data-carac-name'].value))});
this.html.find('.roll-competence').click(async event => this.actor.rollCompetence(RdDSheetUtility.getItemId(event)));
this.html.find('.endurance-plus').click(async event => this.actor.santeIncDec("endurance", 1)); this.html.find('.endurance-plus').click(async event => this.actor.santeIncDec("endurance", 1));
this.html.find('.endurance-moins').click(async event => this.actor.santeIncDec("endurance", -1)); this.html.find('.endurance-moins').click(async event => this.actor.santeIncDec("endurance", -1));
if (game.user.isGM) { if (game.user.isGM) {
this.html.find('.remise-a-neuf').click(async event => this.actor.remiseANeuf()) this.html.find('.button-remise-a-neuf').click(async event => this.actor.remiseANeuf())
this.html.find('.delete-active-effect').click(async event => this.actor.removeEffect(this.html.find(event.currentTarget).parents(".active-effect").data('effect'))); this.html.find('.delete-active-effect').click(async event => this.actor.removeEffect(this.html.find(event.currentTarget).parents(".active-effect").data('effect')));
this.html.find('.enlever-tous-effets').click(async event => await this.actor.removeEffects()); this.html.find('.enlever-tous-effets').click(async event => await this.actor.removeEffects());
} }

View File

@@ -189,7 +189,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
getEffect(effectId) { getEffect(effectId) {
return this.getEmbeddedCollection("ActiveEffect").find(it => it.statuses?.has(effectId)); return this.getEmbeddedCollection("ActiveEffect").find(it => it.statuses?.has(effectId));
} }
async setEffect(effectId, status) { async setEffect(effectId, status) {
if (this.isEffectAllowed(effectId)) { if (this.isEffectAllowed(effectId)) {
const effect = this.getEffect(effectId); const effect = this.getEffect(effectId);
@@ -201,7 +201,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
} }
} }
} }
async removeEffect(id) { async removeEffect(id) {
const effect = this.getEmbeddedCollection("ActiveEffect").find(it => it.id == id); const effect = this.getEmbeddedCollection("ActiveEffect").find(it => it.id == id);
if (effect) { if (effect) {
@@ -296,8 +296,12 @@ export class RdDBaseActorReve extends RdDBaseActor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollCarac(caracName, jetResistance = undefined) { async rollCarac(caracName, jetResistance = undefined) {
if (Grammar.equalsInsensitive(caracName, 'taille')) {
return
}
RdDEmpoignade.checkEmpoignadeEnCours(this) RdDEmpoignade.checkEmpoignadeEnCours(this)
let selectedCarac = this.getCaracByName(caracName) let selectedCarac = this.getCaracByName(caracName)
console.log("selectedCarac", selectedCarac)
await this.openRollDialog({ await this.openRollDialog({
name: 'jet-' + caracName, name: 'jet-' + caracName,
label: 'Jet ' + Grammar.apostrophe('de', selectedCarac.label), label: 'Jet ' + Grammar.apostrophe('de', selectedCarac.label),
@@ -414,9 +418,9 @@ export class RdDBaseActorReve extends RdDBaseActor {
return; return;
} }
const armure = await this.computeArmure(rollData); const armure = await this.computeArmure(rollData);
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')){ if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
await this.encaisserDommagesValidationGR(rollData, armure, attacker?.id, show); await this.encaisserDommagesValidationGR(rollData, armure, attacker?.id, show);
} }
else { else {
const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE }); const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
await this.$onEncaissement(jet, show, attacker); await this.$onEncaissement(jet, show, attacker);
@@ -452,16 +456,19 @@ export class RdDBaseActorReve extends RdDBaseActor {
show: show ?? {} show: show ?? {}
}); });
await ChatUtility.createChatWithRollMode(this.name, { await ChatUtility.createChatWithRollMode(
roll: encaissement.roll, {
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement) roll: encaissement.roll,
}); content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
},
this
)
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) { if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
encaissement = foundry.utils.duplicate(encaissement); encaissement = foundry.utils.duplicate(encaissement)
encaissement.isGM = true; encaissement.isGM = true
ChatMessage.create({ ChatMessage.create({
whisper: ChatMessage.getWhisperRecipients("GM"), whisper: ChatUtility.getGMs(),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement) content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
}); });
} }

View File

@@ -39,8 +39,8 @@ export class RdDBaseActorSangSheet extends RdDBaseActorReveSheet {
ChatMessage.create({ ChatMessage.create({
content: `Jet d'Endurance : ${result.jetEndurance} / ${endurance} content: `Jet d'Endurance : ${result.jetEndurance} / ${endurance}
<br>${this.actor.name} a ${result.sonne ? 'échoué' : 'réussi'} son Jet d'Endurance ${result.sonne ? 'et devient Sonné' : ''}`, <br>${this.actor.name} a ${result.sonne ? 'échoué' : 'réussi'} son Jet d'Endurance ${result.sonne ? 'et devient Sonné' : ''}`,
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.actor.name) whisper: ChatUtility.getOwners(this.actor)
}); })
} }
} }

View File

@@ -5,6 +5,7 @@ import { ITEM_TYPES } from "../item.js";
import { RdDBaseActorReve } from "./base-actor-reve.js"; import { RdDBaseActorReve } from "./base-actor-reve.js";
import { RdDDice } from "../rdd-dice.js"; import { RdDDice } from "../rdd-dice.js";
import { RdDItemBlessure } from "../item/blessure.js"; import { RdDItemBlessure } from "../item/blessure.js";
import { ChatUtility } from "../chat-utility.js";
/** /**
* Classe de base pour les acteurs qui peuvent subir des blessures * Classe de base pour les acteurs qui peuvent subir des blessures
@@ -180,7 +181,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
} }
} }
const endActuelle = this.getEnduranceActuelle(); const endActuelle = this.getEnduranceActuelle();
const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg.loc.label, attacker); const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attacker);
if (blessure.isCritique()) { if (blessure.isCritique()) {
encaissement.endurance = endActuelle; encaissement.endurance = endActuelle;
} }
@@ -196,6 +197,13 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
return blessure; return blessure;
} }
async supprimerBlessure({ gravite }) {
const toDelete = this.itemTypes[ITEM_TYPES.blessure].find(it => it.system.gravite == gravite)?.id
if (toDelete) {
await this.deleteEmbeddedDocuments('Item', [toDelete]);
}
}
async supprimerBlessures(filterToDelete) { async supprimerBlessures(filterToDelete) {
const toDelete = this.filterItems(filterToDelete, ITEM_TYPES.blessure) const toDelete = this.filterItems(filterToDelete, ITEM_TYPES.blessure)
.map(it => it.id); .map(it => it.id);
@@ -203,13 +211,16 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
} }
countBlessures(filter = it => !it.isContusion()) { countBlessures(filter = it => !it.isContusion()) {
return this.filterItems(filter, 'blessure').length return this.filterItems(filter, ITEM_TYPES.blessure).length
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async jetDeVie() { async jetDeVie() {
if (this.isDead()) { if (this.isDead()) {
ChatMessage.create({ content: `Jet de Vie: ${this.name} est déjà mort, ce n'est pas la peine d'en rajouter !!!!!`, whisper: ChatMessage.getWhisperRecipients(this.name) }); ChatMessage.create({
content: `Jet de Vie: ${this.name} est déjà mort, ce n'est pas la peine d'en rajouter !!!!!`,
whisper: ChatUtility.getOwners(this)
})
return return
} }
const jetDeVie = await RdDDice.roll("1d20"); const jetDeVie = await RdDDice.roll("1d20");
@@ -236,7 +247,10 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
else if (prochainJet > 0) { else if (prochainJet > 0) {
msgText += `<br>Prochain jet de vie dans ${prochainJet} ${isCritique ? 'round' : 'minute'}${prochainJet > 1 ? 's' : ''} ${isCritique ? '(état critique)' : '(état grave)'}` msgText += `<br>Prochain jet de vie dans ${prochainJet} ${isCritique ? 'round' : 'minute'}${prochainJet > 1 ? 's' : ''} ${isCritique ? '(état critique)' : '(état grave)'}`
} }
ChatMessage.create({ content: msgText, whisper: ChatMessage.getWhisperRecipients(this.name) }); ChatMessage.create({
content: msgText,
whisper: ChatUtility.getOwners(this)
});
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@@ -270,6 +270,7 @@ export class RdDBaseActor extends Actor {
} }
let fortune = this.getFortune(); let fortune = this.getFortune();
console.log("payer", game.user.character, depense, fortune); console.log("payer", game.user.character, depense, fortune);
// TODO: passer en handlebars
let msg = ""; let msg = "";
if (fortune >= depense) { if (fortune >= depense) {
await Monnaie.optimiserFortune(this, fortune - depense); await Monnaie.optimiserFortune(this, fortune - depense);
@@ -279,11 +280,10 @@ export class RdDBaseActor extends Actor {
msg = "Vous n'avez pas assez d'argent pour payer cette somme !"; msg = "Vous n'avez pas assez d'argent pour payer cette somme !";
} }
let message = { ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: msg content: msg
}; })
ChatMessage.create(message);
} }
async depenserSols(sols) { async depenserSols(sols) {
@@ -317,7 +317,7 @@ export class RdDBaseActor extends Actor {
RdDAudio.PlayContextAudio("argent"); // Petit son RdDAudio.PlayContextAudio("argent"); // Petit son
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this.name),
content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.` content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.`
}); });
} }
@@ -371,7 +371,7 @@ export class RdDBaseActor extends Actor {
ChatMessage.create({ ChatMessage.create({
user: achat.userId, user: achat.userId,
speaker: { alias: (acheteur ?? vendeur).name }, speaker: { alias: (acheteur ?? vendeur).name },
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(this),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem) content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem)
}); });

View File

@@ -0,0 +1,115 @@
import { RdDActorSheet } from "../../actor-sheet.js"
import { SYSTEM_RDD } from "../../constants.js";
import { Misc } from "../../misc.js";
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js";
import { ExportScriptarium } from "./export-scriptarium.js";
import { CATEGORIES_COMPETENCES, CATEGORIES_DRACONIC, Mapping } from "./mapping.js";
export class RdDActorExportSheet extends RdDActorSheet {
static async init() {
await loadTemplates([
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-compteur.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee-compteur.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/competences.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/esquive.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/fatigue.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/protection.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs",
])
Actors.registerSheet(SYSTEM_RDD, RdDActorExportSheet, { types: ["personnage"], makeDefault: false, label: "Feuille simplifiée" })
}
static get defaultOptions() {
return foundry.utils.mergeObject(RdDActorSheet.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/actor-encart-sheet.hbs",
width: 550,
showCompNiveauBase: false,
vueArchetype: false,
}, { inplace: false })
}
constructor(actor, options) {
super(actor, options)
}
async getData() {
const formData = await super.getData()
// Add any structured, precomputed list of data
formData.context = Mapping.prepareContext(this.actor)
formData.export = this.getMappingValues(formData.context, this.actor)
formData.competences = this.getCompetences(CATEGORIES_COMPETENCES)
formData.draconic = this.getCompetences(CATEGORIES_DRACONIC)
const legeres = this.actor.nbBlessuresLegeres()
const graves = this.actor.nbBlessuresGraves()
const critiques = this.actor.nbBlessuresCritiques()
formData.etat = {
surenc: this.actor.computeMalusSurEncombrement(),
fatigue: {
value: this.actor.getFatigueActuelle(),
max: this.actor.getFatigueMax(),
malus: this.actor.malusFatigue()
},
blessures: legeres + graves + critiques,
blessure: [legeres > 0, legeres > 1, legeres > 2, legeres > 3, legeres > 4, graves > 0, graves > 1, critiques > 0],
}
formData.options.exportScriptarium = OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM)
return formData
}
getMappingValues(context, actor) {
return Object.fromEntries(Mapping.getMapping().map(it => [it.column, {
colName: it.colName ?? it.column,
column: it.column,
rollClass: it.rollClass,
value: String(it.getter(actor, context))
}]))
}
getCompetences(categories) {
const competences = Mapping.getCompetencesCategorie(this.actor, categories)
if (competences.length == 0) {
return ''
}
const byCategories = Mapping.competencesByCategoriesByNiveau(competences, categories)
const listByCategories = Object.values(byCategories)
.map(it => it.competencesParNiveau)
.map(byNiveau => {
const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending())
if (niveaux.length == 0) {
return undefined
}
const listCategorieByNiveau = niveaux.map(niveau => {
const list = byNiveau[niveau].sort(Misc.ascending(it => it.name))
return { niveau, list }
})
return Misc.concat(listCategorieByNiveau)
}).filter(it => it != undefined)
return Misc.concat(listByCategories)
}
activateListeners(html) {
super.activateListeners(html);
this.html.find('.click-blessure-remove').click(async event =>
await this.actor.supprimerBlessure({
gravite: this.html.find(event.currentTarget).data('gravite')
})
)
this.html.find('.click-blessure-add').click(async event =>
await this.actor.ajouterBlessure({
gravite: this.html.find(event.currentTarget).data('gravite')
// event.currentTarget.attributes['data-gravite'].value
})
)
this.html.find('.button-export').click(async event => {
ExportScriptarium.INSTANCE.exportActors([this.actor],
`${this.actor.uuid}-${this.actor.name}`
)
})
}
}

View File

@@ -12,14 +12,13 @@ export class ExportScriptarium {
} }
constructor() { constructor() {
this.mapping = Mapping.getMapping()
Hooks.on("getActorDirectoryFolderContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) Hooks.on("getActorDirectoryFolderContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) })
Hooks.on("getActorDirectoryEntryContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) Hooks.on("getActorDirectoryEntryContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) })
} }
onActorDirectoryMenu(actorDirectory, menus) { onActorDirectoryMenu(actorDirectory, menus) {
menus.push({ menus.push({
name: 'Export Personnages', name: 'Export Personnages <i class="fa-regular fa-file-csv"></i>',
icon: IMG_SCRIPTARIUM, icon: IMG_SCRIPTARIUM,
condition: (target) => game.user.isGM && condition: (target) => game.user.isGM &&
OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM) && OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM) &&
@@ -59,12 +58,12 @@ export class ExportScriptarium {
} }
getHeaderLine() { getHeaderLine() {
return this.mapping.map(it => it.column) return Mapping.getColumns()
} }
getActorLine(actor) { getActorLine(actor) {
const context = Mapping.prepareContext(actor) const values = Mapping.getValues(actor)
return this.mapping.map(it => it.getter(actor, context)) return values
.map(it => this.$escapeQuotes(it)) .map(it => this.$escapeQuotes(it))
.map(it => it.replaceAll("\n", " ").replaceAll("\r", "")) .map(it => it.replaceAll("\n", " ").replaceAll("\r", ""))
} }

View File

@@ -6,15 +6,16 @@ import { ITEM_TYPES } from "../../item.js"
import { Misc } from "../../misc.js" import { Misc } from "../../misc.js"
import { RdDTimestamp } from "../../time/rdd-timestamp.js" import { RdDTimestamp } from "../../time/rdd-timestamp.js"
import { RdDBonus } from "../../rdd-bonus.js" import { RdDBonus } from "../../rdd-bonus.js"
import { TMRType } from "../../tmr-utility.js"
const CATEGORIES_COMPETENCES = [ export const CATEGORIES_COMPETENCES = [
"generale", "generale",
"particuliere", "particuliere",
"specialisee", "specialisee",
"connaissance", "connaissance",
] ]
const CATEGORIES_DRACONIC = [ export const CATEGORIES_DRACONIC = [
"draconic", "draconic",
] ]
@@ -37,11 +38,11 @@ const NIVEAU_BASE = {
class ColumnMappingFactory { class ColumnMappingFactory {
static createMappingArme(part, i) { static createMappingArme(part, i) {
return { column: `arme-${part}-${i}`, getter: (actor, context) => Mapping.getArme(actor, context, part, i) } return { column: `arme_${part}_${i}`, getter: (actor, context) => Mapping.getArme(actor, context, part, i) }
} }
static createMappingSort(part, i) { static createMappingSort(part, i) {
return { column: `sort-${part}-${i}`, getter: (actor, context) => Mapping.getSort(actor, context, part, i) } return { column: `sort_${part}_${i}`, getter: (actor, context) => Mapping.getSort(actor, context, part, i) }
} }
} }
@@ -51,38 +52,41 @@ const TABLEAU_ARMES = [...Array(NB_ARMES).keys()]
const TABLEAU_SORTS = [...Array(NB_SORTS).keys()] const TABLEAU_SORTS = [...Array(NB_SORTS).keys()]
const MAPPING_BASE = [ const MAPPING_BASE = [
{ column: "ID", getter: (actor, context) => actor.id }, { column: "ID", colName: 'ID', getter: (actor, context) => actor.id },
{ column: "name", getter: (actor, context) => actor.name }, { column: "name", getter: (actor, context) => actor.name },
{ column: "metier", getter: (actor, context) => actor.system.metier }, { column: "metier", colName: 'Métier', getter: (actor, context) => actor.system.metier },
// { column: "biographie", getter: (actor, context) => actor.system.biographie }, { column: "biographie", colName: 'Biographie', getter: (actor, context) => actor.system.biographie },
{ column: "taille", getter: (actor, context) => actor.system.carac.taille.value }, { column: "taille", getter: (actor, context) => actor.system.carac.taille.value },
{ column: "apparence", getter: (actor, context) => actor.system.carac.apparence.value }, { column: "apparence", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.apparence.value },
{ column: "constitution", getter: (actor, context) => actor.system.carac.constitution.value }, { column: "constitution", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.constitution.value },
{ column: "force", getter: (actor, context) => actor.system.carac.force.value }, { column: "force", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.force.value },
{ column: "agilite", getter: (actor, context) => actor.system.carac.agilite.value }, { column: "agilite", rollClass: 'roll-carac', colName: 'Agilité', getter: (actor, context) => actor.system.carac.agilite.value },
{ column: "dexterite", getter: (actor, context) => actor.system.carac.dexterite.value }, { column: "dexterite", rollClass: 'roll-carac', colName: 'Dextérité', getter: (actor, context) => actor.system.carac.dexterite.value },
{ column: "vue", getter: (actor, context) => actor.system.carac.vue.value }, { column: "vue", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.vue.value },
{ column: "ouie", getter: (actor, context) => actor.system.carac.ouie.value }, { column: "ouie", rollClass: 'roll-carac', colName: 'Ouïe', getter: (actor, context) => actor.system.carac.ouie.value },
{ column: "odoratgout", getter: (actor, context) => actor.system.carac.odoratgout.value }, { column: "odoratgout", rollClass: 'roll-carac', colName: 'Odo-goût', getter: (actor, context) => actor.system.carac.odoratgout.value },
{ column: "volonte", getter: (actor, context) => actor.system.carac.volonte.value }, { column: "volonte", rollClass: 'roll-carac', colName: 'Volonté', getter: (actor, context) => actor.system.carac.volonte.value },
{ column: "intellect", getter: (actor, context) => actor.system.carac.intellect.value }, { column: "intellect", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.intellect.value },
{ column: "empathie", getter: (actor, context) => actor.system.carac.empathie.value }, { column: "empathie", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.empathie.value },
{ column: "reve", getter: (actor, context) => actor.system.carac.reve.value }, { column: "reve", rollClass: 'roll-carac', colName: 'Rêve', getter: (actor, context) => actor.system.carac.reve.value },
{ column: "chance", getter: (actor, context) => actor.system.carac.chance.value }, { column: "chance", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.chance.value },
{ column: "melee", getter: (actor, context) => actor.system.carac.melee.value }, { column: "melee", rollClass: 'roll-carac', colName: 'Mêlée', getter: (actor, context) => actor.system.carac.melee.value },
{ column: "tir", getter: (actor, context) => actor.system.carac.tir.value }, { column: "tir", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.tir.value },
{ column: "lancer", getter: (actor, context) => actor.system.carac.lancer.value }, { column: "lancer", rollClass: 'roll-carac', getter: (actor, context) => actor.system.carac.lancer.value },
{ column: "derobee", getter: (actor, context) => actor.system.carac.derobee.value }, { column: "derobee", rollClass: 'roll-carac', colName: 'Dérobée', getter: (actor, context) => actor.system.carac.derobee.value },
{ column: "vie", getter: (actor, context) => actor.system.sante.vie.max }, { column: "vie", getter: (actor, context) => actor.system.sante.vie.max },
{ column: "plusdom", getter: (actor, context) => actor.system.attributs.plusdom.value },
{ column: "protectionnaturelle", getter: (actor, context) => actor.system.attributs.protection.value },
{ column: "endurance", getter: (actor, context) => actor.system.sante.endurance.max }, { column: "endurance", getter: (actor, context) => actor.system.sante.endurance.max },
{ column: "plusdom", colName: '+dom', getter: (actor, context) => actor.system.attributs.plusdom.value },
{ column: "protectionnaturelle", colName: 'Protection naturelle', getter: (actor, context) => actor.system.attributs.protection.value > 0 ? actor.system.attributs.protection.value : '' },
{ column: "description", getter: (actor, context) => Mapping.getDescription(actor) }, { column: "description", getter: (actor, context) => Mapping.getDescription(actor) },
{ column: "armure", getter: (actor, context) => Mapping.getArmure(actor, context) }, { column: "armure", getter: (actor, context) => Mapping.getArmure(actor, context) },
{ column: "protection", getter: (actor, context) => Mapping.getProtectionArmure(actor, context) }, { column: "protectionarmure", colName: 'Protection', getter: (actor, context) => Mapping.getProtectionArmure(actor, context) },
{ column: "malus-armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) }, { column: "malus_armure", getter: (actor, context) => Mapping.getMalusArmure(actor, context) },
{ column: "reve_actuel", rollClass: 'roll-reve-actuel', colName: 'Rêve actuel', getter: (actor, context) => actor.system.reve.reve.value },
{ column: "vie_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.vie.value },
{ column: "endurance_actuel", rollClass: 'jet-vie', getter: (actor, context) => actor.system.sante.endurance.value },
{ column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) }, { column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) },
{ column: "esquive-armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) }, { column: "esquive_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) },
{ column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) }, { column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) },
{ column: "draconic", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_DRACONIC) }, { column: "draconic", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_DRACONIC) },
] ]
@@ -104,6 +108,27 @@ export class Mapping {
return MAPPING return MAPPING
} }
static getColumns() {
return MAPPING.map(it => it.column)
}
static getValues(actor) {
const context = Mapping.prepareContext(actor)
return MAPPING.map(it => it.getter(actor, context))
}
static getAsObject(actor) {
const context = Mapping.prepareContext(actor)
return Object.fromEntries(MAPPING.map(it => [it.column, {
colName: it.colName ?? it.column,
value: it.getter(actor, context)
}]))
}
static getValues(actor) {
const context = Mapping.prepareContext(actor)
return MAPPING.map(it => it.getter(actor, context))
}
static prepareContext(actor) { static prepareContext(actor) {
return { return {
armes: Mapping.prepareArmes(actor), armes: Mapping.prepareArmes(actor),
@@ -117,11 +142,11 @@ export class Mapping {
const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme)
return armes.map(arme => return armes.map(arme =>
[ [
arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined,
arme.system.lancer = "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined,
arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined,
arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined,
!(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined,
arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined,
arme.system.tir != "" ? Mapping.prepareArme(actor, arme, 'tir') : undefined
] ]
.filter(it => it != undefined) .filter(it => it != undefined)
).reduce((a, b) => a.concat(b), []) ).reduce((a, b) => a.concat(b), [])
@@ -135,14 +160,27 @@ export class Mapping {
} }
const dmgArme = RdDItemArme.dommagesReels(arme, maniement) const dmgArme = RdDItemArme.dommagesReels(arme, maniement)
const dommages = dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme) const dommages = dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)
const categorie = Mapping.complementCategorie(arme, maniement)
return { return {
name: arme.name, name: arme.name + categorie,
niveau: Misc.toSignedString(competence.system.niveau), niveau: Misc.toSignedString(competence.system.niveau),
init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau, init: Mapping.calculBaseInit(actor, competence.system.categorie) + competence.system.niveau,
dommages: Misc.toSignedString(dommages) dommages: Misc.toSignedString(dommages),
competence: competence,
arme: arme
} }
} }
static complementCategorie(arme, maniement) {
switch (maniement) {
case 'unemain': return (arme.system.deuxmains) ? ' 1 main' : (arme.system.lancer||arme.system.tir) ? ' mêlée': ''
case 'deuxmains': return (arme.system.unemain) ? ' 2 mains' : (arme.system.lancer||arme.system.tir) ? ' mêlée': ''
case 'lancer': return (arme.system.unemain || arme.system.deuxmains || arme.system.tir) ? ' jet' : ''
case 'tir': return (arme.system.unemain || arme.system.deuxmains || arme.system.lancer) ? ' tir' : ''
}
return ''
}
static calculBaseInit(actor, categorie) { static calculBaseInit(actor, categorie) {
const mapping = MAPPING_BASE.find(it => it.column == categorie) const mapping = MAPPING_BASE.find(it => it.column == categorie)
if (mapping) { if (mapping) {
@@ -183,19 +221,24 @@ export class Mapping {
const esquive = esquives[0] const esquive = esquives[0]
return { return {
name: esquive.name, name: esquive.name,
niveau: esquive.system.niveau niveau: esquive.system.niveau,
competence: esquive
} }
} }
return undefined return undefined
} }
static prepareSorts(actor) { static prepareSorts(actor) {
return actor.itemTypes[ITEM_TYPES.sort].map(it => Mapping.prepareSort(it)) const codeVoies = Mapping.getCompetencesCategorie(actor, CATEGORIES_DRACONIC)
.map(it => RdDItemSort.getVoieCode(it))
return actor.itemTypes[ITEM_TYPES.sort].map(it => Mapping.prepareSort(it, codeVoies))
.sort(Misc.ascending(it => `${it.voie} : ${it.description}`))
} }
static prepareSort(sort) { static prepareSort(sort, voies) {
return { return {
voie: RdDItemSort.getCodeDraconic(sort), voie: RdDItemSort.getCodeDraconic(sort, voies),
description: Mapping.descriptionSort(sort), description: Mapping.descriptionSort(sort),
bonus: Mapping.bonusCase(sort) bonus: Mapping.bonusCase(sort)
} }
@@ -203,8 +246,18 @@ export class Mapping {
static descriptionSort(sort) { static descriptionSort(sort) {
const ptSeuil = Array(sort.system.coutseuil).map(it => '*') const ptSeuil = Array(sort.system.coutseuil).map(it => '*')
const caseTMR = sort.system.caseTMRspeciale.length > 0 ? sort.system.caseTMRspeciale : sort.system.caseTMR const caseTMR = sort.system.caseTMRspeciale.length > 0 ? Mapping.toVar(sort.system.caseTMRspeciale) : Misc.upperFirst(TMRType[sort.system.caseTMR].name)
return `${sort.name}${ptSeuil} (${caseTMR}) R${sort.system.difficulte} r${sort.system.ptreve}` const ptreve = Mapping.addSpaceToNonNumeric(sort.system.ptreve)
const diff = Mapping.addSpaceToNonNumeric(sort.system.difficulte)
return `${sort.name}${ptSeuil} (${caseTMR}) R${diff} r${ptreve}`
}
static addSpaceToNonNumeric(value) {
return Number.isNumeric(value) ? value : ' ' + Mapping.toVar(value)
}
static toVar(value) {
return value.replace('variable', 'var')
} }
static bonusCase(sort) { static bonusCase(sort) {
@@ -227,7 +280,7 @@ export class Mapping {
const poids = actor.system.poids const poids = actor.system.poids
const cheveux = actor.system.cheveux ? `cheveux ${actor.system.cheveux}` : undefined const cheveux = actor.system.cheveux ? `cheveux ${actor.system.cheveux}` : undefined
const yeux = actor.system.yeux ? `yeux ${actor.system.yeux}` : undefined const yeux = actor.system.yeux ? `yeux ${actor.system.yeux}` : undefined
const beaute = actor.system.beaute ? `Beauté ${actor.system.beaute}` : undefined const beaute = actor.system.beaute ? `beauté ${actor.system.beaute}` : undefined
const list = [race, hn, age, taille, poids, cheveux, yeux, beaute] const list = [race, hn, age, taille, poids, cheveux, yeux, beaute]
return Misc.join(list.filter(it => it), ', ') return Misc.join(list.filter(it => it), ', ')
} }
@@ -237,7 +290,14 @@ export class Mapping {
} }
static getProtectionArmure(actor, context) { static getProtectionArmure(actor, context) {
return Number(context?.armure?.protection ?? 0) + Number(actor.system.attributs.protection.value) const naturelle = Number(actor.system.attributs.protection.value)
if (context?.armure?.protection == undefined) {
return naturelle
}
if (Number.isNumeric(context?.armure?.protection)) {
return Number(context?.armure?.protection ?? 0) + naturelle
}
return context?.armure.protection + (naturelle > 0 ? `+${naturelle}` : '')
} }
static getMalusArmure(actor, context) { static getMalusArmure(actor, context) {
@@ -263,8 +323,8 @@ export class Mapping {
if (competences.length == 0) { if (competences.length == 0) {
return '' return ''
} }
const byCartegories = Mapping.competencesByCategoriesByNiveau(competences, categories) const byCategories = Mapping.competencesByCategoriesByNiveau(competences, categories)
const txtByCategories = Object.values(byCartegories) const txtByCategories = Object.values(byCategories)
.map(it => it.competencesParNiveau) .map(it => it.competencesParNiveau)
.map(byNiveau => { .map(byNiveau => {
const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending()) const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending())

View File

@@ -0,0 +1,188 @@
import { SHOW_DICE } from "../../constants.js";
import { Misc } from "../../misc.js";
import { RdDCarac } from "../../rdd-carac.js";
import { RdDDice } from "../../rdd-dice.js";
import { RdDNameGen } from "../../rdd-namegen.js";
import { RdDTimestamp } from "../../time/rdd-timestamp.js";
const PATHS = [
'name',
'system.sexe',
'system.age',
'system.taille',
'system.poids',
'system.main',
'system.heure',
'system.cheveux',
'system.yeux'
]
const RANDOM_VALUES = {
'system.sexe': { 'masculin': 1, 'féminin': 1 },
'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidectre': 6 },
'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains clair': 5, 'blonds': 4, 'blonds très clair': 1, 'roux carotte': 1, 'roux cuivré': 3 },
'system.yeux': { 'noirs': 2, 'noisettes': 3, 'bruns vert': 4, 'verts': 3, 'bleus clair': 3, 'bleus gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 },
}
export class AppPersonnageAleatoire extends FormApplication {
static preloadHandlebars() {
loadTemplates([
'systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs',
])
}
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor/random/app-personnage-aleatoire.hbs",
title: "Génération aléatoire",
width: 'fit-content',
height: 'fit-content',
classes: ['app-personnage-aleatoire'],
popOut: true,
resizable: true
}, { inplace: false })
}
constructor(actor) {
super({})
this.actor = actor
this.current = foundry.utils.duplicate(actor)
this.checked = {
'name': false,
'system.sexe': true,
'system.age': true,
'system.taille': true,
'system.poids': true,
'system.main': true,
'system.heure': true,
'system.cheveux': true,
'system.yeux': true
}
}
async getData(options) {
return foundry.utils.mergeObject(await super.getData(options), {
actor: this.actor,
current: this.current,
checked: this.checked,
options: { isGM: game.user.isGM }
})
}
activateListeners(html) {
super.activateListeners(html)
this.html = html
this.html.find("button.button-cancel").click(async event => await this.close())
this.html.find("button.button-apply").click(async event => await this.onApply())
this.html.find("input.current-value").change(async event => await this.onChange(event))
this.html.find("div.random-field[data-path='system.heure'] select.current-value").change(async event => await this.onChange(event))
this.html.find("a.random").click(async event => await this.onRandom(event))
this.html.find("a.reset").click(async event => await this.onReset(event))
this.html.find("a.randomize-selected").click(async event => await this.onRandomizeSelected())
this.html.find("input.check-for-random").click(async event => await this.onCheckForRandom(event))
}
async _updateObject(event, formData) { }
async onApply() {
const updates = Object.fromEntries(
PATHS.filter(path => game.user.isGM || path != 'name')
.map(path => [path, this.current[path]])
)
await this.actor.update(updates)
await this.close()
}
getPath(selector) {
const fields = this.html.find(selector).parents("div.random-field:first")
return fields[0].attributes['data-path'].value
}
async onChange(event) {
const path = this.getPath(event.currentTarget)
this.current[path] = event.currentTarget.value
}
async onRandom(event) {
const path = this.getPath(event.currentTarget)
await this.setRandom(path);
this.render()
}
async onReset(event) {
const path = this.getPath(event.currentTarget)
this.current[path] = this.actor[path]
await this.render()
}
async onCheckForRandom(event) {
const path = this.getPath(event.currentTarget)
this.checked[path] = event.currentTarget.checked
this.render()
}
async onRandomizeSelected() {
const paths = this.html.find("input.check-for-random:checked")
.parents("div.random-field")
.toArray()
.map(it => it.attributes['data-path'].value)
await Promise.all(paths.map(path => this.setRandom(path)))
this.render()
}
async setRandom(path) {
this.current[path] = await this.random(path);
}
async random(path) {
switch (path) {
case 'name':
return await RdDNameGen.generate()
case 'system.sexe':
case 'system.main':
case 'system.cheveux':
case 'system.yeux':
return await this.randomFromMap(RANDOM_VALUES[path])
case 'system.poids':
return await this.randomPoids()
case 'system.taille':
return await this.randomTaille()
case 'system.age':
return await RdDDice.rollTotal('(2d4kl)*10 + 1d7xo + 2d20kl')
case 'system.heure':
return RdDTimestamp.defHeure(await RdDDice.rollHeure({ rollMode: "selfroll", showDice: SHOW_DICE })).key
}
return 'unknown'
}
async randomFromMap(valuesMap) {
const max = Object.values(valuesMap).reduce(Misc.sum(), 0)
const total = await RdDDice.rollTotal(`1d${max}`)
let sum = 0
for (let entry of Object.entries(valuesMap)) {
sum = sum + entry[1]
if (sum >= total) {
return entry[0]
}
}
return Object.keys(valuesMap)[0]
}
async randomPoids() {
const caracTaille = RdDCarac.getCaracDerivee(this.current.system.carac.taille.value)
const range = caracTaille.poidsMax - caracTaille.poidsMin + 1
const total = await RdDDice.rollTotal(`1d${range} + ${caracTaille.poidsMin}`)
return total + ' kg'
}
async randomTaille() {
const caracTaille = RdDCarac.getCaracDerivee(this.current.system.carac.taille.value)
const base = this.current.system.carac.taille.value * 2 + 60 + caracTaille.poidsMin
const variation = Math.floor((caracTaille.poidsMax - caracTaille.poidsMin + base / 5) / 2)
const total = await RdDDice.rollTotal(`2d${variation} + ${base}`)
const cm = total % 100
const m = (total - cm) / 100
return `${m}m${cm}`
}
}

View File

@@ -8,15 +8,20 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
*/ */
export class ChatUtility { export class ChatUtility {
static async init() {
Hooks.on("renderChatMessage", async (app, html, msg) => await ChatUtility.onRenderChatMessage(app, html, msg))
Hooks.on("createChatMessage", async (chatMessage, options, id) => await ChatUtility.onCreateChatMessage(chatMessage, options, id))
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static onSocketMessage(sockmsg) { static onSocketMessage(sockmsg) {
switch (sockmsg.msg) { switch (sockmsg.msg) {
case "msg_delete_chat_message": return ChatUtility.onRemoveMessages(sockmsg.data); case "msg_gm_chat_message": return ChatUtility.handleGMChatMessage(sockmsg.data)
case "msg_user_ui_notifications": return ChatUtility.onNotifyUser(sockmsg.data); case "msg_delete_chat_message": return ChatUtility.onRemoveMessages(sockmsg.data)
case "msg_user_ui_notifications": return ChatUtility.onNotifyUser(sockmsg.data)
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static notifyUser(userId, level = 'info', message) { static notifyUser(userId, level = 'info', message) {
const socketData = { const socketData = {
@@ -78,73 +83,90 @@ export class ChatUtility {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async createChatWithRollMode(name, chatOptions) { static async createChatWithRollMode(messageData, actor = undefined) {
let rollMode = game.settings.get("core", "rollMode") switch (game.settings.get("core", "rollMode")) {
switch (rollMode) {
case "blindroll": // GM only case "blindroll": // GM only
if (!game.user.isGM) { if (!game.user.isGM) {
ChatUtility.blindMessageToGM(chatOptions); ChatUtility.blindMessageToGM(messageData)
messageData.whisper = [game.user];
chatOptions.whisper = [game.user.id]; messageData.content = "Message envoyé en aveugle au Gardien"
chatOptions.content = "Message envoyé en aveugle au Gardien";
} }
else { else {
chatOptions.whisper = ChatUtility.getUsers(user => user.isGM); messageData.whisper = ChatUtility.getGMs()
} }
break; break
default: case "gmroll":
chatOptions.whisper = ChatUtility.getWhisperRecipients(rollMode, name); messageData.whisper = ChatUtility.getOwners(actor)
break; break
case "selfroll":
messageData.whisper = [game.user]
break
} }
chatOptions.alias = chatOptions.alias || name; messageData.alias = messageData.alias ?? actor?.name ?? game.user.name
return await ChatMessage.create(chatOptions); return await ChatMessage.create(messageData)
}
static getOwners(document) {
return game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
}
static getUserAndGMs() {
return [game.user, ...ChatUtility.getGMs()]
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static prepareChatMessage(rollMode, name) { static getMultipleActorsOwners(...actors) {
return { return Misc.concat(actors.map(it => it == undefined ? [] : ChatUtility.getOwners(it)))
user: game.user.id,
whisper: ChatUtility.getWhisperRecipients(rollMode, name)
}
}
/* -------------------------------------------- */
static getWhisperRecipients(rollMode, name) {
switch (rollMode) {
case "blindroll": return ChatUtility.getUsers(user => user.isGM);
case "gmroll": return ChatUtility.getWhisperRecipientsAndGMs(name);
case "selfroll": return [game.user.id];
}
return undefined;
}
/* -------------------------------------------- */
static getWhisperRecipientsAndGMs(...names) {
let recipients = [...ChatMessage.getWhisperRecipients('GM')]
names.forEach(name => recipients.push(...ChatMessage.getWhisperRecipients(name)))
return recipients
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static getUsers(filter) { static getUsers(filter) {
return game.users.filter(filter).map(user => user.id); return game.users.filter(filter)
}
static getGMs() {
return game.users.filter(user => user.isGM)
}
static applyRollMode(chatMessageData = {}, rollMode = game.settings.get("core", "rollMode")) {
switch (rollMode) {
case "blindroll":
chatMessageData.blind = true
chatMessageData.whisper = ChatUtility.getGMs()
break
case "gmroll":
chatMessageData.whisper = ChatUtility.getGMs()
chatMessageData.blind = false
break
case "roll":
chatMessageData.whisper = ChatUtility.getUsers(user => user.active)
chatMessageData.blind = false
break
case "selfroll":
chatMessageData.whisper = [game.user]
chatMessageData.blind = false
break
}
return chatMessageData
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static blindMessageToGM(chatOptions) { static blindMessageToGM(chatOptions) {
let chatGM = foundry.utils.duplicate(chatOptions); const chatGM = foundry.utils.duplicate(chatOptions)
chatGM.whisper = ChatUtility.getUsers(user => user.isGM); chatGM.content = "Message aveugle de " + game.user.name + "<br>" + chatOptions.content
chatGM.content = "Message aveugle de " + game.user.name + "<br>" + chatOptions.content; console.log("blindMessageToGM", chatGM)
console.log("blindMessageToGM", chatGM); game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_gm_chat_message", data: chatGM })
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_gm_chat_message", data: chatGM });
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static handleGMChatMessage(socketData) { static handleGMChatMessage(socketData) {
console.log("blindMessageToGM", socketData); console.log("blindMessageToGM", socketData);
if (game.user.isGM) { // message privé pour GM only if (Misc.firstConnectedGM()) {
socketData.user = game.user.id; ChatMessage.create({
ChatMessage.create(socketData); user: game.user.id,
whisper: ChatUtility.getGMs(),
content: socketData.content
})
} }
} }

View File

@@ -30,7 +30,8 @@ export class RdDCoeur {
} }
static extractInfoCoeur(event) { static extractInfoCoeur(event) {
return ChatUtility.getMessageData(ChatUtility.getChatMessage(event), INFO_COEUR) const chatMesage = ChatUtility.getChatMessage(event);
return ChatUtility.getMessageData(chatMesage, INFO_COEUR)
} }
static getInfoCoeur(sourceActorId, targetActorId) { static getInfoCoeur(sourceActorId, targetActorId) {
@@ -98,12 +99,11 @@ export class RdDCoeur {
static async startSubActeurTendreMoment(actorId, subActeurId) { static async startSubActeurTendreMoment(actorId, subActeurId) {
const infoCoeur = RdDCoeur.getInfoCoeur(actorId, subActeurId) const infoCoeur = RdDCoeur.getInfoCoeur(actorId, subActeurId)
if (infoCoeur.target?.actor.id) { if (infoCoeur.target?.actor?.id) {
// TODO: passer par une fenêtre pour saisir sa proposition (lieu, heure, ...) // TODO: passer par une fenêtre pour saisir sa proposition (lieu, heure, ...)
const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-proposer-tendre-moment.hbs`, infoCoeur)
const chatMessage = await ChatMessage.create({ const chatMessage = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(infoCoeur.target?.actor.name), whisper: ChatUtility.getOwners(infoCoeur.target.actor),
content: chatHtml content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-proposer-tendre-moment.hbs`, infoCoeur)
}) })
RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage) RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage)
} }
@@ -127,7 +127,7 @@ export class RdDCoeur {
} }
const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-accepter-tendre-moment.hbs`, infoCoeur) const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-accepter-tendre-moment.hbs`, infoCoeur)
const chatMessage = await ChatMessage.create({ const chatMessage = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(infoCoeur.source?.actor.name, infoCoeur.target?.actor.name), whisper: ChatUtility.getMultipleActorsOwners(infoCoeur.source?.actor, infoCoeur.target?.actor),
content: chatHtml content: chatHtml
}) })
RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage) RdDCoeur.addTagsInfoCoeur(infoCoeur, chatMessage)
@@ -142,7 +142,7 @@ export class RdDCoeur {
ChatUtility.removeChatMessageId(infoCoeur.chatMessageId) ChatUtility.removeChatMessageId(infoCoeur.chatMessageId)
const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-refuser-tendre-moment.hbs`, infoCoeur) const chatHtml = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/coeur/chat-refuser-tendre-moment.hbs`, infoCoeur)
await ChatMessage.create({ await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(infoCoeur.source?.actor.name, infoCoeur.target?.actor.name), whisper: ChatUtility.getMultipleActorsOwners(infoCoeur.source?.actor, infoCoeur.target?.actor),
content: chatHtml content: chatHtml
}); });
} }

View File

@@ -8,7 +8,7 @@ const LATEST_USED_JOURNAL_ID = "chronologie-dernier-journal";
export class DialogChronologie extends Dialog { export class DialogChronologie extends Dialog {
static init() { static initSettings() {
game.settings.register(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, { game.settings.register(SYSTEM_RDD, LATEST_USED_JOURNAL_ID, {
name: "Dernier article de journal utilisé pour enregistrer la chronologie", name: "Dernier article de journal utilisé pour enregistrer la chronologie",
scope: "client", scope: "client",

View File

@@ -48,7 +48,7 @@ export class DialogCreateSigneDraconique extends Dialog {
async _createSigneForActor(actor, signe) { async _createSigneForActor(actor, signe) {
actor.createEmbeddedDocuments("Item", [signe]); actor.createEmbeddedDocuments("Item", [signe]);
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name), whisper: ChatUtility.getOwners(actor),
content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", { content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", {
signe: signe, signe: signe,
alias: actor.name alias: actor.name

View File

@@ -7,7 +7,7 @@ import { CompendiumTableHelpers, CompendiumTable, SystemCompendiums } from "./se
const COMPENDIUMS_RECHERCHE = 'compendiums-recherche'; const COMPENDIUMS_RECHERCHE = 'compendiums-recherche';
export class Environnement { export class Environnement {
static init() { static initSettings() {
game.settings.register(SYSTEM_RDD, COMPENDIUMS_RECHERCHE, { game.settings.register(SYSTEM_RDD, COMPENDIUMS_RECHERCHE, {
name: COMPENDIUMS_RECHERCHE, name: COMPENDIUMS_RECHERCHE,
default: [ default: [

View File

@@ -5,12 +5,12 @@ import { Misc } from "./misc.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRUtility } from "./tmr-utility.js";
const VOIES_DRACONIC = [ const VOIES_DRACONIC = [
{ code: 'O', label: "Voie d'Oniros", short: 'Oniros' }, { code: 'O', label: "Voie d'Oniros", short: 'Oniros', ordre: 'a' },
{ code: 'H', label: "Voie d'Hypnos", short: 'Hypnos' }, { code: 'H', label: "Voie d'Hypnos", short: 'Hypnos', ordre: 'b' },
{ code: 'N', label: "Voie de Narcos", short: 'Narcos' }, { code: 'N', label: "Voie de Narcos", short: 'Narcos', ordre: 'c' },
{ code: 'T', label: "Voie de Thanatos", short: 'Thanatos' }, { code: 'T', label: "Voie de Thanatos", short: 'Thanatos', ordre: 'd' },
{ code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'Oniros/Hypnos/Narcos/Thanatos' }, { code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'Oniros/Hypnos/Narcos/Thanatos', ordre: 'e' },
{ code: 'O/H/N', label: "Oniros/Hypnos/Narcos" } { code: 'O/H/N', label: "Oniros/Hypnos/Narcos", short: "Oniros/Hypnos/Narcos", ordre: 'f' }
] ]
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -27,17 +27,33 @@ export class RdDItemSort extends Item {
return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)]; return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)];
} }
static getCodeDraconic(sort) { static getOrdreCode(code) {
return (VOIES_DRACONIC.find(it => it.code == code)?.ordre ?? '?')
}
static getVoieCode(voie) {
return VOIES_DRACONIC.find(it => voie.name.includes(it.short))?.code ?? '?'
}
static getCodeDraconic(sort, voies = ['O', 'H', 'N', 'T']) {
switch (Grammar.toLowerCaseNoAccent(sort.name)) { switch (Grammar.toLowerCaseNoAccent(sort.name)) {
case "lecture d'aura": case "lecture d'aura":
case "detection d'aura": case "detection d'aura":
return 'O/H/N/T' return RdDItemSort.$voiesConnues('O/H/N/T', voies)
case "annulation de magie": case "annulation de magie":
return 'O/H/N' return RdDItemSort.$voiesConnues('O/H/N', voies)
} }
const voie = VOIES_DRACONIC.find(it => it.label.includes(sort.system.draconic)) const voie = VOIES_DRACONIC.find(it => it.label.includes(sort.system.draconic))
return voie?.code ?? sort.system.draconic return voie?.code ?? sort.system.draconic
} }
static $voiesConnues(voiesSort, voies) {
const codes = voies.filter(it => voiesSort.includes(it))
.sort(Misc.ascending(it => RdDItemSort.getOrdreCode(it)))
return Misc.join(codes ?? [''], '/');
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static isDifficulteVariable(sort) { static isDifficulteVariable(sort) {
return sort && (sort.system.difficulte.toLowerCase() == "variable"); return sort && (sort.system.difficulte.toLowerCase() == "variable");
@@ -67,7 +83,7 @@ export class RdDItemSort extends Item {
static buildBonusCaseList(bonuscase, newCase) { static buildBonusCaseList(bonuscase, newCase) {
const list = RdDItemSort.bonuscaseStringToList(bonuscase) const list = RdDItemSort.bonuscaseStringToList(bonuscase)
if (newCase) { if (newCase) {
list.push({ case: "Nouvelle", bonus: 0 }) list.push({ case: "Nouvelle", bonus: 0 })
} }
return list; return list;
} }

View File

@@ -62,7 +62,7 @@ export class RdDItemBlessure extends RdDItem {
content: `Blessure ${definition.label} appliquée à ${actor.name}`+ content: `Blessure ${definition.label} appliquée à ${actor.name}`+
`<br>Perte d'endurance : ${lostEndurance}`+ `<br>Perte d'endurance : ${lostEndurance}`+
`<br>Perte de Vie : ${lostVie}`, `<br>Perte de Vie : ${lostVie}`,
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name) whisper: ChatUtility.getOwners(actor)
}); });
} }

View File

@@ -1,3 +1,4 @@
import { ChatUtility } from "../chat-utility.js";
import { RdDItem } from "../item.js"; import { RdDItem } from "../item.js";
import { Misc } from "../misc.js"; import { Misc } from "../misc.js";
import { RdDTimestamp } from "../time/rdd-timestamp.js"; import { RdDTimestamp } from "../time/rdd-timestamp.js";
@@ -21,9 +22,12 @@ export class RdDItemMaladie extends RdDItem {
const souffrance = mal.system.identifie const souffrance = mal.system.identifie
? `de ${mal.name}` ? `de ${mal.name}`
: `d'un mal inconnu` : `d'un mal inconnu`
ChatMessage.create({ content: `${mal.actor.name} souffre ${souffrance} (${Misc.typeName('Item', mal.type)}): vérifiez que les effets ne se sont pas aggravés !` }); ChatMessage.create({
mal.postItemToChat('gmroll'); whisper: ChatUtility.getOwners(mal.actor),
await RdDItemMaladie.prolongerPeriode(mal,oldTimestamp, newTimestamp); content: `${mal.actor.name} souffre ${souffrance} (${Misc.typeName('Item', mal.type)}): vérifiez que les effets ne se sont pas aggravés !`
})
mal.postItemToChat('gmroll')
await RdDItemMaladie.prolongerPeriode(mal, oldTimestamp, newTimestamp)
} }
} }

View File

@@ -3,38 +3,38 @@ import { Misc } from "./misc.js";
const TABLE_CARACTERISTIQUES_DERIVEES = { const TABLE_CARACTERISTIQUES_DERIVEES = {
// xp: coût pour passer du niveau inférieur à ce niveau // xp: coût pour passer du niveau inférieur à ce niveau
1: { xp: 3, poids: "moins de 1kg", plusdom: -5, sconst: 0.5, sust: 0.1 }, 1: { xp: 3, poids: "moins de 1kg", poidsMin: 0, poidsMax: 1, plusdom: -5, sconst: 0.5, sust: 0.1 },
2: { xp: 3, poids: "1-5", plusdom: -4, sconst: 0.5, sust: 0.3 }, 2: { xp: 3, poids: "1-5", poidsMin: 1, poidsMax: 5, plusdom: -4, sconst: 0.5, sust: 0.3 },
3: { xp: 4, poids: "6-10", plusdom: -3, sconst: 1, sust: 0.5, beaute: 'hideux' }, 3: { xp: 4, poids: "6-10", poidsMin: 6, poidsMax: 10, plusdom: -3, sconst: 1, sust: 0.5, beaute: 'hideux' },
4: { xp: 4, poids: "11-20", plusdom: -3, sconst: 1, sust: 1, beaute: 'repoussant' }, 4: { xp: 4, poids: "11-20", poidsMin: 11, poidsMax: 20, plusdom: -3, sconst: 1, sust: 1, beaute: 'repoussant' },
5: { xp: 5, poids: "21-30", plusdom: -2, sconst: 1, sust: 1, beaute: 'franchement très laid' }, 5: { xp: 5, poids: "21-30", poidsMin: 21, poidsMax: 30, plusdom: -2, sconst: 1, sust: 1, beaute: 'franchement très laid' },
6: { xp: 5, poids: "31-40", plusdom: -1, sconst: 2, sust: 2, beaute: 'laid' }, 6: { xp: 5, poids: "31-40", poidsMin: 31, poidsMax: 40, plusdom: -1, sconst: 2, sust: 2, beaute: 'laid' },
7: { xp: 6, poids: "41-50", plusdom: -1, sconst: 2, sust: 2, beaute: 'très désavantagé' }, 7: { xp: 6, poids: "41-50", poidsMin: 41, poidsMax: 50, plusdom: -1, sconst: 2, sust: 2, beaute: 'très désavantagé' },
8: { xp: 6, poids: "51-60", plusdom: 0, sconst: 2, sust: 2, beaute: 'désavantagé' }, 8: { xp: 6, poids: "51-60", poidsMin: 51, poidsMax: 60, plusdom: 0, sconst: 2, sust: 2, beaute: 'désavantagé' },
9: { xp: 7, poids: "61-65", plusdom: 0, sconst: 3, sust: 2, beaute: 'pas terrible' }, 9: { xp: 7, poids: "61-65", poidsMin: 61, poidsMax: 65, plusdom: 0, sconst: 3, sust: 2, beaute: 'pas terrible' },
10: { xp: 7, poids: "66-70", plusdom: 0, sconst: 3, sust: 3, beaute: 'commun' }, 10: { xp: 7, poids: "66-70", poidsMin: 66, poidsMax: 70, plusdom: 0, sconst: 3, sust: 3, beaute: 'commun' },
11: { xp: 8, poids: "71-75", plusdom: 0, sconst: 3, sust: 3, beaute: 'pas mal' }, 11: { xp: 8, poids: "71-75", poidsMin: 71, poidsMax: 75, plusdom: 0, sconst: 3, sust: 3, beaute: 'pas mal' },
12: { xp: 8, poids: "76-80", plusdom: +1, sconst: 4, sust: 3, beaute: 'avantagé' }, 12: { xp: 8, poids: "76-80", poidsMin: 76, poidsMax: 80, plusdom: +1, sconst: 4, sust: 3, beaute: 'avantagé' },
13: { xp: 9, poids: "81-90", plusdom: +1, sconst: 4, sust: 3, beaute: 'mignon' }, 13: { xp: 9, poids: "81-90", poidsMin: 81, poidsMax: 90, plusdom: +1, sconst: 4, sust: 3, beaute: 'mignon' },
14: { xp: 9, poids: "91-100", plusdom: +2, sconst: 4, sust: 4, beaute: 'beau' }, 14: { xp: 9, poids: "91-100", poidsMin: 91, poidsMax: 100, plusdom: +2, sconst: 4, sust: 4, beaute: 'beau' },
15: { xp: 10, poids: "101-110", plusdom: +2, sconst: 5, sust: 4, beaute: 'très beau' }, 15: { xp: 10, poids: "101-110", poidsMin: 101, poidsMax: 110, plusdom: +2, sconst: 5, sust: 4, beaute: 'très beau' },
16: { xp: 20, poids: "111-120", plusdom: +3, sconst: 5, sust: 4, beaute: 'éblouissant' }, 16: { xp: 20, poids: "111-120", poidsMin: 111, poidsMax: 120, plusdom: +3, sconst: 5, sust: 4, beaute: 'éblouissant' },
17: { xp: 30, poids: "121-131", plusdom: +3, sconst: 5, sust: 5 }, 17: { xp: 30, poids: "121-131", poidsMin: 121, poidsMax: 131, plusdom: +3, sconst: 5, sust: 5 },
18: { xp: 40, poids: "131-141", plusdom: +4, sconst: 6, sust: 5 }, 18: { xp: 40, poids: "131-141", poidsMin: 131, poidsMax: 141, plusdom: +4, sconst: 6, sust: 5 },
19: { xp: 50, poids: "141-150", plusdom: +4, sconst: 6, sust: 5 }, 19: { xp: 50, poids: "141-150", poidsMin: 141, poidsMax: 150, plusdom: +4, sconst: 6, sust: 5 },
20: { xp: 60, poids: "151-160", plusdom: +4, sconst: 6, sust: 6 }, 20: { xp: 60, poids: "151-160", poidsMin: 151, poidsMax: 160, plusdom: +4, sconst: 6, sust: 6 },
21: { xp: 70, poids: "161-180", plusdom: +5, sconst: 7, sust: 6 }, 21: { xp: 70, poids: "161-180", poidsMin: 161, poidsMax: 180, plusdom: +5, sconst: 7, sust: 6 },
22: { xp: 80, poids: "181-200", plusdom: +5, sconst: 7, sust: 7 }, 22: { xp: 80, poids: "181-200", poidsMin: 181, poidsMax: 200, plusdom: +5, sconst: 7, sust: 7 },
23: { xp: 90, poids: "201-300", plusdom: +6, sconst: 7, sust: 8 }, 23: { xp: 90, poids: "201-300", poidsMin: 201, poidsMax: 300, plusdom: +6, sconst: 7, sust: 8 },
24: { xp: 100, poids: "301-400", plusdom: +6, sconst: 8, sust: 9 }, 24: { xp: 100, poids: "301-400", poidsMin: 301, poidsMax: 400, plusdom: +6, sconst: 8, sust: 9 },
25: { xp: 110, poids: "401-500", plusdom: +7, sconst: 8, sust: 10 }, 25: { xp: 110, poids: "401-500", poidsMin: 401, poidsMax: 500, plusdom: +7, sconst: 8, sust: 10 },
26: { xp: 120, poids: "501-600", plusdom: +7, sconst: 8, sust: 11 }, 26: { xp: 120, poids: "501-600", poidsMin: 501, poidsMax: 600, plusdom: +7, sconst: 8, sust: 11 },
27: { xp: 130, poids: "601-700", plusdom: +8, sconst: 9, sust: 12 }, 27: { xp: 130, poids: "601-700", poidsMin: 601, poidsMax: 700, plusdom: +8, sconst: 9, sust: 12 },
28: { xp: 140, poids: "701-800", plusdom: +8, sconst: 9, sust: 13 }, 28: { xp: 140, poids: "701-800", poidsMin: 701, poidsMax: 800, plusdom: +8, sconst: 9, sust: 13 },
29: { xp: 150, poids: "801-900", plusdom: +9, sconst: 9, sust: 14 }, 29: { xp: 150, poids: "801-900", poidsMin: 801, poidsMax: 900, plusdom: +9, sconst: 9, sust: 14 },
30: { xp: 160, poids: "901-1000", plusdom: +9, sconst: 10, sust: 15 }, 30: { xp: 160, poids: "901-1000", poidsMin: 901, poidsMax: 1000, plusdom: +9, sconst: 10, sust: 15 },
31: { xp: 170, poids: "1001-1500", plusdom: +10, sconst: 10, sust: 16 }, 31: { xp: 170, poids: "1001-1500", poidsMin: 1001, poidsMax: 1500, plusdom: +10, sconst: 10, sust: 16 },
32: { xp: 180, poids: "1501-2000", plusdom: +11, sconst: 10, sust: 17 } 32: { xp: 180, poids: "1501-2000", poidsMin: 1501, poidsMax: 2000, plusdom: +11, sconst: 10, sust: 17 }
}; };
export class RdDCarac { export class RdDCarac {

View File

@@ -54,10 +54,10 @@ export class RdDCombatManager extends Combat {
/* -------------------------------------------- */ /* -------------------------------------------- */
async onPreDeleteCombat() { async onPreDeleteCombat() {
if (Misc.isUniqueConnectedGM()) { if (Misc.isUniqueConnectedGM()) {
await this.finDeRound({ terminer: true }); await this.finDeRound({ terminer: true })
ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`) ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`)
game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined) game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined)
.forEach(it => it.delete()); .forEach(it => it.delete())
RdDEmpoignade.deleteAllEmpoignades() RdDEmpoignade.deleteAllEmpoignades()
} }
} }
@@ -698,7 +698,7 @@ export class RdDCombat {
if (this.defender.isEntite([ENTITE_BLURETTE])) { if (this.defender.isEntite([ENTITE_BLURETTE])) {
ChatMessage.create({ ChatMessage.create({
content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`, content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
whisper: ChatMessage.getWhisperRecipients("GM") whisper: ChatUtility.getGMs()
}) })
} }
else { else {
@@ -721,7 +721,7 @@ export class RdDCombat {
activite: activite, activite: activite,
total: total total: total
}), }),
whisper: ChatMessage.getWhisperRecipients("GM") whisper: ChatUtility.getGMs()
}) })
} }
} }
@@ -846,7 +846,7 @@ export class RdDCombat {
const choixParticuliere = await ChatMessage.create({ const choixParticuliere = await ChatMessage.create({
alias: this.attacker.name, alias: this.attacker.name,
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name), whisper: ChatUtility.getOwners(this.attacker),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', {
alias: this.attacker.name, alias: this.attacker.name,
attackerId: this.attackerId, attackerId: this.attackerId,
@@ -933,7 +933,7 @@ export class RdDCombat {
// message privé: du défenseur à lui même (et aux GMs) // message privé: du défenseur à lui même (et aux GMs)
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
alias: this.attacker.name, alias: this.attacker.name,
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.defender.name), whisper: ChatUtility.getOwners(this.defender),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense),
}); });
// flag pour garder les jets d'attaque/defense // flag pour garder les jets d'attaque/defense
@@ -976,7 +976,7 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _onAttaqueEchecTotal(attackerRoll) { async _onAttaqueEchecTotal(attackerRoll) {
const choixEchecTotal = await ChatMessage.create({ const choixEchecTotal = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name), whisper: ChatUtility.getOwners(this.attacker),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', {
attackerId: this.attackerId, attackerId: this.attackerId,
attacker: this.attacker, attacker: this.attacker,
@@ -994,9 +994,9 @@ export class RdDCombat {
const arme = rollData.arme; const arme = rollData.arme;
const avecArme = !['', 'sans-armes', 'armes-naturelles'].includes(arme?.system.categorie_parade ?? ''); const avecArme = !['', 'sans-armes', 'armes-naturelles'].includes(arme?.system.categorie_parade ?? '');
const action = (rollData.attackerRoll ? (arme ? "la parade" : "l'esquive") : "l'attaque"); const action = (rollData.attackerRoll ? (arme ? "la parade" : "l'esquive") : "l'attaque");
ChatUtility.createChatWithRollMode(this.defender.name, { ChatUtility.createChatWithRollMode(
content: `<strong>Maladresse à ${action}!</strong> ` + await RdDRollTables.getMaladresse({ arme: avecArme }) { content: `<strong>Maladresse à ${action}!</strong> ` + await RdDRollTables.getMaladresse({ arme: avecArme }) },
}); this.defender)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1076,9 +1076,9 @@ export class RdDCombat {
console.log("RdDCombat._onParadeParticuliere >>>", defenderRoll); console.log("RdDCombat._onParadeParticuliere >>>", defenderRoll);
if (!defenderRoll.attackerRoll.isPart) { if (!defenderRoll.attackerRoll.isPart) {
// TODO: attaquant doit jouer résistance et peut être désarmé p132 // TODO: attaquant doit jouer résistance et peut être désarmé p132
ChatUtility.createChatWithRollMode(this.defender.name, { ChatUtility.createChatWithRollMode(
content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
}); this.defender)
} }
} }
@@ -1152,9 +1152,9 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
_onEsquiveParticuliere(rollData) { _onEsquiveParticuliere(rollData) {
console.log("RdDCombat._onEsquiveParticuliere >>>", rollData); console.log("RdDCombat._onEsquiveParticuliere >>>", rollData);
ChatUtility.createChatWithRollMode(this.defender.name, { ChatUtility.createChatWithRollMode(
content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" { content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" },
}); this.defender);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1322,10 +1322,10 @@ export class RdDCombat {
await ChatMessage.create({ await ChatMessage.create({
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData), content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData),
alias: actor.name alias: actor.name
}); })
await ChatMessage.create({ await ChatMessage.create({
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData), content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData),
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name), whisper: ChatUtility.getOwners(actor),
alias: actor.name alias: actor.name
}); });
} }

View File

@@ -17,6 +17,7 @@ import { RdDUtility } from "./rdd-utility.js";
import { FenetreRechercheTirage } from "./tirage/fenetre-recherche-tirage.js"; import { FenetreRechercheTirage } from "./tirage/fenetre-recherche-tirage.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRUtility } from "./tmr-utility.js";
import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js"; import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js";
import { ChatUtility } from "./chat-utility.js";
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/; const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
@@ -81,7 +82,7 @@ export class RdDCommands {
this.registerCommand({ path: ["/sommeil"], func: (content, msg, params) => this.sommeil(msg, params), descr: "Prépare le passage de journée pour chateau dormant" }); this.registerCommand({ path: ["/sommeil"], func: (content, msg, params) => this.sommeil(msg, params), descr: "Prépare le passage de journée pour chateau dormant" });
this.registerCommand({ path: ["/meteo"], func: (content, msg, params) => this.getMeteo(msg, params), descr: "Propose une météo marine" }); this.registerCommand({ path: ["/meteo"], func: (content, msg, params) => this.getMeteo(msg, params), descr: "Propose une météo marine" });
this.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" }); this.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.proposeName(msg, params), descr: "Génère un nom aléatoire" });
this.registerCommand({ this.registerCommand({
path: ["/tmr"], func: (content, msg, params) => this.findTMR(msg, params), path: ["/tmr"], func: (content, msg, params) => this.findTMR(msg, params),
@@ -206,26 +207,20 @@ export class RdDCommands {
/* Manage chat commands */ /* Manage chat commands */
processChatCommand(commandLine, content = '', msg = {}) { processChatCommand(commandLine, content = '', msg = {}) {
// Setup new message's visibility // Setup new message's visibility
let rollMode = game.settings.get("core", "rollMode"); ChatUtility.applyRollMode(msg)
if (["gmroll", "blindroll"].includes(rollMode)) { msg.type = 0;
msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
}
if (rollMode === "blindroll") {
msg["blind"] = true;
}
msg["type"] = 0;
if (!this.commandsTable) { if (!this.commandsTable) {
this._registerCommands(); this._registerCommands()
} }
let command = commandLine[0].toLowerCase(); let command = commandLine[0].toLowerCase();
if (this._isCommandHandled(command)) { if (this._isCommandHandled(command)) {
let params = commandLine.slice(1); let params = commandLine.slice(1);
this._processCommand(this.commandsTable, command, params, content, msg); this._processCommand(this.commandsTable, command, params, content, msg)
return true; return true
} }
return false; return false
} }
_isCommandHandled(command) { _isCommandHandled(command) {
@@ -300,7 +295,7 @@ export class RdDCommands {
async getRencontreTMR(params) { async getRencontreTMR(params) {
if (params.length == 1 || params.length == 2) { if (params.length == 1 || params.length == 2) {
return game.system.rdd.rencontresTMR.rollRencontre(params[0], params[1]) return game.system.rdd.rencontresTMR.rollRencontre(params[0], params[1])
} }
return false; return false;
} }

View File

@@ -2,19 +2,14 @@ import { ChatUtility } from "./chat-utility.js";
import { HIDE_DICE, SHOW_DICE } from "./constants.js"; import { HIDE_DICE, SHOW_DICE } from "./constants.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
function img(src) { const imgHeures = [1, 2, 3, 4, 5, 6, 7, 9, 9, 10, 11, 12].map(heure => {
return `<img src="${src}" class="dice-img" />`
}
function iconHeure(heure) {
if (heure < 10) { if (heure < 10) {
heure = '0' + heure; heure = '0' + heure;
} }
return `systems/foundryvtt-reve-de-dragon/icons/heures/hd${heure}.webp` return `<img src="systems/foundryvtt-reve-de-dragon/icons/heures/hd${heure}.webp" class="dice-img" />`
} })
const imagesHeures = [1, 2, 3, 4, 5, 6, 7, 9, 9, 10, 11, 12].map(it => iconHeure(it));
const imgSigneDragon = img(imagesHeures[4]); const imgSigneDragon = imgHeures[4]
/** De pour les jets de rencontre */ /** De pour les jets de rencontre */
export class DeTMR extends Die { export class DeTMR extends Die {
@@ -25,7 +20,7 @@ export class DeTMR extends Die {
return { return {
type: "dt", type: "dt",
font: "HeuresDraconiques", font: "HeuresDraconiques",
fontScale: 0.7, fontScale: 0.8,
labels: ['1', '2', '3', '4', '5', '6', 'd', '0'], labels: ['1', '2', '3', '4', '5', '6', 'd', '0'],
system: system system: system
} }
@@ -37,13 +32,13 @@ export class DeTMR extends Die {
} }
async evaluate(options) { async evaluate(options) {
await super.evaluate(options); await super.evaluate(options)
this.explode("x=8"); await this.reroll('r=8', { recursive: true })
return this; return this;
} }
get total() { get total() {
return this.values.filter(it => it != 8).reduce(Misc.sum(), 0); return this.values.map(it => Misc.modulo(it, 8)).reduce(Misc.sum(), 0);
} }
getResultLabel(diceTerm) { getResultLabel(diceTerm) {
@@ -56,13 +51,14 @@ export class DeTMR extends Die {
/** DeDraconique pour le D8 sans limite avec 8=>0 */ /** DeDraconique pour le D8 sans limite avec 8=>0 */
export class DeDraconique extends Die { export class DeDraconique extends Die {
/** @override */
static DENOMINATION = "r"; static DENOMINATION = "r";
static diceSoNiceData(system) { static diceSoNiceData(system) {
return { return {
type: "dr", type: "dr",
font: "HeuresDraconiques", font: "HeuresDraconiques",
fontScale: 0.7, fontScale: 0.8,
labels: ['1', '2', '3', '4', '5', '6', 'd', '0'], labels: ['1', '2', '3', '4', '5', '6', 'd', '0'],
system: system system: system
} }
@@ -75,7 +71,7 @@ export class DeDraconique extends Die {
async evaluate(options) { async evaluate(options) {
await super.evaluate(options); await super.evaluate(options);
this.explode("x=7"); await this.explode("x=7");
return this; return this;
} }
@@ -85,7 +81,7 @@ export class DeDraconique extends Die {
getResultLabel(diceTerm) { getResultLabel(diceTerm) {
switch (diceTerm.result) { switch (diceTerm.result) {
case 7: return imgSigneDragon; case 7: return imgSigneDragon
case 8: return '0'; case 8: return '0';
} }
return diceTerm.result.toString(); return diceTerm.result.toString();
@@ -102,6 +98,7 @@ export class DeHeure extends Die {
return { return {
type: "dh", type: "dh",
font: "HeuresDraconiques", font: "HeuresDraconiques",
fontScale: 1.2,
labels: ['v', 'i', 'f', 'o', 'd', 'e', 'l', 's', 'p', 'a', 'r', 'c'], labels: ['v', 'i', 'f', 'o', 'd', 'e', 'l', 's', 'p', 'a', 'r', 'c'],
system: system system: system
} }
@@ -113,15 +110,15 @@ export class DeHeure extends Die {
} }
getResultLabel(diceTerm) { getResultLabel(diceTerm) {
return img(imagesHeures[diceTerm.result - 1]); return imgHeures[diceTerm.result - 1]
} }
} }
export class RdDDice { export class RdDDice {
static init() { static init() {
CONFIG.Dice.terms[DeTMR.DENOMINATION] = DeTMR; CONFIG.Dice.terms[DeTMR.DENOMINATION] = DeTMR
CONFIG.Dice.terms[DeDraconique.DENOMINATION] = DeDraconique; CONFIG.Dice.terms[DeDraconique.DENOMINATION] = DeDraconique
CONFIG.Dice.terms[DeHeure.DENOMINATION] = DeHeure; CONFIG.Dice.terms[DeHeure.DENOMINATION] = DeHeure
} }
static onReady() { static onReady() {
@@ -132,6 +129,18 @@ export class RdDDice {
} }
} }
static diceSoNiceReady(dice3d) {
dice3d.DiceFactory.systems.keys().forEach(system => {
dice3d.addDicePreset(DeTMR.diceSoNiceData(system));
dice3d.addDicePreset(DeDraconique.diceSoNiceData(system));
dice3d.addDicePreset(DeHeure.diceSoNiceData(system));
})
}
static async rollHeure(options = { showDice: HIDE_DICE }) {
return await RdDDice.rollTotal("1dh", options) - 1
}
static async rollTotal(formula, options = { showDice: HIDE_DICE }) { static async rollTotal(formula, options = { showDice: HIDE_DICE }) {
return (await RdDDice.roll(formula, options)).total; return (await RdDDice.roll(formula, options)).total;
} }
@@ -151,21 +160,13 @@ export class RdDDice {
return array[roll - 1]; return array[roll - 1];
} }
static diceSoNiceReady(dice3d) {
for (const system of Object.keys(dice3d.DiceFactory.systems)) {
dice3d.addDicePreset(DeTMR.diceSoNiceData(system));
dice3d.addDicePreset(DeDraconique.diceSoNiceData(system));
dice3d.addDicePreset(DeHeure.diceSoNiceData(system));
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async showDiceSoNice(roll, options) { static async showDiceSoNice(roll, options) {
if (options.showDice == HIDE_DICE || !game.modules.get("dice-so-nice")?.active || !game.dice3d) { if (options.showDice == HIDE_DICE || !game.modules.get("dice-so-nice")?.active || !game.dice3d) {
return; return;
} }
let { whisper, blind } = RdDDice._getWhisperBlind(options); let { whisper, blind } = ChatUtility.applyRollMode({}, options?.rollMode);
if (options.forceDiceResult?.total) { if (options.forceDiceResult?.total) {
let terms = await RdDDice._getForcedTerms(options); let terms = await RdDDice._getForcedTerms(options);
if (terms) { if (terms) {
@@ -219,24 +220,4 @@ export class RdDDice {
await roll.evaluate(); await roll.evaluate();
return roll.total; return roll.total;
} }
static _getWhisperBlind(options) {
let whisper = undefined;
let blind = false;
let rollMode = options.rollMode ?? game.settings.get("core", "rollMode");
switch (rollMode) {
case "blindroll": //GM only
blind = true;
case "gmroll": //GM + rolling player
whisper = ChatUtility.getUsers(user => user.isGM);
break;
case "roll": //everybody
whisper = ChatUtility.getUsers(user => user.active);
break;
case "selfroll":
whisper = [game.user.id];
break;
}
return { whisper, blind };
}
} }

View File

@@ -158,9 +158,12 @@ export class RdDEmpoignade {
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender)) empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
//console.log("W.", empoignade, defender.hasArmeeMeleeEquipee()) //console.log("W.", empoignade, defender.hasArmeeMeleeEquipee())
if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) { if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) {
ChatUtility.createChatWithRollMode(attacker.name, { ChatUtility.createChatWithRollMode(
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.html`, { attacker: attacker, defender: defender }) {
}) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.html`, { attacker: attacker, defender: defender })
},
attacker
)
} else { } else {
await this.onAttaqueEmpoignadeValidee(attacker, defender) await this.onAttaqueEmpoignadeValidee(attacker, defender)
} }
@@ -213,7 +216,7 @@ export class RdDEmpoignade {
competence: attacker.getCompetenceCorpsACorps() competence: attacker.getCompetenceCorpsACorps()
} }
const msg = await ChatMessage.create({ const msg = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(attacker.name), whisper: ChatUtility.getOwners(attacker),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-immobilise.html`, rollData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-immobilise.html`, rollData)
}) })
RdDEmpoignade.$storeRollEmpoignade(msg, rollData); RdDEmpoignade.$storeRollEmpoignade(msg, rollData);
@@ -300,7 +303,7 @@ export class RdDEmpoignade {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async $onRollContrerLiberer(rollData) { static async $onRollContrerLiberer(rollData) {
let empoignade = rollData.empoignade let empoignade = rollData.empoignade
if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) { if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) {
empoignade.system.pointsemp++ empoignade.system.pointsemp++
RdDEmpoignade.$updateEtatEmpoignade(empoignade) RdDEmpoignade.$updateEtatEmpoignade(empoignade)
@@ -309,7 +312,7 @@ export class RdDEmpoignade {
empoignade.system.pointsemp-- empoignade.system.pointsemp--
RdDEmpoignade.$updateEtatEmpoignade(empoignade) RdDEmpoignade.$updateEtatEmpoignade(empoignade)
} }
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html') await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html')
if (empoignade.system.pointsemp >= 2) { if (empoignade.system.pointsemp >= 2) {
let msg = await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-empoignade-entrainer.html'); let msg = await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-empoignade-entrainer.html');

View File

@@ -79,8 +79,7 @@ export class RdDHotbar {
* Actor - open actor sheet * Actor - open actor sheet
* Journal - open journal sheet * Journal - open journal sheet
*/ */
static init() { static initHooks() {
Hooks.on('hotbarDrop', (bar, documentData, slot) => { Hooks.on('hotbarDrop', (bar, documentData, slot) => {
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill // Create item macro if rollable item - weapon, spell, prayer, trait, or skill

View File

@@ -61,12 +61,13 @@ import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js"
import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js" import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js"
import { AppAstrologie } from "./sommeil/app-astrologie.js" import { AppAstrologie } from "./sommeil/app-astrologie.js"
import { RdDItemArmure } from "./item/armure.js" import { RdDItemArmure } from "./item/armure.js"
import { AutoAdjustDarkness as AutoAdjustDarkness } from "./time/auto-adjust-darkness.js" import { AutoAdjustDarkness } from "./time/auto-adjust-darkness.js"
import { RdDCreature } from "./actor/creature.js" import { RdDCreature } from "./actor/creature.js"
import { RdDTMRDialog } from "./rdd-tmr-dialog.js" import { RdDTMRDialog } from "./rdd-tmr-dialog.js"
//import { RdDActorExportSheet } from "./actor/actor-export-sheet.js"
import { OptionsAvancees } from "./settings/options-avancees.js" import { OptionsAvancees } from "./settings/options-avancees.js"
import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js" import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium.js"
import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"
import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js"
/** /**
* RdD system * RdD system
@@ -79,7 +80,7 @@ export class SystemReveDeDragon {
const system = new SystemReveDeDragon() const system = new SystemReveDeDragon()
Hooks.once('init', async () => await system.onInit()) Hooks.once('init', async () => await system.onInit())
Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d)) Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d))
Hooks.once('ready', () => system.onReady()) Hooks.once('ready', async () => await system.onReady())
} }
constructor() { constructor() {
@@ -114,23 +115,31 @@ export class SystemReveDeDragon {
game.system.rdd = this game.system.rdd = this
this.AppAstrologie = AppAstrologie this.AppAstrologie = AppAstrologie
console.log(`Initializing Reve de Dragon System Settings`)
console.log(`Initializing Reve de Dragon System`)
// preload handlebars templates // preload handlebars templates
RdDUtility.preloadHandlebarsTemplates() RdDUtility.preloadHandlebarsTemplates()
AppPersonnageAleatoire.preloadHandlebars()
/* -------------------------------------------- */ /* -------------------------------------------- */
this.initSystemSettings() ReglesOptionnelles.initSettings()
OptionsAvancees.initSettings()
AutoAdjustDarkness.initSettings()
RdDTimestamp.initSettings()
RdDCalendrier.initSettings()
SystemCompendiums.initSettings()
DialogChronologie.initSettings()
RdDTMRDialog.initSettings()
Environnement.initSettings()
this.initSettings()
/* -------------------------------------------- */ /* -------------------------------------------- */
// Set an initiative formula for the system // Set an initiative formula for the system
CONFIG.Combat.initiative = { CONFIG.Combat.initiative = { formula: "1+(1d6/10)", decimals: 2 }
formula: "1+(1d6/10)",
decimals: 2
}
/* -------------------------------------------- */ /* -------------------------------------------- */
console.log(`Initializing Reve de Dragon Socket handlers`)
game.socket.on(SYSTEM_SOCKET_ID, async (sockmsg) => { game.socket.on(SYSTEM_SOCKET_ID, async (sockmsg) => {
console.log(">>>>> MSG RECV", sockmsg) console.log(">>>>> MSG RECV", sockmsg)
try { try {
@@ -145,6 +154,7 @@ export class SystemReveDeDragon {
/* -------------------------------------------- */ /* -------------------------------------------- */
// Define custom Entity classes // Define custom Entity classes
console.log(`Initializing Reve de Dragon Documents`)
CONFIG.Actor.documentClass = RdDBaseActor CONFIG.Actor.documentClass = RdDBaseActor
CONFIG.Item.documentClass = RdDItem CONFIG.Item.documentClass = RdDItem
CONFIG.RDD = { CONFIG.RDD = {
@@ -158,12 +168,12 @@ export class SystemReveDeDragon {
// Register sheet application classes // Register sheet application classes
Actors.unregisterSheet("core", ActorSheet) Actors.unregisterSheet("core", ActorSheet)
Actors.registerSheet(SYSTEM_RDD, RdDCommerceSheet, { types: ["commerce"], makeDefault: true }) Actors.registerSheet(SYSTEM_RDD, RdDCommerceSheet, { types: ["commerce"], makeDefault: true })
//Actors.registerSheet(SYSTEM_RDD, RdDActorExportSheet, { types: ["personnage"], makeDefault: false })
Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true }) Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true })
Actors.registerSheet(SYSTEM_RDD, RdDCreatureSheet, { types: ["creature"], makeDefault: true }) Actors.registerSheet(SYSTEM_RDD, RdDCreatureSheet, { types: ["creature"], makeDefault: true })
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }) Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true })
Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true }) Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true })
Items.unregisterSheet("core", ItemSheet) Items.unregisterSheet("core", ItemSheet)
await RdDActorExportSheet.init()
RdDItemSheet.register(RdDSigneDraconiqueItemSheet) RdDItemSheet.register(RdDSigneDraconiqueItemSheet)
RdDItemSheet.register(RdDRencontreItemSheet) RdDItemSheet.register(RdDRencontreItemSheet)
@@ -190,17 +200,12 @@ export class SystemReveDeDragon {
"tarot", "extraitpoetique", "empoignade" "tarot", "extraitpoetique", "empoignade"
], makeDefault: true ], makeDefault: true
}) })
CONFIG.Combat.documentClass = RdDCombatManager
// préparation des différents modules // préparation des différents modules
AutoAdjustDarkness.init() console.log(`Initializing Reve de Dragon Hooks and handlers`)
RdDTimestamp.init() CONFIG.Combat.documentClass = RdDCombatManager
RdDCalendrier.init() ChatUtility.init()
SystemCompendiums.init() RdDUtility.initHooks()
DialogChronologie.init()
ReglesOptionnelles.init()
OptionsAvancees.init()
RdDUtility.init()
RdDDice.init() RdDDice.init()
RdDCommands.init() RdDCommands.init()
RdDCombatManager.init() RdDCombatManager.init()
@@ -209,15 +214,14 @@ export class SystemReveDeDragon {
RdDCompendiumOrganiser.init() RdDCompendiumOrganiser.init()
EffetsDraconiques.init() EffetsDraconiques.init()
TMRUtility.init() TMRUtility.init()
await RdDTMRDialog.init() RdDHotbar.initHooks()
RdDHotbar.init()
RdDPossession.init() RdDPossession.init()
TMRRencontres.init() TMRRencontres.init()
Environnement.init()
ExportScriptarium.init() ExportScriptarium.init()
} }
initSystemSettings() { initSettings() {
// TODO: déplacer vers les modules correspondants
game.settings.register(SYSTEM_RDD, "accorder-entite-cauchemar", { game.settings.register(SYSTEM_RDD, "accorder-entite-cauchemar", {
name: "Accorder le rêve aux entités", name: "Accorder le rêve aux entités",
hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar", hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar",
@@ -316,4 +320,3 @@ export class SystemReveDeDragon {
} }
SystemReveDeDragon.start() SystemReveDeDragon.start()

View File

@@ -1,3 +1,4 @@
import { ChatUtility } from "./chat-utility.js"
const vents = [ const vents = [
{ min: 0, max: 0, valeur: 'Calme' }, { min: 0, max: 0, valeur: 'Calme' },
@@ -117,7 +118,7 @@ export class RdDMeteo {
ChatMessage.create({ ChatMessage.create({
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-meteo.html', meteo), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-meteo.html', meteo),
whisper: ChatMessage.getWhisperRecipients('GM') whisper: ChatUtility.getGMs()
}); });
} }

View File

@@ -1,4 +1,5 @@
import { RdDBaseActor } from "./actor/base-actor.js"; import { RdDBaseActor } from "./actor/base-actor.js";
import { ChatUtility } from "./chat-utility.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js"; import { RdDDice } from "./rdd-dice.js";
@@ -11,11 +12,15 @@ const words = ['pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i',
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDNameGen { export class RdDNameGen {
static async getName(msg, params) { static async proposeName(msg, params) {
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-command-nom.html`, { const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-command-nom.html`, {
nom: Misc.upperFirst(await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words)) nom: await RdDNameGen.generate()
}); });
ChatMessage.create({ content: html, whisper: ChatMessage.getWhisperRecipients("GM") }); ChatMessage.create({ content: html, whisper: ChatUtility.getGMs() });
}
static async generate() {
return Misc.upperFirst(await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words));
} }
static async onCreerActeur(event) { static async onCreerActeur(event) {

View File

@@ -91,13 +91,14 @@ export class RdDResolutionTable {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') { static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
return await ChatUtility.createChatWithRollMode(RdDResolutionTable.actorChatName(actor), { return await ChatUtility.createChatWithRollMode(
content: await RdDResolutionTable.buildRollDataHtml(rollData, template) { content: await RdDResolutionTable.buildRollDataHtml(rollData, template) },
}); actor
)
} }
static actorChatName(actor) { static actorChatName(actor) {
return actor?.name ?? game.user.name; return actor ?? game.user.name;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -138,14 +139,14 @@ export class RdDResolutionTable {
if (carac == 0) { if (carac == 0) {
return NaN; return NaN;
} }
if (rolled >= carac){ if (rolled >= carac) {
const upper = Math.ceil(rolled/carac); const upper = Math.ceil(rolled / carac);
return 2*upper -10 return 2 * upper - 10
} }
if (rolled > Math.floor(carac/2)) { if (rolled > Math.floor(carac / 2)) {
return -8 return -8
} }
if (rolled > Math.floor(carac/4)) { if (rolled > Math.floor(carac / 4)) {
return -9 return -9
} }
if (rolled > 1) { if (rolled > 1) {
@@ -265,7 +266,7 @@ export class RdDResolutionTable {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static subTable(carac, level, delta = { carac: 2, level: 5}) { static subTable(carac, level, delta = { carac: 2, level: 5 }) {
return { return {
carac, carac,
level, level,
@@ -287,8 +288,8 @@ export class RdDResolutionTable {
carac: carac, carac: carac,
difficulte: level, difficulte: level,
min: minLevel, min: minLevel,
rows: Misc.intArray(minCarac, maxCarac+1), rows: Misc.intArray(minCarac, maxCarac + 1),
cols: Misc.intArray(minLevel, maxLevel+1) cols: Misc.intArray(minLevel, maxLevel + 1)
}); });
} }

View File

@@ -34,7 +34,7 @@ const TMR_DISPLAY_SIZE = {
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDTMRDialog extends Dialog { export class RdDTMRDialog extends Dialog {
static async init() { static initSettings() {
game.settings.register(SYSTEM_RDD, TMR_DISPLAY_SIZE.code, { game.settings.register(SYSTEM_RDD, TMR_DISPLAY_SIZE.code, {
name: 'Taille des cases des TMR', name: 'Taille des cases des TMR',
hint: "Taille en pixel des cases des TMR (réglable directement dans la fenêtre des TMR)", hint: "Taille en pixel des cases des TMR (réglable directement dans la fenêtre des TMR)",
@@ -50,7 +50,7 @@ export class RdDTMRDialog extends Dialog {
await PixiTMR.init() await PixiTMR.init()
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', tmrData); let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', tmrData);
if (tmrData.mode != 'visu' && !game.user.isGM) { if (tmrData.mode != 'visu' && !game.user.isGM) {
ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatMessage.getWhisperRecipients("GM") }); ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatUtility.getGMs() });
} }
return new RdDTMRDialog(html, actor, tmrData) return new RdDTMRDialog(html, actor, tmrData)
} }
@@ -82,7 +82,7 @@ export class RdDTMRDialog extends Dialog {
this.rencontreState = 'aucune'; this.rencontreState = 'aucune';
this.subdialog = undefined this.subdialog = undefined
this.displaySize = undefined this.displaySize = undefined
if (!this.viewOnly) { if (!this.viewOnly && !game.user.isGM) {
this._tellToGM(this.actor.name + " monte dans les terres médianes (" + tmrData.mode + ")"); this._tellToGM(this.actor.name + " monte dans les terres médianes (" + tmrData.mode + ")");
} }
this.callbacksOnAnimate = []; this.callbacksOnAnimate = [];
@@ -496,7 +496,7 @@ export class RdDTMRDialog extends Dialog {
rencData.message = this.formatMessageRencontre(rencData, result.message); rencData.message = this.formatMessageRencontre(rencData, result.message);
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getOwners(this.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData)
}); });
@@ -571,12 +571,20 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
_tellToGM(message) { _tellToGM(message) {
ChatMessage.create({ content: message, user: game.user.id, whisper: ChatMessage.getWhisperRecipients("GM") }); ChatMessage.create({
user: game.user.id,
content: message,
whisper: ChatUtility.getGMs()
});
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_tellToUserAndGM(message) { _tellToUserAndGM(message) {
ChatMessage.create({ content: message, user: game.user.id, whisper: [game.user.id].concat(ChatMessage.getWhisperRecipients("GM")) }); ChatMessage.create({
user: game.user.id,
content: message,
whisper: ChatUtility.getUserAndGMs()
})
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -715,7 +723,7 @@ export class RdDTMRDialog extends Dialog {
} }
rollData.poesie = await Poetique.getExtrait(); rollData.poesie = await Poetique.getExtrait();
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getOwners(this.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
}); });
if (rollData.rolled.isEchec) { if (rollData.rolled.isEchec) {
@@ -739,7 +747,7 @@ export class RdDTMRDialog extends Dialog {
if (this.isCaseMaitrisee(tmr.coord)) { if (this.isCaseMaitrisee(tmr.coord)) {
ChatMessage.create({ ChatMessage.create({
content: tmr.label + ": cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>", content: tmr.label + ": cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>",
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatUtility.getOwners(this.actor)
}); });
return false; return false;
} }
@@ -751,14 +759,14 @@ export class RdDTMRDialog extends Dialog {
if (tmr.type == 'pont' && EffetsDraconiques.isPontImpraticable(this.actor)) { if (tmr.type == 'pont' && EffetsDraconiques.isPontImpraticable(this.actor)) {
ChatMessage.create({ ChatMessage.create({
content: tmr.label + ": Vous êtes sous le coup d'une Impraticabilité des Ponts : ce pont doit être maîtrisé comme une case humide.", content: tmr.label + ": Vous êtes sous le coup d'une Impraticabilité des Ponts : ce pont doit être maîtrisé comme une case humide.",
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatUtility.getOwners(this.actor)
}); });
return true; return true;
} }
if (this.isCaseInondee(tmr.coord)) { if (this.isCaseInondee(tmr.coord)) {
ChatMessage.create({ ChatMessage.create({
content: tmr.label + ": cette case est inondée, elle doit être maîtrisée comme une case humide.", content: tmr.label + ": cette case est inondée, elle doit être maîtrisée comme une case humide.",
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatUtility.getOwners(this.actor)
}); });
return true; return true;
} }
@@ -832,7 +840,7 @@ export class RdDTMRDialog extends Dialog {
} }
rollData.poesie = await Poetique.getExtrait(); rollData.poesie = await Poetique.getExtrait();
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getOwners(this.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
}); });
if (rollData.rolled.isEchec) { if (rollData.rolled.isEchec) {
@@ -882,17 +890,16 @@ export class RdDTMRDialog extends Dialog {
const reserveSecurite = EffetsDraconiques.isReserveEnSecurite(this.actor); const reserveSecurite = EffetsDraconiques.isReserveEnSecurite(this.actor);
const reserveExtensible = this.isReserveExtensible(coord); const reserveExtensible = this.isReserveExtensible(coord);
if (!EffetsDraconiques.isUrgenceDraconique(this.actor) && (reserveSecurite || reserveExtensible)) { if (!EffetsDraconiques.isUrgenceDraconique(this.actor) && (reserveSecurite || reserveExtensible)) {
const msg = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-demande-declencher-sort.hbs`, {
actor: this.actor,
sorts: sorts,
coord: coord,
tete: { reserveSecurite: reserveSecurite, reserveExtensible: reserveExtensible }
})
ChatMessage.create({ ChatMessage.create({
content: msg, content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-demande-declencher-sort.hbs`, {
whisper: ChatMessage.getWhisperRecipients(game.user.name) actor: this.actor,
}); sorts: sorts,
return; coord: coord,
tete: { reserveSecurite: reserveSecurite, reserveExtensible: reserveExtensible }
}),
whisper: ChatUtility.getOwners(this.actor)
})
return
} }
await this.processSortReserve(sorts[0]); await this.processSortReserve(sorts[0]);
} }
@@ -906,9 +913,8 @@ export class RdDTMRDialog extends Dialog {
this.processSortReserve(sort); this.processSortReserve(sort);
} else { } else {
ChatMessage.create({ ChatMessage.create({
content: content: "Une erreur est survenue : impossible de récupérer le sort en réserve demandé.",
"Une erreur est survenue : impossible de récupérer le sort en réserve demandé.", whisper: ChatUtility.getOwners(this.actor)
whisper: ChatMessage.getWhisperRecipients(game.user.name),
}); });
} }
} }
@@ -1091,7 +1097,7 @@ export class RdDTMRDialog extends Dialog {
async notifierResonanceSigneDraconique(coord) { async notifierResonanceSigneDraconique(coord) {
if (!this.viewOnly && this.actor.isResonanceSigneDraconique(coord)) { if (!this.viewOnly && this.actor.isResonanceSigneDraconique(coord)) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getOwners(this.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { alias: this.actor.name, typeTMR: TMRUtility.getTMRType(coord) }) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { alias: this.actor.name, typeTMR: TMRUtility.getTMRType(coord) })
}); });
} }

View File

@@ -99,9 +99,7 @@ export class RdDUtility {
// persistent handling of conteneur show/hide // persistent handling of conteneur show/hide
static afficheContenu = {} static afficheContenu = {}
/* -------------------------------------------- */ /* -------------------------------------------- */
static async init() { static async initHooks() {
Hooks.on("renderChatMessage", async (app, html, msg) => await ChatUtility.onRenderChatMessage(app, html, msg))
Hooks.on("createChatMessage", async (chatMessage, options, id) => await ChatUtility.onCreateChatMessage(chatMessage, options, id))
Hooks.on('renderChatLog', (log, html, chatLog) => RdDUtility.chatListeners(html)) Hooks.on('renderChatLog', (log, html, chatLog) => RdDUtility.chatListeners(html))
} }
@@ -292,6 +290,7 @@ export class RdDUtility {
Handlebars.registerHelper('array-includes', (array, value) => array.includes(value)); Handlebars.registerHelper('array-includes', (array, value) => array.includes(value));
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
Handlebars.registerHelper('isLastIndex', (index, list) => index + 1 >= list.length);
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option)); Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option));
Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name))); Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name)));
Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences)); Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
@@ -644,18 +643,16 @@ export class RdDUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static onSocketMessage(sockmsg) { static onSocketMessage(sockmsg) {
switch (sockmsg.msg) { switch (sockmsg.msg) {
case "msg_gm_chat_message":
return ChatUtility.handleGMChatMessage(sockmsg.data);
case "msg_app_astrologie_refresh": case "msg_app_astrologie_refresh":
return Hooks.callAll(APP_ASTROLOGIE_REFRESH); return Hooks.callAll(APP_ASTROLOGIE_REFRESH)
case "msg_request_nombre_astral": case "msg_request_nombre_astral":
return game.system.rdd.calendrier.requestNombreAstral(sockmsg.data); return game.system.rdd.calendrier.requestNombreAstral(sockmsg.data)
case "msg_tmr_move": case "msg_tmr_move":
let actor = game.actors.get(sockmsg.data.actorId); let actor = game.actors.get(sockmsg.data.actorId);
if (actor.isOwner || game.user.isGM) { if (actor.isOwner || game.user.isGM) {
actor.refreshTMRView(); actor.refreshTMRView()
} }
break; break
} }
} }
@@ -807,17 +804,13 @@ export class RdDUtility {
user: game.user.id, user: game.user.id,
rollMode: modeOverride || game.settings.get("core", "rollMode"), rollMode: modeOverride || game.settings.get("core", "rollMode"),
content: content content: content
}; }
ChatUtility.applyRollMode(chatData)
if (["gmroll", "blindroll"].includes(chatData.rollMode)) chatData["whisper"] = ChatMessage.getWhisperRecipients("GM").map(u => u.id);
if (chatData.rollMode === "blindroll") chatData["blind"] = true;
else if (chatData.rollMode === "selfroll") chatData["whisper"] = [game.user];
if (forceWhisper) { // Final force ! if (forceWhisper) { // Final force !
chatData["speaker"] = ChatMessage.getSpeaker(); chatData.speaker = ChatMessage.getSpeaker();
chatData["whisper"] = ChatMessage.getWhisperRecipients(forceWhisper); chatData.whisper = ChatMessage.getWhisperRecipients(forceWhisper);
} }
return chatData; return chatData;
} }
@@ -880,7 +873,7 @@ export class RdDUtility {
const current = game.system.rdd.calendrier.heureCourante(); const current = game.system.rdd.calendrier.heureCourante();
ChatMessage.create({ ChatMessage.create({
content: `A l'heure de <strong>${current.label}</strong>, le modificateur de Chance/Malchance est de <strong>${Misc.toSignedString(ajustement)}</strong> pour l'heure de naissance <strong>${heure.label}</strong>.`, content: `A l'heure de <strong>${current.label}</strong>, le modificateur de Chance/Malchance est de <strong>${Misc.toSignedString(ajustement)}</strong> pour l'heure de naissance <strong>${heure.label}</strong>.`,
whisper: ChatMessage.getWhisperRecipients("GM") whisper: ChatUtility.getGMs()
}); });
} }
else if (heureNaissance) { else if (heureNaissance) {
@@ -899,7 +892,7 @@ export class RdDUtility {
if (compName.includes('Thanatos')) { if (compName.includes('Thanatos')) {
let message = "Vous avez mis des points d'Expérience dans la Voie de Thanatos !<br>Vous devez réduire manuellement d'un même montant d'XP une autre compétence Draconique."; let message = "Vous avez mis des points d'Expérience dans la Voie de Thanatos !<br>Vous devez réduire manuellement d'un même montant d'XP une autre compétence Draconique.";
ChatMessage.create({ ChatMessage.create({
whisper: ChatMessage.getWhisperRecipients(game.user.name), whisper: ChatUtility.getUserAndGMs(),
content: message content: message
}); });
} }

View File

@@ -4,11 +4,11 @@ import { Misc } from "../misc.js"
export const EXPORT_CSV_SCRIPTARIUM = 'export-csv-scriptarium' export const EXPORT_CSV_SCRIPTARIUM = 'export-csv-scriptarium'
const OPTIONS_AVANCEES = [ const OPTIONS_AVANCEES = [
{ group: 'Menus', name: EXPORT_CSV_SCRIPTARIUM, descr: "Proposer le menu d'export csv Scriptarium (raffraichissement requis)" }, { group: 'Menus', name: EXPORT_CSV_SCRIPTARIUM, descr: "Proposer le menu d'export csv Scriptarium" },
] ]
export class OptionsAvancees extends FormApplication { export class OptionsAvancees extends FormApplication {
static init() { static initSettings() {
for (const regle of OPTIONS_AVANCEES) { for (const regle of OPTIONS_AVANCEES) {
const name = regle.name const name = regle.name
const id = OptionsAvancees._getId(name) const id = OptionsAvancees._getId(name)

View File

@@ -46,7 +46,7 @@ const listeReglesOptionnelles = [
const uniquementJoueur = listeReglesOptionnelles.filter(it => it.uniquementJoueur).map(it=>it.name); const uniquementJoueur = listeReglesOptionnelles.filter(it => it.uniquementJoueur).map(it=>it.name);
export class ReglesOptionnelles extends FormApplication { export class ReglesOptionnelles extends FormApplication {
static init() { static initSettings() {
for (const regle of listeReglesOptionnelles) { for (const regle of listeReglesOptionnelles) {
const name = regle.name; const name = regle.name;
const id = ReglesOptionnelles._getIdRegle(name); const id = ReglesOptionnelles._getIdRegle(name);

View File

@@ -25,7 +25,7 @@ const CONFIGURABLE_COMPENDIUMS = {
* ======= Gestion des accès aux compendiums systèmes (ou surchargés) ======= * ======= Gestion des accès aux compendiums systèmes (ou surchargés) =======
*/ */
export class SystemCompendiums extends FormApplication { export class SystemCompendiums extends FormApplication {
static init() { static initSettings() {
Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => { Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => {
const definition = CONFIGURABLE_COMPENDIUMS[compendium]; const definition = CONFIGURABLE_COMPENDIUMS[compendium];
foundry.utils.mergeObject(definition, { foundry.utils.mergeObject(definition, {
@@ -236,12 +236,12 @@ export class CompendiumTableHelpers {
let max = 0; let max = 0;
const total = rows.map(it => it.frequence).reduce(Misc.sum(), 0); const total = rows.map(it => it.frequence).reduce(Misc.sum(), 0);
return rows.map(row => { return rows.map(row => {
const frequence = row.frequence; const frequence = row.frequence
row.min = max + 1; row.min = max + 1
row.max = max + frequence; row.max = max + frequence
row.total = total row.total = total
max += frequence; max += frequence
return row; return row
}) })
} }
static async getRandom(table, type, subTypes = ['objet'], forcedRoll = undefined, localisation = undefined) { static async getRandom(table, type, subTypes = ['objet'], forcedRoll = undefined, localisation = undefined) {
@@ -260,8 +260,8 @@ export class CompendiumTableHelpers {
} }
const total = table[0].total; const total = table[0].total;
const formula = `1d${total}`; const formula = `1d${total}`;
if (forcedRoll == undefined && (forcedRoll > total || forcedRoll <= 0)) { if (forcedRoll != undefined && (forcedRoll > total || forcedRoll <= 0)) {
ui.notifications.warn(`Jet de rencontre ${forcedRoll} en dehors de la table [1..${total}], le jet est relancé`); ui.notifications.warn(`Jet forcé ${forcedRoll} en dehors de la table [1..${total}], le jet est relancé`);
forcedRoll = undefined; forcedRoll = undefined;
} }
const roll = forcedRoll ? { total: forcedRoll, formula } : await RdDDice.roll(formula, { showDice: HIDE_DICE }); const roll = forcedRoll ? { total: forcedRoll, formula } : await RdDDice.roll(formula, { showDice: HIDE_DICE });
@@ -276,7 +276,7 @@ export class CompendiumTableHelpers {
return; return;
} }
const percentages = (row.total == 100) ? '%' : '' const percentages = (row.total == 100) ? '%' : ''
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.html', { const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.hbs', {
roll: row.roll, roll: row.roll,
document: row.document, document: row.document,
percentages, percentages,
@@ -291,12 +291,12 @@ export class CompendiumTableHelpers {
sound: CONFIG.sounds.dice, sound: CONFIG.sounds.dice,
content: flavorContent content: flavorContent
}; };
await ChatUtility.createChatWithRollMode(game.user.id, messageData) await ChatUtility.createChatWithRollMode(messageData)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async tableToChatMessage(table, type, subTypes, typeName = undefined) { static async tableToChatMessage(table, type, subTypes, typeName = undefined) {
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table.html', { const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table.hbs', {
img: RdDItem.getDefaultImg(subTypes[0]), img: RdDItem.getDefaultImg(subTypes[0]),
typeName: typeName ?? Misc.typeName(type, subTypes[0]), typeName: typeName ?? Misc.typeName(type, subTypes[0]),
table, table,
@@ -304,10 +304,10 @@ export class CompendiumTableHelpers {
}); });
const messageData = { const messageData = {
user: game.user.id, user: game.user.id,
whisper: game.user.id, whisper: [game.user],
content: flavorContent content: flavorContent
}; };
await ChatUtility.createChatWithRollMode(game.user.id, messageData) await ChatUtility.createChatWithRollMode(messageData)
} }
} }

View File

@@ -4,7 +4,7 @@ export const AUTO_ADJUST_DARKNESS = "auto-adjust-darkness";
export class AutoAdjustDarkness { export class AutoAdjustDarkness {
static init() { static initSettings() {
game.settings.register(SYSTEM_RDD, AUTO_ADJUST_DARKNESS, { game.settings.register(SYSTEM_RDD, AUTO_ADJUST_DARKNESS, {
name: AUTO_ADJUST_DARKNESS, name: AUTO_ADJUST_DARKNESS,
scope: "world", scope: "world",

View File

@@ -15,7 +15,7 @@ const TEMPLATE_CALENDRIER = "systems/foundryvtt-reve-de-dragon/templates/time/ca
const INITIAL_CALENDAR_POS = { top: 200, left: 200, horlogeAnalogique: true }; const INITIAL_CALENDAR_POS = { top: 200, left: 200, horlogeAnalogique: true };
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDCalendrier extends Application { export class RdDCalendrier extends Application {
static init() { static initSettings() {
game.settings.register(SYSTEM_RDD, "liste-nombre-astral", { game.settings.register(SYSTEM_RDD, "liste-nombre-astral", {
name: "liste-nombre-astral", name: "liste-nombre-astral",
scope: "world", scope: "world",
@@ -227,7 +227,7 @@ export class RdDCalendrier extends Application {
/* -------------------------------------------- */ /* -------------------------------------------- */
async ajouterNombreAstral(indexDate) { async ajouterNombreAstral(indexDate) {
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: HIDE_DICE, rollMode: "selfroll" }); const nombreAstral = await RdDDice.rollHeure( { showDice: HIDE_DICE, rollMode: "selfroll" });
return { return {
nombreAstral: nombreAstral, nombreAstral: nombreAstral,
lectures: [], lectures: [],

View File

@@ -49,7 +49,7 @@ const FORMULES_PERIODE = [
export class RdDTimestamp { export class RdDTimestamp {
static init() { static initSettings() {
game.settings.register(SYSTEM_RDD, WORLD_TIMESTAMP_SETTING, { game.settings.register(SYSTEM_RDD, WORLD_TIMESTAMP_SETTING, {
name: WORLD_TIMESTAMP_SETTING, name: WORLD_TIMESTAMP_SETTING,
scope: "world", scope: "world",

View File

@@ -105,7 +105,7 @@ export class TMRRencontres {
/* -------------------------------------------- */ /* -------------------------------------------- */
async $chatRolledRencontre(row, rencontre, tmr) { async $chatRolledRencontre(row, rencontre, tmr) {
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll-rencontre.html', const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll-rencontre.hbs',
{ {
roll: row.roll, roll: row.roll,
rencontre, rencontre,

View File

@@ -30,7 +30,7 @@ export class EffetsRencontre {
static $reve_plus = async (actor, reve) => { static $reve_plus = async (actor, reve) => {
if (!ReglesOptionnelles.isUsing("recuperation-reve") && reve < 0) { if (!ReglesOptionnelles.isUsing("recuperation-reve") && reve < 0) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name), whisper: ChatUtility.getOwners(actor),
content: `Pas de récupération de rêve (${reve} points ignorés)` content: `Pas de récupération de rêve (${reve} points ignorés)`
}); });
return return
@@ -112,7 +112,7 @@ export class EffetsRencontre {
poesie: await Poetique.getExtrait() poesie: await Poetique.getExtrait()
}) })
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(context.actor.name), whisper: ChatUtility.getOwners(context.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
}); });
} }
@@ -127,7 +127,7 @@ export class EffetsRencontre {
} }
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getOwners(context.actor),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context) content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context)
}); });
} }

View File

@@ -28,7 +28,7 @@ export class PresentCites extends Draconique {
let existants = actor.items.filter(it => this.isCase(it)).map(it => it.system.coord); let existants = actor.items.filter(it => this.isCase(it)).map(it => it.system.coord);
if (existants.length > 0) { if (existants.length > 0) {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getOwners(actor),
content: "Vous avez encore des présents dans des cités, vous devrez tirer une autre tête pour remplacer celle ci!" content: "Vous avez encore des présents dans des cités, vous devrez tirer une autre tête pour remplacer celle ci!"
}) })
} }

View File

@@ -19,7 +19,7 @@ export class UrgenceDraconique extends Draconique {
// La queue se transforme en idée fixe // La queue se transforme en idée fixe
const ideeFixe = await RdDRollTables.getIdeeFixe(); const ideeFixe = await RdDRollTables.getIdeeFixe();
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), whisper: ChatUtility.getOwners(actor),
content: `En l'absence de sorts en réserve, l'urgence draconique de ${actor.name} se transforme en ${ideeFixe.name}` content: `En l'absence de sorts en réserve, l'urgence draconique de ${actor.name} se transforme en ${ideeFixe.name}`
}); });
await actor.createEmbeddedDocuments('Item', [ideeFixe]); await actor.createEmbeddedDocuments('Item', [ideeFixe]);

View File

@@ -175,7 +175,7 @@ export class DialogFatigueVoyage extends Dialog {
.forEach(async it => { .forEach(async it => {
const perteFatigue = fatigueBase + it.ajustement const perteFatigue = fatigueBase + it.ajustement
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(it.actor.name), whisper: ChatUtility.getOwners(it.actor),
content: await renderTemplate( content: await renderTemplate(
'systems/foundryvtt-reve-de-dragon/templates/voyage/chat-fatigue_voyage.hbs', 'systems/foundryvtt-reve-de-dragon/templates/voyage/chat-fatigue_voyage.hbs',
foundry.utils.mergeObject(it, foundry.utils.mergeObject(it,

View File

@@ -326,7 +326,7 @@ table {border: 1px solid #7a7971;}
display: grid; display: grid;
grid-column: span 2 / span 2; grid-column: span 2 / span 2;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px; gap: 30px;
margin: 10px 0; margin: 10px 0;
padding: 0; padding: 0;
} }
@@ -411,6 +411,11 @@ table {border: 1px solid #7a7971;}
text-align: left; text-align: left;
} }
.flex-group-top {
vertical-align: top;
align-self: start;
}
.flex-group-right { .flex-group-right {
-webkit-box-pack: end; -webkit-box-pack: end;
-ms-flex-pack: end; -ms-flex-pack: end;
@@ -562,7 +567,11 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
.dice-img { .dice-img {
border-width: 0; border-width: 0;
max-width: 1.5rem;
max-height: 1.5rem;
vertical-align: top;
} }
.in-text-img { .in-text-img {
max-width: 1.2em; max-width: 1.2em;
max-height: 1.2em; max-height: 1.2em;
@@ -675,6 +684,7 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
} }
.carac-label { .carac-label {
font-weight: bold;
flex-basis: 40%; flex-basis: 40%;
} }
.rdd.sheet .window-content .sheet-body .carac-list .caracteristique > .utiliser-attribut { .rdd.sheet .window-content .sheet-body .carac-list .caracteristique > .utiliser-attribut {
@@ -1183,9 +1193,6 @@ ul.chat-list li:nth-child(odd) {
padding: 0.5rem; padding: 0.5rem;
cursor: pointer; cursor: pointer;
} }
.carac-label {
font-weight: bold;
}
.list-item { .list-item {
margin: 0.1rem; margin: 0.1rem;
box-shadow: inset 0px 0px 1px #00000096; box-shadow: inset 0px 0px 1px #00000096;

View File

@@ -1,8 +1,8 @@
{ {
"id": "foundryvtt-reve-de-dragon", "id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon", "title": "Rêve de Dragon",
"version": "12.0.10", "version": "12.0.15",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.10.zip", "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.15.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json", "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json",
"changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md", "changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md",
"compatibility": { "compatibility": {

View File

@@ -9,9 +9,9 @@
<div class="flexrow"> <div class="flexrow">
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1> <h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
<div class="header-buttons"> <div class="header-buttons">
<span class="encaisser-direct"><a><img class="button-img" src="icons/svg/bones.svg" data-tooltip="Encaisser des dommages"/></a></span> <span><a class="button-encaissement"><img class="button-img" src="icons/svg/bones.svg" data-tooltip="Encaisser des dommages"/></a></span>
{{#if @root.options.isGM}} {{#if @root.options.isGM}}
<span class="remise-a-neuf"><a><img class="button-img" src="icons/svg/regen.svg" data-tooltip="Remise à neuf"/></a></span> <span><a class="button-remise-a-neuf"><img class="button-img" src="icons/svg/regen.svg" data-tooltip="Remise à neuf"/></a></span>
{{/if}} {{/if}}
</div> </div>
</div> </div>

View File

@@ -9,9 +9,9 @@
<div class="flexrow"> <div class="flexrow">
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1> <h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
<div class="header-buttons"> <div class="header-buttons">
<span class="encaisser-direct"><a><img class="button-img" src="icons/svg/bones.svg" data-tooltip="Encaisser des dommages"/></a></span> <span><a class="button-encaissement"><img class="button-img" src="icons/svg/bones.svg" data-tooltip="Encaisser des dommages"/></a></span>
{{#if @root.options.isGM}} {{#if @root.options.isGM}}
<span class="remise-a-neuf"><a><img class="button-img" src="icons/svg/regen.svg" data-tooltip="Remise à neuf"/></a></span> <span><a class="button-remise-a-neuf"><img class="button-img" src="icons/svg/regen.svg" data-tooltip="Remise à neuf"/></a></span>
{{/if}} {{/if}}
</div> </div>
</div> </div>

View File

@@ -205,6 +205,7 @@
<label for="system.yeux">Yeux :</label> <label for="system.yeux">Yeux :</label>
<input class="flex-grow" type="text" name="system.yeux" value="{{system.yeux}}" data-dtype="String"/> <input class="flex-grow" type="text" name="system.yeux" value="{{system.yeux}}" data-dtype="String"/>
</li> </li>
<a class="chat-card-button description-aleatoire" data-tooltip="Déterminer aléatoirement les détails de description">Description <i class="fa-solid fa-dice-d20"></i></a>
</ul> </ul>
</article> </article>

View File

@@ -7,7 +7,7 @@
<label class="carac-xp"/> <label class="carac-xp"/>
{{else}} {{else}}
{{#if carac.derivee}} {{#if carac.derivee}}
<span class="carac-label" name="system.carac.{{key}}.label"><a name={{key}}>{{carac.label}}</a></span> <span class="carac-label" name="system.carac.{{key}}.label"><a class="roll-carac" data-carac-name={{key}}>{{carac.label}}</a></span>
<label class="competence-value">{{carac.value}}</label> <label class="competence-value">{{carac.value}}</label>
<label class="carac-xp"/> <label class="carac-xp"/>
{{else}} {{else}}
@@ -22,7 +22,7 @@
</a> </a>
</span> </span>
{{else}} {{else}}
<span class="carac-label tooltip" name="system.carac.{{key}}.label"><a name={{key}}>{{carac.label}}</a></span> <span class="carac-label tooltip" name="system.carac.{{key}}.label"><a class="roll-carac" data-carac-name={{key}}>{{carac.label}}</a></span>
{{/if}} {{/if}}
<input class="carac-value" type="text" name="system.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} /> <input class="carac-value" type="text" name="system.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
<span class="carac-xp tooltip"> <span class="carac-xp tooltip">

View File

@@ -13,7 +13,7 @@
data-competence-name="{{arme.system.competence}}" data-competence-name="{{arme.system.competence}}"
data-tooltip="{{arme.name}}: niveau {{plusMoins arme.system.niveau}}"> data-tooltip="{{arme.name}}: niveau {{plusMoins arme.system.niveau}}">
<span class="arme-label"> <span class="arme-label">
<a> <a class="roll-arme">
{{#if arme.img}} {{#if arme.img}}
<img class="sheet-competence-img" src="{{arme.img}}" data-tooltip="{{arme.name}}"/> <img class="sheet-competence-img" src="{{arme.img}}" data-tooltip="{{arme.name}}"/>
{{/if}} {{/if}}
@@ -32,7 +32,7 @@
<li class="item flexrow list-item" data-item-id="{{esq._id}}" <li class="item flexrow list-item" data-item-id="{{esq._id}}"
data-tooltip="{{esq.name}}: niveau {{plusMoins esq.system.niveau}}"> data-tooltip="{{esq.name}}: niveau {{plusMoins esq.system.niveau}}">
<span class="competence-label"> <span class="competence-label">
<a class="competence-label" name="{{esq.name}}"> <a class="roll-competence" name="{{esq.name}}">
<img class="sheet-competence-img" src="{{esq.img}}" /> <img class="sheet-competence-img" src="{{esq.img}}" />
<span>{{esq.name}}</span> <span>{{esq.name}}</span>
</a> </a>

View File

@@ -1,7 +1,7 @@
<ol class="item-list alterne-list"> <ol class="item-list alterne-list">
{{#each (trier competences) as |comp key|}} {{#each (trier competences) as |comp key|}}
<li class="item flexrow list-item" data-item-id="{{comp._id}}"> <li class="item flexrow list-item" data-item-id="{{comp._id}}">
<a class="competence-label"> <a class="competence-label roll-competence">
<img class="sheet-competence-img" src="{{comp.img}}" data-tooltip="{{comp.name}}"/> <img class="sheet-competence-img" src="{{comp.img}}" data-tooltip="{{comp.name}}"/>
<span>{{comp.name}}</span> <span>{{comp.name}}</span>
</a> </a>

View File

@@ -1,17 +1,19 @@
{{#unless system.isHidden}} {{#unless system.isHidden}}
<li class="item flexrow list-item {{#if system.isLevelUp}}xp-level-up tooltip{{/if}}" data-item-id="{{_id}}"> <li class="item flexrow list-item {{#if system.isLevelUp}}xp-level-up{{/if}}" data-item-id="{{_id}}">
<a class="competence-label" name="{{name}}" data-tooltip="Niveau {{plusMoins system.niveau}} en {{name}}"> <span class="tooltip">
<img class="sheet-competence-img" src="{{img}}"/> <a class="competence-label roll-competence" name="{{name}}" data-tooltip="Niveau {{plusMoins system.niveau}} en {{name}}">
<span>{{name}}</span> <img class="sheet-competence-img" src="{{img}}"/>
</a> <span>{{name}}</span>
</a>
{{#if system.isLevelUp}}
<span class="tooltiptext ttt-levelup">Vous pouvez dépenser {{system.xpNext}} points d'Experience pour augmenter de 1 votre compétence {{name}}</span> {{#if system.isLevelUp}}
<a class="competence-xp-augmenter" compname="{{name}}"> <span class="tooltiptext ttt-levelup">Vous pouvez dépenser {{system.xpNext}} points d'Experience pour augmenter de 1 votre compétence {{name}}</span>
<i class="fas fa-arrow-alt-circle-up"></i> <a class="competence-xp-augmenter" compname="{{name}}">
</a> <i class="fas fa-arrow-alt-circle-up"></i>
{{/if}} </a>
{{/if}}
</span>
<input class="competence-value" type="text" compname="{{name}}" name="comp-value-{{name}}" <input class="competence-value" type="text" compname="{{name}}" name="comp-value-{{name}}"
value="{{plusMoins system.niveau}}" data-dtype="number" value="{{plusMoins system.niveau}}" data-dtype="number"
{{#if (or (not @root.options.vueDetaillee) @root.options.vueArchetype)}}disabled{{/if}} /> {{#if (or (not @root.options.vueDetaillee) @root.options.vueArchetype)}}disabled{{/if}} />
@@ -50,7 +52,7 @@
{{/if}} {{/if}}
&nbsp; &nbsp;
<a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a> <a class="item-montrer" data-tooltip="Montrer"><i class="fas fa-comment"></i></a>
</div> </div>
{{/if}} {{/if}}
</li> </li>
{{/unless}} {{/unless}}

View File

@@ -0,0 +1,130 @@
<form class="{{cssClass}}" autocomplete="off" >
<section class="sheet-header">
<div class="flexrow">
<div class="flex-group-left flex-grow-0-5">
<h1 class="charname">{{name}}
</h1>
</div>
<div class="flex-group-right flex-grow-3">
{{#if system.attributs.hautrevant.value}}
<a class="button-tmr" data-tooltip="Montée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}>
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg"/>
</a>
<a class="button-tmr-rapide" data-tooltip="Montée accélérée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}>
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg"/>
</a>
<a class="button-tmr-visu" data-tooltip="Regarder les Terres M&eacute;dianes">
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-view.svg"/>
</a>
{{/if}}
<a class="button-appel-chance"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/appel-chance.svg" data-tooltip="Appel à la chance"/></a>
<a class="button-encaissement"><img class="button-img" src="icons/svg/bones.svg" data-tooltip="Encaisser des dommages"/></a>
<a class="button-ethylisme"><img class="button-img" src="icons/svg/tankard.svg" data-tooltip="Boire"/></a>
<a class="button-repos"><img class="button-img" src="icons/svg/sleep.svg" data-tooltip="Se reposer"/></a>
{{#if @root.options.isGM}}
<a class="button-remise-a-neuf"><img class="button-img" src="icons/svg/regen.svg" data-tooltip="Remise à neuf"/></a>
{{/if}}
{{#if options.exportScriptarium}}
<a class="button-export">
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/scriptarium.svg" data-tooltip="Export format Scriptarium"/>
</a>
{{/if}}
</div>
</div>
</section>
<section class="sheet-body" style=:"margin-bottom: 3rem;">
<div>
<strong>{{export.name.value}}</strong>{{#if export.description.value}}, {{export.description.value}}{{/if}}
</div>
<hr>
<div class="grid-2col">
<div class="flexcol flex-group-top">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.taille}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.apparence}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.constitution}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.force}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.agilite}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.dexterite}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.vue}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.ouie}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.odoratgout}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.volonte}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.empathie}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.intellect}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-compteur.hbs" carac=export.reve actuel=export.reve_actuel button-name='ptreve-actuel'}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs" carac=export.chance}}
</div>
<div class="flexcol flex-group-top">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs" carac=export.melee}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs" carac=export.tir}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs" carac=export.lancer}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs" carac=export.derobee}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee-compteur.hbs" carac=export.vie actuel=export.vie_actuel}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee-compteur.hbs" carac=export.endurance actuel=export.endurance_actuel}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/fatigue.hbs" }}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs" carac=export.plusdom}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/protection.hbs" export}}
<div class="flexrow">&nbsp;</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs" }}
</div>
</div>
<hr>
<div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs" name='' niveau='Niv' init='Init' dommages='+dom'}}
{{#each context.armes as |arme|}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs"
name=arme.name niveau=arme.niveau init=arme.init dommages=arme.dommages
arme=arme.arme competence=arme.competence
}}
{{/each}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/esquive.hbs" name='Esquive' niveau=context.esquive.value competence=context.esquive.competence}}
{{#if (gt export.malue_armure.value 0)}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/esquive.hbs" name='Esquive (avec armure)' niveau=export.esquive_armure.value
competence=context.esquive.competence}}
{{/if}}
</div>
<hr>
<div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/competences.hbs" competences=competences}}
</div>
<hr>
<div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/competences.hbs" competences=draconic }}
</div>
<hr>
<div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_0.value description=export.sort_description_0.value bonus=export.sort_bonus_0.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_1.value description=export.sort_description_1.value bonus=export.sort_bonus_1.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_2.value description=export.sort_description_2.value bonus=export.sort_bonus_2.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_3.value description=export.sort_description_3.value bonus=export.sort_bonus_3.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_4.value description=export.sort_description_4.value bonus=export.sort_bonus_4.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_5.value description=export.sort_description_5.value bonus=export.sort_bonus_5.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_6.value description=export.sort_description_6.value bonus=export.sort_bonus_6.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_7.value description=export.sort_description_7.value bonus=export.sort_bonus_7.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_8.value description=export.sort_description_8.value bonus=export.sort_bonus_8.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_9.value description=export.sort_description_9.value bonus=export.sort_bonus_9.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_10.value description=export.sort_description_10.value bonus=export.sort_bonus_10.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_11.value description=export.sort_description_11.value bonus=export.sort_bonus_11.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_12.value description=export.sort_description_12.value bonus=export.sort_bonus_12.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_13.value description=export.sort_description_13.value bonus=export.sort_bonus_13.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_14.value description=export.sort_description_14.value bonus=export.sort_bonus_14.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_15.value description=export.sort_description_15.value bonus=export.sort_bonus_15.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_16.value description=export.sort_description_16.value bonus=export.sort_bonus_16.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_17.value description=export.sort_description_17.value bonus=export.sort_bonus_17.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_18.value description=export.sort_description_18.value bonus=export.sort_bonus_18.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_19.value description=export.sort_description_19.value bonus=export.sort_bonus_19.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_20.value description=export.sort_description_20.value bonus=export.sort_bonus_20.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_21.value description=export.sort_description_21.value bonus=export.sort_bonus_21.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_22.value description=export.sort_description_22.value bonus=export.sort_bonus_22.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_23.value description=export.sort_description_23.value bonus=export.sort_bonus_23.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_24.value description=export.sort_description_24.value bonus=export.sort_bonus_24.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_25.value description=export.sort_description_25.value bonus=export.sort_bonus_25.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_26.value description=export.sort_description_26.value bonus=export.sort_bonus_26.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_27.value description=export.sort_description_27.value bonus=export.sort_bonus_27.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_28.value description=export.sort_description_28.value bonus=export.sort_bonus_28.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs" voie=export.sort_voie_29.value description=export.sort_description_29.value bonus=export.sort_bonus_29.value}}
<div>&nbsp;</div>
<div>&nbsp;</div>
</div>
</section>
</form>

View File

@@ -0,0 +1,20 @@
<div class="flexrow item"
data-item-id="{{arme._id}}"
data-arme-name="{{arme.name}}"
data-competence-name="{{competence.name}}">
{{#if name}}
<a class="roll-arme">{{upperFirst name}}</a>
{{else}}
<div></div>
{{/if}}
<div class="flexrow">
<div>{{niveau}}</div>
{{#if init}}
<div>{{init}}</div>
<div>{{dommages}}</div>
{{else}}
<div></div>
<div></div>
{{/if}}
</div>
</div>

View File

@@ -0,0 +1,5 @@
{{#if blessure}}
<a class="click-blessure-remove" data-gravite="{{gravite}}"><i class="fa-regular fa-face-head-bandage blessure-active-{{gravite}}"></i></a>
{{else}}
<a class="click-blessure-add" data-gravite="{{gravite}}"><i class="fa-regular fa-circle"></i></a>
{{/if}}

View File

@@ -0,0 +1,26 @@
<div class="flexcol">
<div class="flexrow">
<div>Légères</div>
<div class="flex-group-right">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[0] gravite=2}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[1] gravite=2}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[2] gravite=2}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[3] gravite=2}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[4] gravite=2}}
</div>
</div>
<div class="flexrow">
<div>Graves</div>
<div class="flex-group-right">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[5] gravite=4}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[6] gravite=4}}
</div>
</div>
<div class="flexrow">
<div>Critiques</div>
<div class="flex-group-right">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs" blessure=etat.blessure.[7] gravite=6}}
</div>
</div>
</div>

View File

@@ -0,0 +1,18 @@
<div class="flexrow">
<div>
{{#if carac.rollClass}}
<a class="{{carac.rollClass}}" data-carac-name="{{carac.column}}">
{{upper carac.colName}}
</a>
{{else}}
{{upper carac.colName}}
{{/if}}
<a class="{{button-name}}-moins"><i class="fa-regular fa-square-minus"></i></a>
<a class="{{button-name}}-plus"><i class="fa-regular fa-square-plus"></i></a>
</div>
<div class="flex-group-right">
{{log carac.colName carac.value (eq carac.value actuel.value) actuel.value}}
{{log carac.colName carac.value (eq 1 1) actuel.value}}
<a class="{{actuel.rollClass}}" data-carac-name="{{actuel.column}}">{{carac.value}} {{#unless (eq carac.value actuel.value)}}(Actuel : {{actuel.value}}){{/unless}}</a>
</div>
</div>

View File

@@ -0,0 +1,10 @@
<div class="flexrow">
<div>
{{upperFirst carac.colName}}
<a class="{{carac.column}}-moins"><i class="fa-regular fa-square-minus"></i></a>
<a class="{{carac.column}}-plus"><i class="fa-regular fa-square-plus"></i></a>
</div>
<div class="flex-group-right">
<a class="{{actuel.rollClass}}" data-carac-name="{{actuel.column}}">{{carac.value}} {{#unless (eq carac.value actuel.value)}}(Actuel : {{actuel.value}}){{/unless}}</a>
</div>
</div>

View File

@@ -0,0 +1,12 @@
<div class="flexrow">
<div>
{{#if carac.rollClass}}
<a class="{{carac.rollClass}}" data-carac-name="{{carac.column}}">
{{upperFirst carac.colName}}
</a>
{{else}}
{{upperFirst carac.colName}}
{{/if}}
</div>
<div class="flex-group-right">{{carac.value}}</div>
</div>

View File

@@ -0,0 +1,10 @@
<div class="flexrow">
<div>
{{#if carac.rollClass}}
<a class="{{carac.rollClass}}" data-carac-name="{{carac.column}}">{{upper carac.colName}}</a>
{{else}}
{{upper carac.colName}}
{{/if}}
</div>
<div class="flex-group-right">{{carac.value}}</div>
</div>

View File

@@ -0,0 +1,9 @@
{{#each competences as |group|}}
{{#if @index}}/{{/if}}
{{#with group}}
{{#each list as |comp|}}
<span class="item" data-item-id="{{comp._id}}"><a class="roll-competence">{{comp.name}}</a></span>{{~#unless (isLastIndex @index ../list)~}},{{/unless~}}
{{/each}}
{{numberFormat niveau decimals=0 sign=true}}
{{/with}}
{{/each}}

View File

@@ -0,0 +1,10 @@
{{#if name}}
<div class="flexrow item" data-item-id="{{competence._id}}">
<a class="roll-competence" name="Esquive">{{upperFirst name}}</a>
<div class="flexrow">
<div>{{niveau}}</div>
<div></div>
<div></div>
</div>
</div>
{{/if}}

View File

@@ -0,0 +1,12 @@
<div class="flexrow">
<div>Fatigue
{{#if etat.fatigue.malus}}
({{etat.fatigue.malus}})
{{/if}}
<a class="fatigue-moins"><i class="fa-regular fa-square-minus"></i></a>
<a class="fatigue-plus"><i class="fa-regular fa-square-plus"></i></a>
</div>
<div class="flex-group-right">
{{etat.fatigue.value}}{{#if etat.fatigue.value}} / {{etat.fatigue.max}}{{/if}}
</div>
</div>

View File

@@ -0,0 +1,7 @@
{{#if protectionnaturelle.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs" carac=protectionnaturelle}}
{{/if}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs" carac=protectionarmure}}
{{#if armure.value}}
<div class="flexrow flex-group-right"><i>{{armure.value}}</i></div>
{{/if}}

View File

@@ -0,0 +1,11 @@
{{#if voie}}
<div class="flexrow">
<div style="flex-grow: 0.4;">{{voie}}</div>
<div class="flex-grow-2">{{upperFirst description}}</div>
{{#if bonus}}
<div>{{bonus}}</div>
{{else}}
<div></div>
{{/if}}
</div>
{{/if}}

View File

@@ -1,19 +1,19 @@
<div class="header-buttons"> <div class="header-buttons">
<span class="chance-appel"> <span>
<a><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/appel-chance.svg" data-tooltip="Appel à la chance"/></a> <a class="button-appel-chance"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/appel-chance.svg" data-tooltip="Appel à la chance"/></a>
</span> </span>
<span class="encaisser-direct"> <span>
<a><img class="button-img" src="icons/svg/bones.svg" data-tooltip="Encaisser des dommages"/></a> <a class="button-encaissement"><img class="button-img" src="icons/svg/bones.svg" data-tooltip="Encaisser des dommages"/></a>
</span> </span>
<span class="ethylisme-test"> <span>
<a><img class="button-img" src="icons/svg/tankard.svg" data-tooltip="Boire"/></a> <a class="button-ethylisme"><img class="button-img" src="icons/svg/tankard.svg" data-tooltip="Boire"/></a>
</span> </span>
<span class="repos"> <span>
<a><img class="button-img" src="icons/svg/sleep.svg" data-tooltip="Se reposer"/></a> <a class="button-repos"><img class="button-img" src="icons/svg/sleep.svg" data-tooltip="Se reposer"/></a>
</span> </span>
{{#if @root.options.isGM}} {{#if @root.options.isGM}}
<span class="remise-a-neuf"> <span>
<a><img class="button-img" src="icons/svg/regen.svg" data-tooltip="Remise à neuf"/></a> <a class="button-remise-a-neuf"><img class="button-img" src="icons/svg/regen.svg" data-tooltip="Remise à neuf"/></a>
</span> </span>
{{/if}} {{/if}}
</div> </div>

View File

@@ -30,7 +30,7 @@
</li> </li>
<li> <li>
<label class="compteur"> <label class="compteur">
<span class="ptreve-actuel" data-tooltip="Faire un jet de Rêve actuel (ou jet de résistance)"><a>Rêve</a></span> <span class="roll-reve-actuel" data-tooltip="Faire un jet de Rêve actuel (ou jet de résistance)"><a>Rêve</a></span>
<a class="ptreve-actuel-moins"><i class="fa-solid fa-square-minus"></i></a> <a class="ptreve-actuel-moins"><i class="fa-solid fa-square-minus"></i></a>
<input class="resource-content" class="pointsreve-value" type="text" name="system.reve.reve.value" value="{{system.reve.reve.value}}" data-dtype="Number" /> <input class="resource-content" class="pointsreve-value" type="text" name="system.reve.reve.value" value="{{system.reve.reve.value}}" data-dtype="Number" />
<span>/ {{system.reve.seuil.value}}</span> <span>/ {{system.reve.seuil.value}}</span>

View File

@@ -1,17 +1,17 @@
{{#if system.attributs.hautrevant.value}} {{#if system.attributs.hautrevant.value}}
<div class="tmr-buttons"> <div class="tmr-buttons">
<span class="monte-tmr"> <span>
<a data-tooltip="Montée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}> <a class="button-tmr" data-tooltip="Montée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}>
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg"/> <img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-normal.svg"/>
</a> </a>
</span> </span>
<span class="monte-tmr-rapide"> <span>
<a data-tooltip="Montée accélérée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}> <a class="button-tmr-rapide" data-tooltip="Montée accélérée dans les Terres M&eacute;dianes !" {{#if hautreve.isDemiReve}}disabled{{/if}}>
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg"/> <img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg"/>
</a> </a>
</span> </span>
<span class="visu-tmr"> <span>
<a data-tooltip="Regarder les Terres M&eacute;dianes"> <a class="button-tmr-visu" data-tooltip="Regarder les Terres M&eacute;dianes">
<img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-view.svg"/> <img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-view.svg"/>
</a> </a>
</span> </span>

View File

@@ -0,0 +1,53 @@
<form class="app-personnage-aleatoire">
<h2>Génération aléatoire pour {{actor.name}}</h2>
<div class="flex-group-left">
{{#if options.isGM}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Nom" path="name" type="text" value=current.name checked=checked.name
}}
{{/if}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Sexe" path="system.sexe" type="text"
value=current.system.sexe checked=checked.system.sexe
}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Age" path="system.age" type="entier" min=10 max=100
value=current.system.age checked=checked.system.age
}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Taille" path="system.taille" type="text"
value=current.system.taille checked=checked.system.taille
}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Poids" path="system.poids" type="text"
value=current.system.poids checked=checked.system.poids
}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Main directrice" path="system.main" type="text"
value=current.system.main checked=checked.system.main
}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Heure de naissance" path="system.heure" type="heure"
value=current.system.heure checked=checked.system.heure
}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Cheveux" path="system.cheveux" type="text"
value=current.system.cheveux checked=checked.system.cheveux
}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs"
label="Yeux" path="system.yeux" type="text"
value=current.system.yeux checked=checked.system.yeux
}}
</div>
<hr>
<div style="text-align: right;">
<a class="chat-card-button randomize-selected">Générer les valeurs sélectionnés</a>
</div>
<br>
<div class="flexrow">
<button class="button-cancel">Annuler</button>
<button class="button-apply">Appliquer à {{actor.name}}</button>
</div>
<br>
</form>

View File

@@ -0,0 +1,19 @@
<div class="flexrow random-field" data-path="{{path}}">
<label for="{{path}}">{{label}}:</label>
{{#if (eq type 'entier')}}
<input class="current-value" name="current.{{path}}" value="{{value}}" placeholder="{{label}}" type="number" data-dtype="Number" min="{{min}}" max="{{max}}"/>
{{else if (eq type 'heure')}}
<select class="current-value" name="current.{{path}}" value="{{value}}" type="text" data-dtype="String">
{{#select value}}
{{> "systems/foundryvtt-reve-de-dragon/templates/enum-heures.html"}}
{{/select}}
</select>
{{else}}
<input class="current-value" name="current.{{path}}" value="{{value}}" placeholder="{{label}}" type="text" data-dtype="String"/>
{{/if}}
<div class="item-controls">
<a class="random" data-action="random" data-tooltip="Aléatoire"><i class="fa-solid fa-dice-d20"></i></a>
<a class="reset" data-action="reset" data-tooltip="Reset"><i class="fa-solid fa-eraser"></i></a>
<input class="check-for-random" type="checkbox" data-tooltip="Sélectionné pour génération automatique" {{#if checked}}checked{{/if}}/>
</div>
</div>

View File

@@ -11,9 +11,10 @@
<div> <div>
<ul class="flexcol item-list alterne-list"> <ul class="flexcol item-list alterne-list">
{{#each table as |row|}} {{#each table as |row|}}
<li class="item list-item" > <li class="item list-item ">
<span>{{row.min}}{{#unless (eq row.min row.max)}}-{{row.max}}{{/unless}} : &nbsp;</span> <span class="flex-group-left">
<span>{{linkCompendium row.document.pack row.document.id row.document.name}}</span> {{row.min}}{{#unless (eq row.min row.max)}}-{{row.max}}{{/unless}}&nbsp;: {{linkCompendium row.document.pack row.document.id row.document.name}}
</span>
</li> </li>
{{/each}} {{/each}}
</ul> </ul>