Compare commits

...

114 Commits

Author SHA1 Message Date
d795968519 v10.0.28 2022-10-14 21:52:38 +02:00
37e5b3c0aa Version 10.0.28 2022-10-14 21:47:34 +02:00
e1aecb05c3 Fix: Organisation boutons/messages d'équipement
Le message de surencombrement rendait la présentation moche
2022-10-14 00:58:26 +02:00
168127d8fe Fix: tirage dans une table ne fonctionnait plus
Régression bête, qui empêchait aussi d'afficher le résultat d'un échec
contre un rêve de dragon
2022-10-14 00:48:05 +02:00
21ec043e98 Fix: alignement des queues avec le reste
Sans l'onglet Haut rêve, les queues n'étaient pas bien alignées.
2022-10-14 00:46:42 +02:00
00b3b7f9b3 Fix: Affichage ajustement encaissement
Pour les encaissements hors combat, rappel de l'ajustement
d'encaissement choisi
2022-10-14 00:45:53 +02:00
d1be242791 Minor: optimisation de monnaies
pas d'updates pour les monnaies non affectées
2022-10-14 00:43:37 +02:00
fa75828bc1 Fix: régression lancer de sorts
A cause du duplicate, les voies n'étaient plus des RdDItem, du coup,
la méthode isCompetence de la recherche de compétences ne marche
pas...

Et le duplicate était inutile de toutes façons.
2022-10-14 00:42:35 +02:00
232f414a62 Ajout distance 2022-10-09 13:44:40 +02:00
14e76ac631 Merge pull request 'v10' (#564) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#564
2022-10-09 13:43:27 +02:00
43763dbe3a Jets d'encaissement validés par le MJ
* ajout d'une option pour activer la validation par le MJ
* lors d'un jet d'encaissement, une fenêtre s'ouvre chez le MJ
  avec le résultat d'encaissement
* le MJ peut changer le jet d'encaissement
* si le MJ annule, l'encaissement n'a pas lieu
* Attention, si plusieurs MJ, un seul doit valider, sinon
  encaissements multiples
2022-10-09 02:19:33 +02:00
81ae15a6a2 Simuler les lancers de dés
Lorsqu'on force le résultat des dés, on force l'affichage d'un lancer
donnant ce résultat avec DiceSoNice
2022-10-08 17:37:39 +02:00
6dc7272ef6 Corrections mineures
Plus besoin de vérifier game.versions pour utiliser game.users
Plus besoin d'une indirection Misc.getUsers

defender.system.name => defender.name
2022-10-08 17:37:32 +02:00
d75eef1926 Correction configuration affichage prix
L'option de configuration étaity toujours vrai quand vue par le MJ
2022-10-08 17:37:32 +02:00
18039e905b Compétences & herbes personalisées
* permettre d'ajouter des compétences dans un monde, qui seront
  ajoutés aux acteurs créés dans ce monde
* les herbes de repos/soins du monde sont bien considérées comme
  des herbes pour les potions
2022-10-08 17:37:32 +02:00
6d0e5321a2 Nommage homogène 2022-10-08 11:56:52 +02:00
3073670afa Ajout visibilité 2022-10-07 23:46:36 +02:00
690dd1f0a2 Merge pull request 'Monnaies et armes à distance' (#563) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#563
2022-10-07 23:35:40 +02:00
0dcce5456b Inatteignable à -10
au lieu de hyphen non affiché
2022-10-07 23:31:57 +02:00
35f1f2437c Garde fous
En cas d'exception dans le traitement d'un message websocket,
faire un catch pour être sûr de ne pas réémettre si l'exception
revient à l'émetteur (boucle infinie d'envois sinon)
2022-10-07 23:30:06 +02:00
3e17dd9b7e Ajout d'informations pour armes à distance
* prise en compte de la taille de la cible
* prise en compte de l'activité
* valeur indicative
2022-10-07 23:28:41 +02:00
4f8406360f Suppression de création de personnage
la feuille n'est pas encore prête
2022-10-07 19:07:25 +02:00
d316bba8fa Déplacement de méthode compendium 2022-10-07 19:07:25 +02:00
9621d72f92 Correction des monnaies
* Des deniers sont créés si on n'a rien d'autre
* Gagner ou dépenser de l'argent fonctionne même si on n'a pas
  tous les types de pièces
* Tous les acteurs peuvent acheter/vendre s'ils ont de l'argent
  => Pratique pour créer une auberge!
* Seuls les personnages peuvent boire et manger
* plus de problèmes de monnaies manquantes
2022-10-07 19:07:25 +02:00
5382fb5df3 Ajout affichage distance 2022-10-06 14:07:47 +02:00
fd6fbba9cb Merge vk 2022-10-05 20:00:42 +02:00
3739204b42 Merge pull request 'Confirmations' (#562) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#562
2022-10-05 19:58:41 +02:00
7e2a867bdd Regroupement d'onglets 2022-10-05 19:40:31 +02:00
e983715ad2 Suppression des malusarmure
Les animaux/entités n'ont pas de malus armure.

La présence dans les compendium faisait apparaître un
attribut sans nom avec comme valeur à 0.
2022-10-05 19:30:57 +02:00
d8d5a20904 Simplification des feuilles de créatures
* Homogénisation des fiches de créatures / entités
* Regroupement d'onglets (peu de compétences/caracs)
* ajout du bouton vue détaillée/simplifiée pour toutes les feuilles
* la santé des créatures est dans l'en-tête
* bouton pour boire pour els personnages
* agrandissement des caractéristiques dérivées
2022-10-05 19:29:16 +02:00
5410dd6ec0 Texte moins long 2022-10-05 00:07:16 +02:00
4443548b0e Bouton "Toujours supprimer"
Label et icône plus clairs
2022-10-04 23:45:14 +02:00
3c86e1b97c Correction largeur confirmations 2022-10-04 23:42:07 +02:00
5cde57e07c Ajout de la possession au compendium
Ajout de la compétence au compendium pour les entités
2022-10-04 23:27:05 +02:00
970c8b0244 Messages de confirmations
* Confirmer pour monter dans les TMR
* les confirmations peuvent être désactivées (par utilisateur)
* plusieurs groupes différents sont gérés
2022-10-04 23:27:04 +02:00
ade977ed68 Increase releas 2022-10-04 06:48:31 +02:00
f83d51b72d Merge pull request 'Petites améliorations de la feuille de personnage' (#561) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#561
2022-10-04 06:47:38 +02:00
34f2e33d6d Déplacer la remise à neuf
C'est plus cohérent de grouper les boutons joueur pour avoir un même
aspect que la feuille soit affichée en joueur ou MJ
2022-10-04 03:33:17 +02:00
0a5c5c5486 Bouton pour utiliser la chance
Déplacé dans les boutons d'action de la partie haute
2022-10-04 03:21:41 +02:00
6becca6672 Bouton pour créer une oeuvre 2022-10-04 02:25:06 +02:00
b2d4dc5d00 Bouton Ré-insertion aléatoire
N'indique plus que les TMR sont masquées:
le bouton cacher/montrer permet de le savoir.
2022-10-04 02:16:05 +02:00
22091ef431 Corrections prix et enc. équipement
Affichage de la valeur si option activée
Utilisation de boutons au lieu des liens
2022-10-04 01:58:49 +02:00
efdc676776 Ajout confirmation pour vider les conteneurs 2022-10-04 01:53:18 +02:00
d25c6b7f1c Montrer/cacher les TMR
Le bouton "Montrer les TMR" devient "Cacher les TMR"/"Montrer les TMR"
selon qu'elles sont visibles ou pas

Lors de l'utilisation d'une terre d'attache, c'un changeur ou de la
connaissance du fleuve, le demi-rêve redevient visible
2022-09-30 01:55:19 +02:00
0cc6b1de98 Release 10.0.22 2022-09-28 08:26:35 +02:00
c41b59b703 Merge pull request 'v10.0.22' (#560) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#560
2022-09-28 08:25:28 +02:00
b4ca941065 Nettoyage de journal d'expérience pour MJ
Permet au MJ de vider les anciennes entrées du journal d'expérience
(jusqu'à une entrée, comprise)

Permet de supprimer une entrée spécifique
2022-09-28 01:24:32 +02:00
322506250b Regrouper vue détaillée avec dévérouiller 2022-09-27 22:38:49 +02:00
5d36ea9e0c Ajout Résistance/structure max aux véhicules
Pour qu'on puisse les réparer
2022-09-27 22:37:33 +02:00
dc0fab2957 Nettoyage acteurs compendium 2022-09-27 22:37:33 +02:00
2e158f9d39 Organisation des parties de la feuille 2022-09-27 22:37:24 +02:00
7e1bbcada0 Séparation actor-sheet en sous-parties 2022-09-27 22:35:25 +02:00
02ccb1f287 Nouvelle visualisation des blessures
Extractions des parties de la feuille pour préparer la possibilité de
proposer une autre fiche
2022-09-27 22:35:25 +02:00
4afa313ffc Enable links in editor 2022-09-27 21:03:18 +02:00
1b8ad316b9 Merge conteneur + fix hotbar 2022-09-25 21:21:28 +02:00
b35eaad757 Merge conteneur + fix hotbar 2022-09-25 21:17:47 +02:00
e325ab9278 Merge pull request 'Drop sur un objet met dans le conteneur parent' (#559) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#559
2022-09-25 21:17:01 +02:00
ebe19959fa Drop sur un objet met dans le conteneur parent
Augmenter la zone pour lacher un objet:
* si c'est un objet similaire, on regroupe
* si c'est un conteneur: on met dans le conteneur
* si c'est un objet dans un conteneur, on met dans le conteneur
* si c'est un objet porté, on met dans les objets portés
2022-09-25 18:45:40 +02:00
5a2bc69fbb Typo "nuage" dans les signes draconiques 2022-09-25 17:50:07 +02:00
57dfdf0b65 Merge fixes from Vincent 2022-09-24 09:58:45 +02:00
028e8b883f Merge pull request 'Corrections et quelques améliorations' (#557) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#557
2022-09-24 09:57:44 +02:00
4bab69b88f Fix: déplacement de contenu rangé 2022-09-24 01:05:32 +02:00
be0c0fbf3a Correction de la monnaie de la serveuse 2022-09-24 00:53:27 +02:00
cd4bf203e6 Corrections d'images dans les compendiums 2022-09-24 00:53:27 +02:00
fc5674a7d8 TMR et acteurs à cocher pour les signe draconiques
Au lieu d'une liste à sélection multiple, choisir les types de TMR
avec des cases à cocher.

Lors de l'ajout de signes éphémères, sélectionner les personnages
avec des cases à cocher.
2022-09-24 00:53:27 +02:00
fe80881405 Fenêtre de stress avec acteurs à cocher
Remplacement de la liste d'acteurs par des cases à cocher car la
sélection n'est pas visible
2022-09-24 00:53:27 +02:00
3a29c25b09 Fix: calculs des bonus de potions
Le calcul du bonus d'herbe d'une potion dépend des brins manquants.

La fabrication de potion propose les nombres de brins pour avoir un
effet. Impossible de faire une potion si on n'a pas assez de brins.

La puissance/points de guérison des potions magiques sont affichées lors
 de la consomation
2022-09-23 02:23:20 +02:00
e2ff813226 Fix: pas plus de lots que disponibles
On pouvait saisir à la main un nombre de lots plus grand que le nombre
disponible, ce qui multipliait la quantité par ce nombre de lots
2022-09-23 01:32:18 +02:00
b67f230212 Fix actionPrincipale de l'équipement 2022-09-23 00:57:02 +02:00
47f9e1adaa Fix boutons d'avancement des heures
Bloqués par la recherche de maladies/poisons pour afficher le
message sur leurs effets
2022-09-23 00:46:57 +02:00
33808b8cf0 Fix transfert de contenants 2022-09-23 00:46:57 +02:00
0d67d9af88 New v10.0.18 release 2022-09-22 08:35:57 +02:00
45a562f502 Merge pull request 'Stabilisation v10.0.18' (#556) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#556
2022-09-22 08:34:46 +02:00
21fc62b302 Fix de la séquence TMR
Lors d'une rencontre/case humide/conquête/..., le haut rêvant
déclenchait tout de même les sorts en réserve
2022-09-22 01:19:10 +02:00
c37c68e6db Fix erreur quand la fenêtre est fermée
Erreur dans les logs, par exemple, suite à une rencontre
2022-09-22 01:19:10 +02:00
ca893088d2 Détails de case pour les sorts en réserve 2022-09-22 01:19:10 +02:00
e69fb222c3 Affiche le type de case si TMR cachées 2022-09-22 01:19:10 +02:00
c76bf912d1 Fix compteur d'utilisations d'esquive 2022-09-22 01:19:10 +02:00
4b1573ab8b Rétablissement des icônes RdD des onglets Foundry
Perdus avec le changement d'entrée FontAwsome
2022-09-22 01:19:10 +02:00
e0049cc2f7 v10 mods+fixes 2022-09-20 07:48:36 +02:00
8e0949442d Merge pull request 'Stabilisation de la v10' (#555) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#555
2022-09-20 07:46:17 +02:00
28427bc7c7 Initiative et competences créatures
Fix de l'initiative des compétences de créatures
* armes naturelles en général
* lancer pour les pierres lancées des Glous et Mariols

La catégorie de parade: remplace l'utilisation de "isparade"

Migration autoimatique des items du monde
Modification des compendiums
2022-09-20 00:14:34 +02:00
50980d5216 Fix Initiative: utilise l'action, pas l'arme 2022-09-20 00:14:18 +02:00
a75ee8fbc6 Fix RollTables: utilisent data, pas system 2022-09-20 00:14:18 +02:00
78c757a21a Ajout des images dans le haut-rêve 2022-09-20 00:14:18 +02:00
6d06c96497 chgt endurance ne rend plus inconscient 2022-09-20 00:14:18 +02:00
5402508b26 Le "label for" indique le "name" du contrôle 2022-09-20 00:14:18 +02:00
43d097581e Log de l'acteur avec monnaies manquantes 2022-09-19 20:22:30 +02:00
7785851719 Log de l'actor dont les sorts sont migrés 2022-09-19 20:22:30 +02:00
8f127bc66b Corrections diverses suite v10 2022-09-18 08:57:45 +02:00
8c5f6b8f1b Merge pull request 'Corrections des TMRs et des Statuis' (#554) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#554
2022-09-18 08:55:40 +02:00
00630849cb Réinsertion sortie de carte
En sortant de la carte (avec les flèches de direction), le demi-rêve
est maintenant bien réinséré aléatoirement
2022-09-18 01:00:38 +02:00
c4392f0320 Fix TMR accessibles par une rencontre
Les cases n'étaient polus accessibles, ni coloriées
2022-09-18 01:00:38 +02:00
7a92ee85ef Nettoyage des status effects
* Recherche et suppression toujours par flags.core.statusId
* l'ajout d'un status depuis le token est maintenant équivallent
  à l'ajout par le code
* Correction des demi-surprises
* Correction du Demi-rêve (qui ne disparaissait pas)
* fix de la selection dans la configuration système
2022-09-18 01:00:36 +02:00
56ea9dd2e4 Sorts en réserve éditables 2022-09-17 22:35:17 +02:00
ee42902b5c Gestion reserve et queues ameliores(Vincent) 2022-09-17 09:09:09 +02:00
838d4381a4 Merge pull request 'Refouler des queues et supprimer des sorts en réserve' (#553) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#553
2022-09-17 09:04:19 +02:00
2232224951 Suppression de sorts en réserve 2022-09-17 01:54:27 +02:00
1251d04860 Action Refoulement de queue 2022-09-17 01:54:27 +02:00
63c6d5ff0f Integration fixes Vincent 2022-09-16 08:35:48 +02:00
c0d37e42ca Merge pull request 'Petits fixes suite à tests' (#552) from VincentVk/foundryvtt-reve-de-dragon:v10-fixes into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#552
2022-09-16 08:34:18 +02:00
c8c13d626c Fix drop item sans actor 2022-09-16 02:41:54 +02:00
e1ca7ab738 Amélioration des monnaies
On peut maintenant supprimer es monnaies tant qu'on garde une monnaie
pour chaque valeur de base
2022-09-16 02:41:08 +02:00
8f1ee315ef Template en-tête standard 2022-09-16 02:24:08 +02:00
5daf15901a Correction erreur xp restant 2022-09-16 02:24:08 +02:00
bddaecbc74 Fix entite 2022-09-11 16:14:27 +02:00
87fdd655d4 Merge v10 fixes 2022-09-07 23:09:21 +02:00
9cbb12e900 Merge pull request 'Utilisation de system dans les Item/Actor Sheet' (#551) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#551
2022-09-07 23:08:26 +02:00
509b7f97dc Utilisation de system dans les Item/Actor Sheet
Utilisation de system dans les data de formulaire pour tous
les Item/Actor (à la base, ou les sous-éléments)

Corrections sur les sorts en réserve (ce ne sont pas des Item)

Petites améliorations:

* `actor.itemTypes[type]`
   revient à faire (sans besoin de filtrer)
    `actor.items.filter(it => it.type == type)`
* dans les ItemSheet, this.object et this.document
  remplacés par this.item
* dans les ActorSheet, this.object et this.document
  remplacés par this.actor

Quelques corrections en plus:
* parade ne marchait pas
* problèmes sur le commerce
2022-09-07 18:47:56 +02:00
5cd9fb3a1c v10 WIP 2022-09-07 09:14:42 +02:00
336767c19e v10 WIP 2022-09-07 09:01:23 +02:00
5a32cf26dc Merge pull request 'Corrections v10' (#550) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#550
2022-09-07 08:17:41 +02:00
67b0555b11 Corrections v10
Il y en avait partout dans des dialogues, des options,
le drag&drop d'acteur sur acteur, l'empilage d'objet...
2022-09-07 00:36:52 +02:00
59613c3bf8 Sync 2022-09-06 23:52:21 +02:00
212 changed files with 4787 additions and 4416 deletions

View File

@ -41,7 +41,8 @@
"TypeOmbre": "Ombre de Thanatos",
"TypeSouffle": "Souffle de Dragon",
"TypeTete": "Tête de Dragon",
"TypePossession": "Possession"
"TypePossession": "Possession",
"TypeSortreserve": "Sort en réserve"
},
"EFFECT": {
"StatusStunned": "Sonné",

View File

@ -4,7 +4,6 @@
* @extends {ActorSheet}
*/
import { HtmlUtility } from "./html-utility.js";
import { RdDUtility } from "./rdd-utility.js";
import { RdDActorSheet } from "./actor-sheet.js";
import { RdDCarac } from "./rdd-carac.js";
@ -24,34 +23,11 @@ export class RdDActorCreatureSheet extends RdDActorSheet {
});
}
/* -------------------------------------------- */
async getData() {
let formData = await super.getData()
//console.log("Creature : ", formData, formData.system)
formData.calc = {
caracTotal: RdDCarac.computeTotal(formData.data.carac),
resumeBlessures: this.actor.computeResumeBlessure(formData.data.blessures),
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
surEncombrementMessage: this.actor.getMessageSurEncombrement()
}
RdDUtility.filterItemsPerTypeForSheet(formData);
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
console.log("Creature : ", this.objetVersConteneur, formData);
return formData;
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;

View File

@ -1,14 +1,8 @@
/**
* Extend the basic ActorSheet with some very simple modifications
* @extends {ActorSheet}
*/
import { RdDActorSheet } from "./actor-sheet.js";
import { HtmlUtility } from "./html-utility.js";
import { Misc } from "./misc.js";
import { RdDUtility } from "./rdd-utility.js";
/* -------------------------------------------- */
export class RdDActorEntiteSheet extends ActorSheet {
export class RdDActorEntiteSheet extends RdDActorSheet {
/** @override */
static get defaultOptions() {
@ -22,65 +16,14 @@ export class RdDActorEntiteSheet extends ActorSheet {
});
}
/* -------------------------------------------- */
async getData() {
const objectData = this.object;
let formData = {
title: this.title,
id: objectData.id,
type: objectData.type,
img: objectData.img,
name: objectData.name,
// actor: this.object,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
data: foundry.utils.deepClone(this.actor.system),
effects: this.object.effects.map(e => foundry.utils.deepClone(e)),
// items: items,
limited: this.object.limited,
options: this.options,
owner: this.document.isOwner,
itemsByType: Misc.classify(this.object.items.map(i => foundry.utils.deepClone(i))),
};
formData.options.isGM = game.user.isGM;
RdDUtility.filterItemsPerTypeForSheet(formData);
return formData;
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
// Update Inventory Item
html.find('.item-edit').click(event => {
const li = $(event.currentTarget).parents(".item");
const item = this.actor.getEmbeddedDocument('Item', li.data("itemId"));
item.sheet.render(true);
});
// Delete Inventory Item
html.find('.item-delete').click(event => {
const li = $(event.currentTarget).parents(".item");
this.actor.deleteEmbeddedDocuments('Item', [li.data("itemId")]);
li.slideUp(200, () => this.render(false));
});
// Roll Carac
html.find('.carac-label a').click(async event => {
let caracName = event.currentTarget.attributes.name.value;
this.actor.rollCarac( caracName.toLowerCase() );
});
// On competence change
html.find('.creature-carac').change(async event => {
let compName = event.currentTarget.attributes.compname.value;
@ -94,53 +37,6 @@ export class RdDActorEntiteSheet extends ActorSheet {
let compName = event.currentTarget.attributes.compname.value;
this.actor.updateCreatureCompetence( compName, "dommages", parseInt(event.target.value) );
} );
// Roll Skill
html.find('.competence-label a').click(async event => {
let compName = event.currentTarget.text;
this.actor.rollCompetence( compName );
});
html.find('.endurance-plus').click(event => {
this.actor.santeIncDec("endurance", 1);
this.render(true);
});
html.find('.endurance-moins').click(event => {
this.actor.santeIncDec("endurance", -1);
this.render(true);
});
html.find('.encaisser-direct').click(event => {
this.actor.encaisser();
});
html.find('.remise-a-neuf').click(event => {
if (game.user.isGM) {
this.actor.remiseANeuf();
}
});
}
/* -------------------------------------------- */
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
const sheetHeader = this.element.find(".sheet-header");
const sheetTabs = this.element.find(".sheet-tabs");
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - sheetHeader[0].clientHeight - sheetTabs[0].clientHeight;
sheetBody.css("height", bodyHeight);
return position;
}
/* -------------------------------------------- */
/** @override */
_updateObject(event, formData) {
// Update the Actor
return this.object.update(formData);
}
}

View File

@ -15,6 +15,7 @@ import { DialogSplitItem } from "./dialog-split-item.js";
import { ReglesOptionelles } from "./regles-optionelles.js";
import { DialogRepos } from "./dialog-repos.js";
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
import { STATUSES } from "./status-effects.js";
/* -------------------------------------------- */
export class RdDActorSheet extends ActorSheet {
@ -28,7 +29,6 @@ export class RdDActorSheet extends ActorSheet {
width: 640,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
editCaracComp: false,
showCompNiveauBase: false,
vueDetaillee: false
});
@ -36,90 +36,85 @@ export class RdDActorSheet extends ActorSheet {
/* -------------------------------------------- */
async getData() {
const objectData = this.object.system
this.timerRecherche = undefined;
console.log("New actor", objectData)
let formData = {
title: this.title,
id: this.object.id,
type: this.object.type,
img: this.object.img,
name: this.object.name,
id: this.actor.id,
type: this.actor.type,
img: this.actor.img,
name: this.actor.name,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
data: foundry.utils.deepClone(this.actor.system),
effects: this.object.effects.map(e => foundry.utils.deepClone(e)),
limited: this.object.limited,
system: foundry.utils.deepClone(this.actor.system),
effects: this.actor.effects.map(e => foundry.utils.deepClone(e)),
limited: this.actor.limited,
options: this.options,
owner: this.document.isOwner,
itemsByType: Misc.classify(this.object.items.map(i => foundry.utils.deepClone(i))),
}
RdDUtility.filterItemsPerTypeForSheet(formData)
formData.options.isGM = game.user.isGM;
if (formData.type == 'creature') return formData; // Shortcut
formData.competenceByCategory = Misc.classify(formData.competences, it => it.system.categorie)
formData.calc = {
comptageArchetype: RdDItemCompetence.computeResumeArchetype(formData.competences),
competenceXPTotal: RdDItemCompetence.computeTotalXP(formData.competences),
caracTotal: RdDCarac.computeTotal(formData.data.carac, formData.data.beaute),
// Mise à jour de l'encombrement total et du prix de l'équipement
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
fatigue: RdDUtility.calculFatigueHtml(formData.data.sante.fatigue.value, formData.data.sante.endurance.max),
resumeBlessures: this.actor.computeResumeBlessure(formData.data.blessures),
surEncombrementMessage: this.actor.getMessageSurEncombrement()
};
formData.competences.forEach(item => {
item.visible = this.options.recherche
? RdDItemCompetence.nomContientTexte(item, this.options.recherche.text)
: (!this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(item));
RdDItemCompetence.levelUp(item, formData.data.compteurs.experience.value);
});
Object.values(formData.data.carac).forEach(c => {
RdDCarac.levelUp(c);
});
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
formData.combat = duplicate(formData.armes ?? []);
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.data.carac);
formData.esquives = this.actor.getCompetences("Esquive").map(i => foundry.utils.deepClone(i.system));
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.data.carac);
this.armesList = formData.combat;
// Common data
formData.ajustementsConditions = CONFIG.RDD.ajustementsConditions;
formData.difficultesLibres = CONFIG.RDD.difficultesLibres;
formData.hautreve = {
isDemiReve: this.actor.getEffectByLabel("Demi-rêve"),
sortsReserve: formData.data.reve.reserve.list,
rencontres: duplicate(formData.data.reve.rencontre.list),
casesTmr: formData.itemsByType.casetmr,
cacheTMR: this.actor.isTMRCache()
owner: this.actor.isOwner,
description: await TextEditor.enrichHTML(this.object.system.description, {async: true}),
biographie: await TextEditor.enrichHTML(this.object.system.biographie, {async: true}),
notes: await TextEditor.enrichHTML(this.object.system.notes, {async: true}),
notesmj: await TextEditor.enrichHTML(this.object.system.notesmj, {async: true}),
calc: {
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
surEncombrementMessage: this.actor.getMessageSurEncombrement(),
},
}
formData.options.isGM = game.user.isGM;
RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
formData.subacteurs = {
vehicules: this.actor.listeVehicules(),
montures: this.actor.listeMontures(),
suivants: this.actor.listeSuivants()
}
if (this.actor.getBestDraconic().system.niveau > -11 && !this.actor.isHautRevant()) {
ui.notifications.error(`${this.actor.name} a des compétences draconiques, mais pas le don de Haut-Rêve!
<br>Ajoutez-lui la tête "Don de Haut-Rêve" pour lui permettre d'utiliser ses compétences et d'accéder aux terres médianes du rêve`);
if (formData.type == 'personnage') {
formData.byCateg = Misc.classify(formData.competences, it => it.system.categorie)
formData.calc.comptageArchetype = RdDItemCompetence.computeResumeArchetype(formData.competences);
formData.calc.competenceXPTotal= RdDItemCompetence.computeTotalXP(formData.competences);
formData.calc.fatigue= RdDUtility.calculFatigueHtml(formData.system.sante.fatigue.value, formData.system.sante.endurance.max);
formData.competences.forEach(item => {
item.system.isVisible = this.options.recherche
? RdDItemCompetence.nomContientTexte(item, this.options.recherche.text)
: (!this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(item));
RdDItemCompetence.levelUp(item, formData.system.compteurs.experience.value);
});
Object.values(formData.system.carac).forEach(c => {
RdDCarac.levelUp(c);
});
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
formData.combat = duplicate(formData.armes ?? []);
RdDItemArme.computeNiveauArmes(formData.combat, formData.competences);
RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.system.carac);
formData.esquives = this.actor.getCompetences("Esquive");
formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac);
this.armesList = formData.combat;
// Common data
formData.ajustementsConditions = CONFIG.RDD.ajustementsConditions;
formData.difficultesLibres = CONFIG.RDD.difficultesLibres;
formData.hautreve = {
isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve),
rencontres: duplicate(formData.system.reve.rencontre.list),
cacheTMR: this.actor.isTMRCache()
}
formData.subacteurs = {
vehicules: this.actor.listeVehicules(),
montures: this.actor.listeMontures(),
suivants: this.actor.listeSuivants()
}
if (this.actor.getBestDraconic().system.niveau > -11 && !this.actor.isHautRevant()) {
ui.notifications.error(`${this.actor.name} a des compétences draconiques, mais pas le don de Haut-Rêve!
<br>Ajoutez-lui la tête "Don de Haut-Rêve" pour lui permettre d'utiliser ses compétences et d'accéder aux terres médianes du rêve`);
}
}
return formData;
}
@ -130,8 +125,8 @@ export class RdDActorSheet extends ActorSheet {
/* -------------------------------------------- */
async _onDropActor(event, dragData) {
console.log("_onDropActor", this.actor.id, dragData);
this.actor.addSubActeur(dragData.id || dragData.data._id);
const dropActor = fromUuidSync(dragData.uuid);
this.actor.addSubActeur(dropActor);
super._onDropActor(event, dragData);
}
@ -159,7 +154,6 @@ export class RdDActorSheet extends ActorSheet {
activateListeners(html) {
super.activateListeners(html);
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue"));
// Everything below here is only needed if the sheet is editable
@ -171,7 +165,6 @@ export class RdDActorSheet extends ActorSheet {
});
html.find('.item-edit').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor)
console.log("ITEM :", item)
item.sheet.render(true)
})
html.find('.display-label a').click(async event => {
@ -183,7 +176,8 @@ export class RdDActorSheet extends ActorSheet {
});
html.find('.item-delete').click(async event => {
const li = RdDSheetUtility.getEventElement(event);
RdDUtility.confirmerSuppression(this, li);
const item = this.actor.getObjet(li.data("item-id"));
RdDUtility.confirmerSuppressionItem(this, item, li);
});
html.find('.item-vendre').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
@ -193,16 +187,28 @@ export class RdDActorSheet extends ActorSheet {
const item = RdDSheetUtility.getItem(event, this.actor);
item?.postItem();
});
html.find('.item-action').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor)
this.actor.actionItem(item);
});
html.find('.subacteur-delete').click(async event => {
const li = RdDSheetUtility.getEventElement(event);
RdDUtility.confirmerSuppressionSubacteur(this, li);
const actorId = li.data("actor-id");
if (actorId) {
const subActor = game.actors.get(actorId);
RdDUtility.confirmerSuppressionSubacteur(this, subActor, li);
}
});
html.find('.experiencelog-delete').click(async event => {
const li = $(event.currentTarget)?.parents(".experiencelog");
const key = Number(li.data("key") ?? -1);
await this.actor.deleteExperienceLog(key, 1);
});
html.find('.experiencelog-delete-previous').click(async event => {
const li = $(event.currentTarget)?.parents(".experiencelog");
const key = Number(li.data("key") ?? -1);
await this.actor.deleteExperienceLog(0, key + 1);
});
html.find('.encaisser-direct').click(async event => {
this.actor.encaisser();
})
@ -224,7 +230,7 @@ export class RdDActorSheet extends ActorSheet {
html.find('.creer-une-oeuvre').click(async event => {
RdDUtility.selectTypeOeuvre(this);
});
html.find('#nettoyer-conteneurs').click(async event => {
html.find('.nettoyer-conteneurs').click(async event => {
this.actor.nettoyerConteneurs();
});
@ -239,7 +245,7 @@ export class RdDActorSheet extends ActorSheet {
});
// Blessure data
html.find('.blessures-soins').change(async event => {
html.find('.blessure-soins').change(async event => {
const tr = $(event.currentTarget).parents(".item");
let btype = tr.data('blessure-type');
let index = tr.data('blessure-index');
@ -317,7 +323,7 @@ export class RdDActorSheet extends ActorSheet {
this.actor.reinsertionAleatoire("Action MJ");
});
html.find('.afficher-tmr').click(async event => {
this.actor.afficheTMRetMessage();
this.actor.changeTMRVisible();
});
// Points de reve actuel
@ -332,7 +338,7 @@ export class RdDActorSheet extends ActorSheet {
});
// Initiative pour l'arme
html.find('.arme-initiative a').click(async event => {
let combatant = game.combat.data.combatants.find(c => c.actor.data._id == this.actor.data._id);
let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id);
if (combatant) {
let action = this._getEventArmeCombat(event);
RdDCombatManager.rollInitiativeAction(combatant._id, action);
@ -359,11 +365,15 @@ export class RdDActorSheet extends ActorSheet {
await DialogRepos.create(this.actor);
});
html.find('.delete-active-effect').click(async event => {
let id = $(event.currentTarget).parents(".active-effect").data('id');
this.actor.enleverActiveEffectById(id);
if (game.user.isGM) {
let effect = $(event.currentTarget).parents(".active-effect").data('effect');
this.actor.removeEffect(effect);
}
});
html.find('.enlever-tous-effets').click(async event => {
this.actor.enleverTousLesEffets();
if (game.user.isGM) {
await this.actor.removeEffects();
}
});
html.find('.conteneur-name a').click(async event => {
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
@ -380,16 +390,14 @@ export class RdDActorSheet extends ActorSheet {
this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event));
});
if (this.options.editCaracComp) {
if (this.options.vueDetaillee) {
// On carac change
html.find('.carac-value').change(async event => {
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
//console.log("Value changed :", event, caracName);
this.actor.updateCarac(caracName, parseInt(event.target.value));
});
html.find('.carac-xp').change(async event => {
html.find('input.carac-xp').change(async event => {
let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
//console.log("Value changed :", event, caracName);
this.actor.updateCaracXP(caracName, parseInt(event.target.value));
});
// On competence change
@ -399,12 +407,12 @@ export class RdDActorSheet extends ActorSheet {
this.actor.updateCompetence(compName, parseInt(event.target.value));
});
// On competence xp change
html.find('.competence-xp').change(async event => {
html.find('input.competence-xp').change(async event => {
let compName = event.currentTarget.attributes.compname.value;
this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
});
// On competence xp change
html.find('.competence-xp-sort').change(async event => {
html.find('input.competence-xp-sort').change(async event => {
let compName = event.currentTarget.attributes.compname.value;
this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
});
@ -419,10 +427,6 @@ export class RdDActorSheet extends ActorSheet {
this.options.showCompNiveauBase = !this.options.showCompNiveauBase;
this.render(true);
});
html.find('.lock-unlock-sheet').click(async event => {
this.options.editCaracComp = !this.options.editCaracComp;
this.render(true);
});
html.find('.recherche')
.each((index, field) => {
@ -455,7 +459,7 @@ export class RdDActorSheet extends ActorSheet {
// On pts de reve change
html.find('.pointsreve-value').change(async event => {
let reveValue = event.currentTarget.value;
this.actor.update({ "data.reve.reve.value": reveValue });
this.actor.update({ "system.reve.reve.value": reveValue });
});
// On seuil de reve change
@ -489,7 +493,7 @@ export class RdDActorSheet extends ActorSheet {
html.find('.moral-heureux').click(async event => {
this.actor.jetDeMoral('heureuse');
});
html.find('#ethylisme-test').click(async event => {
html.find('.ethylisme-test').click(async event => {
this.actor.jetEthylisme();
});
@ -562,7 +566,10 @@ export class RdDActorSheet extends ActorSheet {
const sheetHeader = this.element.find(".sheet-header");
const sheetTabs = this.element.find(".sheet-tabs");
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - sheetHeader[0].clientHeight - sheetTabs[0].clientHeight;
let bodyHeight = position.height - sheetHeader[0].clientHeight;
if (sheetTabs.length>0) {
bodyHeight -= sheetTabs[0].clientHeight;
}
sheetBody.css("height", bodyHeight);
return position;
}
@ -572,7 +579,7 @@ export class RdDActorSheet extends ActorSheet {
/** @override */
_updateObject(event, formData) {
// Update the Actor
return this.object.update(formData);
return this.actor.update(formData);
}
async splitItem(item) {
@ -581,11 +588,11 @@ export class RdDActorSheet extends ActorSheet {
}
async _onSplitItem(item, split) {
if (split >= 1 && split < Misc.data(item).data.quantite) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split);
const itemData = duplicate(Misc.data(item));
itemData.data.quantite = split;
await this.actor.createEmbeddedDocuments('Item', [itemData])
const splitItem = duplicate(item);
splitItem.system.quantite = split;
await this.actor.createEmbeddedDocuments('Item', [splitItem])
}
}

View File

@ -1,15 +1,9 @@
/**
* Extend the basic ActorSheet with some very simple modifications
* @extends {ActorSheet}
*/
import { RdDUtility } from "./rdd-utility.js";
import { HtmlUtility } from "./html-utility.js";
import { Misc } from "./misc.js";
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
import { RdDActorSheet } from "./actor-sheet.js";
/* -------------------------------------------- */
export class RdDActorVehiculeSheet extends ActorSheet {
export class RdDActorVehiculeSheet extends RdDActorSheet {
/** @override */
static get defaultOptions() {
@ -25,141 +19,5 @@ export class RdDActorVehiculeSheet extends ActorSheet {
});
}
/* -------------------------------------------- */
async getData() {
const objectData = this.object
let formData = {
title: this.title,
id: objectData.id,
type: objectData.type,
img: objectData.img,
name: objectData.name,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
data: foundry.utils.deepClone(this.object.system),
effects: this.object.effects.map(e => foundry.utils.deepClone(e)),
limited: this.object.limited,
options: this.options,
owner: this.document.isOwner,
itemsByType: Misc.classify(this.object.items.map(i => foundry.utils.deepClone(i))),
};
RdDUtility.filterItemsPerTypeForSheet(formData);
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
formData.options.isGM = game.user.isGM;
formData.calc = {
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
surEncombrementMessage: this.actor.getMessageSurEncombrement()
}
console.log("DATA", formData);
return formData;
}
async computeMalusArmure() {
// pas de malus armure
}
/* -------------------------------------------- */
async _onDropItem(event, dragData) {
const destItemId = $(event.target)?.closest('.item').attr('data-item-id');
const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor.id, dragData, this.objetVersConteneur);
const callSuper = await this.actor.processDropItem(dropParams);
if (callSuper) {
await super._onDropItem(event, dragData)
}
}
/* -------------------------------------------- */
async createItem(name, type) {
await this.actor.createEmbeddedDocuments('Item', [{ name: name, type: type }], { renderSheet: true });
}
/* -------------------------------------------- */
async monnaieIncDec(id, value) {
let monnaie = this.getMonnaie(id);
if (monnaie) {
const quantite = Math.max(0, monnaie.system.quantite + value);
await this.updateEmbeddedDocuments('Item', [{ _id: monnaie.id, 'data.quantite': quantite }]);
}
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
// Update Inventory Item
html.find('.item-edit').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
item.sheet.render(true);
});
// Delete Inventory Item
html.find('.item-delete').click(async event => {
const li = RdDSheetUtility.getEventElement(event);
RdDUtility.confirmerSuppression(this, li);
});
html.find('.item-vendre').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
item?.proposerVente();
});
html.find('.item-montrer').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
item?.postItem();
});
html.find('.item-action').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
this.actor.actionItem(item);
});
html.find('.creer-un-objet').click(async event => {
RdDUtility.selectObjetType(this);
});
html.find('#nettoyer-conteneurs').click(async event => {
this.actor.nettoyerConteneurs();
});
html.find('.monnaie-plus').click(async event => {
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1);
});
html.find('.monnaie-moins').click(async event => {
this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1);
});
// Display info about queue
html.find('.conteneur-name a').click((event) => {
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
this.render(true);
});
}
/* -------------------------------------------- */
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
const sheetHeader = this.element.find(".sheet-header");
const sheetTabs = this.element.find(".sheet-tabs");
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - sheetHeader[0].clientHeight - sheetTabs[0].clientHeight;
sheetBody.css("height", bodyHeight);
return position;
}
/* -------------------------------------------- */
/** @override */
_updateObject(event, formData) {
// Update the Actor
return this.object.update(formData);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
import { Misc } from "./misc.js";
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
export const MESSAGE_DATA = 'message-data';
/**
* Class providing helper methods to get the list of users, and
@ -19,61 +18,50 @@ export class ChatUtility {
/* -------------------------------------------- */
static notifyUser(userId, level = 'info', message) {
const data = {
const socketData = {
userId: userId, level: level, message: message
};
if (game.user.id == userId) {
ChatUtility.onNotifyUser(data);
ChatUtility.onNotifyUser(socketData);
}
else {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_user_ui_notifications", data: data
msg: "msg_user_ui_notifications", data: socketData
});
}
}
static onNotifyUser(data) {
if (game.user.id == data.userId) {
switch (data.level) {
case 'warn': ui.notifications.warn(data.message); break;
case 'error': ui.notifications.error(data.message); break;
default: ui.notifications.info(data.message); break;
static onNotifyUser(socketData) {
if (game.user.id == socketData.userId) {
switch (socketData.level) {
case 'warn': ui.notifications.warn(socketData.message); break;
case 'error': ui.notifications.error(socketData.message); break;
default: ui.notifications.info(socketData.message); break;
}
}
}
/* -------------------------------------------- */
static onRemoveMessages(data) {
static onRemoveMessages(socketData) {
if (Misc.isUniqueConnectedGM()) {
if (data.part) {
const toDelete = game.messages.filter(it => it.data.content.includes(data.part));
if (socketData.part) {
const toDelete = game.messages.filter(it => it.content.includes(socketData.part));
toDelete.forEach(it => it.delete());
}
if (data.messageId) {
game.messages.get(data.messageId)?.delete();
if (socketData.messageId) {
game.messages.get(socketData.messageId)?.delete();
}
}
}
static onRemoveMessages(data) {
if (Misc.isUniqueConnectedGM()) {
if (data.part) {
const toDelete = game.messages.filter(it => it.content.includes(data.part));
toDelete.forEach(it => it.delete());
}
if (data.messageId) {
game.messages.get(data.messageId)?.delete();
}
}
}
/* -------------------------------------------- */
static removeMessages(data) {
static removeMessages(socketData) {
if (Misc.isUniqueConnectedGM()) {
ChatUtility.onRemoveMessages(data);
ChatUtility.onRemoveMessages(socketData);
}
else {
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_delete_chat_message", data: data });
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_delete_chat_message", data: socketData });
}
}
@ -141,7 +129,7 @@ export class ChatUtility {
/* -------------------------------------------- */
static getUsers(filter) {
return Misc.getUsers().filter(filter).map(user => user.data._id);
return game.users.filter(filter).map(user => user.id);
}
/* -------------------------------------------- */
@ -154,17 +142,17 @@ export class ChatUtility {
}
/* -------------------------------------------- */
static handleGMChatMessage(data) {
console.log("blindMessageToGM", data);
static handleGMChatMessage(socketData) {
console.log("blindMessageToGM", socketData);
if (game.user.isGM) { // message privé pour GM only
data.user = game.user.id;
ChatMessage.create(data);
socketData.user = game.user.id;
ChatMessage.create(socketData);
}
}
static async setMessageData(chatMessage, key, data) {
if (data) {
await chatMessage.setFlag(SYSTEM_RDD, key, JSON.stringify(data));
static async setMessageData(chatMessage, key, flag) {
if (flag) {
await chatMessage.setFlag(SYSTEM_RDD, key, JSON.stringify(flag));
}
}

View File

@ -1,5 +1,6 @@
export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon';
export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon';
export const LOG_HEAD = 'RdD | ';
export const HIDE_DICE = 'hide';
export const SHOW_DICE = 'show';

View File

@ -1,7 +1,6 @@
import { ChatUtility } from "./chat-utility.js";
import { HtmlUtility } from "./html-utility.js";
import { RdDItemSigneDraconique } from "./item-signedraconique.js";
import { Misc } from "./misc.js";
import { TMRUtility } from "./tmr-utility.js";
export class DialogCreateSigneDraconique extends Dialog {
@ -10,12 +9,13 @@ export class DialogCreateSigneDraconique extends Dialog {
const signe = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
let dialogData = {
signe: signe,
tmrs: TMRUtility.listSelectedTMR(signe.data.typesTMR ?? []),
actors: game.actors.filter(actor => actor.isHautRevant()).map(actor => {
let actorData = duplicate(actor);
actorData.selected = actor.hasPlayerOwner;
return actorData;
})
tmrs: TMRUtility.buildSelectionTypesTMR(signe.system.typesTMR),
actors: game.actors.filter(actor => actor.isPersonnage() && actor.isHautRevant())
.map(actor => ({
id: actor.id,
name: actor.name,
selected: true
}))
};
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.html", dialogData);
@ -23,12 +23,11 @@ export class DialogCreateSigneDraconique extends Dialog {
.render(true);
}
constructor(dialogData, html, callback) {
constructor(dialogData, html) {
let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 650, 'z-index': 99999 };
let conf = {
title: "Créer un signe",
content: html,
default: "Ajouter aux haut-rêvants",
buttons: {
"Ajouter aux haut-rêvants": { label: "Ajouter aux haut-rêvants", callback: it => { this._onCreerSigneActeurs(); } }
}
@ -38,10 +37,11 @@ export class DialogCreateSigneDraconique extends Dialog {
}
async _onCreerSigneActeurs() {
await $("[name='signe.data.ephemere']").change();
await $("[name='signe.system.ephemere']").change();
await $(".signe-xp-sort").change();
this.validerSigne();
this.dialogData.actors.filter(it => it.selected).map(it => game.actors.get(it._id))
this.dialogData.actors.filter(it => it.selected)
.map(it => game.actors.get(it.id))
.forEach(actor => this._createSigneForActor(actor, this.dialogData.signe));
}
@ -58,61 +58,70 @@ export class DialogCreateSigneDraconique extends Dialog {
validerSigne() {
this.dialogData.signe.name = $("[name='signe.name']").val();
this.dialogData.signe.data.valeur.norm = $("[name='signe.data.valeur.norm']").val();
this.dialogData.signe.data.valeur.sign = $("[name='signe.data.valeur.sign']").val();
this.dialogData.signe.data.valeur.part = $("[name='signe.data.valeur.part']").val();
this.dialogData.signe.data.difficulte = $("[name='signe.data.difficulte']").val();
this.dialogData.signe.data.ephemere = $("[name='signe.data.ephemere']").prop("checked");
this.dialogData.signe.data.duree = $("[name='signe.data.duree']").val();
this.dialogData.signe.data.typesTMR = $(".select-tmr").val();
this.dialogData.signe.system.valeur.norm = $("[name='signe.system.valeur.norm']").val();
this.dialogData.signe.system.valeur.sign = $("[name='signe.system.valeur.sign']").val();
this.dialogData.signe.system.valeur.part = $("[name='signe.system.valeur.part']").val();
this.dialogData.signe.system.difficulte = $("[name='signe.system.difficulte']").val();
this.dialogData.signe.system.ephemere = $("[name='signe.system.ephemere']").prop("checked");
this.dialogData.signe.system.duree = $("[name='signe.system.duree']").val();
this.dialogData.signe.system.typesTMR = TMRUtility.buildListTypesTMRSelection(this.dialogData.tmrs);
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
this.setEphemere(this.dialogData.signe.data.ephemere);
this.setEphemere(this.dialogData.signe.system.ephemere);
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
html.find("[name='signe.data.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
html.find(".select-actor").change((event) => this.onSelectActor(event));
html.find("[name='signe.system.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked));
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event));
html.find("input.select-actor").change((event) => this.onSelectActor(event));
html.find("input.select-tmr").change((event) => this.onSelectTmr(event));
}
async setSigneAleatoire() {
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique({ephemere: true});
$("[name='signe.name']").val(newSigne.name);
$("[name='signe.data.valeur.norm']").val(newSigne.data.valeur.norm);
$("[name='signe.data.valeur.sign']").val(newSigne.data.valeur.sign);
$("[name='signe.data.valeur.part']").val(newSigne.data.valeur.part);
$("[name='signe.data.difficulte']").val(newSigne.data.difficulte);
$("[name='signe.data.duree']").val(newSigne.data.duree);
$("[name='signe.data.ephemere']").prop("checked", newSigne.data.ephemere);
$(".select-tmr").val(newSigne.data.typesTMR);
this.setEphemere(newSigne.data.ephemere);
$("[name='signe.system.valeur.norm']").val(newSigne.system.valeur.norm);
$("[name='signe.system.valeur.sign']").val(newSigne.system.valeur.sign);
$("[name='signe.system.valeur.part']").val(newSigne.system.valeur.part);
$("[name='signe.system.difficulte']").val(newSigne.system.difficulte);
$("[name='signe.system.duree']").val(newSigne.system.duree);
$("[name='signe.system.ephemere']").prop("checked", newSigne.system.ephemere);
this.dialogData.tmrs = TMRUtility.buildSelectionTypesTMR(newSigne.system.typesTMR);
this.dialogData.tmrs.forEach(t => {
$(`[data-tmr-name='${t.name}']`).prop( "checked", t.selected);
})
this.setEphemere(newSigne.system.ephemere);
}
async setEphemere(ephemere) {
this.dialogData.signe.data.ephemere = ephemere;
HtmlUtility._showControlWhen($(".signe-data-duree"), ephemere);
this.dialogData.signe.system.ephemere = ephemere;
HtmlUtility._showControlWhen($(".signe-system-duree"), ephemere);
}
async onSelectActor(event) {
event.preventDefault();
const options = event.currentTarget.options;
for (var i = 0; i < options.length; i++) { // looping over the options
const actorId = options[i].attributes["data-actor-id"].value;
const actor = this.dialogData.actors.find(it => it._id == actorId);
if (actor) {
actor.selected = options[i].selected;
}
};
const actorId = $(event.currentTarget)?.data("actor-id");
const actor = this.dialogData.actors.find(it => it.id == actorId);
if (actor) {
actor.selected = event.currentTarget.checked;
}
}
onSelectTmr(event) {
const tmrName = $(event.currentTarget)?.data("tmr-name");
const onTmr = this.tmrs.find(it => it.name == tmrName);
if (onTmr){
onTmr.selected = event.currentTarget.checked;
}
}
onValeurXpSort(event) {
const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
const xp = Number(event.currentTarget.value);
const oldValeur = this.dialogData.signe.data.valeur;
this.dialogData.signe.data.valeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur);
const oldValeur = this.dialogData.signe.system.valeur;
this.dialogData.signe.system.valeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur);
}
}

View File

@ -6,10 +6,15 @@ export class DialogFabriquerPotion extends Dialog {
/* -------------------------------------------- */
static async create(actor, item, dialogConfig) {
const min = DialogFabriquerPotion.nombreBrinsMinimum(item);
if (item.system.quantite < min) {
ui.notifications.warn(`Vous avez ${item.system.quantite} brins de ${item.name}, il en faut au moins ${min} pour faire une potion!`);
return;
}
let potionData = DialogFabriquerPotion.prepareData(actor, item);
let conf = {
title: `Fabriquer une potion de ${potionData.data.categorie}`,
title: `Fabriquer une potion de ${potionData.system.categorie}`,
content: await renderTemplate(dialogConfig.html, potionData),
default: potionData.buttonName,
};
@ -25,8 +30,11 @@ export class DialogFabriquerPotion extends Dialog {
/* -------------------------------------------- */
static prepareData(actor, item) {
let potionData = duplicate(item)
potionData.nbBrinsSelect = RdDUtility.buildListOptions(1, potionData.data.quantite);
potionData.nbBrins = Math.min(potionData.data.quantite, DialogFabriquerPotion.getNombreBrinOptimal(potionData));
potionData.nbBrinsSelect = RdDUtility.buildListOptions(
DialogFabriquerPotion.nombreBrinsMinimum(item),
DialogFabriquerPotion.nombreBrinsOptimal(item));
potionData.nbBrins = Math.min(potionData.system.quantite, DialogFabriquerPotion.nombreBrinsOptimal(potionData));
potionData.herbebonus = item.system.niveau;
potionData.buttonName = "Fabriquer";
return potionData;
}
@ -45,10 +53,18 @@ export class DialogFabriquerPotion extends Dialog {
this.potionData = potionData;
}
static getNombreBrinOptimal(herbeData) {
switch (herbeData.data.categorie ?? '') {
case "Soin": return 12 - herbeData.data.niveau;
case "Repos": return 7 - herbeData.data.niveau;
static nombreBrinsMinimum(herbeData) {
switch (herbeData.system.categorie ?? '') {
case "Soin": return 1 + Math.max(0, 12 - 2 * herbeData.system.niveau);
case "Repos": return 1 + Math.max(0, 7 - 2 * herbeData.system.niveau);
}
return 1;
}
static nombreBrinsOptimal(herbeData) {
switch (herbeData.system.categorie ?? '') {
case "Soin": return 12 - herbeData.system.niveau;
case "Repos": return 7 - herbeData.system.niveau;
}
return 1;
}
@ -59,6 +75,8 @@ export class DialogFabriquerPotion extends Dialog {
html.find("#nbBrins").change(event => {
this.potionData.nbBrins = Misc.toInt(event.currentTarget.value);
const brinsManquants = Math.max(0, DialogFabriquerPotion.nombreBrinsOptimal(this.potionData) - this.potionData.nbBrins);
this.potionData.herbebonus = Math.max(0, this.potionData.system.niveau - brinsManquants)
});
}

View File

@ -1,69 +1,33 @@
import { Monnaie } from "./item-monnaie.js";
import { Misc } from "./misc.js";
import { RdDUtility } from "./rdd-utility.js";
export class DialogItemAchat extends Dialog {
static async onButtonAcheter(event) {
const buttonAcheter = event.currentTarget;
if (!buttonAcheter.attributes['data-jsondata']?.value) {
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
return;
}
const chatMessageIdVente = RdDUtility.findChatMessageId(buttonAcheter);
const vendeurId = buttonAcheter.attributes['data-vendeurId']?.value;
static venteData(button) {
const vendeurId = button.attributes['data-vendeurId']?.value;
const vendeur = vendeurId ? game.actors.get(vendeurId) : undefined;
const acheteur = RdDUtility.getSelectedActor();
const json = button.attributes['data-jsondata']?.value;
if (!acheteur && !vendeur) {
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
return;
return undefined;
}
if (!json) {
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
return undefined;
}
let venteData = DialogItemAchat.prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur);
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
const dialog = new DialogItemAchat(html, vendeur, acheteur, venteData, chatMessageIdVente);
dialog.render(true);
}
constructor(html, vendeur, acheteur, venteData, chatMessageIdVente) {
const isConsommable = venteData.item.type == 'nourritureboisson';
let options = { classes: ["dialogachat"], width: 400, height: isConsommable ? 450 : 350, 'z-index': 99999 };
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
const buttons = {};
if (isConsommable) {
buttons["consommer"] = { label: venteData.item.data.boisson ? "Boire" : "Manger", callback: it => { this.onAchatConsommer(); } }
}
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
buttons["decliner"] = { label: "Décliner", callback: it => { } };
let conf = {
title: venteData.acheteur? venteData.acheteur.name + " - " + actionAchat : actionAchat,
content: html,
default: actionAchat,
buttons: buttons
};
super(conf, options);
this.vendeur = vendeur;
this.acheteur = acheteur;
this.chatMessageIdVente = chatMessageIdVente;
this.venteData = venteData;
}
static prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur) {
const jsondata = buttonAcheter.attributes['data-jsondata']?.value;
const prixLot = parseInt(buttonAcheter.attributes['data-prixLot']?.value ?? 0);
let venteData = {
item: JSON.parse(jsondata),
const prixLot = Monnaie.arrondiDeniers(button.attributes['data-prixLot']?.value ?? 0);
return {
item: json ? JSON.parse(json) : undefined,
vendeurId: vendeurId,
vendeur: vendeur,
acheteur:acheteur,
tailleLot: parseInt(buttonAcheter.attributes['data-tailleLot']?.value ?? 1),
quantiteIllimite: buttonAcheter.attributes['data-quantiteIllimite']?.value == 'true',
quantiteNbLots: parseInt(buttonAcheter.attributes['data-quantiteNbLots']?.value),
acheteur: acheteur,
tailleLot: parseInt(button.attributes['data-tailleLot']?.value ?? 1),
quantiteIllimite: button.attributes['data-quantiteIllimite']?.value == 'true',
quantiteNbLots: parseInt(button.attributes['data-quantiteNbLots']?.value),
choix: {
nombreLots: 1,
seForcer: false,
@ -71,23 +35,51 @@ export class DialogItemAchat extends Dialog {
},
prixLot: prixLot,
prixTotal: prixLot,
isVente: prixLot > 0
isVente: prixLot > 0,
chatMessageIdVente: RdDUtility.findChatMessageId(button)
};
return venteData;
}
static async onAcheter(venteData) {
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
const dialog = new DialogItemAchat(html, venteData);
dialog.render(true);
}
constructor(html, venteData) {
const isConsommable = venteData.item.type == 'nourritureboisson' && venteData.acheteur?.isPersonnage();
let options = { classes: ["dialogachat"], width: 400, height: isConsommable ? 450 : 350, 'z-index': 99999 };
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
const buttons = {};
if (isConsommable) {
buttons["consommer"] = { label: venteData.item.system.boisson ? "Boire" : "Manger", callback: it => { this.onAchatConsommer(); } }
}
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
buttons["decliner"] = { label: "Décliner", callback: it => { } };
let conf = {
title: venteData.acheteur ? venteData.acheteur.name + " - " + actionAchat : actionAchat,
content: html,
default: actionAchat,
buttons: buttons
};
super(conf, options);
this.venteData = venteData;
}
async onAchat() {
await $(".nombreLots").change();
(this.vendeur ?? this.acheteur).achatVente({
(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
userId: game.user.id,
vendeurId: this.vendeur?.id,
acheteurId: this.acheteur?.id,
vendeurId: this.venteData.vendeur?.id,
acheteurId: this.venteData.acheteur?.id,
prixTotal: this.venteData.prixTotal,
chatMessageIdVente: this.chatMessageIdVente,
chatMessageIdVente: this.venteData.chatMessageIdVente,
choix: this.venteData.choix
});
}
async onAchatConsommer() {
this.venteData.choix.consommer = true;
await this.onAchat();
@ -106,8 +98,12 @@ export class DialogItemAchat extends Dialog {
}
setNombreLots(nombreLots) {
this.venteData.choix.nombreLots = nombreLots;
if (nombreLots > this.venteData.quantiteNbLots) {
ui.notifications.warn(`Seulement ${this.venteData.quantiteNbLots} lots disponibles, vous ne pouvez pas en prendre ${nombreLots}`)
}
this.venteData.choix.nombreLots = Math.min(nombreLots, this.venteData.quantiteNbLots);
this.venteData.prixTotal = (nombreLots * this.venteData.prixLot).toFixed(2);
$(".nombreLots").val(this.venteData.choix.nombreLots);
$(".prixTotal").text(this.venteData.prixTotal);
}

View File

@ -38,22 +38,22 @@ export class DialogConsommer extends Dialog {
/* -------------------------------------------- */
static prepareData(actor, item) {
const itemData = duplicate(item);
item = duplicate(item);
let consommerData = {
item: itemData,
item: item,
cuisine: actor.getCompetence('cuisine'),
choix: {
doses: 1,
seForcer: false,
}
}
switch (itemData.type) {
switch (item.type) {
case 'nourritureboisson':
consommerData.title = itemData.data.boisson ? `${itemData.name}: boire une dose` : `${itemData.name}: manger une portion`;
consommerData.buttonName = itemData.data.boisson ? "Boire" : "Manger";
consommerData.title = item.system.boisson ? `${item.name}: boire une dose` : `${item.name}: manger une portion`;
consommerData.buttonName = item.system.boisson ? "Boire" : "Manger";
break;
case 'potion':
consommerData.title = `${itemData.name}: boire la potion`;
consommerData.title = `${item.name}: boire la potion`;
consommerData.buttonName = "Boire";
break;
}
@ -61,11 +61,11 @@ export class DialogConsommer extends Dialog {
return consommerData;
}
static calculDoses(consommerData) {
const doses = consommerData.choix.doses;
consommerData.totalSust = Misc.keepDecimals(doses * (consommerData.item.data.sust ?? 0), 2);
consommerData.totalDesaltere = consommerData.item.data.boisson
? Misc.keepDecimals(doses * (consommerData.item.data.desaltere ?? 0), 2)
static calculDoses(consommer) {
const doses = consommer.choix.doses;
consommer.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2);
consommer.totalDesaltere = consommer.item.system.boisson
? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2)
: 0;
}

View File

@ -3,16 +3,15 @@ import { Misc } from "./misc.js";
export class DialogItemVente extends Dialog {
static async create(item, callback) {
const itemData = item
const quantite = item.isConteneur() ? 1 : itemData.system.quantite;
static async display(item, callback) {
const quantite = item.isConteneur() ? 1 : item.system.quantite;
const venteData = {
item: itemData,
item: item,
alias: item.actor?.name ?? game.user.name,
vendeurId: item.actor?.id,
prixOrigine: itemData.system.cout,
prixUnitaire: itemData.system.cout,
prixLot: itemData.system.cout,
prixOrigine: item.system.cout,
prixUnitaire: item.system.cout,
prixLot: item.system.cout,
tailleLot: 1,
quantiteNbLots: quantite,
quantiteMaxLots: quantite,
@ -21,7 +20,7 @@ export class DialogItemVente extends Dialog {
isOwned: item.isOwned,
};
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
return new DialogItemVente(venteData, html, callback);
return new DialogItemVente(venteData, html, callback).render(true);
}
constructor(venteData, html, callback) {

View File

@ -3,10 +3,9 @@ import { Misc } from "./misc.js";
export class DialogSplitItem extends Dialog {
static async create(item, callback) {
const itemData = item
const splitData = {
item: itemData,
choix: { quantite: 1, max: itemData.data.quantite - 1 }
item: item,
choix: { quantite: 1, max: item.system.quantite - 1 }
};
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-split.html`, splitData);
return new DialogSplitItem(item, splitData, html, callback)

View File

@ -1,18 +1,19 @@
import { Misc } from "./misc.js";
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
export class DialogStress extends Dialog {
static async distribuerStress() {
let dialogData = {
const dialogData = {
motif: "Motif",
stress: 10,
immediat: false,
actors: game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage())
.map(actor => {
let actorData = duplicate(actor);
actorData.selected = actor.hasPlayerOwner;
return actorData;
})
.map(actor => ({
id: actor.id,
name: actor.name,
selected: true
})
)
};
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-stress.html", dialogData);
@ -21,52 +22,44 @@ export class DialogStress extends Dialog {
}
constructor(dialogData, html) {
let options = { classes: ["DialogStress"], width: 400, height: 320, 'z-index': 99999 };
let conf = {
const options = { classes: ["DialogStress"],
width: 400,
height: 205+dialogData.actors.length*25,
'z-index': 99999
};
const conf = {
title: "Donner du stress",
content: html,
buttons: {
"Stress": { label: "Stress !", callback: it => { this._onStress(); } }
}
stress: { label: "Stress !", callback: it => { this.onStress(); } }
},
default: "stress"
};
super(conf, options);
this.dialogData = dialogData;
}
async _onStress() {
this.validerStress();
const compteur = this.dialogData.immediat ? 'experience' : 'stress';
const stress = this.dialogData.stress;
const motif = this.dialogData.motif;
async onStress() {
const motif = $("form.rdddialogstress input[name='motif']").val();
const stress = Number($("form.rdddialogstress input[name='stress']").val());
const compteur = ($("form.rdddialogstress input[name='immediat']").prop("checked")) ? 'experience' : 'stress';
this.dialogData.actors.filter(it => it.selected)
.map(it => game.actors.get(it._id))
.map(it => game.actors.get(it.id))
.forEach(actor => actor.distribuerStress(compteur, stress, motif));
}
validerStress() {
this.dialogData.motif = $("form.rdddialogstress input[name='motif']").val();
this.dialogData.stress = $("form.rdddialogstress input[name='stress']").val();
this.dialogData.immediat = $("form.rdddialogstress input[name='immediat']").prop("checked");;
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
html.find(".select-actor").change((event) => this.onSelectActor(event));
html.find("input.select-actor").change((event) => this.onSelectActor(event));
}
async onSelectActor(event) {
event.preventDefault();
const options = event.currentTarget.options;
for (var i = 0; i < options.length; i++) { // looping over the options
const actorId = options[i].attributes["data-actor-id"].value;
const actor = this.dialogData.actors.find(it => it._id == actorId);
if (actor) {
actor.selected = options[i].selected;
}
};
const actorId = $(event.currentTarget)?.data("actor-id");
const actor = this.dialogData.actors.find(it => it.id == actorId);
if (actor) {
actor.selected = event.currentTarget.checked;
}
}
}

View File

@ -0,0 +1,70 @@
import { HIDE_DICE, SHOW_DICE } from "./constants.js";
import { RdDUtility } from "./rdd-utility.js";
/**
* Extend the base Dialog entity by defining a custom window to perform roll.
* @extends {Dialog}
*/
export class DialogValidationEncaissement extends Dialog {
static async validerEncaissement(actor, rollData, armure, show, onEncaisser) {
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
actor: actor,
rollData: rollData,
encaissement: encaissement,
show: show
});
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, show, onEncaisser);
dialog.render(true);
}
/* -------------------------------------------- */
constructor(html, actor, rollData, armure, encaissement, show, onEncaisser) {
// Common conf
let buttons = {
"valider": { label: "Valider", callback: html => this.validerEncaissement() },
"annuler": { label: "Annuler", callback: html => { } },
};
let dialogConf = {
title: "Validation d'encaissement",
content: html,
buttons: buttons,
default: "valider"
}
let dialogOptions = {
classes: ["rdddialog"],
width: 350,
height: 290
}
// Select proper roll dialog template and stuff
super(dialogConf, dialogOptions);
this.actor = actor
this.rollData = rollData;
this.armure = armure;
this.encaissement = encaissement;
this.show = show;
this.onEncaisser = onEncaisser;
this.forceDiceResult = {total: encaissement.roll.result };
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
html.find('input.encaissement-roll-result').keyup(async event => {
this.forceDiceResult.total = event.currentTarget.value;
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult});
$('label.encaissement-total').text(this.encaissement.total);
$('label.encaissement-blessure').text(this.encaissement.blessures)
});
}
async validerEncaissement() {
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
this.onEncaisser(this.encaissement, this.show)
}
}

View File

@ -1,9 +0,0 @@
/* -------------------------------------------- */
import { RdDUtility } from "./rdd-utility.js";
/* -------------------------------------------- */
// Activate chat listeners defined
// Hooks.on('renderChatLog', (log, html, data) => {
// RdDUtility.chatListeners(html);
// });

View File

@ -19,18 +19,16 @@ const nomCategorieParade = {
/* -------------------------------------------- */
export class RdDItemArme extends Item {
static isArme(itemData) {
itemData = itemData
return (itemData.type == 'competencecreature' && itemData.system.iscombat) || itemData.type == 'arme';
static isArme(item) {
return (item.type == 'competencecreature' && item.system.iscombat) || item.type == 'arme';
}
/* -------------------------------------------- */
static getArmeData(armeData) {
armeData = armeData
switch (armeData ? armeData.type : '') {
case 'arme': return armeData;
static getArme(arme) {
switch (arme ? arme.type : '') {
case 'arme': return arme;
case 'competencecreature':
return RdDItemCompetenceCreature.toActionArme(armeData);
return RdDItemCompetenceCreature.toActionArme(arme);
}
return RdDItemArme.mainsNues();
}
@ -160,18 +158,18 @@ export class RdDItemArme extends Item {
return armeData;
}
static isArmeUtilisable(itemData) {
return itemData.type == 'arme' && itemData.system.equipe && (itemData.system.resistance > 0 || itemData.system.portee_courte > 0);
static isArmeUtilisable(arme) {
return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0);
}
static ajoutCorpsACorps(armes, competences, carac) {
let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { system: { niveau: -6 } };
let init = RdDCombatManager.calculInitiative(corpsACorps.system.niveau, carac['melee'].value);
armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.system.niveau, initiative: init }));
//armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.data.niveau, initiative: init }));
//armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.system.niveau, initiative: init }));
}
static corpsACorps(actorData) {
static corpsACorps(mainsNuesActor) {
const corpsACorps = {
name: 'Corps à corps',
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp',
@ -186,20 +184,20 @@ export class RdDItemArme extends Item {
categorie_parade: 'sans-armes'
}
};
mergeObject(corpsACorps.system, actorData ?? {}, { overwrite: false });
mergeObject(corpsACorps.system, mainsNuesActor ?? {}, { overwrite: false });
return corpsACorps;
}
static mainsNues(actorData) {
const mainsNues = RdDItemArme.corpsACorps(actorData)
static mainsNues(mainsNuesActor) {
const mainsNues = RdDItemArme.corpsACorps(mainsNuesActor)
mainsNues.name = 'Mains nues'
mainsNues.system.cac = 'pugilat'
mainsNues.system.baseInit = 4
return mainsNues;
}
static empoignade(actorData) {
const empoignade = RdDItemArme.corpsACorps(actorData)
static empoignade(mainsNuesActor) {
const empoignade = RdDItemArme.corpsACorps(mainsNuesActor)
empoignade.name = 'Empoignade'
empoignade.system.cac = 'empoignade'
empoignade.system.baseInit = 3

View File

@ -57,8 +57,8 @@ const competence_xp_cumul = _buildCumulXP();
export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static actorCompendium(actorType) {
return compendiumCompetences[actorType];
static actorCompendium(actorType = undefined) {
return compendiumCompetences[actorType ?? 'personnage'];
}
/* -------------------------------------------- */
@ -84,27 +84,36 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static getVoieDraconic(competences, voie) {
return RdDItemCompetence.findCompetence(competences.filter(it => RdDItemCompetence.isDraconic(it)), voie);
return RdDItemCompetence.findFirstItem(competences, voie, {
preFilter: it => it.isCompetence() && RdDItemCompetence.isDraconic(it),
description: 'Draconic',
});
}
/* -------------------------------------------- */
static isCompetenceArme(competence) {
switch (competence.system.categorie) {
case 'melee':
return competence.name != 'Esquive';
case 'tir':
case 'lancer':
return true;
if (competence.isCompetence()) {
switch (competence.system.categorie) {
case 'melee':
return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive');
case 'tir':
case 'lancer':
return true;
}
}
return false;
}
/* -------------------------------------------- */
static isArmeUneMain(competence) {
return competence.name.toLowerCase().includes("1 main");
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("1 main");
}
static isArme2Main(competence) {
return competence.name.toLowerCase().includes("2 main");
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main");
}
static isThanatos(competence) {
return competence.isCompetencePersonnage() && Grammar.toLowerCaseNoAccent(competence.name).includes('thanatos');
}
/* -------------------------------------------- */
@ -133,7 +142,7 @@ export class RdDItemCompetence extends Item {
/* -------------------------------------------- */
static computeXP(competence) {
const factor = competence.name.includes('Thanatos') ? 2 : 1; // Thanatos compte double !
const factor = RdDItemCompetence.isThanatos(competence) ? 2 : 1; // Thanatos compte double !
const xpNiveau = RdDItemCompetence.computeDeltaXP(competence.system.base, competence.system.niveau ?? competence.system.base);
const xp = competence.system.xp ?? 0;
const xpSort = competence.system.xp_sort ?? 0;
@ -183,29 +192,29 @@ export class RdDItemCompetence extends Item {
}
/* -------------------------------------------- */
static levelUp(itemData, stressTransforme) {
itemData.system.xpNext = RdDItemCompetence.getCompetenceNextXp(itemData.system.niveau);
const xpManquant = itemData.system.xpNext - itemData.system.xp;
itemData.system.isLevelUp = xpManquant <= 0;
itemData.system.isStressLevelUp = (xpManquant > 0 && stressTransforme >= xpManquant && itemData.system.niveau < itemData.system.niveau_archetype);
itemData.system.stressXpMax = 0;
if (xpManquant > 0 && stressTransforme > 0 && itemData.system.niveau < itemData.system.niveau_archetype) {
itemData.system.stressXpMax = Math.min(xpManquant , stressTransforme);
static levelUp(item, stressTransforme) {
item.system.xpNext = RdDItemCompetence.getCompetenceNextXp(item.system.niveau);
const xpManquant = item.system.xpNext - item.system.xp;
item.system.isLevelUp = xpManquant <= 0;
item.system.isStressLevelUp = (xpManquant > 0 && stressTransforme >= xpManquant && item.system.niveau < item.system.niveau_archetype);
item.system.stressXpMax = 0;
if (xpManquant > 0 && stressTransforme > 0 && item.system.niveau < item.system.niveau_archetype) {
item.system.stressXpMax = Math.min(xpManquant , stressTransforme);
}
}
/* -------------------------------------------- */
static isVisible(itemData) {
return Number(itemData.data.niveau) != RdDItemCompetence.getNiveauBase(itemData.data.categorie);
static isVisible(item) {
return Number(item.system.niveau) != RdDItemCompetence.getNiveauBase(item.system.categorie);
}
static nomContientTexte(itemData, texte) {
return Grammar.toLowerCaseNoAccent(itemData.name).includes(Grammar.toLowerCaseNoAccent(texte))
static nomContientTexte(item, texte) {
return Grammar.toLowerCaseNoAccent(item.name).includes(Grammar.toLowerCaseNoAccent(texte))
}
/* -------------------------------------------- */
static isNiveauBase(itemData) {
return Number(itemData.system.niveau) == RdDItemCompetence.getNiveauBase(itemData.system.categorie);
static isNiveauBase(item) {
return Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie);
}
/* -------------------------------------------- */
@ -213,21 +222,18 @@ export class RdDItemCompetence extends Item {
if (idOrName == undefined) {
return undefined;
}
options = mergeObject(options, {
preFilter: it => RdDItemCompetence.isCompetence(it),
description: 'compétence',
});
return list.find(it => it.id == idOrName && RdDItemCompetence.isCompetence(it))
?? Misc.findFirstLike(idOrName, list, options);
options = mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence' }, {overwrite: false});
return RdDItemCompetence.findFirstItem(list, idOrName, options);
}
/* -------------------------------------------- */
static findCompetences(list, name) {
return Misc.findAllLike(name, list, { filter: it => RdDItemCompetence.isCompetence(it), description: 'compétence' });
return Misc.findAllLike(name, list, { filter: it => it.isCompetence(), description: 'compétence' });
}
static isCompetence(item) {
return item.type == 'competence' || item.type == 'competencecreature';
static findFirstItem(list, idOrName, options) {
return list.find(it => it.id == idOrName && options.preFilter(it))
?? Misc.findFirstLike(idOrName, list, options);
}
/* -------------------------------------------- */

View File

@ -1,4 +1,5 @@
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
/* -------------------------------------------- */
export class RdDItemCompetenceCreature extends Item {
@ -16,36 +17,37 @@ export class RdDItemCompetenceCreature extends Item {
}
/* -------------------------------------------- */
static toActionArme(item) {
if (RdDItemCompetenceCreature.isCompetenceAttaque(item)) {
static toActionArme(competencecreature) {
if (RdDItemCompetenceCreature.isCompetenceAttaque(competencecreature)) {
// si c'est un Item compétence: cloner pour ne pas modifier lma compétence
let arme = (item instanceof Item) ? item.clone(): item;
let arme = (competencecreature instanceof Item) ? competencecreature.clone(): competencecreature;
mergeObject(arme.system,
{
competence: arme.name,
resistance: 100,
initiative: RdDCombatManager.calculInitiative(competencecreature.system.niveau, competencecreature.system.carac_value),
niveau: competencecreature.system.niveau,
equipe: true,
resistance: 100,
dommagesReels: arme.system.dommages,
penetration: 0,
force: 0,
rapide: true,
cac: competencecreature.system.isnaturelle ? "naturelle" : "",
action: 'attaque'
});
return arme;
}
console.error("RdDItemCompetenceCreature.toActionArme(", item, ") : impossible de transformer l'Item en arme");
console.error("RdDItemCompetenceCreature.toActionArme(", competencecreature, ") : impossible de transformer l'Item en arme");
return undefined;
}
/* -------------------------------------------- */
static isCompetenceAttaque(itemData) {
itemData = itemData
return itemData.type == 'competencecreature' && itemData.system.iscombat;
static isCompetenceAttaque(item) {
return item.type == 'competencecreature' && item.system.iscombat;
}
/* -------------------------------------------- */
static isCompetenceParade(itemData) {
itemData = itemData
return itemData.type == 'competencecreature' && itemData.system.isparade;
static isCompetenceParade(item) {
return item.type == 'competencecreature' && item.system.categorie_parade !== "";
}
}

View File

@ -1,59 +1,93 @@
import { Misc } from "./misc.js";
import { LOG_HEAD } from "./constants.js";
const monnaiesData = [
{
name: "Etain (1 denier)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
data: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
},
{
name: "Bronze (10 deniers)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
data: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
},
{
name: "Argent (1 sol)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
data: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
},
{
name: "Or (10 sols)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
data: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
}
]
const MONNAIE_ETAIN = {
name: "Etain (1 denier)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
system: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
};
const MONNAIE_BRONZE = {
name: "Bronze (10 deniers)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
system: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
};
const MONNAIE_ARGENT = {
name: "Argent (1 sol)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
system: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
};
const MONNAIE_OR = {
name: "Or (10 sols)", type: 'monnaie',
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
system: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
};
const MONNAIES_STANDARD = [MONNAIE_ETAIN, MONNAIE_BRONZE, MONNAIE_ARGENT, MONNAIE_OR];
export class Monnaie {
static isSystemMonnaie(item) {
let present = monnaiesData.find(monnaie => monnaie.system.valeur_deniers == item?.system?.valeur_deniers);
return present;
static monnaiesStandard() {
return MONNAIES_STANDARD;
}
static monnaiesData() {
return monnaiesData;
static monnaiesManquantes(actor) {
const disponibles = actor.itemTypes['monnaie'];
const manquantes = MONNAIES_STANDARD.filter(standard => !disponibles.find(disponible => Monnaie.deValeur(disponible, standard.system?.valeur_deniers)));
if (manquantes.length > 0) {
console.error(`${LOG_HEAD} monnaiesManquantes pour ${actor.name}`, manquantes, ' avec monnaies', disponibles, MONNAIES_STANDARD);
}
return manquantes;
}
static filtrerMonnaies(items) {
return items.filter(it => it.type == 'monnaie');
}
static monnaiesManquantes(items) {
const valeurs = Monnaie.filtrerMonnaies(items)
.map(it => it.system.valeur_deniers);
const manquantes = monnaiesData.filter(monnaie => !valeurs.find(v => v != monnaie.system?.valeur_deniers))
return []; //manquantes;
}
static deValeur(monnaie, v) {
return v != monnaie.system.valeur_deniers
static deValeur(monnaie, valeur) {
return valeur == monnaie.system.valeur_deniers
}
static arrondiDeniers(sols) {
return sols.toFixed(2);
return Number(sols).toFixed(2);
}
static triValeurDenier() {
return Misc.ascending(item => item.system.valeur_deniers)
}
static async creerMonnaiesStandard(actor) {
await actor.createEmbeddedDocuments('Item', MONNAIES_STANDARD, { renderSheet: false });
}
static async creerMonnaiesDeniers(actor, fortune) {
await actor.createEmbeddedDocuments('Item', [Monnaie.creerDeniers(fortune)], { renderSheet: false });
}
static creerDeniers(fortune) {
const deniers = duplicate(MONNAIE_ETAIN);
deniers.system.quantite = fortune;
return deniers;
}
static async optimiser(actor, fortune) {
let reste = fortune;
let monnaies = actor.itemTypes['monnaie'];
let updates = [];
let parValeur = Misc.classifyFirst(monnaies, it => it.system.valeur_deniers);
for (let valeur of [1000, 100, 10, 1]) {
const itemPiece = parValeur[valeur];
const piecesDeCetteValeur = Math.floor(reste / valeur);
if (itemPiece) {
if (piecesDeCetteValeur != itemPiece.system.quantite) {
updates.push({ _id: parValeur[valeur].id, 'system.quantite': piecesDeCetteValeur });
}
reste -= piecesDeCetteValeur*valeur;
}
}
console.log('Monnaie.optimiser', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', reste);
if (updates.length > 0) {
await actor.updateEmbeddedDocuments('Item', updates);
}
if (reste>0){
// créer le reste en deniers fortune en deniers
await Monnaie.creerMonnaiesDeniers(actor, reste);
}
}
}

View File

@ -32,7 +32,7 @@ export class RdDItemSheet extends ItemSheet {
let buttons = super._getHeaderButtons();
// Add "Post to chat" button
// We previously restricted this to GM and editable items only. If you ever find this comment because it broke something: eh, sorry!
if ("cout" in this.object.system && this.object.isVideOuNonConteneur()) {
if ("cout" in this.item.system && this.item.isVideOuNonConteneur()) {
buttons.unshift({
class: "vendre",
icon: "fas fa-comments-dollar",
@ -61,53 +61,68 @@ export class RdDItemSheet extends ItemSheet {
/* -------------------------------------------- */
async getData() {
let formData = {
id: this.object.id,
title: this.object.name,
type: this.object.type,
img: this.object.img,
name: this.object.name,
data: this.object.system,
id: this.item.id,
title: this.item.name,
type: this.item.type,
img: this.item.img,
name: this.item.name,
system: this.item.system,
// TODO: v10 remove
data: this.item.system,
isGM: game.user.isGM,
actorId: this.actor?.id,
owner: this.document.isOwner,
owner: this.item.isOwner,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
isSoins: false
isSoins: false,
description: await TextEditor.enrichHTML(this.object.system.description, {async: true}),
descriptionmj: await TextEditor.enrichHTML(this.object.system.descriptionmj, {async: true})
}
if (this.actor) {
formData.isOwned = true;
if (this.object.type == 'conteneur') {
if (this.item.type == 'conteneur') {
this.prepareConteneurData(formData);
}
}
formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences()
if (formData.type == 'tache' || formData.type == 'livre' || formData.type == 'meditation' || formData.type == 'oeuvre') {
if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences')
formData.competences = await RdDUtility.loadItems(it => it.isCompetencePersonnage(), RdDItemCompetence.actorCompendium(this.actor?.type))
}
if (formData.type == 'arme') {
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it));
console.log(formData.competences)
if (this.item.type == 'arme') {
formData.competences = await RdDUtility.loadItems(it => RdDItemCompetence.isCompetenceArme(it), RdDItemCompetence.actorCompendium(this.actor?.type))
}
if (formData.type == 'recettealchimique') {
RdDAlchimie.processManipulation(objectData, this.actor && this.actor.id);
if (this.item.type == 'recettecuisine') {
formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, {async: true})
}
if (formData.type == 'gemme') {
if (this.item.type == 'recettealchimique') {
RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id);
formData.manipulation_update = await TextEditor.enrichHTML(this.object.system.manipulation_update, {async: true})
formData.utilisation = await TextEditor.enrichHTML(this.object.system.utilisation, {async: true})
formData.enchantement = await TextEditor.enrichHTML(this.object.system.enchantement, {async: true})
formData.sureffet = await TextEditor.enrichHTML(this.object.system.sureffet, {async: true})
}
if (this.item.type == 'gemme') {
formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList();
RdDGemme.calculDataDerivees(formData.data);
RdDGemme.calculDataDerivees(this.item);
}
if (formData.type == 'potion') {
if (this.item.type == 'potion') {
if (this.dateUpdated) {
formData.data.prdate = this.dateUpdated;
formData.system.prdate = this.dateUpdated;
this.dateUpdated = undefined;
}
RdDHerbes.updatePotionData(formData);
await RdDHerbes.updatePotionData(formData);
}
if (formData.isOwned && formData.type == 'herbe' && (formData.data.categorie == 'Soin' || formData.data.categorie == 'Repos')) {
if (formData.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) {
formData.isIngredientPotionBase = true;
}
if (this.item.type == 'sortreserve') {
const sortId = this.item.system.sortid;
formData.sort = formData.isOwned ? this.item.actor.items.get(sortId) : game.items.get(sortId);
}
formData.bonusCaseList = RdDItemSort.getBonusCaseList(formData, true);
return formData;
@ -115,11 +130,10 @@ export class RdDItemSheet extends ItemSheet {
/* -------------------------------------------- */
prepareConteneurData(formData) {
formData.itemsByType = Misc.classify(this.actor.items.map(i => foundry.utils.deepClone(i)))
RdDUtility.filterEquipementParType(formData)
RdDUtility.filterEquipementParType(formData, this.actor.itemTypes);
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
formData.subItems = formData.conteneurs.find(it => it._id == this.object.id)?.subItems;
formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems;
}
@ -128,15 +142,15 @@ export class RdDItemSheet extends ItemSheet {
activateListeners(html) {
super.activateListeners(html);
if (this.object.type == 'conteneur') {
if (this.item.type == 'conteneur') {
this.form.ondragstart = (event) => this._onDragStart(event);
this.form.ondrop = (event) => this._onDrop(event);
}
let itemSheetDialog = this;
HtmlUtility._showControlWhen($(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.object.isOwned);
HtmlUtility._showControlWhen($(".item-magique"), this.object.isMagique());
HtmlUtility._showControlWhen($(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.item.isOwned);
HtmlUtility._showControlWhen($(".item-magique"), this.item.isMagique());
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
@ -145,8 +159,8 @@ export class RdDItemSheet extends ItemSheet {
html.find(".categorie").change(event => this._onSelectCategorie(event));
html.find('.sheet-competence-xp').change((event) => {
if (this.object.data.type == 'competence') {
RdDUtility.checkThanatosXP(this.object.data.name);
if (this.item.isCompetencePersonnage()) {
RdDUtility.checkThanatosXP(this.item.name);
}
});
@ -195,7 +209,8 @@ export class RdDItemSheet extends ItemSheet {
});
html.find('.item-delete').click(async event => {
const li = RdDSheetUtility.getEventElement(event);
RdDUtility.confirmerSuppression(this, li);
const item = this.actor.getObjet(li.data("item-id"));
RdDUtility.confirmerSuppressionItem(this, item, li);
});
html.find('.item-vendre').click(async event => {
const item = RdDSheetUtility.getItem(event, this.actor);
@ -219,16 +234,16 @@ export class RdDItemSheet extends ItemSheet {
async _onSelectCategorie(event) {
event.preventDefault();
if (this.object.isCompetence()) {
if (this.item.isCompetence()) {
let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
this.object.system.base = level;
this.item.system.base = level;
$("#base").val(level);
}
}
/* -------------------------------------------- */
get template() {
let type = this.object.type
let type = this.item.type
return `systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html`;
}
@ -239,7 +254,7 @@ export class RdDItemSheet extends ItemSheet {
// Données de bonus de cases ?
formData = RdDItemSort.buildBonusCaseStringFromFormData(formData);
return this.object.update(formData);
return this.item.update(formData);
}
async _onDragStart(event) {
@ -252,28 +267,28 @@ export class RdDItemSheet extends ItemSheet {
const dragData = {
actorId: this.actor.id,
type: "Item",
data: item.data
data: item.system
};
event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
}
async _onDrop(event) {
// Try to extract the data
let data;
// Try to extract the dragData
let dragData;
try {
data = JSON.parse(event.dataTransfer.getData('text/plain'));
dragData = JSON.parse(event.dataTransfer.getData('text/plain'));
} catch (err) {
return false;
}
const allowed = Hooks.call("dropActorSheetData", this.actor, this, data);
const allowed = Hooks.call("dropActorSheetData", this.actor, this, dragData);
if (allowed === false) return;
// Handle different data types
switch (data.type) {
// Handle different dragData types
switch (dragData.type) {
case "Item":
return this._onDropItem(event, data);
return this._onDropItem(event, dragData);
}
return super._onDrop(event);
}
@ -281,7 +296,7 @@ export class RdDItemSheet extends ItemSheet {
/* -------------------------------------------- */
async _onDropItem(event, dragData) {
if (this.actor) {
const dropParams = RdDSheetUtility.prepareItemDropParameters(this.object.id, this.actor.id, dragData, this.objetVersConteneur);
const dropParams = RdDSheetUtility.prepareItemDropParameters(this.item.id, this.actor.id, dragData, this.objetVersConteneur);
await this.actor.processDropItem(dropParams);
await this.render(true);
}

View File

@ -32,25 +32,25 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
const position = super.setPosition(options);
const sheetHeader = this.element.find(".sheet-header");
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - sheetHeader[0].clientHeight;
sheetBody.css("height", bodyHeight);
sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
return position;
}
/* -------------------------------------------- */
async getData() {
const formData = duplicate(this.object);
const formData = duplicate(this.item);
this.tmrs = TMRUtility.buildSelectionTypesTMR(this.item.system.typesTMR);
mergeObject(formData, {
tmrs: this.tmrs,
title: formData.name,
isGM: game.user.isGM,
owner: this.document.isOwner,
owner: this.actor?.isOwner,
isOwned: this.actor ? true : false,
actorId: this.actor?.id,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
});
formData.tmrs = TMRUtility.listSelectedTMR(formData.data.typesTMR ?? []);
return formData;
}
@ -62,27 +62,31 @@ export class RdDSigneDraconiqueItemSheet extends ItemSheet {
if (!this.options.editable) return;
html.find(".signe-aleatoire").click(event => this.setSigneAleatoire());
html.find(".select-tmr").change((event) => this.onSelectTmr(event));
html.find("input.select-tmr").change((event) => this.onSelectTmr(event));
html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value)));
}
async setSigneAleatoire() {
const newSigne = await RdDItemSigneDraconique.randomSigneDraconique();
this.object.update(newSigne);
this.item.update(newSigne);
}
async onSelectTmr(event) {
event.preventDefault();
const selectedTMR = $(".select-tmr").val();
this.object.update({ 'data.typesTMR': selectedTMR });
const tmrName = $(event.currentTarget)?.data("tmr-name");
const onTmr = this.tmrs.find(it => it.name == tmrName);
if (onTmr){
onTmr.selected = event.currentTarget.checked;
}
this.item.update({ 'system.typesTMR': TMRUtility.buildListTypesTMRSelection(this.tmrs) });
}
async onValeurXpSort(event) {
const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0;
const xp = Number(event.currentTarget.value);
const oldValeur = this.object.system.valeur;
const oldValeur = this.item.system.valeur;
const newValeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur);
await this.object.update({ 'data.valeur': newValeur });
await this.item.update({ 'system.valeur': newValeur });
}
/* -------------------------------------------- */

View File

@ -18,13 +18,12 @@ const DIFFICULTE_LECTURE_SIGNE_MANQUE = +11;
export class RdDItemSigneDraconique {
static prepareSigneDraconiqueMeditation(meditation, rolled) {
meditation = meditation
return {
name: "de la " + meditation.name,
type: "signedraconique",
img: meditation.img,
data: {
typesTMR: [TMRUtility.typeTmrName(meditation.data.tmr)],
system: {
typesTMR: [TMRUtility.typeTmrName(meditation.system.tmr)],
difficulte: rolled.isSuccess ? RdDItemSigneDraconique.getDiffSigneMeditation(rolled.code) : DIFFICULTE_LECTURE_SIGNE_MANQUE,
ephemere: true,
duree: "1 round",
@ -75,7 +74,7 @@ export class RdDItemSigneDraconique {
name: await RdDItemSigneDraconique.randomSigneDescription(),
type: "signedraconique",
img: defaultItemImg.signedraconique,
data: {
system: {
typesTMR: await RdDItemSigneDraconique.randomTmrs(modele.nbCases),
ephemere: options?.ephemere == undefined ? RdDDice.rollTotal("1d2") == 2 : options.ephemere,
duree: "1 round",

View File

@ -7,12 +7,12 @@ export class RdDItemSort extends Item {
/* -------------------------------------------- */
static isDifficulteVariable(sort) {
return sort && (sort.data.difficulte.toLowerCase() == "variable");
return sort && (sort.system.difficulte.toLowerCase() == "variable");
}
/* -------------------------------------------- */
static isCoutVariable(sort) {
return sort && (sort.data.ptreve.toLowerCase() == "variable" || sort.data.ptreve.indexOf("+") >= 0);
return sort && (sort.system.ptreve.toLowerCase() == "variable" || sort.system.ptreve.indexOf("+") >= 0);
}
/* -------------------------------------------- */
@ -25,7 +25,7 @@ export class RdDItemSort extends Item {
/* -------------------------------------------- */
static getDifficulte(sort, variable) {
if (sort && !RdDItemSort.isDifficulteVariable(sort)) {
return Misc.toInt(sort.data.difficulte);
return Misc.toInt(sort.system.difficulte);
}
return variable;
}
@ -54,40 +54,40 @@ export class RdDItemSort extends Item {
static getBonusCaseList( item, newCase = false ) {
// Gestion spéciale case bonus
if ( item.type == 'sort') {
return this.buildBonusCaseList(item.data.bonuscase, newCase );
return this.buildBonusCaseList(item.system.bonuscase, newCase );
}
return undefined;
}
/* -------------------------------------------- */
/** Met à jour les données de formulaire
* si static des bonus de cases sont présents
* */
static buildBonusCaseStringFromFormData( formData ) {
if ( formData.bonusValue ) {
let list = [];
let caseCheck = {};
for(let i=0; i<formData.bonusValue.length; i++) {
let coord = formData.caseValue[i] || 'A1';
coord = coord.toUpperCase();
if ( TMRUtility.verifyTMRCoord( coord ) ) { // Sanity check
let bonus = formData.bonusValue[i] || 0;
if ( bonus > 0 && caseCheck[coord] == undefined ) {
caseCheck[coord] = bonus;
list.push( coord+":"+bonus );
}
/* -------------------------------------------- */
/** Met à jour les données de formulaire
* si static des bonus de cases sont présents
* */
static buildBonusCaseStringFromFormData( formData ) {
if ( formData.bonusValue ) {
let list = [];
let caseCheck = {};
for(let i=0; i<formData.bonusValue.length; i++) {
let coord = formData.caseValue[i] || 'A1';
coord = coord.toUpperCase();
if ( TMRUtility.verifyTMRCoord( coord ) ) { // Sanity check
let bonus = formData.bonusValue[i] || 0;
if ( bonus > 0 && caseCheck[coord] == undefined ) {
caseCheck[coord] = bonus;
list.push( coord+":"+bonus );
}
}
formData.bonusValue = undefined;
formData.caseValue = undefined;
formData['data.bonuscase'] = list.toString(); // Reset
}
return formData;
formData.bonusValue = undefined;
formData.caseValue = undefined;
formData.system.bonuscase = list.toString(); // Reset
}
return formData;
}
/* -------------------------------------------- */
static incrementBonusCase( actor, sort, coord ) {
let bonusCaseList = this.buildBonusCaseList(sort.data.bonuscase, false);
let bonusCaseList = this.buildBonusCaseList(sort.system.bonuscase, false);
//console.log("ITEMSORT", sort, bonusCaseList);
let found = false;
@ -106,12 +106,12 @@ export class RdDItemSort extends Item {
// Sauvegarde/update
let bonuscase = StringList.toString();
//console.log("Bonus cae :", bonuscase);
actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'data.bonuscase': bonuscase }] );
actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': bonuscase }] );
}
/* -------------------------------------------- */
static getCaseBonus( sort, coord) {
let bonusCaseList = this.buildBonusCaseList(sort.data.bonuscase, false);
let bonusCaseList = this.buildBonusCaseList(sort.system.bonuscase, false);
for( let bc of bonusCaseList) {
if (bc.case == coord) { // Case existante
return Number(bc.bonus);

View File

@ -1,15 +1,35 @@
import { DialogItemVente } from "./dialog-item-vente.js";
import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { RdDHerbes } from "./rdd-herbes.js";
import { RdDUtility } from "./rdd-utility.js";
const typesObjetsEquipement = ["objet", "arme", "armure", "gemme", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "nourritureboisson", "monnaie"]
const typesObjetsEquipement = [
"arme",
"armure",
"conteneur",
"gemme",
"herbe",
"ingredient",
"livre",
"monnaie",
"munition",
"nourritureboisson",
"objet",
"potion",
]
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
const encBrin = 0.00005;// un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve"]
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
const typesObjetsEffet = ["possession", "poison", "maladie"]
const typesObjetsCompetence = ["competence", "competencecreature"]
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/
*/
export const defaultItemImg = {
competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
compcreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
competencecreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp",
armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp",
conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp",
@ -35,20 +55,21 @@ export const defaultItemImg = {
nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp",
gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp"
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
}
/* -------------------------------------------- */
export class RdDItem extends Item {
constructor(data, context) {
if (!data.img) {
data.img = defaultItemImg[data.type];
constructor(itemData, context) {
if (!itemData.img) {
itemData.img = defaultItemImg[itemData.type];
}
super(data, context);
super(itemData, context);
}
static getTypeObjetsEquipement() {
static getTypesObjetsEquipement() {
return typesObjetsEquipement
}
@ -56,14 +77,41 @@ export class RdDItem extends Item {
return typesObjetsOeuvres
}
isCompetence() {
return this.type == 'competence';
isCompetencePersonnage() {
return this.type == 'competence'
}
isCompetence() {
return typesObjetsCompetence.includes(this.type)
}
isEquipement() {
return typesObjetsEquipement.includes(this.type)
}
isOeuvre() {
return typesObjetsOeuvres.includes(this.type)
}
isDraconique() {
return typesObjetsDraconiques.includes(this.type)
}
isEffet() {
return typesObjetsEffet.includes(this.type)
}
isConnaissance() {
return typesObjetsConnaissance.includes(this.type)
}
isConteneur() {
return this.type == 'conteneur';
}
getItemGroup() {
if (this.isEquipement()) return "equipement";
if (this.isOeuvre()) return "oeuvre";
if (this.isDraconique()) return "draconique";
if (this.isConnaissance()) return "connaissance";
if (this.isEffet()) return "effet";
if (this.isCompetence()) return "competence";
return "autres";
}
isConteneurNonVide() {
return this.isConteneur() && (this.system.contenu?.length ?? 0) > 0;
}
@ -85,11 +133,6 @@ export class RdDItem extends Item {
isPotion() {
return this.type == 'potion';
}
isEquipement() {
return RdDItem.getTypeObjetsEquipement().includes(this.type)
}
isCristalAlchimique() {
return this.type == 'objet' && Grammar.toLowerCaseNoAccent(this.name) == 'cristal alchimique' && this.system.quantite > 0;
}
@ -98,26 +141,40 @@ export class RdDItem extends Item {
return this.system.magique
}
getEncTotal() {
return Number(this.system.encombrement ?? 0) * Number(this.system.quantite ?? 1)
getQuantite() {
return Math.round(this.isConteneur() ? 1 : (this.system.quantite ?? 0))
}
getEncTotal() {
return this.getEnc() * this.getQuantite();
}
getEnc() {
switch (this.type) {
case 'herbe':
return encBrin;
case 'gemme':
return encPepin * this.system.taille;
}
return this.system.encombrement ?? 0;
return Math.max(this.system.encombrement ?? 0, 0);
}
prixTotalDeniers() {
return this.getQuantite() * this.valeurDeniers()
}
valeurDeniers() {
return Math.max(Math.round(this.system.cout ? (this.system.cout * 100) : (this.system.valeur_deniers ?? 0)), 0)
}
prepareDerivedData() {
super.prepareDerivedData();
if (this.isEquipement()) {
this._calculsEquipement();
this.system.encTotal = this.getEncTotal();
if (this.isPotion()) {
this.prepareDataPotion()
}
this.actionPrincipale = this.getActionPrincipale({ warnIfNot: false });
this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false });
}
}
@ -126,41 +183,35 @@ export class RdDItem extends Item {
this.system.magique = categorie.includes('enchante');
if (this.system.magique) {
if (categorie.includes('soin') || categorie.includes('repos')) {
this.system.puissance = this.system.herbebonus * this.system.pr;
// TODO: utiliser calculPointsRepos / calculPointsGuerison
this.system.puissance = RdDHerbes.calculPuissancePotion(this);
}
}
}
_calculsEquipement() {
const quantite = this.isConteneur() ? 1 : (this.system.quantite ?? 0);
const enc = this.getEnc();
if (enc != undefined) {
this.system.encTotal = Math.max(enc, 0) * quantite;
}
if (this.cout != undefined) {
this.system.prixTotal = Math.max(this.cout, 0) * quantite;
}
}
getActionPrincipale(options = { warnIfNot: true }) {
if (!this.isConteneur() && (this.system.quantite ?? 0) <= 0) {
if (options.warnIfNot) {
const warn = options.warnIfNot;
switch (this.type) {
case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
case 'conteneur': return 'Ouvrir';
case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
case 'queue': case 'ombre': return this.system.refoulement>0 ? 'Refouler' : undefined;
}
return undefined;
}
_actionOrWarnQuantiteZero(actionName, warn){
if ((this.system.quantite ?? 0) <= 0) {
if (warn) {
ui.notifications.warn(`Vous n'avez plus de ${this.name}.`);
}
return undefined;
}
switch (this.type) {
case 'nourritureboisson': return this.boisson ? 'Boire' : 'Manger';
case 'potion': return 'Boire';
case 'livre': return 'Lire';
case 'conteneur': return 'Ouvrir';
else {
return actionName;
}
if (this.isHerbeAPotion()) { return 'Décoction'; }
if (options.warnIfNot) {
ui.notifications.warn(`Impossible d'utiliser un ${this.name}, aucune action associée définie.`);
}
return undefined;
}
async diminuerQuantite(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
@ -180,63 +231,63 @@ export class RdDItem extends Item {
}
else {
ui.notifications.notify(`Il ne vous reste plus de ${this.name}, vous pouvez le supprimer de votre équipement, ou trouver un moyen de vous en procurer.`);
await this.update({ "data.quantite": 0 });
await this.update({ "system.quantite": 0 });
}
}
else {
await this.update({ "data.quantite": reste });
await this.update({ "system.quantite": reste });
}
}
}
/* -------------------------------------------- */
// détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité
isEquipementSimilaire(other) {
const itemData = this
const otherData = other
const tplData = this
const otherTplData = other
if (!this.isEquipement()) return false;
if (itemData.type != otherData.type) return false;
if (itemData.name != otherData.name) return false;
if (tplData.quantite == undefined) return false;
messageEquipementDifferent(other) {
if (!other || !this.isEquipement()) return undefined;
const differences = Object.entries(tplData).filter(([key, value]) => !['quantite', 'encTotal', 'prixTotal', 'cout'].includes(key))
.filter(([key, value]) => value != otherTplData[key]);
if (differences.length > 0) {
let message = `Impossible de regrouper les ${itemData.type} ${itemData.name}: `;
for (const [key, value] of differences) {
message += `<br>${key}: ${value} vs ${otherTplData[key]}`;
}
ui.notifications.info(message)
return false;
let message = undefined;
if (this.system.quantite == undefined) {
message = `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`;
}
else if (this.type != other.type) {
message = `Impossible de regrouper des ${this.type} avec des ${other.type}`;
}
return true;
else if (this.name != other.name) {
message = `Impossible de regrouper ${this.name} avec ${other.name}`;
}
else {
const differences = Object.entries(this.system)
.filter(([key, value]) => !['quantite', 'cout'].includes(key) && value != other.system[key]);
if (differences.length > 0) {
message = `Impossible de regrouper les ${this.type} ${this.name}: `;
for (const [key, value] of differences) {
message += `<br>${key}: ${value} vs ${other.system[key]}`;
}
}
}
return message;
}
async proposerVente() {
console.log(this);
if (this.isConteneurNonVide()) {
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le donner ou le vendre`);
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
return;
}
const dialog = await DialogItemVente.create(this, (vente) => this._onProposerVente(vente))
dialog.render(true);
}
async _onProposerVente(venteData) {
venteData["properties"] = this.getProprietes();
if (venteData.isOwned) {
if (venteData.quantiteNbLots * venteData.tailleLot > venteData.quantiteMax) {
ui.notifications.warn(`Vous avez ${venteData.quantiteMax} ${venteData.item.name}, ce n'est pas suffisant pour vendre ${venteData.quantiteNbLots} de ${venteData.tailleLot}`)
return;
await DialogItemVente.display(this, async (vente) => {
vente["properties"] = this.getProprietes();
if (vente.isOwned) {
if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`)
return;
}
}
}
venteData.jsondata = JSON.stringify(venteData.item);
console.log(venteData);
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', venteData);
ChatMessage.create(RdDUtility.chatDataSetup(html));
vente.jsondata = JSON.stringify(vente.item);
console.log(vente);
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
ChatMessage.create(RdDUtility.chatDataSetup(html));
});
}
/* -------------------------------------------- */

160
module/migrations.js Normal file
View File

@ -0,0 +1,160 @@
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
import { Grammar } from "./grammar.js";
class Migration {
get code() { return "sample"; }
get version() { return "0.0.0"; }
async migrate() { }
async applyItemsUpdates(computeUpdates) {
await game.actors.forEach(async (actor) => {
const actorItemUpdates = computeUpdates(actor.items);
if (actorItemUpdates.length > 0) {
console.log(
this.code,
`Applying updates on actor ${actor.name} items`,
actorItemUpdates
);
await actor.updateEmbeddedDocuments("Item", actorItemUpdates);
}
});
const itemUpdates = computeUpdates(game.items);
if (itemUpdates.length > 0) {
console.log(this.code, "Applying updates on items", itemUpdates);
await Item.updateDocuments(itemUpdates);
}
}
}
class _10_0_16_MigrationSortsReserve extends Migration {
get code() { return "creation-item-sort-reserve"; }
get version() { return "10.0.16"; }
async migrate() {
await game.actors
.filter((actor) => actor.type == "personnage")
.filter((actor) => actor.system.reve?.reserve?.list?.length ?? 0 > 0)
.forEach(async (actor) => {
const sortsReserve = actor.system.reve.reserve.list.map(this.conversionSortReserve);
console.log(`${LOG_HEAD} Migration des sorts en réserve de ${actor.name}`, sortsReserve);
await actor.createEmbeddedDocuments("Item", sortsReserve, {
renderSheet: false,
});
await actor.update({ 'system.reve.reserve.list': [] })
});
}
conversionSortReserve(it) {
return {
type: 'sortreserve',
name: it.sort.name,
img: it.sort.img,
system: {
// ATTENTION, utilisation de data / _id possibles, encore présents pour les anciens sorts en réserve
sortid: it.sort._id,
draconic: it.sort.draconic,
ptreve: (it.sort.system ?? it.sort.data).ptreve_reel,
coord: it.coord,
heurecible: 'Vaisseau',
},
};
}
}
class _10_0_17_MigrationCompetenceCreature extends Migration {
get code() { return "competences-creature-parade"; }
get version() { return "10.0.17"; }
async migrate() {
await this.applyItemsUpdates(items => items
.filter(it => it.type == "competencecreature" && it.system.isparade && it.system.categorie_parade == "")
.map(it => { return { _id: it.id, "system.categorie_parade": "armes-naturelles" } }));
await this.applyItemsUpdates(items => items
.filter(it => it.type == "competencecreature" && it.system.iscombat)
.map(it => { return { _id: it.id, "system.categorie": (Grammar.includesLowerCaseNoAccent(it.name, "lancee") ? "lancer" : "melee") } })
);
}
}
class _10_0_21_VehiculeStructureResistanceMax extends Migration {
get code() { return "vehicule-structure-resistance-max"; }
get version() { return "10.0.21"; }
async migrate() {
await game.actors
.filter((actor) => actor.type == "vehicule")
.forEach(async (actor) => {
await actor.update({
'system.etat.resistance.value': actor.system.resistance,
'system.etat.resistance.max': actor.system.resistance,
'system.etat.structure.value': actor.system.structure,
'system.etat.structure.max': actor.system.structure
})
});
}
}
export class Migrations {
static getMigrations() {
return [
new _10_0_16_MigrationSortsReserve(),
new _10_0_17_MigrationCompetenceCreature(),
new _10_0_21_VehiculeStructureResistanceMax(),
];
}
constructor() {
game.settings.register(SYSTEM_RDD, "systemMigrationVersion", {
name: "System Migration Version",
scope: "world",
config: false,
type: String,
default: "0.0.0",
});
}
migrate() {
const currentVersion = game.settings.get(
SYSTEM_RDD,
"systemMigrationVersion"
);
if (isNewerVersion(game.system.version, currentVersion)) {
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
if (migrations.length > 0) {
migrations.sort((a, b) =>
isNewerVersion(a.version, b.version)
? 1
: isNewerVersion(b.version, a.version)
? -1
: 0
);
migrations.forEach(async (m) => {
ui.notifications.info(
`Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}`
);
await m.migrate();
});
ui.notifications.info(
`Migrations done, version will change to ${game.system.version}`
);
} else {
console.log(
LOG_HEAD +
`No migration needeed, version will change to ${game.system.version}`
);
}
game.settings.set(
SYSTEM_RDD,
"systemMigrationVersion",
game.system.version
);
} else {
console.log(LOG_HEAD + `No system version changed`);
}
}
}

View File

@ -105,17 +105,6 @@ export class Misc {
return params.reduce((a, b) => a + separator + b);
}
static getEntityTypeLabel(entity) {
const documentName = entity?.documentName
const type = entity?.type
if (documentName === 'Actor' || documentName === 'Item') {
const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
return game.i18n.has(label) ? game.i18n.localize(label) : t;
}
return type;
}
static connectedGMOrUser(ownerId = undefined) {
if (ownerId && game.user.id == ownerId) {
return ownerId;
@ -123,16 +112,12 @@ export class Misc {
return Misc.firstConnectedGM()?.id ?? game.user.id;
}
static getUsers() {
return game.version ? game.users : game.users.entities;
}
static getActiveUser(id) {
return Misc.getUsers().find(u => u.id == id && u.active);
return game.users.find(u => u.id == id && u.active);
}
static firstConnectedGM() {
return Misc.getUsers().filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
return game.users.filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
}
@ -153,7 +138,7 @@ export class Misc {
/* -------------------------------------------- */
static findPlayer(name) {
return Misc.findFirstLike(name, Misc.getUsers(), { description: 'joueur' });
return Misc.findFirstLike(name, game.users, { description: 'joueur' });
}
/* -------------------------------------------- */

View File

@ -7,9 +7,9 @@ const matchOperationTerms = new RegExp(/@(\w*){([\w\-]+)}/i);
export class RdDAlchimie {
/* -------------------------------------------- */
static processManipulation(recetteData, actorId = undefined) {
static processManipulation(recette, actorId = undefined) {
//console.log("CALLED", recette, recette.isOwned, actorId );
let manip = recetteData.data.manipulation;
let manip = recette.system.manipulation;
let matchArray = manip.match(matchOperations);
if (matchArray) {
for (let matchStr of matchArray) {
@ -17,12 +17,12 @@ export class RdDAlchimie {
//console.log("RESULT ", result);
if (result[1] && result[2]) {
let commande = Misc.upperFirst(result[1]);
let replacement = this[`_alchimie${commande}`](recetteData, result[2], actorId);
let replacement = this[`_alchimie${commande}`](recette, result[2], actorId);
manip = manip.replace(result[0], replacement);
}
}
}
recetteData.data.manipulation_update = manip;
recette.system.manipulation_update = manip;
}
/* -------------------------------------------- */

View File

@ -12,23 +12,23 @@ export class RdDAstrologieJoueur extends Dialog {
/* -------------------------------------------- */
static async create(actor, dialogConfig) {
let data = {
let dialogData = {
nombres: this.organizeNombres(actor),
dates: game.system.rdd.calendrier.getJoursSuivants(10),
etat: actor.getEtatGeneral(),
ajustementsConditions: CONFIG.RDD.ajustementsConditions,
astrologie: RdDItemCompetence.findCompetence(actor.items, 'Astrologie')
}
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', data);
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', dialogData);
let options = { classes: ["rdddialog"], width: 600, height: 500, 'z-index': 99999 };
if (dialogConfig.options) {
mergeObject(options, dialogConfig.options, { overwrite: true });
}
return new RdDAstrologieJoueur(html, actor, data);
return new RdDAstrologieJoueur(html, actor, dialogData);
}
/* -------------------------------------------- */
constructor(html, actor, data) {
constructor(html, actor, dialogData) {
let myButtons = {
saveButton: { label: "Fermer", callback: html => this.quitDialog() }
@ -41,7 +41,7 @@ export class RdDAstrologieJoueur extends Dialog {
super(dialogConf, dialogOptions);
this.actor = actor;
this.dataNombreAstral = duplicate(data);
this.dataNombreAstral = duplicate(dialogData);
}
/* -------------------------------------------- */
@ -63,7 +63,7 @@ export class RdDAstrologieJoueur extends Dialog {
/* -------------------------------------------- */
requestJetAstrologie() {
let data = {
let socketData = {
id: this.actor.id,
carac_vue: this.actor.system.carac['vue'].value,
etat: this.dataNombreAstral.etat,
@ -73,11 +73,11 @@ export class RdDAstrologieJoueur extends Dialog {
userId: game.user.id
}
if (Misc.isUniqueConnectedGM()) {
game.system.rdd.calendrier.requestNombreAstral(data);
game.system.rdd.calendrier.requestNombreAstral(socketData);
} else {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_request_nombre_astral",
data: data
data: socketData
});
}
this.close();

View File

@ -223,9 +223,9 @@ export class RdDCalendrier extends Application {
checkMaladie( periode) {
for (let actor of game.actors) {
if (actor.type == 'personnage') {
let maladies = actor.filterItems( item => (item.type == 'maladie' || (item.type == 'poison' && item.data.active) ) && item.data.periodicite.toLowerCase().includes(periode) );
let maladies = actor.items.filter( item => (item.type == 'maladie' || (item.type == 'poison' && item.system.active) ) && item.system.periodicite.toLowerCase().includes(periode) );
for (let maladie of maladies) {
if ( maladie.data.identifie) {
if ( maladie.system.identifie) {
ChatMessage.create({ content: `${actor.name} souffre de ${maladie.name} (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` });
} else {
ChatMessage.create({ content: `${actor.name} souffre d'un mal inconnu (${maladie.type}): vérifiez que les effets ne se sont pas aggravés !` });
@ -444,9 +444,9 @@ export class RdDCalendrier extends Application {
/* -------------------------------------------- */
updateDisplay() {
let data = this.fillCalendrierData();
// Rebuild data
let dateHTML = `Jour ${data.jourMois} de ${data.nomMois} (${data.nomSaison})`
let calendrier = this.fillCalendrierData();
// Rebuild text du calendrier
let dateHTML = `Jour ${calendrier.jourMois} de ${calendrier.nomMois} (${calendrier.nomSaison})`
if (game.user.isGM) {
dateHTML = dateHTML + " - NA: " + (this.getCurrentNombreAstral() ?? "indéterminé");
}
@ -454,13 +454,13 @@ export class RdDCalendrier extends Application {
handle.innerHTML = dateHTML;
}
for (let heure of document.getElementsByClassName("calendar-heure-texte")) {
heure.innerHTML = data.nomHeure;
heure.innerHTML = calendrier.nomHeure;
}
for (const minute of document.getElementsByClassName("calendar-time-disp")) {
minute.innerHTML = `${data.minutesRelative} minutes`;
minute.innerHTML = `${calendrier.minutesRelative} minutes`;
}
for (const heureImg of document.getElementsByClassName("calendar-heure-img")) {
heureImg.src = data.iconHeure;
heureImg.src = calendrier.iconHeure;
}
}
@ -534,9 +534,7 @@ export class RdDCalendrier extends Application {
async activateListeners(html) {
super.activateListeners(html);
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
await this.updateDisplay();
this.updateDisplay();
html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));

View File

@ -62,7 +62,7 @@ export class RdDCarac {
static computeTotal(carac, beaute = undefined) {
const total = Object.values(carac).filter(c => !c.derivee)
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
.map(it => parseInt(it.value))
.reduce(Misc.sum(), 0);
const beauteSuperieur10 = Math.max((beaute ?? 10) - 10, 0);
@ -101,35 +101,35 @@ export class RdDCarac {
}
/* -------------------------------------------- */
static computeCarac(data) {
data.carac.force.value = Math.min(data.carac.force.value, parseInt(data.carac.taille.value) + 4);
static computeCarac(system) {
system.carac.force.value = Math.min(system.carac.force.value, parseInt(system.carac.taille.value) + 4);
data.carac.derobee.value = Math.floor(parseInt(((21 - data.carac.taille.value)) + parseInt(data.carac.agilite.value)) / 2);
let bonusDomKey = Math.floor((parseInt(data.carac.force.value) + parseInt(data.carac.taille.value)) / 2);
system.carac.derobee.value = Math.floor(parseInt(((21 - system.carac.taille.value)) + parseInt(system.carac.agilite.value)) / 2);
let bonusDomKey = Math.floor((parseInt(system.carac.force.value) + parseInt(system.carac.taille.value)) / 2);
bonusDomKey = Math.min(Math.max(bonusDomKey, 0), 32); // Clamp de securite
let tailleData = tableCaracDerivee[bonusDomKey];
data.attributs.plusdom.value = tailleData.plusdom;
system.attributs.plusdom.value = tailleData.plusdom;
data.attributs.sconst.value = RdDCarac.calculSConst(data.carac.constitution.value);
data.attributs.sust.value = tableCaracDerivee[Number(data.carac.taille.value)].sust;
system.attributs.sconst.value = RdDCarac.calculSConst(system.carac.constitution.value);
system.attributs.sust.value = tableCaracDerivee[Number(system.carac.taille.value)].sust;
data.attributs.encombrement.value = (parseInt(data.carac.force.value) + parseInt(data.carac.taille.value)) / 2;
data.carac.melee.value = Math.floor((parseInt(data.carac.force.value) + parseInt(data.carac.agilite.value)) / 2);
data.carac.tir.value = Math.floor((parseInt(data.carac.vue.value) + parseInt(data.carac.dexterite.value)) / 2);
data.carac.lancer.value = Math.floor((parseInt(data.carac.tir.value) + parseInt(data.carac.force.value)) / 2);
system.attributs.encombrement.value = (parseInt(system.carac.force.value) + parseInt(system.carac.taille.value)) / 2;
system.carac.melee.value = Math.floor((parseInt(system.carac.force.value) + parseInt(system.carac.agilite.value)) / 2);
system.carac.tir.value = Math.floor((parseInt(system.carac.vue.value) + parseInt(system.carac.dexterite.value)) / 2);
system.carac.lancer.value = Math.floor((parseInt(system.carac.tir.value) + parseInt(system.carac.force.value)) / 2);
data.sante.vie.max = Math.ceil((parseInt(data.carac.taille.value) + parseInt(data.carac.constitution.value)) / 2);
system.sante.vie.max = Math.ceil((parseInt(system.carac.taille.value) + parseInt(system.carac.constitution.value)) / 2);
data.sante.vie.value = Math.min(data.sante.vie.value, data.sante.vie.max)
data.sante.endurance.max = Math.max(parseInt(data.carac.taille.value) + parseInt(data.carac.constitution.value), parseInt(data.sante.vie.max) + parseInt(data.carac.volonte.value));
data.sante.endurance.value = Math.min(data.sante.endurance.value, data.sante.endurance.max);
data.sante.fatigue.max = data.sante.endurance.max * 2;
data.sante.fatigue.value = Math.min(data.sante.fatigue.value, data.sante.fatigue.max);
system.sante.vie.value = Math.min(system.sante.vie.value, system.sante.vie.max)
system.sante.endurance.max = Math.max(parseInt(system.carac.taille.value) + parseInt(system.carac.constitution.value), parseInt(system.sante.vie.max) + parseInt(system.carac.volonte.value));
system.sante.endurance.value = Math.min(system.sante.endurance.value, system.sante.endurance.max);
system.sante.fatigue.max = system.sante.endurance.max * 2;
system.sante.fatigue.value = Math.min(system.sante.fatigue.value, system.sante.fatigue.max);
//Compteurs
data.reve.reve.max = data.carac.reve.value;
data.compteurs.chance.max = data.carac.chance.value;
system.reve.reve.max = system.carac.reve.value;
system.compteurs.chance.max = system.carac.chance.value;
}

View File

@ -1,5 +1,5 @@
import { ChatUtility } from "./chat-utility.js";
import { ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { Grammar } from "./grammar.js";
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
@ -10,6 +10,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDRoll } from "./rdd-roll.js";
import { RdDRollTables } from "./rdd-rolltables.js";
import { ReglesOptionelles } from "./regles-optionelles.js";
import { STATUSES } from "./status-effects.js";
/* -------------------------------------------- */
const premierRoundInit = [
@ -66,7 +67,7 @@ export class RdDCombatManager extends Combat {
/* -------------------------------------------- */
async finDeRound(options = { terminer: false }) {
for (let combatant of this.data.combatants) {
for (let combatant of this.combatants) {
if (combatant.actor) {
await combatant.actor.finDeRound(options);
}
@ -78,8 +79,8 @@ export class RdDCombatManager extends Combat {
/************************************************************************************/
async rollInitiative(ids, formula = undefined, messageOptions = {}) {
console.log(`${game.data.system.data.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
// Structure input data
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
ids = typeof ids === "string" ? [ids] : ids;
const currentId = this.combatant._id;
// calculate initiative
@ -93,13 +94,13 @@ export class RdDCombatManager extends Combat {
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
}
} else {
const armeCombat = combatant.actor.items.find(it => it.type == 'arme' && itemData.system.equipe)
const armeCombat = combatant.actor.itemTypes['arme'].find(it => it.system.equipe)
const compName = (armeCombat == undefined) ? "Corps à corps" : armeCombat.system.competence;
const competence = RdDItemCompetence.findCompetence(combatant.actor.items, compName);
if (competence) {
const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
const niveau = competence.system.niveau;
const bonusEcaille = (armeCombat?.data.magique) ? armeCombat.system.ecaille_efficacite : 0;
const bonusEcaille = (armeCombat?.system.magique) ? armeCombat.system.ecaille_efficacite : 0;
rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, bonusEcaille);
}
}
@ -155,14 +156,14 @@ export class RdDCombatManager extends Combat {
// Gestion des armes 1/2 mains
let actionsArme = [];
for (const arme of armes) {
let action = duplicate(Misc.data(arme));
let action = duplicate(arme)
if (action.system.equipe) {
let compData = competences.find(c => c.name == action.system.competence)
actionsArme.push(action);
action.action = 'attaque';
action.system.dommagesReels = Number(action.system.dommages);
action.system.niveau = compData.data.niveau;
action.system.niveau = compData.system.niveau;
action.system.initiative = RdDCombatManager.calculInitiative(compData.system.niveau, carac[compData.system.defaut_carac].value);
// Dupliquer les armes pouvant être à 1 main et 2 mains en patchant la compétence
if (action.system.unemain && !action.system.deuxmains) {
@ -196,15 +197,20 @@ export class RdDCombatManager extends Combat {
return actionsArme.sort(Misc.ascending(armeData => armeData.name + (armeData.system.mainInfo ?? '')));
}
static listActionsCreature(competences) {
return competences.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
.map(it => RdDItemCompetenceCreature.toActionArme(it));
}
static listActionsPossessions(actor) {
return RdDCombatManager._indexActions(actor.getPossessions().map(p =>
{
return {
name: p.name,
action: 'conjurer',
data: {
system: {
competence: p.name,
possessionid: p.data.data.possessionid,
possessionid: p.system.possessionid,
}
}
}));
@ -217,21 +223,19 @@ export class RdDCombatManager extends Combat {
if (actions.length>0) {
return actions;
}
let items = actor.items;
if (actor.isCreature()) {
actions = actions.concat(items.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
.map(competence => RdDItemCompetenceCreature.toActionArme(competence)));
actions = actions.concat(RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']));
} else {
// Recupération des items 'arme'
let armes = items.filter(it => RdDItemArme.isArmeUtilisable(it))
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
//.concat(RdDItemArme.empoignade())
.concat(RdDItemArme.mainsNues());
let competences = items.filter(it => it.type == 'competence');
actions = actions.concat(RdDCombatManager.listActionsArmes(armes, competences, actor.data.data.carac));
const competences = actor.itemTypes['competence'];
actions = actions.concat(RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac));
if (actor.data.data.attributs.hautrevant.value) {
actions.push({ name: "Draconic", action: 'haut-reve', data: { initOnly: true, competence: "Draconic" } });
if (actor.system.attributs.hautrevant.value) {
actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } });
}
}
@ -249,14 +253,14 @@ export class RdDCombatManager extends Combat {
static processPremierRoundInit() {
// Check if we have the whole init !
if (Misc.isUniqueConnectedGM() && game.combat.current.round == 1) {
let initMissing = game.combat.data.combatants.find(it => !it.initiative);
let initMissing = game.combat.combatants.find(it => !it.initiative);
if (!initMissing) { // Premier round !
for (let combatant of game.combat.data.combatants) {
for (let combatant of game.combat.combatants) {
let action = combatant.initiativeData?.arme;
//console.log("Parsed !!!", combatant, initDone, game.combat.current, arme);
if (action && action.type == "arme") {
for (let initData of premierRoundInit) {
if (Grammar.toLowerCaseNoAccentNoSpace(action.data.initpremierround).includes(initData.pattern)) {
if (Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround).includes(initData.pattern)) {
let msg = `<h4>L'initiative de ${combatant.actor.name} a été modifiée !</h4>
<hr>
<div>
@ -327,22 +331,16 @@ export class RdDCombatManager extends Combat {
initOffset = 9;
initInfo = "Draconic"
} else {
compData = RdDItemCompetence.findCompetence(combatant.actor.items, arme.system.competence);
compData = RdDItemCompetence.findCompetence(combatant.actor.items, action.system.competence);
compNiveau = compData.system.niveau;
initInfo = action.name + " / " + action.data.competence;
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
caracForInit = compData.data.carac_value;
if (compData.system.categorie == "lancer") {
initOffset = 7;
}
else {
initOffset = 5;
}
} else {
caracForInit = combatant.actor.system.carac[compData.system.defaut_carac].value;
initOffset = RdDCombatManager._baseInitOffset(compData.system.categorie, action);
initInfo = action.name + " / " + action.system.competence;
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
caracForInit = compData.system.carac_value;
} else {
caracForInit = combatant.actor.system.carac[compData.system.defaut_carac].value;
}
initOffset = RdDCombatManager._baseInitOffset(compData.system.categorie, action);
}
let malus = combatant.actor.getEtatGeneral(); // Prise en compte état général
@ -353,6 +351,7 @@ export class RdDCombatManager extends Combat {
game.combat.rollInitiative(combatantId, rollFormula, { initInfo: initInfo });
}
/* -------------------------------------------- */
static _baseInitOffset(categorie, arme) {
if (categorie == "tir") { // Offset de principe pour les armes de jet
return 8;
@ -360,10 +359,12 @@ export class RdDCombatManager extends Combat {
if (categorie == "lancer") { // Offset de principe pour les armes de jet
return 7;
}
// Offset de principe pour les armes de jet
switch (arme.data.cac) {
case "empoignade": return 3;
case "pugilat": return 4;
switch (arme.system.cac) {
case "empoignade":
return 3;
case "pugilat":
case "naturelle":
return 4;
}
return 5;
}
@ -384,7 +385,7 @@ export class RdDCombatManager extends Combat {
let menuItems = [];
for (let action of actions) {
menuItems.push({
name: action.data.competence,
name: action.system.competence,
icon: "<i class='fas fa-dice-d6'></i>",
callback: target => { RdDCombatManager.rollInitiativeAction(combatantId, action) }
});
@ -415,7 +416,7 @@ export class RdDCombat {
/* -------------------------------------------- */
static onUpdateCombat(combat, change, options, userId) {
if (combat.data.round != 0 && combat.turns && combat.data.active) {
if (combat.round != 0 && combat.turns && combat.active) {
RdDCombat.combatNouveauTour(combat);
}
}
@ -448,7 +449,7 @@ export class RdDCombat {
/* -------------------------------------------- */
static createUsingTarget(attacker) {
const target = RdDCombat.getTarget();
const target = RdDCombat.getTarget()
if (target == undefined) {
ui.notifications.warn((game.user.targets?.size ?? 0) > 1
? "Vous devez choisir <strong>une seule</strong> cible à attaquer!"
@ -555,12 +556,12 @@ export class RdDCombat {
/* -------------------------------------------- */
constructor(attacker, defender, defenderTokenId, target) {
this.attacker = attacker;
this.defender = defender;
this.target = target;
this.attackerId = this.attacker.id;
this.defenderId = this.defender.id;
this.defenderTokenId = defenderTokenId;
this.attacker = attacker
this.defender = defender
this.target = target
this.attackerId = this.attacker.id
this.defenderId = this.defender.id
this.defenderTokenId = defenderTokenId
}
/* -------------------------------------------- */
@ -686,8 +687,82 @@ export class RdDCombat {
return rollData.rolled.isSuccess;
}
/* -------------------------------------------- */
async proposerAjustementTirLancer( rollData ) {
if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) {
if (this.defender.isEntite([ENTITE_BLURETTE])){
ChatMessage.create( {
content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
whisper: ChatMessage.getWhisperRecipients("GM")})
}
else {
const defenderToken = canvas.tokens.get(this.defenderTokenId);
const dist = this.distance(_token, defenderToken)
const isVisible = this.isVisible(_token, defenderToken)
const portee = this._ajustementPortee(dist, rollData.arme)
const taille = this._ajustementTaille(this.defender)
const activite = this._ajustementMouvement(this.defender)
const total = [portee, taille, activite].map(it=>it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0)
ChatMessage.create({
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', {
rollData: rollData,
attacker: _token,
isVisible: isVisible,
defender: defenderToken,
distance: dist,
portee: portee,
taille: taille,
activite: activite,
total: total
}),
whisper: ChatMessage.getWhisperRecipients("GM")
})
}
}
}
isVisible(token, defenderToken) {
return canvas.effects.visibility.testVisibility(defenderToken.center, { object: token })
}
distance(token, defenderToken) {
return Number(canvas.grid.measureDistances([{ ray: new Ray(token.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
}
_ajustementPortee(dist, arme) {
if (dist <= arme.system.portee_courte) return {msg:"courte", diff:0};
if (dist <= arme.system.portee_moyenne) return {msg: "moyenne" , diff: -3};
if (dist <= arme.system.portee_extreme) return {msg: "extrême", diff:-5};
return {msg: "inatteignable", diff: -10};
}
_ajustementTaille(actor) {
if (actor.isVehicule()) return {msg: "véhicule", diff: 0}
const taille = actor.getCaracByName('TAILLE')?.value ?? 1;
if (taille <= 1) return {msg: "souris", diff: -8};
if (taille <= 3) return {msg: "chat", diff: -4};
if (taille <= 5) return {msg: "chien", diff: -2};
if (taille <= 15) return {msg: "humanoïde", diff: 0};
if (taille <= 20) return {msg: "ogre", diff: 2};
return {msg: "gigantesque", diff: 4};
}
_ajustementMouvement(defender) {
if (defender.getSurprise(true)) return {msg: "immobile (surprise)", diff: 0};
if (game.combat?.combatants.find(it => it.actorId == defender.id)) return {msg: "en mouvement (combat)", diff: -4};
return {msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3};
}
/* -------------------------------------------- */
async attaque(competence, arme) {
// const nonIncarnee = this.defender.isEntite([ENTITE_NONINCARNE])
// const blurette = this.defender.isEntite([ENTITE_BLURETTE])
// if (nonIncarnee || blurette) {
// ChatMessage.create( {
// content: `<strong>La cible est ${nonIncarnee ? 'non incarnée' : 'une blurette'}.
// Il est impossible de l'atteindre.`,
// whisper: ChatMessage.getWhisperRecipients("GM")})
// }
if (!await this.accorderEntite('avant-attaque')) {
return;
}
@ -708,6 +783,7 @@ export class RdDCombat {
if (arme) {
this.attacker.verifierForceMin(arme);
}
await this.proposerAjustementTirLancer(rollData)
const dialog = await RdDRoll.create(this.attacker, rollData,
{
@ -802,7 +878,7 @@ export class RdDCombat {
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntite());
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
attackerRoll.show = {
cible: this.target ? this.defender.system.name : 'la cible',
cible: this.target ? this.defender.name : 'la cible',
isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge')
}
await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
@ -833,7 +909,7 @@ export class RdDCombat {
// # utilisation esquive
const corpsACorps = this.defender.getCompetence("Corps à corps", { onMessage: it => console.info(it, this.defender) });
const esquives = duplicate(this.defender.getCompetences("esquive", { onMessage: it => console.info(it, this.defender) }))
esquives.forEach(e => e.usages = e?.id ? this.defender.getItemUse(e.id) : 0);
esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0);
const paramChatDefense = {
passeArme: attackerRoll.passeArme,
@ -892,8 +968,7 @@ export class RdDCombat {
/* -------------------------------------------- */
_filterArmesParade(defender, competence) {
let items = defender.items;
items = items.filter(it => RdDItemArme.isArmeUtilisable(it) || RdDItemCompetenceCreature.isCompetenceParade(it))
let items = defender.items.filter(it => RdDItemArme.isArmeUtilisable(it) || RdDItemCompetenceCreature.isCompetenceParade(it))
for (let item of items) {
item.system.nbUsage = defender.getItemUse(item.id); // Ajout du # d'utilisation ce round
}
@ -960,10 +1035,10 @@ export class RdDCombat {
async parade(attackerRoll, armeParadeId) {
const arme = this.defender.getArmeParade(armeParadeId);
console.log("RdDCombat.parade >>>", attackerRoll, armeParadeId, arme);
const competence = this.system?.competence;
const competence = arme?.system?.competence;
if (competence == undefined)
{
console.error("Pas de compétence de parade associée à ", arme) ;
console.error("Pas de compétence de parade associée à ", arme?.name, armeParadeId) ;
return;
}
@ -1144,7 +1219,7 @@ export class RdDCombat {
resistance -= perteResistance;
defenderRoll.show.deteriorationArme = resistance <= 0 ? 'brise' : 'perte';
defenderRoll.show.perteResistance = perteResistance;
this.defender.updateEmbeddedDocuments('Item', [{ _id: defenderRoll.arme._id, 'data.resistance': resistance }]);
this.defender.updateEmbeddedDocuments('Item', [{ _id: defenderRoll.arme._id, 'system.resistance': resistance }]);
}
}
} else {
@ -1160,7 +1235,7 @@ export class RdDCombat {
resistance -= dmg;
defenderRoll.show.deteriorationArme = resistance <= 0 ? 'brise' : 'perte';
defenderRoll.show.perteResistance = dmg;
this.defender.updateEmbeddedDocuments('Item', [{ _id: defenderRoll.arme._id, 'data.resistance': resistance }]);
this.defender.updateEmbeddedDocuments('Item', [{ _id: defenderRoll.arme._id, 'system.resistance': resistance }]);
}
}
// Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132)
@ -1186,7 +1261,7 @@ export class RdDCombat {
defenderRoll.show.recul = 'encaisse';
} else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) {
defenderRoll.show.recul = 'chute';
await this.defender.setStatusEffect("EFFECT.StatusProne", true);
await this.defender.setEffect(STATUSES.StatusProne, true);
}
else {
defenderRoll.show.recul = 'recul';
@ -1228,7 +1303,7 @@ export class RdDCombat {
attackerRoll.defenderTokenId = defenderTokenId;
await this.computeRecul(defenderRoll);
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll);
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show);
}
else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
game.socket.emit(SYSTEM_SOCKET_ID, {
@ -1274,7 +1349,7 @@ export class RdDCombat {
/* -------------------------------------------- */
static async displayActorCombatStatus(combat, actor) {
let data = {
let formData = {
combatId: combat._id,
alias: actor.name,
etatGeneral: actor.getEtatGeneral(),
@ -1286,13 +1361,13 @@ export class RdDCombat {
isCritique: false
}
if (actor.countBlessuresNonSoigneeByName("critiques") > 0) { // Pour éviter le cumul grave + critique
data.isCritique = true;
formData.isCritique = true;
} else if (actor.countBlessuresNonSoigneeByName("graves") > 0) {
data.isGrave = true;
formData.isGrave = true;
}
ChatUtility.createChatWithRollMode(actor.name, {
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html`, data)
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html`, formData)
});
}
}

View File

@ -358,10 +358,9 @@ export class RdDCommands {
async supprimerSignesDraconiquesEphemeres() {
game.actors.forEach(actor => {
const ephemeres = actor.filterItems(item => item.type = 'signedraconique' && item.system.ephemere)
.map(item => item.id);
const ephemeres = actor.items.filter(item => item.type = 'signedraconique' && item.system.ephemere);
if (ephemeres.length > 0) {
actor.deleteEmbeddedDocuments("Item", ephemeres);
actor.deleteEmbeddedDocuments("Item", ephemeres.map(item => item.id));
}
});
return true;

View File

@ -1,13 +1,12 @@
import { SYSTEM_RDD } from "./constants.js";
import { Misc } from "./misc.js";
export class RddCompendiumOrganiser {
static init() {
Hooks.on('renderCompendium', async (pack, html, data) => RddCompendiumOrganiser.onRenderCompendium(pack, html, data))
Hooks.on('renderCompendium', async (pack, html, compendiumData) => RddCompendiumOrganiser.onRenderCompendium(pack, html, compendiumData))
}
static async onRenderCompendium(compendium, html, data) {
console.log('onRenderCompendium', compendium, html, data);
static async onRenderCompendium(compendium, html, compendiumData) {
console.log('onRenderCompendium', compendium, html, compendiumData);
const pack = compendium.collection
if (pack.metadata.system === SYSTEM_RDD) {
html.find('.directory-item').each((i, element) => {
@ -17,7 +16,7 @@ export class RddCompendiumOrganiser {
}
static async setEntityTypeName(pack, element) {
const label = Misc.getEntityTypeLabel(await pack.getDocument(element.dataset.documentId));
const label = RddCompendiumOrganiser.getEntityTypeLabel(await pack.getDocument(element.dataset.documentId));
RddCompendiumOrganiser.insertEntityType(element, label);
}
@ -27,4 +26,16 @@ export class RddCompendiumOrganiser {
}
}
static getEntityTypeLabel(entity) {
const documentName = entity?.documentName
const type = entity?.type
if (documentName === 'Actor' || documentName === 'Item') {
const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
return game.i18n.has(label) ? game.i18n.localize(label) : t;
}
return type;
}
}

56
module/rdd-confirm.js Normal file
View File

@ -0,0 +1,56 @@
import { Grammar } from "./grammar.js";
import { ReglesOptionelles } from "./regles-optionelles.js";
export class RdDConfirm {
/* -------------------------------------------- */
static confirmer(options, autresActions) {
options.bypass = options.bypass || !(options.settingConfirmer == undefined || ReglesOptionelles.isUsing(options.settingConfirmer));
if (options.bypass) {
options.onAction();
}
else {
let buttons = {
"action": RdDConfirm._createButtonAction(options),
"cancel": RdDConfirm._createButtonCancel()
};
if (options.settingConfirmer) {
buttons = mergeObject(RdDConfirm._createButtonActionSave(options), buttons);
}
if (autresActions) {
buttons = mergeObject(autresActions, buttons);
}
const dialogDetails = {
title: options.title,
content: options.content,
default: "cancel",
buttons: buttons
};
new Dialog(dialogDetails, { width: 150 * Object.keys(buttons).length }).render(true);
}
}
static _createButtonCancel() {
return { icon: '<i class="fas fa-times"></i>', label: "Annuler" };
}
static _createButtonAction(options) {
return {
icon: '<i class="fas fa-check"></i>',
label: options.buttonLabel,
callback: () => options.onAction()
};
}
static _createButtonActionSave(options) {
return {
"actionSave": {
icon: '<i class="fas fa-user-check"></i>',
label: "Toujours "+ options.buttonLabel.toLowerCase(),
callback: () => {
ReglesOptionelles.set(options.settingConfirmer, false);
options.onAction();
}
}
};
}
}

View File

@ -132,18 +132,15 @@ export class RdDDice {
}
}
static async roll(formula, options = { showDice: SHOW_DICE, rollMode: undefined }) {
const roll = new Roll(formula);
await roll.evaluate({ async: true });
if (options.showDice != HIDE_DICE) {
await this.showDiceSoNice(roll, options.rollMode ?? game.settings.get("core", "rollMode"));
}
return roll;
static async rollTotal(formula, options = { showDice: HIDE_DICE }) {
return (await RdDDice.roll(formula, options)).total;
}
static async rollTotal(formula, options = { showDice: HIDE_DICE}) {
const roll = await RdDDice.roll(formula, options);
return roll.total;
static async roll(formula, options = { showDice: SHOW_DICE, rollMode: undefined }) {
const roll = new Roll(RdDDice._formulaOrFake(formula, options));
await roll.evaluate({ async: true });
await this.showDiceSoNice(roll, options);
return roll;
}
static async rollOneOf(array) {
@ -160,27 +157,106 @@ export class RdDDice {
}
/* -------------------------------------------- */
static async showDiceSoNice(roll, rollMode) {
if (game.modules.get("dice-so-nice")?.active) {
if (game.dice3d) {
let whisper = null;
let blind = false;
rollMode = 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;
}
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
static async showDiceSoNice(roll, options) {
if (options.showDice == HIDE_DICE || !game.modules.get("dice-so-nice")?.active || !game.dice3d) {
return;
}
let { whisper, blind } = RdDDice._getWhisperBlind(options);
if (options.forceDiceResult?.total) {
let terms = await RdDDice._getForcedTerms(options);
if (terms) {
await game.dice3d.show({ throws: [{ dice: terms }] })
return;
}
}
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
}
static _formulaOrFake(formula, options) {
if (options?.forceDiceResult?.total) {
options.forceDiceResult.formula = formula;
return options.forceDiceResult.total.toString()
}
return formula;
}
static async _getForcedTerms(options) {
const total = options.forceDiceResult.total;
switch (options.forceDiceResult.formula) {
case '1d100':
return terms1d100(total);
case "2d10":
return await terms2d10(total);
}
return undefined;
function terms1d100(total) {
const unites = total % 10;
const dizaines = Math.floor(total / 10);
return [{
resultLabel: dizaines * 10,
d100Result: total,
result: dizaines,
type: "d100",
vectors: [],
options: {}
},
{
resultLabel: unites,
d100Result: total,
result: unites,
type: "d10",
vectors: [],
options: {}
}];
}
async function terms2d10(total) {
if (total>20 || total<2) { return undefined }
let first = await RdDDice.d10();
let second = Math.min(total-first, 10);
first = Math.max(first, total-second);
return [{
resultLabel:first,
result: first,
type: "d10",
vectors: [],
options: {}
},
{
resultLabel: second,
result: second,
type: "d10",
vectors: [],
options: {}
}];
}
}
static async d10() {
let roll = new Roll('1d10');
await roll.evaluate({ async: true });
return roll.total;
}
static _getWhisperBlind(options) {
let whisper = null;
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

@ -18,18 +18,19 @@ const tableGemmes = {
export class RdDGemme extends Item {
static getGemmeTypeOptionList() {
// TODO: look how to map object key-value pairs
let options = ""
for (let gemmeKey in tableGemmes) {
let gemmeData = tableGemmes[gemmeKey];
options += `<option value="${gemmeKey}">${gemmeData.label}</option>`
options += `<option value="${gemmeKey}">${tableGemmes[gemmeKey].label}</option>`
}
return options;
}
static calculDataDerivees(data) {
data.cout = (data.taille * data.purete) + data.qualite;
data.inertie = 7 - data.purete;
data.enchantabilite = data.taille - data.inertie;
static calculDataDerivees(gemme) {
gemme.system.cout = (gemme.system.taille * gemme.system.purete) + gemme.system.qualite;
gemme.system.inertie = 7 - gemme.system.purete;
gemme.system.enchantabilite = gemme.system.taille - gemme.system.inertie;
}
}

View File

@ -1,76 +1,75 @@
/* -------------------------------------------- */
import { RdDUtility } from "./rdd-utility.js";
import { Misc } from "./misc.js";
import { RdDCalendrier } from "./rdd-calendrier.js";
import { Grammar } from "./grammar.js";
/* -------------------------------------------- */
export class RdDHerbes extends Item {
/* -------------------------------------------- */
static isHerbeSoin( botaniqueItem ) {
return botaniqueItem.categorie == 'Soin';
static async initializeHerbes() {
this.herbesSoins = await RdDHerbes.listCategorieHerbes('Soin');
this.herbesRepos = await RdDHerbes.listCategorieHerbes('Repos');
}
/* -------------------------------------------- */
static isHerbeRepos( botaniqueItem ) {
return botaniqueItem.categorie == 'Repos';
static async listCategorieHerbes(categorie) {
return await RdDUtility.loadItems(
it => it.type == 'herbe' && it.system.categorie.toLowerCase() == categorie.toLowerCase(),
'foundryvtt-reve-de-dragon.botanique');
}
/* -------------------------------------------- */
static async initializeHerbes( ) {
this.herbesSoins = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeSoin(item));
this.herbesRepos = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeRepos(item));
}
/* -------------------------------------------- */
static buildHerbesList(listHerbes, max) {
static buildHerbesList(listeHerbes, max) {
let list = {}
for ( let herbe of listHerbes) {
let herbeData = herbe.system
let brins = max - herbeData.niveau;
list[herbe.data.name] = `${herbe.data.name} (Bonus: ${herbeData.niveau}, Brins: ${brins})`;
for (let herbe of listeHerbes) {
let brins = max - herbe.system.niveau;
list[herbe.name] = `${herbe.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`;
}
list['Autre'] = 'Autre (Bonus: variable, Brins: variable)'
return list;
}
/* -------------------------------------------- */
static updatePotionData( formData ) {
formData.herbesSoins = this.buildHerbesList(this.herbesSoins, 12);
formData.herbesRepos = this.buildHerbesList(this.herbesRepos, 7);
static async updatePotionData(formData) {
formData.isSoins = formData.system.categorie.includes('Soin');
formData.isRepos = formData.system.categorie.includes('Repos');
if (formData.isSoins) {
RdDHerbes.calculBonusHerbe(formData, this.herbesSoins, 12);
}
if (formData.isRepos) {
RdDHerbes.calculBonusHerbe(formData, this.herbesRepos, 7);
}
formData.herbesSoins = RdDHerbes.buildHerbesList(this.herbesSoins, 12);
formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7);
formData.jourMoisOptions = RdDCalendrier.buildJoursMois();
formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex();
formData.splitDate = game.system.rdd.calendrier.getNumericDateFromIndex(formData.data.prdate);
if (formData.data.categorie.includes('Soin') ) {
formData.isHerbe = true;
this.computeHerbeBonus(formData, this.herbesSoins, 12);
} else if (formData.data.categorie.includes('Repos')) {
formData.isRepos = true;
this.computeHerbeBonus(formData, this.herbesRepos, 7);
}
formData.splitDate = game.system.rdd.calendrier.getNumericDateFromIndex(formData.system.prdate);
}
/* -------------------------------------------- */
static calculePointsRepos( data ) {
return data.herbebonus * data.pr;
static calculPuissancePotion(potion) {
return potion.system.herbebonus * potion.system.pr;
}
/* -------------------------------------------- */
static calculePointsGuerison( data ){
return data.herbebonus * data.pr;
static calculPointsRepos(potion) {
return potion.system.herbebonus * potion.system.pr;
}
/* -------------------------------------------- */
static computeHerbeBonus( formData, herbesList, max) {
if ( Number(formData.data.herbebrins) ) {
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.data.herbe.toLowerCase() );
if( herbe ) {
let herbeData = herbe.system;
let brinsBase = max - herbeData.niveau;
//console.log(herbeData, brinsBase, formData.data.herbebrins);
formData.data.herbebonus = Math.max(herbeData.niveau - Math.max(brinsBase - formData.data.herbebrins, 0), 0);
static calculPointsGuerison(potion) {
return potion.system.herbebonus * potion.system.pr;
}
/* -------------------------------------------- */
static calculBonusHerbe(formData, herbesList, max) {
if (Number(formData.system.herbebrins)) {
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase());
if (herbe) {
const brinsRequis = max - herbe.system.niveau;
const brinsManquants = Math.max(brinsRequis - formData.system.herbebrins, 0);
formData.system.herbebonus = Math.max(herbe.system.niveau - brinsManquants, 0);
}
}
}
}
}

View File

@ -2,64 +2,46 @@ import { Misc } from "./misc.js";
export class RdDHotbar {
static async addToHotbar(item, slot) {
let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}");`;
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: item.name,
type: "script",
img: item.img,
command: command
}, { displaySheet: false })
}
await game.user.assignHotbarMacro(macro, slot);
}
/**
* Create a macro when dropping an entity on the hotbar
* Item - open roll dialog for item
* Actor - open actor sheet
* Journal - open journal sheet
*/
static initDropbar( ) {
static initDropbar() {
Hooks.on("hotbarDrop", async (bar, documentData, slot) => {
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
if (documentData.type == "Item") {
if (documentData.data.type != "arme" && documentData.data.type != "competence" )
return
let item = documentData.data
let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}");`;
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: item.name,
type: "script",
img: item.img,
command: command
}, { displaySheet: false })
Hooks.on("hotbarDrop", (bar, documentData, slot) => {
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
if (documentData.type == "Item") {
let item = fromUuidSync(documentData.uuid)
if (item == undefined) {
item = this.actor.items.get(documentData.uuid)
}
console.log("DROP", documentData, item)
if (!item || (item.type != "arme" && item.type != "competence")) {
return true
}
this.addToHotbar(item, slot)
return false
}
game.user.assignHotbarMacro(macro, slot);
}
// Create a macro to open the actor sheet of the actor dropped on the hotbar
else if (documentData.type == "Actor") {
let actor = game.actors.get(documentData.id);
let command = `game.actors.get("${documentData.id}").sheet.render(true)`
let macro = game.macros.contents.find(m => (m.name === actor.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: actor.data.name,
type: "script",
img: actor.data.img,
command: command
}, { displaySheet: false })
game.user.assignHotbarMacro(macro, slot);
}
}
// Create a macro to open the journal sheet of the journal dropped on the hotbar
else if (documentData.type == "JournalEntry") {
let journal = game.journal.get(documentData.id);
let command = `game.journal.get("${documentData.id}").sheet.render(true)`
let macro = game.macros.contents.find(m => (m.name === journal.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: journal.data.name,
type: "script",
img: "systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp",
command: command
}, { displaySheet: false })
game.user.assignHotbarMacro(macro, slot);
}
}
return false;
});
return true
})
}
/** Roll macro */
@ -69,15 +51,17 @@ export class RdDHotbar {
if (speaker.token) actor = game.actors.tokens[speaker.token];
if (!actor) actor = game.actors.get(speaker.actor);
let item = Misc.data(actor?.items.find(it => it.name === itemName && it.type == itemType));
if (!item) return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`);
let item = actor?.items.find(it => it.name === itemName && it.type == itemType) ?? undefined;
if (!item) {
return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`);
}
// Trigger the item roll
switch (item.type) {
case "arme":
return actor.rollArme(item);
case "competence":
return actor.rollCompetence( itemName );
return actor.rollCompetence(itemName);
}
}

View File

@ -35,6 +35,7 @@ import { RdDDice } from "./rdd-dice.js";
import { RdDPossession } from "./rdd-possession.js";
import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js";
import { Misc } from "./misc.js";
import { Migrations } from './migrations.js';
/* -------------------------------------------- */
/* Foundry VTT Initialization */
@ -149,11 +150,14 @@ Hooks.once("init", async function () {
/* -------------------------------------------- */
game.socket.on(SYSTEM_SOCKET_ID, sockmsg => {
console.log(">>>>> MSG RECV", sockmsg);
RdDUtility.onSocketMessage(sockmsg);
RdDCombat.onSocketMessage(sockmsg);
ChatUtility.onSocketMessage(sockmsg);
RdDActor.onSocketMessage(sockmsg);
try {
RdDUtility.onSocketMessage(sockmsg);
RdDCombat.onSocketMessage(sockmsg);
ChatUtility.onSocketMessage(sockmsg);
RdDActor.onSocketMessage(sockmsg);
} catch(e) {
console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg,' => ', e)
}
});
/* -------------------------------------------- */
@ -183,7 +187,7 @@ Hooks.once("init", async function () {
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
types: ["arme", "armure", "objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",
"tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique", "gemme",
"musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession"], makeDefault: true
"musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession", "sortreserve"], makeDefault: true
});
CONFIG.Combat.documentClass = RdDCombatManager;
@ -245,6 +249,9 @@ function registerUsageCount( registerKey ) {
/* -------------------------------------------- */
Hooks.once("ready", async function () {
await migrationPngWebp_1_5_34()
if (Misc.isUniqueConnectedGM()) {
new Migrations().migrate();
}
StatusEffects.onReady();
RdDHerbes.initializeHerbes();
@ -292,8 +299,8 @@ async function migrationPngWebp_1_5_34() {
await Item.updateDocuments(itemsUpdates);
await Actor.updateDocuments(actorsUpdates);
game.actors.forEach(actor => {
if (actor.data.token?.img && actor.data.token.img.match(regexOldPngJpg)) {
actor.update({ "token.img": convertImgToWebp(actor.data.token.img) });
if (actor.token?.img && actor.token.img.match(regexOldPngJpg)) {
actor.update({ "token.img": convertImgToWebp(actor.token.img) });
}
const actorItemsToUpdate = prepareDocumentsImgUpdate(actor.items);
actor.updateEmbeddedDocuments('Item', actorItemsToUpdate);

View File

@ -84,7 +84,7 @@ export class RdDPossession {
attacker: attacker,
defender: defender,
competence: defender.getDraconicOuPossession(),
selectedCarac: defender.system.data.carac.reve,
selectedCarac: defender.system.carac.reve,
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: defender.getReveActuel() } }
}
rollData.competence.system.defaut_carac = 'reve-actuel'
@ -159,7 +159,7 @@ export class RdDPossession {
let possessionData = {
name: "Possession en cours de " + attacker.name, type: 'possession',
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
data: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
system: { description: "", typepossession: attacker.name, possede: false, possessionid: randomID(16), possesseurid: attacker.id, possedeid: defender.id, date: 0, compteur: 0 }
}
// Creates only the possession on the personnage side
let poss = await defender.createEmbeddedDocuments('Item', [possessionData])

View File

@ -142,10 +142,8 @@ export class RdDResolutionTable {
/* -------------------------------------------- */
static async rollChances(chances, diviseur, forceDiceResult = -1) {
if (forceDiceResult <= 0 || forceDiceResult > 100) {
forceDiceResult = -1;
}
chances.roll = await RdDDice.rollTotal((forceDiceResult == -1) ? "1d100" : `${forceDiceResult}`, chances);
chances.forceDiceResult = forceDiceResult <= 0 || forceDiceResult > 100 ? undefined : {total: forceDiceResult};
chances.roll = await RdDDice.rollTotal( "1d100", chances);
mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
return chances;
}
@ -166,7 +164,7 @@ export class RdDResolutionTable {
if (rollData.selectedCarac?.label.toLowerCase().includes('chance')) {
return true;
}
if (rollData.selectedSort?.data.isrituel) {
if (rollData.selectedSort?.system.isrituel) {
return true;
}
return false;

View File

@ -1,4 +1,4 @@
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "./constants.js";
import { ENTITE_BLURETTE, ENTITE_INCARNE} from "./constants.js";
/**
* Extend the base Dialog entity by defining a custom window to perform roll.
@ -33,7 +33,7 @@ export class RdDEncaisser extends Dialog {
let dialogOptions = {
classes: ["rdddialog"],
width: 320,
height: 240
height: 260
}
// Select proper roll dialog template and stuff
@ -51,6 +51,7 @@ export class RdDEncaisser extends Dialog {
this.actor.encaisserDommages({
dmg: {
total: Number(this.modifier),
ajustement: Number(this.modifier),
encaisserSpecial: this.encaisserSpecial,
loc: { result: 0, label: "" },
mortalite: mortalite

View File

@ -144,6 +144,7 @@ export class RdDRoll extends Dialog {
/* -------------------------------------------- */
async onAction(action, html) {
this.rollData.forceDiceResult = Number.parseInt($('#force-dice-result').val()) ?? -1;
await RdDResolutionTable.rollData(this.rollData);
console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
this.actor.setRollWindowsOpened(false);
@ -165,8 +166,8 @@ export class RdDRoll extends Dialog {
function onLoad() {
let rollData = dialog.rollData;
console.log(rollData);
// Update html, according to data
console.log('Ouverture RdDRoll', rollData);
// Update html, according to rollData
if (rollData.competence) {
const defaut_carac = rollData.competence.system.defaut_carac
// Set the default carac from the competence item
@ -221,7 +222,7 @@ export class RdDRoll extends Dialog {
});
html.find('#ptreve-variable').change((event) => {
let ptreve = Misc.toInt(event.currentTarget.value);
this.rollData.selectedSort.data.ptreve_reel = ptreve;
this.rollData.selectedSort.system.ptreve_reel = ptreve;
console.log("RdDRollSelectDialog - Cout reve", ptreve);
this.updateRollResult();
});
@ -294,7 +295,7 @@ export class RdDRoll extends Dialog {
async setSelectedSigneDraconique(signe){
this.rollData.signe = signe;
this.rollData.diffLibre = Misc.data(signe).data.difficulte,
this.rollData.diffLibre = signe.system.difficulte,
$(".signe-difficulte").text(Misc.toSignedString(this.rollData.diffLibre));
}
@ -348,10 +349,10 @@ export class RdDRoll extends Dialog {
/* -------------------------------------------- */
_computeDiffCompetence(rollData) {
if (rollData.competence) {
return Misc.toInt(rollData.competence.data.niveau);
return Misc.toInt(rollData.competence.system.niveau);
}
if (rollData.draconicList) {
return Misc.toInt(rollData.competence.data.niveau);
return Misc.toInt(rollData.competence.system.niveau);
}
return 0;
}

View File

@ -2,16 +2,22 @@ export class RdDRollTables {
/* -------------------------------------------- */
static async genericGetTableResult(tableName, toChat) {
let table = game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase())
if ( !table) {
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
const index = await pack.getIndex();
const entry = index.find(e => e.name === tableName);
table = await pack.getDocument(entry._id);
}
let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName));
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
//console.log("RdDRollTables", tableName, toChat, ":", draw);
return draw.results.length > 0 ? draw.results[0] : undefined;
}
static getWorldTable(tableName) {
return game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase());
}
static async getSystemTable(tableName) {
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
const index = await pack.getIndex();
const entry = index.find(e => e.name === tableName);
return await pack.getDocument(entry._id);
}
/* -------------------------------------------- */
@ -25,7 +31,7 @@ export class RdDRollTables {
/* -------------------------------------------- */
static async drawTextFromRollTable(tableName, toChat) {
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
return drawResult.system.text;
return drawResult.text;
}
/* -------------------------------------------- */

View File

@ -1,5 +1,4 @@
import { DialogSplitItem } from "./dialog-split-item.js";
import { Misc } from "./misc.js";
export class RdDSheetUtility {
@ -21,17 +20,14 @@ export class RdDSheetUtility {
}
static prepareItemDropParameters(destItemId, actorId, dragData, objetVersConteneur) {
console.log("ID", dragData)
const item = fromUuidSync(dragData.uuid)
let itemId = item.id
//const itemId = dragData.id || dragData.data._id
return {
destId: destItemId,
targetActorId: actorId,
itemId: itemId,
sourceActorId: dragData.actorId,
srcId: objetVersConteneur[itemId],
onEnleverConteneur: () => { delete objetVersConteneur[itemId]; },
itemId: item.id,
sourceActorId: item.actor?.id,
srcId: objetVersConteneur[item.id],
onEnleverConteneur: () => { delete objetVersConteneur[item.id]; },
onAjouterDansConteneur: (itemId, conteneurId) => { objetVersConteneur[itemId] = conteneurId; }
}
}
@ -47,10 +43,10 @@ export class RdDSheetUtility {
static async _onSplitItem(item, split, actor) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split);
const itemData = duplicate(item);
const splitItem = duplicate(item);
// todo: ajouter dans le même conteneur?
itemData.system.quantite = split;
await actor.createEmbeddedDocuments('Item', [itemData])
splitItem.system.quantite = split;
await actor.createEmbeddedDocuments('Item', [splitItem])
}
}
}

View File

@ -1,4 +1,3 @@
import { SYSTEM_SOCKET_ID } from "./constants.js";
import { RollDataAjustements } from "./rolldata-ajustements.js";
import { RdDUtility } from "./rdd-utility.js";
import { TMRUtility } from "./tmr-utility.js";
@ -16,6 +15,7 @@ import { Misc } from "./misc.js";
import { HtmlUtility } from "./html-utility.js";
import { ReglesOptionelles } from "./regles-optionelles.js";
import { RdDDice } from "./rdd-dice.js";
import { STATUSES } from "./status-effects.js";
/* -------------------------------------------- */
export class RdDTMRDialog extends Dialog {
@ -55,7 +55,6 @@ export class RdDTMRDialog extends Dialog {
this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue();
this.cumulFatigue = 0;
this.loadRencontres();
this.loadSortsReserve();
this.loadCasesSpeciales();
this.allTokens = [];
this.rencontreState = 'aucune';
@ -81,9 +80,16 @@ export class RdDTMRDialog extends Dialog {
this.casesSpeciales = this.actor.items.filter(item => Draconique.isCaseTMR(item));
}
/* -------------------------------------------- */
loadSortsReserve() {
this.sortsReserves = this.actor.system.reve.reserve.list;
get sortsReserve() {
return this.actor.itemTypes['sortreserve'];
}
getSortsReserve(coord) {
return this.actor.itemTypes['sortreserve'].filter(// Reserve sur une case fleuve ou normale
TMRUtility.getTMR(coord).type == 'fleuve'
? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve'
: it => it.system.coord == coord
);
}
/* -------------------------------------------- */
@ -97,10 +103,10 @@ export class RdDTMRDialog extends Dialog {
this.updateTokens();
this.forceDemiRevePositionView();
}
/* -------------------------------------------- */
_createTokens() {
if (!this.isDemiReveCache()){
if (!this.isDemiReveCache()) {
this.demiReve = this._tokenDemiReve();
this._trackToken(this.demiReve);
}
@ -117,7 +123,6 @@ export class RdDTMRDialog extends Dialog {
updateTokens() {
this._removeTokens(t => true);
this.loadRencontres();
this.loadSortsReserve();
this.loadCasesSpeciales();
this._createTokens();
}
@ -136,7 +141,7 @@ export class RdDTMRDialog extends Dialog {
return this.rencontresExistantes.map(it => this._tokenRencontre(it));
}
_getTokensSortsReserve() {
return this.sortsReserves.map(it => this._tokenSortEnReserve(it));
return this.actor.itemTypes['sortreserve'].map(it => this._tokenSortEnReserve(it));
}
/* -------------------------------------------- */
@ -148,12 +153,12 @@ export class RdDTMRDialog extends Dialog {
const draconique = Draconique.get(caseData.system.specific);
return draconique?.token(this.pixiTMR, caseData, () => caseData.system.coord);
}
_tokenSortEnReserve(sortEnReserve) {
return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortEnReserve.sort, () => sortEnReserve.coord);
_tokenSortEnReserve(sortReserve) {
return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortReserve, () => sortReserve.system.coord);
}
_tokenDemiReve() {
return EffetsDraconiques.demiReve.token(this.pixiTMR, this.actor.system, () => this.actor.system.reve.tmrpos.coord);
return EffetsDraconiques.demiReve.token(this.pixiTMR, this.actor, () => this.actor.system.reve.tmrpos.coord);
}
forceDemiRevePositionView() {
@ -209,24 +214,12 @@ export class RdDTMRDialog extends Dialog {
this.actor.rollLireSigneDraconique(this._getActorCoord());
});
html.find('#dir-top').click((event) => {
this.moveFromKey("top");
});
html.find('#dir-top-left').click((event) => {
this.moveFromKey("top-left");
});
html.find('#dir-top-right').click((event) => {
this.moveFromKey("top-right");
});
html.find('#dir-bottom-left').click((event) => {
this.moveFromKey("bottom-left");
});
html.find('#dir-bottom-right').click((event) => {
this.moveFromKey("bottom-right");
});
html.find('#dir-bottom').click((event) => {
this.moveFromKey("bottom");
});
html.find('#dir-top').click((event) => this.moveFromKey("top"));
html.find('#dir-top-left').click((event) => this.moveFromKey("top-left"));
html.find('#dir-top-right').click((event) => this.moveFromKey("top-right"));
html.find('#dir-bottom-left').click((event) => this.moveFromKey("bottom-left"));
html.find('#dir-bottom-right').click((event) => this.moveFromKey("bottom-right"));
html.find('#dir-bottom').click((event) => this.moveFromKey("bottom"));
// Gestion du cout de montée en points de rêve
let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
@ -238,13 +231,14 @@ export class RdDTMRDialog extends Dialog {
// Le reste...
this.updateValuesDisplay();
let tmr = TMRUtility.getTMR(this._getActorCoord());
await this.manageRencontre(tmr, () => {
this.postRencontre(tmr);
});
await this.manageRencontre(tmr);
}
/* -------------------------------------------- */
async updateValuesDisplay() {
if (!this.rendered) {
return;
}
const coord = this._getActorCoord();
HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(coord));
@ -254,9 +248,9 @@ export class RdDTMRDialog extends Dialog {
let tmrpos = document.getElementById("tmr-pos");
if (this.isDemiReveCache()) {
tmrpos.innerHTML = '?? (' + TMRUtility.getTMRType(coord) + ')';
tmrpos.innerHTML = `?? ( ${ TMRUtility.getTMRType(coord)})`;
} else {
tmrpos.innerHTML = coord + " (" + TMRUtility.getTMRLabel(coord) + ")";
tmrpos.innerHTML = `${coord} ( ${TMRUtility.getTMRLabel(coord)})`;
}
let etat = document.getElementById("tmr-etatgeneral-value");
@ -267,21 +261,22 @@ export class RdDTMRDialog extends Dialog {
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
let fatigueItem = document.getElementById("tmr-fatigue-table");
//console.log("Refresh : ", actorData.data.sante.fatigue.value);
fatigueItem.innerHTML = "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(this.actor.system.sante.fatigue.value, this.actor.system.sante.endurance.max).html() + "</table>";
}
}
/* -------------------------------------------- */
close() {
if ( this.actor.tmrApp ) {
async close() {
this.descenteTMR = true;
if (this.actor.tmrApp) {
this.actor.tmrApp = undefined; // Cleanup reference
if ( !this.viewOnly ) {
this.actor.setStatusEffect("EFFECT.StatusDemiReve", false);
if (!this.viewOnly) {
await this.actor.setEffect(STATUSES.StatusDemiReve, false)
this._tellToGM(this.actor.name + " a quitté les terres médianes");
}
this.actor.santeIncDec("fatigue", this.cumulFatigue).then(super.close()); // moving 1 cell costs 1 fatigue
await this.actor.santeIncDec("fatigue", this.cumulFatigue)
}
await super.close(); // moving 1 cell costs 1 fatigue
}
/* -------------------------------------------- */
@ -317,11 +312,11 @@ export class RdDTMRDialog extends Dialog {
this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
for (let coordTMR of listCoordTMR) {
let rect = this._getCaseRectangleCoord(coordTMR);
var rectDraw = new PIXI.Graphics();
rectDraw.beginFill(0xFFFF00, 0.3);
const rect = this._getCaseRectangleCoord(coordTMR);
const rectDraw = new PIXI.Graphics();
rectDraw.beginFill(0xffff00, 0.3);
// set the line style to have a width of 5 and set the color to red
rectDraw.lineStyle(5, 0xFF0000);
rectDraw.lineStyle(5, 0xff0000);
// draw a rectangle
rectDraw.drawRect(rect.x, rect.y, rect.w, rect.h);
this.pixiApp.stage.addChild(rectDraw);
@ -337,19 +332,13 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async choisirCasePortee(coord, portee) {
if (this.actor.isTMRCache())
{
return;
}
// Récupère la liste des cases à portées
let locList = TMRUtility.getTMRPortee(coord, portee);
this.colorierZoneRencontre(locList);
this.colorierZoneRencontre(TMRUtility.getTMRPortee(coord, portee));
}
/* -------------------------------------------- */
async choisirCaseType(type) {
const locList = TMRUtility.filterTMR(it => it.type == type).map(it => it.coord);
this.colorierZoneRencontre(locList);
this.colorierZoneRencontre(TMRUtility.filterTMR(it => it.type == type).map(it => it.coord));
}
/* -------------------------------------------- */
@ -484,12 +473,13 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async manageRencontre(tmr, postRencontre) {
async manageRencontre(tmr) {
if (this.viewOnly) {
return;
}
this.descenteTMR = false;
this.currentRencontre = undefined;
if (this._presentCite(tmr, postRencontre)) {
if (this._presentCite(tmr)) {
return;
}
let rencontre = await this._jetDeRencontre(tmr);
@ -499,27 +489,27 @@ export class RdDTMRDialog extends Dialog {
console.log("manageRencontre", rencontre);
this.currentRencontre = duplicate(rencontre);
let dialog = new RdDTMRRencontreDialog("", this, this.currentRencontre, postRencontre);
let dialog = new RdDTMRRencontreDialog(this, this.currentRencontre, () => this.postRencontre(tmr));
dialog.render(true);
}
else {
postRencontre();
this.postRencontre(tmr);
}
}
/* -------------------------------------------- */
_presentCite(tmr, postRencontre) {
_presentCite(tmr) {
const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord));
if (presentCite) {
this.minimize();
const caseData = presentCite;
EffetsDraconiques.presentCites.choisirUnPresent(caseData, (type => this._utiliserPresentCite(presentCite, type, tmr, postRencontre)));
EffetsDraconiques.presentCites.choisirUnPresent(caseData, (type => this._utiliserPresentCite(presentCite, type, tmr)));
}
return presentCite;
}
/* -------------------------------------------- */
async _utiliserPresentCite(presentCite, typeRencontre, tmr, postRencontre) {
async _utiliserPresentCite(presentCite, typeRencontre, tmr) {
this.currentRencontre = TMRRencontres.getRencontre(typeRencontre);
await TMRRencontres.evaluerForceRencontre(this.currentRencontre);
await EffetsDraconiques.presentCites.ouvrirLePresent(this.actor, presentCite);
@ -538,7 +528,7 @@ export class RdDTMRDialog extends Dialog {
await this._tentativeMaitrise(rencontreData);
this.maximize();
postRencontre();
this.postRencontre(tmr);
}
/* -------------------------------------------- */
@ -574,6 +564,9 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async manageTmrInnaccessible(tmr) {
if (!tmr) {
return await this.actor.reinsertionAleatoire('Sortie de carte');
}
const caseTmrInnaccessible = this.casesSpeciales.find(c => EffetsDraconiques.isInnaccessible(c, tmr.coord));
if (caseTmrInnaccessible) {
return await this.actor.reinsertionAleatoire(caseTmrInnaccessible.name);
@ -606,7 +599,6 @@ export class RdDTMRDialog extends Dialog {
async _resultatMaitriseCaseHumide(rollData) {
await this.souffleSiEchecTotal(rollData);
this.toclose = rollData.rolled.isEchec;
if (rollData.rolled.isSuccess && rollData.double) {
rollData.previous = { rolled: rollData.rolled, ajustements: rollData.ajustements };
rollData.double = undefined;
@ -619,7 +611,7 @@ export class RdDTMRDialog extends Dialog {
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
});
if (rollData.rolled.isEchec) {
this.close();
await this.close();
}
}
@ -633,16 +625,16 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
isCaseHumide(tmr) {
if (!(TMRUtility.isCaseHumide(tmr) || this.isCaseHumideAdditionelle(tmr))) {
return undefined;
return false;
}
if (this.isCaseMaitrisee(tmr.coord)) {
ChatMessage.create({
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)
});
return undefined;
return false;
}
return -7;
return true;
}
/* -------------------------------------------- */
@ -729,8 +721,6 @@ export class RdDTMRDialog extends Dialog {
if (rollData.rolled.isETotal) {
rollData.souffle = await this.actor.ajouterSouffle({ chat: false });
}
this.toclose = rollData.rolled.isEchec;
rollData.poesie = await Poetique.getExtrait();
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
@ -775,9 +765,8 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async declencheSortEnReserve(coord) {
let sortsEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord);
if (sortsEnCoord.length > 0) {
let sorts = this.getSortsReserve(coord);
if (sorts.length > 0) {
if (EffetsDraconiques.isSortReserveImpossible(this.actor)) {
ui.notifications.error("Une queue ou un souffle vous empèche de déclencher de sort!");
return;
@ -785,8 +774,8 @@ export class RdDTMRDialog extends Dialog {
if (!EffetsDraconiques.isUrgenceDraconique(this.actor) &&
(EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coord))) {
let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>";
for (let sortReserve of sortsEnCoord) {
msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='" + this.actor._id + "' data-tmr-coord='" + coord + "' data-sort-id='" + sortReserve.sort._id + "'>" + sortReserve.sort.name + "</a></li>";
for (let sort of sorts) {
msg += `<li><a class="chat-card-button declencher-sort-reserve" data-actor-id="${this.actor.id}" data-tmr-coord="${coord}" data-sort-id='${sort.id}">${sort.name}</a></li>`;
}
msg += "</ol>";
ChatMessage.create({
@ -795,33 +784,35 @@ export class RdDTMRDialog extends Dialog {
});
return;
}
await this.processSortReserve(sortsEnCoord[0]);
await this.processSortReserve(sorts[0]);
}
}
/* -------------------------------------------- */
lancerSortEnReserve(coord, sortId) {
let sortEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord);
let sortReserve = sortEnCoord.find(sortReserve => sortReserve.sort._id == sortId);
if (sortReserve) {
this.processSortReserve(sortReserve);
let sorts = this.getSortsReserve(coord);
let sort = sorts.find(it => it.id == sortId);
if (sort) {
this.processSortReserve(sort);
} else {
ChatMessage.create({
content: "Une erreur est survenue : impossible de récupérer le sort en réserve demandé.",
whisper: ChatMessage.getWhisperRecipients(game.user.name)
content:
"Une erreur est survenue : impossible de récupérer le sort en réserve demandé.",
whisper: ChatMessage.getWhisperRecipients(game.user.name),
});
}
}
/* -------------------------------------------- */
async processSortReserve(sortReserve) {
await this.actor.deleteSortReserve(sortReserve);
//this.updateSortReserve();
console.log("declencheSortEnReserve", sortReserve)
this._tellToUserAndGM(`Vous avez déclenché le sort en réserve <strong> ${sortReserve.sort.name}</strong>
avec ${sortReserve.sort.system.ptreve_reel} points de Rêve
en ${sortReserve.coord} (${TMRUtility.getTMRLabel(sortReserve.coord)})
`);
await this.actor.deleteEmbeddedDocuments('Item', [sortReserve.id]);
console.log("declencheSortEnReserve", sortReserve);
this._tellToUserAndGM(`Vous avez déclenché
${sortReserve.system.echectotal ? "<strong>l'échec total!</strong>" : "le sort"}
en réserve <strong>${sortReserve.name}</strong>
avec ${sortReserve.system.ptreve} points de Rêve
en ${sortReserve.system.coord} (${TMRUtility.getTMRLabel(sortReserve.system.coord)}).
L'heure ciblée est ${sortReserve.system.heurecible}`);
this.close();
}
@ -873,7 +864,6 @@ export class RdDTMRDialog extends Dialog {
if (this.viewOnly) {
return;
}
let clickOddq = RdDTMRDialog._computeEventOddq(event.data.originalEvent);
await this._onClickTMRPos(clickOddq); // Vérifier l'état des compteurs reve/fatigue/vie
}
@ -888,11 +878,13 @@ export class RdDTMRDialog extends Dialog {
if (this.isDemiReveCache()) {
if (this.isTerreAttache(targetCoord)
|| (this.isCaseHumide(currentCoord) && this.isCaseHumide(targetCoord))
|| this.isConnaissanceFleuve(currentCoord, targetCoord)
|| deplacementType == 'changeur')
{
// déplacement possible
await this.actor.montreTMR();
await this.actor.setTMRVisible(true);
this.demiReve = this._tokenDemiReve();
this._trackToken(this.demiReve);
}
else
{
@ -928,7 +920,7 @@ export class RdDTMRDialog extends Dialog {
const isInArea = this.rencontreState == 'aucune'
? (this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || TMRUtility.distanceOddq(fromOddq, toOddq) <= 1)
: this.currentRencontre?.locList.find(coord => coord == targetCoord) ?? false
: this.currentRencontre?.locList?.find(coord => coord == targetCoord) ?? false
if (isInArea) {
switch (this.rencontreState) {
case 'aucune': return 'normal';
@ -977,7 +969,7 @@ export class RdDTMRDialog extends Dialog {
this.actor.notifyRefreshTMR();
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
await this.manageRencontre(tmr, () => this.postRencontre(tmr));
await this.manageRencontre(tmr);
}
else {
await this.postRencontre(tmr);
@ -996,13 +988,14 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async postRencontre(tmr) {
if (!(this.viewOnly || this.currentRencontre)) {
await this.manageCaseHumide(tmr);
await this.conquerirCiteFermee(tmr);
await this.purifierPeriple(tmr);
await this.conquerirTMR(tmr);
await this.validerVisite(tmr);
await this.declencheSortEnReserve(tmr.coord);
await this.actor.checkSoufflePeage(tmr);
// TODO: vérifier que la méthode s'arrête en cas de non-maîtrise
if (!this.descenteTMR) await this.manageCaseHumide(tmr);
if (!this.descenteTMR) await this.conquerirCiteFermee(tmr);
if (!this.descenteTMR) await this.purifierPeriple(tmr);
if (!this.descenteTMR) await this.conquerirTMR(tmr);
if (!this.descenteTMR) await this.validerVisite(tmr);
if (!this.descenteTMR) await this.declencheSortEnReserve(tmr.coord);
if (!this.descenteTMR) await this.actor.checkSoufflePeage(tmr);
}
}
@ -1021,7 +1014,7 @@ export class RdDTMRDialog extends Dialog {
let x = origEvent.clientX - canvasRect.left;
let y = origEvent.clientY - canvasRect.top;
let col = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
y -= (col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
y -= col % 2 == 0 ? tmrConstants.col1_y : tmrConstants.col2_y;
let row = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14]
return { col: col, row: row };
}
@ -1031,7 +1024,7 @@ export class RdDTMRDialog extends Dialog {
_getCaseRectangleCoord(coord) {
return this.pixiTMR.getCaseRectangle(TMRUtility.coordTMRToOddq(coord));
}
/* -------------------------------------------- */
_removeTokens(filter) {
const tokensToRemove = this.allTokens.filter(filter);
@ -1039,7 +1032,7 @@ export class RdDTMRDialog extends Dialog {
this.pixiApp.stage.removeChild(token.sprite);
}
}
/* -------------------------------------------- */
_trackToken(token) {
if (this.demiReve === token && this.isDemiReveCache()) {

View File

@ -2,7 +2,7 @@
export class RdDTMRRencontreDialog extends Dialog {
/* -------------------------------------------- */
constructor(html, tmrApp, rencontre, postRencontre) {
constructor(tmrApp, rencontre, postRencontre) {
const dialogConf = {
title: "Rencontre en TMR!",
content: "Vous rencontrez un " + rencontre.name + " de force " + rencontre.force + "<br>",

View File

@ -8,7 +8,7 @@ export class RdDTokenHud {
static init() {
// Integration du TokenHUD
Hooks.on('renderTokenHUD', (app, html, data) => { RdDTokenHud.addTokenHudExtensions(app, html, data._id) });
Hooks.on('renderTokenHUD', (app, html, token) => { RdDTokenHud.addTokenHudExtensions(app, html, token._id) });
}
/* -------------------------------------------- */
@ -63,7 +63,7 @@ export class RdDTokenHud {
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
const action = actionsCombat[actionIndex];
if (action.action == 'conjurer') {
actor.conjurerPossession(actor.getPossession(action.data.possessionid));
actor.conjurerPossession(actor.getPossession(action.system.possessionid));
}
else {
actor.rollArme(action);
@ -76,7 +76,7 @@ export class RdDTokenHud {
case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01);
case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01);
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
{ name: "Autre action", action: 'autre', data: { initOnly: true, competence: "Autre action" } });
{ name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
}
}

View File

@ -12,6 +12,8 @@ import { RdDItem } from "./item.js";
import { Monnaie } from "./item-monnaie.js";
import { RdDPossession } from "./rdd-possession.js";
import { RdDNameGen } from "./rdd-namegen.js";
import { RdDConfirm } from "./rdd-confirm.js";
import { RdDActor } from "./actor.js";
/* -------------------------------------------- */
// This table starts at 0 -> niveau -10
@ -104,7 +106,7 @@ export class RdDUtility {
/* -------------------------------------------- */
static async init() {
Hooks.on("renderChatMessage", async (app, html, msg) => RdDUtility.onRenderChatMessage(app, html, msg));
Hooks.on('renderChatLog', (log, html, data) => RdDUtility.chatListeners(html));
Hooks.on('renderChatLog', (log, html, chatLog) => RdDUtility.chatListeners(html));
}
/* -------------------------------------------- */
@ -115,21 +117,58 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-effects-partial.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html',
// Conteneur/item in Actor sheet
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-item.html',
"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-monnaie.html",
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-animaux.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-suivants.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-vehicules.html',
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html',
// sous-parties de feuilles de personnages
'systems/foundryvtt-reve-de-dragon/templates/actor/header-buttons.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-entitee.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/competence.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/combat.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/jeux.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-signes-draconiques.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-rencontres.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts-reserve.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-meditations.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/hr-casestmr.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html',
"systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html",
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
//Items
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-arme-sheet.html',
@ -175,6 +214,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html',
@ -203,6 +243,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html',
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html',
@ -238,8 +279,9 @@ export class RdDUtility {
Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
Handlebars.registerHelper('typeTmr-name', coord => TMRUtility.typeTmrName(coord));
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));
Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.visible)
Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.system.isVisible)
.sort((a, b) => {
if (a.name.startsWith("Survie") && b.name.startsWith("Survie")) {
if (a.name.includes("Cité")) return -1;
@ -248,7 +290,7 @@ export class RdDUtility {
if (b.name.includes("Extérieur")) return 1;
return a.name.localeCompare(b.name);
}
if (a.data.categorie.startsWith("melee") && b.data.categorie.startsWith("melee")) {
if (a.system.categorie.startsWith("melee") && b.system.categorie.startsWith("melee")) {
if (a.name.includes("Corps")) return -1;
if (b.name.includes("Corps")) return 1;
if (a.name.includes("Dague")) return -1;
@ -283,7 +325,7 @@ export class RdDUtility {
/* -------------------------------------------- */
static async selectObjetType(actorSheet) {
let typeObjets = RdDItem.getTypeObjetsEquipement();
let typeObjets = RdDItem.getTypesObjetsEquipement();
let options = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
for (let typeName of typeObjets) {
options += `<option value="${typeName}">${typeName}</option>`
@ -365,48 +407,50 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static filterItemsPerTypeForSheet(formData) {
static filterItemsPerTypeForSheet(formData, itemTypes) {
RdDUtility.filterEquipementParType(formData);
RdDUtility.filterEquipementParType(formData, itemTypes);
formData.sorts = this.arrayOrEmpty(formData.itemsByType['sort']);
formData.signesdraconiques = this.arrayOrEmpty(formData.itemsByType['signedraconique']);
formData.queues = this.arrayOrEmpty(formData.itemsByType['queue']);
formData.souffles = this.arrayOrEmpty(formData.itemsByType['souffle']);
formData.ombres = this.arrayOrEmpty(formData.itemsByType['ombre']);
formData.tetes = this.arrayOrEmpty(formData.itemsByType['tete']);
formData.taches = this.arrayOrEmpty(formData.itemsByType['tache']);
formData.meditations = this.arrayOrEmpty(formData.itemsByType['meditation']);
formData.chants = this.arrayOrEmpty(formData.itemsByType['chant']);
formData.danses = this.arrayOrEmpty(formData.itemsByType['danse']);
formData.musiques = this.arrayOrEmpty(formData.itemsByType['musique']);
formData.oeuvres = this.arrayOrEmpty(formData.itemsByType['oeuvre']);
formData.jeux = this.arrayOrEmpty(formData.itemsByType['jeu']);
formData.sorts = this.arrayOrEmpty(itemTypes['sort']);
formData.casestmr = this.arrayOrEmpty(itemTypes['casetmr']);
formData.signesdraconiques = this.arrayOrEmpty(itemTypes['signedraconique']);
formData.queues = this.arrayOrEmpty(itemTypes['queue']);
formData.souffles = this.arrayOrEmpty(itemTypes['souffle']);
formData.ombres = this.arrayOrEmpty(itemTypes['ombre']);
formData.tetes = this.arrayOrEmpty(itemTypes['tete']);
formData.taches = this.arrayOrEmpty(itemTypes['tache']);
formData.meditations = this.arrayOrEmpty(itemTypes['meditation']);
formData.chants = this.arrayOrEmpty(itemTypes['chant']);
formData.danses = this.arrayOrEmpty(itemTypes['danse']);
formData.musiques = this.arrayOrEmpty(itemTypes['musique']);
formData.oeuvres = this.arrayOrEmpty(itemTypes['oeuvre']);
formData.jeux = this.arrayOrEmpty(itemTypes['jeu']);
formData.recettescuisine = this.arrayOrEmpty(formData.itemsByType['recettecuisine']);
formData.recettesAlchimiques = this.arrayOrEmpty(formData.itemsByType['recettealchimique']);
formData.maladies = this.arrayOrEmpty(formData.itemsByType['maladie']);
formData.poisons = this.arrayOrEmpty(formData.itemsByType['poison']);
formData.possessions = this.arrayOrEmpty(formData.itemsByType['possession']);
formData.recettescuisine = this.arrayOrEmpty(itemTypes['recettecuisine']);
formData.recettesAlchimiques = this.arrayOrEmpty(itemTypes['recettealchimique']);
formData.maladies = this.arrayOrEmpty(itemTypes['maladie']);
formData.poisons = this.arrayOrEmpty(itemTypes['poison']);
formData.possessions = this.arrayOrEmpty(itemTypes['possession']);
formData.maladiesPoisons = formData.maladies.concat(formData.poisons);
formData.competences = (formData.itemsByType.competence ?? []).concat(formData.itemsByType.competencecreature ?? []);
formData.competences = (itemTypes['competence'] ?? []).concat(itemTypes['competencecreature'] ?? []);
formData.sortsReserve = this.arrayOrEmpty(itemTypes['sortreserve']);
}
static filterEquipementParType(formData) {
formData.conteneurs = this.arrayOrEmpty(formData.itemsByType['conteneur']);
static filterEquipementParType(formData, itemTypes) {
formData.conteneurs = this.arrayOrEmpty(itemTypes['conteneur']);
formData.materiel = this.arrayOrEmpty(formData.itemsByType['objet']);
formData.armes = this.arrayOrEmpty(formData.itemsByType['arme']);
formData.armures = this.arrayOrEmpty(formData.itemsByType['armure']);
formData.munitions = this.arrayOrEmpty(formData.itemsByType['munition']);
formData.livres = this.arrayOrEmpty(formData.itemsByType['livre']);
formData.potions = this.arrayOrEmpty(formData.itemsByType['potion']);
formData.ingredients = this.arrayOrEmpty(formData.itemsByType['ingredient']);
formData.herbes = this.arrayOrEmpty(formData.itemsByType['herbe']);
formData.monnaie = this.arrayOrEmpty(formData.itemsByType['monnaie']);
formData.materiel = this.arrayOrEmpty(itemTypes['objet']);
formData.armes = this.arrayOrEmpty(itemTypes['arme']);
formData.armures = this.arrayOrEmpty(itemTypes['armure']);
formData.munitions = this.arrayOrEmpty(itemTypes['munition']);
formData.livres = this.arrayOrEmpty(itemTypes['livre']);
formData.potions = this.arrayOrEmpty(itemTypes['potion']);
formData.ingredients = this.arrayOrEmpty(itemTypes['ingredient']);
formData.herbes = this.arrayOrEmpty(itemTypes['herbe']);
formData.monnaie = this.arrayOrEmpty(itemTypes['monnaie']);
formData.monnaie.sort(Monnaie.triValeurDenier());
formData.nourritureboissons = this.arrayOrEmpty(formData.itemsByType['nourritureboisson']);
formData.gemmes = this.arrayOrEmpty(formData.itemsByType['gemme']);
formData.nourritureboissons = this.arrayOrEmpty(itemTypes['nourritureboisson']);
formData.gemmes = this.arrayOrEmpty(itemTypes['gemme']);
formData.objets = formData.conteneurs
.concat(formData.materiel)
@ -445,16 +489,16 @@ export class RdDUtility {
/* -------------------------------------------- */
static calculEncContenu(conteneur, objets) {
const contenuDatas = (conteneur.system.contenu ?? []).filter(id => id != undefined)
.map(id => objets.find(it => (id == it._id)))
const contenus = (conteneur.system.contenu ?? []).filter(id => id != undefined)
.map(id => objets.find(it => (id == it.id)))
.filter(it => it);
let enc = Number(conteneur.system.encombrement ?? 0) * Number(conteneur.system.quantite ?? 1);
for (let itemData of contenuDatas) {
if (itemData.type == 'conteneur') {
enc += RdDUtility.calculEncContenu(itemData, objets);
for (let contenu of contenus) {
if (contenu.type == 'conteneur') {
enc += RdDUtility.calculEncContenu(contenu, objets);
}
else {
enc += Number(itemData.system.encombrement ?? 0) * Number(itemData.system.quantite ?? 1)
enc += Number(contenu.system.encombrement ?? 0) * Number(contenu.system.quantite ?? 1)
}
}
return enc
@ -475,8 +519,8 @@ export class RdDUtility {
objet.niveau = profondeur;
const isConteneur = objet.type == 'conteneur';
const isOuvert = isConteneur && this.getAfficheContenu(objet._id);
const isVide = isConteneur && Misc.templateData(objet).contenu.length == 0;
const conteneur = Handlebars.partials['systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-item.html']({
const isVide = isConteneur && objet.system.contenu.length == 0;
const conteneur = Handlebars.partials['systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html']({
item: objet,
vide: isVide,
ouvert: isOuvert
@ -610,7 +654,68 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static selectEncaissement(degats, mortalite) {
static async jetEncaissement(rollData, armure, options = { showDice: HIDE_DICE }) {
let formula = "2d10";
// Chaque dé fait au minmum la difficulté libre
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre')) {
if (rollData.diffLibre < 0) {
let valeurMin = Math.abs(rollData.diffLibre);
formula += "min" + valeurMin;
}
}
// Chaque dé fait au minmum la difficulté libre
if (ReglesOptionelles.isUsing('degat-ajout-malus-libre')) {
if (rollData.diffLibre < 0) {
let valeurMin = Math.abs(rollData.diffLibre);
formula += "+" + valeurMin;
}
}
let roll = await RdDDice.roll(formula, options);
// 1 dé fait au minmum la difficulté libre
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre-simple')) {
if (rollData.diffLibre < 0) {
let valeurMin = Math.abs(rollData.diffLibre);
if (roll.terms[0].results[0].result < valeurMin) {
roll.terms[0].results[0].result = valeurMin;
} else if (roll.terms[0].results[1].result < valeurMin) {
roll.terms[0].results[1].result = valeurMin;
}
roll._total = roll.terms[0].results[0].result + roll.terms[0].results[1].result;
}
}
return await RdDUtility.prepareEncaissement(rollData, roll, armure);
}
/* -------------------------------------------- */
static async prepareEncaissement(rollData, roll, armure) {
const jetTotal = roll.total + rollData.dmg.total - armure;
let encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
let over20 = Math.max(jetTotal - 20, 0);
encaissement.dmg = rollData.dmg;
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type);
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;';
encaissement.roll = roll;
encaissement.armure = armure;
encaissement.total = jetTotal;
encaissement.vie = await RdDUtility._evaluatePerte(encaissement.vie, over20);
encaissement.endurance = await RdDUtility._evaluatePerte(encaissement.endurance, over20);
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
encaissement.blessures = (
encaissement.critiques> 0 ? "Critique":
encaissement.graves> 0 ? "Grave":
encaissement.legeres> 0 ? "Légère":
encaissement.eraflures>0 ? "Contusions/Eraflures":
'Aucune'
);
return encaissement;
}
/* -------------------------------------------- */
static _selectEncaissement(degats, mortalite) {
const table = definitionsEncaissement[mortalite] === undefined ? definitionsEncaissement["mortel"] : definitionsEncaissement[mortalite];
for (let encaissement of table) {
if ((encaissement.minimum === undefined || encaissement.minimum <= degats)
@ -621,6 +726,13 @@ export class RdDUtility {
return duplicate(table[0]);
}
/* -------------------------------------------- */
static async _evaluatePerte(formula, over20) {
let perte = new Roll(formula, { over20: over20 });
await perte.evaluate({ async: true });
return perte.total;
}
/* -------------------------------------------- */
static currentFatigueMalus(value, max) {
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
@ -640,6 +752,23 @@ export class RdDUtility {
return 0;
}
/* -------------------------------------------- */
static async loadItems(filter, compendium) {
let items = game.items.filter(filter);
if (compendium) {
const ids = items.map(it => it.id);
const names = items.map(it => it.name.toLowerCase());
items = items.concat(await RdDUtility.loadCompendium(compendium, it => !ids.includes(it.id) && !names.includes(it.name.toLowerCase()) && filter(it)));
}
return items;
}
/* -------------------------------------------- */
static async loadCompendium(compendium, filter = it => true) {
let compendiumData = await RdDUtility.loadCompendiumData(compendium);
return compendiumData.filter(filter);
}
/* -------------------------------------------- */
static async loadCompendiumData(compendium) {
const pack = game.packs.get(compendium);
@ -647,15 +776,9 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static async loadCompendium(compendium, filter = item => true) {
let compendiumData = await RdDUtility.loadCompendiumData(compendium);
return compendiumData.filter(filter);
}
/* -------------------------------------------- */
static async responseNombreAstral(data) {
let actor = game.actors.get(data.id);
actor.ajouteNombreAstral(data);
static async responseNombreAstral(callData) {
let actor = game.actors.get(callData.id);
actor.ajouteNombreAstral(callData);
}
/* -------------------------------------------- */
@ -690,12 +813,13 @@ export class RdDUtility {
actor.tmrApp.positionnerDemiReve(coord);
});
// Gestion spécifique des sorts en réserve multiples (ie têtes)
html.on("click", '#sort-reserve', event => {
html.on("click", '.declencher-sort-reserve', event => {
let coord = event.currentTarget.attributes['data-tmr-coord'].value;
let sortId = event.currentTarget.attributes['data-sort-id'].value;
let actorId = event.currentTarget.attributes['data-actor-id'].value;
let actor = game.actors.get(actorId);
actor.tmrApp.lancerSortEnReserve(coord, sortId);
// TODO: supprimer le message?
});
// gestion bouton tchat Possession
@ -707,7 +831,12 @@ export class RdDUtility {
});
// gestion bouton tchat Acheter
html.on("click", '.button-acheter', event => DialogItemAchat.onButtonAcheter(event));
html.on("click", '.button-acheter', event => {
const venteData = DialogItemAchat.venteData(event.currentTarget);
if (venteData) {
DialogItemAchat.onAcheter(venteData);
}
});
html.on("click", '.button-creer-acteur', event => RdDNameGen.onCreerActeur(event));
// Gestion du bouton payer
@ -753,7 +882,7 @@ export class RdDUtility {
static getSelectedActor(msgPlayer = undefined) {
if (canvas.tokens.controlled.length == 1) {
let token = canvas.tokens.controlled[0];
if (token.actor && token.data.actorLink) {
if (token.actor) {
return token.actor;
}
if (msgPlayer != undefined) {
@ -776,7 +905,7 @@ export class RdDUtility {
static createMonnaie(name, valeur_deniers, img = "", enc = 0.01) {
let piece = {
name: name, type: 'monnaie', img: img, _id: randomID(16),
data: {
dasystemta: {
quantite: 0,
valeur_deniers: valeur_deniers,
encombrement: enc,
@ -828,80 +957,57 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static confirmerSuppressionSubacteur(actorSheet, li) {
let actorId = li.data("actor-id");
let actor = game.actors.get(actorId);
let msgTxt = "<p>Etes vous certain de vouloir supprimer le lien vers ce véhicule/monture/suivant : " + actor.data.name + " ?</p>";
let d = new Dialog({
title: "Confirmer la suppression du lien",
content: msgTxt,
buttons: {
delete: {
icon: '<i class="fas fa-check"></i>',
label: "Supprimer le lien",
callback: () => {
console.log("Delete : ", actorId);
actorSheet.actor.removeSubacteur(actorId);
li.slideUp(200, () => actorSheet.render(false));
}
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: "Annuler"
}
},
default: "cancel"
});
d.render(true);
static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete) {
RdDConfirm.confirmer({
settingConfirmer: "confirmation-supprimer-lien-acteur",
content: `<p>Etes vous certain de vouloir supprimer le lien vers ${subActor.name} ?</p>`,
title: 'Confirmer la suppression',
buttonLabel: 'Supprimer le lien',
onAction: () => {
console.log('Delete : ', subActor.id);
sheet.actor.removeSubacteur(subActor.id);
RdDUtility.slideOnDelete(sheet, htmlToDelete);
}
})
}
/* -------------------------------------------- */
static async confirmerSuppression(actorSheet, li) {
let itemId = li.data("item-id");
let objet = actorSheet.actor.getObjet(itemId);
if (objet.type == 'monnaie' && Monnaie.isSystemMonnaie(objet)) {
ui.notifications.warn("Suppression des monnaies de base impossible");
return;
}
let msgTxt = "<p>Etes vous certain de vouloir supprimer cet objet ?";
let buttons = {
delete: {
icon: '<i class="fas fa-check"></i>',
label: "Supprimer l'objet",
callback: () => {
console.log("Delete : ", itemId);
actorSheet.actor.deleteEmbeddedDocuments('Item', [itemId]);
li.slideUp(200, () => actorSheet.render(false));
}
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: "Annuler"
static async confirmerSuppressionItem(sheet, item, htmlToDelete) {
const itemId = item.id;
const confirmationSuppression = {
settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(),
content: `<p>Etes vous certain de vouloir supprimer: ${item.name}?</p>`,
title: `Supprimer ${item.name}`,
buttonLabel: "Supprimer",
onAction: () => {
console.log('Delete : ', itemId);
sheet.actor.deleteEmbeddedDocuments('Item', [itemId], { renderSheet: false });
RdDUtility.slideOnDelete(sheet, htmlToDelete);
}
};
if (item.isConteneurNonVide()) {
confirmationSuppression.content += `<p>Ce conteneur n'est pas vide. Que voulez vous supprimer?</p>`;
confirmationSuppression.settingConfirmer = undefined;
RdDConfirm.confirmer(confirmationSuppression,
{
'deleteall': {
icon: '<i class="fas fa-check"></i>',
label: "Supprimer conteneur et contenu",
callback: () => {
console.log("Delete : ", itemId);
sheet.actor.deleteAllConteneur(itemId, { renderSheet: false });
RdDUtility.slideOnDelete(sheet, htmlToDelete);
}
}
});
}
const docData = objet
if (docData.type == 'conteneur' && docData.data.contenu.length > 0) {
msgTxt += "<br>Ce conteneur n'est pas vide. Choisissez l'option de suppression";
buttons['deleteall'] = {
icon: '<i class="fas fa-check"></i>',
label: "Supprimer le conteneur et tout son contenu",
callback: () => {
console.log("Delete : ", itemId);
actorSheet.actor.deleteAllConteneur(itemId);
li.slideUp(200, () => actorSheet.render(false));
}
}
else {
RdDConfirm.confirmer(confirmationSuppression)
}
msgTxt += "</p>";
let d = new Dialog({
title: "Confirmer la suppression",
content: msgTxt,
buttons: buttons,
default: "cancel"
});
d.render(true);
}
static slideOnDelete(sheet, htmlToDelete) {
return htmlToDelete.slideUp(200, () => sheet.render(false));
}
/* -------------------------------------------- */

View File

@ -2,27 +2,42 @@ import { SYSTEM_RDD } from "./constants.js";
import { Misc } from "./misc.js";
const listeReglesOptionelles = [
{ name: 'recul', group: 'Règles de combat', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
{ name: 'resistanceArmeParade', group: 'Règles de combat', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
{ name: 'deteriorationArmure', group: 'Règles de combat', descr: "Tenir compte de la détérioration des armures" },
{ name: 'defenseurDesarme', group: 'Règles de combat', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
{ name: 'categorieParade', group: 'Règles de combat', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
{ name: 'tripleSignificative', group: 'Règles de combat', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
{ name: 'degat-minimum-malus-libre-simple', group: 'Règles de combat', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si 1 résultat est inférieur à 4, alors il devient 4.", default: false },
{ name: 'degat-minimum-malus-libre', group: 'Règles de combat', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
{ name: 'degat-ajout-malus-libre', group: 'Règles de combat', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
{ name: 'astrologie', group: 'Règles générales', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels", default: true },
{ name: 'afficher-prix-joueurs', group: 'Règles générales', descr: "Afficher le prix de l'équipement des joueurs", default: true },
{ name: 'appliquer-fatigue', group: 'Règles générales', descr: "Appliquer les règles de fatigue", default: true },
{ name: 'afficher-colonnes-reussite', group: 'Règles générales', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
{ group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
{ group: 'Règles de combat', name: 'resistanceArmeParade', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
{ group: 'Règles de combat', name: 'deteriorationArmure', descr: "Tenir compte de la détérioration des armures" },
{ group: 'Règles de combat', name: 'defenseurDesarme', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
{ group: 'Règles de combat', name: 'categorieParade', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
{ group: 'Règles de combat', name: 'tripleSignificative', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre-simple', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si le plus petit dé est inférieur à 4, alors il devient 4.", default: false },
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
{ group: 'Règles de combat', name: 'degat-ajout-malus-libre', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
{ group: 'Règles de combat', name: 'validation-encaissement-gr', descr: "Le Gardien des Rêves doit valider les jets d'encaissement et peut les changer.", default: false },
{ group: 'Règles générales', name: 'astrologie', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels"},
{ group: 'Règles générales', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
{ group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
{ group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-equipement', descr: "Confirmer la suppression des équipements", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-connaissance', descr: "Confirmer la suppression des connaissances", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-draconique', descr: "Confirmer la suppression des queues, souffles, têtes", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-effet', descr: "Confirmer la suppression des effets", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-competence', descr: "Confirmer la suppression des compétences", scope: "client"},
{ group: 'Confirmations', name: 'confirmation-supprimer-autres', descr: "Confirmer la suppression des autres types d'Objets", scope: "client"},
];
const uniquementJoueur = listeReglesOptionelles.filter(it => it.uniquementJoueur).map(it=>it.name);
export class ReglesOptionelles extends FormApplication {
static init() {
for (const regle of listeReglesOptionelles) {
const name = regle.name;
const id = ReglesOptionelles._getIdRegle(name);
game.settings.register(SYSTEM_RDD, id, { name: id, scope: "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean });
game.settings.register(SYSTEM_RDD, id, { name: id, scope: regle.scope ?? "world", config: false, default: regle.default == undefined ? true : regle.default, type: Boolean });
}
game.settings.registerMenu(SYSTEM_RDD, "rdd-options-regles", {
@ -30,8 +45,7 @@ export class ReglesOptionelles extends FormApplication {
label: "Choix des règles optionelles",
hint: "Ouvre la fenêtre de sélection des règles optionelles",
icon: "fas fa-bars",
type: ReglesOptionelles,
restricted: true
type: ReglesOptionelles
});
}
@ -49,7 +63,7 @@ export class ReglesOptionelles extends FormApplication {
id: "optional-settings",
template: "systems/foundryvtt-reve-de-dragon/templates/regles-optionelles.html",
height: 600,
width: 350,
width: 450,
minimizable: false,
closeOnSubmit: true,
title: "Règles optionnelles"
@ -59,10 +73,10 @@ export class ReglesOptionelles extends FormApplication {
getData() {
let formData = super.getData();
const regles = listeReglesOptionelles.map(it => {
const regles = listeReglesOptionelles.filter(it => game.user.isGM || it.scope == "client").map(it => {
it = duplicate(it);
it.id = ReglesOptionelles._getIdRegle(it.name);
it.active = ReglesOptionelles.isUsing(it.name);
it.active = ReglesOptionelles.isSet(it.name);
return it;
});
formData.regles = regles;
@ -71,9 +85,20 @@ export class ReglesOptionelles extends FormApplication {
}
static isUsing(name) {
if (game.user.isGM && uniquementJoueur.includes(name)) {
return true;
}
return ReglesOptionelles.isSet(name);
}
static isSet(name) {
return game.settings.get(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name));
}
static set(name, value) {
return game.settings.set(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name), value ? true: false);
}
activateListeners(html) {
html.find(".select-option").click((event) => {
if (event.currentTarget.attributes.name) {

View File

@ -33,7 +33,7 @@ export const referenceAjustements = {
getLabel: (rollData, actor) => rollData.selectedSort?.name ?? rollData.attackerRoll ? 'Imposée' : 'Libre',
getValue: (rollData, actor) => rollData.selectedSort
? RdDItemSort.getDifficulte(rollData.selectedSort, rollData.diffLibre)
: rollData.diffLibre ?? rollData.competence?.data.default_diffLibre ?? 0
: rollData.diffLibre ?? rollData.competence?.system.default_diffLibre ?? 0
},
diffConditions: {
isUsed: (rollData, actor) => rollData.diffConditions != undefined,

View File

@ -1,26 +1,41 @@
import { SYSTEM_RDD } from "./constants.js";
const rddStatusEffects = [
{ rdd: true, id: 'stun', label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 },
{ rdd: true, id: 'bleeding', label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' },
{ rdd: true, id: 'prone', label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' },
{ rdd: true, id: 'grappling', tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
{ rdd: true, id: 'grappled', tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
{ rdd: true, id: 'restrain', label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' },
{ rdd: true, id: 'unconscious', label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' },
{ rdd: true, id: 'blind', label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' },
{ rdd: true, id: 'comma', label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' },
{ rdd: true, id: 'dead', label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' },
{ rdd: true, id: 'demi-reve', label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' }
];
const demiReveStatusEffect = rddStatusEffects.find(it => it.label == 'EFFECT.StatusDemiReve');
export const STATUSES = {
StatusStunned : 'stun',
StatusBleeding: 'bleeding',
StatusProne: 'prone',
StatusGrappling: 'grappling',
StatusGrappled: 'grappled',
StatusRestrained: 'restrain',
StatusUnconscious: 'unconscious',
StatusBlind: 'blind',
StatusComma: 'comma',
StatusDead: 'dead',
StatusDemiReve: 'demi-reve',
}
const statusDemiSurprise = new Set(['EFFECT.StatusStunned', 'EFFECT.StatusProne', 'EFFECT.StatusRestrain']);
const statusSurpriseTotale = new Set(['EFFECT.StatusUnconscious', 'EFFECT.StatusBlind', 'EFFECT.StatusComma']);
const rddStatusEffects = [
{ rdd: true, id: STATUSES.StatusStunned, label: 'EFFECT.StatusStunned', icon: 'icons/svg/stoned.svg', "duration.rounds": 1 },
{ rdd: true, id: STATUSES.StatusBleeding, label: 'EFFECT.StatusBleeding', icon: 'icons/svg/blood.svg' },
{ rdd: true, id: STATUSES.StatusProne, label: 'EFFECT.StatusProne', icon: 'icons/svg/falling.svg' },
{ rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', label: 'EFFECT.StatusGrappling', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
{ rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', label: 'EFFECT.StatusGrappled', icon: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp' },
{ rdd: true, id: STATUSES.StatusRestrained, label: 'EFFECT.StatusRestrained', icon: 'icons/svg/net.svg' },
{ rdd: true, id: STATUSES.StatusUnconscious, label: 'EFFECT.StatusUnconscious', icon: 'icons/svg/unconscious.svg' },
{ rdd: true, id: STATUSES.StatusBlind, label: 'EFFECT.StatusBlind', icon: 'icons/svg/blind.svg' },
{ rdd: true, id: STATUSES.StatusComma, label: 'EFFECT.StatusComma', icon: 'icons/svg/skull.svg' },
{ rdd: true, id: STATUSES.StatusDead, label: 'EFFECT.StatusDead', icon: 'icons/svg/skull.svg' },
{ rdd: true, id: STATUSES.StatusDemiReve, label: 'EFFECT.StatusDemiReve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' }
];
const demiReveStatusEffect = rddStatusEffects.find(it => it.id == STATUSES.StatusDemiReve);
const statusDemiSurprise = [STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained];
const statusSurpriseTotale = [STATUSES.StatusUnconscious, STATUSES.StatusBlind, STATUSES.StatusComma];
export class StatusEffects {
static onReady() {
const rddStatusIds = rddStatusEffects.map(it => it.id);
rddStatusEffects.forEach(it => it.flags = { core: { statusId: it.id } });
const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id);
game.settings.register(SYSTEM_RDD, "use-status-effects", {
name: "use-status-effects",
@ -47,40 +62,36 @@ export class StatusEffects {
static valeurSurprise(effect, isCombat) {
// const id = StatusEffects.statusId(effect);
if (statusSurpriseTotale.has(effect.label)) {
if (statusSurpriseTotale.includes(effect.flags?.core?.statusId)) {
return 2;
}
return statusDemiSurprise.has(effect.label) || (isCombat && effect.label == demiReveStatusEffect.label) ? 1 : 0;
}
static setMandatoryRdd() {
CONFIG.statusEffects.filter(it => statusDemiSurprise.has(it.id) || statusSurpriseTotale.has(it.id))
.forEach(it => it.rdd = true);
return statusDemiSurprise.includes(effect.flags?.core?.statusId) || (isCombat && effect.flags?.core?.statusId == STATUSES.StatusDemiReve) ? 1 : 0;
}
static _getUseStatusEffects() {
const setting = game.settings.get(SYSTEM_RDD, "use-status-effects");
return setting ? new Set(setting.split(',')) : new Set();
return setting ? setting.split(',') : [];
}
static _setUseStatusEffects(useStatusEffects) {
static _setUseStatusEffects(statusIds) {
if (game.user.isGM) {
game.settings.set(SYSTEM_RDD, "use-status-effects", StatusEffects._toSetting(useStatusEffects));
game.settings.set(SYSTEM_RDD, "use-status-effects", StatusEffects._toSetting(statusIds));
}
for (let effect of CONFIG.RDD.allEffects) {
effect.active = effect.rdd || useStatusEffects.has(effect.id);
effect.active = effect.rdd || statusIds.includes(effect.flags?.core?.statusId);
}
CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active);
}
static _toSetting(useStatusEffects) {
return Array.from(useStatusEffects).join();
static _toSetting(statusIds) {
return statusIds.join();
}
static status(label) {
return rddStatusEffects.find(it => it.label == label) ?? { label: label };
static status(statusId) {
return rddStatusEffects.find(it => it.flags?.core?.statusId == statusId);
}
static demiReve() {
return demiReveStatusEffect;
}
@ -106,8 +117,10 @@ class StatusEffectsSettings extends FormApplication {
}
getData() {
const used = StatusEffects._getUseStatusEffects();
let formData = super.getData();
formData.effects = CONFIG.RDD.allEffects;
formData.effects = duplicate(CONFIG.RDD.allEffects);
formData.effects.forEach(it => it.active = used.includes(it.id))
return formData;
}
@ -118,10 +131,10 @@ class StatusEffectsSettings extends FormApplication {
let selected = StatusEffects._getUseStatusEffects();
let isChecked = event.currentTarget.checked;
if (isChecked) {
selected.add(id);
selected.push(id);
}
else {
selected.delete(id);
selected = selected.filter(it => it != id)
}
StatusEffects._setUseStatusEffects(selected);
}

View File

@ -433,9 +433,9 @@ export class TMRRencontres {
/* -------------------------------------------- */
static async msgEchecPasseurFou(tmrData) {
tmrData.sortReserve = tmrData.actor.system.reve.reserve.list[0];
tmrData.sortReserve = RdDDice.rollOneOf(tmrData.actor.itemTypes['sortreserve']);
if (tmrData.sortReserve) {
// Passeur fou positionne sur la case d'un ort en réserve // TODO : Choisir le sort le plus loin ou au hasard
// Passeur fou positionne sur la case d'un sort en réserve
tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord);
} else {
// Déplacement aléatoire de la force du Passeur Fou
@ -468,10 +468,10 @@ export class TMRRencontres {
}
/* -------------------------------------------- */
static async onPostEchecTourbillonRouge(tmrDialog, data) {
await data.actor.reveActuelIncDec(-2); // -2 pts de Reve a chaque itération
TMRRencontres._toubillonner(tmrDialog, data.actor, 4);
await data.actor.santeIncDec("vie", -1); // Et -1 PV
static async onPostEchecTourbillonRouge(tmrDialog, rencontre) {
await rencontre.actor.reveActuelIncDec(-2); // -2 pts de Reve a chaque itération
TMRRencontres._toubillonner(tmrDialog, rencontre.actor, 4);
await rencontre.actor.santeIncDec("vie", -1); // Et -1 PV
}
/* -------------------------------------------- */
@ -486,7 +486,7 @@ export class TMRRencontres {
/* -------------------------------------------- */
static async onPostSuccessReveDeDragon(tmrDialog, tmrData) {
if (tmrData.rolled.isPart) {
await tmrData.actor.appliquerAjoutExperience(tmrData, true);
await tmrData.actor.appliquerAjoutExperience(tmrData);
}
await tmrData.actor.resultCombatReveDeDragon(tmrData);
}

View File

@ -291,12 +291,18 @@ export class TMRUtility {
static typeTmrName(type) {
return Misc.upperFirst(TMRType[Grammar.toLowerCaseNoAccent(type)].name);
}
static listSelectedTMR(typesTMR) {
static buildSelectionTypesTMR(typesTMR) {
typesTMR= typesTMR?? [];
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
.sort()
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
}
static buildListTypesTMRSelection(selectionTMRs) {
return selectionTMRs.filter(it => it.selected).map(it => it.name).join(" ");
}
static isCaseHumide(tmr) {
return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
}
@ -379,18 +385,6 @@ export class TMRUtility {
return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter))
}
/* -------------------------------------------- */
static getSortsReserve(reserveList, coord) {
// TODO : Gérer les têtes spéciales réserve!
let tmrDescr = this.getTMR(coord);
//console.log("Sort réserve : ", tmrDescr);
if (tmrDescr.type == 'fleuve') { // Gestion de la reserve en Fleuve
return reserveList.filter(it => TMRUtility.getTMR(it.coord).type == 'fleuve');
}
// Reserve sur un case "normale"
return reserveList.filter(it => it.coord == coord);
}
/* -------------------------------------------- */
/** Returns a list of case inside a given distance
*

View File

@ -1,5 +1,4 @@
import { Grammar } from "../grammar.js";
import { Misc } from "../misc.js";
import { RdDDice } from "../rdd-dice.js";
import { TMRUtility } from "../tmr-utility.js";
import { tmrConstants, tmrColors, tmrTokenZIndex } from "../tmr-constants.js";

View File

@ -9,11 +9,11 @@ const registeredEffects = [
* Définition des informations d'une "draconique" (queue, ombre, tête, souffle) qui influence les TMR
*/
export class Draconique {
static isCaseTMR(itemData) { return itemData.type == 'casetmr'; }
static isQueueDragon(itemData) { return itemData.type == 'queue' || itemData.type == 'ombre'; }
static isSouffleDragon(itemData) { return itemData.type == 'souffle'; }
static isTeteDragon(itemData) { return itemData.type == 'tete'; }
static isQueueSouffle(itemData) { return Draconique.isQueueDragon(itemData) || Draconique.isSouffleDragon(itemData); }
static isCaseTMR(item) { return item.type == 'casetmr'; }
static isQueueDragon(item) { return item.type == 'queue' || item.type == 'ombre'; }
static isSouffleDragon(item) { return item.type == 'souffle'; }
static isTeteDragon(item) { return item.type == 'tete'; }
static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); }
tmrLabel(linkData) { return TMRUtility.getTMRLabel(linkData.system.coord); }
@ -38,8 +38,7 @@ export class Draconique {
* @returns true si l'item correspond
*/
match(item) {
const itemData = item;
return Draconique.isQueueDragon(itemData) || Draconique.isSouffleDragon(itemData) || Draconique.isTeteDragon(itemData);
return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item) || Draconique.isTeteDragon(item);
}
/**

View File

@ -112,7 +112,7 @@ export class EffetsDraconiques {
}
static filterItems(actor, filter, name) {
return actor.filter(filter)
return actor.filterItems(filter)
.filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
}

View File

@ -25,7 +25,7 @@ export class PixiTMR {
for (const [name, img] of Object.entries(PixiTMR.textures)) {
loader = loader.add(name, img);
}
loader.onLoad.add((error, reason) => { console.log("ERROR", error, reason) });
loader.onError.add((error, reason) => { console.log("ERROR", error, reason) });
loader.load( (loader, resources) => {
onLoad(loader, resources);
for (let onAnimate of this.callbacksOnAnimate) {

View File

@ -12,8 +12,8 @@ export class SortReserve extends Draconique {
manualMessage() { return false }
async onActorCreateOwned(actor, item) { }
code() { return 'sort' }
tooltip(sort) { return `${sort.name}, r${sort.data.ptreve_reel}` }
code() { return 'sortreserve' }
tooltip(sort) { return `${sort.name}, r${sort.system.ptreve}` }
img() { return 'systems/foundryvtt-reve-de-dragon/icons/tmr/scroll.webp' }
createSprite(pixiTMR) {

View File

@ -37,7 +37,7 @@ export class UrgenceDraconique extends Draconique {
}
async onActorDeleteCaseTmr(actor, casetmr) {
await actor.deleteEmbeddedDocuments('Item', [casetmr.data.sourceid]);
await actor.deleteEmbeddedDocuments('Item', [casetmr.system.sourceid]);
}
code() { return 'urgence' }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,27 +1,29 @@
{"_id":"0zRL8bOpCXNQnIR4","name":"Ruade","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":4,"description":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[]}
{"_id":"4GmpkphbsmQjvVVK","name":"Escalade","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_escalade.webp","effects":[]}
{"_id":"6DK46pyO0hzEuuUg","name":"Morsure","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
{"_id":"BjqRrGtHtTzuNpZB","name":"Griffes et Crocs","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[]}
{"_id":"CYpxxf1uTa78NWR9","name":"Esquive","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"dommages":0,"iscombat":false,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp","effects":[]}
{"_id":"JTuBQCPdumw3DfxH","name":"Crête","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"dommages":3,"iscombat":true,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-crete.webp","effects":[]}
{"_id":"Kt7WlB5Ui97X211z","name":"Vol","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"dommages":0,"iscombat":false,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-vol.webp","effects":[]}
{"_id":"LWQHz5ymNBzh6ZEr","name":"Cornes","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-corne.webp","effects":[]}
{"_id":"NctG7suzvGE7ZZzj","name":"Bras-bouches","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"epees-lourdes","isparade":true,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-brasbouche.webp","effects":[]}
{"_id":"OzHBowOMADRwcVXR","name":"Pierre Tenue","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierretenue.webp","effects":[]}
{"_id":"PCwbR6lghjydTj93","name":"Grande morsure","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"","niveau":0,"carac_value":0,"iscombat":true,"isparade":false,"dommages":2,"description":"","default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
{"_id":"PrVuVpwuYaZtwRUi","name":"Piétinement","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":4,"description":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[]}
{"_id":"RAnasKnoA3OQgwfv","name":"Pinces","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":3,"description":"","categorie_parade":"epees-lourdes","isparade":true,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pinces.webp","effects":[]}
{"_id":"XgfRxSj8Ty1d3JFM","name":"Mandibules","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","carac-value":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-mandibules.webp","effects":[]}
{"_id":"Zpl2Bi451vB3r91W","name":"Coup de pied","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":3,"description":null,"categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-coup_de_pied.webp","effects":[]}
{"_id":"efl1HdDSKpBfImQ1","name":"Pierre Lancée","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierrelancee.webp","effects":[]}
{"_id":"h9ASt4vrvEgxfj7j","name":"Tronçonneuse","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":10,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-tronconneuse.webp","effects":[]}
{"_id":"jhua9kkCs55OV7Yl","name":"Grandes griffes","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"sans-armes","niveau":0,"carac_value":0,"iscombat":true,"isparade":true,"dommages":2,"description":"","default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[]}
{"_id":"lzEdMrKXbOYrWG5S","name":"Vigilance","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[]}
{"_id":"ndNshntOYb1JFNqi","name":"Serres","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":2,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-serres.webp","effects":[]}
{"_id":"os88Rsp7mBkahqmh","name":"Bec","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-beak.webp","effects":[]}
{"_id":"qilRzXpVaGceNmQp","name":"Dague","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"dagues","isparade":true,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_dague.webp","effects":[]}
{"_id":"qrd9AoZzFgyzFBxz","name":"Griffes","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"sans-armes","niveau":0,"carac_value":0,"iscombat":true,"isparade":true,"dommages":1,"description":"","default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[]}
{"_id":"sUdXhpuVVOAlcVpo","name":"Pickpocket","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_pickpocket.webp","effects":[]}
{"_id":"shsUV8UpU18c0RJK","name":"Course","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_course.webp","effects":[]}
{"_id":"yBUVTjTXYfwvzusb","name":"Saut","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_saut.webp","effects":[]}
{"_id":"yDHZfK4RmwQW4YaW","name":"Discrétion","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":false,"dommages":0,"description":"","categorie_parade":"","isparade":false,"default_diffLibre":0},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_discretion.webp","effects":[]}
{"_id":"0zRL8bOpCXNQnIR4","name":"Ruade","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.0zRL8bOpCXNQnIR4"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":4,"description":null,"descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"4GmpkphbsmQjvVVK","name":"Escalade","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.4GmpkphbsmQjvVVK"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_escalade.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"6DK46pyO0hzEuuUg","name":"Morsure","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.6DK46pyO0hzEuuUg"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"generale","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"name":"Possession","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.c0I93Q53i4ZmxpyT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp","effects":[],"system":{"categorie_parade":"","niveau":2,"default_diffLibre":0,"carac_value":14,"iscombat":true,"isparade":false,"ispossession":true,"dommages":0,"description":"<p>L'entit&eacute; tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","categorie":"melee"},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624948267,"modifiedTime":1663625011162,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"9u16zxXRurCtxuOX","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
{"_id":"BjqRrGtHtTzuNpZB","name":"Griffes et Crocs","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.BjqRrGtHtTzuNpZB"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011172,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"CYpxxf1uTa78NWR9","name":"Esquive","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.CYpxxf1uTa78NWR9"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702692,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"JTuBQCPdumw3DfxH","name":"Crête","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.JTuBQCPdumw3DfxH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-crete.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":3,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"Kt7WlB5Ui97X211z","name":"Vol","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.Kt7WlB5Ui97X211z"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-vol.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"LWQHz5ymNBzh6ZEr","name":"Cornes","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.LWQHz5ymNBzh6ZEr"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-corne.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"NctG7suzvGE7ZZzj","name":"Bras-bouches","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.NctG7suzvGE7ZZzj"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-brasbouche.webp","effects":[],"system":{"categorie_parade":"epees-lourdes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"OzHBowOMADRwcVXR","name":"Pierre Tenue","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.OzHBowOMADRwcVXR"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierretenue.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"PCwbR6lghjydTj93","name":"Grande morsure","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.PCwbR6lghjydTj93"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"PrVuVpwuYaZtwRUi","name":"Piétinement","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.PrVuVpwuYaZtwRUi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pietinement.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":4,"description":null,"descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702693,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"RAnasKnoA3OQgwfv","name":"Pinces","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.RAnasKnoA3OQgwfv"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pinces.webp","effects":[],"system":{"categorie_parade":"epees-lourdes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":3,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"XgfRxSj8Ty1d3JFM","name":"Mandibules","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.XgfRxSj8Ty1d3JFM"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-mandibules.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","carac-value":null,"categorie":"generale","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"Zpl2Bi451vB3r91W","name":"Coup de pied","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.Zpl2Bi451vB3r91W"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-coup_de_pied.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":3,"description":null,"descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"name":"Possession","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.c0I93Q53i4ZmxpyT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp","effects":[],"system":{"categorie_parade":"","niveau":2,"default_diffLibre":0,"carac_value":14,"iscombat":true,"isparade":false,"ispossession":true,"dommages":0,"description":"<p>L'entit&eacute; tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","categorie":"draconic"},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624976822,"modifiedTime":1663625011162,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"_id":"duVgxI3Cdko0KzAj","folder":null,"sort":0,"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3}}
{"_id":"efl1HdDSKpBfImQ1","name":"Pierre Lancée","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.efl1HdDSKpBfImQ1"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-pierrelancee.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"lancer","isnaturelle":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"h9ASt4vrvEgxfj7j","name":"Tronçonneuse","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.h9ASt4vrvEgxfj7j"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-tronconneuse.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":10,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"jhua9kkCs55OV7Yl","name":"Grandes griffes","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.jhua9kkCs55OV7Yl"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[],"system":{"categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"lzEdMrKXbOYrWG5S","name":"Vigilance","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.lzEdMrKXbOYrWG5S"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"ndNshntOYb1JFNqi","name":"Serres","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.ndNshntOYb1JFNqi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-serres.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":2,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702694,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"os88Rsp7mBkahqmh","name":"Bec","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.os88Rsp7mBkahqmh"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-beak.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"qilRzXpVaGceNmQp","name":"Dague","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.qilRzXpVaGceNmQp"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_dague.webp","effects":[],"system":{"categorie_parade":"dagues","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"qrd9AoZzFgyzFBxz","name":"Griffes","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.qrd9AoZzFgyzFBxz"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[],"system":{"categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":true,"isparade":true,"ispossession":false,"dommages":1,"description":"","descriptionmj":"","categorie":"melee","isnaturelle":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011173,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"sUdXhpuVVOAlcVpo","name":"Pickpocket","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.sUdXhpuVVOAlcVpo"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_pickpocket.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"shsUV8UpU18c0RJK","name":"Course","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.shsUV8UpU18c0RJK"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_course.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"yBUVTjTXYfwvzusb","name":"Saut","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.yBUVTjTXYfwvzusb"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_saut.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":"","categorie":"generale"},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"yDHZfK4RmwQW4YaW","name":"Discrétion","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-creatures.yDHZfK4RmwQW4YaW"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_discretion.webp","effects":[],"system":{"categorie_parade":"","niveau":0,"default_diffLibre":0,"carac_value":0,"iscombat":false,"isparade":false,"ispossession":false,"dommages":0,"description":"","descriptionmj":""},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.16","coreVersion":"10.285","createdTime":1663624702695,"modifiedTime":1663625011174,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}

View File

@ -12,3 +12,4 @@
{"_id":"gPOQd9NI7AFH0whX","name":"Epée Bâtarde","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":4,"description":"","carac-value":null,"categorie_parade":"epees-lourdes","isparade":true},"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-humanoides.YTKld5ggDsHqwYoR"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_epee_1_main.webp","effects":[]}
{"_id":"j1xHCzfIeYKgXxoH","name":"Morsure","permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"type":"competencecreature","data":{"niveau":0,"carac_value":0,"iscombat":true,"dommages":1,"description":"","categorie_parade":"","isparade":false},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
{"_id":"lDZ3qUPKN35ob5TH","name":"Grande morsure","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"competencecreature","data":{"categorie_parade":"","niveau":0,"carac_value":0,"iscombat":true,"isparade":false,"dommages":2,"description":""},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[]}
{"name":"Possession","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.c0I93Q53i4ZmxpyT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp","effects":[],"system":{"categorie_parade":"","niveau":2,"default_diffLibre":-4,"categorie":"melee","carac_value":14,"iscombat":true,"isnaturelle":true,"ispossession":true,"dommages":0,"description":"<p>L'entit&eacute; tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","isparade":false},"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.22","coreVersion":"10.286","createdTime":1663624976822,"modifiedTime":1664918524164,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"wDHR5UHWq568lfGa"}

View File

@ -1,40 +1,40 @@
{"name":"Idée fixe : Anorexie. Ne rien avaler, ni solide, ni liquide, pas même une potion","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"anorexie.webp","effects":[],"_id":"0uc2pMIGL03Hq2Hn"}
{"name":"Désir lancinant : Briser un objet de verre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"briser_verre.webp","effects":[],"_id":"1l59lWbtvYp74OTb"}
{"name":"Idée fixe : Cracher dans toute nourriture ou boisson aperçue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"cracher_nourriture.webp","effects":[],"_id":"22EQLBJfHVYs96iC"}
{"name":"Idée fixe : Éteindre tout feu rencontré (feu de camp, torche, lanterne, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"eteindre_feu.webp","effects":[],"_id":"2Rtm78bMKPy8eG4q"}
{"name":"Désir lancinant : Danser avec un(e) partenaire inconnu(e) (Beauté 13 minimum)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"danser_inconnu.webp","effects":[],"_id":"2i3PndTKG1n3hEUU"}
{"name":"Idée fixe : Traîner son épée en laisse (ou sa meilleure arme)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"trainer_laisse.webp","effects":[],"_id":"2j1q9e07ZLlIQDYl"}
{"name":"Désir lancinant : Gagner de largent (minimum 10 deniers)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"gagner_argent.webp","effects":[],"_id":"3BcC8lSsP5WIyva7"}
{"name":"Désir lancinant : Mégalomanie. Être acclamé par un minimum de 10 personnes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"megalomanie.webp","effects":[],"_id":"3ZjwYyQRatCMnBCi"}
{"name":"Idée fixe : Avoir le visage noirci à la cendre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"avoir_visage.webp","effects":[],"_id":"6G0lF06jSryTduAt"}
{"name":"Idée fixe : Ne marcher quà quatre pattes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"marcher_quatre_pattes.webp","effects":[],"_id":"7TKsit2Mv9mWGq3C"}
{"name":"Désir lancinant : Acquérir une chèvre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"acqu%C3%A9rir_chevre.webp","effects":[],"_id":"8sLXQBqo8XwjAFG0"}
{"name":"Idée fixe : Garder les yeux bandés","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"garder_yeux.webp","effects":[],"_id":"E902EEYZHg3zFKq6"}
{"name":"Désir lancinant : Danser nu sous la pluie","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"danser_pluie.webp","effects":[],"_id":"F6qL4d4g3qjh045R"}
{"name":"Idée fixe : Garder sur soi 3d6 kilos de cailloux","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"garder_cailloux.webp","effects":[],"_id":"F8G3rdU1nfJzYwYR"}
{"name":"Désir lancinant : Se faire raser la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"raser_tete.webp","effects":[],"_id":"HSNOvBR890dsEDw2"}
{"name":"Idée fixe : Aller tout nu, sans porter le moindre paquet ni objet","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"aller_nu.webp","effects":[],"_id":"I0CtQ05xFW6ghcdP"}
{"name":"Idée fixe : Boulimie. Manger au moins un point de sust. par heure","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"boulimie.webp","effects":[],"_id":"JcTX8qMS0z8bmdVt"}
{"name":"Désir lancinant : Passer une nuit sur une échelle","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"nuit_echelle.webp","effects":[],"_id":"LlELEB0FhymLx6VM"}
{"name":"Idée fixe : Refuser de monter dans les TMR","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"refuser_tmr.webp","effects":[],"_id":"NpTDqICR7ZuToQrg"}
{"name":"Désir lancinant : Masochisme. Perdre 3 points dendurance minimum en 1 round","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"masochisme.webp","effects":[],"_id":"NzJJNK0YMAbobu0p"}
{"name":"Désir lancinant : Casser 3d6 oeufs en les jetant à terre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"casser_oeufs.webp","effects":[],"_id":"OjG8XRbeYtq2jcgB"}
{"name":"Désir lancinant : Traire une vache","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"traire_vache.webp","effects":[],"_id":"QHUOwjMR6AvepGPm"}
{"name":"Désir lancinant : Pisser dans un violon (luth, mandoline, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"pisser_violon.webp","effects":[],"_id":"S8PVNgxb7TcFXq9g"}
{"name":"Désir lancinant : Manger du poisson","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"manger_poisson.webp","effects":[],"_id":"SY0SsWtZdxSodMcl"}
{"name":"Idée fixe : Ne pas franchir de porte. (On peut franchir une fenêtre)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"pas-franchir.webp","effects":[],"_id":"UUTbsktTcxsIe5L5"}
{"name":"Idée fixe : Refuser de se délester du moindre objet, ni donner ni prêter","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"refuser_delester.webp","effects":[],"_id":"VChJbtGFtWoiFNky"}
{"name":"Idée fixe : Ne sexprimer que par des cris danimaux (meuh ! coin-coin ! etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"exprimer_cris.webp","effects":[],"_id":"YCHBbRLiMzTH7IBj"}
{"name":"Idée fixe : Vider sur sa tête toute fiole ou flacon aperçu","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"verser_flacon.webp","effects":[],"_id":"afGp9CewfyJKecEE"}
{"name":"Désir lancinant : Faire des bulles de savon","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"bulles_savon.webp","effects":[],"_id":"df5oN8Ub3dWTVxNj"}
{"name":"Désir lancinant : Entendre braire un âne","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"entendre_ane.webp","effects":[],"_id":"diCCimukdNM6bPub"}
{"name":"Désir lancinant : Se rouler dans la boue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"se_rouler_boue.webp","effects":[],"_id":"el4lofhhSucMv5xv"}
{"name":"Idée fixe : Ne dire que «non» ou négation analogue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"dire_non.webp","effects":[],"_id":"gMmqdJ9I7Mt8Tg3f"}
{"name":"Désir lancinant : Manger des champignons","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"manger_champignons.webp","effects":[],"_id":"gadh6aI5iCM82qpP"}
{"name":"Idée fixe : Refuser de se déplacer autrement que porté","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"refuser_deplacer.webp","effects":[],"_id":"hghw6Cldrad1CIiJ"}
{"name":"Idée fixe : Garder une main sur la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"garder_main.webp","effects":[],"_id":"iPYPgxL2uUnphStc"}
{"name":"Idée fixe : Appeler les hommes «madame» et les femmes «messire»","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"appeler_hommes_femmes.webp","effects":[],"_id":"j2xIrFWYqhDM4TcN"}
{"name":"Désir lancinant : Se soûler (minimum pas frais)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"se_souler.webp","effects":[],"_id":"jShpKV8mVcqWmYvp"}
{"name":"Désir lancinant : Construire une cabane","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"construire_cabane.webp","effects":[],"_id":"mN0yghXkFfj2YctJ"}
{"name":"Désir lancinant : Embrasser un cochon sur le groin","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"embrasser_cochon.webp","effects":[],"_id":"sjXBBr85OBk4Yg4t"}
{"name":"Idée fixe : Faire le mort","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"faire_mort.webp","effects":[],"_id":"xa4t9Lbt6uLEjap6"}
{"name":"Idée fixe : Anorexie. Ne rien avaler, ni solide, ni liquide, pas même une potion","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"0uc2pMIGL03Hq2Hn"}
{"name":"Désir lancinant : Briser un objet de verre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"1l59lWbtvYp74OTb"}
{"name":"Idée fixe : Cracher dans toute nourriture ou boisson aperçue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"22EQLBJfHVYs96iC"}
{"name":"Idée fixe : Éteindre tout feu rencontré (feu de camp, torche, lanterne, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"2Rtm78bMKPy8eG4q"}
{"name":"Désir lancinant : Danser avec un(e) partenaire inconnu(e) (Beauté 13 minimum)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"2i3PndTKG1n3hEUU"}
{"name":"Idée fixe : Traîner son épée en laisse (ou sa meilleure arme)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"2j1q9e07ZLlIQDYl"}
{"name":"Désir lancinant : Gagner de largent (minimum 10 deniers)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"3BcC8lSsP5WIyva7"}
{"name":"Désir lancinant : Mégalomanie. Être acclamé par un minimum de 10 personnes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"3ZjwYyQRatCMnBCi"}
{"name":"Idée fixe : Avoir le visage noirci à la cendre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"6G0lF06jSryTduAt"}
{"name":"Idée fixe : Ne marcher quà quatre pattes","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"7TKsit2Mv9mWGq3C"}
{"name":"Désir lancinant : Acquérir une chèvre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"8sLXQBqo8XwjAFG0"}
{"name":"Idée fixe : Garder les yeux bandés","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"E902EEYZHg3zFKq6"}
{"name":"Désir lancinant : Danser nu sous la pluie","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"F6qL4d4g3qjh045R"}
{"name":"Idée fixe : Garder sur soi 3d6 kilos de cailloux","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"F8G3rdU1nfJzYwYR"}
{"name":"Désir lancinant : Se faire raser la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"HSNOvBR890dsEDw2"}
{"name":"Idée fixe : Aller tout nu, sans porter le moindre paquet ni objet","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"I0CtQ05xFW6ghcdP"}
{"name":"Idée fixe : Boulimie. Manger au moins un point de sust. par heure","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"JcTX8qMS0z8bmdVt"}
{"name":"Désir lancinant : Passer une nuit sur une échelle","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"LlELEB0FhymLx6VM"}
{"name":"Idée fixe : Refuser de monter dans les TMR","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"NpTDqICR7ZuToQrg"}
{"name":"Désir lancinant : Masochisme. Perdre 3 points dendurance minimum en 1 round","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"NzJJNK0YMAbobu0p"}
{"name":"Désir lancinant : Casser 3d6 oeufs en les jetant à terre","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"OjG8XRbeYtq2jcgB"}
{"name":"Désir lancinant : Traire une vache","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"QHUOwjMR6AvepGPm"}
{"name":"Désir lancinant : Pisser dans un violon (luth, mandoline, etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"S8PVNgxb7TcFXq9g"}
{"name":"Désir lancinant : Manger du poisson","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"SY0SsWtZdxSodMcl"}
{"name":"Idée fixe : Ne pas franchir de porte. (On peut franchir une fenêtre)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"UUTbsktTcxsIe5L5"}
{"name":"Idée fixe : Refuser de se délester du moindre objet, ni donner ni prêter","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"VChJbtGFtWoiFNky"}
{"name":"Idée fixe : Ne sexprimer que par des cris danimaux (meuh ! coin-coin ! etc.)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"YCHBbRLiMzTH7IBj"}
{"name":"Idée fixe : Vider sur sa tête toute fiole ou flacon aperçu","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"afGp9CewfyJKecEE"}
{"name":"Désir lancinant : Faire des bulles de savon","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"df5oN8Ub3dWTVxNj"}
{"name":"Désir lancinant : Entendre braire un âne","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"diCCimukdNM6bPub"}
{"name":"Désir lancinant : Se rouler dans la boue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"el4lofhhSucMv5xv"}
{"name":"Idée fixe : Ne dire que «non» ou négation analogue","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"gMmqdJ9I7Mt8Tg3f"}
{"name":"Désir lancinant : Manger des champignons","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"gadh6aI5iCM82qpP"}
{"name":"Idée fixe : Refuser de se déplacer autrement que porté","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"hghw6Cldrad1CIiJ"}
{"name":"Idée fixe : Garder une main sur la tête","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"iPYPgxL2uUnphStc"}
{"name":"Idée fixe : Appeler les hommes «madame» et les femmes «messire»","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"j2xIrFWYqhDM4TcN"}
{"name":"Désir lancinant : Se soûler (minimum pas frais)","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},""img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"jShpKV8mVcqWmYvp"}
{"name":"Désir lancinant : Construire une cabane","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"mN0yghXkFfj2YctJ"}
{"name":"Désir lancinant : Embrasser un cochon sur le groin","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Tant que satisfaction n'est pas obtenue, aucun point d'exp&eacute;rience ne peut plus &ecirc;tre gagn&eacute; par l'exercice en cas de particuli&egrave;re et d'ajustement final n&eacute;gatif.<br />Les points d'exp&eacute;rience dus au stress ne sont pas affect&eacute;s.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp","effects":[],"_id":"sjXBBr85OBk4Yg4t"}
{"name":"Idée fixe : Faire le mort","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"queue","data":{"description":"<p>Prend effet imm&eacute;diatement et dure jusqu'&agrave; la <strong>fin de l'heure du Ch&acirc;teau Dormant </strong>du <strong>lendemain.<br /></strong>Si pass&eacute; ce d&eacute;lai, l'occasion de la manifester ne s'est pas pr&eacute;sent&eacute;e, la queue prend fin.</p>\n<p>Si elle entre en contradiction avec une autre queue, retirer.</p>","refoulement":1},"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp","effects":[],"_id":"xa4t9Lbt6uLEjap6"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
{"_id":"0ZW71u9G8fqnyNfy","name":"Drakkar","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Bateau","resistance":28,"structure":12,"vitesse":"3/2/1","bonus":"(10)/+10/+14","manoeuvrabilite":"0/-2/-4","equipage":8,"capacite_encombrement":150,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/drakkar.webp","token":{"flags":{},"name":"Drakkar","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/drakkar_token.webp","tint":"","width":10,"height":10,"scale":1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"0ZW71u9G8fqnyNfy","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"5FWY38a5emYmqisa","name":"Cariole","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Cariole à Bras","resistance":10,"structure":6,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":1,"capacite_encombrement":50,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/cariole.webp","token":{"flags":{},"name":"Cariole","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/cariole_token.webp","tint":"","width":2,"height":2,"scale":1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"5FWY38a5emYmqisa","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"C0JpbzQSELoml971","name":"Canot","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Barque","resistance":14,"structure":6,"vitesse":"","bonus":"(2)/+3/+5","manoeuvrabilite":"","equipage":1,"capacite_encombrement":50,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/canot.webp","token":{"flags":{},"name":"Canot","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/canot_token.webp","tint":"","width":3,"height":3,"scale":1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"C0JpbzQSELoml971","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"PoQUTsNThYDp6XAW","name":"Nef","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Bateau","resistance":30,"structure":14,"vitesse":"5/4/2","bonus":"","manoeuvrabilite":"0/-3/-4","equipage":12,"capacite_encombrement":200,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/nef.webp","token":{"flags":{},"name":"Nef","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/nef_token.webp","tint":"","width":13,"height":13,"scale":1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"PoQUTsNThYDp6XAW","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"RFOYL8HBUxd32DXS","name":"Galère","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Bateau","resistance":36,"structure":14,"vitesse":"2/2/1","bonus":"(12)/+12/+16","manoeuvrabilite":"0/-4/-6","equipage":10,"capacite_encombrement":300,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/galere.webp","token":{"flags":{},"name":"Galère","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/galere_token.webp","tint":"","width":14,"height":14,"scale":1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"RFOYL8HBUxd32DXS","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"TDpSn7GawJ1LCHp7","name":"Charette","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Chariot","resistance":16,"structure":8,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":1,"capacite_encombrement":100,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/charette.webp","token":{"flags":{},"name":"Charette","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/charette_token.webp","tint":"","width":3,"height":3,"scale":1.1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"TDpSn7GawJ1LCHp7","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"ZiyRDzz3gGzlpLIc","name":"Barque","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Barque","resistance":20,"structure":10,"vitesse":"3/2/1","bonus":"(4)/+4/+6","manoeuvrabilite":"0/0/-4","equipage":4,"capacite_encombrement":100,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/barque.webp","token":{"flags":{},"name":"Barque","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/barque_token.webp","tint":"","width":6,"height":6,"scale":1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"ZiyRDzz3gGzlpLIc","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"gM77co80kmpVsYg6","name":"Posé par terre","permission":{"default":0,"Q2G6GTdrotKzYGUC":3},"type":"vehicule","data":{"categorie":"Autre","resistance":0,"structure":0,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":0,"capacite_encombrement":100,"description":"<p>D&eacute;poser ici les objets que vous voulez &eacute;changer avec d'autres joueurs</p>","notesmj":""},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp","token":{"flags":{},"name":"Posé par terre","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp","tint":"","width":1,"height":1,"scale":1,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"gM77co80kmpVsYg6","actorLink":true,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"idyDmDWYpQ4Eppen","name":"Chariot","permission":{"default":0,"rYShh2P1DNavdoBD":3},"type":"vehicule","data":{"categorie":"Chariot","resistance":20,"structure":10,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":1,"capacite_encombrement":150,"description":"Description ...","notesmj":"Notes du MJ"},"sort":100001,"flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/chariot.webp","token":{"flags":{},"name":"Chariot","displayName":0,"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/chariot_token.webp","tint":"","width":4,"height":4,"scale":1.4,"mirrorX":false,"mirrorY":false,"lockRotation":false,"rotation":0,"vision":false,"dimSight":0,"brightSight":0,"dimLight":0,"brightLight":0,"sightAngle":360,"lightAngle":360,"lightColor":"","lightAlpha":1,"lightAnimation":{"type":"","speed":5,"intensity":5},"actorId":"idyDmDWYpQ4Eppen","actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":""},"bar2":{"attribute":""},"randomImg":false},"items":[],"effects":[]}
{"_id":"0ZW71u9G8fqnyNfy","name":"Drakkar","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.0ZW71u9G8fqnyNfy"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/drakkar.webp","items":[],"effects":[],"system":{"categorie":"Bateau","resistance":28,"structure":12,"vitesse":"3/2/1","bonus":"(10)/+10/+14","manoeuvrabilite":"0/-2/-4","equipage":8,"capacite_encombrement":150,"etat":{"resistance":{"type":"number","max":28,"value":28,"label":"Résistance","derivee":false},"structure":{"type":"number","max":12,"value":12,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Drakkar","displayName":0,"width":10,"height":10,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/drakkar_token.webp","tint":null,"scaleX":1,"scaleY":1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097623,"modifiedTime":1664231486338,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"5FWY38a5emYmqisa","name":"Cariole","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.5FWY38a5emYmqisa"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/cariole.webp","items":[],"effects":[],"system":{"categorie":"Cariole à Bras","resistance":10,"structure":6,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":1,"capacite_encombrement":50,"etat":{"resistance":{"type":"number","max":10,"value":10,"label":"Résistance","derivee":false},"structure":{"type":"number","max":6,"value":6,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Cariole","displayName":0,"width":2,"height":2,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/cariole_token.webp","tint":null,"scaleX":1,"scaleY":1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097624,"modifiedTime":1664231486337,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"C0JpbzQSELoml971","name":"Canot","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.C0JpbzQSELoml971"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/canot.webp","items":[],"effects":[],"system":{"categorie":"Barque","resistance":14,"structure":6,"vitesse":"","bonus":"(2)/+3/+5","manoeuvrabilite":"","equipage":1,"capacite_encombrement":50,"etat":{"resistance":{"type":"number","max":14,"value":14,"label":"Résistance","derivee":false},"structure":{"type":"number","max":6,"value":6,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Canot","displayName":0,"width":3,"height":3,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/canot_token.webp","tint":null,"scaleX":1,"scaleY":1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097625,"modifiedTime":1664231486336,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"PoQUTsNThYDp6XAW","name":"Nef","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.PoQUTsNThYDp6XAW"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/nef.webp","items":[],"effects":[],"system":{"categorie":"Bateau","resistance":30,"structure":14,"vitesse":"5/4/2","bonus":"","manoeuvrabilite":"0/-3/-4","equipage":12,"capacite_encombrement":200,"etat":{"resistance":{"type":"number","max":30,"value":30,"label":"Résistance","derivee":false},"structure":{"type":"number","max":14,"value":14,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Nef","displayName":0,"width":13,"height":13,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/nef_token.webp","tint":null,"scaleX":1,"scaleY":1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097626,"modifiedTime":1664231486339,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"RFOYL8HBUxd32DXS","name":"Galère","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.RFOYL8HBUxd32DXS"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/galere.webp","items":[],"effects":[],"system":{"categorie":"Bateau","resistance":36,"structure":14,"vitesse":"2/2/1","bonus":"(12)/+12/+16","manoeuvrabilite":"0/-4/-6","equipage":10,"capacite_encombrement":300,"etat":{"resistance":{"type":"number","max":36,"value":36,"label":"Résistance","derivee":false},"structure":{"type":"number","max":14,"value":14,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Galère","displayName":0,"width":14,"height":14,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/galere_token.webp","tint":null,"scaleX":1,"scaleY":1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097627,"modifiedTime":1664231486339,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"TDpSn7GawJ1LCHp7","name":"Charette","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.TDpSn7GawJ1LCHp7"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/charette.webp","items":[],"effects":[],"system":{"categorie":"Chariot","resistance":16,"structure":8,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":1,"capacite_encombrement":100,"etat":{"resistance":{"type":"number","max":16,"value":16,"label":"Résistance","derivee":false},"structure":{"type":"number","max":8,"value":8,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Charette","displayName":0,"width":3,"height":3,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/charette_token.webp","tint":null,"scaleX":1.1,"scaleY":1.1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097629,"modifiedTime":1664231486337,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"ZiyRDzz3gGzlpLIc","name":"Barque","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.ZiyRDzz3gGzlpLIc"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/barque.webp","items":[],"effects":[],"system":{"categorie":"Barque","resistance":20,"structure":10,"vitesse":"3/2/1","bonus":"(4)/+4/+6","manoeuvrabilite":"0/0/-4","equipage":4,"capacite_encombrement":100,"etat":{"resistance":{"type":"number","max":20,"value":20,"label":"Résistance","derivee":false},"structure":{"type":"number","max":10,"value":10,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Barque","displayName":0,"width":6,"height":6,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/barque_token.webp","tint":null,"scaleX":1,"scaleY":1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097629,"modifiedTime":1664231486336,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"gM77co80kmpVsYg6","name":"Posé par terre","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.gM77co80kmpVsYg6"}},"img":"systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp","items":[],"effects":[],"system":{"categorie":"Autre","resistance":0,"structure":0,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":0,"capacite_encombrement":100,"etat":{"resistance":{"type":"number","max":0,"value":0,"label":"Résistance","derivee":false},"structure":{"type":"number","max":0,"value":0,"label":"Structure","derivee":false}},"description":"<p>D&eacute;poser ici les objets que vous voulez &eacute;changer avec d'autres joueurs</p>","race":"","notesmj":""},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"prototypeToken":{"flags":{},"name":"Posé par terre","displayName":0,"width":1,"height":1,"lockRotation":false,"rotation":0,"actorLink":true,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp","tint":null,"scaleX":1,"scaleY":1,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097630,"modifiedTime":1664231486340,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
{"_id":"idyDmDWYpQ4Eppen","name":"Chariot","type":"vehicule","sort":100001,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.vehicules.idyDmDWYpQ4Eppen"}},"img":"systems/foundryvtt-reve-de-dragon/icons/vehicules/chariot.webp","items":[],"effects":[],"system":{"categorie":"Chariot","resistance":20,"structure":10,"vitesse":"","bonus":"","manoeuvrabilite":"","equipage":1,"capacite_encombrement":150,"etat":{"resistance":{"type":"number","max":20,"value":20,"label":"Résistance","derivee":false},"structure":{"type":"number","max":10,"value":10,"label":"Structure","derivee":false}},"description":"Description ...","race":"","notesmj":"Notes du MJ"},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"prototypeToken":{"flags":{},"name":"Chariot","displayName":0,"width":4,"height":4,"lockRotation":false,"rotation":0,"actorLink":false,"disposition":0,"displayBars":0,"bar1":{"attribute":"sante.vie"},"bar2":{"attribute":"sante.endurance"},"randomImg":false,"light":{"dim":0,"bright":0,"angle":360,"color":null,"alpha":1,"animation":{"type":null,"speed":5,"intensity":5,"reverse":false},"coloration":1,"attenuation":0.5,"luminosity":0.5,"saturation":0,"contrast":0,"shadows":0,"darkness":{"min":0,"max":1}},"texture":{"src":"systems/foundryvtt-reve-de-dragon/icons/vehicules/chariot_token.webp","tint":null,"scaleX":1.4,"scaleY":1.4,"offsetX":0,"offsetY":0,"rotation":0},"sight":{"angle":360,"enabled":false,"range":0,"brightness":1,"visionMode":"basic","color":null,"attenuation":0.1,"saturation":0,"contrast":0},"alpha":1,"detectionModes":[]},"folder":null,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.0.21","coreVersion":"10.286","createdTime":1664231097632,"modifiedTime":1664231486338,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="80.64064mm"
height="87.145065mm"
viewBox="0 0 80.64064 87.145065"
version="1.1"
id="svg857"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
sodipodi:docname="appel-chance.svg">
<defs
id="defs851" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.3758788"
inkscape:cx="275.41114"
inkscape:cy="237.41072"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2054"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1" />
<metadata
id="metadata854">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-65.513013,-104.59413)">
<g
id="g7"
transform="matrix(0.26458333,0,0,0.26458333,66.057598,105.25559)"
style="image-rendering:auto;fill:#ffffff;stroke:none">
<title
id="title4">Layer 1</title>
<path
fill="#ffffff"
fill-rule="evenodd"
stroke="#000000"
stroke-width="8"
id="path2"
d="m 206.5,1.5 q 8.5,0 15,3 6.5,3 12.25,8.25 5.75,5.25 12.5,15.5 Q 253,38.5 259.5,43 266,47.5 273.75,52.25 281.5,57 285.5,63 q 4,6 5.75,11.5 1.75,5.5 0,18 -1.75,12.5 -5.75,20 -4,7.5 -12.75,14.25 -8.75,6.75 -17.25,10.75 -8.5,4 -15,6 -6.5,2 -28.75,4.25 -22.25,2.25 -23,3 l -0.75,0.75 0.5,1.25 q 0.5,1.25 32,0.5 31.5,-0.75 43.5,2.75 12,3.5 18.25,8.25 6.25,4.75 9.75,10.25 3.5,5.5 5.5,10.5 2,5 0.5,19.5 -1.5,14.5 -4.75,19.75 -3.25,5.25 -3.75,6.5 l -0.5,1.25 -4.25,2.5 q -4.25,2.5 -10.25,10.5 -6,8 -10,16.5 -4,8.5 -6.75,12.25 -2.75,3.75 -5.25,5.5 -2.5,1.75 -4,4 -1.5,2.25 -9.5,6.25 -8,4 -18.5,2.5 Q 210,290.5 202.75,285.25 195.5,280 190.5,275 q -5,-5 -10.25,-12.25 -5.25,-7.25 -7,-10.5 Q 171.5,249 169,237 q -2.5,-12 -5.5,-21 l -3,-9 -1.5,6.5 q -1.5,6.5 0,28.5 1.5,22 6.5,35 5,13 9.25,18.25 4.25,5.25 10,10.5 5.75,5.25 4.75,10.75 -1,5.5 -1.25,5.75 L 188,322.5 181,321 q -7,-1.5 -13.75,-7.25 Q 160.5,308 156,301.5 q -4.5,-6.5 -8.5,-17 -4,-10.5 -5.5,-20.5 -1.5,-10 -0.25,-36.25 l 1.25,-26.25 -3.25,0.75 q -3.25,0.75 -4.75,5.25 -1.5,4.5 -5.5,29.5 -4,25 -8,32.5 -4,7.5 -7.25,10.75 -3.25,3.25 -8.25,6.75 -5,3.5 -11,5.5 -6,2 -19,0.5 Q 63,291.5 57,288 51,284.5 43.25,274.75 35.5,265 31.75,257 L 28,249 26.5,247.75 Q 25,246.5 20.75,242.75 16.5,239 10,230.5 3.5,222 2.5,219 1.5,216 3,202.5 4.5,189 9.5,181 14.5,173 21.75,167.25 29,161.5 37,158.5 q 8,-3 36.5,-3.5 28.5,-0.5 30.75,-2.75 l 2.25,-2.25 -1.25,-1.25 Q 104,147.5 74,145 44,142.5 30.5,136.5 17,130.5 11.75,125.25 6.5,120 4.5,116.5 2.5,113 2,103.5 1.5,94 5.25,84.75 9,75.5 21.5,65 34,54.5 35,54.25 L 36,54 37.5,51.25 Q 39,48.5 46.25,39.25 53.5,30 57.25,25.75 61,21.5 68,16 75,10.5 83,8 91,5.5 97,6 q 6,0.5 14,4 8,3.5 14.25,9.25 6.25,5.75 9.25,12.25 3,6.5 4.5,15.5 1.5,9 4.25,34 2.75,25 3.75,25 h 1 l 0.75,-2.5 Q 149.5,101 151.5,72 153.5,43 155,39.5 156.5,36 162.25,27.75 168,19.5 176,13.5 q 8,-6 15,-9 7,-3 15.5,-3 z"
style="fill:#ffffff;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -93,7 +93,7 @@
.sheet nav.sheet-tabs {
font-family: "CaslonAntique";
} /* For nav and title */
.window-app input, .foundryvtt-reve-de-dragon .item-form, .sheet header.sheet-header .flex-group-center.flex-compteurs, .sheet header.sheet-header .flex-group-center.flex-fatigue, select, button, .item-checkbox, #sidebar, #players, #navigation #nav-toggle {
.window-app input, .foundryvtt-reve-de-dragon .item-form, .sheet header.sheet-header .flex-compteurs, .sheet header.sheet-header .flex-group-center.flex-fatigue, select, button, .item-checkbox, #sidebar, #players, #navigation #nav-toggle {
font-family: "CaslonAntique"; /* For sheet parts */
}
@ -252,6 +252,49 @@ table {border: 1px solid #7a7971;}
justify-content: center;
text-align: left;
}
.blessure-control {
flex-grow: 1;
flex-direction: row;
}
.blessure-soins {
flex-direction: row;
align-content: flex-start;
justify-content: flex-start;
margin-right: 2px;
margin-left: 2px;
padding: 2px;
}
input:is(.blessure-psdone, .blessure-scdone) {
width: 20px;
}
input:is(.blessure-premiers_soins, .blessure-soins_complets) {
width: calc(100% - 25px);
}
.blessure-jours {
flex-direction: row;
align-content: flex-start;
justify-content: flex-start;
}
.blessure-localisation {
flex-direction: row;
align-content: flex-start;
justify-content: flex-start;
}
.blessure-inactive {
color:rgba(150, 150, 150, 0.4);
}
.blessure-active-legere {
color:rgba(60, 60, 60, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
}
.blessure-active-grave {
color: rgba(218, 126, 21, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
}
.blessure-active-critique {
color: rgba(173, 36, 26, 0.9);
text-shadow: 1px 1px 4px rgba(60, 60, 60, 1);
}
.foundryvtt-reve-de-dragon .sheet-header {
-webkit-box-flex: 0;
@ -289,9 +332,9 @@ table {border: 1px solid #7a7971;}
}
.button-img {
vertical-align: baseline;
width: 8%;
height: 8%;
max-height: 48px;
width: 32px;
height: 32px;
max-height: 36px;
border-width: 0;
border: 1px solid rgba(0, 0, 0, 0);
}
@ -366,6 +409,13 @@ table {border: 1px solid #7a7971;}
flex-wrap: nowrap;
justify-content: stretch;
}
.rdd.sheet .window-content .sheet-body .carac-list .caracteristique.streched {
flex-wrap: nowrap;
justify-content: stretch;
flex-basis: 7.5em;
width: max-content;
}
.rdd.sheet .window-content .sheet-body .carac-list .caracteristique > .carac-label {
flex-basis: 50%;
}
@ -450,20 +500,6 @@ table {border: 1px solid #7a7971;}
border-bottom: 1px solid #BBB;
}
.blessure-inactive {
color:rgba(150, 150, 150, 0.4)
}
.blessure-active-legere {
color:rgba(60, 60, 60, 0.9);
text-shadow: rgba(60, 60, 60, 0.7);
}
.blessure-active-grave {
color:rgba(218, 126, 21, 0.9);
}
.blessure-active-critique {
color:rgba(173, 36, 26, 0.9);
}
.foundryvtt-reve-de-dragon .items-list .item .item-image {
-webkit-box-flex: 0;
-ms-flex: 0 0 24px;
@ -603,7 +639,14 @@ section.sheet-body{padding: 0.25rem 0.5rem;}
margin: 0.5rem 0 0.5rem 0.5rem;
padding: 0;
}
.sheet header.sheet-header h1 {
flex: 3;
}
.sheet header.sheet-header img.button-img{
height: 48px;
padding: 1px;
margin: 1px;
}
.sheet nav.sheet-tabs {
font-size: 0.65rem;
font-weight: bold;
@ -645,9 +688,13 @@ section.sheet-body:after {
clear: both;
}
.sheet header.sheet-header .flex-compteurs {text-align: right;}
.sheet header.sheet-header .flex-compteurs { text-align: right; max-width: max-content;}
.sheet header.sheet-header .resource-content {width: 2rem;}
li label.compteur {
display: inline-block;
flex-direction: row;
}
.compteur span {
display: inline-block;
text-align: left;
@ -840,6 +887,23 @@ ul, li {
margin-left: 3rem;
}
.grid-select-type-tmr {
display: grid;
grid-column: span 4 / span 4;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 0.1rem;
margin: 0.1rem;
padding: 0;
}
.grid-select-actor {
display: grid;
grid-column: span 2 / span 2;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.1rem;
margin: 0.1rem;
padding: 0;
}
.sheet-competence-img {
width: 24px;
height: 24px;
@ -891,6 +955,12 @@ ul, li {
margin-right: 0.2rem;
margin-left: 0.2rem;
}
.initiative-value {
flex-grow: 0;
flex-basis: 3rem;
margin-right: 0.2rem;
margin-left: 0.2rem;
}
.description-value {
flex-grow: 0;
flex-basis: 4rem;
@ -909,23 +979,6 @@ ul, li {
.alchimie-title {
font-weight: bold;
}
.blessure-data {
flex-direction: row;
align-content: flex-start;
justify-content: flex-start;
}
.blessures-soins {
flex-grow: 0;
flex-basis: 32px;
margin-right: 4px;
margin-left: 4px;
}
.blessures-loc {
flex-grow: 0;
flex-basis: 96px;
margin-right: 4px;
margin-left: 4px;
}
.pointsreve-value {
flex-grow: 0;
flex-basis: 64px;
@ -1076,7 +1129,7 @@ ul, li {
.table-fatigue .fatigue-malus {
font-size: 0.8rem;
}
.flex-actions-bar {
.flex-actions-bar {
flex-grow: 2;
}
@ -1146,9 +1199,16 @@ ul, li {
}
#sidebar #sidebar-tabs i.fa-comments:before, #sidebar #sidebar-tabs i.fa-fist-raised:before, #sidebar #sidebar-tabs i.fa-users:before, #sidebar #sidebar-tabs i.fa-map:before, #sidebar #sidebar-tabs i.fa-suitcase:before, #sidebar #sidebar-tabs i.fa-book-open:before, #sidebar #sidebar-tabs i.fa-th-list:before, #sidebar #sidebar-tabs i.fa-music:before, #sidebar #sidebar-tabs i.fa-atlas:before, #sidebar #sidebar-tabs i.fa-cogs:before {content: "";}
#sidebar #sidebar-tabs i:is(
.fa-comments, .fa-fist-raised, .fa-swords,
.fa-users, .fa-user, .fa-map, .fa-suitcase,
.fa-book-open, .fa-th-list, .fa-music,
.fa-atlas,.fa-cogs
):before {content: "";}
#sidebar #sidebar-tabs i.fa-comments {background: url("img/ui/icon_sidebar_chat.svg") no-repeat;}
#sidebar #sidebar-tabs i.fa-fist-raised {background: url("img/ui/icon_sidebar_fight.svg") no-repeat;}
#sidebar #sidebar-tabs i.fa-swords {background: url("img/ui/icon_sidebar_fight.svg") no-repeat;}
#sidebar #sidebar-tabs i.fa-user {background: url("img/ui/icon_sidebar_actor.svg") no-repeat;}
#sidebar #sidebar-tabs i.fa-users {background: url("img/ui/icon_sidebar_actor.svg") no-repeat;}
#sidebar #sidebar-tabs i.fa-map {background: url("img/ui/icon_sidebar_scene.svg") no-repeat;}
#sidebar #sidebar-tabs i.fa-suitcase {background: url("img/ui/icon_sidebar_item.svg") no-repeat;}

View File

@ -1,6 +1,13 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
"version": "10.0.28",
"download": "https://www.uberwald.me/gitea/VincentVk/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.0.28.zip",
"manifest": "https://www.uberwald.me/gitea/VincentVk/foundryvtt-reve-de-dragon/raw/v10/system.json",
"compatibility": {
"minimum": "10",
"verified": "10.288"
},
"description": "Rêve de Dragon RPG for FoundryVTT",
"authors": [
{
@ -34,12 +41,6 @@
],
"url": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/",
"license": "LICENSE.txt",
"version": "10.0.8",
"compatibility": {
"minimum": "10",
"verified": "10.283",
"maximum": "10"
},
"esmodules": [
"module/rdd-main.js"
],
@ -333,8 +334,6 @@
}
],
"socket": true,
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.0.8.zip",
"gridDistance": 1,
"gridUnits": "m",
"primaryTokenAttribute": "sante.vie",

View File

@ -31,13 +31,27 @@
},
"vehicule": {
"categorie": "",
"resistance": 0,
"structure": 0,
"vitesse": "",
"bonus": "",
"manoeuvrabilite": "",
"equipage": 0,
"capacite_encombrement": 0
"capacite_encombrement": 0,
"etat": {
"resistance" : {
"type": "number",
"max": 20,
"value": 20,
"label": "Résistance",
"derivee": false
},
"structure":{
"type": "number",
"max": 10,
"value": 10,
"label": "Structure",
"derivee": false
}
}
},
"entite": {
"definition": {
@ -224,7 +238,7 @@
}
}
},
"common": {
"personnage": {
"carac": {
"taille": {
"type": "number",
@ -560,7 +574,7 @@
}
},
"personnage": {
"templates": [ "background", "common", "subacteurs" ]
"templates": [ "personnage", "background", "subacteurs" ]
},
"creature": {
"templates": [ "creature", "description" ]
@ -576,7 +590,7 @@
"types": ["objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",
"tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique",
"musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "signedraconique", "gemme",
"possession" ],
"possession", "sortreserve" ],
"possession": {
"typepossession": "",
"possede": false,
@ -679,9 +693,10 @@
"categorie_parade": "",
"niveau": 0,
"default_diffLibre": 0,
"categorie": "",
"carac_value": 0,
"iscombat": false,
"isparade": false,
"isnaturelle": true,
"ispossession": false,
"dommages": 0,
"description": "Compétence : ...",
@ -889,7 +904,7 @@
"descriptionmj": ""
},
"oeuvre": {
"default_carac": "",
"default_carac": "",
"competence": "",
"niveau": 0,
"reference": "",
@ -943,6 +958,14 @@
},
"description": "",
"descriptionmj": ""
},
"sortreserve": {
"sortid" : "",
"draconic": "",
"coord": "",
"ptreve": 0,
"heurecible": "",
"echectotal": false
}
}
}

View File

@ -1,27 +0,0 @@
<tr class="table-row alterne-row item" data-blessure-type="{{gravite}}" data-attribute={{key}} data-blessure-index="{{key}}" >
<td class="blessure-control" title="Blessure {{title}}" data-blessure-active="{{bless.active}}">
{{#if bless.active}}
<i class="fas fa-skull-crossbones blessure-active-{{gravite}}" name="blessure-{{gravite}}-{{key}}-active"></i>
{{else}}
<i class="fas fa-skull-crossbones blessure-inactive" name="blessure-{{gravite}}-{{key}}-active"></i>
{{/if}}
</td>
<td>
<input class="blessures-soins blessure-localisation" type="text" name="blessure-{{gravite}}-{{key}}-localisation" data-dtype="String" value="{{bless.loc}}"/>
</td>
<td>
<input class="blessures-soins blessure-premiers_soins" type="text" name="blessure-{{gravite}}-{{key}}-premiers_soins" data-dtype="number" value="{{bless.premiers_soins}}"/>
</td>
<td>
<input class="blessures-soins blessure-psdone" name="blessure-{{gravite}}-{{key}}-psdone" type="checkbox" name="bless.psdone" {{#if bless.psdone}}checked{{/if}}/>
</td>
<td>
<input class="blessures-soins blessure-soins_complets" type="text" name="blessure-{{gravite}}-{{key}}-soins_complets" data-dtype="number" value="{{bless.soins_complets}}"/>
</td>
<td>
<input class="blessures-soins blessure-scdone" name="blessure-{{gravite}}-{{key}}-scdone" type="checkbox" name="bless.scdone" {{#if bless.scdone}}checked{{/if}}/>
</td>
<td>
<input class="blessures-soins blessure-jours" type="text" name="blessure-{{gravite}}-{{key}}-jours" name="jours" data-dtype="number" value="{{bless.jours}}"/>
</td>
</tr>

View File

@ -2,33 +2,33 @@
{{!-- Sheet Header --}}
<header class="sheet-header">
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<div class="header-fields">
<div class="flexrow">
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
</div>
<div class="flexrow flex-group-center flex-actions-bar">
<div>
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<h1 class="charname flex-grow"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
<div class="flex-group-center">
<span class="encaisser-direct"><a title="Encaisser des dommages"><img class="button-img" src="icons/svg/bones.svg" alt="Encaisser des dommages"/></a></span>
<span class="gm-only remise-a-neuf"><a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a></span>
{{#if @root.options.isGM}}
<span class="remise-a-neuf"><a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a></span>
{{/if}}
</div>
</div>
<div class="flexrow">
<div class="flexrow">
<span>{{calc.resumeBlessures}}</span>
<div class="flex-group-left flexrow">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.html"}}
<div class="flex-group-center">
<span>
{{calc.resumeBlessures}}
&hyphen; Etat Général : {{system.compteurs.etat.value}}
</span>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html"}}
</div>
<div class="flexrow">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-effects-partial.html"}}
</div>
</div>
</div>
</div>
</header>
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="carac">Caractéristiques</a>
<a class="item" data-tab="competences">Compétences</a>
<a class="item" data-tab="blessures">Blessures</a>
<a class="item" data-tab="items">Équipement</a>
<a class="item" data-tab="description">Description</a>
</nav>
@ -36,97 +36,27 @@
{{!-- Sheet Body --}}
<section class="sheet-body">
{{!-- Carac Tab --}}
{{!-- Carac & compétences --}}
<div class="tab items" data-group="primary" data-tab="carac">
<div class="flexrow">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
</div>
<div class="grid grid-2col">
<div class="flex-group-left flexcol">
<ol class="carac-list alterne-list">
{{#each data.carac as |carac key|}}
<li class="flexrow list-item" data-attribute="{{key}}">
{{#if (eq key 'taille')}}
<span class="carac-label flexrow" name="system.carac.{{key}}.label">{{carac.label}}</span>
{{else}}
<span class="carac-label flexrow" name="system.carac.{{key}}.label"><a
name={{key}}>{{carac.label}}</a></span>
{{/if}}
<input class="competence-value flexrow" type="text" name="system.carac.{{key}}.value"
value="{{carac.value}}" data-dtype="{{carac.type}}" />
</li>
{{/each}}
<li class="flexrow">
<span class="carac-label" name="carac-total">Total Caractéristiques</span>
<span class="competence-value" name="carac-total-value">{{calc.caracTotal}}</span>
</li>
</ol>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.html"}}
</div>
<div class="flex-group-left flexcol">
<ol class="carac-list alterne-list">
{{#each data.attributs as |attr key|}}
<li class="flexrow list-item" data-attribute="{{key}}">
<span class="carac-label" name="system.attributs.{{key}}.label">{{attr.label}}</span>
<input type="text" name="system.attributs.{{key}}.value" value="{{attr.value}}" data-dtype="{{attr.type}}" />
</li>
{{/each}}
<li class="flexrow list-item" data-attribute="vie">
<span class="competence-label" name="data.sante.vie.label">Vie</span>
<span class="flexrow" >
<input type="text" name="system.sante.vie.value" value="{{data.sante.vie.value}}" data-dtype="Number" /> /
<input type="text" name="system.sante.vie.max" value="{{data.sante.vie.max}}" data-dtype="Number" />
</span>
</li>
<li class="flexrow list-item" data-attribute="endurance">
<span class="competence-label" name="system.sante.endurance.label">Endurance</span>
<span class="flexrow" >
<input type="text" name="system.sante.endurance.value" value="{{data.sante.endurance.value}}" data-dtype="Number" /> /
<input type="text" name="system.sante.endurance.max" value="{{data.sante.endurance.max}}" data-dtype="Number" />
</span>
</li>
<li class="flexrow list-item" data-attribute="etat">
<span class="competence-label" name="system.compteurs.etat.label">Etat Général</span>
<input type="text" value="{{data.compteurs.etat.value}}" disabled />
</li>
</ol>
</div>
</div>
</div>
{{!-- Compétences Tab --}}
<div class="tab competences" data-group="primary" data-tab="competences">
<div class="flexcol">
<div class="flex-group-left flexcol competence-column">
<ol class="item-list alterne-list">
{{#each competences as |comp key|}}
<li class="item flexrow list-item" data-item-id="{{comp._id}}">
<a class="competence-label" name="{{comp.name}}">
<img class="sheet-competence-img" src="{{comp.img}}"/>
<span class="competence-label">{{comp.name}}</span>
</a>
<input class="competence-value creature-carac" type="text" compname="{{comp.name}}"
value="{{comp.system.carac_value}}" data-dtype="number" />
<input class="competence-value creature-niveau" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.system.niveau decimals=0 sign=true}}" data-dtype="number" />
<input class="competence-value creature-dommages" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.system.dommages decimals=0 sign=true}}" data-dtype="number" />
<div class="item-controls">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ol>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html"}}
</div>
</div>
</div>
{{!-- blessures Tab --}}
<div class="tab blessures" data-group="primary" data-tab="blessures" style="height:200px">
{{!-- Liste de blessures --}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html" this}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html"}}
</div>
{{!-- Equipment Tab --}}
<div class="tab items" data-group="primary" data-tab="items">
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html"}}
</div>
{{!-- Biography Tab --}}
@ -134,15 +64,15 @@
<div class="form-group">
<span class="item-name"><h4>Race</h4></span>
<input type="text" name="system.race" value="{{data.race}}" data-dtype="String" />
<input type="text" name="system.race" value="{{system.race}}" data-dtype="String" />
</div>
<div class="form-group editor">
<span class="item-name"><h4>Description</h4>
{{editor data.description target="system.description" button=true owner=owner editable=true}}
{{editor description target="system.description" button=true owner=owner editable=true}}
</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html"}}
</div>

View File

@ -2,138 +2,48 @@
{{!-- Sheet Header --}}
<header class="sheet-header">
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<div class="header-fields">
<div class="flexrow">
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
</div>
<div class="flexrow flex-group-center flex-actions-bar">
<div>
<div class="flex-group-center">
<span class="encaisser-direct"><a title="Encaisser des dommages"><img class="button-img" src="icons/svg/bones.svg" alt="Encaisser des dommages"/></a></span>
<span class="gm-only remise-a-neuf"><a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a></span>
{{#if @root.options.isGM}}
<span class="remise-a-neuf"><a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a></span>
{{/if}}
</div>
</div>
<div class="flex-group-left flexrow">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.html"}}
</div>
</div>
</header>
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="carac">Caractéristiques</a>
<a class="item" data-tab="competences">Compétences</a>
<a class="item" data-tab="description">Description</a>
</nav>
{{!-- Sheet Body --}}
<section class="sheet-body">
{{!-- Carac Tab --}}
<div class="tab items" data-group="primary" data-tab="carac">
<div class="items" data-group="primary" data-tab="carac">
<div class="flexrow">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
</div>
<div class="grid grid-2col">
<div class="flex-group-left flexcol">
<ol class="carac-list alterne-list">
{{#each data.carac as |carac key|}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
{{#if (eq key 'taille')}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label">{{carac.label}}</span>
{{else}}
<span class="carac-label flexrow" name="data.carac.{{key}}.label"><a
name={{key}}>{{carac.label}}</a></span>
{{/if}}
<input class="competence-value flexrow" type="text" name="data.carac.{{key}}.value"
value="{{carac.value}}" data-dtype="{{carac.type}}" />
</li>
{{/each}}
</ol>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-entitee.html"}}
</div>
<div class="flex-group-left flexcol">
<ol class="carac-list alterne-list">
<li class="caracteristique flexrow list-item">
<span class="carac-label flexrow" name="catEntite">Catégorie : </span>
<select name="data.definition.categorieentite" value="{{data.definition.categorieentite}}" data-dtype="String">
{{#select data.definition.categorieentite}}
<option value="cauchemar">Cauchemar</option>
<option value="reve">Rêve</option>
{{/select}}
</select>
</li>
<li class="caracteristique flexrow list-item">
<span class="carac-label flexrow" name="typeEntite">Type d'entité : </span>
<select name="data.definition.typeentite" value="{{data.definition.typeentite}}" data-dtype="String">
{{#select data.definition.typeentite}}
<option value="incarne">Incarnée</option>
<option value="nonincarne">Non Incarnée</option>
<option value="blurette">Blurete</option>
{{/select}}
</select>
</li>
{{#each data.attributs as |attr key|}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="data.attributs.{{key}}.label">{{attr.label}} : </span>
<span><input class="attribut-value flexrow" type="text" name="data.attributs.{{key}}.value"
value="{{attr.value}}" data-dtype="{{attr.type}}" /></span>
</li>
{{/each}}
<li class="caracteristique flexrow list-item" data-attribute="endurance">
<span class="competence-label flexrow" name="data.sante.endurance.label">Endurance : </span>
<span><input class="sante-value flexrow" type="text" name="data.sante.endurance.value"
value="{{data.sante.endurance.value}}" data-dtype="Number" /></span><span>/ </span>
<span><input class="sante-value flexrow" type="text" name="data.sante.endurance.max"
value="{{data.sante.endurance.max}}" data-dtype="Number" /></span>
</li>
</ol>
<div class="flex-group-left flexcol">
<div class="flex-group-left flexcol competence-column">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html"}}
</div>
</div>
</div>
</div>
{{!-- Compétences Tab --}}
<div class="tab competences" data-group="primary" data-tab="competences">
<div class="flexcol">
<div class="flex-group-left flexcol competence-column">
<ol class="item-list alterne-list">
{{#each competences as |comp key|}}
<li class="item flexrow list-item" data-item-id="{{comp._id}}">
<img class="sheet-competence-img" src="{{comp.img}}" />
<span class="competence-label"><a>{{comp.name}}</a></span>
<input class="competence-value creature-carac" type="text" compname="{{comp.name}}"
value="{{comp.data.carac_value}}" data-dtype="number" />
<input class="competence-value creature-niveau" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.data.niveau decimals=0 sign=true}}" data-dtype="number" />
<input class="competence-value creature-dommages" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.data.dommages decimals=0 sign=true}}" data-dtype="number" />
<div class="item-controls">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ol>
</div>
<div class="flex-group-left flexcol competence-column">
<ol class="item-list alterne-list">
{{#each possessions as |possession key|}}
<li class="item flexrow list-item" data-item-id="{{possession._id}}">
<img class="sheet-competence-img" src="{{possession.img}}" />
<span class="competence-label">{{possession.name}}</span>
<div class="item-controls">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ol>
</div>
</div>
</div>
{{!-- Biography Tab --}}
<div class="tab description" data-group="primary" data-tab="description">
<div class="form-group editor">
{{editor data.description target="system.description" button=true owner=owner editable=true}}
{{editor description target="system.description" button=true owner=owner editable=true}}
</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html"}}
</div>
</section>

View File

@ -1,28 +0,0 @@
<h3>Blessures:</h3>
<table class="table-container" role="table">
<thead>
<tr class="competence-header competence-title competence-label" >
<th></th>
<th>Loc.</th>
<th>Premiers soins</th>
<th>P.S. OK?</th>
<th>Soins complets</th>
<th>S.C. OK?</th>
<th>Age (jours)</th>
</tr>
</thead>
<tbody>
<tr class="table-row alterne-row" ><td/><td colspan="4">Légères</td></tr>
{{#each data.blessures.legeres.liste as |bless key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html" bless=bless key=key gravite="legere" title="Légère"}}
{{/each}}
<tr class="table-row alterne-row"><td/><td colspan="4">Graves</td></tr>
{{#each data.blessures.graves.liste as |bless key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html" bless=bless key=key gravite="grave" title="Grave"}}
{{/each}}
<tr class="table-row alterne-row"><td/><td colspan="4">Critiques</td></tr>
{{#each data.blessures.critiques.liste as |bless key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-blessure-partial.html" bless=bless key=key gravite="critique" title="Critique"}}
{{/each}}
</tbody>
</table>

View File

@ -1,6 +0,0 @@
{{#if options.isGM}}
<h3>Notes du MJ : </h3>
<div class="form-group editor">
{{editor system.notesmj target="system.notesmj" button=true owner=owner editable=editable}}
</div>
{{/if}}

View File

@ -1,13 +0,0 @@
{{#if calc.surprise}}{{calc.surprise}}! {{/if}}
{{#if effects}}
{{#each effects as |effect key|}}
<span class="active-effect" data-id="{{effect._id}}">
<img class="button-effect-img delete-active-effect" src="{{effect.icon}}" alt="{{localize effect.label}}" width="24" height="24" />
</span>
{{/each}}
{{#if options.isGM}}
<span class="enlever-tous-effets"><a>(enlever tout)</a></span>
{{/if}}
{{else}}
Aucun effet actif
{{/if}}

View File

@ -1,52 +0,0 @@
<li class="item flexrow list-item" data-item-id="{{item._id}}" draggable="true">
{{#if (eq item.type 'conteneur')}}
<span class="sheet-competence-img conteneur-name">
{{#if vide}}
<i class="far fa-square"></i>
{{else}}
<a data-item-id="{{item._id}}">
{{#if ouvert}}
<i class="far fa-minus-square"></i>
<!-- <i class="far fa-caret-square-down"></i> -->
{{else}}
<i class="far fa-plus-square"></i>
<!-- <i class="fas fa-caret-square-right"></i> -->
{{/if}}
</a>
{{/if}}
</span>
<span class="item-name conteneur-name flex-grow">
<a data-item-id="{{item._id}}">
<img class="sheet-competence-img" src="{{item.img}}" title="{{item.name}}"/>
{{item.name}}
</a>
</span>
{{else}}
<img class="sheet-competence-img" src="{{item.img}}" title="{{item.name}}"/>
<span class="item-name flex-grow">{{item.name}}</span>
{{/if}}
<span class="item-quantite">{{item.system.quantite}}
{{#if (gt item.system.quantite 1)}}
<a class="item-control item-split" title="Séparer"><i class="fas fa-unlink"></i></a>
{{/if}}
</span>
<span class="item-quantite">{{numberFormat item.system.encTotal decimals=2}}</span>
<div class="item-controls flex-grow">
{{#unless item.estContenu}}
{{#if (ne item.type 'conteneur')}}
<a class="item-control item-equip" title="Equiper">{{#if item.system.equipe}}<i class="fas fa-hand-rock"></i>{{else}}<i class="far fa-hand-paper"></i>{{/if}}</a>
{{/if}}
{{/unless}}
<a class="item-control item-edit" title="Editer"><i class="fas fa-edit"></i></a>
<a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
{{#if (or (eq item.type 'arme') (eq item.type 'conteneur') item.system.quantite)}}
&nbsp;
<a class="item-control item-vendre" title="Vendre ou donner"><i class="fas fa-comments-dollar"></i></a>
{{/if}}
<a class="item-control item-montrer" title="Montrer"><i class="fas fa-comment"></i></a>
{{#if item.system.actionPrincipale}}
<a class="item-name item-action">{{item.system.actionPrincipale}}</a>
{{/if}}
</div>
</li>

View File

@ -1,26 +0,0 @@
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-monnaie.html" monnaie=monnaie}}
<span class="item-name"><h4>Equipement</h4></span>
<span class="item-name">Encombrement total/max : {{numberFormat calc.encTotal decimals=2}} / {{data.attributs.encombrement.value}} <b>{{calc.surEncombrementMessage}}</b></span> -
<span class="item-name"><a class="creer-un-objet">Créer un objet</a></span>
{{#if options.isGM}}
<span class="item-name"> - <a id="nettoyer-conteneurs">Vider tout les conteneurs</a></span>
{{/if}}
<ul class="item-list alterne-list">
<li class="competence-header flexrow">
<span class="equipement-nom">Nom</span>
<span class="equipement-detail">Q.</span>
<span class="equipement-detail">Enc.</span>
<span class="equipement-actions">Actions</span>
</li>
{{#each objets as |item id|}}
{{#unless item.estContenu}}
{{#if (ne item.type 'conteneur')}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire-item.html" item=item vide=true ouvert=true }}
{{/if}}
{{/unless}}
{{/each}}
{{#each conteneurs as |conteneur id|}}
{{buildConteneur this}}
{{/each}}
</ul>

View File

@ -1,15 +0,0 @@
<span class="item-name"><h4>Véhicules</h4></span>
<ul class="item-list alterne-list">
{{#each subacteurs.vehicules as |vehicule id|}}
<li class="item flexrow list-item" data-actor-id="{{vehicule.id}}">
<img class="sheet-competence-img" src="{{vehicule.img}}" title="{{vehicule.name}}"/>
<span class="flex-grow subacteur-label"><a>{{vehicule.name}}</a></span>
<span>{{vehicule.categorie}}</span>
<span>{{vehicule.structure}}</span>
<div class="flex-shrink">
<a class="subacteur-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>

View File

@ -8,69 +8,11 @@
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name"/></h1>
</div>
<div class="flexrow">
<ul class="flex-group-center flex-compteurs">
<li>
<label class="compteur">
<a class="jet-vie">Vie</a>
<a class="vie-moins"><i class="fas fa-minus-square"></i></a>
<input class="resource-content" type="text" name="data.sante.vie.value" value="{{data.sante.vie.value}}" data-dtype="Number"/>
<span>/ {{data.sante.vie.max}}</span>
<a class="vie-plus"><i class="fas fa-plus-square"></i></a>
</label>
</li>
<li>
<label class="compteur">
<a class="jet-endurance">Endurance</a>
<a class="endurance-moins"><i class="fas fa-minus-square"></i></a>
<input class="resource-content" type="text" name="data.sante.endurance.value" value="{{data.sante.endurance.value}}" data-dtype="Number"/>
<span>/ {{data.sante.endurance.max}}</span>
<a class="endurance-plus"><i class="fas fa-plus-square"></i></a>
</label>
</li>
<li>
<label class="appliquerFatigue compteur tooltip">
<span class="tooltiptext ttt-fatigue">{{{calc.fatigue.html}}}</span>
Fatigue
<a class="fatigue-moins"><i class="fas fa-minus-square"></i></a>
<input class="resource-content" id="fatigue-value" type="text" name="data.sante.fatigue.value" value="{{data.sante.fatigue.value}}" data-dtype="Number" />
<span>/ {{data.sante.fatigue.max}}</span>
<a class="fatigue-plus"><i class="fas fa-plus-square"></i></a>
</label>
</li>
<li>
<label class="compteur">
<span class="ptreve-actuel"><a>Rêve</a></span>
<a class="ptreve-actuel-moins"><i class="fas fa-minus-square"></i></a>
<input class="resource-content" id="pointsreve-value" type="text" name="data.reve.reve.value" value="{{data.reve.reve.value}}" data-dtype="Number" />
<span>/ {{data.reve.seuil.value}}</span>
<a class="ptreve-actuel-plus"><i class="fas fa-plus-square"></i></a>
</label>
</li>
</ul>
<div class="flex-group-center flex-actions-bar">
<div>
<span class="encaisser-direct"><a title="Encaisser des dommages"><img class="button-img" src="icons/svg/bones.svg" alt="Encaisser des dommages"/></a></span>
<span class="gm-only remise-a-neuf"><a title="Remise à neuf"><img class="button-img" src="icons/svg/regen.svg" alt="Remise à neuf"/></a></span>
<span class="repos"><a title="Repos"><img class="button-img" src="icons/svg/sleep.svg" alt="Se reposer"/></a></span>
{{#if data.attributs.hautrevant.value}}
<span class="monte-tmr"><a title="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" alt="Montée dans les Terres M&eacute;dianes !"/></a></span>
<span class="monte-tmr-rapide"><a title="Montée accélérée dans les Terres M&eacute;dianes !"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-rapide.svg" alt="Montée accélérée dans les Terres M&eacute;dianes !"/></a></span>
<span class="visu-tmr"><a title="Regarder les Terres M&eacute;dianes"><img class="button-img" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon-tmr-view.svg" alt="Regarder les Terres M&eacute;dianes"/></a></span>
{{/if}}
</div>
<div class="flexrow">
<span class="appliquerFatigue tooltip tooltip-dotted">Malus de fatigue : {{calc.fatigue.malus}}
<span class="tooltiptext ttt-fatigue">{{{calc.fatigue.html}}}</span>
</span>
<span>{{calc.resumeBlessures}}</span>
</div>
<div class="flexrow">
<span>{{data.compteurs.etat.label}}: {{data.compteurs.etat.value}}</span>
<span>{{data.compteurs.surenc.label}}: {{data.compteurs.surenc.value}}</span>
</div>
<div class="flexrow">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-effects-partial.html"}}
</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.html"}}
<div class="flex-group-center">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-buttons.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html"}}
</div>
</div>
</div>
@ -85,589 +27,105 @@
<a class="item" data-tab="hautreve">Haut-Rêve</a>
<a class="item" data-tab="items">Équipement</a>
<a class="item" data-tab="description">Description</a>
</nav>
{{!-- Sheet Body --}}
<section class="sheet-body">
</nav>
{{!-- Sheet Body --}}
<section class="sheet-body">
{{!-- Carac Tab --}}
<div class="tab items" data-group="primary" data-tab="carac">
<div class="flexrow">
<span><a class="lock-unlock-sheet"><img class="small-button-container"
src="systems/foundryvtt-reve-de-dragon/icons/{{#if options.editCaracComp}}unlocked.svg{{else}}locked.svg{{/if}}" alt="blocker/débloquer"
>{{#if options.editCaracComp}}Verrouiller{{else}}Déverrouiller{{/if}}</a></span>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
</div>
<div class="grid grid-2col">
<div class="flex-group-left flexcol">
<ul class="carac-list alterne-list">
{{#each data.carac as |carac key|}}
{{#if carac.isLevelUp}}
<li class="caracteristique flexrow item-list xp-level-up" data-attribute="{{key}}">
{{else}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
{{/if}}
{{#if (eq key 'taille')}}
<span class="carac-label" name="data.carac.{{key}}.label">{{carac.label}}</span>
<input class="carac-value" type="text" name="data.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
<label class="carac-xp"/>
{{else}}
{{#if carac.derivee}}
<span class="carac-label" name="data.carac.{{key}}.label"> <a name={{key}}>{{carac.label}}</a></span>
<label class="competence-value">{{carac.value}}</label>
<label class="carac-xp"/>
{{else}}
{{#if carac.isLevelUp}}
<span class="carac-label tooltip" name="data.carac.{{key}}.label">
<span class="tooltiptext ttt-xp">
Vous pouvez dépenser {{carac.xpNext}} points d'Experience pour augmenter de 1 votre caractéristique {{carac.label}}
</span>
<a name={{key}}>{{carac.label}}</a></span>
{{else}}
<span class="carac-label tooltip" name="data.carac.{{key}}.label"><a name={{key}}>{{carac.label}}</a></span>
{{/if}}
<input class="carac-value" type="text" name="data.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
<span class="carac-xp tooltip">
<input class="carac-xp" type="text" name="data.carac.{{key}}.xp" value="{{carac.xp}}" data-dtype="number" {{#unless @root.options.editCaracComp}}disabled{{/unless}} />
<span class="tooltiptext ttt-xp">Vous devez acquérir {{carac.xpNext}} points d'Experience pour augmenter de 1 votre {{carac.label}}</span>
</span>
{{#if carac.isLevelUp}}
<a class="carac-xp-augmenter" name="augmenter.{{key}}" title="Augmenter">
<i class="fas fa-arrow-alt-circle-up"></i>
</a>
{{/if}}
{{/if}}
{{/if}}
</li>
{{/each}}
<li class="caracteristique flexrow">
<span class="carac-label" name="carac-total">Total Caractéristiques </span>
<span class="competence-value total" name="carac-total-value">{{calc.caracTotal}} </span>
</li>
</ul>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html"}}
</div>
<div class="flex-group-left flexcol" >
<ul class="carac-list">
<li class="caracteristique flexrow list-item">
<span class="carac-label" name="beaute">Beauté&nbsp;:</span>
<input class="description-value" type="text" name="data.beaute" value="{{data.beaute}}" data-dtype="String" {{#unless @root.options.editCaracComp}}disabled{{/unless}}/>
<label class="carac-xp"/>
</li>
{{#each data.attributs as |attr key|}}
{{#unless (eq key 'hautrevant')}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label" name="data.attributs.{{key}}.label">{{attr.label}}&nbsp;:</span>
{{#if (eq key 'protection')}}
<input class="description-value" id="attribut-protection-edit" type="text" name="{{key}}" value="{{attr.value}}" data-dtype="number"/>
{{else}}
<input class="description-value" type="text" disabled name="data.attributs.{{key}}." value="{{attr.value}}" data-dtype="number"/>
{{/if}}
<label class="carac-xp"/>
</li>
{{/unless}}
{{/each}}
</ul>
<ul class="carac-list alterne-list">
<li class="caracteristique flexrow list-item">
<span class="attribut-label chance-actuelle"><a>Chance actuelle</a></span>
<input class="description-value compteur-edit" type="text" name="chance" value="{{data.compteurs.chance.value}}" data-dtype="number"/>
<span class="utiliser-attribut" style="padding-left: 5px"><a class="chance-appel">Utiliser</a></span>
</li>
{{#each data.compteurs as |compteur key|}}
{{#if (eq compteur.label 'Chance')}}
{{else if (eq compteur.label 'Experience')}}
{{else if compteur.isInput}}
<li class="caracteristique flexrow list-item">
<span class="attribut-label">{{compteur.label}}</span>
{{#if (eq compteur.label 'Ethylisme')}}
<select class="description-value" name="data.compteurs.ethylisme.value" id="ethylisme" data-dtype="Number">
{{#select compteur.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html"}}
{{/select}}
</select>
{{else}}
<input class="description-value compteur-edit" id="{{key}}-edit" type="text" name="{{key}}" value="{{compteur.value}}" data-dtype="number"/>
{{/if}}
<span class="utiliser-attribut" style="padding-left: 5px">
{{#if compteur.isStress}}
<a class="stress-test" title="Transformer">Transformer</a>
{{else if (eq compteur.label 'Ethylisme')}}
<a class="ethylisme-test" id="ethylisme-test" title="Jet d'Ethylisme">Boire</a>
{{else if (eq compteur.label 'Moral')}}
<a class="moral-malheureux" title="Jet de moral situation malheureuse"><img class="small-button-container" src="systems/foundryvtt-reve-de-dragon/icons/moral-malheureux.svg" alt="Jet de moral situation malheureuse"/></a>
<a class="moral-neutre" title="Jet de moral situation neutre"><img class="small-button-container" src="systems/foundryvtt-reve-de-dragon/icons/moral-neutre.svg" alt="Jet de moral situation neutre"/></a>
<a class="moral-heureux" title="Jet de moral situation heureuse"><img class="small-button-container" src="systems/foundryvtt-reve-de-dragon/icons/moral-heureux.svg" alt="Jet de moral situation heureuse"/></a>
{{else}}
<label></label>
{{/if}}
</span>
</li>
{{/if}}
{{/each}}
</ul>
<!-- <ul class="carac-list"></ul>-->
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html"}}
</div>
</div>
</div>
{{!-- Compétences Tab --}}
<div class="tab competences" data-group="primary" data-tab="competences">
<div class="grid grid-4col">
<span><a class="lock-unlock-sheet"><img class="small-button-container"
src="systems/foundryvtt-reve-de-dragon/icons/{{#if options.editCaracComp}}unlocked.svg{{else}}locked.svg{{/if}}" alt="blocker/débloquer">
{{#if options.editCaracComp}}Verrouiller{{else}}Déverrouiller{{/if}}</a></span>
<span>
<input class="recherche flex-grow" type="text" value="{{options.recherche.text}}" name="recherche"
size="8" data-dtype="String" placeholder="chercher"/>
<div class="flexrow">
<span><a class="vue-detaillee">
<i class="fas {{#if options.vueDetaillee}}fa-eye-slash{{else}}fa-eye{{/if}}"></i>
{{#if options.vueDetaillee}}Vue simplifiée{{else}}Vue détaillée{{/if}}</a>
</span>
<span><a class="show-hide-competences"><img class="small-button-container"
src="systems/foundryvtt-reve-de-dragon/icons/{{#if options.showCompNiveauBase}}no-filter.svg{{else}}filter.svg{{/if}}" alt="filter/montrer tout">
{{#if options.showCompNiveauBase}}Montrer tout{{else}}Filtrer{{/if}}</a>
</span>
<span><a class="vue-detaillee">
<i class="fas {{#if options.vueDetaillee}}fa-eye-slash{{else}}fa-eye{{/if}}"></i>
{{#if options.vueDetaillee}}Vue simplifiée{{else}}Vue détaillée{{/if}}</a>
<span class="flexrow">
<i class="fas fa-search flex-shrink"></i>
<input class="recherche flex-grow" type="text" value="{{options.recherche.text}}" name="recherche"
size="8" data-dtype="String" placeholder="chercher"/>
</span>
<span>
</span>
</div>
<div class="grid grid-2col">
<div class="flex-group-left flexcol competence-column">
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.generale) categorie="Compétences générales"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.particuliere) categorie="Compétences Particulières"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.specialisee) categorie="Compétences Spécialisées"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.generale) categorie="Compétences générales"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.particuliere) categorie="Compétences Particulières"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.specialisee) categorie="Compétences Spécialisées"}}
</div>
<div class="flex-group-left flexcol competence-column">
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.melee) categorie="Compétences de Mêlée"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.tir) categorie="Compétences de Tir"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.lancer) categorie="Compétences de Lancer"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.connaissance) categorie="Connaissances"}}
{{#if (or data.attributs.hautrevant.value options.vueDetaillee)}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-categorie-competences-partial.html" competences=(filtreTriCompetences competenceByCategory.draconic) categorie="Draconic"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.melee) categorie="Compétences de Mêlée"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.tir) categorie="Compétences de Tir"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.lancer) categorie="Compétences de Lancer"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.connaissance) categorie="Connaissances"}}
{{#if (or system.attributs.hautrevant.value options.vueDetaillee)}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html" competences=(filtreTriCompetences byCateg.draconic) categorie="Draconic"}}
{{/if}}
<div>
<ul class="item-list">
<li class="item flexrow">
<span class="generic-label">Stress transformé</span>
<input class="compteur-edit" type="text" name="experience" value="{{data.compteurs.experience.value}}" data-dtype="number" size="3"/>
</li>
<li class="item flexrow">
<span class="generic-label">Total XP compétences</span>
<span class="competence-value">{{calc.competenceXPTotal}}</span>
</li>
{{#if options.vueDetaillee}}
<li>Niveaux d'archétype à répartir</li>
{{#each calc.comptageArchetype as |archetype key|}}
{{#if (lt archetype.nombre archetype.nombreMax)}}
<li class="item flexrow">
<label class="generic-label">Archetype {{archetype.niveau}} : {{archetype.nombre}} / {{archetype.nombreMax}}</label>
</li>
{{/if}}
{{/each}}
{{/if}}
</ul>
</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html"}}
</div>
</div>
</div>
{{!-- Combat Tab --}}
<div class="tab combat" data-group="primary" data-tab="combat">
<h3 class="blessures-title">Armes et Défenses:</h3>
<ul class="item-list alterne-list">
<li class="competence-header flexrow">
<span class="competence-title competence-label">Armes</span>
<span class="competence-title competence-label">Initiative</span>
<span class="competence-title competence-label">Comp.</span>
<span class="competence-title competence-value">Niveau</span>
<span class="competence-title competence-value">+dom</span>
</li>
{{#each combat as |arme key|}}
<li class="item flexrow list-item" data-item-id="{{arme._id}}"
data-arme-name="{{arme.name}}" data-competence-name="{{arme.system.competence}}" >
<span class="arme-label">
<a>
{{#if arme.img}}
<img class="sheet-competence-img" src="{{arme.img}}"/>
{{/if}}
<span>{{arme.name}}</span>
</a>
</span>
<span class="arme-initiative"><a>{{arme.system.initiative}}</a></span>
<span class="competence-label">{{arme.system.competence}}</span>
<span class="competence-value">{{numberFormat arme.system.niveau decimals=0 sign=true}}</span>
<span class="competence-value">{{numberFormat arme.system.dommagesReels decimals=0 sign=true}}</span>
</li>
{{/each}}
{{#each esquives as |esq key|}}
<li class="item flexrow list-item">
<span class="competence-label">
<a class="competence-label" name="{{esq.name}}">
<img class="sheet-competence-img" src="{{esq.img}}"/>
<span>{{esq.name}}</span>
</a>
</span>
<span class="arme-initiative"></span>
<span class="competence-label"></span>
<span class="competence-value">{{numberFormat esq.data.niveau decimals=0 sign=true}}</span>
<span class="competence-value"></span>
</li>
{{/each}}
</ul>
<hr>
{{!-- Liste de blessures --}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-liste-blessures-partial.html" this}}
{{#if maladiesPoisons.length}}
{{!-- Maladies & Poison --}}
<h3 class="blessures-title">Maladies & Poisons:</h3>
<ul class="item-list alterne-list">
<li class="competence-header flexrow">
<span class="competence-title flex-grow competence-label">Nom</span>
<span class="competence-title competence-label">Type</span>
<span class="competence-title competence-value">Remèdes</span>
<span class="competence-title flex-grow competence-value">Edition</span>
</li>
{{#each maladiesPoisons as |maladie key|}}
<li class="item flexrow list-item" data-item-id="{{maladie._id}}">
<span class="competence-label">
{{#if (or @root.options.isGM maladie.data.identifie)}}
{{maladie.name}}
{{else}}
Inconnue
{{/if}}
</span>
<span class="competence-label">{{maladie.type}}</span>
<span class="competence-label">
{{#if (or @root.options.isGM maladie.data.remedesconnus)}}
{{maladie.data.remedes}}
{{else}}
Remèdes Inconnus
{{/if}}
</span>
<div class="item-controls">
<a class="item-edit" title="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{#if possessions.length}}
{{!-- Possession --}}
<h3 class="blessures-title">Possession:</h3>
<ul class="item-list alterne-list">
<li class="competence-header flexrow">
<span class="competence-title flex-grow competence-label">Nom</span>
<span class="competence-title competence-label">Type</span>
</li>
{{#each possessions as |possession key|}}
<li class="item flexrow list-item" data-item-id="{{possession._id}}">
<span class="competence-label">
<a class="sheet-possession-attack">{{possession.name}} (Conjurer)</a>
</span>
<span class="competence-label">{{possession.system.type}}</span>
<div class="item-controls">
<a class="item-edit" title="Modifier"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/combat.html"}}<hr>
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html"}}
</div>
{{!-- Connaissances Tab --}}
<div class="tab connaissances" data-group="primary" data-tab="connaissances">
<h3>Tâches</h3><a class='creer-tache'>Créer une nouvelle Tâche</a>
<ul class="item-list alterne-list">
{{#each taches as |tache id|}}
<li class="item flexrow list-item" data-item-id="{{tache._id}}"><span class="competence-title tache-label"><a>{{tache.name}}
({{tache.system.points_de_tache_courant}}{{#if
(or @root.options.isGM (not tache.system.cacher_points_de_tache))
}}/{{tache.system.points_de_tache}}{{/if}})</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
<hr>
<h3>Oeuvres diverses :</h3><a class="creer-une-oeuvre">Créer une oeuvre</a>
<ul class="item-list alterne-list">
{{#each chants as |chant id|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html" oeuvre=chant typeOeuvre="Chant" classOeuvre="chant-label"}}
{{/each}}
{{#each musiques as |musique id|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html" oeuvre=musique typeOeuvre="Musique" classOeuvre="musique-label"}}
{{/each}}
{{#each danses as |danse id|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html" oeuvre=danse typeOeuvre="Danse" classOeuvre="danse-label"}}
{{/each}}
{{#each oeuvres as |oeuvre id|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html" oeuvre=oeuvre typeOeuvre=oeuvre.system.competence classOeuvre="oeuvre-label"}}
{{/each}}
{{#each recettescuisine as |recette id|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-oeuvre-partial.html" oeuvre=recette typeOeuvre="Recette de cuisine" classOeuvre="recettecuisine-label"}}
{{/each}}
</ul>
<h3>Jeux :</h3>
<ul class="item-list alterne-list">
{{#each jeux as |jeu id|}}
<li class="item flexrow list-item" data-item-id="{{jeu._id}}"><span class="competence-title jeu-label"><a>{{jeu.name}} (base {{jeu.system.base}})</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
<h3>Recettes Alchimiques</h3>
<ul class="item-list alterne-list">
{{#each recettesAlchimiques as |recette id|}}
<li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
<hr>
<h3>Astrologie</h3>
<span class="astrologie-label"><a id="jet-astrologie">Astrologie : Nombres Astraux</a></span>
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/taches.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/jeux.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.html"}}
</div>
{{!-- hautreve Tab --}}
<div class="tab hautreve " data-group="primary" data-tab="hautreve" style="height:200px">
<div>
{{#if data.attributs.hautrevant.value}}
{{#if system.attributs.hautrevant.value}}
<h3>Haut rêvant</h3>
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.html"}}
{{else}}
<h3>Vous n'avez pas le don de haut-rêve! Il faut attribuer la Tête de Dragon 'Don de Haut Rêve' si votre personnage est ou devient Haut-Rêvant.</h3>
<h3>Vous n'avez pas le don de haut-rêve</h3>
<p>Attribuer la Tête de Dragon 'Don de Haut Rêve' pour rendre le personnage Haut-Rêvant.</p>
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.html"}}
{{/if}}
<ul class="item-list">
{{#if data.attributs.hautrevant.value}}
{{#if options.isGM}}
<li class="item flexrow">
<span>
<a class="chat-card-button forcer-tmr-aleatoire">Ré-insertion aléatoire (ie TMR cachée)</a>
</span>
<span>
<a class="chat-card-button afficher-tmr">Montrer les TMR</a>
</span>
</li>
{{/if}}
<li class="item flexrow">
{{#if options.isGM}}
<span class="competence-label flex-shrink">Demi rêve :
<span>{{caseTmr-label data.reve.tmrpos.coord}}</span>
</span>
<span>
<input class="competence-value" type="text" name="data.reve.tmrpos.coord" value="{{data.reve.tmrpos.coord}}" data-dtype="String"/>
</span>
{{else}}
<span class="competence-label flex-shrink">Demi rêve :
{{#unless hautreve.cacheTMR}}
<span>{{caseTmr-label data.reve.tmrpos.coord}}</span>
{{/unless}}
</span>
<span>
{{#if hautreve.cacheTMR}}
??
{{else}}
{{data.reve.tmrpos.coord}}
{{/if}}
</span>
{{/if}}
</li>
{{/if}}
<li class="item flexrow">
<span class="competence-label">Seuil de Rêve :</span>
<span>
{{#if options.isGM}}
<input class="seuil-reve-value" type="text" name="data.reve.seuil.value" value="{{data.reve.seuil.value}}" data-dtype="Number"/>
{{else}}
{{data.reve.seuil.value}}
{{/if}}
</span>
</li>
<li class="item flexrow" >
<span class="competence-label">Refoulement : </span>
<span>
{{#if options.isGM}}
<input class="competence-value" type="text" name="data.reve.refoulement.value" value="{{data.reve.refoulement.value}}" data-dtype="Number"/>
{{else}}
{{data.reve.refoulement.value}}
{{/if}}
</span>
</li>
</ul>
<br><br>
</div>
<hr>
{{!-- Queues, Souffles, Tetes, Ombre --}}
{{#if queues.length}}
<h3>Queues:</h3>
<ul class="flex-group-left">
{{#each queues as |queue key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{queue._id}}">
<span class="display-label flex-grow"><a data-item-id="{{queue._id}}">{{queue.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{#if ombres.length}}
<h3>Ombres de Thanatos:</h3>
<ul class="item-list">
{{#each ombres as |ombre key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{ombre._id}}">
<span class="display-label flex-grow"><a data-item-id="{{ombre._id}}">{{ombre.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{#if souffles.length}}
<h3>Souffles:</h3>
<ul class="item-list">
{{#each souffles as |souffle key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}">
<span class="display-label flex-grow"><a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{#if tetes.length}}
<h3>Tetes:</h3>
<ul class="item-list">
{{#each tetes as |tete key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}">
<span class="display-label flex-grow"><a data-item-id="{{tete._id}}">{{tete.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{#if data.attributs.hautrevant.value}}
{{#if (and options.isGM signesdraconiques.length)}}
<h3>Signes draconiques</h3>
<ul class="item-list alterne-list">
{{#each signesdraconiques as |signe key|}}
<li class="item list-item flexrow" data-item-id="{{signe._id}}" data-attribute="{{key}}">
<span class="display-label flex-grow"> <a data-item-id="{{signe._id}}">{{signe.name}}</a></span>
<span class="flex-shrink">{{signe.data.difficulte}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{#if hautreve.rencontres.length}}
<h3>Rencontres présentes:</h3>
<ul class="item-list">
{{#each hautreve.rencontres as |rencontre key|}}
<li class="item flexrow" data-item-id="{{key}}" data-attribute="{{key}}">
<span class="display-label"><a data-item-id="{{key}}">{{rencontre.name}} r{{rencontre.force}}</a></span>
<span class="flex-shrink">{{rencontre.coord}} - {{caseTmr-label rencontre.coord}}</span>
{{#if rencontre.date}}
<span>{{upperFirst rencontre.heure}}, le {{rencontre.date}}</span>
{{/if}}
<div class="item-controls flex-shrink">
<a class="rencontre-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
{{#if hautreve.sortsReserve.length}}
<h3>Sorts en Réserve:</h3>
<ul class="item-list alterne-list">
{{#each hautreve.sortsReserve as |reserve key|}}
<li class="item list-item flexrow" data-item-id="{{reserve._id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{reserve.sort.img}}" />
<span class="display-label">{{reserve.sort.name}} r{{reserve.sort.system.ptreve_reel}}</span>
<span>{{reserve.coord}} - {{caseTmr-label reserve.coord}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
<hr>
<h3>Sorts:</h3>
<ul class="item-list alterne-list">
{{#each sorts as |sort key|}}
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
<span class="display-label flex-grow">
<a data-item-id="{{sort._id}}">{{sort.name}}
- {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}}
</a>
</span>
<span>{{sort.system.draconic}} / {{sort.system.difficulte}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
<h3>Méditations:</h3>
<ul class="item-list">
{{#each meditations as |meditation key|}}
<li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}">
<span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.system.competence}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" title="Editer"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
<hr>
{{#if hautreve.casesTmr}}
<h3>Cases Spéciales:</h3>
<ul class="item-list">
{{#each hautreve.casesTmr as |casetmr key|}}
<li class="item flexrow" data-item-id="{{casetmr._id}}" data-attribute="{{key}}">
<span class="display-label"><a data-item-id="{{casetmr._id}}">{{casetmr.name}}</a></span>
<span>{{casetmr.system.coord}} - {{caseTmr-label casetmr.system.coord}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}
<br><br>
{{/if}}
</div>
{{!-- Equipment Tab --}}
<div class="tab items" data-group="primary" data-tab="items">
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-animaux.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-suivants.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-liens-vehicules.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html"}}
</div>
@ -676,50 +134,50 @@
<article class="flexrow">
<ul class="item-list alterne-list">
<li class="item flexrow list-item">
<label for="data.race">Race :</label>
<input class="flex-grow" type="text" name="data.race" value="{{data.race}}" data-dtype="String"/>
<label for="system.race">Race :</label>
<input class="flex-grow" type="text" name="system.race" value="{{system.race}}" data-dtype="String"/>
</li>
<li class="item flexrow list-item">
<label for="data.sexe">Sexe :</label>
<input class="flex-grow" type="text" name="data.sexe" value="{{data.sexe}}" data-dtype="String"/>
<label for="system.sexe">Sexe :</label>
<input class="flex-grow" type="text" name="system.sexe" value="{{system.sexe}}" data-dtype="String"/>
</li>
<li class="item flexrow list-item">
<label for="data.age">Age :</label>
<input class="flex-grow" type="text" name="data.age" value="{{data.age}}" data-dtype="String"/>
<label for="system.age">Age :</label>
<input class="flex-grow" type="text" name="system.age" value="{{system.age}}" data-dtype="String"/>
</li>
<li class="item flexrow list-item">
<label for="data.poids">Poids :</label>
<input class="flex-grow" type="text" name="data.poids" value="{{data.poids}}" data-dtype="String"/>
<label for="system.poids">Poids :</label>
<input class="flex-grow" type="text" name="system.poids" value="{{system.poids}}" data-dtype="String"/>
</li>
<li class="item flexrow list-item">
<label for="data.taille">Taille :</label>
<input class="flex-grow" type="text" name="data.taille" value="{{data.taille}}" data-dtype="String"/>
<label for="system.taille">Taille :</label>
<input class="flex-grow" type="text" name="system.taille" value="{{system.taille}}" data-dtype="String"/>
</li>
</ul>
<ul class="item-list alterne-list">
<li class="item flexrow list-item">
<label for="data.main">Main directrice :</label>
<input type="text" name="data.main" value="{{data.main}}" data-dtype="String"/>
<label for="system.main">Main directrice :</label>
<input type="text" name="system.main" value="{{system.main}}" data-dtype="String"/>
</li>
<li class="item flexrow list-item">
<label for="data.heure">Heure de naissance :</label>
<select type="text" name="data.heure" value="{{data.heure}}" data-dtype="String">
{{#select data.heure}}
<label for="system.heure">Heure de naissance :</label>
<select type="text" name="system.heure" value="{{system.heure}}" data-dtype="String">
{{#select system.heure}}
{{>"systems/foundryvtt-reve-de-dragon/templates/heures-select-option.html"}}
{{/select}}
</select>
</li>
<li class="item flexrow list-item">
<label>Beauté :</label>
<input type="text" value="{{data.beaute}}" data-dtype="String" disabled/>
<input type="text" value="{{system.beaute}}" data-dtype="String" disabled/>
</li>
<li class="item flexrow list-item">
<label for="data.cheveux">Cheveux :</label>
<input class="flex-grow" type="text" name="data.cheveux" value="{{data.cheveux}}" data-dtype="String"/>
<label for="system.cheveux">Cheveux :</label>
<input class="flex-grow" type="text" name="system.cheveux" value="{{system.cheveux}}" data-dtype="String"/>
</li>
<li class="item flexrow list-item">
<label for="data.yeux">Yeux :</label>
<input class="flex-grow" type="text" name="data.yeux" value="{{data.yeux}}" data-dtype="String"/>
<label for="system.yeux">Yeux :</label>
<input class="flex-grow" type="text" name="system.yeux" value="{{system.yeux}}" data-dtype="String"/>
</li>
</ul>
</article>
@ -727,27 +185,14 @@
<article class="flexcol">
<h3>Biographie : </h3>
<div class="form-group editor">
{{editor data.biographie target="system.biographie" button=true owner=owner editable=editable}}
{{editor biographie target="system.biographie" button=true owner=owner editable=editable}}
</div>
<h3>Notes : </h3>
<div class="form-group editor">
{{editor data.notes target="system.notes" button=true owner=owner editable=editable}}
{{editor notes target="system.notes" button=true owner=owner editable=editable}}
</div>
<h3>Journal d'Experience</h3>
<div class="form-group editor">
<ul class="item-list alterne-list">
{{#each data.experiencelog as |xp key|}}
<li class="item flexrow list-item">
<label class="flex-shrink">{{xp.mode}} </label>
<label class="flex-grow">{{xp.valeur}} {{xp.raison}} </label>
<label class="flex-shrink">{{xp.daterdd}} </label>
<label class="flex-shrink">{{xp.datereel}} </label>
</li>
{{/each}}
</ul>
</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.html"}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html"}}
</article>
</div>

View File

@ -12,74 +12,78 @@
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="carac">Caractéristiques</a>
<a class="item" data-tab="items">Contenu</a>
<a class="item" data-tab="description">Description</a>
<a class="item" data-tab="items">Chargement</a>
</nav>
{{!-- Sheet Body --}}
<section class="sheet-body">
{{!-- Carac Tab --}}
<div class="tab items" data-group="primary" data-tab="carac">
<div class="tab" data-group="primary" data-tab="description">
<div class="flexrow">
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html"}}
</div>
<div class="grid grid-2col">
<div class="flex-group-left flexcol">
<ol class="carac-list alterne-list">
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Catégorie</span>
<select name="data.categorie" class="categorie" data-dtype="String">
{{#select data.categorie}}
<li class="caracteristique flexrow list-item">
<span class="carac-label">Résistance</span>
<input class="competence-value" type="text" name="system.etat.resistance.value" value="{{system.etat.resistance.value}}" data-dtype="Number" />
/
<input class="competence-value" type="text" name="system.etat.resistance.max" value="{{system.etat.resistance.max}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
</li>
<li class="caracteristique flexrow list-item">
<span class="carac-label">Structure</span>
<input class="competence-value" type="text" name="system.etat.structure.value" value="{{system.etat.structure.value}}" data-dtype="Number" />
/
<input class="competence-value" type="text" name="system.etat.structure.max" value="{{system.etat.structure.max}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
</li>
</ol>
</div>
<div class="flex-group-left flexcol">
<ol>
<li class="caracteristique flexrow list-item">
<span class="carac-label">Catégorie</span>
<select name="system.categorie" class="categorie" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}>
{{#select system.categorie}}
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html"}}
{{/select}}
</select>
</li>
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Résistance</span>
<input class="competence-value flexrow" type="text" name="data.resistance" value="{{data.resistance}}" data-dtype="Number" />
<li class="caracteristique flexrow list-item">
<span class="carac-label">Vitesse</span>
<input class="caracteristique streched" type="text" name="system.vitesse" value="{{system.vitesse}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
</li>
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Structure</span>
<input class="competence-value flexrow" type="text" name="data.structure" value="{{data.structure}}" data-dtype="Number" />
<li class="caracteristique flexrow list-item">
<span class="carac-label">Bonus rames</span>
<input class="caracteristique streched" type="text" name="system.bonus" value="{{system.bonus}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
</li>
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Vitesse</span>
<input class="competence-value flexrow" type="text" name="data.vitesse" value="{{data.vitesse}}" data-dtype="String" />
<li class="caracteristique flexrow list-item">
<span class="carac-label">Manoeuvrabilité</span>
<input class="caracteristique streched" type="text" name="system.manoeuvrabilite" value="{{system.manoeuvrabilite}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
</li>
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Bonus</span>
<input class="competence-value flexrow" type="text" name="data.bonus" value="{{data.bonus}}" data-dtype="String" />
<li class="caracteristique flexrow list-item">
<span class="carac-label">Equipage</span>
<input class="caracteristique streched" type="text" name="system.equipage" value="{{system.equipage}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
</li>
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Manoeuvrabilité</span>
<input class="competence-value flexrow" type="text" name="data.manoeuvrabilite" value="{{data.manoeuvrabilite}}" data-dtype="String" />
</li>
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Equipage</span>
<input class="competence-value flexrow" type="text" name="data.equipage" value="{{data.equipage}}" data-dtype="Number" />
</li>
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label flexrow" name="categorie">Capacité d'Encombrement</span>
<input class="competence-value flexrow" type="text" name="data.capacite_encombrement" value="{{data.capacite_encombrement}}" data-dtype="Number" />
<li class="caracteristique flexrow list-item">
<span class="carac-label">Capacité d'Encombrement</span>
<input class="caracteristique streched" type="text" name="system.capacite_encombrement" value="{{system.capacite_encombrement}}" data-dtype="Number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
</li>
</ol>
</div>
</div>
<div class="form-group editor">
{{editor description target="system.description" button=true owner=owner editable=editable}}
</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html"}}
</div>
{{!-- Equipment Tab --}}
<div class="tab items" data-group="primary" data-tab="items">
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-inventaire.html"}}
{{!-- Biography Tab --}}
<div class="tab description" data-group="primary" data-tab="description">
<div class="form-group editor">
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
{{>"systems/foundryvtt-reve-de-dragon/templates/actor-sheet-editor-notes-mj.html"}}
</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html"}}
</div>
</section>

View File

@ -0,0 +1,13 @@
{{#if recettesAlchimiques.length}}
<h3>Recettes Alchimiques</h3>
<ul class="item-list alterne-list">
{{#each recettesAlchimiques as |recette id|}}
<li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
{{/if}}

View File

@ -0,0 +1,2 @@
<h3>Astrologie</h3>
<span class="astrologie-label"><a id="jet-astrologie">Astrologie : Nombres Astraux</a></span>

View File

@ -0,0 +1,27 @@
<li class="item flexrow list-item {{#if blessure.active}}blessure-active-{{gravite}}{{else}}blessure-inactive{{/if}}"
data-blessure-type="{{gravite}}"
data-attribute={{key}}
data-blessure-index="{{key}}"
data-blessure-active="{{blessure.active}}">
<span class="blessure-control" title="Blessure {{title}}">
<i class="fas fa-skull-crossbones" name="blessure-{{gravite}}-{{key}}-active"></i>
{{title}}
</span>
{{#if blessure.active}}
<span class="blessure-soins flexrow">
<input class="blessure-psdone" name="blessure-{{gravite}}-{{key}}-psdone" type="checkbox" name="blessure.psdone" {{#if blessure.psdone}}checked{{/if}}/>
<input class="blessure-premiers_soins" type="text" name="blessure-{{gravite}}-{{key}}-premiers_soins" data-dtype="number" value="{{blessure.premiers_soins}}"/>
</span>
<span class="blessure-soins flexrow">
<input class="blessure-scdone" name="blessure-{{gravite}}-{{key}}-scdone" type="checkbox" name="blessure.scdone" {{#if blessure.scdone}}checked{{/if}}/>
<input class="blessure-soins_complets" type="text" name="blessure-{{gravite}}-{{key}}-soins_complets" data-dtype="number" value="{{blessure.soins_complets}}"/>
</span>
<input class="blessure-jours" type="text" name="blessure-{{gravite}}-{{key}}-jours" name="jours" data-dtype="number" value="{{blessure.jours}}"/>
<input class="blessure-localisation" type="text" name="blessure-{{gravite}}-{{key}}-localisation" data-dtype="String" value="{{blessure.loc}}"/>
{{else}}
<span></span>
<span></span>
<span></span>
<span></span>
{{/if}}
</li>

View File

@ -0,0 +1,18 @@
<ul class="item-list alterne-list">
<li class="competence-header flexrow" >
<span>Blessures</span>
<span>Premiers soins</span>
<span>Soins complets</span>
<span>Age (jours)</span>
<span>Localisation</span>
</li>
{{#each system.blessures.legeres.liste as |blessure key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html" blessure=blessure key=key gravite="legere" title="Légère"}}
{{/each}}
{{#each system.blessures.graves.liste as |blessure key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html" blessure=blessure key=key gravite="grave" title="Grave"}}
{{/each}}
{{#each system.blessures.critiques.liste as |blessure key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/blessure.html" blessure=blessure key=key gravite="critique" title="Critique"}}
{{/each}}
</ul>

View File

@ -0,0 +1,8 @@
<ol class="carac-list alterne-list">
{{#each system.attributs as |attr key|}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label" name="system.attributs.{{key}}.label">{{attr.label}}</span>
<input class="caracteristique streched" type="text" name="system.attributs.{{key}}.value" value="{{attr.value}}" data-dtype="{{attr.type}}" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
</li>
{{/each}}
</ol>

View File

@ -0,0 +1,55 @@
<ul class="carac-list">
<li class="caracteristique flexrow list-item">
<span class="carac-label" name="beaute">Beauté&nbsp;:</span>
<input class="description-value" type="text" name="system.beaute" value="{{system.beaute}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
<label class="carac-xp"/>
</li>
{{#each system.attributs as |attr key|}}
{{#unless (eq key 'hautrevant')}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label" name="system.attributs.{{key}}.label">{{attr.label}}&nbsp;:</span>
{{#if (eq key 'protection')}}
<input class="description-value" id="attribut-protection-edit" type="text" name="{{key}}" value="{{attr.value}}" data-dtype="number"/>
{{else}}
<input class="description-value" type="text" disabled name="system.attributs.{{key}}." value="{{attr.value}}" data-dtype="number"/>
{{/if}}
<label class="carac-xp"/>
</li>
{{/unless}}
{{/each}}
</ul>
<ul class="carac-list alterne-list">
<li class="caracteristique flexrow list-item">
<span class="attribut-label chance-actuelle"><a>Chance actuelle</a></span>
<input class="description-value compteur-edit" type="text" name="chance" value="{{system.compteurs.chance.value}}" data-dtype="number"/>
</li>
{{#each system.compteurs as |compteur key|}}
{{#if (eq compteur.label 'Chance')}}
{{else if (eq compteur.label 'Experience')}}
{{else if compteur.isInput}}
<li class="caracteristique flexrow list-item">
<span class="attribut-label">{{compteur.label}}</span>
{{#if (eq compteur.label 'Ethylisme')}}
<select class="description-value" name="system.compteurs.ethylisme.value" id="ethylisme" data-dtype="Number">
{{#select compteur.value}}
{{>"systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html"}}
{{/select}}
</select>
{{else}}
<input class="description-value compteur-edit" id="{{key}}-edit" type="text" name="{{key}}" value="{{compteur.value}}" data-dtype="number"/>
{{/if}}
<span class="utiliser-attribut" style="padding-left: 5px">
{{#if compteur.isStress}}
<a class="stress-test" title="Transformer">Transformer</a>
{{else if (eq compteur.label 'Moral')}}
<a class="moral-malheureux" title="Jet de moral situation malheureuse"><img class="small-button-container" src="systems/foundryvtt-reve-de-dragon/icons/moral-malheureux.svg" alt="Jet de moral situation malheureuse"/></a>
<a class="moral-neutre" title="Jet de moral situation neutre"><img class="small-button-container" src="systems/foundryvtt-reve-de-dragon/icons/moral-neutre.svg" alt="Jet de moral situation neutre"/></a>
<a class="moral-heureux" title="Jet de moral situation heureuse"><img class="small-button-container" src="systems/foundryvtt-reve-de-dragon/icons/moral-heureux.svg" alt="Jet de moral situation heureuse"/></a>
{{else}}
<label></label>
{{/if}}
</span>
</li>
{{/if}}
{{/each}}
</ul>

View File

@ -0,0 +1,28 @@
{{log 'entitee.system' system}}
<ol class="carac-list alterne-list">
<li class="caracteristique flexrow list-item">
<span class="carac-label" name="catEntite">Catégorie : </span>
<select name="system.definition.categorieentite" value="{{system.definition.categorieentite}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}>
{{#select system.definition.categorieentite}}
<option value="cauchemar">Cauchemar</option>
<option value="reve">Rêve</option>
{{/select}}
</select>
</li>
<li class="caracteristique flexrow list-item">
<span class="carac-label" name="typeEntite">Type d'entité : </span>
<select name="system.definition.typeentite" value="{{system.definition.typeentite}}" data-dtype="String" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}>
{{#select system.definition.typeentite}}
<option value="incarne">Incarnée</option>
<option value="nonincarne">Non Incarnée</option>
<option value="blurette">Blurette</option>
{{/select}}
</select>
</li>
{{#each system.attributs as |attr key|}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
<span class="carac-label" name="system.attributs.{{key}}.label">{{attr.label}} : </span>
<input class="caracteristique streched" type="text" name="system.attributs.{{key}}.value" value="{{attr.value}}" data-dtype="{{attr.type}}" {{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
</li>
{{/each}}
</ol>

View File

@ -0,0 +1,41 @@
<ul class="carac-list alterne-list">
{{#each system.carac as |carac key|}}
{{#if carac.isLevelUp}}
<li class="caracteristique flexrow item-list xp-level-up" data-attribute="{{key}}">
{{else}}
<li class="caracteristique flexrow list-item" data-attribute="{{key}}">
{{/if}}
{{#if (eq key 'taille')}}
<span class="carac-label" name="system.carac.{{key}}.label">{{carac.label}}</span>
<input class="carac-value" type="text" name="system.carac.{{key}}.value" value="{{carac.value}}" data-dtype="{{carac.type}}" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
<label class="carac-xp"/>
{{else}}
{{#if carac.derivee}}
<span class="carac-label" name="system.carac.{{key}}.label"> <a name={{key}}>{{carac.label}}</a></span>
<label class="competence-value">{{carac.value}}</label>
<label class="carac-xp"/>
{{else}}
{{#if carac.isLevelUp}}
<span class="carac-label tooltip" name="system.carac.{{key}}.label">
<span class="tooltiptext ttt-xp">
Vous pouvez dépenser {{carac.xpNext}} points d'Experience pour augmenter de 1 votre caractéristique {{carac.label}}
</span>
<a name={{key}}>{{carac.label}}</a></span>
{{else}}
<span class="carac-label tooltip" name="system.carac.{{key}}.label"><a name={{key}}>{{carac.label}}</a></span>
{{/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}} />
<span class="carac-xp tooltip">
<input class="carac-xp" type="text" name="system.carac.{{key}}.xp" value="{{carac.xp}}" data-dtype="number" {{#unless @root.options.vueDetaillee}}disabled{{/unless}} />
<span class="tooltiptext ttt-xp">Vous devez acquérir {{carac.xpNext}} points d'Experience pour augmenter de 1 votre {{carac.label}}</span>
</span>
{{#if carac.isLevelUp}}
<a class="carac-xp-augmenter" name="augmenter.{{key}}" title="Augmenter">
<i class="fas fa-arrow-alt-circle-up"></i>
</a>
{{/if}}
{{/if}}
{{/if}}
</li>
{{/each}}
</ul>

View File

@ -0,0 +1,6 @@
<ul class="carac-list alterne-list">
<li class="caracteristique flexrow">
<span class="carac-label" name="carac-total">Total Caractéristiques </span>
<span class="competence-value total" name="carac-total-value">{{calc.caracTotal}} </span>
</li>
</ul>

View File

@ -0,0 +1,43 @@
<ul class="item-list alterne-list">
<li class="competence-header flexrow">
<span class="competence-title competence-label">Armes et Défenses</span>
<span class="competence-title competence-value">Niveau</span>
<span class="competence-title competence-value">+dom</span>
<span class="competence-title competence-value"></span>
<span class="competence-title initiative-value">Initiative</span>
</li>
{{#each combat as |arme key|}}
<li class="item flexrow list-item"
data-item-id="{{arme._id}}"
data-arme-name="{{arme.name}}"
data-competence-name="{{arme.system.competence}}" >
<span class="arme-label">
<a>
{{#if arme.img}}
<img class="sheet-competence-img" src="{{arme.img}}"/>
{{/if}}
<span>{{arme.name}}</span>
</a>
({{arme.system.competence}})
</span>
<span class="competence-value">{{numberFormat arme.system.niveau decimals=0 sign=true}}</span>
<span class="competence-value">{{numberFormat arme.system.dommagesReels decimals=0 sign=true}}</span>
<span class="competence-value"></span>
<span class="initiative-value arme-initiative"><a>{{arme.system.initiative}}</a></span>
</li>
{{/each}}
{{#each esquives as |esq key|}}
<li class="item flexrow list-item" data-item-id="{{esq._id}}">
<span class="competence-label">
<a class="competence-label" name="{{esq.name}}">
<img class="sheet-competence-img" src="{{esq.img}}"/>
<span>{{esq.name}}</span>
</a>
</span>
<span class="competence-value">{{numberFormat esq.system.niveau decimals=0 sign=true}}</span>
<span class="competence-value"></span>
<span class="competence-value"></span>
<span class="initiative-value"></span>
</li>
{{/each}}
</ul>

View File

@ -0,0 +1,26 @@
<ol class="item-list alterne-list">
{{#each competences as |comp key|}}
<li class="item flexrow list-item" data-item-id="{{comp._id}}">
<a class="competence-label">
<img class="sheet-competence-img" src="{{comp.img}}" />
<span>{{comp.name}}</span>
</a>
<input class="competence-value creature-carac" type="text" compname="{{comp.name}}"
value="{{comp.system.carac_value}}" data-dtype="number"
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
<input class="competence-value creature-niveau" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.system.niveau decimals=0 sign=true}}" data-dtype="number"
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
<input class="competence-value creature-dommages" type="text" compname="{{comp.name}}"
value="{{numberFormat comp.system.dommages decimals=0 sign=true}}" data-dtype="number"
{{#unless @root.options.vueDetaillee}}disabled{{/unless}}/>
{{#if @root.options.vueDetaillee}}
<div class="item-controls">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
{{/if}}
</li>
{{/each}}
</ol>

View File

@ -0,0 +1,16 @@
{{#if possessions}}
<div class="flex-group-left flexcol competence-column">
<ol class="item-list alterne-list">
{{#each possessions as |possession key|}}
<li class="item flexrow list-item" data-item-id="{{possession._id}}">
<img class="sheet-competence-img" src="{{possession.img}}" />
<span class="competence-label">{{possession.name}}</span>
<div class="item-controls">
<a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ol>
</div>
{{/if}}

View File

@ -6,7 +6,6 @@
<ul class="item-list alterne-list competence-list">
{{#if @root.options.vueDetaillee}}
<li class="item flexrow list-item ">
<span class="competence-label"></span>
<span class="competence-value" >Niv.</span>
<span class="competence-xp">xp</span>
@ -15,7 +14,7 @@
{{/if}}
<div class="item-controls">
<i class="far fa-arrow-alt-circle-up"></i>
<span class="competence-archetype">Arch</span>
<span class="competence-archetype">Arch.</span>
<i class="far fa-edit"></i>
{{#if @root.options.isGM}}
<i class="far fa-trash"></i>
@ -24,7 +23,7 @@
</li>
{{/if}}
{{#each competences as |comp key|}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor-sheet-competence-partial.html" comp}}
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/competence.html" comp}}
{{/each}}
</ul>
</div>

Some files were not shown because too many files have changed in this diff Show More