Compare commits
109 Commits
foundryvtt
...
foundryvtt
Author | SHA1 | Date | |
---|---|---|---|
18dfb36a78 | |||
febccd508f | |||
b147f8937b | |||
55a93b317a | |||
02a630152d | |||
ad8ac0de77 | |||
dceb6f026f | |||
ad37ee1b8e | |||
4d40e2fe59 | |||
9d7e57d9fb | |||
717029e572 | |||
d6f8976298 | |||
92e93cbbea | |||
994eaad9a9 | |||
cfed7e2afa | |||
436f9e6fa4 | |||
18a50197cd | |||
b6910612f8 | |||
4ba1ec8a2e | |||
75a0f7c322 | |||
e2a9f55740 | |||
1e0788cde8 | |||
c10195f753 | |||
4d7317b964 | |||
7b1fa009bb | |||
71bb8a14e1 | |||
5444bc7fd8 | |||
debaf1da34 | |||
69e2ab9000 | |||
24218ed062 | |||
da4e18dc3c | |||
154a9b7a37 | |||
fb8189606b | |||
cfbfad27bd | |||
f541849306 | |||
d2d1891838 | |||
5580b6d59c | |||
40c45c30de | |||
1b6c5256cc | |||
c0e6759164 | |||
a096590a07 | |||
9883048fb5 | |||
7bec42c4cf | |||
6708dc0da9 | |||
96c2da0d05 | |||
2b19250e8b | |||
957eabcac7 | |||
285937c201 | |||
93965ce91a | |||
18aba9adff | |||
0a5662ff71 | |||
bf98e4eae2 | |||
e32a1d25f6 | |||
327943c4aa | |||
de56fa909a | |||
2aa62cffe9 | |||
c57f140c54 | |||
9cf14f8b75 | |||
b8e7b21e14 | |||
c1d02d9fda | |||
23af30a538 | |||
4e1b663dec | |||
c9d98c57da | |||
0aef139cf8 | |||
9c85293714 | |||
ab1c04ae17 | |||
a585e0faba | |||
50c730ba72 | |||
928a60f092 | |||
e5c2f52b0e | |||
f9391523f8 | |||
55434762f4 | |||
5e6ffc7846 | |||
3344e20936 | |||
5a66e4e741 | |||
d329724d63 | |||
8a5405c9f5 | |||
ea992aae46 | |||
0bfcfec58f | |||
88e00c59bc | |||
d314dc39a0 | |||
30bb803da2 | |||
dd79e16ea5 | |||
83e2d56fd4 | |||
afc23dfa7b | |||
3e189cbe5f | |||
d0475e8677 | |||
a3694c1673 | |||
9e6d5856b1 | |||
acc880b53f | |||
2598ae3489 | |||
4f5fb63751 | |||
d739a7993a | |||
41335cd433 | |||
e470d76ea0 | |||
ffccc819f1 | |||
45bfc69b39 | |||
79e9358072 | |||
5cab418e62 | |||
7809f7c21a | |||
1bac204071 | |||
3bf5beb67b | |||
ac1da6e979 | |||
67735197bc | |||
f81dc9a5f5 | |||
a563233d6b | |||
0c11013694 | |||
77cf72a752 | |||
42ed5da2d4 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
.vscode/settings.json
|
||||
.idea
|
||||
.history
|
||||
todo.md
|
||||
/.vscode
|
||||
/ignored/
|
||||
|
270
changelog.md
270
changelog.md
@ -1,10 +1,266 @@
|
||||
==================================================================
|
||||
v0.9.2 - 05/09/2020
|
||||
---
|
||||
|
||||
Erreur de calcul sur points de vie
|
||||
Gestion différente des compétences "troncs"
|
||||
# v11.0
|
||||
|
||||
==================================================================
|
||||
v0.9.1 - 03/09/2020
|
||||
# v10.7 - L'os de Semolosse
|
||||
|
||||
Initial official release
|
||||
## v10.7.14 - l'expérience de Semolosse
|
||||
- Affichage des personnages accordés sur les fiches des entités
|
||||
- Refonte du journal d'expérience
|
||||
- disponible pour les personnages des joueurs
|
||||
- explication "comptable" des changements (dépense ou ajout, changements de niveaux, ...)
|
||||
- tri alphabétique des différentes listes (sorts, recettes, oeuvres, ...)
|
||||
|
||||
## v10.7.13 - l'armure de Semolosse
|
||||
- Fix: en cas d'armure variable, la détérioration diminue le dé d'armure
|
||||
|
||||
## v10.7.12
|
||||
- Fix: si le MJ gère les changements de jours, l'option "sieste" de la fenêtre de repos est prise par défaut si chateau dormant n'est pas passé
|
||||
|
||||
## v10.7.11 - Le Pugilat de Semolosse
|
||||
- Fix sur la projection au sol.
|
||||
|
||||
## v10.7.10 - Le Pugilat de Semolosse
|
||||
- Gestion de l'empoignade
|
||||
- Corrections sur l'initiative
|
||||
- Correction sur l'equipement des vêtements et bijoux
|
||||
|
||||
## v10.7.9 - Le Pugilat de Semolosse
|
||||
|
||||
- Gestion assistée de l'empoignade
|
||||
1. On selectionne sa cible (ie le token qui va être empoigné)
|
||||
2. On lance une attaque avec l'"arme" _Empoignade_
|
||||
3. A ce stade, si la victime a une arme, on rappelle le point de règle d'engagement
|
||||
(page 134), et un bouton permet de confirmer l'empoignade
|
||||
4. L'empoigneur fait son jet
|
||||
5. Si réussite, l'empoigné peut se défendre, avec gestion du premier round d'engagement
|
||||
(ie Esquive autorisée ou pas)
|
||||
- 4 bis. et 5 bis. L'empoigné, à son tour, peut tenter de se libérer, toujours en cliquant sur l'action "Empoignade"
|
||||
6. Selon le résultat, incrément/décrément des points d'emp
|
||||
7. Retour en 4., ou si 2 points d'Emp, alors 8.
|
||||
8. Affichage des options disponibles pour l'empoigneur : perte d'endurance, projection au
|
||||
sol ou entrainer au sol. Ces 3 options sont gérées automatiquement ensuite, selon le
|
||||
bouton cliqué par l'empoigneur.
|
||||
|
||||
Les empoignades sont des "items" supprimées à la fin d'un combat, qui peuvent aussi être
|
||||
gérés par le MJ au cas ou. Hors combat, penser à les supprimer (ou commencer et
|
||||
arrêter un combat).
|
||||
|
||||
## v10.7.7 - Les bobos de Sémolosse
|
||||
- Mise à jour du texte de l'heure pour les joueurs
|
||||
- L'horloge n'empêche plus de sélectionner les tokens dessous
|
||||
- _Lecture & Détection d'Aura_ sous Hypnos sont des rituels
|
||||
- _Lire les étoiles_ pour les joueurs de nouveau fonctionnel
|
||||
- Ajout de logs pour comprendre un cas d'échec des achatVente
|
||||
|
||||
## v10.7.6 - L'origine des maux de Sémolosse
|
||||
- Calendrier
|
||||
- fix du ré-affichage de l'horloge qui ne marchait pas pour les joueurs
|
||||
- l'horloge ne se ferme plus sur Escape
|
||||
- amélioration d'affichage
|
||||
- couleurs jour/nuit plus marquées
|
||||
- Divers
|
||||
- correction de l'affichage de quantités diminuées d'herbes dans les contenants ouvert
|
||||
- ajout d'un bouton pour diminuer les quantités dans l'équipement (si quantité > 1)
|
||||
- ajout de la signature de l'acteur sur les blessures qu'il a causées
|
||||
|
||||
- Magie
|
||||
- correction des bonus de cases pour les sorts en Fleuve
|
||||
|
||||
## v10.7.5 - La montre-gousset de Sémolosse
|
||||
- Amélioration de la fenêtre calendrier
|
||||
* plus compacte
|
||||
* horloge analogique (optionnelle)
|
||||
* minimizable (juste la barre de titre)
|
||||
* normalement compatible pop-out
|
||||
|
||||
## v10.7.4 - Les ligatures de Sémolosse
|
||||
- Corrections diverses
|
||||
- Correction des boutons pour déclencher un sort en réserve avec réserve en sécurité ou réserve extensible
|
||||
- le lien pour les jets de vie suite à une blessure critique est remplacé par un bouton
|
||||
- déplacement des tâches et boutons de chirurgie dans l'onglet savoirs et tâches
|
||||
- correction de l'affichage des bonus de cases des sorts
|
||||
- corrections des queues non-refoulables dans le compendium
|
||||
|
||||
## v10.7.3 - Les tisanes de Sémolosse
|
||||
- Soins
|
||||
- on peut de nouveau boire une potion de soins enchantée
|
||||
- les potions non enchantées donnent de nouveau un bonus au prochain jet de récupération
|
||||
- Une fois les soins complets faits, le bonus aux soins complets fournis par les premiers soins est masqué
|
||||
|
||||
- Horloge
|
||||
- A l'heure de Couronne pile, les aiguilles des heures et des minutes pointent sur couronne (comme une montre) au lieu d'avoir l'aiguille des heures 15° à gauche
|
||||
|
||||
## v10.7.2 - les maux de dents de Semolosse
|
||||
- correction des récupérations de blessures
|
||||
- la fin de château dormant se passe normalement
|
||||
|
||||
## v10.7.1 - L'os de Semolosse
|
||||
- Fix rapide sur les jets de carac qui n'étaient plus possibles
|
||||
|
||||
## v10.7.0 - L'os de Semolosse
|
||||
- gestion des blessures en items
|
||||
- soins du token ciblé par menu contextuel (comme le combat)
|
||||
- automatisation des soins et de l'affichage de l'avancement des soins
|
||||
- support des changements d'opérants
|
||||
|
||||
---
|
||||
# v10.6 - Les recherches de Pralinor le Goûteux
|
||||
|
||||
## v10.6.25 - Fix sur l'astrologie
|
||||
|
||||
## v10.6.22 - le nuage de lait dans le thé de Pralinor
|
||||
- Amélioration de l'affichage de l'horloge
|
||||
- Fix: affichage des points de guérison dans les potions
|
||||
|
||||
## v10.6.21 - La théière de Pralinor
|
||||
- Astrologie
|
||||
- le thème astral est directement dans la fenêtre d'astrologie
|
||||
- la roue des heures sert d'horloge
|
||||
- sélectionner un personnage ajuste le thème astral pour son heure de naissance
|
||||
- sélectionner le nombre astral d'un jour ajuste le thème astral
|
||||
|
||||
- Fix: les PNJs peuvent de nouveau dormir
|
||||
|
||||
## v10.6.20 - Les Oracles de Pralinor: vous mangerez à Couronne
|
||||
- Ajout de la fenêtre pour effectuer un thème astral
|
||||
|
||||
## v10.6.19 - La cerise de Pralinor
|
||||
- les joueurs peuvent chercher dans les commerces avec un droit limité/observateur
|
||||
- simplifications des fins de tours et nombre d'utilisations
|
||||
- ajout du _Haubert d'Oniros_ dans le compendium de sorts
|
||||
|
||||
## v10.6.17 - Les désordres de Pralinor
|
||||
- le contenu des casseroles et autres contenants est maintenant trié dans l'ordre alphabétique
|
||||
- les objets dupliqués du compendium d'équipement sont de nouveaux uniques
|
||||
|
||||
## v0.6.16 - Le pardon de Pralinor
|
||||
- Ajout d'un commerce _Liste d'équipement_ dans les archétypes de PNJs
|
||||
- Séparations d'équipements groupés et corrections de quelques objets & herbes
|
||||
- On peut éditer les armes stockées dans un commerce
|
||||
|
||||
## v10.6.15 - les digestifs de Pralinor
|
||||
- amélioration des messages de sommeil (nombre d'heure dormies, uniquement les
|
||||
récupérations de rêve en dessous du seuil, affichage de la récupération d'endurance
|
||||
qui avait disparu, meilleur message sur le jet de moral)
|
||||
- les insomnies ne durent bien que 12h draconique à partir du prochain
|
||||
Chateau Dormant (elles pouvaient durer 3 nuits suite à une erreur).
|
||||
- la recherche dans l'équipement affiche correctement les conteneurs dans lesquels les
|
||||
objets trouvés sont rangés
|
||||
|
||||
## v10.6.14 - la digestion de Pralinor
|
||||
- Chateau dormant
|
||||
- la situation du jet de moral peut être choisie lorsque l'on dort
|
||||
- les queues de dragon "insomnie" empêchent de dormir, et de rêver
|
||||
- ajout d'une option pour meilleure gestion de Chateau Dormant par le MJ
|
||||
- avec cette option, à la fin Chateau Dormant, une fenêtre permet au gardien de
|
||||
positionner pour chaque joueur:
|
||||
- le stress de la journée
|
||||
- les heures de sommeil
|
||||
- la situation du jet de moral (neutre/heureux/malheureux)
|
||||
|
||||
- l'affichage des heures Chateau Dormant et Poisson Acrobate est correct
|
||||
- le jet de moral en situation neutre fait maintenant retourner le moral vers 0, et
|
||||
n'affecte plus un moral à 0.
|
||||
## v10.6.13 - la cave de Pralinor
|
||||
- on peut maintenant chercher dans l'inventaire des commerces
|
||||
- l'inventaire est correctement affiché en entier après suppression de la recherche
|
||||
- le message de chateau dormant reflète correctement un jet de moral neutre qui passe le moral de 0 à +1
|
||||
|
||||
## v10.6.12 - l'index de Pralinor
|
||||
- On peut désormais chercher dans l'inventaire comme dans les compétences
|
||||
|
||||
## v10.6.11 - l'empoisonnement de Pralinor
|
||||
- La récupération est bloquée par les maladies. Pas de récupération de vie ou de blessures possibles sous l'effet d'un poison ou d'une maladie
|
||||
- ajout d'un "poison" pour bloquer la récupération sous Griffe Morbide de Thanatos.
|
||||
Ajout du lien vers l'objet du compendium dans la description MJ,, qui pourra donc
|
||||
ajouter ce "poison" à la victime pour empêcher ses guérisons de vie ou blessure.
|
||||
|
||||
## v10.6.10
|
||||
- Correction de l'édition des description
|
||||
- Amélioration des descriptions d'alchimie:
|
||||
- difficulté calculée automatiquement
|
||||
- Température pour les couleurs
|
||||
- La sustentation n'est plus concaténée dans certains cas (ce qui donnait 2+2=22)
|
||||
|
||||
## v10.6.8 : les bon mots de Pralinor
|
||||
- Dans la fenêtre de _recherche et tirages_, possibilité de chercher sur le nom des objets en plus des autres critères
|
||||
|
||||
## v10.6.7 : les grumelés de Pralinor
|
||||
- les objets peuvent être utilisés depuis la fenêtre d'un conteneur
|
||||
- dans les fenêtres de contenants, le contenu est correctement indenté
|
||||
- la présentation du contenu d'un sac est améliorée
|
||||
- le bouton Nouvel Objet n'est affiché que si on est propriétaire de l'acteur
|
||||
- la fenêtre de vente permet de nouveau de choisir les quantités à vendre
|
||||
|
||||
## v10.6.6
|
||||
- Corrections d'armes rudimentaires
|
||||
- Inversion: Taille puis poids
|
||||
- Suppression d'une ligne de caractéristique vide (causée par la beauté)
|
||||
- Les messages liés aux compétences troncs deviennent des notifications
|
||||
## v10.6.5
|
||||
- Le +dom est de nouveau affiché
|
||||
- L'édition de caractéristiques des créatures fonctionne de nouveau
|
||||
|
||||
## v10.6.4 - La sénilité de Pralinor
|
||||
- Fenêtre _Recherches et tirages_
|
||||
- les résultats de recherches sur plusieurs compendiums sont triés
|
||||
- lors de recherches avec un ou des milieux sélectionnés:
|
||||
- le filtre sur la rareté utilise la rareté dans ces milieux
|
||||
- les tirages se basent sur la fréquence la plus élevées dans ces milieux
|
||||
- les filtres par utilisation prennent les potions en compte
|
||||
- les remèdes ont une catégorie de potion 'Remède' (et correspondent à une utilisation médicale)
|
||||
- ajout d'un filtre d'utilisation 'cuisine'
|
||||
|
||||
|
||||
# Divers
|
||||
- fix du cas où la transformation de 0 points de stress était concaténé, (passage de 29 à 290 avec 0 points transformés)
|
||||
- suppression du compendium de taches courantes, désormais inutile
|
||||
|
||||
## v10.6.3 - le baba-brandevin de Pralinor
|
||||
- les tâches de Soins sont maintenant déplacées à côté des blessures
|
||||
- on peut créer les tâches de soins directement avec un bouton par gravité.
|
||||
|
||||
- le round n'est plus bloqué si un acteur est sonné
|
||||
- un rare cas d'initiative négative pouvait empêcher de faire une initiative (à cause de l'état général)
|
||||
- dans une circonstance inconnue, une rencontre pouvait disparaître lors de la maîtrise. Ajout d'un message pour essayer d'obtenir des détails sur ce cas, et ajout d'une sécurité pour retrouver la rencontre (qui est conservée par la fenêtre de choix d'action).
|
||||
- les objets temporels (queues, souffles, poisons, maladies...) créés avant la gestion temporelle ne pouvaient pas être édités.
|
||||
- les particulières sur les jets de résistance de rêve actuel ne rapportent qu'un point d'expérience (p191)
|
||||
- pour lutter contre l'alcoolisme, les jets d'éthylisme sont considérés comme des jets de résistance, et n'apportent qu'un point d'expérience.
|
||||
## v10.6.2 - Le méli-mélo de Pralinor
|
||||
- Fenêtre _Recherches et tirages_
|
||||
- support de la recherche dans les compendiums choisis
|
||||
- suppression des commandes `/table milieu` et `/tirer milieu` (remplacées par la fenêtre de recherche)
|
||||
- ajout de fréquences à tous les équipements
|
||||
## v10.6.1 - Les recherches de Pralinor
|
||||
- Fenêtre _Recherches et tirages_
|
||||
- Amélioration des filtres de cuisine/utilisation
|
||||
- Ajout de catégories pour les poisons, urtiquants, ...
|
||||
- Bouton "Effacer les filtres" plus clair
|
||||
- Drag&drop depuis la recherche
|
||||
- Reprise du compendium
|
||||
- pour les plantes vénéneuses
|
||||
- pour les plantes venimeuses
|
||||
- ajout de sust pour les champignons et autres plantes comestibles
|
||||
|
||||
- Affichage de l'image du token pour les commerces non liés
|
||||
- Les pièces d'or sont appelées 'Dragon'
|
||||
|
||||
## v10.6.0 - Les recherches de Pralinor le Goûteux
|
||||
- Fenêtre _Recherches et tirages_
|
||||
- ajout de la fenêtre _Recherches et tirages_ avec filtres paramétrables
|
||||
- ouverture de la fenêtre: commande `/tirage` ou macro disponible dans les macros du système
|
||||
- support des équipements, faune & flore (depuis les compendiums configurés par défaut)
|
||||
- nombreux choix à activer
|
||||
- possibilité de montrer les objets correspondant à la sélection
|
||||
- possibilité de faire un tirage parmi ces objets (en prenant en compte la fréquence)
|
||||
|
||||
- Plantes & pèche
|
||||
- séparation des ingrédients et plantes comestibles
|
||||
- retour des poissons dans les compendiums
|
||||
- ajout d'un lien depuis les plantes toxiques/dangereuses vers la maladie/poison correspondante
|
||||
|
||||
- On peut de nouveau ouvrir les conteneurs dans une fenêtre séparée
|
||||
- Les jets de volontés d'éthylisme calculent correctement la difficulté liée au moral (ie: 0 au lieu de -22)
|
||||
- si le journal de chronologie est supprimée, on peut en choisir un autre
|
||||
- la taille du calendrier est ajustée pour éviter une présentation bancale quand le nom du mois est court
|
||||
|
BIN
icons/sante/blessure-mort.webp
Normal file
BIN
icons/sante/blessure-mort.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
BIN
icons/sante/blessure-soins.webp
Normal file
BIN
icons/sante/blessure-soins.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
BIN
icons/sante/blessure.webp
Normal file
BIN
icons/sante/blessure.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
icons/sante/eraflure.webp
Normal file
BIN
icons/sante/eraflure.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
icons/sante/mort.webp
Normal file
BIN
icons/sante/mort.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
101
lang/fr.json
101
lang/fr.json
@ -1,53 +1,56 @@
|
||||
{
|
||||
"ACTOR": {
|
||||
"TypePersonnage": "Personnage",
|
||||
"TypeCreature": "Créature",
|
||||
"TypeEntite": "Entité de cauchemar",
|
||||
"TypeCommerce": "Commerce",
|
||||
"TypeVehicule": "Véhicule"
|
||||
},
|
||||
"ITEM": {
|
||||
"TypeObjet": "Objet",
|
||||
"TypeGemme": "Gemme",
|
||||
"TypeCompetence": "Compétence",
|
||||
"TypeCompetencecreature": "Compétence de créature",
|
||||
"TypeMaladie": "Maladie",
|
||||
"TypePoison": "Poison",
|
||||
"TypeNombreastral": "Nombre astral",
|
||||
"TypeTarot": "Carte de tarot",
|
||||
"TypeCasetmr": "TMR spéciale",
|
||||
"TypeRencontre": "Rencontre TMR",
|
||||
"TypeMunition": "Munition",
|
||||
"TypeMonnaie": "Monnaie",
|
||||
"TypeHerbe": "Herbe",
|
||||
"TypePlante": "Plante",
|
||||
"TypeIngredient": "Ingrédient",
|
||||
"TypeFaune": "Faune",
|
||||
"TypeLivre": "Livre",
|
||||
"TypePotion": "Potion",
|
||||
"TypeArme": "Arme",
|
||||
"TypeArmure": "Armure",
|
||||
"TypeConteneur": "Conteneur",
|
||||
"TypeNourritureboisson": "Nourriture & boisson",
|
||||
"TypeService": "Service",
|
||||
"TypeChant": "Chant",
|
||||
"TypeDanse": "Danse",
|
||||
"TypeMusique": "Musique",
|
||||
"TypeOeuvre": "Oeuvre",
|
||||
"TypeTache": "Tâche",
|
||||
"TypeJeu": "Jeu",
|
||||
"TypeRecettealchimique": "Recette alchimique",
|
||||
"TypeRecettecuisine": "Recette de cuisine",
|
||||
"TypeSort": "Sort",
|
||||
"TypeMeditation": "Méditation",
|
||||
"TypeSignedraconique": "Signe draconique",
|
||||
"TypeQueue": "Queue de Dragon",
|
||||
"TypeOmbre": "Ombre de Thanatos",
|
||||
"TypeSouffle": "Souffle de Dragon",
|
||||
"TypeTete": "Tête de Dragon",
|
||||
"TypePossession": "Possession",
|
||||
"TypeSortreserve": "Sort en réserve",
|
||||
"TypeExtraitpoetique": "Extrait poetique"
|
||||
"TYPES": {
|
||||
"Actor": {
|
||||
"Personnage": "Personnage",
|
||||
"Creature": "Créature",
|
||||
"Entite": "Entité de cauchemar",
|
||||
"Commerce": "Commerce",
|
||||
"Vehicule": "Véhicule"
|
||||
},
|
||||
"Item": {
|
||||
"Arme": "Arme",
|
||||
"Armure": "Armure",
|
||||
"Blessure": "Blessure",
|
||||
"Casetmr": "TMR spéciale",
|
||||
"Chant": "Chant",
|
||||
"Competence": "Compétence",
|
||||
"Competencecreature": "Compétence de créature",
|
||||
"Conteneur": "Conteneur",
|
||||
"Danse": "Danse",
|
||||
"Extraitpoetique": "Extrait poetique",
|
||||
"Faune": "Faune",
|
||||
"Gemme": "Gemme",
|
||||
"Herbe": "Herbe",
|
||||
"Ingredient": "Ingrédient",
|
||||
"Jeu": "Jeu",
|
||||
"Livre": "Livre",
|
||||
"Maladie": "Maladie",
|
||||
"Meditation": "Méditation",
|
||||
"Monnaie": "Monnaie",
|
||||
"Munition": "Munition",
|
||||
"Musique": "Musique",
|
||||
"Nombreastral": "Nombre astral",
|
||||
"Nourritureboisson": "Nourriture & boisson",
|
||||
"Objet": "Objet",
|
||||
"Oeuvre": "Oeuvre",
|
||||
"Ombre": "Ombre de Thanatos",
|
||||
"Plante": "Plante",
|
||||
"Poison": "Poison",
|
||||
"Possession": "Possession",
|
||||
"Potion": "Potion",
|
||||
"Queue": "Queue de Dragon",
|
||||
"Recettealchimique": "Recette alchimique",
|
||||
"Recettecuisine": "Recette de cuisine",
|
||||
"Rencontre": "Rencontre TMR",
|
||||
"Service": "Service",
|
||||
"Signedraconique": "Signe draconique",
|
||||
"Sort": "Sort",
|
||||
"Sortreserve": "Sort en réserve",
|
||||
"Souffle": "Souffle de Dragon",
|
||||
"Tache": "Tâche",
|
||||
"Tarot": "Carte de tarot",
|
||||
"Tete": "Tête de Dragon"
|
||||
}
|
||||
},
|
||||
"EFFECT": {
|
||||
"StatusStunned": "Sonné",
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { RdDActorSheet } from "./actor-sheet.js";
|
||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
export class RdDActorEntiteSheet extends RdDActorSheet {
|
||||
|
||||
@ -13,6 +15,12 @@ export class RdDActorEntiteSheet extends RdDActorSheet {
|
||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
||||
});
|
||||
}
|
||||
async getData() {
|
||||
let formData = await super.getData();
|
||||
formData.resonances = this.actor.system.sante.resonnance.actors.map(actorId => game.actors.get(actorId))
|
||||
.map(actor => { return { id: actor.id, name: actor.name, img: actor.img } })
|
||||
return formData
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
@ -35,6 +43,23 @@ export class RdDActorEntiteSheet extends RdDActorSheet {
|
||||
let compName = event.currentTarget.attributes.compname.value;
|
||||
this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value));
|
||||
});
|
||||
this.html.find('.resonance-delete').click(async event => {
|
||||
const li = RdDSheetUtility.getEventElement(event);
|
||||
const actorId = li.data("actor-id");
|
||||
if (actorId) {
|
||||
const actorResonance = game.actors.get(actorId);
|
||||
RdDUtility.confirmerSuppressionSubacteur(this, actorResonance, li, () => {
|
||||
console.log('Delete : ', actorId);
|
||||
this.removeSubacteur(actorId);
|
||||
RdDUtility.slideOnDelete(this, li);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async removeSubacteur(actorId) {
|
||||
let newResonances = this.actor.system.sante.resonnance.actors.filter(id => id != actorId);
|
||||
await this.actor.update({ 'system.sante.resonnance.actors': newResonances }, { renderSheet: false });
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import { STATUSES } from "./settings/status-effects.js";
|
||||
import { MAINS_DIRECTRICES } from "./actor.js";
|
||||
import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDItemBlessure } from "./item/blessure.js";
|
||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
@ -82,6 +84,7 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
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);
|
||||
formData.empoignades = this.actor.getEmpoignades();
|
||||
|
||||
this.armesList = formData.combat;
|
||||
|
||||
@ -116,14 +119,21 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.options.editable) return;
|
||||
|
||||
this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor));
|
||||
this.html.find('.item-action').click(async event => {
|
||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
||||
item?.actionPrincipale(this.actor, async () => this.render())
|
||||
});
|
||||
|
||||
this.html.find('.subacteur-delete').click(async event => {
|
||||
const li = RdDSheetUtility.getEventElement(event);
|
||||
const actorId = li.data("actor-id");
|
||||
if (actorId) {
|
||||
const subActor = game.actors.get(actorId);
|
||||
RdDUtility.confirmerSuppressionSubacteur(this, subActor, li);
|
||||
RdDUtility.confirmerSuppressionSubacteur(this, subActor, li, () => {
|
||||
console.log('Delete : ', subActor.id);
|
||||
this.actor.removeSubacteur(subActor.id);
|
||||
RdDUtility.slideOnDelete(this, li);
|
||||
});
|
||||
}
|
||||
});
|
||||
this.html.find('.experiencelog-delete').click(async event => {
|
||||
@ -136,6 +146,13 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
const key = Number(li.data("key") ?? -1);
|
||||
await this.actor.deleteExperienceLog(0, key + 1);
|
||||
});
|
||||
this.html.find("input.derivee-value[name='system.compteurs.stress.value']").change(async event => {
|
||||
this.actor.updateCompteurValue("stress", parseInt(event.target.value));
|
||||
});
|
||||
this.html.find("input.derivee-value[name='system.compteurs.experience.value']").change(async event => {
|
||||
this.actor.updateCompteurValue("experience", parseInt(event.target.value));
|
||||
});
|
||||
|
||||
this.html.find('.encaisser-direct').click(async event => {
|
||||
this.actor.encaisser();
|
||||
})
|
||||
@ -151,42 +168,31 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
this.html.find('.creer-tache').click(async event => {
|
||||
this.createEmptyTache();
|
||||
});
|
||||
this.html.find('.creer-tache-blessure-legere').click(async event => {
|
||||
this.actor.createTacheBlessure('legere');
|
||||
});
|
||||
this.html.find('.creer-tache-blessure-grave').click(async event => {
|
||||
this.actor.createTacheBlessure('grave');
|
||||
});
|
||||
this.html.find('.creer-tache-blessure-critique').click(async event => {
|
||||
this.actor.createTacheBlessure('critique');
|
||||
});
|
||||
this.html.find('.creer-tache-blessure-legere').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 2));
|
||||
this.html.find('.creer-tache-blessure-grave').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 4));
|
||||
this.html.find('.creer-tache-blessure-critique').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 6));
|
||||
this.html.find('.creer-blessure-legere').click(async event => RdDItemBlessure.createBlessure(this.actor, 2));
|
||||
this.html.find('.creer-blessure-grave').click(async event => RdDItemBlessure.createBlessure(this.actor, 4));
|
||||
this.html.find('.creer-blessure-critique').click(async event => RdDItemBlessure.createBlessure(this.actor, 6));
|
||||
this.html.find('.creer-une-oeuvre').click(async event => {
|
||||
this.selectTypeOeuvreToCreate();
|
||||
});
|
||||
|
||||
// Blessure control
|
||||
this.html.find('.blessure-control').click(async event => {
|
||||
const tr = this.html.find(event.currentTarget).parents(".item");
|
||||
let btype = tr.data("blessure-type");
|
||||
let index = tr.data('blessure-index');
|
||||
let active = this.html.find(event.currentTarget).data('blessure-active');
|
||||
//console.log(btype, index, active);
|
||||
await this.actor.manageBlessureFromSheet(btype, index, active);
|
||||
this.html.find('.blessure-premierssoins-done').change(async event => {
|
||||
const blessure = this.getBlessure(event);
|
||||
await blessure?.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } });
|
||||
});
|
||||
|
||||
// Blessure data
|
||||
this.html.find('.blessure-soins').change(async event => {
|
||||
const tr = this.html.find(event.currentTarget).parents(".item");
|
||||
let btype = tr.data('blessure-type');
|
||||
let index = tr.data('blessure-index');
|
||||
let psoins = tr.find('.blessure-premiers_soins').val();
|
||||
let pcomplets = tr.find('.blessure-soins_complets').val();
|
||||
let jours = tr.find('.blessure-jours').val();
|
||||
let loc = tr.find('.blessure-localisation').val();
|
||||
let psdone = tr.find('.blessure-psdone:checked').val();
|
||||
let scdone = tr.find('.blessure-scdone:checked').val();
|
||||
console.log(btype, index, psoins, pcomplets, jours, loc, psdone, scdone);
|
||||
await this.actor.setDataBlessureFromSheet(btype, index, psoins, pcomplets, jours, loc, psdone, scdone);
|
||||
this.html.find('.blessure-soinscomplets-done').change(async event => {
|
||||
const blessure = this.getBlessure(event);
|
||||
await blessure?.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } })
|
||||
});
|
||||
this.html.find('.blessure-premierssoins-bonus').change(async event => {
|
||||
const blessure = this.getBlessure(event);
|
||||
await blessure?.setSoinsBlessure({ premierssoins: { bonus: Number(event.currentTarget.value) } })
|
||||
});
|
||||
this.html.find('.blessure-soinscomplets-bonus').change(async event => {
|
||||
const blessure = this.getBlessure(event);
|
||||
await blessure?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } })
|
||||
});
|
||||
|
||||
// Equip Inventory Item
|
||||
@ -261,6 +267,11 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
this.actor.rollCarac('reve-actuel', true);
|
||||
});
|
||||
|
||||
// Suite empoignade
|
||||
this.html.find('.empoignade-label a').click(async event => {
|
||||
let emp = RdDSheetUtility.getItem(event, this.actor)
|
||||
RdDEmpoignade.onAttaqueEmpoignadeFromItem(emp)
|
||||
});
|
||||
// Roll Weapon1
|
||||
this.html.find('.arme-label a').click(async event => {
|
||||
let arme = this._getEventArmeCombat(event);
|
||||
@ -426,6 +437,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
||||
});
|
||||
}
|
||||
|
||||
getBlessure(event) {
|
||||
const itemId = this.html.find(event.currentTarget).parents(".item-blessure").data('item-id');
|
||||
const blessure = this.actor.getItem(itemId, 'blessure');
|
||||
return blessure;
|
||||
}
|
||||
|
||||
isCompetenceAffichable(competence) {
|
||||
return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
|
||||
}
|
||||
|
1132
module/actor.js
1132
module/actor.js
File diff suppressed because it is too large
Load Diff
@ -78,6 +78,7 @@ export class RdDBaseActorSheet extends ActorSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static filterItemsPerTypeForSheet(formData, itemTypes) {
|
||||
formData.blessures = Misc.arrayOrEmpty(itemTypes['blessure']);
|
||||
formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']);
|
||||
formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']);
|
||||
formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']);
|
||||
@ -151,6 +152,8 @@ export class RdDBaseActorSheet extends ActorSheet {
|
||||
const item = this.getItem(event);
|
||||
RdDSheetUtility.splitItem(item, this.actor);
|
||||
});
|
||||
this.html.find('.item-quantite-plus').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), 1));
|
||||
this.html.find('.item-quantite-moins').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), -1));
|
||||
this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, this.getItem(event)));
|
||||
this.html.find('.item-vendre').click(async event => this.vendre(this.getItem(event)));
|
||||
|
||||
@ -160,12 +163,6 @@ export class RdDBaseActorSheet extends ActorSheet {
|
||||
this.html.find('.nettoyer-conteneurs').click(async event => {
|
||||
this.actor.nettoyerConteneurs();
|
||||
});
|
||||
this.html.find('.monnaie-plus').click(async event => {
|
||||
this.actor.monnaieIncDec(this.getItemId(event), 1);
|
||||
});
|
||||
this.html.find('.monnaie-moins').click(async event => {
|
||||
this.actor.monnaieIncDec(this.getItemId(event), -1);
|
||||
});
|
||||
}
|
||||
|
||||
_rechercherKeyup(event) {
|
||||
|
@ -5,6 +5,7 @@ import { Misc } from "../misc.js";
|
||||
import { RdDAudio } from "../rdd-audio.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
||||
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
|
||||
|
||||
export class RdDBaseActor extends Actor {
|
||||
|
||||
@ -20,14 +21,16 @@ export class RdDBaseActor extends Actor {
|
||||
Hooks.on("updateActor", (actor, change, options, actorId) => actor.onUpdateActor(change, options, actorId));
|
||||
}
|
||||
|
||||
|
||||
static onSocketMessage(sockmsg) {
|
||||
switch (sockmsg.msg) {
|
||||
case "msg_remote_actor_call":
|
||||
return RdDBaseActor.onRemoteActorCall(sockmsg.data, sockmsg.userId);
|
||||
case "msg_reset_nombre_astral":
|
||||
console.log("RESET ASTRAL", game.user.character);
|
||||
game.user.character.resetNombreAstral();
|
||||
game.user.character.resetNombresAstraux();
|
||||
game.system.rdd.calendrier.notifyChangeNombresAstraux();
|
||||
return;
|
||||
case "msg_refresh_nombre_astral":
|
||||
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -106,7 +109,6 @@ export class RdDBaseActor extends Actor {
|
||||
isEntite() { return this.type == 'entite'; }
|
||||
isPersonnage() { return this.type == 'personnage'; }
|
||||
isVehicule() { return this.type == 'vehicule'; }
|
||||
|
||||
getItem(id, type = undefined) {
|
||||
const item = this.items.get(id);
|
||||
if (type == undefined || (item?.type == type)) {
|
||||
@ -116,7 +118,7 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
|
||||
listItems(type = undefined) { return (type ? this.itemTypes[type] : this.items); }
|
||||
filterItems(filter, type = undefined) { return this.listItems(type)?.filter(filter) ?? []; }
|
||||
filterItems(filter, type = undefined) { return type ? this.itemTypes[type]?.filter(filter) ?? [] : []; }
|
||||
findItemLike(idOrName, type) {
|
||||
return this.getItem(idOrName, type)
|
||||
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
||||
@ -147,11 +149,11 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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, 'system.quantite': quantite }]);
|
||||
async itemQuantiteIncDec(id, value) {
|
||||
let item = this.getItem(id);
|
||||
if (item && item.isInventaire()) {
|
||||
const quantite = Math.max(0, item.system.quantite + value);
|
||||
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, 'system.quantite': quantite }]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,13 +243,16 @@ export class RdDBaseActor extends Actor {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const cout = Number(achat.prixTotal ?? 0);
|
||||
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
|
||||
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
|
||||
const vente = achat.vente;
|
||||
const quantite = (achat.choix.nombreLots ?? 1) * (vente.tailleLot);
|
||||
const itemVendu = vendeur?.getItem(vente.item._id);
|
||||
const quantite = (achat.choix.nombreLots ?? 1) * (achat.vente.tailleLot);
|
||||
const itemVendu = vendeur?.getItem(achat.vente.item._id) ?? game.items.get(achat.vente.item._id) ?? achat.vente.item;
|
||||
if (!itemVendu) {
|
||||
ui.notifications.warn("Erreur sur achat: rien à acheter<br>Si possible, transmettez les logs de la console aux développeurs");
|
||||
console.log('Erreur sur achat: rien à acheter', achat);
|
||||
return;
|
||||
}
|
||||
if (!this.verifierQuantite(vendeur, itemVendu, quantite)) {
|
||||
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
||||
return
|
||||
@ -259,13 +264,13 @@ export class RdDBaseActor extends Actor {
|
||||
await this.decrementerVente(vendeur, itemVendu, quantite, cout);
|
||||
if (acheteur) {
|
||||
await acheteur.depenserSols(cout);
|
||||
const createdItemId = await acheteur.creerQuantiteItem(vente.item, quantite);
|
||||
await acheteur.consommerNourritureAchetee(achat, vente, createdItemId);
|
||||
const createdItemId = await acheteur.creerQuantiteItem(achat.vente.item, quantite);
|
||||
await acheteur.consommerNourritureAchetee(achat, achat.vente, createdItemId);
|
||||
}
|
||||
if (cout > 0) {
|
||||
RdDAudio.PlayContextAudio("argent");
|
||||
}
|
||||
const chatAchatItem = duplicate(vente);
|
||||
const chatAchatItem = duplicate(achat.vente);
|
||||
chatAchatItem.quantiteTotal = quantite;
|
||||
ChatMessage.create({
|
||||
user: achat.userId,
|
||||
@ -274,16 +279,16 @@ export class RdDBaseActor extends Actor {
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem)
|
||||
});
|
||||
|
||||
if (!vente.quantiteIllimite) {
|
||||
if (vente.quantiteNbLots <= achat.choix.nombreLots) {
|
||||
if (!achat.vente.quantiteIllimite) {
|
||||
if (achat.vente.quantiteNbLots <= achat.choix.nombreLots) {
|
||||
ChatUtility.removeChatMessageId(achat.chatMessageIdVente);
|
||||
}
|
||||
else if (achat.chatMessageIdVente) {
|
||||
vente["properties"] = itemVendu.getProprietes();
|
||||
vente.quantiteNbLots -= achat.choix.nombreLots;
|
||||
vente.jsondata = JSON.stringify(vente.item);
|
||||
achat.vente.properties = itemVendu.getProprietes();
|
||||
achat.vente.quantiteNbLots -= achat.choix.nombreLots;
|
||||
achat.vente.jsondata = JSON.stringify(achat.vente.item);
|
||||
const messageVente = game.messages.get(achat.chatMessageIdVente);
|
||||
messageVente.update({ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente) });
|
||||
messageVente.update({ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', achat.vente) });
|
||||
messageVente.render(true);
|
||||
}
|
||||
}
|
||||
|
39
module/actor/experience-log.js
Normal file
39
module/actor/experience-log.js
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
export const XP_TOPIC = {
|
||||
XP: { code: 'xp', label: 'xp' },
|
||||
XPSORT: { code: 'xpsort', label: 'xp sort' },
|
||||
NIVEAU: { code: 'niveau', label: 'Niveau' },
|
||||
XPCARAC: { code: 'xpcarac', label: 'xp carac' },
|
||||
CARAC: { code: 'carac', label: 'Carac' },
|
||||
STRESS: { code: 'stress', label: 'Stress' },
|
||||
TRANSFORM: { code: 'xps', label: 'Transformé' },
|
||||
}
|
||||
|
||||
export class ExperienceLog {
|
||||
|
||||
static async add(actor, topic, from, to, raison, manuel = false) {
|
||||
if (!actor.hasPlayerOwner || !actor.isPersonnage()) {
|
||||
return
|
||||
}
|
||||
if (from == to) {
|
||||
return
|
||||
}
|
||||
const newXpLog = {
|
||||
mode: topic?.code ?? topic,
|
||||
raison: (manuel ? '(manuel) ' : '') + raison,
|
||||
from: from,
|
||||
to: to,
|
||||
valeur: to - from,
|
||||
daterdd: game.system.rdd.calendrier.dateCourante(),
|
||||
datereel: game.system.rdd.calendrier.dateReel().replace('T', ' ')
|
||||
};
|
||||
console.log('ExperienceLog.add', newXpLog)
|
||||
const newExperienceLog = (actor.system.experiencelog ?? []).concat([newXpLog]);
|
||||
await actor.update({ [`system.experiencelog`]: newExperienceLog });
|
||||
}
|
||||
|
||||
static labelTopic(topic) {
|
||||
const xpt = Object.values(XP_TOPIC).find(it => it.code == topic);
|
||||
return xpt?.label ?? xpt?.code ?? topic;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { SYSTEM_RDD } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
|
||||
|
||||
const LATEST_USED_JOURNAL_ID = "chronologie-dernier-journal";
|
||||
@ -25,23 +25,13 @@ export class DialogChronologie extends Dialog {
|
||||
journalId: game.settings.get(SYSTEM_RDD, LATEST_USED_JOURNAL_ID),
|
||||
journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)),
|
||||
timestamp: game.system.rdd.calendrier.timestamp,
|
||||
dateReel: DialogChronologie.getCurrentDateTime()
|
||||
dateReel: game.system.rdd.calendrier.dateReel()
|
||||
};
|
||||
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData);
|
||||
const dialog = new DialogChronologie(html, dialogData);
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
static getCurrentDateTime() {
|
||||
return new Date().toLocaleString("sv-SE", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit"
|
||||
}).replace(" ", "T");
|
||||
}
|
||||
|
||||
constructor(html, dialogData) {
|
||||
const options = {
|
||||
classes: ["DialogChronologie"],
|
||||
@ -124,7 +114,7 @@ export class DialogChronologie extends Dialog {
|
||||
heure: RdDTimestamp.definition(this.html.find("form.rdddialogchrono :input[name='chronologie.heure']").val()),
|
||||
minute: this.html.find("form.rdddialogchrono :input[name='chronologie.minute']").val(),
|
||||
},
|
||||
dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val().replace('T', ' ')
|
||||
dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { RdDUtility } from "./rdd-utility.js";
|
||||
export class DialogFabriquerPotion extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async create(actor, item, dialogConfig) {
|
||||
static async create(actor, item, onActionItem) {
|
||||
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!`);
|
||||
@ -13,12 +13,10 @@ export class DialogFabriquerPotion extends Dialog {
|
||||
}
|
||||
let potionData = DialogFabriquerPotion.prepareData(actor, item);
|
||||
|
||||
const html = await renderTemplate(dialogConfig.html, potionData);
|
||||
const html = await renderTemplate( 'systems/foundryvtt-reve-de-dragon/templates/dialog-fabriquer-potion-base.html', potionData);
|
||||
|
||||
let options = { classes: ["dialogfabriquerpotion"], width: 600, height: 160, 'z-index': 99999 };
|
||||
mergeObject(options, dialogConfig.options ?? {}, { overwrite: true })
|
||||
|
||||
new DialogFabriquerPotion(actor, potionData, html, options).render(true);
|
||||
new DialogFabriquerPotion(actor, potionData, onActionItem, html, options).render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -34,14 +32,14 @@ export class DialogFabriquerPotion extends Dialog {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(actor, potionData, html, options) {
|
||||
constructor(actor, potionData, onActionItem, html, options) {
|
||||
const conf = {
|
||||
title: `Fabriquer une potion de ${potionData.system.categorie}`,
|
||||
content: html,
|
||||
default: 'fabriquer',
|
||||
buttons: {
|
||||
'fabriquer': {
|
||||
label: potionData.buttonName, callback: it => this.onFabriquer(html)
|
||||
label: potionData.buttonName, callback: it => this.onFabriquer()
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -50,6 +48,7 @@ export class DialogFabriquerPotion extends Dialog {
|
||||
|
||||
this.actor = actor;
|
||||
this.potionData = potionData;
|
||||
this.onActionItem = onActionItem;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -64,10 +63,11 @@ export class DialogFabriquerPotion extends Dialog {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onFabriquer(html) {
|
||||
async onFabriquer() {
|
||||
await this.html.find("[name='nbBrins']").change();
|
||||
this.actor.fabriquerPotion(this.potionData);
|
||||
await this.actor.fabriquerPotion(this.potionData);
|
||||
this.close();
|
||||
await this.onActionItem()
|
||||
}
|
||||
|
||||
static nombreBrinsMinimum(herbeData) {
|
||||
|
@ -18,7 +18,7 @@ export class DialogItemAchat extends Dialog {
|
||||
}
|
||||
|
||||
return {
|
||||
item: (json ? JSON.parse(json) : undefined),
|
||||
item: JSON.parse(json),
|
||||
vendeur,
|
||||
acheteur,
|
||||
nbLots: parseInt(chatButton.attributes['data-quantiteNbLots']?.value),
|
||||
@ -34,7 +34,6 @@ export class DialogItemAchat extends Dialog {
|
||||
const venteData = {
|
||||
item,
|
||||
actingUserId: game.user.id,
|
||||
vendeurId: vendeur?.id,
|
||||
vendeur,
|
||||
acheteur,
|
||||
tailleLot,
|
||||
|
@ -23,7 +23,7 @@ export class DialogValidationEncaissement extends Dialog {
|
||||
constructor(html, actor, rollData, armure, encaissement, show, onEncaisser) {
|
||||
// Common conf
|
||||
let buttons = {
|
||||
"valider": { label: "Valider", callback: html => this.validerEncaissement() },
|
||||
"valider": { label: "Valider", callback: html => this.onValider() },
|
||||
"annuler": { label: "Annuler", callback: html => { } },
|
||||
};
|
||||
|
||||
@ -64,7 +64,7 @@ export class DialogValidationEncaissement extends Dialog {
|
||||
});
|
||||
}
|
||||
|
||||
async validerEncaissement() {
|
||||
async onValider() {
|
||||
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
||||
this.onEncaisser(this.encaissement, this.show)
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ export class RdDItemArme extends Item {
|
||||
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.system.niveau, initiative: init }));
|
||||
armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.system.niveau, initiative: init }));
|
||||
}
|
||||
|
||||
static corpsACorps(mainsNuesActor) {
|
||||
|
@ -10,7 +10,7 @@ import { SYSTEM_RDD } from "./constants.js";
|
||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
|
||||
/**
|
||||
* Extend the basic ItemSheet for RdD specific items
|
||||
@ -188,7 +188,7 @@ export class RdDItemSheet extends ItemSheet {
|
||||
});
|
||||
|
||||
this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item));
|
||||
this.html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item));
|
||||
this.html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item, this.getActionRenderItem()));
|
||||
this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).dialogFabriquerPotion(this.item));
|
||||
|
||||
this.html.find('.alchimie-tache a').click((event) => {
|
||||
@ -203,12 +203,23 @@ export class RdDItemSheet extends ItemSheet {
|
||||
}
|
||||
});
|
||||
|
||||
this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => this.render(true)));
|
||||
this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true));
|
||||
this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor)));
|
||||
this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
|
||||
this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat());
|
||||
this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => this.render(true)));
|
||||
if (this.actor) {
|
||||
this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, this.getActionRenderItem()));
|
||||
this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true));
|
||||
this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor)));
|
||||
this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
|
||||
this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat());
|
||||
this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, this.getActionRenderItem()));
|
||||
|
||||
this.html.find('.item-quantite-plus').click(async event => {
|
||||
await this.actor.itemQuantiteIncDec(RdDSheetUtility.getItemId(event), 1)
|
||||
this.render();
|
||||
});
|
||||
this.html.find('.item-quantite-moins').click(async event => {
|
||||
await this.actor.itemQuantiteIncDec(RdDSheetUtility.getItemId(event), -1)
|
||||
this.render();
|
||||
});
|
||||
}
|
||||
|
||||
const updateItemTimestamp = (path, timestamp) => this.item.update({ [path]: duplicate(timestamp) })
|
||||
|
||||
@ -216,6 +227,16 @@ export class RdDItemSheet extends ItemSheet {
|
||||
RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.fin', updateItemTimestamp);
|
||||
}
|
||||
|
||||
getActionRenderItem() {
|
||||
return async () => {
|
||||
let item = this.item;
|
||||
while (item) {
|
||||
await item.sheet?.render()
|
||||
item = this.actor.getContenant(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_getEventActor(event) {
|
||||
let actorId = event.currentTarget.attributes['data-actor-id'].value;
|
||||
let actor = game.actors.get(actorId);
|
||||
@ -239,9 +260,8 @@ export class RdDItemSheet extends ItemSheet {
|
||||
_updateObject(event, formData) {
|
||||
if (this.item.type == 'sort') {
|
||||
// Données de bonus de cases ?
|
||||
formData['system.bonuscase'] = RdDItemSort.buildBonusCaseStringFromFormData(formData.bonusValue, formData.caseValue);
|
||||
formData['system.bonuscase'] = RdDItemSort.buildBonuscaseFromArrays(formData.bonusValue, formData.caseValue);
|
||||
}
|
||||
|
||||
return this.item.update(formData);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* -------------------------------------------- */
|
||||
import { Misc } from "./misc.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
@ -14,9 +13,9 @@ export class RdDItemSort extends Item {
|
||||
static isCoutVariable(sort) {
|
||||
return sort && (sort.system.ptreve.toLowerCase() == "variable" || sort.system.ptreve.indexOf("+") >= 0);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static setCoutReveReel(sort){
|
||||
static setCoutReveReel(sort) {
|
||||
if (sort) {
|
||||
sort.system.ptreve_reel = this.isCoutVariable(sort) ? 1 : sort.system.ptreve;
|
||||
}
|
||||
@ -25,94 +24,91 @@ export class RdDItemSort extends Item {
|
||||
/* -------------------------------------------- */
|
||||
static getDifficulte(sort, variable) {
|
||||
if (sort && !RdDItemSort.isDifficulteVariable(sort)) {
|
||||
return Misc.toInt(sort.system.difficulte);
|
||||
return Misc.toInt(sort.system.difficulte);
|
||||
}
|
||||
return variable;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static buildBonusCaseList( caseBonusString, newCase ) {
|
||||
if (caseBonusString == undefined) {
|
||||
return [];
|
||||
}
|
||||
let bonusCaseList = [];
|
||||
let bonusCaseArray = caseBonusString == undefined ? [] : caseBonusString.split(',');
|
||||
for( let bonusCase of bonusCaseArray) {
|
||||
let bonusSplit = bonusCase.split(':');
|
||||
bonusCaseList.push( { case: bonusSplit[0], bonus: bonusSplit[1] } );
|
||||
}
|
||||
if ( newCase )
|
||||
bonusCaseList.push( {case: "Nouvelle", bonus: 0} );
|
||||
return bonusCaseList;
|
||||
static buildBonusCaseList(bonuscase, newCase) {
|
||||
const list = RdDItemSort._bonuscaseStringToList(bonuscase)
|
||||
if (newCase) {
|
||||
return list.concat({ case: "Nouvelle", bonus: 0 });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne une liste de bonus/case pour un item-sheet
|
||||
* @param {} item
|
||||
*/
|
||||
static getBonusCaseList( item, newCase = false ) {
|
||||
static getBonusCaseList(item, newCase = false) {
|
||||
// Gestion spéciale case bonus
|
||||
if ( item.type == 'sort') {
|
||||
return this.buildBonusCaseList(item.system.bonuscase, newCase );
|
||||
if (item.type == 'sort') {
|
||||
return RdDItemSort.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( bonuses, cases ) {
|
||||
if ( bonuses ) {
|
||||
let list = [];
|
||||
let caseCheck = {};
|
||||
for (let i=0; i<bonuses.length; i++) {
|
||||
let coord = cases[i]?.toUpperCase() || 'A1';
|
||||
let bonus = bonuses[i] || 0;
|
||||
if ( TMRUtility.verifyTMRCoord( coord ) && bonus > 0 && caseCheck[coord] == undefined ) {
|
||||
static buildBonuscaseFromArrays(bonuses, coords) {
|
||||
if (bonuses) {
|
||||
const list = [];
|
||||
const caseCheck = {};
|
||||
for (let i = 0; i < bonuses.length && i < coords.length; i++) {
|
||||
const coord = coords[i] == 'Fleuve' ? 'Fleuve' : (coords[i]?.toUpperCase() ?? 'A1');
|
||||
const bonus = bonuses[i] || 0;
|
||||
if (TMRUtility.verifyTMRCoord(coord) && bonus > 0 && caseCheck[coord] == undefined) {
|
||||
caseCheck[coord] = bonus;
|
||||
list.push( coord+":"+bonus );
|
||||
list.push({ case: coord, bonus: bonus });
|
||||
}
|
||||
}
|
||||
return list.toString();
|
||||
return RdDItemSort._bonuscaseListToString(list);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static incrementBonusCase( actor, sort, coord ) {
|
||||
let bonusCaseList = this.buildBonusCaseList(sort.system.bonuscase, false);
|
||||
//console.log("ITEMSORT", sort, bonusCaseList);
|
||||
|
||||
let found = false;
|
||||
let StringList = [];
|
||||
for( let bc of bonusCaseList) {
|
||||
if (bc.case == coord) { // Case existante
|
||||
found = true;
|
||||
bc.bonus = Number(bc.bonus) + 1;
|
||||
}
|
||||
StringList.push( bc.case+':'+bc.bonus );
|
||||
}
|
||||
if ( !found) { //Nouvelle case, bonus de 1
|
||||
StringList.push(coord+':1');
|
||||
}
|
||||
|
||||
// Sauvegarde/update
|
||||
let bonuscase = StringList.toString();
|
||||
//console.log("Bonus cae :", bonuscase);
|
||||
actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': bonuscase }] );
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getCaseBonus( sort, coord) {
|
||||
let bonusCaseList = this.buildBonusCaseList(sort.system.bonuscase, false);
|
||||
for( let bc of bonusCaseList) {
|
||||
if (bc.case == coord) { // Case existante
|
||||
return Number(bc.bonus);
|
||||
}
|
||||
static incrementBonusCase(actor, sort, coord) {
|
||||
if (TMRUtility.getTMR(coord).type == "fleuve") {
|
||||
coord = 'Fleuve';
|
||||
}
|
||||
return 0;
|
||||
const list = RdDItemSort.buildBonusCaseList(sort.system.bonuscase, false);
|
||||
const bonus = Number(list.find(it => it.case == coord)?.bonus ?? 0);
|
||||
const modified = { case: coord, bonus: bonus + 1 };
|
||||
|
||||
const bonuscase = RdDItemSort._bonuscaseListToString(
|
||||
list.filter(it => it.case != coord).concat(modified)
|
||||
);
|
||||
|
||||
// Sauvegarde/update
|
||||
actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': bonuscase }]);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getCaseBonus(sort, coord) {
|
||||
const isFleuve = TMRUtility.getTMR(coord).type == "fleuve";
|
||||
|
||||
let bc = RdDItemSort.buildBonusCaseList(sort.system.bonuscase, false)
|
||||
.filter(it => it.case == coord || (isFleuve && it.case == 'Fleuve'))
|
||||
.find(it => true)
|
||||
return Number(bc?.bonus ?? 0);
|
||||
}
|
||||
|
||||
static _bonuscaseListToString(list) {
|
||||
return list.map(it => `${it.case}:${it.bonus}`)
|
||||
.sort(Misc.ascending())
|
||||
.join(',');
|
||||
}
|
||||
static _bonuscaseStringToList(bonuscase) {
|
||||
return (bonuscase ?? '').split(',').map(it => {
|
||||
const b = it.split(':');
|
||||
return { case: b[0], bonus: b[1] };
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
const BASE_TACHE_SOIN_BLESSURE = { type: "tache", img: 'systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp', system: { carac: "dexterite", competence: "Chirurgie", periodicite: "1 round", fatigue: 0, } }
|
||||
const TACHES_SOIN_BLESSURE = {
|
||||
'critique': { name: 'Blessure critique', system: { difficulte: -6, points_de_tache: 6 } },
|
||||
'grave': { name: 'Blessure grave', system: { difficulte: -4, points_de_tache: 4 } },
|
||||
'legere': { name: 'Blessure légère', system: { difficulte: -2, points_de_tache: 2 } },
|
||||
}
|
||||
|
||||
export class RdDItemTache extends Item {
|
||||
|
||||
static prepareTacheSoin(gravite) {
|
||||
const blessure = TACHES_SOIN_BLESSURE[gravite]
|
||||
if (blessure) {
|
||||
return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), blessure)
|
||||
}
|
||||
ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
|
||||
return undefined;
|
||||
}
|
||||
}
|
162
module/item.js
162
module/item.js
@ -2,38 +2,76 @@ import { DialogItemVente } from "./dialog-item-vente.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDHerbes } from "./rdd-herbes.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
import { RdDRaretes } from "./item/raretes.js";
|
||||
|
||||
export const TYPES = {
|
||||
competence: 'competence',
|
||||
competencecreature: 'competencecreature',
|
||||
arme: 'arme',
|
||||
armure: 'armure',
|
||||
conteneur: 'conteneur',
|
||||
sort: 'sort',
|
||||
herbe: 'herbe',
|
||||
faune: 'faune',
|
||||
ingredient: 'ingredient',
|
||||
livre: 'livre',
|
||||
potion: 'potion',
|
||||
rencontre: 'rencontre',
|
||||
queue: 'queue',
|
||||
ombre: 'ombre',
|
||||
souffle: 'souffle',
|
||||
tete: 'tete',
|
||||
meditation: 'meditation',
|
||||
recettealchimique: 'recettealchimique',
|
||||
chant: 'chant',
|
||||
danse: 'danse',
|
||||
jeu: 'jeu',
|
||||
recettecuisine: 'recettecuisine',
|
||||
musique: 'musique',
|
||||
maladie: 'maladie',
|
||||
poison: 'poison',
|
||||
oeuvre: 'oeuvre',
|
||||
nourritureboisson: 'nourritureboisson',
|
||||
service: 'service',
|
||||
signedraconique: 'signedraconique',
|
||||
gemme: 'gemme',
|
||||
possession: 'possession',
|
||||
sortreserve: 'sortreserve',
|
||||
extraitpoetique: 'extraitpoetique',
|
||||
tarot: 'tarot',
|
||||
empoignade: 'empoignade'
|
||||
}
|
||||
const typesInventaireMateriel = [
|
||||
"arme",
|
||||
"armure",
|
||||
"conteneur",
|
||||
"faune",
|
||||
"gemme",
|
||||
"herbe",
|
||||
"plante",
|
||||
"ingredient",
|
||||
"livre",
|
||||
"monnaie",
|
||||
"munition",
|
||||
"nourritureboisson",
|
||||
"objet",
|
||||
"potion",
|
||||
TYPES.arme,
|
||||
TYPES.armure,
|
||||
TYPES.conteneur,
|
||||
TYPES.faune,
|
||||
TYPES.gemme,
|
||||
TYPES.herbe,
|
||||
TYPES.plante,
|
||||
TYPES.ingredient,
|
||||
TYPES.livre,
|
||||
TYPES.monnaie,
|
||||
TYPES.munition,
|
||||
TYPES.nourritureboisson,
|
||||
TYPES.objet,
|
||||
TYPES.potion,
|
||||
]
|
||||
const typesInventaire = {
|
||||
materiel: typesInventaireMateriel,
|
||||
all: ['service'].concat(typesInventaireMateriel),
|
||||
}
|
||||
|
||||
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
|
||||
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
|
||||
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
|
||||
const typesObjetsEffet = ["possession", "poison", "maladie"]
|
||||
const typesObjetsCompetence = ["competence", "competencecreature"]
|
||||
const typesObjetsTemporels = ["poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"]
|
||||
const typesObjetsOeuvres = [TYPES.oeuvre, TYPES.recettecuisine, TYPES.musique, TYPES.chant, TYPES.danse, TYPES.jeu]
|
||||
const typesObjetsDraconiques = [TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.tete, TYPES.signedraconique, TYPES.sortreserve, TYPES.rencontre]
|
||||
const typesObjetsConnaissance = [TYPES.meditation, TYPES.recettealchimique, TYPES.sort]
|
||||
const typesObjetsEffet = [TYPES.possession, TYPES.poison, TYPES.maladie, TYPES.blessure]
|
||||
const typesObjetsCompetence = [TYPES.competence, TYPES.competencecreature]
|
||||
const typesObjetsTemporels = [TYPES.blessure, TYPES.poison, TYPES.maladie, TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.signedraconique, TYPES.rencontre]
|
||||
const typesObjetsEquipable = [TYPES.arme, TYPES.armure, TYPES.objet];
|
||||
const typesEnvironnement = typesInventaireMateriel;
|
||||
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
|
||||
@ -75,11 +113,16 @@ export const defaultItemImg = {
|
||||
sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
|
||||
extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp",
|
||||
tarot: "systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp",
|
||||
empoignade: "systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp"
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDItem extends Item {
|
||||
|
||||
static get defaultIcon() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static getDefaultImg(itemType) {
|
||||
return game.system.rdd.itemClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
|
||||
}
|
||||
@ -87,12 +130,12 @@ export class RdDItem extends Item {
|
||||
static isFieldInventaireModifiable(type, field) {
|
||||
switch (field) {
|
||||
case 'quantite':
|
||||
if (['conteneur'].includes(type)) {
|
||||
if ([TYPES.conteneur].includes(type)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'cout':
|
||||
if (['monnaie'].includes(type)) {
|
||||
if ([TYPES.monnaie].includes(type)) {
|
||||
return game.user.isGM;
|
||||
}
|
||||
break;
|
||||
@ -138,44 +181,46 @@ export class RdDItem extends Item {
|
||||
super(docData, context);
|
||||
}
|
||||
|
||||
static get defaultIcon() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getUniteQuantite() {
|
||||
switch (this.type) {
|
||||
case "monnaie": return "(Pièces)"
|
||||
case "herbe":
|
||||
case TYPES.monnaie: return "(Pièces)"
|
||||
case TYPES.herbe:
|
||||
switch (this.system.categorie) {
|
||||
case 'Alchimie': case 'Repos': case 'Soin':
|
||||
return "(Brins)"
|
||||
case 'Cuisine': return '';
|
||||
}
|
||||
return '';
|
||||
case "ingredient": return "(Pépins ou Brins)"
|
||||
case TYPES.ingredient: return "(Pépins ou Brins)"
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
isCompetencePersonnage() { return this.type == 'competence' }
|
||||
isCompetenceCreature() { return this.type == 'competencecreature' }
|
||||
isConteneur() { return this.type == 'conteneur'; }
|
||||
isMonnaie() { return this.type == 'monnaie'; }
|
||||
isPotion() { return this.type == 'potion'; }
|
||||
isNourritureBoisson() { return this.type == 'nourritureboisson'; }
|
||||
isService() { return this.type == 'service'; }
|
||||
isEquipable() {
|
||||
return typesObjetsEquipable.includes(this.type)
|
||||
}
|
||||
|
||||
isCompetencePersonnage() { return this.type == TYPES.competence }
|
||||
isCompetenceCreature() { return this.type == TYPES.competencecreature }
|
||||
isConteneur() { return this.type == TYPES.conteneur; }
|
||||
isMonnaie() { return this.type == TYPES.monnaie; }
|
||||
isPotion() { return this.type == TYPES.potion; }
|
||||
isNourritureBoisson() { return this.type == TYPES.nourritureboisson; }
|
||||
isService() { return this.type == TYPES.service; }
|
||||
|
||||
isCompetence() { return typesObjetsCompetence.includes(this.type) }
|
||||
isTemporel() { return typesObjetsTemporels.includes(this.type) }
|
||||
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
|
||||
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
|
||||
isQueueDragon() { return [TYPES.queue, TYPES.ombre].includes(this.type) }
|
||||
isEffet() { return typesObjetsEffet.includes(this.type) }
|
||||
isConnaissance() { return typesObjetsConnaissance.includes(this.type) }
|
||||
|
||||
isInventaire(mode = 'materiel') { return RdDItem.getItemTypesInventaire(mode).includes(this.type); }
|
||||
isBoisson() { return this.isNourritureBoisson() && this.system.boisson; }
|
||||
isAlcool() { return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; }
|
||||
isHerbeAPotion() { return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
|
||||
isHerbeAPotion() { return this.type == TYPES.herbe && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
|
||||
isBlessure() { return this.type == TYPES.blessure }
|
||||
|
||||
isPresentDansMilieux(milieux) {
|
||||
return this.getEnvironnements(milieux).length > 0
|
||||
@ -260,15 +305,15 @@ export class RdDItem extends Item {
|
||||
|
||||
getUtilisation() {
|
||||
switch (this.type) {
|
||||
case 'potion':
|
||||
case TYPES.potion:
|
||||
switch (this.system.categorie) {
|
||||
case 'Alchimie': case 'AlchimieEnchante': case 'AlchimieAutre': return 'alchimie'
|
||||
case 'Cuisine': return 'cuisine'
|
||||
case 'Remede': case 'Repos': case 'ReposEnchante': case 'Soin': case 'SoinEnchante': return 'soins'
|
||||
}
|
||||
return '';
|
||||
case 'nourritureboisson': return 'cuisine';
|
||||
case 'herbe': case 'faune': case 'ingredient': case 'plante':
|
||||
case TYPES.nourritureboisson: return 'cuisine';
|
||||
case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
|
||||
switch (this.system.categorie) {
|
||||
case 'Cuisine': return 'cuisine';
|
||||
case 'Toxique': case 'Poison': return 'poison';
|
||||
@ -283,9 +328,9 @@ export class RdDItem extends Item {
|
||||
getUtilisationCuisine() {
|
||||
if (this.getUtilisation() == 'cuisine') {
|
||||
switch (this.type) {
|
||||
case 'nourritureboisson':
|
||||
case TYPES.nourritureboisson:
|
||||
return 'pret';
|
||||
case 'herbe': case 'faune': case 'ingredient': case 'plante':
|
||||
case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
|
||||
return 'brut';
|
||||
}
|
||||
}
|
||||
@ -293,7 +338,7 @@ export class RdDItem extends Item {
|
||||
}
|
||||
|
||||
isCristalAlchimique() {
|
||||
return this.type == 'objet' && Grammar.toLowerCaseNoAccent(this.name) == 'cristal alchimique' && this.system.quantite > 0;
|
||||
return this.type == TYPES.objet && Grammar.includesLowerCaseNoAccent(this.name, 'cristal alchimique') && this.system.quantite > 0;
|
||||
}
|
||||
|
||||
isMagique() {
|
||||
@ -321,11 +366,11 @@ export class RdDItem extends Item {
|
||||
|
||||
getEnc() {
|
||||
switch (this.type) {
|
||||
case 'service':
|
||||
case TYPES.service:
|
||||
return 0;
|
||||
case 'herbe':
|
||||
case TYPES.herbe:
|
||||
return this.getEncHerbe();
|
||||
case 'gemme':
|
||||
case TYPES.gemme:
|
||||
return encPepin * this.system.taille;
|
||||
}
|
||||
return Math.max(this.system.encombrement ?? 0, 0);
|
||||
@ -365,6 +410,7 @@ export class RdDItem extends Item {
|
||||
}
|
||||
this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false });
|
||||
}
|
||||
this.equipable = this.isEquipable();
|
||||
}
|
||||
|
||||
prepareDataPotion() {
|
||||
@ -380,7 +426,7 @@ export class RdDItem extends Item {
|
||||
|
||||
getActionPrincipale(options = { warnIfNot: true }) {
|
||||
switch (this.type) {
|
||||
case 'conteneur': return 'Ouvrir';
|
||||
case TYPES.conteneur: return 'Ouvrir';
|
||||
}
|
||||
if (this.actor?.isPersonnage()) {
|
||||
const warn = options.warnIfNot;
|
||||
@ -388,11 +434,11 @@ export class RdDItem extends Item {
|
||||
return 'Utiliser';
|
||||
}
|
||||
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 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
|
||||
case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined;
|
||||
case TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
|
||||
case TYPES.potion: return this._actionOrWarnQuantiteZero('Boire', warn);
|
||||
case TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn);
|
||||
case TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
|
||||
case TYPES.queue: case TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
@ -407,11 +453,11 @@ export class RdDItem extends Item {
|
||||
return;
|
||||
}
|
||||
switch (this.type) {
|
||||
case 'potion': return await actor.consommerPotion(this, onActionItem);
|
||||
case 'livre': return await actor.actionLire(this);
|
||||
case 'conteneur': return await this.sheet.render(true);
|
||||
case 'herbe': return await actor.actionHerbe(this);
|
||||
case 'queue': case 'ombre': return await actor.actionRefoulement(this);
|
||||
case TYPES.potion: return await actor.consommerPotion(this, onActionItem);
|
||||
case TYPES.livre: return await actor.actionLire(this);
|
||||
case TYPES.conteneur: return await this.sheet.render(true);
|
||||
case TYPES.herbe: return await actor.actionHerbe(this, onActionItem);
|
||||
case TYPES.queue: case TYPES.ombre: return await actor.actionRefoulement(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
51
module/item/armure.js
Normal file
51
module/item/armure.js
Normal file
@ -0,0 +1,51 @@
|
||||
import { RdDItem } from "../item.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { ReglesOptionelles } from "../settings/regles-optionelles.js";
|
||||
|
||||
export class RdDItemArmure extends RdDItem {
|
||||
|
||||
static get defaultIcon() {
|
||||
return "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp";
|
||||
}
|
||||
|
||||
deteriorerArmure(dmg) {
|
||||
if (!ReglesOptionelles.isUsing('deteriorationArmure') || this.system.protection == '0') {
|
||||
return;
|
||||
}
|
||||
let deterioration = (this.system.deterioration ?? 0) + dmg;
|
||||
let protection = this.system.protection;
|
||||
|
||||
if (deterioration >= 10) {
|
||||
deterioration -= 10;
|
||||
protection = this.calculProtectionDeterioree();
|
||||
ChatMessage.create({ content: `Votre armure ${this.name} s'est détériorée, elle protège maintenant de ${protection}` });
|
||||
}
|
||||
this.update({
|
||||
system: {
|
||||
deterioration: deterioration,
|
||||
protection: protection
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
calculProtectionDeterioree() {
|
||||
const protectionCourante = this.system.protection;
|
||||
let res = /(\d+)?d(\d+)(\-\d+)?/.exec(protectionCourante);
|
||||
if (res) {
|
||||
let protection = Misc.toInt(res[2]);
|
||||
let malus = Misc.toInt(res[3]) - 1;
|
||||
if (protection + malus <= 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return `1d${protection}${malus}`;
|
||||
}
|
||||
}
|
||||
else if (/\d+/.exec(protectionCourante)) {
|
||||
return `1d${protectionCourante}`;
|
||||
}
|
||||
else {
|
||||
ui.notifications.warn(`La valeur d'armure de votre ${this.name} est incorrecte`);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
199
module/item/blessure.js
Normal file
199
module/item/blessure.js
Normal file
@ -0,0 +1,199 @@
|
||||
import { RdDItem } from "../item.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDTimestamp } from "../time/rdd-timestamp.js";
|
||||
|
||||
const BASE_TACHE_SOIN_BLESSURE = {
|
||||
type: "tache",
|
||||
img: 'systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp',
|
||||
system: { carac: "dexterite", competence: "Chirurgie", periodicite: "1 round", fatigue: 0, }
|
||||
}
|
||||
const TACHES_SOIN_BLESSURE = {
|
||||
6: { name: 'Blessure critique', system: { difficulte: -6, points_de_tache: 6 } },
|
||||
4: { name: 'Blessure grave', system: { difficulte: -4, points_de_tache: 4 } },
|
||||
2: { name: 'Blessure légère', system: { difficulte: -2, points_de_tache: 2 } },
|
||||
}
|
||||
|
||||
const definitionsBlessures = [
|
||||
{ type: "contusion", gravite: 0, label: 'Contusion/éraflure', max: 100, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/eraflure.webp" },
|
||||
{ type: "legere", gravite: 2, label: 'Légère', max: 5, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
|
||||
{ type: "grave", gravite: 4, label: 'Grave', max: 2, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
|
||||
{ type: "critique", gravite: 6, label: 'Critique', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
|
||||
{ type: "mort", gravite: 8, label: 'Mort', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/mort.webp" }
|
||||
]
|
||||
|
||||
export class RdDItemBlessure extends RdDItem {
|
||||
|
||||
static get defaultIcon() {
|
||||
return "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp";
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData();
|
||||
this.system.label = this.getLabelGravite()
|
||||
}
|
||||
|
||||
static prepareTacheSoin(gravite) {
|
||||
const tache = TACHES_SOIN_BLESSURE[gravite]
|
||||
if (!tache) {
|
||||
ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
|
||||
return undefined;
|
||||
}
|
||||
return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), tache)
|
||||
}
|
||||
static async createBlessure(actor, gravite, localisation = '', attacker) {
|
||||
const definition = RdDItemBlessure.getDefinition(gravite)
|
||||
const blessure = {
|
||||
name: definition.label,
|
||||
type: 'blessure',
|
||||
img: definition.icon,
|
||||
system: {
|
||||
gravite: gravite,
|
||||
difficulte: - gravite,
|
||||
localisation: localisation,
|
||||
origine: attacker?.name ?? ""
|
||||
}
|
||||
}
|
||||
const blessures = await actor.createEmbeddedDocuments('Item', [blessure])
|
||||
return blessures[0]
|
||||
}
|
||||
|
||||
static async createTacheSoinBlessure(actor, gravite) {
|
||||
const tache = RdDItemBlessure.prepareTacheSoin(gravite)
|
||||
if (tache) {
|
||||
const taches = await actor.createEmbeddedDocuments('Item', [tache], { renderSheet: false });
|
||||
return taches[0];
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
async updateTacheSoinBlessure(tache) {
|
||||
if (tache) {
|
||||
await tache.update({
|
||||
system: {
|
||||
itemId: this.id,
|
||||
difficulte: Math.min(this.system.difficulte, tache.system.difficulte),
|
||||
points_de_tache_courant: Math.max(0, this.system.premierssoins.tache)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async setSoinsBlessure(systemUpdate = {}) {
|
||||
systemUpdate = mergeObject(systemUpdate, this.system, { overwrite: false }),
|
||||
systemUpdate.soinscomplets.done = systemUpdate.premierssoins.done && systemUpdate.soinscomplets.done
|
||||
await this.update({
|
||||
img: this.getImgSoins(systemUpdate.gravite, systemUpdate.soinscomplets.done),
|
||||
system: systemUpdate
|
||||
});
|
||||
}
|
||||
|
||||
async recuperationBlessure({ actor, timestamp, message, isMaladeEmpoisonne, blessures }) {
|
||||
if (this.parent != actor || actor == undefined) {
|
||||
return
|
||||
}
|
||||
if (new RdDTimestamp(this.system.temporel.fin).compare(timestamp) > 0) {
|
||||
// attente periode
|
||||
return
|
||||
}
|
||||
if (this.system.gravite > 0) {
|
||||
const update = { system: { premierssoins: { bonus: 0 }, soinscomplets: { bonus: 0 } } }
|
||||
const gravite = this.system.gravite;
|
||||
const graviteMoindre = gravite - 2;
|
||||
const moindres = blessures.filter(it => it.system.gravite == graviteMoindre, 'blessures').length
|
||||
const label = this.getLabelGravite();
|
||||
|
||||
let rolled = await actor.jetRecuperationConstitution(this.system.soinscomplets.bonus, message);
|
||||
|
||||
if (rolled.isETotal) {
|
||||
message.content += ` -- une blessure ${label} s'infecte (temps de guérison augmenté de ${gravite} jours, perte de vie)`;
|
||||
await actor.santeIncDec("vie", -1);
|
||||
mergeObject(update, {
|
||||
system: { fin: { indexDate: timestamp.addJours(gravite).indexDate } }
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (!isMaladeEmpoisonne && rolled.isSuccess && this.peutRetrograder(graviteMoindre, moindres)) {
|
||||
message.content += ` -- une blessure ${label} cicatrise`;
|
||||
mergeObject(update, {
|
||||
system: { gravite: graviteMoindre, fin: { indexDate: timestamp.addJours(graviteMoindre).indexDate } }
|
||||
});
|
||||
}
|
||||
else {
|
||||
message.content += ` -- une blessure ${label} reste stable`;
|
||||
}
|
||||
}
|
||||
await this.update(update);
|
||||
}
|
||||
}
|
||||
|
||||
peutRetrograder(graviteMoindre, moindres) {
|
||||
return moindres < RdDItemBlessure.getDefinition(graviteMoindre).max
|
||||
}
|
||||
|
||||
async calculerFinPeriodeTemporel(debut) {
|
||||
return await debut.nouveauJour().addJours(this.system.gravite);
|
||||
}
|
||||
|
||||
async onFinPeriode(oldTimestamp, newTimestamp) {
|
||||
if (this.system.gravite <= 0) {
|
||||
await super.onFinPeriode(oldTimestamp, newTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
getImgSoins(gravite, soins) {
|
||||
let img = 'blessure'
|
||||
if (gravite > 6) {
|
||||
img = 'mort'
|
||||
}
|
||||
if (gravite <= 0) {
|
||||
img = 'eraflure'
|
||||
}
|
||||
return `systems/foundryvtt-reve-de-dragon/icons/sante/${soins ? 'blessure-soins' : img}.webp`
|
||||
}
|
||||
|
||||
getLabelGravite() {
|
||||
return RdDItemBlessure.getDefinition(this.system.gravite).label
|
||||
}
|
||||
|
||||
static getDefinition(gravite) {
|
||||
return definitionsBlessures.sort(Misc.ascending(it => it.gravite))
|
||||
.find(it => it.gravite >= gravite);
|
||||
}
|
||||
static maxBlessures(gravite) {
|
||||
return RdDItemBlessure.getDefinition(gravite).max
|
||||
}
|
||||
|
||||
isContusion() {
|
||||
return this.system.gravite <= 0
|
||||
}
|
||||
isLegere() {
|
||||
return this.system.gravite > 0 && this.system.gravite <= 2
|
||||
}
|
||||
isGrave() {
|
||||
return this.system.gravite > 2 && this.system.gravite <= 4
|
||||
}
|
||||
isCritique() {
|
||||
return this.system.gravite > 4 && this.system.gravite <= 6
|
||||
}
|
||||
isMort() {
|
||||
return this.system.gravite > 6
|
||||
}
|
||||
|
||||
getProprietes() {
|
||||
return [
|
||||
RdDItem.propertyIfDefined('Causée par', this.system.origine, this.system.origine),
|
||||
`<b>Heure et Date</b>: ${new RdDTimestamp(this.system.temporel.debut).formatDateHeure()}`,
|
||||
RdDItem.propertyIfDefined('Blessé', this.parent?.name, this.parent),
|
||||
`<b>Localisation</b>: ${this.system.localisation}`,
|
||||
`<b>Gravité</b>: ${RdDItemBlessure.getDefinition(this.system.gravite).label}`,
|
||||
`<b>Difficulté des soins</b>: ${this.system.difficulte}`,
|
||||
(this.system.soinscomplets.done ?
|
||||
`<b>Bonus soins complets</b>: ${this.system.soinscomplets.bonus}` :
|
||||
(this.system.premierssoins.done ?
|
||||
`<b>Bonus premiers soins</b>: ${this.system.premierssoins.bonus}` :
|
||||
`<b>Points de tâche</b>: ${this.system.premierssoins.tache}`
|
||||
)
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { RdDItem } from "../item.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDTimestamp } from "../rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "../time/rdd-timestamp.js";
|
||||
|
||||
export class RdDItemMaladie extends RdDItem {
|
||||
|
||||
|
29
module/item/sheet-blessure.js
Normal file
29
module/item/sheet-blessure.js
Normal file
@ -0,0 +1,29 @@
|
||||
import { RdDItemSheet } from "../item-sheet.js";
|
||||
|
||||
export class RdDBlessureItemSheet extends RdDItemSheet {
|
||||
|
||||
static get ITEM_TYPE() { return "blessure" };
|
||||
|
||||
async getData() {
|
||||
const formData = await super.getData();
|
||||
formData.disabled = formData.options.isGM || formData.options.isOwned ? '' : 'disabled';
|
||||
return formData;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
if (!this.options.editable) return;
|
||||
|
||||
this.html.find('[name="premierssoins-done"]').change(async event => {
|
||||
await this.item.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } });
|
||||
});
|
||||
this.html.find('[name="soinscomplets-done"]').change(async event => {
|
||||
await this.item.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } })
|
||||
});
|
||||
this.html.find('[name="system-gravite"]').change(async event => {
|
||||
const gravite = Number(event.currentTarget.value)
|
||||
await this.item.setSoinsBlessure({ gravite: gravite, difficulte: - gravite })
|
||||
});
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import { RdDItem, defaultItemImg } from "../item.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
import { RdDRollTables } from "../rdd-rolltables.js";
|
||||
import { RdDTimestamp } from "../rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "../time/rdd-timestamp.js";
|
||||
import { TMRType, TMRUtility } from "../tmr-utility.js";
|
||||
|
||||
const tableSignesIndicatifs = [
|
||||
|
@ -3,7 +3,7 @@ import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Monnaie } from "./item-monnaie.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
import { RdDRaretes } from "./item/raretes.js";
|
||||
|
||||
class Migration {
|
||||
@ -416,6 +416,48 @@ class _10_5_0_UpdatePeriodicite extends Migration {
|
||||
}
|
||||
}
|
||||
|
||||
class _10_7_0_MigrationBlessures extends Migration {
|
||||
get code() { return "migration-blessures"; }
|
||||
get version() { return "10.7.0"; }
|
||||
|
||||
async migrate() {
|
||||
const timestamp = game.system.rdd.calendrier.getTimestamp()
|
||||
await Promise.all(game.actors.filter(it => it.isPersonnage() || it.isCreature())
|
||||
.map(async (actor) => {
|
||||
const legeres = actor.system.blessures?.legeres.liste.filter(it => it.active).map(it => this.creerBlessure(2, 'légère', it, timestamp)) ?? [];
|
||||
const graves = actor.system.blessures?.graves.liste.filter(it => it.active).map(it => this.creerBlessure(4, 'grave', it, timestamp)) ?? [];
|
||||
const critiques = actor.system.blessures?.critiques.liste.filter(it => it.active).map(it => this.creerBlessure(6, 'critique', it, timestamp));
|
||||
const blessures = legeres.concat(graves).concat(critiques);
|
||||
if (blessures.length > 0) {
|
||||
await actor.createEmbeddedDocuments("Item", blessures);
|
||||
}
|
||||
await actor.update({
|
||||
'system.blessures.legeres.liste': [],
|
||||
'system.blessures.graves.liste': [],
|
||||
'system.blessures.critiques.liste': []
|
||||
})
|
||||
}));
|
||||
}
|
||||
creerBlessure(gravite, graviteTexte, blessure, timestamp) {
|
||||
const dateBlessure = timestamp.addJours(-blessure.jours);
|
||||
const datePremiereRecup = dateBlessure.addJours(gravite);
|
||||
return {
|
||||
name: `Blessure ${graviteTexte}`,
|
||||
type: 'blessure',
|
||||
img: `systems/foundryvtt-reve-de-dragon/icons/sante/blessure${blessure.psdone ? '-soins' : ''}.webp`,
|
||||
system: {
|
||||
gravite: gravite,
|
||||
difficulte: -gravite,
|
||||
debut: { indexDate: dateBlessure.indexDate, indexMinute: 0 },
|
||||
fin: { indexDate: datePremiereRecup.indexDate, indexMinute: 0 },
|
||||
premierssoins: { done: blessure.psdone, bonus: blessure.premiers_soins },
|
||||
soinscomplets: { done: blessure.scdone, bonus: blessure.soins_complets },
|
||||
localisation: blessure.localisation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Migrations {
|
||||
static getMigrations() {
|
||||
return [
|
||||
@ -431,6 +473,7 @@ export class Migrations {
|
||||
new _10_3_17_Monnaies(),
|
||||
new _10_4_6_ServicesEnCommerces(),
|
||||
new _10_5_0_UpdatePeriodicite(),
|
||||
new _10_7_0_MigrationBlessures(),
|
||||
];
|
||||
}
|
||||
|
||||
@ -447,7 +490,7 @@ export class Migrations {
|
||||
migrate() {
|
||||
const currentVersion = game.settings.get(SYSTEM_RDD, "systemMigrationVersion");
|
||||
if (isNewerVersion(game.system.version, currentVersion)) {
|
||||
//if (true) { /* comment previous and uncomment here to test before upgrade */
|
||||
//if (true) { /* comment previous and uncomment here to test before upgrade */
|
||||
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
|
||||
if (migrations.length > 0) {
|
||||
migrations.sort((a, b) => this.compareVersions(a, b));
|
||||
|
@ -119,6 +119,17 @@ export class Misc {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns an array of incremental integers (including from / excluding to).
|
||||
* if max<min, the array is decrementing integers
|
||||
*/
|
||||
static intArray(from, to) {
|
||||
if (from > to) {
|
||||
return Array.from(Array(from - to).keys()).map(i => from - i)
|
||||
}
|
||||
return Array.from(Array(to - from).keys()).map(i => from + i)
|
||||
}
|
||||
|
||||
static distinct(array) {
|
||||
return [...new Set(array)];
|
||||
}
|
||||
@ -228,4 +239,15 @@ export class Misc {
|
||||
}
|
||||
return subset;
|
||||
}
|
||||
|
||||
static cssRotation(angle) {
|
||||
const rotation = `rotate(${angle}deg)`;
|
||||
return {
|
||||
'transform': rotation,
|
||||
'-ms-transform': rotation,
|
||||
'-moz-transform': rotation,
|
||||
'-webkit-transform': rotation,
|
||||
'-o-transform': rotation
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
import { ThemeAstral } from "./sommeil/theme-astral.js";
|
||||
|
||||
/**
|
||||
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||
* @extends {Dialog}
|
||||
*/
|
||||
export class RdDAstrologieEditeur extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(html, calendrier, calendrierData) {
|
||||
let dialogConf = {
|
||||
title: "Editeur d'Astrologie",
|
||||
content: html,
|
||||
default: "fermer",
|
||||
buttons: {
|
||||
fermer: { label: "Fermer", callback: html => { } }
|
||||
}
|
||||
};
|
||||
let dialogOptions = {
|
||||
classes: ["rdd-roll-dialog"],
|
||||
width: 600,
|
||||
height: 'fit-content',
|
||||
'max-height': 800,
|
||||
'z-index': 99999
|
||||
}
|
||||
super(dialogConf, dialogOptions)
|
||||
|
||||
this.calendrier = calendrier;
|
||||
this.updateData(calendrierData);
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this.html = html;
|
||||
this.html.find('[name="theme-astral"]').click(event => ThemeAstral.create());
|
||||
this.html.find('[name="reset-nombres-astraux"]').click(event => this.resetNombreAstraux());
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async resetNombreAstraux() {
|
||||
game.system.rdd.calendrier.resetNombreAstral();
|
||||
await game.system.rdd.calendrier.rebuildListeNombreAstral();
|
||||
|
||||
game.system.rdd.calendrier.showAstrologieEditor();
|
||||
this.close()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
updateData(calendrierData) {
|
||||
this.calendrierData = duplicate(calendrierData);
|
||||
}
|
||||
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { ThemeAstral } from "./sommeil/theme-astral.js";
|
||||
|
||||
|
||||
/**
|
||||
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||
* @extends {Dialog}
|
||||
*/
|
||||
export class RdDAstrologieJoueur extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async create(actor) {
|
||||
|
||||
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', dialogData);
|
||||
|
||||
const options = { classes: ["rdd-roll-dialog"], width: 600, height: 'fit-content', 'z-index': 99999 };
|
||||
const dialog = new RdDAstrologieJoueur(html, actor, dialogData, options);
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(html, actor, dialogData, dialogOptions) {
|
||||
const dialogConf = {
|
||||
title: "Nombres Astraux",
|
||||
content: html,
|
||||
default: "saveButton",
|
||||
buttons: {
|
||||
saveButton: { label: "Fermer", callback: html => {} }
|
||||
},
|
||||
};
|
||||
super(dialogConf, dialogOptions);
|
||||
|
||||
this.actor = actor;
|
||||
this.dataNombreAstral = duplicate(dialogData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this.html = html;
|
||||
|
||||
this.html.find("[name='diffConditions']").val(0);
|
||||
|
||||
this.html.find('[name="jet-astrologie"]').click(event => {
|
||||
this.requestJetAstrologie();
|
||||
});
|
||||
this.html.find('[name="theme-astral"]').click(event => {
|
||||
ThemeAstral.create();
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static organizeNombres(actor) {
|
||||
let itemNombres = actor.listItems('nombreastral');
|
||||
let itemFiltered = {};
|
||||
for (let item of itemNombres) {
|
||||
if (itemFiltered[item.system.jourindex]) {
|
||||
itemFiltered[item.system.jourindex].listValues.push(item.system.value);
|
||||
} else {
|
||||
itemFiltered[item.system.jourindex] = {
|
||||
listValues: [item.system.value],
|
||||
jourlabel: item.system.jourlabel
|
||||
}
|
||||
}
|
||||
}
|
||||
return itemFiltered;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
requestJetAstrologie() {
|
||||
let socketData = {
|
||||
id: this.actor.id,
|
||||
carac_vue: this.actor.system.carac['vue'].value,
|
||||
etat: this.dataNombreAstral.etat,
|
||||
astrologie: this.dataNombreAstral.astrologie,
|
||||
conditions: this.html.find('[name="diffConditions"]').val(),
|
||||
date: this.html.find('[name="joursAstrologie"]').val(),
|
||||
userId: game.user.id
|
||||
}
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
game.system.rdd.calendrier.requestNombreAstral(socketData);
|
||||
} else {
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_request_nombre_astral",
|
||||
data: socketData
|
||||
});
|
||||
}
|
||||
this.close();
|
||||
}
|
||||
|
||||
}
|
@ -24,11 +24,14 @@ export class RdDBonus {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static isDefenseAttaqueFinesse(rollData) {
|
||||
if (rollData.isEmpoignade && rollData.rolled?.isPart) {
|
||||
return true
|
||||
}
|
||||
return rollData.attackerRoll?.particuliere == 'finesse';
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static dmg(rollData, dmgActor, isCauchemar = false) {
|
||||
static dmg(rollData, dmgActor, isEntiteIncarnee = false) {
|
||||
let dmg = { total: 0 };
|
||||
if (rollData.arme && rollData.arme.name.toLowerCase() == "esquive") {
|
||||
// Specific case management
|
||||
@ -41,7 +44,7 @@ export class RdDBonus {
|
||||
dmg.dmgSurprise = RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used);
|
||||
dmg.dmgActor = rollData.selectedCarac ? RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac.label, dmg.dmgArme) : 0;
|
||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
|
||||
dmg.mortalite = RdDBonus._calculMortalite(rollData, isCauchemar)
|
||||
dmg.mortalite = RdDBonus._calculMortalite(rollData, isEntiteIncarnee)
|
||||
}
|
||||
return dmg;
|
||||
}
|
||||
@ -62,11 +65,8 @@ export class RdDBonus {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _calculMortalite(rollData, isCauchemar) {
|
||||
if (isCauchemar) {
|
||||
return "cauchemar";
|
||||
}
|
||||
return isCauchemar ? "cauchemar"
|
||||
static _calculMortalite(rollData, isEntiteIncarnee) {
|
||||
return isEntiteIncarnee ? "entiteincarnee"
|
||||
: rollData.dmg?.mortalite
|
||||
?? rollData.arme?.system.mortalite
|
||||
?? "mortel";
|
||||
|
@ -1,513 +0,0 @@
|
||||
import { RdDCalendrierEditeur } from "./rdd-calendrier-editeur.js";
|
||||
import { RdDAstrologieEditeur } from "./rdd-astrologie-editeur.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { DialogChronologie } from "./dialog-chronologie.js";
|
||||
import { RdDTimestamp, WORLD_TIMESTAMP_SETTING } from "./rdd-timestamp.js";
|
||||
import { DialogChateauDormant } from "./sommeil/dialog-chateau-dormant.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
|
||||
const RDD_JOUR_PAR_MOIS = 28;
|
||||
const RDD_HEURES_PAR_JOUR = 12;
|
||||
const MAX_NOMBRE_ASTRAL = 12;
|
||||
const JOURS_DU_MOIS = Array(RDD_JOUR_PAR_MOIS).fill().map((item, index) => 1 + index);
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDCalendrier extends Application {
|
||||
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
template: "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html",
|
||||
popOut: false,
|
||||
resizable: false
|
||||
});
|
||||
}
|
||||
|
||||
static createCalendrierPos() {
|
||||
return { top: 200, left: 200 };
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
// position
|
||||
this.calendrierPos = duplicate(game.settings.get(SYSTEM_RDD, "calendrier-pos"));
|
||||
if (this.calendrierPos == undefined || this.calendrierPos.top == undefined) {
|
||||
this.calendrierPos = RdDCalendrier.createCalendrierPos();
|
||||
game.settings.set(SYSTEM_RDD, "calendrier-pos", this.calendrierPos);
|
||||
}
|
||||
// Calendrier
|
||||
this.timestamp = RdDTimestamp.getWorldTime();
|
||||
|
||||
if (Misc.isUniqueConnectedGM()) { // Uniquement si GM
|
||||
RdDTimestamp.setWorldTime(this.timestamp);
|
||||
this.listeNombreAstral = this.getListeNombreAstral();
|
||||
this.rebuildListeNombreAstral(HIDE_DICE); // Ensure always up-to-date
|
||||
}
|
||||
console.log('RdDCalendrier.constructor()', this.timestamp, this.timestamp.toCalendrier(), this.calendrierPos, this.listeNombreAstral);
|
||||
Hooks.on('updateSetting', async (setting, update, options, id) => this.onUpdateSetting(setting, update, options, id));
|
||||
}
|
||||
|
||||
async onUpdateSetting(setting, update, options, id) {
|
||||
if (setting.key == SYSTEM_RDD + '.' + WORLD_TIMESTAMP_SETTING) {
|
||||
this.timestamp = RdDTimestamp.getWorldTime();
|
||||
this.updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
async activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this.html = html;
|
||||
|
||||
this.updateDisplay();
|
||||
|
||||
this.html.find('.ajout-chronologie').click(ev => DialogChronologie.create());
|
||||
|
||||
this.html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
|
||||
|
||||
this.html.find('.calendar-set-datetime').click(ev => {
|
||||
ev.preventDefault();
|
||||
this.showCalendarEditor();
|
||||
});
|
||||
|
||||
this.html.find('.calendar-astrologie').click(ev => {
|
||||
ev.preventDefault();
|
||||
this.showAstrologieEditor();
|
||||
});
|
||||
|
||||
this.html.find('.calendar-title').mousedown(ev => {
|
||||
ev.preventDefault();
|
||||
ev = ev || window.event;
|
||||
let isRightMB = false;
|
||||
if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
|
||||
isRightMB = ev.which == 3;
|
||||
} else if ("button" in ev) { // IE, Opera
|
||||
isRightMB = ev.button == 2;
|
||||
}
|
||||
|
||||
if (!isRightMB) {
|
||||
dragElement(document.getElementById("calendar-time-container"));
|
||||
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
|
||||
|
||||
function dragElement(elmnt) {
|
||||
elmnt.onmousedown = dragMouseDown;
|
||||
function dragMouseDown(e) {
|
||||
e = e || window.event;
|
||||
e.preventDefault();
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
|
||||
document.onmouseup = closeDragElement;
|
||||
document.onmousemove = elementDrag;
|
||||
}
|
||||
|
||||
function elementDrag(e) {
|
||||
e = e || window.event;
|
||||
e.preventDefault();
|
||||
// calculate the new cursor position:
|
||||
pos1 = pos3 - e.clientX;
|
||||
pos2 = pos4 - e.clientY;
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
// set the element's new position:
|
||||
elmnt.style.bottom = undefined
|
||||
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
|
||||
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
|
||||
}
|
||||
|
||||
function closeDragElement() {
|
||||
// stop moving when mouse button is released:
|
||||
elmnt.onmousedown = undefined;
|
||||
document.onmouseup = undefined;
|
||||
document.onmousemove = undefined;
|
||||
let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth - 200 : (elmnt.offsetLeft - pos1);
|
||||
let yPos = (elmnt.offsetTop - pos2) > window.innerHeight - 20 ? window.innerHeight - 100 : (elmnt.offsetTop - pos2)
|
||||
xPos = xPos < 0 ? 0 : xPos;
|
||||
yPos = yPos < 0 ? 0 : yPos;
|
||||
if (xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)) {
|
||||
elmnt.style.top = (yPos) + "px";
|
||||
elmnt.style.left = (xPos) + "px";
|
||||
}
|
||||
game.system.rdd.calendrier.calendrierPos.top = yPos;
|
||||
game.system.rdd.calendrier.calendrierPos.left = xPos;
|
||||
if (game.user.isGM) {
|
||||
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (isRightMB) {
|
||||
game.system.rdd.calendrier.calendrierPos.top = 200;
|
||||
game.system.rdd.calendrier.calendrierPos.left = 200;
|
||||
if (game.user.isGM) {
|
||||
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
|
||||
}
|
||||
this.setPos(game.system.rdd.calendrier.calendrierPos);
|
||||
}
|
||||
});
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getListeNombreAstral() {
|
||||
return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? [];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
dateCourante() {
|
||||
return this.timestamp.formatDate();
|
||||
}
|
||||
|
||||
isAfterIndexDate(indexDate) {
|
||||
// TODO: standardize
|
||||
return indexDate < this.timestamp.indexDate;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
heureCourante() { return RdDTimestamp.definition(this.timestamp.heure); }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCurrentMinute() { return this.timestamp.indexMinute; }
|
||||
|
||||
getTimestamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
getTimestampFinChateauDormant(nbJours = 0) {
|
||||
return this.timestamp.nouveauJour().addJours(nbJours);
|
||||
}
|
||||
|
||||
getTimestampFinHeure(nbHeures = 0) {
|
||||
return this.timestamp.nouvelleHeure().addHeures(nbHeures);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getIndexFromDate(jour, mois) {
|
||||
const addYear = mois < this.timestamp.mois || (mois == this.timestamp.mois && jour < this.timestamp.jour)
|
||||
const time = RdDTimestamp.timestamp(this.timestamp.annee + (addYear ? 1 : 0), mois, jour);
|
||||
return time.indexDate;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getJoursSuivants(count) {
|
||||
let jours = [];
|
||||
let indexDate = this.timestamp.indexDate;
|
||||
for (let i = 0; i < count; i++, indexDate++) {
|
||||
jours[i] = { label: RdDTimestamp.formatIndexDate(indexDate), index: indexDate };
|
||||
}
|
||||
return jours;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async ajouterNombreAstral(indexDate, showDice = SHOW_DICE) {
|
||||
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showDice, rollMode: "selfroll" });
|
||||
const dateFuture = RdDTimestamp.formatIndexDate(indexDate);
|
||||
if (showDice != HIDE_DICE) {
|
||||
ChatMessage.create({
|
||||
whisper: ChatMessage.getWhisperRecipients("GM"),
|
||||
content: `Le chiffre astrologique du ${dateFuture} sera le ${nombreAstral}`
|
||||
});
|
||||
}
|
||||
return {
|
||||
nombreAstral: nombreAstral,
|
||||
valeursFausses: [],
|
||||
index: indexDate
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
resetNombreAstral() {
|
||||
this.listeNombreAstral = [];
|
||||
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", []);
|
||||
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_reset_nombre_astral",
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
*
|
||||
* @param {*} indexDate la date pour laquelle obtenir le nombre astral. Si undefined, on prend la date du jour
|
||||
* @returns le nombre astral pour la date, ou pour la date du jour si la date n'est pas fournie.
|
||||
* Si aucun nombre astral n'est trouvé, retourne 0 (cas où l'on demanderait un nombre astral en dehors des 12 jours courant et à venir)
|
||||
*/
|
||||
getNombreAstral(indexDate = undefined) {
|
||||
if (indexDate == undefined) {
|
||||
indexDate = this.timestamp.indexDate;
|
||||
}
|
||||
const listNombreAstral = this.getListeNombreAstral();
|
||||
let astralData = listNombreAstral.find((nombreAstral, i) => nombreAstral.index == indexDate);
|
||||
return astralData?.nombreAstral ?? 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rebuildListeNombreAstral(showDice = HIDE_DICE) {
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
let newList = [];
|
||||
for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
|
||||
let dayIndex = this.timestamp.indexDate + i;
|
||||
let na = this.listeNombreAstral.find(n => n.index == dayIndex);
|
||||
if (na) {
|
||||
newList[i] = na;
|
||||
} else {
|
||||
newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
|
||||
}
|
||||
}
|
||||
this.listeNombreAstral = newList;
|
||||
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", newList);
|
||||
game.actors.forEach(actor => actor.deleteEmbeddedDocuments("Item", actor.listItems('nombreastral').map(it => it.id)));
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setNewTimestamp(newTimestamp) {
|
||||
const oldTimestamp = this.timestamp;
|
||||
await Promise.all(game.actors.map(async actor => await actor.onTimeChanging(oldTimestamp, newTimestamp)));
|
||||
RdDTimestamp.setWorldTime(newTimestamp);
|
||||
if (oldTimestamp.indexDate + 1 == newTimestamp.indexDate && ReglesOptionelles.isUsing("chateau-dormant-gardien")) {
|
||||
await DialogChateauDormant.create();
|
||||
}
|
||||
this.timestamp = newTimestamp;
|
||||
await this.rebuildListeNombreAstral();
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onCalendarButton(ev) {
|
||||
ev.preventDefault();
|
||||
const calendarAvance = ev.currentTarget.attributes['data-calendar-avance'];
|
||||
const calendarSet = ev.currentTarget.attributes['data-calendar-set'];
|
||||
if (calendarAvance) {
|
||||
await this.incrementTime(Number(calendarAvance.value));
|
||||
}
|
||||
else if (calendarSet) {
|
||||
this.positionnerHeure(Number(calendarSet.value));
|
||||
}
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incrementTime(minutes = 0) {
|
||||
await this.setNewTimestamp(this.timestamp.addMinutes(minutes));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incrementerJour() {
|
||||
await this.setNewTimestamp(this.timestamp.nouveauJour());
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async positionnerHeure(heure) {
|
||||
const indexDate = this.timestamp.indexDate;
|
||||
const addDay = this.timestamp.heure < heure ? 0 : 1;
|
||||
const newTimestamp = new RdDTimestamp({ indexDate: indexDate + addDay }).addHeures(heure);
|
||||
await this.setNewTimestamp(newTimestamp)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
fillCalendrierData(formData = {}) {
|
||||
mergeObject(formData, this.timestamp.toCalendrier());
|
||||
formData.isGM = game.user.isGM;
|
||||
return formData;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getLectureAstrologieDifficulte(dateIndex) {
|
||||
let indexNow = this.timestamp.indexDate;
|
||||
let diffDay = dateIndex - indexNow;
|
||||
return - Math.floor(diffDay / 2);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async requestNombreAstral(request) {
|
||||
const actor = game.actors.get(request.id);
|
||||
if (Misc.isUniqueConnectedGM()) { // Only once
|
||||
console.log(request);
|
||||
let jourDiff = this.getLectureAstrologieDifficulte(request.date);
|
||||
let niveau = Number(request.astrologie.system.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat);
|
||||
let rollData = {
|
||||
caracValue: request.carac_vue,
|
||||
finalLevel: niveau,
|
||||
showDice: HIDE_DICE,
|
||||
rollMode: "blindroll"
|
||||
};
|
||||
await RdDResolutionTable.rollData(rollData);
|
||||
request.rolled = rollData.rolled;
|
||||
request.isValid = request.rolled.isSuccess;
|
||||
request.nbAstral = this.getNombreAstral(request.date);
|
||||
|
||||
if (request.rolled.isSuccess) {
|
||||
if (request.rolled.isPart) {
|
||||
// Gestion expérience (si existante)
|
||||
request.competence = actor.getCompetence("astrologie")
|
||||
request.selectedCarac = actor.system.carac["vue"];
|
||||
actor.appliquerAjoutExperience(request, 'hide');
|
||||
}
|
||||
}
|
||||
else {
|
||||
request.nbAstral = await RdDDice.rollTotal("1dhr" + request.nbAstral, {
|
||||
rollMode: "selfroll", showDice: HIDE_DICE
|
||||
});
|
||||
// Mise à jour des nombres astraux du joueur
|
||||
this.addNbAstralIncorect(request.id, request.date, request.nbAstral);
|
||||
}
|
||||
|
||||
if (Misc.getActiveUser(request.userId)?.isGM) {
|
||||
RdDUtility.responseNombreAstral(request);
|
||||
} else {
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_response_nombre_astral",
|
||||
data: request
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addNbAstralIncorect(actorId, date, nbAstral) {
|
||||
let astralData = this.listeNombreAstral.find((nombreAstral, i) => nombreAstral.index == date);
|
||||
astralData.valeursFausses.push({ actorId: actorId, nombreAstral: nbAstral });
|
||||
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getAjustementAstrologique(heureNaissance, name = undefined) {
|
||||
let defHeure = RdDTimestamp.findHeure(heureNaissance);
|
||||
if (defHeure) {
|
||||
return RdDCalendrier.ajustementAstrologiqueHeure(defHeure.heure, this.getNombreAstral(), this.timestamp.heure);
|
||||
}
|
||||
else if (name) {
|
||||
ui.notifications.warn(name + " n'a pas d'heure de naissance, ou elle est incorrecte : " + heureNaissance);
|
||||
}
|
||||
else {
|
||||
ui.notifications.warn(heureNaissance + " ne correspond pas à une heure de naissance");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ajustementAstrologiqueHeure(hn, nbAstral, heure) {
|
||||
switch (RdDCalendrier.ecartHeureChance(hn, nbAstral, heure)) {
|
||||
case 0: return 4;
|
||||
case 4: case 8: return 2;
|
||||
case 6: return -4;
|
||||
case 3: case 9: return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ecartHeureChance(heureNaissance, nombreAstral, heure) {
|
||||
return ((heureNaissance + nombreAstral - heure) % RDD_HEURES_PAR_JOUR + RDD_HEURES_PAR_JOUR) % RDD_HEURES_PAR_JOUR;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getData() {
|
||||
let formData = super.getData();
|
||||
this.fillCalendrierData(formData);
|
||||
this.setPos(this.calendrierPos);
|
||||
return formData;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
setPos(pos) {
|
||||
return new Promise(resolve => {
|
||||
function check() {
|
||||
let elmnt = document.getElementById("calendar-time-container");
|
||||
if (elmnt) {
|
||||
elmnt.style.bottom = undefined;
|
||||
let xPos = (pos.left) > window.innerWidth ? window.innerWidth - 200 : pos.left;
|
||||
let yPos = (pos.top) > window.innerHeight - 20 ? window.innerHeight - 100 : pos.top;
|
||||
elmnt.style.top = (yPos) + "px";
|
||||
elmnt.style.left = (xPos) + "px";
|
||||
resolve();
|
||||
} else {
|
||||
setTimeout(check, 30);
|
||||
}
|
||||
}
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
updateDisplay() {
|
||||
let calendrier = this.fillCalendrierData();
|
||||
// Rebuild text du calendrier
|
||||
let dateHTML = `${calendrier.jourDuMois} ${calendrier.mois.label} (${calendrier.mois.saison}) de l'année ${calendrier.annee}`
|
||||
if (game.user.isGM) {
|
||||
dateHTML = dateHTML + "<br>Nombre Astral: " + (this.getNombreAstral() ?? "?");
|
||||
}
|
||||
for (let handle of document.getElementsByClassName("calendar-title")) {
|
||||
handle.innerHTML = dateHTML;
|
||||
}
|
||||
for (let heure of document.getElementsByClassName("calendar-heure-texte")) {
|
||||
heure.innerHTML = calendrier.heure.label;
|
||||
}
|
||||
for (const minute of document.getElementsByClassName("calendar-minute-texte")) {
|
||||
minute.innerHTML = `${calendrier.minute} minutes`;
|
||||
}
|
||||
for (const heureImg of document.getElementsByClassName("calendar-heure-img")) {
|
||||
heureImg.src = calendrier.heure.icon;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async saveEditeur(calendrierData) {
|
||||
const newTimestamp = RdDTimestamp.timestamp(
|
||||
Number.parseInt(calendrierData.annee),
|
||||
calendrierData.mois.heure,
|
||||
Number.parseInt(calendrierData.jourMois),
|
||||
calendrierData.heure.heure,
|
||||
Number.parseInt(calendrierData.minutes)
|
||||
);
|
||||
await this.setNewTimestamp(newTimestamp);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async showCalendarEditor() {
|
||||
let calendrierData = this.fillCalendrierData();
|
||||
if (this.editeur == undefined) {
|
||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html', calendrierData);
|
||||
this.editeur = new RdDCalendrierEditeur(html, this, calendrierData)
|
||||
}
|
||||
this.editeur.updateData(calendrierData);
|
||||
this.editeur.render(true);
|
||||
}
|
||||
|
||||
static buildJoursMois() { return JOURS_DU_MOIS; }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async showAstrologieEditor() {
|
||||
const calendrierData = duplicate(this.fillCalendrierData());
|
||||
this.listeNombreAstral = this.listeNombreAstral || [];
|
||||
|
||||
calendrierData.astrologieData = this.listeNombreAstral.map(astro => {
|
||||
const timestamp = new RdDTimestamp({ indexDate: astro.index });
|
||||
astro.date = { mois: timestamp.mois, jour: timestamp.jour + 1 }
|
||||
for (let vf of astro.valeursFausses) {
|
||||
let actor = game.actors.get(vf.actorId);
|
||||
vf.actorName = (actor) ? actor.name : "Inconnu";
|
||||
}
|
||||
return astro;
|
||||
});
|
||||
|
||||
const nbAstral = this.getNombreAstral()
|
||||
calendrierData.heures = Array.from(Array(RDD_HEURES_PAR_JOUR).keys());
|
||||
calendrierData.ajustementsActeur = game.actors.filter(it => it.isPersonnage() && it.hasPlayerOwner).map(actor => {
|
||||
return {
|
||||
actor,
|
||||
ajustements: calendrierData.heures.map(heure => {
|
||||
const hn = RdDTimestamp.findHeure(actor.getHeureNaissance())?.heure;
|
||||
return {
|
||||
heure,
|
||||
ajustement: RdDCalendrier.ajustementAstrologiqueHeure(hn, nbAstral, heure)
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-astrologie-template.html', calendrierData);
|
||||
let astrologieEditeur = new RdDAstrologieEditeur(html, this, calendrierData)
|
||||
astrologieEditeur.updateData(calendrierData);
|
||||
astrologieEditeur.render(true);
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
import { Targets } from "./targets.js";
|
||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const premierRoundInit = [
|
||||
@ -57,6 +58,7 @@ export class RdDCombatManager extends Combat {
|
||||
ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`)
|
||||
game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined)
|
||||
.forEach(it => it.delete());
|
||||
RdDEmpoignade.deleteAllEmpoignades()
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,13 +93,26 @@ export class RdDCombatManager extends Combat {
|
||||
}
|
||||
} else {
|
||||
const armeCombat = combatant.actor.itemTypes['arme'].find(it => it.system.equipe)
|
||||
const compName = (armeCombat == undefined) ? "Corps à corps" : armeCombat.system.competence;
|
||||
let compName = "Corps à corps"
|
||||
if (armeCombat) {
|
||||
if (armeCombat.system.competence != "") {
|
||||
compName = armeCombat.system.competence
|
||||
}
|
||||
if (armeCombat.system.lancer != "") {
|
||||
compName = armeCombat.system.lancer
|
||||
}
|
||||
if (armeCombat.system.tir != "") {
|
||||
compName = armeCombat.system.tir
|
||||
}
|
||||
}
|
||||
const competence = RdDItemCompetence.findCompetence(combatant.actor.items, compName);
|
||||
if (competence) {
|
||||
if (competence && competence.system.defaut_carac) {
|
||||
const carac = combatant.actor.system.carac[competence.system.defaut_carac].value;
|
||||
const niveau = competence.system.niveau;
|
||||
const bonusEcaille = (armeCombat?.system.magique) ? armeCombat.system.ecaille_efficacite : 0;
|
||||
rollFormula = RdDCombatManager.formuleInitiative(2, carac, niveau, bonusEcaille);
|
||||
} else {
|
||||
ui.notifications.warn(`Votre arme ${armeCombat.name} n'a pas de compétence renseignée`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,7 +259,7 @@ export class RdDCombatManager extends Combat {
|
||||
} else if (actor.isPersonnage()) {
|
||||
// Recupération des items 'arme'
|
||||
const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it))
|
||||
//.concat(RdDItemArme.empoignade())
|
||||
.concat(RdDItemArme.empoignade())
|
||||
.concat(RdDItemArme.mainsNues());
|
||||
|
||||
const competences = actor.itemTypes['competence'];
|
||||
@ -737,17 +752,11 @@ export class RdDCombat {
|
||||
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
|
||||
return;
|
||||
}
|
||||
if (arme.system.cac == 'empoignade' && this.attacker.isCombatTouche()) {
|
||||
ChatMessage.create({
|
||||
alias: this.attacker.name,
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-actor-perte-empoignade.html', {
|
||||
attacker: this.attacker,
|
||||
competence: competence
|
||||
})
|
||||
});
|
||||
if (arme.system.cac == 'empoignade') {
|
||||
RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender)
|
||||
return;
|
||||
}
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this.attacker)
|
||||
|
||||
let rollData = this._prepareAttaque(competence, arme);
|
||||
console.log("RdDCombat.attaque >>>", rollData);
|
||||
@ -1295,13 +1304,8 @@ export class RdDCombat {
|
||||
blessuresStatus: actor.computeResumeBlessure(),
|
||||
SConst: actor.getSConst(),
|
||||
actorId: actor.id,
|
||||
isGrave: false,
|
||||
isCritique: false
|
||||
}
|
||||
if (actor.countBlessuresNonSoigneeByName("critiques") > 0) { // Pour éviter le cumul grave + critique
|
||||
formData.isCritique = true;
|
||||
} else if (actor.countBlessuresNonSoigneeByName("graves") > 0) {
|
||||
formData.isGrave = true;
|
||||
isGrave: actor.countBlessures(it => it.isGrave()) > 0,
|
||||
isCritique: actor.countBlessures(it => it.isCritique()) > 0
|
||||
}
|
||||
|
||||
ChatUtility.createChatWithRollMode(actor.name, {
|
||||
|
@ -332,7 +332,7 @@ export class RdDCommands {
|
||||
let competence = length > 1 ? actors[0].getCompetence(Misc.join(params.slice(1, length), ' ')) : { name: undefined };
|
||||
if (competence) {
|
||||
for (let actor of actors) {
|
||||
await actor.rollCaracCompetence(caracName, competence.name, diff);
|
||||
await actor.doRollCaracCompetence(caracName, competence.name, diff);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
314
module/rdd-empoignade.js
Normal file
314
module/rdd-empoignade.js
Normal file
@ -0,0 +1,314 @@
|
||||
/* -------------------------------------------- */
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDRoll } from "./rdd-roll.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDEmpoignade {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static init() {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static checkEmpoignadeEnCours(actor) {
|
||||
// TODO: autoriser la perception? la comédie/séduction?
|
||||
if (RdDEmpoignade.isEmpoignadeEnCours(actor)) {
|
||||
ui.notifications.warn("Une empoignade est en cours ! Normalement, vous ne pouvez rien faire d'autre que continuer l'empoignade ou la rompre.")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isEmpoignadeEnCours(actor) {
|
||||
return actor.itemTypes['empoignade'].find(it => it.system.pointsemp > 0)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getEmpoignadeById(actor, id) {
|
||||
let emp = actor.itemTypes['empoignade'].find(it => it.system.empoignadeid == id)
|
||||
return emp && duplicate(emp) || undefined;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getEmpoignade(attacker, defender) {
|
||||
let emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == attacker.id && it.system.empoigneid == defender.id)
|
||||
if (!emp) {
|
||||
emp = attacker.itemTypes['empoignade'].find(it => it.system.empoigneurid == defender.id && it.system.empoigneid == attacker.id)
|
||||
}
|
||||
if (emp) {
|
||||
return duplicate(emp);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static getMalusTaille(emp, attacker, defender) {
|
||||
// Si pas empoigné, alors 0
|
||||
if (emp.system.pointsemp == 0) {
|
||||
return 0
|
||||
}
|
||||
// Malus de -1 si différence de taille de 2 ou plus (p 135)
|
||||
if (attacker.system.carac.taille.value < defender.system.carac.taille.value - 1) {
|
||||
return attacker.system.carac.taille.value - (defender.system.carac.taille.value - 1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onAttaqueEmpoignadeValidee(attacker, defender) {
|
||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
const isNouvelle = empoignade == undefined;
|
||||
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
||||
|
||||
let mode = (empoignade && empoignade.system.empoigneurid == attacker.id) ? "empoigner" : "liberer"
|
||||
|
||||
let rollData = {
|
||||
mode: mode,
|
||||
isEmpoignade: true,
|
||||
competence: attacker.getCompetence("Corps à corps"),
|
||||
selectedCarac: attacker.system.carac.melee,
|
||||
empoignade: empoignade,
|
||||
attackerId: attacker.id,
|
||||
attackerName: attacker.name,
|
||||
defenderName: defender.name,
|
||||
defenderId: defender.id,
|
||||
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
||||
}
|
||||
if (attacker.isCreatureEntite()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||
}
|
||||
if (empoignade.system.pointsemp >= 2) {
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html');
|
||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
||||
} else {
|
||||
await RdDEmpoignade.$rollAttaqueEmpoignade(attacker, rollData, isNouvelle);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onAttaqueEmpoignade(attacker, defender) {
|
||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
const isNouvelle = empoignade == undefined;
|
||||
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
|
||||
//console.log("W.", empoignade, defender.hasArmeeMeleeEquipee())
|
||||
if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) {
|
||||
ChatUtility.createChatWithRollMode(attacker.name, {
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.html`, { attacker: attacker, defender: defender })
|
||||
})
|
||||
} else {
|
||||
await this.onAttaqueEmpoignadeValidee(attacker, defender)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onAttaqueEmpoignadeFromItem(empoignade) {
|
||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||
let defender = game.actors.get(empoignade.system.empoigneid)
|
||||
await this.onAttaqueEmpoignadeValidee(attacker, defender)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) {
|
||||
const dialog = await RdDRoll.create(attacker, rollData,
|
||||
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' },
|
||||
{
|
||||
name: 'jet-empoignade',
|
||||
label: 'Empoigner',
|
||||
callbacks: [
|
||||
{ condition: r => (r.rolled.isSuccess), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, true, isNouvelle) },
|
||||
{ condition: r => (r.rolled.isEchec), action: async (r) => await RdDEmpoignade.$onRollEmpoignade(r, false, isNouvelle) },
|
||||
]
|
||||
});
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $onRollEmpoignade(rollData, isSuccess, isNouvelle = false) {
|
||||
let attacker = game.actors.get(rollData.attackerId)
|
||||
let defender = game.actors.get(rollData.defenderId)
|
||||
|
||||
let empoignade = rollData.empoignade
|
||||
empoignade.isSuccess = isSuccess;
|
||||
|
||||
if (isSuccess && isNouvelle) {
|
||||
// Creer l'empoignade sur attaquant/defenseur
|
||||
await attacker.createEmbeddedDocuments('Item', [empoignade.toObject()])
|
||||
await defender.createEmbeddedDocuments('Item', [empoignade.toObject()])
|
||||
}
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-resultat.html');
|
||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async onDefenseEmpoignade(rollData, defenseMode, competenceName = "Corps à corps", carac = "melee") {
|
||||
let attacker = game.actors.get(rollData.attackerId)
|
||||
let defender = game.actors.get(rollData.defenderId)
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
|
||||
if (!empoignade) {
|
||||
ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!")
|
||||
return
|
||||
}
|
||||
|
||||
empoignade = duplicate(empoignade)
|
||||
rollData.mode = defenseMode
|
||||
rollData.empoignade = empoignade
|
||||
rollData.competence = defender.getCompetence(competenceName),
|
||||
rollData.selectedCarac = defender.system.carac[carac],
|
||||
rollData.malusTaille = RdDEmpoignade.getMalusTaille(empoignade, defender, attacker)
|
||||
|
||||
await RdDEmpoignade.$rollDefenseEmpoignade(defender, rollData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $rollDefenseEmpoignade(defender, rollData) {
|
||||
const dialog = await RdDRoll.create(defender, rollData,
|
||||
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' },
|
||||
{
|
||||
name: 'empoignade',
|
||||
label: 'Contrer',
|
||||
callbacks: [
|
||||
{ action: async (r) => await RdDEmpoignade.$onRollContrerLiberer(r) }
|
||||
]
|
||||
}
|
||||
);
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $onRollContrerLiberer(rollData) {
|
||||
let empoignade = rollData.empoignade
|
||||
|
||||
if (rollData.mode == "contrer-empoigner" && !rollData.rolled.isSuccess) {
|
||||
empoignade.system.pointsemp++
|
||||
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
||||
}
|
||||
if (rollData.mode == "contrer-liberer" && !rollData.rolled.isSuccess) {
|
||||
empoignade.system.pointsemp--
|
||||
RdDEmpoignade.$updateEtatEmpoignade(empoignade)
|
||||
}
|
||||
|
||||
if (empoignade.system.pointsemp >= 2) {
|
||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-actions.html');
|
||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
||||
}
|
||||
await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html')
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $updateEtatEmpoignade(empoignade) {
|
||||
console.log("UPDATE Empoignade", empoignade)
|
||||
|
||||
let defender = game.actors.get(empoignade.system.empoigneid)
|
||||
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
||||
let update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
|
||||
await defender.updateEmbeddedDocuments('Item', [update])
|
||||
|
||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||
emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
|
||||
update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
|
||||
await attacker.updateEmbeddedDocuments('Item', [update])
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $deleteEmpoignade(empoignade) {
|
||||
console.log("DELETE Empoignade", empoignade)
|
||||
|
||||
let defender = game.actors.get(empoignade.system.empoigneid)
|
||||
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
||||
await defender.deleteEmbeddedDocuments('Item', [emp._id])
|
||||
|
||||
//let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||
//emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
|
||||
//await attacker.deleteEmbeddedDocuments('Item', [emp._id])
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async entrainerAuSol(rollData) {
|
||||
let attacker = game.actors.get(rollData.attackerId)
|
||||
let defender = game.actors.get(rollData.defenderId)
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
|
||||
empoignade.system.ausol = true
|
||||
await this.$updateEtatEmpoignade(empoignade)
|
||||
|
||||
await attacker.setEffect(STATUSES.StatusProne, true);
|
||||
await defender.setEffect(STATUSES.StatusProne, true);
|
||||
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html');
|
||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async projeterAuSol(rollData) {
|
||||
let attacker = game.actors.get(rollData.attackerId)
|
||||
let defender = game.actors.get(rollData.defenderId)
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
|
||||
await defender.setEffect(STATUSES.StatusProne, true);
|
||||
await this.$deleteEmpoignade(empoignade)
|
||||
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html');
|
||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static async perteEndurance(rollData, perteMode) {
|
||||
let attacker = game.actors.get(rollData.attackerId)
|
||||
let defender = game.actors.get(rollData.defenderId)
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
|
||||
//console.log("Perte d'endurance :!!!", perteMode)
|
||||
let endValue = defender.system.sante.endurance.value
|
||||
if (perteMode == "end0") {
|
||||
await defender.santeIncDec("endurance", -endValue);
|
||||
}
|
||||
if (perteMode == "end1") {
|
||||
await defender.santeIncDec("endurance", -(endValue - 1));
|
||||
}
|
||||
if (perteMode == "endmoitie") {
|
||||
await defender.santeIncDec("endurance", -Math.floor(endValue / 2));
|
||||
}
|
||||
if (perteMode == "endquart") {
|
||||
await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4)));
|
||||
}
|
||||
let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html');
|
||||
ChatUtility.setMessageData(msg, "empoignade-roll-data", rollData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async deleteAllEmpoignades() {
|
||||
for (let actor of game.actors) {
|
||||
let empIds = actor.itemTypes["empoignade"].map(it => it.id)
|
||||
await actor.deleteEmbeddedDocuments('Item', empIds)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async deleteLinkedEmpoignade(actorId, empoignade) {
|
||||
let actorDeleteId = (actorId == empoignade.system.empoigneurid) ? empoignade.system.empoigneid : empoignade.system.empoigneurid
|
||||
let actor = game.actors.get(actorDeleteId)
|
||||
let emp = this.getEmpoignadeById(actor, empoignade.system.empoignadeid)
|
||||
if (emp) {
|
||||
await actor.deleteEmbeddedDocuments('Item', [emp._id])
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async createEmpoignade(attacker, defender) {
|
||||
return await Item.create({
|
||||
name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name,
|
||||
type: 'empoignade',
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
||||
system: { description: "", empoignadeid: randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name }
|
||||
},
|
||||
{
|
||||
temporary: true
|
||||
})
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDHerbes extends Item {
|
||||
|
@ -4,8 +4,8 @@ import { Migrations } from './migrations.js';
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
import { TMRRencontres } from "./tmr-rencontres.js";
|
||||
import { RdDCalendrier } from "./rdd-calendrier.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDCalendrier } from "./time/rdd-calendrier.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
import { DialogChronologie } from "./dialog-chronologie.js";
|
||||
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
@ -36,6 +36,7 @@ import { RdDActorVehiculeSheet } from "./actor-vehicule-sheet.js";
|
||||
import { RdDActorEntiteSheet } from "./actor-entite-sheet.js";
|
||||
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDItemBlessure } from "./item/blessure.js";
|
||||
import { RdDItemService } from "./item/service.js";
|
||||
import { RdDItemMaladie } from "./item/maladie.js";
|
||||
import { RdDItemPoison } from "./item/poison.js";
|
||||
@ -46,6 +47,7 @@ import { RdDItemSouffle } from "./item/souffle.js";
|
||||
import { RdDRencontre } from "./item/rencontre.js";
|
||||
|
||||
import { RdDItemSheet } from "./item-sheet.js";
|
||||
import { RdDBlessureItemSheet } from "./item/sheet-blessure.js";
|
||||
import { RdDServiceItemSheet } from "./item/sheet-service.js";
|
||||
import { RdDRencontreItemSheet } from "./item/sheet-rencontre.js";
|
||||
import { RdDHerbeItemSheet } from "./item/sheet-herbe.js";
|
||||
@ -55,7 +57,8 @@ import { RdDFauneItemSheet } from "./item/sheet-faune.js";
|
||||
import { RdDConteneurItemSheet } from "./item/sheet-conteneur.js";
|
||||
import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js";
|
||||
import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js";
|
||||
import { ThemeAstral } from "./sommeil/theme-astral.js";
|
||||
import { AppAstrologie } from "./sommeil/app-astrologie.js";
|
||||
import { RdDItemArmure } from "./item/armure.js";
|
||||
|
||||
/**
|
||||
* RdD system
|
||||
@ -74,21 +77,23 @@ export class SystemReveDeDragon {
|
||||
this.RdDUtility = RdDUtility;
|
||||
this.RdDHotbar = RdDHotbar;
|
||||
this.itemClasses = {
|
||||
service: RdDItemService,
|
||||
armure: RdDItemArmure,
|
||||
blessure: RdDItemBlessure,
|
||||
maladie: RdDItemMaladie,
|
||||
ombre: RdDItemOmbre,
|
||||
poison: RdDItemPoison,
|
||||
queue: RdDItemQueue,
|
||||
ombre: RdDItemOmbre,
|
||||
souffle: RdDItemSouffle,
|
||||
rencontre: RdDRencontre,
|
||||
service: RdDItemService,
|
||||
signedraconique: RdDItemSigneDraconique,
|
||||
rencontre: RdDRencontre
|
||||
souffle: RdDItemSouffle,
|
||||
}
|
||||
this.actorClasses = {
|
||||
commerce: RdDCommerce,
|
||||
creature: RdDActor,
|
||||
entite: RdDActor,
|
||||
personnage: RdDActor,
|
||||
vehicule: RdDActor,
|
||||
commerce: RdDCommerce,
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +102,7 @@ export class SystemReveDeDragon {
|
||||
/* -------------------------------------------- */
|
||||
async onInit() {
|
||||
game.system.rdd = this;
|
||||
this.ThemeAstral = ThemeAstral;
|
||||
this.AppAstrologie = AppAstrologie;
|
||||
|
||||
|
||||
console.log(`Initializing Reve de Dragon System`);
|
||||
@ -157,6 +162,7 @@ export class SystemReveDeDragon {
|
||||
RdDItemSheet.register(RdDPlanteItemSheet);
|
||||
RdDItemSheet.register(RdDIngredientItemSheet);
|
||||
RdDItemSheet.register(RdDServiceItemSheet);
|
||||
RdDItemSheet.register(RdDBlessureItemSheet);
|
||||
|
||||
Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, {
|
||||
types: [
|
||||
@ -170,13 +176,14 @@ export class SystemReveDeDragon {
|
||||
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
|
||||
"meditation", "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve",
|
||||
"nombreastral", "tache", "maladie", "poison", "possession",
|
||||
"tarot", "extraitpoetique"
|
||||
"tarot", "extraitpoetique", "empoignade"
|
||||
], makeDefault: true
|
||||
});
|
||||
CONFIG.Combat.documentClass = RdDCombatManager;
|
||||
|
||||
// préparation des différents modules
|
||||
RdDTimestamp.init();
|
||||
RdDCalendrier.init();
|
||||
SystemCompendiums.init();
|
||||
DialogChronologie.init();
|
||||
ReglesOptionelles.init();
|
||||
@ -212,25 +219,6 @@ export class SystemReveDeDragon {
|
||||
default: "avant-encaissement"
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "liste-nombre-astral", {
|
||||
name: "liste-nombre-astral",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: [],
|
||||
type: Object
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "calendrier-pos", {
|
||||
name: "calendrierPos",
|
||||
scope: "client",
|
||||
config: false,
|
||||
default: RdDCalendrier.createCalendrierPos(),
|
||||
type: Object
|
||||
});
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
|
||||
name: "Supprimer les dialogues de combat",
|
||||
@ -276,9 +264,11 @@ export class SystemReveDeDragon {
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
sidebar.style.width = "min-content";
|
||||
}
|
||||
|
||||
game.system.rdd.calendrier = new RdDCalendrier();
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
new Migrations().migrate();
|
||||
this.messageDeBienvenue();
|
||||
this.registerUsageCount(SYSTEM_RDD);
|
||||
}
|
||||
|
||||
StatusEffects.onReady();
|
||||
@ -286,14 +276,7 @@ export class SystemReveDeDragon {
|
||||
RdDDice.onReady();
|
||||
/* -------------------------------------------- */
|
||||
/* Affiche/Init le calendrier */
|
||||
let calendrier = new RdDCalendrier();
|
||||
let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html";
|
||||
let templateData = {};
|
||||
renderTemplate(templatePath, templateData).then(html => {
|
||||
calendrier.render(true);
|
||||
});
|
||||
game.system.rdd.calendrier = calendrier; // Reference;
|
||||
|
||||
game.system.rdd.calendrier.display();
|
||||
// Avertissement si joueur sans personnage
|
||||
if (!game.user.isGM && game.user.character == undefined) {
|
||||
ui.notifications.info("Attention ! Vous n'êtes connecté à aucun personnage !");
|
||||
@ -302,10 +285,6 @@ export class SystemReveDeDragon {
|
||||
user: game.user.id
|
||||
});
|
||||
}
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
this.messageDeBienvenue();
|
||||
this.registerUsageCount(SYSTEM_RDD);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -283,12 +283,9 @@ export class RdDResolutionTable {
|
||||
carac: carac,
|
||||
difficulte: level,
|
||||
min: minLevel,
|
||||
rows: RdDResolutionTable.incrementalArray(minCarac, maxCarac),
|
||||
cols: RdDResolutionTable.incrementalArray(minLevel, maxLevel)
|
||||
rows: Misc.intArray(minCarac, maxCarac+1),
|
||||
cols: Misc.intArray(minLevel, maxLevel+1)
|
||||
});
|
||||
}
|
||||
static incrementalArray(min, max) {
|
||||
return Array.from(Array(max-min+1).keys()).map(i=>i+min)
|
||||
}
|
||||
|
||||
}
|
@ -30,9 +30,9 @@ export class RdDEncaisser extends Dialog {
|
||||
};
|
||||
}
|
||||
else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) {
|
||||
dialogConf.default = "cauchemar"
|
||||
dialogConf.default = "entiteincarnee"
|
||||
dialogConf.buttons = {
|
||||
"cauchemar": { label: "Cauchemar", callback: html => this.performEncaisser("cauchemar") }
|
||||
"entiteincarnee": { label: "Entité incarnée", callback: html => this.performEncaisser("entiteincarnee") }
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +70,6 @@ export class RdDEncaisser extends Dialog {
|
||||
total: Number(this.modifier),
|
||||
ajustement: Number(this.modifier),
|
||||
encaisserSpecial: this.encaisserSpecial,
|
||||
loc: { result: 0, label: "" },
|
||||
mortalite: mortalite
|
||||
}
|
||||
});
|
||||
|
@ -7,15 +7,16 @@ export class RdDSheetUtility {
|
||||
const userRightLevel = game.user.isGM
|
||||
? CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER
|
||||
: document.getUserLevel(game.user);
|
||||
mergeObject(options, {
|
||||
let newOptions = {
|
||||
isGM: game.user.isGM,
|
||||
isOwned: document.parent,
|
||||
isOwned: document.parent ? true : false,
|
||||
editable: editable,
|
||||
cssClass: editable ? "editable" : "locked",
|
||||
isLimited: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED,
|
||||
isObserver: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER,
|
||||
isOwner: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER
|
||||
});
|
||||
}
|
||||
mergeObject(options, newOptions);
|
||||
return options;
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,7 @@ import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
import { RdDRencontre } from "./item/rencontre.js";
|
||||
import { RdDCalendrier } from "./rdd-calendrier.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
@ -286,7 +285,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onActionRencontre(action, tmr, rencontre) {
|
||||
if (!this.currentRencontre){
|
||||
if (!this.currentRencontre) {
|
||||
ui.notifications.warn("#612 Rencontre perdue, récupération en cours. Vous pouvez contacter l'équipe avec les logs pour aider à résoudre ce problème")
|
||||
console.error("#612 Rencontre perdue", action, tmr, rencontre, this);
|
||||
this.currentRencontre = rencontre;
|
||||
@ -805,19 +804,21 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async declencheSortEnReserve(coord) {
|
||||
let sorts = this.getSortsReserve(coord);
|
||||
const 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;
|
||||
}
|
||||
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 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>";
|
||||
const reserveSecurite = EffetsDraconiques.isReserveEnSecurite(this.actor);
|
||||
const reserveExtensible = this.isReserveExtensible(coord);
|
||||
if (!EffetsDraconiques.isUrgenceDraconique(this.actor) && (reserveSecurite || reserveExtensible)) {
|
||||
const msg = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-demande-declencher-sort.hbs`, {
|
||||
actor: this.actor,
|
||||
sorts: sorts,
|
||||
coord: coord,
|
||||
tete: { reserveSecurite: reserveSecurite, reserveExtensible: reserveExtensible }
|
||||
})
|
||||
ChatMessage.create({
|
||||
content: msg,
|
||||
whisper: ChatMessage.getWhisperRecipients(game.user.name)
|
||||
@ -1051,6 +1052,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _computeEventOddq(origEvent) {
|
||||
console.log("EVENT", origEvent)
|
||||
let canvasRect = origEvent.target.getBoundingClientRect();
|
||||
let x = origEvent.clientX - canvasRect.left;
|
||||
let y = origEvent.clientY - canvasRect.top;
|
||||
|
@ -2,6 +2,7 @@
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDCombatManager } from "./rdd-combat.js";
|
||||
import { Targets } from "./targets.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDTokenHud {
|
||||
@ -18,29 +19,39 @@ export class RdDTokenHud {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async addExtensionHud(app, html, tokenId) {
|
||||
static async addExtensionHud(app, html, tokenId, isCombat) {
|
||||
|
||||
let token = canvas.tokens.get(tokenId);
|
||||
let actor = token.actor;
|
||||
let combatant = game.combat.combatants.find(c => c.tokenId == tokenId);
|
||||
if (! (combatant?.actor) ) {
|
||||
app.hasExtension = true;
|
||||
// soins
|
||||
await RdDTokenHud.addExtensionHudSoins(html, actor);
|
||||
|
||||
if (isCombat) {
|
||||
let combatant = game.combat.combatants.find(c => c.tokenId == tokenId);
|
||||
if (!(combatant?.actor)) {
|
||||
ui.notifications.warn(`Le combatant ${token.name} n'est pas associé à un acteur, impossible de déterminer ses actions de combat!`)
|
||||
return;
|
||||
}
|
||||
let actions = RdDCombatManager.listActionsCombat(combatant);
|
||||
// initiative
|
||||
await RdDTokenHud.addExtensionHudInit(html, combatant, actions);
|
||||
// combat
|
||||
await RdDTokenHud.addExtensionHudCombat(html, combatant, actions);
|
||||
}
|
||||
app.hasExtension = true;
|
||||
|
||||
let actionsCombat = RdDCombatManager.listActionsCombat(combatant);
|
||||
|
||||
}
|
||||
|
||||
static async addExtensionHudInit(html, combatant, actions) {
|
||||
const hudData = {
|
||||
combatant: combatant,
|
||||
actions: actionsCombat,
|
||||
combatant, actions,
|
||||
commandes: [
|
||||
{ name: "Autre action", command: 'autre' },
|
||||
{ name: 'Initiative +1', command: 'inc', value: 0.01 },
|
||||
{ name: 'Initiative +1', command: 'inc', value: 0.01 },
|
||||
{ name: 'Initiative -1', command: 'dec', value: -0.01 }]
|
||||
};
|
||||
|
||||
const controlIconCombat = html.find('.control-icon[data-action=combat]');
|
||||
// initiative
|
||||
await RdDTokenHud._configureSubMenu(controlIconCombat,
|
||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
|
||||
hudData,
|
||||
@ -51,48 +62,70 @@ export class RdDTokenHud {
|
||||
RdDTokenHud._initiativeCommand(initCommand, combatantId);
|
||||
} else {
|
||||
let index = event.currentTarget.attributes['data-action-index'].value;
|
||||
let action = actionsCombat[index];
|
||||
let action = hudData.actions[index];
|
||||
RdDCombatManager.rollInitiativeAction(combatantId, action);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static async addExtensionHudCombat(html, combatant, actions) {
|
||||
const hudData = { combatant, actions, commandes: [] };
|
||||
const controlIconTarget = html.find('.control-icon[data-action=target]');
|
||||
// combat
|
||||
await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData,
|
||||
(event) => {
|
||||
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
|
||||
const action = actionsCombat[actionIndex];
|
||||
const action = hudData.actions[actionIndex];
|
||||
if (action.action == 'conjurer') {
|
||||
actor.conjurerPossession(actor.getPossession(action.system.possessionid));
|
||||
const possession = combatant.actor.getPossession(action.system.possessionid);
|
||||
combatant.actor.conjurerPossession(possession);
|
||||
}
|
||||
else {
|
||||
actor.rollArme(action);
|
||||
combatant.actor.rollArme(action);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static async addExtensionHudSoins(html, sourceActor) {
|
||||
const target = Targets.getTarget({ warn: false });
|
||||
if (target?.actor) {
|
||||
const hudSoins = { blessures: target.actor.blessuresASoigner() ?? [] };
|
||||
if (hudSoins.blessures.length > 0) {
|
||||
// soins
|
||||
const controlIconTarget = html.find('.control-icon[data-action=combat]');
|
||||
await RdDTokenHud._configureSubMenu(controlIconTarget,
|
||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs',
|
||||
hudSoins,
|
||||
(event) => {
|
||||
const blessureId = event.currentTarget.attributes['data-blessure-id']?.value;
|
||||
sourceActor.rollSoins(target.actor, blessureId)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static _initiativeCommand(initCommand, combatantId) {
|
||||
switch (initCommand) {
|
||||
case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01);
|
||||
case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01);
|
||||
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
|
||||
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
|
||||
{ name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async addTokenHudExtensions(app, html, tokenId) {
|
||||
const controlIconCombat = html.find('.control-icon[data-action=combat]');
|
||||
controlIconCombat.click(event => {
|
||||
if (event.currentTarget.className.includes('active')) {
|
||||
RdDTokenHud.removeExtensionHud(app, html, tokenId);
|
||||
} else {
|
||||
setTimeout(function () { RdDTokenHud.addExtensionHud(app, html, tokenId) }, 200);
|
||||
}
|
||||
});
|
||||
const controlIconCombat = html.find('.control-icon[data-action=combat]');
|
||||
if (controlIconCombat.length > 0) {
|
||||
controlIconCombat.click(event => {
|
||||
if (event.currentTarget.className.includes('active')) {
|
||||
RdDTokenHud.removeExtensionHud(app, html, tokenId);
|
||||
} else {
|
||||
setTimeout(() => RdDTokenHud.addExtensionHud(app, html, tokenId), 200);
|
||||
}
|
||||
});
|
||||
|
||||
if (controlIconCombat.length>0 && controlIconCombat[0].className.includes('active')) {
|
||||
RdDTokenHud.addExtensionHud(app, html, tokenId);
|
||||
const isCombat = controlIconCombat[0].className.includes('active');
|
||||
RdDTokenHud.addExtensionHud(app, html, tokenId, isCombat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,9 +133,9 @@ export class RdDTokenHud {
|
||||
static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) {
|
||||
const hud = $(await renderTemplate(template, hudData));
|
||||
const list = hud.find('div.rdd-hud-list');
|
||||
|
||||
|
||||
RdDTokenHud._toggleHudListActive(hud, list);
|
||||
|
||||
|
||||
hud.find('img.rdd-hud-togglebutton').click(event => RdDTokenHud._toggleHudListActive(hud, list));
|
||||
list.find('.rdd-hud-menu').click(onMenuItem);
|
||||
|
||||
|
@ -13,15 +13,17 @@ import { RdDNameGen } from "./rdd-namegen.js";
|
||||
import { RdDConfirm } from "./rdd-confirm.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
import { RdDRaretes } from "./item/raretes.js";
|
||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||
import { ExperienceLog } from "./actor/experience-log.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// This table starts at 0 -> niveau -10
|
||||
const carac_array = ["taille", "apparence", "constitution", "force", "agilite", "dexterite", "vue", "ouie", "odoratgout", "volonte", "intellect", "empathie", "reve", "chance", "melee", "tir", "lancer", "derobee"];
|
||||
const difficultesLibres = [0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10];
|
||||
const ajustementsConditions = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10];
|
||||
const ajustementsEncaissement = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13, +14, +15, +16, +17, +18, +19, +20, +21, +22, +23, +24, +25];
|
||||
const difficultesLibres = Misc.intArray(0, -11);
|
||||
const ajustementsConditions = Misc.intArray(-10, 11);
|
||||
const ajustementsEncaissement = Misc.intArray(-10, 26);
|
||||
|
||||
/* -------------------------------------------- */
|
||||
function _buildAllSegmentsFatigue(max) {
|
||||
@ -66,38 +68,31 @@ const fatigueMarche = {
|
||||
"tresdifficile": { "4": 4, "6": 6 }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const definitionsBlessures = [
|
||||
{ type: "legere", facteur: 2 },
|
||||
{ type: "grave", facteur: 4 },
|
||||
{ type: "critique", facteur: 6 }
|
||||
]
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const nomEthylisme = ["Emeché", "Gris", "Pinté", "Pas frais", "Ivre", "Bu", "Complètement fait", "Ivre mort"];
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const definitionsEncaissement = {
|
||||
"mortel": [
|
||||
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
|
||||
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "2", eraflures: 0, legeres: 0, graves: 1, critiques: 0 },
|
||||
{ minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", eraflures: 0, legeres: 0, graves: 0, critiques: 1 },
|
||||
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
|
||||
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0},
|
||||
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2},
|
||||
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4},
|
||||
{ minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6},
|
||||
],
|
||||
"non-mortel": [
|
||||
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
|
||||
{ minimum: 20, maximum: undefined, endurance: "100", vie: "0", eraflures: 0, legeres: 1, graves: 0, critiques: 0 },
|
||||
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
|
||||
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 },
|
||||
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 },
|
||||
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 },
|
||||
{ minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 },
|
||||
],
|
||||
"cauchemar": [
|
||||
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", eraflures: 0, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
|
||||
{ minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", eraflures: 1, legeres: 0, graves: 0, critiques: 0 },
|
||||
"entiteincarnee": [
|
||||
{ minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1},
|
||||
{ minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0},
|
||||
{ minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 },
|
||||
{ minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 0 },
|
||||
{ minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 0 },
|
||||
]
|
||||
};
|
||||
|
||||
@ -139,9 +134,10 @@ export class RdDUtility {
|
||||
'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/blessure.hbs',
|
||||
'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/resonances.hbs',
|
||||
'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',
|
||||
@ -203,6 +199,7 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html',
|
||||
// Partials
|
||||
'systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats-recherche.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/time/horloge.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/common/timestamp.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/common/periodicite.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/common/enum-duree.hbs',
|
||||
@ -234,11 +231,10 @@ export class RdDUtility {
|
||||
'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',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs',
|
||||
// Calendrier
|
||||
'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/sommeil/astrologie-gardien.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/sommeil/astrologie-joueur.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/sommeil/astrologie-theme.hbs',
|
||||
// HUD
|
||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html',
|
||||
@ -247,20 +243,6 @@ export class RdDUtility {
|
||||
'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',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-appelchance.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-attaque.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-parade.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-esquive.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-competence.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-general.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-tache.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-sort.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-alchimie.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-resultat-possession.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html',
|
||||
@ -274,7 +256,8 @@ export class RdDUtility {
|
||||
Handlebars.registerHelper('computeResolutionChances', (row, col) => RdDResolutionTable.computeChances(row, col));
|
||||
Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
|
||||
Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
|
||||
Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL');
|
||||
Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? '');
|
||||
Handlebars.registerHelper('lowercase', str => str?.toLowerCase() ?? '');
|
||||
Handlebars.registerHelper('le', str => Grammar.articleDetermine(str));
|
||||
Handlebars.registerHelper('apostrophe', (article, str) => Grammar.apostrophe(article, str));
|
||||
Handlebars.registerHelper('un', str => Grammar.articleIndetermine(str));
|
||||
@ -302,6 +285,9 @@ export class RdDUtility {
|
||||
Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite());
|
||||
Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field));
|
||||
Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field));
|
||||
|
||||
Handlebars.registerHelper('experienceLog-topic', topic => ExperienceLog.labelTopic(topic));
|
||||
|
||||
return loadTemplates(templatePaths);
|
||||
}
|
||||
|
||||
@ -470,10 +456,6 @@ export class RdDUtility {
|
||||
return ajustementsEncaissement;
|
||||
}
|
||||
|
||||
static getDefinitionsBlessures() {
|
||||
return definitionsBlessures;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getSegmentsFatigue(maxEnd) {
|
||||
maxEnd = Math.max(maxEnd, 1);
|
||||
@ -614,17 +596,10 @@ export class RdDUtility {
|
||||
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;';
|
||||
encaissement.roll = roll;
|
||||
encaissement.armure = armure;
|
||||
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -719,6 +694,44 @@ export class RdDUtility {
|
||||
RdDPossession.onDefensePossession(attackerId, defenderId, possessionId)
|
||||
});
|
||||
|
||||
html.on("click", '.defense-empoignade-cac', event => {
|
||||
const chatMessage = ChatUtility.getChatMessage(event);
|
||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
||||
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
||||
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Corps à corps", "melee")
|
||||
});
|
||||
html.on("click", '.defense-empoignade-esquive', event => {
|
||||
const chatMessage = ChatUtility.getChatMessage(event);
|
||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
||||
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
|
||||
RdDEmpoignade.onDefenseEmpoignade(rollData, defenseMode, "Esquive", "derobee")
|
||||
});
|
||||
html.on("click", '.empoignade-poursuivre', event => {
|
||||
let attackerId = event.currentTarget.attributes['data-attackerId'].value
|
||||
let defenderId = event.currentTarget.attributes['data-defenderId'].value
|
||||
RdDEmpoignade.onAttaqueEmpoignadeValidee(game.actors.get(attackerId), game.actors.get(defenderId))
|
||||
});
|
||||
html.on("click", '.empoignade-entrainer-sol', event => {
|
||||
const chatMessage = ChatUtility.getChatMessage(event);
|
||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
||||
RdDEmpoignade.entrainerAuSol(rollData)
|
||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||
});
|
||||
html.on("click", '.empoignade-projeter-sol', event => {
|
||||
const chatMessage = ChatUtility.getChatMessage(event);
|
||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
||||
RdDEmpoignade.projeterAuSol(rollData)
|
||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||
});
|
||||
html.on("change", '.empoignade-perte-endurance', event => {
|
||||
const chatMessage = ChatUtility.getChatMessage(event);
|
||||
const rollData = ChatUtility.getMessageData(chatMessage, 'empoignade-roll-data');
|
||||
if (event.currentTarget.value && event.currentTarget.value != "none") {
|
||||
RdDEmpoignade.perteEndurance(rollData, event.currentTarget.value)
|
||||
ChatUtility.removeChatMessageId(chatMessage.id)
|
||||
}
|
||||
});
|
||||
|
||||
// gestion bouton tchat Acheter
|
||||
html.on("click", '.button-acheter', event => {
|
||||
const venteData = DialogItemAchat.preparerAchat(event.currentTarget);
|
||||
@ -851,17 +864,13 @@ export class RdDUtility {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete) {
|
||||
static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete, onSuppression = ()=>{}) {
|
||||
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);
|
||||
}
|
||||
onAction: onSuppression
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,12 @@ export const referenceAjustements = {
|
||||
isUsed: (rollData, actor) => rollData.ethylisme != undefined,
|
||||
getLabel: (rollData, actor) => "Ethylisme - " + RdDUtility.getNomEthylisme(rollData.ethylisme),
|
||||
getValue: (rollData, actor) => rollData.ethylisme,
|
||||
},
|
||||
tailleempoignade: {
|
||||
isVisible: (rollData, actor) => rollData.isEmpoignade,
|
||||
isUsed: (rollData, actor) => rollData.isEmpoignade,
|
||||
getLabel: (rollData, actor) => "Malus de taille",
|
||||
getValue: (rollData, actor) => rollData.malusTaille,
|
||||
}
|
||||
}
|
||||
|
||||
|
206
module/sommeil/app-astrologie.js
Normal file
206
module/sommeil/app-astrologie.js
Normal file
@ -0,0 +1,206 @@
|
||||
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDTimestamp } from "../time/rdd-timestamp.js";
|
||||
|
||||
export const APP_ASTROLOGIE_REFRESH = `${SYSTEM_RDD}-refresh-astrologie`
|
||||
|
||||
export class AppAstrologie extends Application {
|
||||
static async create(actor = undefined, options = {}) {
|
||||
if (actor == undefined && !game.user.isGM) {
|
||||
actor = game.user.character
|
||||
}
|
||||
if (!actor && !game.user.isGM) {
|
||||
console.error("AppAstrologie uniquement accessible pour le MJ, ou depuis un personnage pour un joueur")
|
||||
}
|
||||
new AppAstrologie(actor, options).render(true);
|
||||
}
|
||||
|
||||
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
template: "systems/foundryvtt-reve-de-dragon/templates/sommeil/app-astrologie.hbs",
|
||||
title: "Astrologie",
|
||||
width: 'fit-content',
|
||||
height: 'fit-content',
|
||||
classes: ['calendar-astrologie'],
|
||||
popOut: true,
|
||||
resizable: false
|
||||
});
|
||||
}
|
||||
|
||||
constructor(actor, options = {}) {
|
||||
super(options);
|
||||
this.actor = actor;
|
||||
this.hookReference = Hooks.on(APP_ASTROLOGIE_REFRESH, () => this.refreshAstrologie());
|
||||
}
|
||||
|
||||
getData(options) {
|
||||
this.appData = super.getData(options)
|
||||
const calendrier = game.system.rdd.calendrier;
|
||||
mergeObject(this.appData, {
|
||||
isGM: game.user.isGM,
|
||||
isActor: this.actor != undefined,
|
||||
calendrier: calendrier.getTimestamp().toCalendrier(),
|
||||
dates: calendrier.getJoursSuivants(10),
|
||||
heures: RdDTimestamp.definitions(),
|
||||
actorAstrologie: this.getActorAstrologie(),
|
||||
gmAstrologie: this.getGMAstrologie(calendrier),
|
||||
theme: {
|
||||
signeAstral: RdDTimestamp.definition(0),
|
||||
signeNaissance: RdDTimestamp.definition(0)
|
||||
}
|
||||
})
|
||||
return this.appData;
|
||||
}
|
||||
|
||||
getActorAstrologie() {
|
||||
if (this.actor) {
|
||||
return {
|
||||
actor: this.actor,
|
||||
nombres: this._organizeNombresAstraux(this.actor.itemTypes['nombreastral']),
|
||||
ajustements: CONFIG.RDD.difficultesLibres,
|
||||
etat: this.actor.getEtatGeneral(),
|
||||
astrologie: this.actor.getCompetence('Astrologie')
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
_organizeNombresAstraux(nombresAstraux) {
|
||||
let organized = {};
|
||||
nombresAstraux.forEach(na => {
|
||||
if (!organized[na.system.jourindex]) {
|
||||
organized[na.system.jourindex] = {
|
||||
listValues: [],
|
||||
jourlabel: na.system.jourlabel
|
||||
}
|
||||
}
|
||||
organized[na.system.jourindex].listValues.push(na.system.value);
|
||||
})
|
||||
return organized;
|
||||
}
|
||||
|
||||
getGMAstrologie(calendrier) {
|
||||
if (game.user.isGM) {
|
||||
const nbAstral = calendrier.getNombreAstral()
|
||||
const heures = RdDTimestamp.heures();
|
||||
return {
|
||||
ajustementsActors: game.actors.filter(it => it.isPersonnage() && it.hasPlayerOwner)
|
||||
.map(actor => this.getAjustementActor(actor, nbAstral, heures)),
|
||||
nombresAstraux: calendrier.getNombresAstraux().map(na => this.getDetailNombreAstral(na))
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
getAjustementActor(actor, nbAstral, heures) {
|
||||
const hn = RdDTimestamp.findHeure(actor.getHeureNaissance())?.heure ?? 0;
|
||||
return {
|
||||
actor,
|
||||
ajustements: heures.map(heure => {
|
||||
return { heure, ajustement: RdDTimestamp.ajustementAstrologiqueHeure(hn, nbAstral, heure) };
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getDetailNombreAstral(nombreAstral) {
|
||||
const detail = duplicate(nombreAstral);
|
||||
const timestamp = new RdDTimestamp({ indexDate: nombreAstral.index });
|
||||
detail.date = { mois: timestamp.mois, jour: timestamp.jour + 1 };
|
||||
detail.valeursFausses.forEach(fausse => fausse.actorName = game.actors.get(fausse.actorId).name ?? "Inconnu");
|
||||
return detail;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this.html = html;
|
||||
this.html.find('select[name="signe-astral"]').change(event => {
|
||||
this.selectNombreAstral(this.html.find('select[name="signe-astral"]').val());
|
||||
})
|
||||
this.html.find('select[name="signe-naissance"]').change(event => {
|
||||
this.selectHeureNaissance(this.html.find('select[name="signe-naissance"]').val());
|
||||
})
|
||||
this.html.find('td.nombre-astral').click(event => {
|
||||
this.selectNombreAstral(Number.parseInt(event.currentTarget.attributes['data-nombre-astral'].value) - 1);
|
||||
})
|
||||
this.html.find('tr.heure-naissance').click(event => {
|
||||
this.selectHeureNaissance(event.currentTarget.attributes['data-heure-naissance'].value);
|
||||
})
|
||||
this.html.find('[name="jet-astrologie"]').click(event => this.requestJetAstrologie());
|
||||
this.html.find('[name="rebuild-nombres-astraux"]').click(event => this.rebuildNombresAstraux());
|
||||
|
||||
this.onCalculThemeAstral();
|
||||
}
|
||||
|
||||
selectHeureNaissance(heureNaissance) {
|
||||
this.appData.theme.signeNaissance = RdDTimestamp.definition(heureNaissance);
|
||||
this.onCalculThemeAstral();
|
||||
}
|
||||
|
||||
selectNombreAstral(nombreAstral) {
|
||||
this.appData.theme.signeAstral = RdDTimestamp.definition(nombreAstral);
|
||||
this.onCalculThemeAstral();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rebuildNombresAstraux() {
|
||||
game.system.rdd.calendrier.resetNombresAstraux();
|
||||
|
||||
await game.system.rdd.calendrier.rebuildNombresAstraux();
|
||||
}
|
||||
|
||||
onCalculThemeAstral() {
|
||||
const chiffreAstral = this.appData.theme.signeAstral.heure + 1;
|
||||
const heureNaissance = this.appData.theme.signeNaissance.heure + 1;
|
||||
RdDTimestamp.definitions().forEach(dh => {
|
||||
const ajustement = RdDTimestamp.ajustementAstrologiqueHeure(heureNaissance, chiffreAstral, dh.heure + 1);
|
||||
const txtAjustement = ajustement == 0 ? '' : Misc.toSignedString(ajustement);
|
||||
this.html.find(`div.horloge-ajustement.heure-${dh.hh}`).text(txtAjustement)
|
||||
});
|
||||
|
||||
this.html.find(`select[name="signe-astral"]`).val(this.appData.theme.signeAstral.key)
|
||||
this.html.find(`select[name="signe-naissance"]`).val(this.appData.theme.signeNaissance.key)
|
||||
|
||||
const angleAstrologie = ((chiffreAstral + heureNaissance) * 30) % 360 - 45;
|
||||
this.html.find(`div.horloge-roue div.disque-astro img`).css(Misc.cssRotation(angleAstrologie));
|
||||
|
||||
const timestamp = game.system.rdd.calendrier.getTimestamp();
|
||||
|
||||
this.html.find(`div.horloge-roue div.horloge-aiguille-heure img`).css(Misc.cssRotation(timestamp.angleHeure));
|
||||
this.html.find(`div.horloge-roue div.horloge-aiguille-minute img`).css(Misc.cssRotation(timestamp.angleMinute));
|
||||
}
|
||||
|
||||
requestJetAstrologie() {
|
||||
if (!this.appData?.isActor) {
|
||||
return
|
||||
}
|
||||
let socketData = {
|
||||
id: this.appData.actorAstrologie.actor.id,
|
||||
carac_vue: this.actor.system.carac['vue'].value,
|
||||
etat: this.actor.getEtatGeneral(),
|
||||
astrologie: this.actor.getCompetence('Astrologie'),
|
||||
conditions: this.html.find('[name="diffConditions"]').val(),
|
||||
date: this.html.find('[name="joursAstrologie"]').val(),
|
||||
userId: game.user.id
|
||||
}
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
game.system.rdd.calendrier.requestNombreAstral(socketData);
|
||||
} else {
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_request_nombre_astral",
|
||||
data: socketData
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
refreshAstrologie() {
|
||||
this.render(true)
|
||||
}
|
||||
|
||||
async close(options) {
|
||||
Hooks.off(APP_ASTROLOGIE_REFRESH, this.hookReference);
|
||||
this.hookReference = undefined
|
||||
await super.close(options)
|
||||
}
|
||||
}
|
@ -4,7 +4,10 @@ import { EffetsDraconiques } from "../tmr/effets-draconiques.js";
|
||||
export class DialogRepos extends Dialog {
|
||||
|
||||
static async create(actor) {
|
||||
if (!ReglesOptionelles.isUsing("chateau-dormant-gardien")) {
|
||||
if (!actor.isPersonnage()) {
|
||||
return
|
||||
}
|
||||
if (!ReglesOptionelles.isUsing("chateau-dormant-gardien") || !actor.hasPlayerOwner) {
|
||||
actor.system.sommeil = {
|
||||
"nouveaujour": true,
|
||||
"insomnie": EffetsDraconiques.isSujetInsomnie(actor),
|
||||
|
@ -1,58 +0,0 @@
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDCalendrier } from "../rdd-calendrier.js";
|
||||
import { RdDTimestamp } from "../rdd-timestamp.js";
|
||||
|
||||
export class ThemeAstral extends Application {
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
template: "systems/foundryvtt-reve-de-dragon/templates/sommeil/theme-astral.hbs",
|
||||
title: "Thème astral",
|
||||
width: 'fit-content',
|
||||
height: 'fit-content',
|
||||
popOut: true,
|
||||
resizable: false
|
||||
});
|
||||
}
|
||||
|
||||
static async create() {
|
||||
new ThemeAstral().render(true);
|
||||
}
|
||||
constructor() {
|
||||
super({});
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this.html = html;
|
||||
this.html.find('select[name="signe-astral"]').change(event => {
|
||||
this.onCalculThemeAstral();
|
||||
})
|
||||
this.html.find('select[name="signe-naissance"]').change(event => {
|
||||
this.onCalculThemeAstral();
|
||||
})
|
||||
this.onCalculThemeAstral();
|
||||
}
|
||||
|
||||
onCalculThemeAstral() {
|
||||
const signeAstral = RdDTimestamp.definition(this.html.find('select[name="signe-astral"]').val())
|
||||
const chiffreAstral = signeAstral.heure + 1;
|
||||
const signeNaissance = RdDTimestamp.definition(this.html.find('select[name="signe-naissance"]').val())
|
||||
const heureNaissance = signeNaissance.heure + 1;
|
||||
const heureChance = (chiffreAstral + heureNaissance) % 12 + 1
|
||||
RdDTimestamp.definitions().forEach(dh => {
|
||||
const ajustement = RdDCalendrier.ajustementAstrologiqueHeure(heureNaissance, chiffreAstral, dh.heure + 1);
|
||||
const txtAjustement = ajustement == 0 ? '' : Misc.toSignedString(ajustement);
|
||||
this.html.find(`div.astro-ajustement.ajustement-${dh.hh}`).text(txtAjustement)
|
||||
});
|
||||
|
||||
const angle = (heureChance * 30 + 330) % 360;
|
||||
const rotation = `rotate(${angle}deg)`;
|
||||
this.html.find(`div.astro-roue div.astro-disque img`).css({
|
||||
'transform': rotation,
|
||||
'-ms-transform': rotation,
|
||||
'-moz-transform': rotation,
|
||||
'-webkit-transform': rotation,
|
||||
'-o-transform': rotation
|
||||
});
|
||||
}
|
||||
}
|
@ -39,18 +39,18 @@ export class Targets {
|
||||
}
|
||||
}
|
||||
|
||||
static getTarget() {
|
||||
static getTarget(options = { warn: true }) {
|
||||
const targets = Targets.listTargets();
|
||||
switch (targets.length) {
|
||||
case 1:
|
||||
return targets[0];
|
||||
case 0:
|
||||
ui.notifications.warn("Vous devez choisir une cible à attaquer!");
|
||||
if (options.warn) ui.notifications.warn("Vous devez choisir une cible à attaquer!");
|
||||
break;
|
||||
default:
|
||||
ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
|
||||
return;
|
||||
if (options.warn) ui.notifications.warn("Vous devez choisir une cible (et <strong>une seule</strong>) à attaquer!");
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,7 @@ import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||
* @extends {Dialog}
|
||||
*/
|
||||
export class RdDCalendrierEditeur extends Dialog {
|
||||
export class RdDCalendrierEditor extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(html, calendrier, calendrierData) {
|
||||
@ -30,8 +30,8 @@ export class RdDCalendrierEditeur extends Dialog {
|
||||
this.html.find("input[name='calendar.annee']").val(this.calendrierData.annee);
|
||||
this.html.find("select[name='calendar.mois']").val(this.calendrierData.mois.key);
|
||||
this.html.find("select[name='calendar.heure']").val(this.calendrierData.heure.key);
|
||||
RdDCalendrierEditeur.setLimited(this.html.find("input[name='calendar.jourDuMois']"), this.calendrierData.jourDuMois, 1, 28);
|
||||
RdDCalendrierEditeur.setLimited(this.html.find("input[name='calendar.minute']"), this.calendrierData.minute, 0, 119);
|
||||
RdDCalendrierEditor.setLimited(this.html.find("input[name='calendar.jourDuMois']"), this.calendrierData.jourDuMois, 1, 28);
|
||||
RdDCalendrierEditor.setLimited(this.html.find("input[name='calendar.minute']"), this.calendrierData.minute, 0, 119);
|
||||
}
|
||||
|
||||
static setLimited(input, init, min, max) {
|
455
module/time/rdd-calendrier.js
Normal file
455
module/time/rdd-calendrier.js
Normal file
@ -0,0 +1,455 @@
|
||||
import { MAX_NOMBRE_ASTRAL, RdDTimestamp, WORLD_TIMESTAMP_SETTING } from "./rdd-timestamp.js";
|
||||
import { RdDCalendrierEditor } from "./rdd-calendrier-editor.js";
|
||||
import { RdDResolutionTable } from "../rdd-resolution-table.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { DialogChronologie } from "../dialog-chronologie.js";
|
||||
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { ReglesOptionelles } from "../settings/regles-optionelles.js";
|
||||
import { DialogChateauDormant } from "../sommeil/dialog-chateau-dormant.js";
|
||||
import { APP_ASTROLOGIE_REFRESH, AppAstrologie } from "../sommeil/app-astrologie.js";
|
||||
|
||||
const TEMPLATE_CALENDRIER = "systems/foundryvtt-reve-de-dragon/templates/time/calendar.hbs";
|
||||
|
||||
const INITIAL_CALENDAR_POS = { top: 200, left: 200, horlogeAnalogique: true };
|
||||
/* -------------------------------------------- */
|
||||
export class RdDCalendrier extends Application {
|
||||
static init() {
|
||||
game.settings.register(SYSTEM_RDD, "liste-nombre-astral", {
|
||||
name: "liste-nombre-astral",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: [],
|
||||
type: Object
|
||||
});
|
||||
|
||||
game.settings.register(SYSTEM_RDD, "calendrier-pos", {
|
||||
name: "calendrierPos",
|
||||
scope: "client",
|
||||
config: false,
|
||||
default: INITIAL_CALENDAR_POS,
|
||||
type: Object
|
||||
});
|
||||
}
|
||||
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
title: "Calendrier",
|
||||
template: TEMPLATE_CALENDRIER,
|
||||
classes: ["calendar"],
|
||||
popOut: true,
|
||||
resizable: false,
|
||||
width: 'fit-content',
|
||||
height: 'fit-content',
|
||||
});
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.timestamp = RdDTimestamp.getWorldTime();
|
||||
if (Misc.isUniqueConnectedGM()) { // Uniquement si GM
|
||||
RdDTimestamp.setWorldTime(this.timestamp);
|
||||
this.nombresAstraux = this.getNombresAstraux();
|
||||
this.rebuildNombresAstraux(HIDE_DICE); // Ensure always up-to-date
|
||||
}
|
||||
Hooks.on('updateSetting', async (setting, update, options, id) => this.onUpdateSetting(setting, update, options, id));
|
||||
}
|
||||
|
||||
get title() {
|
||||
const calendrier = this.timestamp.toCalendrier();
|
||||
return `${calendrier.heure.label}, ${calendrier.jourDuMois} ${calendrier.mois.label} ${calendrier.annee} (${calendrier.mois.saison})`;
|
||||
}
|
||||
|
||||
savePosition() {
|
||||
game.settings.set(SYSTEM_RDD, "calendrier-pos", {
|
||||
top: this.position.top,
|
||||
left: this.position.left,
|
||||
horlogeAnalogique: this.horlogeAnalogique
|
||||
});
|
||||
}
|
||||
|
||||
getSavePosition() {
|
||||
const pos = game.settings.get(SYSTEM_RDD, "calendrier-pos");
|
||||
if (pos?.top == undefined) {
|
||||
return INITIAL_CALENDAR_POS;
|
||||
}
|
||||
this.horlogeAnalogique = pos.horlogeAnalogique;
|
||||
return pos
|
||||
}
|
||||
|
||||
setPosition(position) {
|
||||
super.setPosition(position)
|
||||
this.savePosition()
|
||||
}
|
||||
|
||||
display() {
|
||||
const pos = this.getSavePosition()
|
||||
this.render(true, { left: pos.left, top: pos.top });
|
||||
return this;
|
||||
}
|
||||
|
||||
_getHeaderButtons() {
|
||||
const buttons = [];
|
||||
if (game.user.isGM) {
|
||||
buttons.unshift({
|
||||
class: "calendar-astrologie",
|
||||
icon: "fa-solid fa-moon-over-sun",
|
||||
onclick: ev => this.showAstrologieEditor()
|
||||
},
|
||||
{
|
||||
class: "calendar-set-datetime",
|
||||
icon: "fa-solid fa-calendar-pen",
|
||||
onclick: ev => this.showCalendarEditor()
|
||||
});
|
||||
}
|
||||
return buttons
|
||||
}
|
||||
|
||||
/*async maximize() {
|
||||
await super.maximize()
|
||||
this.render(true)
|
||||
}*/
|
||||
|
||||
async close() { }
|
||||
|
||||
async onUpdateSetting(setting, update, options, id) {
|
||||
if (setting.key == SYSTEM_RDD + '.' + WORLD_TIMESTAMP_SETTING) {
|
||||
this.timestamp = RdDTimestamp.getWorldTime();
|
||||
this.positionAiguilles()
|
||||
this.render(false);
|
||||
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
|
||||
}
|
||||
}
|
||||
|
||||
getData() {
|
||||
const formData = super.getData();
|
||||
this.fillCalendrierData(formData);
|
||||
return formData;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
fillCalendrierData(formData = {}) {
|
||||
mergeObject(formData, this.timestamp.toCalendrier());
|
||||
formData.isGM = game.user.isGM;
|
||||
formData.heures = RdDTimestamp.definitions()
|
||||
formData.horlogeAnalogique = this.horlogeAnalogique;
|
||||
return formData;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
async activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
this.html = html;
|
||||
this.html.find('.ajout-chronologie').click(ev => DialogChronologie.create());
|
||||
this.html.find('.toggle-horloge-analogique').click(ev => this.onToggleHorlogeAnalogique())
|
||||
this.html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
|
||||
this.html.find('.horloge-roue .horloge-heure').click(event => {
|
||||
const h = this.html.find(event.currentTarget)?.data('heure');
|
||||
this.positionnerHeure(Number(h));
|
||||
})
|
||||
this.html.find('.calendar-set-datetime').click(ev => {
|
||||
ev.preventDefault();
|
||||
this.showCalendarEditor();
|
||||
});
|
||||
|
||||
this.html.find('.calendar-astrologie').click(ev => {
|
||||
ev.preventDefault();
|
||||
this.showAstrologieEditor();
|
||||
});
|
||||
this.positionAiguilles()
|
||||
}
|
||||
|
||||
positionAiguilles() {
|
||||
const timestamp = this.getTimestamp();
|
||||
this.html.find(`div.horloge-roue div.horloge-aiguille-heure img`).css(Misc.cssRotation(timestamp.angleHeure));
|
||||
this.html.find(`div.horloge-roue div.horloge-aiguille-minute img`).css(Misc.cssRotation(timestamp.angleMinute));
|
||||
}
|
||||
|
||||
onToggleHorlogeAnalogique() {
|
||||
this.horlogeAnalogique = !this.horlogeAnalogique;
|
||||
this.savePosition()
|
||||
this.display()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getNombresAstraux() {
|
||||
return game.settings.get(SYSTEM_RDD, "liste-nombre-astral") ?? [];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
dateCourante() {
|
||||
return this.timestamp.formatDate();
|
||||
}
|
||||
|
||||
dateReel() {
|
||||
return new Date().toLocaleString("sv-SE", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit"
|
||||
});
|
||||
}
|
||||
|
||||
isAfterIndexDate(indexDate) {
|
||||
// TODO: standardize
|
||||
return indexDate < this.timestamp.indexDate;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
heureCourante() { return RdDTimestamp.definition(this.timestamp.heure); }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCurrentMinute() { return this.timestamp.indexMinute; }
|
||||
|
||||
getTimestamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
getTimestampFinChateauDormant(nbJours = 0) {
|
||||
return this.timestamp.nouveauJour().addJours(nbJours);
|
||||
}
|
||||
|
||||
getTimestampFinHeure(nbHeures = 0) {
|
||||
return this.timestamp.nouvelleHeure().addHeures(nbHeures);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getIndexFromDate(jour, mois) {
|
||||
const addYear = mois < this.timestamp.mois || (mois == this.timestamp.mois && jour < this.timestamp.jour)
|
||||
const time = RdDTimestamp.timestamp(this.timestamp.annee + (addYear ? 1 : 0), mois, jour);
|
||||
return time.indexDate;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getJoursSuivants(count) {
|
||||
return Misc.intArray(this.timestamp.indexDate, this.timestamp.indexDate + count)
|
||||
.map(i => { return { label: RdDTimestamp.formatIndexDate(i), index: i } })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async ajouterNombreAstral(indexDate, showDice = SHOW_DICE) {
|
||||
const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showDice, rollMode: "selfroll" });
|
||||
const dateFuture = RdDTimestamp.formatIndexDate(indexDate);
|
||||
if (showDice != HIDE_DICE) {
|
||||
ChatMessage.create({
|
||||
whisper: ChatMessage.getWhisperRecipients("GM"),
|
||||
content: `Le chiffre astrologique du ${dateFuture} sera le ${nombreAstral}`
|
||||
});
|
||||
}
|
||||
return {
|
||||
nombreAstral: nombreAstral,
|
||||
valeursFausses: [],
|
||||
index: indexDate
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
resetNombresAstraux() {
|
||||
this.nombresAstraux = [];
|
||||
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", []);
|
||||
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_reset_nombre_astral",
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} indexDate la date pour laquelle obtenir le nombre astral. Si undefined, on prend la date du jour
|
||||
* @returns le nombre astral pour la date, ou pour la date du jour si la date n'est pas fournie.
|
||||
* Si aucun nombre astral n'est trouvé, retourne 0 (cas où l'on demanderait un nombre astral en dehors des 12 jours courant et à venir)
|
||||
*/
|
||||
getNombreAstral(indexDate = undefined) {
|
||||
if (indexDate == undefined) {
|
||||
indexDate = this.timestamp.indexDate;
|
||||
}
|
||||
this.nombresAstraux = this.getNombresAstraux();
|
||||
let astralData = this.nombresAstraux.find((nombreAstral, i) => nombreAstral.index == indexDate);
|
||||
return astralData?.nombreAstral ?? 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rebuildNombresAstraux(showDice = HIDE_DICE) {
|
||||
if (Misc.isUniqueConnectedGM()) {
|
||||
console.log("Astral rebuild")
|
||||
let newList = [];
|
||||
for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) {
|
||||
let dayIndex = this.timestamp.indexDate + i;
|
||||
let na = this.nombresAstraux.find(n => n.index == dayIndex);
|
||||
if (na) {
|
||||
newList[i] = na;
|
||||
} else {
|
||||
newList[i] = await this.ajouterNombreAstral(dayIndex, showDice);
|
||||
}
|
||||
}
|
||||
this.nombresAstraux = newList;
|
||||
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", newList);
|
||||
game.actors.filter(it => it.isPersonnage()).forEach(actor => actor.supprimerAnciensNombresAstraux());
|
||||
this.notifyChangeNombresAstraux();
|
||||
}
|
||||
}
|
||||
|
||||
notifyChangeNombresAstraux() {
|
||||
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_refresh_nombre_astral",
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setNewTimestamp(newTimestamp) {
|
||||
const oldTimestamp = this.timestamp;
|
||||
await Promise.all(game.actors.map(async actor => await actor.onTimeChanging(oldTimestamp, newTimestamp)));
|
||||
RdDTimestamp.setWorldTime(newTimestamp);
|
||||
if (oldTimestamp.indexDate + 1 == newTimestamp.indexDate && ReglesOptionelles.isUsing("chateau-dormant-gardien")) {
|
||||
await DialogChateauDormant.create();
|
||||
}
|
||||
this.timestamp = newTimestamp;
|
||||
await this.rebuildNombresAstraux();
|
||||
this.positionAiguilles()
|
||||
this.display();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onCalendarButton(ev) {
|
||||
ev.preventDefault();
|
||||
const calendarAvance = ev.currentTarget.attributes['data-calendar-avance'];
|
||||
const calendarSet = ev.currentTarget.attributes['data-calendar-set'];
|
||||
if (calendarAvance) {
|
||||
await this.incrementTime(Number(calendarAvance.value));
|
||||
}
|
||||
else if (calendarSet) {
|
||||
this.positionnerHeure(Number(calendarSet.value));
|
||||
}
|
||||
this.positionAiguilles()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incrementTime(minutes = 0) {
|
||||
if (game.user.isGM) {
|
||||
await this.setNewTimestamp(this.timestamp.addMinutes(minutes));
|
||||
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incrementerJour() {
|
||||
await this.setNewTimestamp(this.timestamp.nouveauJour());
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async positionnerHeure(heure) {
|
||||
if (game.user.isGM) {
|
||||
const indexDate = this.timestamp.indexDate;
|
||||
const addDay = this.timestamp.heure < heure ? 0 : 1;
|
||||
const newTimestamp = new RdDTimestamp({ indexDate: indexDate + addDay }).addHeures(heure);
|
||||
await this.setNewTimestamp(newTimestamp)
|
||||
Hooks.callAll(APP_ASTROLOGIE_REFRESH);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getLectureAstrologieDifficulte(dateIndex) {
|
||||
let indexNow = this.timestamp.indexDate;
|
||||
let diffDay = dateIndex - indexNow;
|
||||
return - Math.floor(diffDay / 2);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async requestNombreAstral(request) {
|
||||
const actor = game.actors.get(request.id);
|
||||
if (Misc.isUniqueConnectedGM()) { // Only once
|
||||
console.log(request);
|
||||
let jourDiff = this.getLectureAstrologieDifficulte(request.date);
|
||||
let niveau = Number(request.astrologie.system.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat);
|
||||
let rollData = {
|
||||
caracValue: request.carac_vue,
|
||||
finalLevel: niveau,
|
||||
showDice: HIDE_DICE,
|
||||
rollMode: "blindroll"
|
||||
};
|
||||
await RdDResolutionTable.rollData(rollData);
|
||||
request.rolled = rollData.rolled;
|
||||
request.isValid = request.rolled.isSuccess;
|
||||
request.nbAstral = this.getNombreAstral(request.date);
|
||||
|
||||
if (request.rolled.isSuccess) {
|
||||
if (request.rolled.isPart) {
|
||||
// Gestion expérience (si existante)
|
||||
request.competence = actor.getCompetence("astrologie")
|
||||
request.selectedCarac = actor.system.carac["vue"];
|
||||
actor.appliquerAjoutExperience(request, 'hide');
|
||||
}
|
||||
}
|
||||
else {
|
||||
request.nbAstral = await RdDDice.rollTotal("1dhr" + request.nbAstral, {
|
||||
rollMode: "selfroll", showDice: HIDE_DICE
|
||||
});
|
||||
// Mise à jour des nombres astraux du joueur
|
||||
this.addNbAstralIncorect(request.id, request.date, request.nbAstral);
|
||||
}
|
||||
|
||||
if (Misc.getActiveUser(request.userId)?.isGM) {
|
||||
RdDUtility.responseNombreAstral(request);
|
||||
} else {
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_response_nombre_astral",
|
||||
data: request
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addNbAstralIncorect(actorId, date, nbAstral) {
|
||||
const astralData = this.nombresAstraux.find((nombreAstral, i) => nombreAstral.index == date);
|
||||
astralData.valeursFausses.push({ actorId: actorId, nombreAstral: nbAstral });
|
||||
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.nombresAstraux);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getAjustementAstrologique(heureNaissance, name = undefined) {
|
||||
const defHeure = RdDTimestamp.findHeure(heureNaissance);
|
||||
if (defHeure) {
|
||||
return RdDTimestamp.ajustementAstrologiqueHeure(defHeure.heure, this.getNombreAstral(), this.timestamp.heure);
|
||||
}
|
||||
else if (name) {
|
||||
ui.notifications.warn(name + " n'a pas d'heure de naissance, ou elle est incorrecte : " + heureNaissance);
|
||||
}
|
||||
else {
|
||||
ui.notifications.warn(heureNaissance + " ne correspond pas à une heure de naissance");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async saveEditeur(calendrierData) {
|
||||
const newTimestamp = RdDTimestamp.timestamp(
|
||||
Number.parseInt(calendrierData.annee),
|
||||
calendrierData.mois.heure,
|
||||
Number.parseInt(calendrierData.jourMois),
|
||||
calendrierData.heure.heure,
|
||||
Number.parseInt(calendrierData.minutes)
|
||||
);
|
||||
await this.setNewTimestamp(newTimestamp);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async showCalendarEditor() {
|
||||
const calendrierData = this.fillCalendrierData();
|
||||
if (this.editeur == undefined) {
|
||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/time/calendar-editor.hbs', calendrierData);
|
||||
this.editeur = new RdDCalendrierEditor(html, this, calendrierData)
|
||||
}
|
||||
this.editeur.updateData(calendrierData);
|
||||
this.editeur.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async showAstrologieEditor() {
|
||||
await AppAstrologie.create();
|
||||
}
|
||||
}
|
@ -1,16 +1,17 @@
|
||||
import { SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
|
||||
export const WORLD_TIMESTAMP_SETTING = "calendrier";
|
||||
|
||||
const RDD_MOIS_PAR_AN = 12;
|
||||
const RDD_JOURS_PAR_MOIS = 28;
|
||||
const RDD_JOURS_PAR_AN = 336; //RDD_JOURS_PAR_MOIS * RDD_MOIS_PAR_AN;
|
||||
const RDD_HEURES_PAR_JOUR = 12;
|
||||
const RDD_MINUTES_PAR_HEURES = 120;
|
||||
const RDD_MINUTES_PAR_JOUR = 1440; //RDD_HEURES_PAR_JOUR * RDD_MINUTES_PAR_HEURES;
|
||||
const RDD_MOIS_PAR_AN = 12;
|
||||
export const RDD_JOURS_PAR_MOIS = 28;
|
||||
export const RDD_HEURES_PAR_JOUR = 12;
|
||||
export const MAX_NOMBRE_ASTRAL = 12;
|
||||
export const RDD_MINUTES_PAR_HEURES = 120;
|
||||
export const RDD_MINUTES_PAR_JOUR = 1440; //RDD_HEURES_PAR_JOUR * RDD_MINUTES_PAR_HEURES;
|
||||
const ROUNDS_PAR_MINUTE = 10;
|
||||
|
||||
const DEFINITION_HEURES = [
|
||||
@ -48,14 +49,6 @@ const FORMULES_PERIODE = [
|
||||
|
||||
export class RdDTimestamp {
|
||||
|
||||
static hh(heure) {
|
||||
return heure < 9 ? `0${heure + 1}` : `${heure + 1}`;
|
||||
}
|
||||
|
||||
static iconeHeure(heure) {
|
||||
return `systems/foundryvtt-reve-de-dragon/icons/heures/hd${RdDTimestamp.hh(heure)}.svg`;
|
||||
}
|
||||
|
||||
static init() {
|
||||
game.settings.register(SYSTEM_RDD, WORLD_TIMESTAMP_SETTING, {
|
||||
name: WORLD_TIMESTAMP_SETTING,
|
||||
@ -73,10 +66,35 @@ export class RdDTimestamp {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static hh(heure) {
|
||||
return heure < 9 ? `0${heure + 1}` : `${heure + 1}`;
|
||||
}
|
||||
|
||||
static iconeHeure(heure) {
|
||||
return `systems/foundryvtt-reve-de-dragon/icons/heures/hd${RdDTimestamp.hh(heure)}.svg`;
|
||||
}
|
||||
|
||||
static definitions() {
|
||||
return DEFINITION_HEURES
|
||||
}
|
||||
|
||||
static formulesDuree() {
|
||||
return FORMULES_DUREE
|
||||
}
|
||||
|
||||
static formulesPeriode() {
|
||||
return FORMULES_PERIODE
|
||||
}
|
||||
|
||||
static heures() {
|
||||
return Misc.intArray(0, RDD_HEURES_PAR_JOUR)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param signe
|
||||
* @param signe
|
||||
* @returns L'entrée de DEFINITION_HEURES correspondant au signe
|
||||
*/
|
||||
*/
|
||||
static definition(signe) {
|
||||
if (signe == undefined) {
|
||||
signe = 0;
|
||||
@ -91,23 +109,26 @@ export class RdDTimestamp {
|
||||
return definition
|
||||
}
|
||||
|
||||
static definitions() {
|
||||
return DEFINITION_HEURES
|
||||
}
|
||||
static formulesDuree() {
|
||||
return FORMULES_DUREE
|
||||
}
|
||||
|
||||
static formulesPeriode() {
|
||||
return FORMULES_PERIODE
|
||||
}
|
||||
|
||||
static imgSigneHeure(heure) {
|
||||
return RdDTimestamp.imgSigne(RdDTimestamp.definition(heure));
|
||||
}
|
||||
|
||||
static imgSigne(signe) {
|
||||
return signe == undefined ? '' : `<img class="img-signe-heure" src="${signe.webp}" alt="${signe.label}"/>`
|
||||
return signe == undefined ? '' : `<img class="img-signe-heure" src="${signe.webp}" alt="${signe.label}" title="${signe.label}"/>`
|
||||
}
|
||||
|
||||
static ajustementAstrologiqueHeure(hn, nbAstral, heure) {
|
||||
let ecart = (hn + nbAstral - heure) % RDD_HEURES_PAR_JOUR;
|
||||
if (ecart < 0) {
|
||||
ecart = (ecart + RDD_HEURES_PAR_JOUR) % RDD_HEURES_PAR_JOUR;
|
||||
}
|
||||
switch (ecart) {
|
||||
case 0: return 4;
|
||||
case 4: case 8: return 2;
|
||||
case 6: return -4;
|
||||
case 3: case 9: return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static handleTimestampEditor(html, path, consumeTimestamp = async (path, timestamp) => { }) {
|
||||
@ -207,6 +228,14 @@ export class RdDTimestamp {
|
||||
this.indexMinute = indexMinute ?? 0
|
||||
}
|
||||
|
||||
get annee() { return Math.floor(this.indexDate / RDD_JOURS_PAR_AN) }
|
||||
get mois() { return Math.floor((this.indexDate % RDD_JOURS_PAR_AN) / RDD_JOURS_PAR_MOIS) }
|
||||
get jour() { return (this.indexDate % RDD_JOURS_PAR_AN) % RDD_JOURS_PAR_MOIS }
|
||||
get heure() { return Math.floor(this.indexMinute / RDD_MINUTES_PAR_HEURES) }
|
||||
get minute() { return this.indexMinute % RDD_MINUTES_PAR_HEURES }
|
||||
get round() { return ROUNDS_PAR_MINUTE * (this.indexMinute - Math.floor(this.indexMinute)) }
|
||||
get angleHeure() { return this.indexMinute / RDD_MINUTES_PAR_JOUR * 360 - 45 }
|
||||
get angleMinute() { return this.indexMinute / RDD_MINUTES_PAR_HEURES * 360 + 45 }
|
||||
|
||||
/**
|
||||
* Convertit le timestamp en une structure avec les informations utiles
|
||||
@ -224,13 +253,6 @@ export class RdDTimestamp {
|
||||
};
|
||||
}
|
||||
|
||||
get annee() { return Math.floor(this.indexDate / RDD_JOURS_PAR_AN) }
|
||||
get mois() { return Math.floor((this.indexDate % RDD_JOURS_PAR_AN) / RDD_JOURS_PAR_MOIS) }
|
||||
get jour() { return (this.indexDate % RDD_JOURS_PAR_AN) % RDD_JOURS_PAR_MOIS }
|
||||
get heure() { return Math.floor(this.indexMinute / RDD_MINUTES_PAR_HEURES) }
|
||||
get minute() { return this.indexMinute % RDD_MINUTES_PAR_HEURES }
|
||||
get round() { return ROUNDS_PAR_MINUTE * (this.indexMinute - Math.floor(this.indexMinute)) }
|
||||
|
||||
formatDate() {
|
||||
const jour = this.jour + 1;
|
||||
const mois = RdDTimestamp.definition(this.mois).label;
|
||||
@ -238,6 +260,10 @@ export class RdDTimestamp {
|
||||
return `${jour} ${mois}` + (annee ? ' ' + annee : '');
|
||||
}
|
||||
|
||||
formatDateHeure() {
|
||||
return `${RdDTimestamp.definition(this.heure).label}, ${this.formatDate()}`;
|
||||
}
|
||||
|
||||
nouveauJour() { return new RdDTimestamp({ indexDate: this.indexDate + 1, indexMinute: 0 }) }
|
||||
|
||||
nouvelleHeure() {
|
@ -226,9 +226,6 @@ export const TMRType = {
|
||||
desolation: { name: "désolation", genre: "f" }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const caseSpecificModes = ["attache", "trounoir", "debordement", "reserve_extensible", "maitrisee"];
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const tmrRandomMovePatten =
|
||||
[{ name: 'top', col: 0, row: -1 },
|
||||
@ -239,8 +236,6 @@ const tmrRandomMovePatten =
|
||||
{ name: 'topleft', col: -1, row: -1 }
|
||||
]
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class TMRUtility {
|
||||
static init() {
|
||||
@ -258,32 +253,25 @@ export class TMRUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static verifyTMRCoord(coord) {
|
||||
let TMRregexp = new RegExp(/([A-M])(\d+)/g);
|
||||
let res = TMRregexp.exec(coord);
|
||||
if (res && res[1] && res[2]) {
|
||||
if (res[2] > 0 && res[2] < 16) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return Grammar.equalsInsensitive(coord, 'Fleuve') || TMRUtility.getTMR(coord);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getTMR(coord) {
|
||||
return TMRMapping[coord];
|
||||
return coord == 'Fleuve' ? TMRMapping['D1'] : TMRMapping[coord];
|
||||
}
|
||||
|
||||
static getTMRLabel(coord) {
|
||||
return TMRMapping[coord]?.label ?? (coord + ": case inconnue");
|
||||
return TMRUtility.getTMR(coord)?.label ?? (coord + ": case inconnue");
|
||||
}
|
||||
|
||||
static getTMRType(coord) {
|
||||
const tmr = TMRMapping[coord];
|
||||
const tmr = TMRUtility.getTMR(coord);
|
||||
return Misc.upperFirst(TMRType[tmr.type].name);
|
||||
}
|
||||
|
||||
static getTMRDescr(coord) {
|
||||
const tmr = TMRMapping[coord];
|
||||
const tmr = TMRUtility.getTMR(coord);
|
||||
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { Draconique } from "./draconique.js";
|
||||
import { PixiTMR } from "./pixi-tmr.js";
|
||||
|
||||
export class CarteTmr extends Draconique {
|
||||
|
||||
constructor() {
|
||||
console.log("Sprite create 1!!!!")
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Misc } from "../misc.js";
|
||||
import { TYPES } from "../item.js";
|
||||
import { TMRUtility } from "../tmr-utility.js";
|
||||
import { PixiTMR } from "./pixi-tmr.js";
|
||||
|
||||
@ -9,10 +9,10 @@ const registeredEffects = [
|
||||
* Définition des informations d'une "draconique" (queue, ombre, tête, souffle) qui influence les TMR
|
||||
*/
|
||||
export class Draconique {
|
||||
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 isCaseTMR(item) { return item.type == TYPES.casetmr; }
|
||||
static isQueueDragon(item) { return item.isQueueDragon(); }
|
||||
static isSouffleDragon(item) {return item.type == TYPES.souffle; }
|
||||
static isTeteDragon(item) { return item.type == TYPES.tete; }
|
||||
static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); }
|
||||
|
||||
tmrLabel(linkData) { return TMRUtility.getTMRLabel(linkData.system.coord); }
|
||||
@ -91,6 +91,8 @@ export class Draconique {
|
||||
coordTMR: coordTMR
|
||||
};
|
||||
token[type ?? this.code()] = linkData;
|
||||
console.log("SPRITE: ", token.sprite)
|
||||
//PixiTMR.getImgFromCode()
|
||||
pixiTMR.addTooltip(token.sprite, this.tooltip(linkData));
|
||||
return token;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import { Periple } from "./periple.js";
|
||||
import { UrgenceDraconique } from "./urgence-draconique.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { AugmentationSeuil } from "./augmentation-seuil.js";
|
||||
import { TYPES } from "../item.js";
|
||||
|
||||
|
||||
export class EffetsDraconiques {
|
||||
@ -114,46 +115,57 @@ export class EffetsDraconiques {
|
||||
);
|
||||
}
|
||||
|
||||
static filterItems(actor, filter, name) {
|
||||
return actor.filterItems(filter)
|
||||
.filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
|
||||
static tetesDragon(actor, name) {
|
||||
return actor.itemTypes[TYPES.tete].filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
|
||||
}
|
||||
|
||||
static soufflesDragon(actor, name) {
|
||||
return actor.itemTypes[TYPES.souffle].filter(it => Grammar.includesLowerCaseNoAccent(it.name, name));
|
||||
}
|
||||
|
||||
static queuesDragon(actor, name) {
|
||||
return actor.filterItems(it => it.isQueueDragon() && Grammar.includesLowerCaseNoAccent(it.name, name));
|
||||
}
|
||||
|
||||
static queuesSoufflesDragon(actor, name) {
|
||||
return actor.filterItems(it => [TYPES.queue, TYPES.ombre, TYPES.souffle].includes(it.type) && Grammar.includesLowerCaseNoAccent(it.name, name));
|
||||
}
|
||||
|
||||
static countAugmentationSeuil(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Augmentation du seuil de rêve').length;
|
||||
return EffetsDraconiques.tetesDragon(actor, 'Augmentation du seuil de rêve').length;
|
||||
}
|
||||
|
||||
static isDonDoubleReve(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'Don de double-rêve').length>0;
|
||||
return EffetsDraconiques.tetesDragon(actor, 'Don de double-rêve').length > 0;
|
||||
}
|
||||
|
||||
static isConnaissanceFleuve(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'connaissance du fleuve').length>0;
|
||||
return EffetsDraconiques.tetesDragon(actor, 'connaissance du fleuve').length > 0;
|
||||
}
|
||||
|
||||
static isReserveEnSecurite(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, 'réserve en sécurité').length>0;
|
||||
return EffetsDraconiques.tetesDragon(actor, 'réserve en sécurité').length > 0;
|
||||
}
|
||||
|
||||
static isDeplacementAccelere(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isTeteDragon, ' déplacement accéléré').length>0;
|
||||
return EffetsDraconiques.tetesDragon(actor, 'déplacement accéléré').length > 0;
|
||||
}
|
||||
|
||||
static isDoubleResistanceFleuve(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isSouffleDragon, 'résistance du fleuve').length>0;
|
||||
return EffetsDraconiques.soufflesDragon(actor, 'résistance du fleuve').length > 0;
|
||||
}
|
||||
|
||||
static countInertieDraconique(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isQueueDragon, 'inertie draconique').length;
|
||||
return EffetsDraconiques.queuesDragon(actor, 'inertie draconique').length;
|
||||
}
|
||||
|
||||
static countMonteeLaborieuse(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isQueueSouffle, 'montée laborieuse').length;
|
||||
return EffetsDraconiques.queuesSoufflesDragon(actor, 'montée laborieuse').length;
|
||||
}
|
||||
|
||||
static mauvaiseRencontre(actor) {
|
||||
const mauvaisesRencontres = EffetsDraconiques.filterItems(actor, Draconique.isQueueSouffle, 'mauvaise rencontre');
|
||||
return mauvaisesRencontres.length>0 ? mauvaisesRencontres[0] : undefined;
|
||||
const mauvaisesRencontres = EffetsDraconiques.queuesSoufflesDragon(actor, 'mauvaise rencontre');
|
||||
return mauvaisesRencontres.length > 0 ? mauvaisesRencontres[0] : undefined;
|
||||
}
|
||||
|
||||
static isPontImpraticable(actor) {
|
||||
@ -165,11 +177,11 @@ export class EffetsDraconiques {
|
||||
}
|
||||
|
||||
static isSujetInsomnie(actor) {
|
||||
return actor.items.find(it => ['queue', 'ombre'].includes(it.type) && Grammar.includesLowerCaseNoAccent(it.name, 'Insomnie')) ? true : false;
|
||||
return EffetsDraconiques.queuesDragon(actor, 'Insomnie').length > 0 ? true : false;
|
||||
}
|
||||
|
||||
static isPeage(actor) {
|
||||
return EffetsDraconiques.filterItems(actor, Draconique.isSouffleDragon, 'péage').length > 0;
|
||||
return EffetsDraconiques.soufflesDragon(actor, 'péage').length > 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { ExperienceLog, XP_TOPIC } from "../actor/experience-log.js";
|
||||
import { ChatUtility } from "../chat-utility.js";
|
||||
import { Poetique } from "../poetique.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
@ -53,9 +54,10 @@ export class EffetsRencontre {
|
||||
static xp_sort_force = async (dialog, context) => {
|
||||
let competence = context.competence;
|
||||
if (competence) {
|
||||
const xpSort = Misc.toInt(competence.system.xp_sort) + context.rencontre.system.force;
|
||||
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': xpSort }]);
|
||||
await this.updateExperienceLog("XP Sort", xpSort, `Rencontre d'un ${context.rencontre.name} en TMR`);
|
||||
const fromXpSort = Number(competence.system.xp_sort);
|
||||
const toXpSort = fromXpSort + context.rencontre.system.force;
|
||||
await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': toXpSort }]);
|
||||
await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, `${competence.name} - ${context.rencontre.name} en TMR`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,18 +20,20 @@ export class PixiTMR {
|
||||
this.callbacksOnAnimate = [];
|
||||
}
|
||||
|
||||
load( onLoad = (loader, resources) => {} ) {
|
||||
let loader = this.pixiApp.loader;
|
||||
async load( onLoad = (loader, resources) => {} ) {
|
||||
// WIP - Deprecated since v7 : let loader = new PIXI.Loader();
|
||||
for (const [name, img] of Object.entries(PixiTMR.textures)) {
|
||||
loader = loader.add(name, img);
|
||||
const texture = await PIXI.Assets.load(img);
|
||||
let image = PIXI.Sprite.from(texture);
|
||||
}
|
||||
loader.onError.add((error, reason) => { console.log("ERROR", error, reason) });
|
||||
loader.load( (loader, resources) => {
|
||||
onLoad(loader, resources);
|
||||
for (let onAnimate of this.callbacksOnAnimate) {
|
||||
onAnimate();
|
||||
}
|
||||
});
|
||||
onLoad();
|
||||
for (let onAnimate of this.callbacksOnAnimate) {
|
||||
onAnimate();
|
||||
}
|
||||
}
|
||||
|
||||
static getImgFromCode(code) {
|
||||
return PixiTMR.textures[code]
|
||||
}
|
||||
|
||||
static register(name, img) {
|
||||
@ -44,7 +46,9 @@ export class PixiTMR {
|
||||
}
|
||||
|
||||
carteTmr(code) {
|
||||
const carteTmr = new PIXI.Sprite(PIXI.utils.TextureCache[code]);
|
||||
let img = PixiTMR.getImgFromCode(code)
|
||||
const carteTmr = new PIXI.Sprite(PIXI.utils.TextureCache[img]);
|
||||
console.log(code, carteTmr)
|
||||
// Setup the position of the TMR
|
||||
carteTmr.x = 0;
|
||||
carteTmr.y = 0;
|
||||
@ -52,7 +56,8 @@ export class PixiTMR {
|
||||
carteTmr.height = 860;
|
||||
// Rotate around the center
|
||||
carteTmr.anchor.set(0);
|
||||
carteTmr.interactive = true;
|
||||
carteTmr.eventMode = 'dynamic'; // PIXI 7 : Not sure ..
|
||||
// This one is deprecated ; carteTmr.interactive = true;
|
||||
carteTmr.buttonMode = true;
|
||||
carteTmr.tmrObject = this;
|
||||
if (!this.tmrObject.viewOnly) {
|
||||
@ -63,9 +68,10 @@ export class PixiTMR {
|
||||
}
|
||||
|
||||
sprite(code, options = {}) {
|
||||
const texture = PIXI.utils.TextureCache[code];
|
||||
let img = PixiTMR.getImgFromCode(code)
|
||||
const texture = PIXI.utils.TextureCache[img];
|
||||
if (!texture) {
|
||||
console.error("Texture manquante", code)
|
||||
console.error("Texture manquante", code, PIXI.utils.TextureCache)
|
||||
return;
|
||||
}
|
||||
let sprite = new PIXI.Sprite(texture);
|
||||
@ -97,7 +103,8 @@ export class PixiTMR {
|
||||
sprite.tooltip = new PIXI.Text(text, tooltipStyle);
|
||||
sprite.tooltip.zIndex = tmrTokenZIndex.tooltip;
|
||||
sprite.isOver = false;
|
||||
sprite.interactive = true;
|
||||
// Deprecated : sprite.interactive = true;
|
||||
sprite.eventMode = 'dynamic'; // PIXI 7 To be checked
|
||||
sprite.on('pointerdown', event => this.onClickBackground(event))
|
||||
.on('pointerover', () => this.onShowTooltip(sprite))
|
||||
.on('pointerout', () => this.onHideTooltip(sprite));
|
||||
|
File diff suppressed because one or more lines are too long
BIN
packs/animaux/000028.ldb
Normal file
BIN
packs/animaux/000028.ldb
Normal file
Binary file not shown.
0
packs/animaux/000047.log
Normal file
0
packs/animaux/000047.log
Normal file
1
packs/animaux/CURRENT
Normal file
1
packs/animaux/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000045
|
0
packs/animaux/LOCK
Normal file
0
packs/animaux/LOCK
Normal file
7
packs/animaux/LOG
Normal file
7
packs/animaux/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:40:34.656615 7fca067fc6c0 Recovering log #43
|
||||
2023/05/29-08:40:34.674483 7fca067fc6c0 Delete type=3 #41
|
||||
2023/05/29-08:40:34.674520 7fca067fc6c0 Delete type=0 #43
|
||||
2023/05/29-08:50:04.296687 7fca04ff96c0 Level-0 table #48: started
|
||||
2023/05/29-08:50:04.296723 7fca04ff96c0 Level-0 table #48: 0 bytes OK
|
||||
2023/05/29-08:50:04.302846 7fca04ff96c0 Delete type=0 #46
|
||||
2023/05/29-08:50:04.323728 7fca04ff96c0 Manual compaction at level-0 from '!actors!0ogeNTXl7IwYfWZR' @ 72057594037927935 : 1 .. '!actors.items!zMvyRrp10dkfcS43.shsUV8UpU18c0RJK' @ 0 : 0; will stop at (end)
|
7
packs/animaux/LOG.old
Normal file
7
packs/animaux/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:00:37.697935 7fca067fc6c0 Recovering log #39
|
||||
2023/05/29-08:00:37.713407 7fca067fc6c0 Delete type=3 #37
|
||||
2023/05/29-08:00:37.713452 7fca067fc6c0 Delete type=0 #39
|
||||
2023/05/29-08:38:02.219865 7fca04ff96c0 Level-0 table #44: started
|
||||
2023/05/29-08:38:02.219887 7fca04ff96c0 Level-0 table #44: 0 bytes OK
|
||||
2023/05/29-08:38:02.226757 7fca04ff96c0 Delete type=0 #42
|
||||
2023/05/29-08:38:02.239623 7fca04ff96c0 Manual compaction at level-0 from '!actors!0ogeNTXl7IwYfWZR' @ 72057594037927935 : 1 .. '!actors.items!zMvyRrp10dkfcS43.shsUV8UpU18c0RJK' @ 0 : 0; will stop at (end)
|
BIN
packs/animaux/MANIFEST-000045
Normal file
BIN
packs/animaux/MANIFEST-000045
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
packs/archetypes/000011.ldb
Normal file
BIN
packs/archetypes/000011.ldb
Normal file
Binary file not shown.
0
packs/archetypes/000046.log
Normal file
0
packs/archetypes/000046.log
Normal file
1
packs/archetypes/CURRENT
Normal file
1
packs/archetypes/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000044
|
0
packs/archetypes/LOCK
Normal file
0
packs/archetypes/LOCK
Normal file
7
packs/archetypes/LOG
Normal file
7
packs/archetypes/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:40:34.682366 7fca057fa6c0 Recovering log #42
|
||||
2023/05/29-08:40:34.699920 7fca057fa6c0 Delete type=3 #40
|
||||
2023/05/29-08:40:34.699959 7fca057fa6c0 Delete type=0 #42
|
||||
2023/05/29-08:50:04.323849 7fca04ff96c0 Level-0 table #47: started
|
||||
2023/05/29-08:50:04.323886 7fca04ff96c0 Level-0 table #47: 0 bytes OK
|
||||
2023/05/29-08:50:04.330053 7fca04ff96c0 Delete type=0 #45
|
||||
2023/05/29-08:50:04.352593 7fca04ff96c0 Manual compaction at level-0 from '!actors!1Nng9d8r6lrPHCaJ' @ 72057594037927935 : 1 .. '!actors.items!ryUZTa17LzNv25UY.zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end)
|
7
packs/archetypes/LOG.old
Normal file
7
packs/archetypes/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:00:37.736173 7fca05ffb6c0 Recovering log #38
|
||||
2023/05/29-08:00:37.750924 7fca05ffb6c0 Delete type=3 #36
|
||||
2023/05/29-08:00:37.750965 7fca05ffb6c0 Delete type=0 #38
|
||||
2023/05/29-08:38:02.239711 7fca04ff96c0 Level-0 table #43: started
|
||||
2023/05/29-08:38:02.239732 7fca04ff96c0 Level-0 table #43: 0 bytes OK
|
||||
2023/05/29-08:38:02.246710 7fca04ff96c0 Delete type=0 #41
|
||||
2023/05/29-08:38:02.253050 7fca04ff96c0 Manual compaction at level-0 from '!actors!1Nng9d8r6lrPHCaJ' @ 72057594037927935 : 1 .. '!actors.items!ryUZTa17LzNv25UY.zyNYa3hYtrOcF2jA' @ 0 : 0; will stop at (end)
|
BIN
packs/archetypes/MANIFEST-000044
Normal file
BIN
packs/archetypes/MANIFEST-000044
Normal file
Binary file not shown.
@ -1,49 +0,0 @@
|
||||
{"name":"Moussecaille","type":"recettecuisine","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.240HPtZsgZQERFMF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_6.webp","effects":[],"_id":"240HPtZsgZQERFMF","system":{"description":"<p>Civet de cailles aux mousseroles.</p>\n<p>La mousserole est un petit champignon rose, très abondant après la pluie (commun). Pratiquement, cette recette peut s’appliquer à tout gibier à plume préparé aux champignons.</p>","descriptionmj":"","niveau":6,"ingredients":"<ul>\n<li>4 grosses cailles (1 sust chaque)</li>\n<li>3 livres de mousseroles</li>\n<li>4 échalotes</li>\n<li>1 racine de réfèble</li>\n<li>1 schouillat de miel</li>\n<li>10 schouillats de beurre</li>\n<li>2 doigts d’huile</li>\n<li>5 schouillats de farine de blédièze</li>\n<li>eau</li>\n<li>sel</li>\n<li>4 brins de klampine</li>\n<li>4 brins de luciane</li>\n<li>1 brin de mentharde</li>\n<li>4 brins de pèpre</li>\n</ul>","duree":"80 minutes","sust":8,"exotisme":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870029,"modifiedTime":1671048281603,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Panaris et Phlegmon","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.36YGDFJBxekzEvBw"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_7.webp","effects":[],"_id":"36YGDFJBxekzEvBw","system":{"description":"<p>Romance sur la fatalité qui sépare deux amants et que seule la mort réunit.</p>\n<p>À la fin, la belle Panaris est transformée en carafe et le gentil Phlegmon en bouchon de cristal. L’empereur, à qui échoit le flacon, les rassemble symboliquement.</p>","descriptionmj":"","niveau":7,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870029,"modifiedTime":1671048281603,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La danse des sept rêves","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.4mhiTAEhwDh7S3i0"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_sol_8.webp","effects":[],"_id":"4mhiTAEhwDh7S3i0","system":{"description":"<p>Véritable ballet, la danse des sept rêves est une chorégraphie dramatique élaborée.</p>","descriptionmj":"","type":"soliste","agilite":false,"apparence":true,"niveau":6,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870030,"modifiedTime":1671048281604,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Les fléchettes","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.8jOKQkuS6RJyM3uD"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_flechettes.webp","effects":[],"_id":"8jOKQkuS6RJyM3uD","system":{"description":"<p>Jeu d’adresse consistant à viser une cible avec des fléchettes.</p>\n<p>Pour simuler une partie, faire tirer à chaque participant 5 jets de Lancer/Jeu à zéro et additionner les points de tâche obtenus. Le plus grand nombre gagne.</p>","descriptionmj":"","type":"adressehasard","base":-6,"caraccomp":"Lancer","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870030,"modifiedTime":1671048281604,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La peccadille","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.8p4pMXbgY4S5fZjJ"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_2.webp","effects":[],"_id":"8p4pMXbgY4S5fZjJ","system":{"description":"<p>La peccadille se danse à deux, comme la valse ou le tango. Plus lente et moins rythmée que les deux premières, elle comporte quatre figures :</p>\n<p>1) les cavaliers se tiennent par les mains</p>\n<p>2) ils se tiennent par la taille</p>\n<p>3) figure libre, improvisée par celui ou celle qui a invité l’autre</p>\n<p>4) les deux visages doivent se rapprocher de façon à se toucher par le bout du nez à l’exclusion de toute autre partie du corps.</p>\n<p>Et l’on recommence.</p>\n<p>L’intérêt de cette danse réside dans sa figure libre, sobre ou osée, et sa difficulté dans le nez à nez.</p>\n<p>Il arrive lors de cette figure que, emportés par le mouvement, les visages se heurtent violemment, ce qui produit toujours une mauvaise impression chez le partenaire.</p>","descriptionmj":"","type":"recreative","agilite":false,"apparence":true,"niveau":2,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870030,"modifiedTime":1671048281604,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Les dragons","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.AVAMD5C2mxuOfwV4"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_calculs.webp","effects":[],"_id":"AVAMD5C2mxuOfwV4","system":{"description":"<p>Les dragons sont les échecs draconics.</p>\n<p>Plus complexes et soumis à beaucoup plus de variantes que nos échecs, les dragons se jouent sur un plateau de 7 x 7 cases. Chaque joueur possède 14 pièces : le voyageur, le haut-rêvant, la pucelle, le groin, le ménestrel, l’archer, la maison, et 7 arbres.</p>\n<p>Les arbres sont l’équivalent des pions et servent à constituer les forêts. Les joueurs ne jouent pas l’un en face de l’autre, mais côte à côte, avec l’échiquier devant eux. Il y a ainsi le joueur de droite qui plante la forêt dite dextriote, et le joueur de gauche qui plante la forêt sinistrante. Quelle que soit la variante jouée, l’échiquier commence vide, les joueurs introduisant leurs pièces, arbres ou autres, l’un après l’autre.</p>\n<p>Selon les variantes, les pièces ne se déplacent pas de la même façon. Les arbres ne prennent ni ne se déplacent jamais. Ils servent d’obstacle aux lignes de déplacement des autres pièces. Seuls les haut-rêvants peuvent les prendre dans certaines variantes.</p>\n<p>Les maisons, également fixes, ne peuvent être prises que quand elles sont vides. Selon les variantes, elles peuvent contenir de deux à quatre autres pièces (qui coexistent sur la même case), sauf des arbres. Dans la maison les pièces sont protégées, on ne peut les prendre. Une variante permet d’agrandir la maison en sacrifiant un arbre.</p>\n<p>Selon une autre, les archers peuvent augmenter leur nombre de flèches en sacrifiant également un arbre.</p>\n<p>Dans la variante traditionnelle, la plus ancienne, le but du jeu est d’investir la maison adverse. Cela suppose qu’elle soit vide. Il faut préalablement éliminer ou neutraliser les pièces en dehors, jusqu’à obliger les occupants de la maison à sortir (comme aux échecs, on ne peut passer son coup, on doit effectuer un mouvement).</p>\n<p>Dans des variantes plus récentes, plus faciles, le but est de capturer une certaine pièce adverse, généralement le groin ou la pucelle (qui joue l’équivalent du roi de nos échecs). Une variante très populaire oblige que ce soit le groin qui capture la pucelle.</p>\n<p>La durée d’une partie de dragons est en moyenne d’une heure.</p>","descriptionmj":"","type":"reflexion","base":-8,"caraccomp":"Intellect","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870030,"modifiedTime":1671048281605,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La mort d’Amarak","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.C5smOdHzrDHlrrZq"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_6.webp","effects":[],"_id":"C5smOdHzrDHlrrZq","system":{"description":"<p>Épopée à gros budget et effets spéciaux spectaculaires.</p>\n<p>Amarak, ayant bu une potion de gigantisme, meurt en se cognant la tête dans la lune.</p>","descriptionmj":"","niveau":6,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870030,"modifiedTime":1671048281605,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La princesse endormie","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.CBpwK9udfdzlWbfb"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_7.webp","effects":[],"_id":"CBpwK9udfdzlWbfb","system":{"description":"<p>Ballade sur une princesse qui se pique le doigt et dort très longtemps suite à un maléfice.</p>\n<p>Les derniers couplets sont malheureusement oubliés, de sorte que la chanson ne finit pas.</p>","descriptionmj":"","niveau":7,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870030,"modifiedTime":1671048281605,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le mal rêvé","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.FcTMJE5Wfd02axxd"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_4.webp","effects":[],"_id":"FcTMJE5Wfd02axxd","system":{"description":"<p>Complainte sur la destinée misérable d’un homme qui avait les oreilles à la place des genoux.</p>","descriptionmj":"","niveau":4,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870031,"modifiedTime":1671048281605,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La plumette","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.HyOXCAtpaP7eaHGj"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_plumette.webp","effects":[],"_id":"HyOXCAtpaP7eaHGj","system":{"description":"<p>Jeu d’adresse et de volonté, la plumette se joue à deux, chacun chatouillant le visage de l’autre avec une plume. Les visages doivent rester imperturbables.</p>\n<p>Le premier qui trahit un signe quelconque (rire, éternuement, grimace) a perdu.</p>\n<p>Pour simuler une partie, utiliser les règles de combat, chacun à tour de rôle attaquant ou tentant de parer l’adversaire.</p>\n<p>Pour attaquer, utiliser DEXTÉRITÉ/Jeu difficulté libre et pour parer VOLONTÉ/Jeu à la difficulté de l’attaque. Le vainqueur est le premier à réussir une attaque non parée.</p>","descriptionmj":"","type":"adressehasard","base":-4,"caraccomp":"Dextérité / Volonté","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870032,"modifiedTime":1671048281605,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La bergamasque","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.KJ0Ck2G2t4lYIKJH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_5.webp","effects":[],"_id":"KJ0Ck2G2t4lYIKJH","system":{"description":"<p>La bergamasque reprend le principe de la sarabande, mais sur un rythme plus vif et des figures plus compliquées.</p>","descriptionmj":"","type":"recreative","agilite":false,"apparence":true,"niveau":5,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870032,"modifiedTime":1671048281606,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Les calculs","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.MixMWkfRpEN51QuP"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_calculs.webp","effects":[],"_id":"MixMWkfRpEN51QuP","system":{"description":"<p>Ce jeu se pratique avec des calculs, c’est à-dire des petits cailloux, que l’on pose alternativement sur une surface grillée.</p>\n<p>La stratégie est à mi-chemin entre le go et le morpion.</p>\n<p>Très pratiqué, ce jeu peut être facilement improvisé en traçant la grille à la craie sur une table, ou à l’extérieur, sur du sable lisse.</p>","descriptionmj":"","type":"reflexion","base":-6,"caraccomp":"Intellect","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870032,"modifiedTime":1671048281606,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La serpentine","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.N7bgcR8OEh6MpfiF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_sol_1.webp","effects":[],"_id":"N7bgcR8OEh6MpfiF","system":{"description":"<p>Danse basique, lente ou vive, ondulante et serpentine.</p>","descriptionmj":"","type":"soliste","agilite":false,"apparence":true,"niveau":1,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870032,"modifiedTime":1671048281606,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Rêve de Dragon","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.OTRi9mHhIANUnPA7"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_8.webp","effects":[],"_id":"OTRi9mHhIANUnPA7","system":{"description":"<p>Récitatif, dont la moralité se résume ainsi : puisque tout n’est qu’un rêve, allons dormir.</p>","descriptionmj":"","niveau":8,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870033,"modifiedTime":1671048281607,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Choucroume","type":"recettecuisine","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.POuOV6xoPnO0b9OQ"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_2.webp","effects":[],"_id":"POuOV6xoPnO0b9OQ","system":{"description":"<p>Variété de bloutade au chou, cuite dans de la bière.</p>\n<p>Émincer finement le chou et le faire revenir dans l’huile.</p>\n<p>Ajouter la bière, le sel, les aromates, puis cuire sans cesser de touiller comme pour une bloutade ordinaire.</p>","descriptionmj":"","niveau":2,"ingredients":"<ul>\n<li>1 livre de chou émincé</li>\n<li>2 doigts d’huile</li>\n<li>1 pinte de bière</li>\n<li>sel</li>\n<li>8 brins d’aromates (béjaune, luciane)</li>\n</ul>\n<p> </p>\n<p>Une variante appelée choucroume liquide utilise le double de bière (2 pintes) et se consomme froide.</p>","duree":"30 minutes","sust":8,"exotisme":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870033,"modifiedTime":1671048281607,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La turlutaine","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.Q5Lx4WWKWGFjF9cX"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_3.webp","effects":[],"_id":"Q5Lx4WWKWGFjF9cX","system":{"description":"<p>Sarabande simplifiée dansée par les villageois, moins lente et moins guindée que cette dernière.</p>\n<p>On danse tantôt en groupe, tantôt par couples, avec changements de partenaire.</p>\n<p>Au moment de la séparation pour reformer le groupe, les partenaires s’envoient des baisers du bout des doigts.</p>","descriptionmj":"","type":"recreative","agilite":false,"apparence":true,"niveau":3,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870033,"modifiedTime":1671048281607,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le bourrichon","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.QvMNog5MF3vDIBGR"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_0.webp","effects":[],"_id":"QvMNog5MF3vDIBGR","system":{"description":"<p>Le bourrichon est une sorte de farandole joyeuse et rythmée où un grand nombre de danseurs évoluent en se tenant par la main. Les figures sont libres, l’essentiel étant de garder le rythme.</p>","descriptionmj":"","type":"recreative","agilite":true,"apparence":true,"niveau":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870033,"modifiedTime":1671048281607,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Grabuge","type":"recettecuisine","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.RvsPbA1ehQgRvGu6"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_3.webp","effects":[],"_id":"RvsPbA1ehQgRvGu6","system":{"description":"<p>Plat de tomari, de plures et de poisson mijoté au pif-paf.</p>","descriptionmj":"","niveau":3,"ingredients":"<ul>\n<li>1 livre de tomari</li>\n<li>1 livre de poisson (mer ou eau douce)</li>\n<li>2 poireaux</li>\n<li>6 oignons</li>\n<li>1 laitue</li>\n<li>2 schouillats de beurre</li>\n<li>2 doigts d’huile</li>\n<li>1 doigt de vinaigre</li>\n<li>eau</li>\n<li>sel</li>\n<li>6 brins de luciane</li>\n<li>6 brins de klampine</li>\n<li>8 brins de pif-paf</li>\n</ul>","duree":"60 minutes","sust":12,"exotisme":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870033,"modifiedTime":1671048281608,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La danse du feu","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.UBVYoQmilTmkqppd"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_sol_5.webp","effects":[],"_id":"UBVYoQmilTmkqppd","system":{"description":"<p>La danse du feu se danse usuellement de nuit et près d’un feu.</p>\n<p>Lente, aux mouvements plus suggérés que marqués, elle est imitative des flammes, comme si le danseur avait le feu pour partenaire.</p>","descriptionmj":"","type":"soliste","agilite":false,"apparence":true,"niveau":5,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870034,"modifiedTime":1671048281608,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La danse du voile","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.Ui1bMMBBdxMb2AZ2"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_sol_6.webp","effects":[],"_id":"Ui1bMMBBdxMb2AZ2","system":{"description":"<p>De caractère libre, tantôt altière comme la souveraine ou déhanchée comme la callipyge, cette danse utilise un voile comme accessoire (pièce de tissu, châle, écharpe, etc.).</p>\n<p>Son intérêt réside dans les mouvements du voile avec lesquels s’harmonisent ceux de la danseuse.</p>\n<p>Peu pratiquée par les hommes.</p>","descriptionmj":"","type":"soliste","agilite":false,"apparence":true,"niveau":6,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870034,"modifiedTime":1671048281608,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Fleur de haut-rêve","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.Y5rAtXL0WxOqqbZs"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_1.webp","effects":[],"_id":"Y5rAtXL0WxOqqbZs","system":{"description":"<p>Romance à l’eau de rose sur les malheurs d’une jeune haut-rêvante.</p>","descriptionmj":"","niveau":1,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870034,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La souveraine","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.Y791UctCHALnBgjO"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_sol_4.webp","effects":[],"_id":"Y791UctCHALnBgjO","system":{"description":"<p>Danse très lente, sobre, hiératique, plus caractérisée par ses poses que par ses mouvements.</p>","descriptionmj":"","type":"soliste","agilite":false,"apparence":true,"niveau":4,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870034,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Bras de fer","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.ZJvL0e5hjuws7mIH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_brasdefer.webp","effects":[],"_id":"ZJvL0e5hjuws7mIH","system":{"description":"<p>Pour attaquer, utiliser Force/Jeu difficulté libre. Pour parer, l'opposant joue pareillement Force/Jeu à la difficulté de l’attaque.</p>\n<p>Le vainqueur est le premier à réussir une attaque non parée.</p>","descriptionmj":"","type":"adressehasard","base":-4,"caraccomp":"Force","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870034,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La chèvre rose","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.aB78Io55m2kXDjwQ"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_3.webp","effects":[],"_id":"aB78Io55m2kXDjwQ","system":{"description":"<p>Ballade comique sur une chèvre de la couleur en question, qui s’avère finalement être une princesse métamorphosée par un maléfice.</p>","descriptionmj":"","niveau":3,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870034,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Tripotée","type":"recettecuisine","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.aWfeLfT1kM2cCrNn"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_2.webp","effects":[],"_id":"aWfeLfT1kM2cCrNn","system":{"description":"<p>Soupe végétarienne comprenant des légumes de chacune des trois sortes. Selon les légumes utilisés, la tripotée peut avoir de multiples variantes, la plus courante étant pois-quaroce-turneps.</p>","descriptionmj":"","niveau":2,"ingredients":"<ul>\n<li>1/2 livre de cosses</li>\n<li>1/2 livre de porte-pépins</li>\n<li>1/2 livre de racines</li>\n<li>eau</li>\n<li>5 schouillats de farine de blédièze</li>\n<li>3 schouillats de farine de bloute</li>\n<li>4 brins de béjaune</li>\n<li>2 brins de muscaline</li>\n<li>2 brins de pèpre</li>\n</ul>","duree":"40 minutes","sust":6,"exotisme":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870035,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Tiens, v’là les Groins !","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.dwSY0ImswRHUSuRQ"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp","effects":[],"_id":"dwSY0ImswRHUSuRQ","system":{"description":"<p>Chanson de marche peu rafinée, comme en témoigne le refrain :</p>\n<blockquote>\n<p>« Tiens, v’là les Groins !</p>\n<p>Ça y’en a eux qui faire du foin !</p>\n<p>Quand y’en a près, y’en a pas loin !</p>\n<p>Tiens, v’là les Groins ! »</p>\n</blockquote>","descriptionmj":"","niveau":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870035,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La volée","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.ehAslJ16qKJDrTqt"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_6.webp","effects":[],"_id":"ehAslJ16qKJDrTqt","system":{"description":"<p>Danse villageoise, la volée est une farandole rapide incluant des sauts et des figures quasi acrobatiques, ainsi que des moments rapprochés à deux (comme la peccadille). Elle est évidemment réservée aux bons danseurs, et particulièrement exténuante.</p>","descriptionmj":"","type":"recreative","agilite":true,"apparence":true,"niveau":6,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870035,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"jOL4buV3m3nHr8v7","name":"Le doublon","type":"jeu","img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_doublon.webp","effects":[],"folder":null,"sort":0,"flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.jOL4buV3m3nHr8v7"}},"system":{"description":"<p>Jeu de pur hasard consistant à obtenir un double avec deux dés.</p>\n<p>Si plusieurs joueurs y parviennent, le plus haut gagne ; si aucun n’y parvient, le coup est nul et les mises restent au pot.</p>\n<p>Pour simuler une partie de doublon, faire simplement tirer des jets de CHANCE à zéro (ajustés astrologiquement), mais sans compétence, pas même Jeu, et comparer les résultats (échec, réussite normale, significative, etc.) : le meilleur gagne. À égalité de réussites, le coup est nul.</p>","descriptionmj":"","type":"de","base":0,"caraccomp":"Chance","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870036,"modifiedTime":1671048281609,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le rossignol d’Ostarlath","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.jUsy5PTDwBgDrRnq"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_8.webp","effects":[],"_id":"jUsy5PTDwBgDrRnq","system":{"description":"<p>Romance où les paroles, peu importantes, sont essentiellement un exercice de vocalises.</p>","descriptionmj":"","niveau":8,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870037,"modifiedTime":1671048281610,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le roi des ours","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.jUxckTsggDZBgn2W"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_3.webp","effects":[],"_id":"jUxckTsggDZBgn2W","system":{"description":"<p>Sanglante épopée sur un thème identique* : maléfice, métamorphose et superbe vengeance finale.</p>\n<p> </p>\n<p><em>*voir \"La chèvre rose\"</em></p>","descriptionmj":"","niveau":3,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870037,"modifiedTime":1671048281610,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La route est longue","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.jyPBU95uPhIhsdpa"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp","effects":[],"_id":"jyPBU95uPhIhsdpa","system":{"description":"<p>Chanson de marche aux couplets répétitifs.</p>\n<blockquote>\n<p>« Une lieue sans cheval, ça use, ça use</p>\n<p>Une lieue sans cheval, ça use les sandales !»</p>\n</blockquote>","descriptionmj":"","niveau":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870037,"modifiedTime":1671048281610,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La danse du couteau","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.k9EELSV0DrurUt1e"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_sol_6.webp","effects":[],"_id":"k9EELSV0DrurUt1e","system":{"description":"<p>Plus masculine que féminine, cette danse utilise un couteau (dague) comme accessoire.</p>\n<p>Elle est imitative d’un combat.</p>","descriptionmj":"","type":"soliste","agilite":false,"apparence":true,"niveau":6,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870037,"modifiedTime":1671048281610,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"L’amour est morte","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.kCU7A8fMczERjizY"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_5.webp","effects":[],"_id":"kCU7A8fMczERjizY","system":{"description":"<p>Romance sentimentale d’une tristesse à faire pleurer les cailloux.</p>","descriptionmj":"","niveau":5,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870037,"modifiedTime":1671048281610,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Amandjara","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.kiIlPL5XANy5OgYn"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_2.webp","effects":[],"_id":"kiIlPL5XANy5OgYn","system":{"description":"<p>Sérénade sur la légendaire cité d’Amandjara,</p>\n<p>« Perle du désert bleu, sur qui la lune fait les doux yeux ... »</p>","descriptionmj":"","niveau":2,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870038,"modifiedTime":1671048281611,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Bloutade","type":"recettecuisine","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.lv6AiGYIjtqHhn7u"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_1.webp","effects":[],"_id":"lv6AiGYIjtqHhn7u","system":{"description":"<p>Purée de farine de bloute.</p>\n<p> </p>\n<p><strong>Bloute</strong></p>\n<p>Avec le tomari ou le blédièze, la bloute est à la base de l’alimentation dans un grand nombre d’endroits. C’est un tubercule de forme et de couleur voisins de notre manioc, à la chair gélatineuse et fade. Totalement immangeables telles quelles, les bloutes sont mises à sécher sur des claies, puis broyées en farine. Ce n’est qu’ainsi qu’on peut les consommer. La farine de bloute entre dans la confection des brouets et des ragoûts, notamment de la bloutade. Ainsi cuite, elle ressemble à du tapioca.</p>","descriptionmj":"","niveau":1,"ingredients":"<ul>\n<li>1 livre de farine de bloute*</li>\n<li>1/2 livre de viande de porc ou de padongre coupée en petits morceaux</li>\n<li>2 doigts d’huile</li>\n<li>eau,</li>\n<li>sel</li>\n<li>8 brins d’aromates (béjaune, luciane)</li>\n</ul>","duree":"30 minutes","sust":8,"exotisme":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870038,"modifiedTime":1671048281611,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le tisonnier","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.mRzHzrubRkyqHUTC"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_tisonnier.webp","effects":[],"_id":"mRzHzrubRkyqHUTC","system":{"description":"<p>On commence par se mettre d’accord sur la valeur hiérarchique des symboles et des combinaisons possibles, puis le jeu consiste, à chaque distribution de cartes, à miser selon un système de surenchères jusqu’à ce que les cartes soient dévoilées.</p>\n<p>La combinaison la plus forte emporte alors les mises.</p>\n<p>Le jeu demande de la chance, sans laquelle il est difficile de gagner à long terme, mais tout autant de l’empathie pour bluffer lors des surenchères.</p>\n<p>Pour simuler une partie, jouer un jet de CHANCE à zéro (ajusté astrologiquement), suivi d’un jet d’EMPATHIE/Jeu à zéro, et additionner les points de tâche obtenus par les deux jets. Le vainqueur est celui qui en totalise le plus.</p>","descriptionmj":"","type":"carte","base":-4,"caraccomp":"Chance / Empathie","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870038,"modifiedTime":1671048281611,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Plume de zyglute","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.nCFFhbL54WXU0FFi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_4.webp","effects":[],"_id":"nCFFhbL54WXU0FFi","system":{"description":"<p>Sérénade.</p>\n<p>Belle musique, mais paroles d’une rare stupidité :</p>\n<blockquote>\n<p>« Coin-coin, glou-glou, c’est qui ? c’est vous ? »</p>\n</blockquote>","descriptionmj":"","niveau":4,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870038,"modifiedTime":1671048281611,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"L’auberge noire","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.srNKj5s0TOw7VDQ4"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_5.webp","effects":[],"_id":"srNKj5s0TOw7VDQ4","system":{"description":"<p>Complainte macabre sur un aubergiste qui assassine ses clients avec la râpe à fromage.</p>","descriptionmj":"","niveau":5,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870038,"modifiedTime":1671048281611,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Ma chope est vide !","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.uGVOeSq2ZKMG8VjU"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp","effects":[],"_id":"uGVOeSq2ZKMG8VjU","system":{"description":"<p>Chanson à boire peu raffinée.</p>","descriptionmj":"","niveau":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870039,"modifiedTime":1671048281611,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La callipyge","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.uf7a9D5RYw7gOi36"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_sol_2.webp","effects":[],"_id":"uf7a9D5RYw7gOi36","system":{"description":"<p>Comme la serpentine, avec des effets plus marqués, essentiellement basée sur les mouvements du bassin. La callipyge n’est généralement dansée que par les femmes.</p>","descriptionmj":"","type":"soliste","agilite":false,"apparence":true,"niveau":2,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870039,"modifiedTime":1671048281612,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La gambade","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.uxdljYU7TlC2F6oA"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_1.webp","effects":[],"_id":"uxdljYU7TlC2F6oA","system":{"description":"<p>Gigue endiablée, proche du bourrichon, mais avec des figures un peu moins sommaires.</p>","descriptionmj":"","type":"recreative","agilite":true,"apparence":true,"niveau":1,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870039,"modifiedTime":1671048281612,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Trompe de padongre à la mentharde","type":"recettecuisine","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.uzSivEs6SFEGVoI0"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_4.webp","effects":[],"_id":"uzSivEs6SFEGVoI0","system":{"description":"<p>Enduite de miel, de beurre et entourée de feuilles de mentharde fraîches, la trompe de padongre doit être cuite au four et arrosée régulièrement de lait. Toute la difficulté réside dans la cuisson.</p>","descriptionmj":"","niveau":4,"ingredients":"<ul>\n<li>1 belle trompe de padongre (10 sust)</li>\n<li>25 schouillats de miel</li>\n<li>1 livre de beurre</li>\n<li>1 pinte de lait</li>\n<li>20 brins de mentharde</li>\n<li>sel</li>\n</ul>","duree":"90 minutes","sust":12,"exotisme":0,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870039,"modifiedTime":1671048281613,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La triplette","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.vYPjOjd3vSAvjL76"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_doublon.webp","effects":[],"_id":"vYPjOjd3vSAvjL76","system":{"description":"<p>Autre jeu de hasard, la triplette est un jeu de dés de combinaisons se jouant avec trois dés (sorte de 421).</p>\n<p>Pour simuler une partie de triplette, déterminer l’ordre dans lequel jouent les participants. Le premier à jouer peut tenter de un à trois jets de CHANCE à zéro (ajustés astrologiquement comme pour le doublon), et additionner les points de tâche obtenus.</p>\n<p>Attention aux échecs qui donnent des points négatifs ! Il peut être plus judicieux de se contenter d’un seul jet bien réussi.</p>\n<p>Les joueurs suivants, en effet, pourront à leur tour tenter le même nombre de jets de CHANCE ou moins, mais pas davantage. Le plus grand nombre de points gagne finalement.</p>","descriptionmj":"","type":"de","base":0,"caraccomp":"Chance","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870040,"modifiedTime":1671048281613,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le voyageur","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.vlqX5BC9recz2kM2"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_1.webp","effects":[],"_id":"vlqX5BC9recz2kM2","system":{"description":"<p>Ballade sur les tribulations d’un voyageur.</p>\n<p>Interminable, cette chanson possède plus de cent couplets.</p>\n<p> </p>\n<p><em>Déterminer en tirant 1d100 le nombre de couplets connus.</em></p>","descriptionmj":"","niveau":1,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870040,"modifiedTime":1671048281613,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La pétasse","type":"jeu","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.vo8GoXIBNWp1GY12"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/jeux_petasse.webp","effects":[],"_id":"vo8GoXIBNWp1GY12","system":{"description":"<p>Jeu d’adresse combinant boules et quilles.</p>\n<p>Chaque joueur dispose de plusieurs quilles, appelées pétasses, et de boules de bois, appelées tronchets. Le jeu connaît de nombreuses variantes, mais le principe général est le même : culbuter les pétasses des adversaires en évitant de se faire troncher les siennes.</p>\n<p>Pour simuler une partie, faire tirer à chaque participant 5 jets de Lancer/Jeu à zéro et additionner les points de tâche obtenus. Le plus grand nombre gagne.</p>","descriptionmj":"","type":"adressehasard","base":-6,"caraccomp":"Lancer","reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870040,"modifiedTime":1671048281613,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"La sarabande","type":"danse","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.wf1jpIZmrB5LfK93"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/danse_4.webp","effects":[],"_id":"wf1jpIZmrB5LfK93","system":{"description":"<p>Peu pratiquée dans les villages, la sarabande est une danse de cour, lente et solennelle, alternant groupe et couples, comme la turlutaine dont elle est une version «sérieuse».</p>\n<p>Les changements de partenaire s’accompagnent de profondes révérences.</p>","descriptionmj":"","type":"recreative","agilite":false,"apparence":true,"niveau":4,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870042,"modifiedTime":1671048281613,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le retour du baron gris","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.xjITZoom3Azu9NQa"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_2.webp","effects":[],"_id":"xjITZoom3Azu9NQa","system":{"description":"<p>Épopée pleine de cavalcades, de trahisons, de batailles et de cervelles éclatées.</p>","descriptionmj":"","niveau":2,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870042,"modifiedTime":1671048281614,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"L’heure de la Lyre","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.yLcvnrbqIKS4ezj7"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_1.webp","effects":[],"_id":"yLcvnrbqIKS4ezj7","system":{"description":"<p>Berceuse sur le thème de la nuit qui descend.</p>","descriptionmj":"","niveau":1,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870043,"modifiedTime":1671048281614,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Le cavalier de sombre neige","type":"chant","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.arts-et-divertissements.zRQ5WnPI483CKm9Q"}},"img":"systems/foundryvtt-reve-de-dragon/icons/arts/chant_6.webp","effects":[],"_id":"zRQ5WnPI483CKm9Q","system":{"description":"<p>Épopée pleine de suspense et de terreur, où le soleil est rouge, la lune violette et la neige noire.</p>","descriptionmj":"","niveau":6,"reference":""},"ownership":{"default":0,"rYShh2P1DNavdoBD":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047870043,"modifiedTime":1671048281614,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
BIN
packs/arts-et-divertissements/000011.ldb
Normal file
BIN
packs/arts-et-divertissements/000011.ldb
Normal file
Binary file not shown.
0
packs/arts-et-divertissements/000046.log
Normal file
0
packs/arts-et-divertissements/000046.log
Normal file
1
packs/arts-et-divertissements/CURRENT
Normal file
1
packs/arts-et-divertissements/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000044
|
0
packs/arts-et-divertissements/LOCK
Normal file
0
packs/arts-et-divertissements/LOCK
Normal file
7
packs/arts-et-divertissements/LOG
Normal file
7
packs/arts-et-divertissements/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:40:34.473425 7fca057fa6c0 Recovering log #42
|
||||
2023/05/29-08:40:34.489629 7fca057fa6c0 Delete type=3 #40
|
||||
2023/05/29-08:40:34.489672 7fca057fa6c0 Delete type=0 #42
|
||||
2023/05/29-08:50:04.169228 7fca04ff96c0 Level-0 table #47: started
|
||||
2023/05/29-08:50:04.169266 7fca04ff96c0 Level-0 table #47: 0 bytes OK
|
||||
2023/05/29-08:50:04.176244 7fca04ff96c0 Delete type=0 #45
|
||||
2023/05/29-08:50:04.189729 7fca04ff96c0 Manual compaction at level-0 from '!items!240HPtZsgZQERFMF' @ 72057594037927935 : 1 .. '!items!zRQ5WnPI483CKm9Q' @ 0 : 0; will stop at (end)
|
7
packs/arts-et-divertissements/LOG.old
Normal file
7
packs/arts-et-divertissements/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:00:37.527199 7fca057fa6c0 Recovering log #38
|
||||
2023/05/29-08:00:37.537455 7fca057fa6c0 Delete type=3 #36
|
||||
2023/05/29-08:00:37.537507 7fca057fa6c0 Delete type=0 #38
|
||||
2023/05/29-08:38:02.086958 7fca04ff96c0 Level-0 table #43: started
|
||||
2023/05/29-08:38:02.086980 7fca04ff96c0 Level-0 table #43: 0 bytes OK
|
||||
2023/05/29-08:38:02.093744 7fca04ff96c0 Delete type=0 #41
|
||||
2023/05/29-08:38:02.107101 7fca04ff96c0 Manual compaction at level-0 from '!items!240HPtZsgZQERFMF' @ 72057594037927935 : 1 .. '!items!zRQ5WnPI483CKm9Q' @ 0 : 0; will stop at (end)
|
BIN
packs/arts-et-divertissements/MANIFEST-000044
Normal file
BIN
packs/arts-et-divertissements/MANIFEST-000044
Normal file
Binary file not shown.
@ -1,29 +0,0 @@
|
||||
{"_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":{"description":null,"descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":4,"isparade":false},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702692,"modifiedTime":1671048288982,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702692,"modifiedTime":1671048288983,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"generale","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":1,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702692,"modifiedTime":1671048288983,"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":{"description":"<p>L'entité tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","categorie_parade":"","niveau":2,"default_diffLibre":0,"categorie":"draconic","carac_value":14,"iscombat":true,"isnaturelle":true,"ispossession":true,"dommages":0,"isparade":false},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624976822,"modifiedTime":1671048288983,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":1,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702692,"modifiedTime":1671048288983,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702692,"modifiedTime":1671048288983,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":3,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702693,"modifiedTime":1671048288983,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702693,"modifiedTime":1671048288983,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702693,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"epees-lourdes","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702693,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":false,"ispossession":false,"dommages":2,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702693,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":false},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702693,"modifiedTime":1671048288984,"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":{"description":null,"descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":4,"isparade":false},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702693,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"epees-lourdes","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":3,"isparade":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"generale","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":false,"carac-value":null},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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":{"description":null,"descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":3,"isparade":false},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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é 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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"lancer","carac_value":0,"iscombat":true,"isnaturelle":false,"ispossession":false,"dommages":1,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":10,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702694,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702695,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"dagues","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":false,"ispossession":false,"dommages":1,"isparade":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702695,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"categorie":"melee","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":1,"isparade":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702695,"modifiedTime":1671048288984,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702695,"modifiedTime":1671048288985,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702695,"modifiedTime":1671048288985,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"generale","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702695,"modifiedTime":1671048288985,"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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624702695,"modifiedTime":1671048288985,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
BIN
packs/competences-creatures/000011.ldb
Normal file
BIN
packs/competences-creatures/000011.ldb
Normal file
Binary file not shown.
0
packs/competences-creatures/000046.log
Normal file
0
packs/competences-creatures/000046.log
Normal file
1
packs/competences-creatures/CURRENT
Normal file
1
packs/competences-creatures/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000044
|
0
packs/competences-creatures/LOCK
Normal file
0
packs/competences-creatures/LOCK
Normal file
7
packs/competences-creatures/LOG
Normal file
7
packs/competences-creatures/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:40:34.473425 7fca06ffd6c0 Recovering log #42
|
||||
2023/05/29-08:40:34.489628 7fca06ffd6c0 Delete type=3 #40
|
||||
2023/05/29-08:40:34.489672 7fca06ffd6c0 Delete type=0 #42
|
||||
2023/05/29-08:50:04.162334 7fca04ff96c0 Level-0 table #47: started
|
||||
2023/05/29-08:50:04.162374 7fca04ff96c0 Level-0 table #47: 0 bytes OK
|
||||
2023/05/29-08:50:04.169093 7fca04ff96c0 Delete type=0 #45
|
||||
2023/05/29-08:50:04.189714 7fca04ff96c0 Manual compaction at level-0 from '!items!0zRL8bOpCXNQnIR4' @ 72057594037927935 : 1 .. '!items!yDHZfK4RmwQW4YaW' @ 0 : 0; will stop at (end)
|
7
packs/competences-creatures/LOG.old
Normal file
7
packs/competences-creatures/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:00:37.527196 7fca05ffb6c0 Recovering log #38
|
||||
2023/05/29-08:00:37.537511 7fca05ffb6c0 Delete type=3 #36
|
||||
2023/05/29-08:00:37.537612 7fca05ffb6c0 Delete type=0 #38
|
||||
2023/05/29-08:38:02.093873 7fca04ff96c0 Level-0 table #43: started
|
||||
2023/05/29-08:38:02.093898 7fca04ff96c0 Level-0 table #43: 0 bytes OK
|
||||
2023/05/29-08:38:02.100659 7fca04ff96c0 Delete type=0 #41
|
||||
2023/05/29-08:38:02.114114 7fca04ff96c0 Manual compaction at level-0 from '!items!0zRL8bOpCXNQnIR4' @ 72057594037927935 : 1 .. '!items!yDHZfK4RmwQW4YaW' @ 0 : 0; will stop at (end)
|
BIN
packs/competences-creatures/MANIFEST-000044
Normal file
BIN
packs/competences-creatures/MANIFEST-000044
Normal file
Binary file not shown.
@ -1,15 +0,0 @@
|
||||
{"_id":"0Ms9iKxqigNNpZEx","name":"Esquive","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.0Ms9iKxqigNNpZEx"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895714,"modifiedTime":1671048307066,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"18wcei5hlEInsBFO","name":"Attaque","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.18wcei5hlEInsBFO"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-griffes.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":0,"carac-value":null,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895715,"modifiedTime":1671048307066,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"3Crwg8cx2JOb697T","name":"Parade","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.3Crwg8cx2JOb697T"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_saut.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":false,"isnaturelle":true,"ispossession":false,"dommages":0,"carac-value":null,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895715,"modifiedTime":1671048307066,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"6eWCVDYLXXO1Z48D","name":"Grandes griffes","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":{"description":"","descriptionmj":"","categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":false},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895715,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"9Y83OsQgeyR5oCdH","name":"Griffes","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":{"description":"","descriptionmj":"","categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":1,"carac-value":null,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895715,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"D9cBJ3EJPYLnABiJ","name":"Tentacules","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.D9cBJ3EJPYLnABiJ"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-tentacule.webp","effects":[],"system":{"description":"<p>Attaque ou parade avec un tentacule.</p>","descriptionmj":"","categorie_parade":"boucliers","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":true},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895716,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"QGULMUoC9JXFze0r","name":"Bouclier Lourd","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.QGULMUoC9JXFze0r"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_bouclier.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"boucliers","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":0,"carac-value":null,"isparade":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895716,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"WsYnwR8GcOxfuCI0","name":"Bras-Galet","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.WsYnwR8GcOxfuCI0"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_course.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":1,"carac-value":null,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895716,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"c0I93Q53i4ZmxpyT","name":"Corps à Corps","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.c0I93Q53i4ZmxpyT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"sans-armes","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895716,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"d5SZ09sFaG3cL2Rg","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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":0,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895716,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"db8E8HwROw1ZcwRR","name":"Crocs","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":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":1,"carac-value":null,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895716,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"gPOQd9NI7AFH0whX","name":"Epée Bâtarde","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-humanoides.YTKld5ggDsHqwYoR"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_epee_1_main.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"epees-lourdes","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":4,"carac-value":null,"isparade":true},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895717,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"j1xHCzfIeYKgXxoH","name":"Morsure","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.j1xHCzfIeYKgXxoH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":1,"isparade":false},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895717,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"_id":"lDZ3qUPKN35ob5TH","name":"Grande morsure","type":"competencecreature","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences-entites.lDZ3qUPKN35ob5TH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/compcreature-morsure.webp","effects":[],"system":{"description":"","descriptionmj":"","categorie_parade":"","niveau":0,"default_diffLibre":0,"categorie":"","carac_value":0,"iscombat":true,"isnaturelle":true,"ispossession":false,"dommages":2,"isparade":false},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047895717,"modifiedTime":1671048307067,"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":{"description":"<p>L'entité tente de prendre possession du corps de sa victime.</p>","descriptionmj":"","categorie_parade":"","niveau":2,"default_diffLibre":-4,"categorie":"melee","carac_value":14,"iscombat":true,"isnaturelle":true,"ispossession":true,"dommages":0,"isparade":false},"ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1663624976822,"modifiedTime":1671048307067,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"wDHR5UHWq568lfGa"}
|
BIN
packs/competences-entites/000011.ldb
Normal file
BIN
packs/competences-entites/000011.ldb
Normal file
Binary file not shown.
0
packs/competences-entites/000046.log
Normal file
0
packs/competences-entites/000046.log
Normal file
1
packs/competences-entites/CURRENT
Normal file
1
packs/competences-entites/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000044
|
0
packs/competences-entites/LOCK
Normal file
0
packs/competences-entites/LOCK
Normal file
7
packs/competences-entites/LOG
Normal file
7
packs/competences-entites/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:40:34.492648 7fca057fa6c0 Recovering log #42
|
||||
2023/05/29-08:40:34.503069 7fca057fa6c0 Delete type=3 #40
|
||||
2023/05/29-08:40:34.503121 7fca057fa6c0 Delete type=0 #42
|
||||
2023/05/29-08:50:04.176372 7fca04ff96c0 Level-0 table #47: started
|
||||
2023/05/29-08:50:04.176410 7fca04ff96c0 Level-0 table #47: 0 bytes OK
|
||||
2023/05/29-08:50:04.182550 7fca04ff96c0 Delete type=0 #45
|
||||
2023/05/29-08:50:04.189740 7fca04ff96c0 Manual compaction at level-0 from '!items!0Ms9iKxqigNNpZEx' @ 72057594037927935 : 1 .. '!items!wDHR5UHWq568lfGa' @ 0 : 0; will stop at (end)
|
7
packs/competences-entites/LOG.old
Normal file
7
packs/competences-entites/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2023/05/29-08:00:37.541075 7fca06ffd6c0 Recovering log #38
|
||||
2023/05/29-08:00:37.554609 7fca06ffd6c0 Delete type=3 #36
|
||||
2023/05/29-08:00:37.554667 7fca06ffd6c0 Delete type=0 #38
|
||||
2023/05/29-08:38:02.100767 7fca04ff96c0 Level-0 table #43: started
|
||||
2023/05/29-08:38:02.100800 7fca04ff96c0 Level-0 table #43: 0 bytes OK
|
||||
2023/05/29-08:38:02.107003 7fca04ff96c0 Delete type=0 #41
|
||||
2023/05/29-08:38:02.114130 7fca04ff96c0 Manual compaction at level-0 from '!items!0Ms9iKxqigNNpZEx' @ 72057594037927935 : 1 .. '!items!wDHR5UHWq568lfGa' @ 0 : 0; will stop at (end)
|
BIN
packs/competences-entites/MANIFEST-000044
Normal file
BIN
packs/competences-entites/MANIFEST-000044
Normal file
Binary file not shown.
@ -1,67 +0,0 @@
|
||||
{"name":"Comédie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.2JLK5e97WbTM5WxX"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp","_id":"2JLK5e97WbTM5WxX","system":{"description":"<p>L’art de paraître sur une scène : jouer un rôle, déclamer des vers, mimer, conter. Peut aussi servir à simuler, mystifier.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"apparence","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890257,"modifiedTime":1671048297532,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Jeu","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.3VSMRwMYpOi83wgE"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_jeu.webp","_id":"3VSMRwMYpOi83wgE","system":{"description":"<p>Jeux de tripot, manipuler les dés. Connaître les jeux et les meilleures stratégies, déceler un tricheur et tricher soi-même.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890257,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Cuisine","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.3qRzl3nhLZNsoDsI"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_cuisine.webp","_id":"3qRzl3nhLZNsoDsI","system":{"description":"<p>Identifier les saveurs culinaires, les épices et les aromates. Exécuter, inventer une recette. Faire griller un gibier sur un feu de camp n’est généralement pas de la cuisine, mais de la simple survie.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"odoratgout","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890258,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Sous-Sol","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.6pXxEdeo7xcDvgx0"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_sous_sol.webp","_id":"6pXxEdeo7xcDvgx0","system":{"description":"<p>Par exemple pister un gibier en forêt demande l’usage de Survie en forêt, trouver une grotte pour s’abriter en montagne demande Survie en montagne. Survie en extérieur tient lieu de survie spécifique pour les plaines et collines non boisées.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890258,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Corps à corps","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.8Uj41cL5Qlxxy675"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp","_id":"8Uj41cL5Qlxxy675","system":{"description":"<p>Groupées en une seule jusqu’au niveau zéro, ces compétences sont les principes de base du combat de mêlée. Corps à corps permet de se battre sans armes ; Es-quive permet d’esquiver toutes les sortes de coup ; Dague de mêlée permet l’utilisation de la dague au contact.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890258,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Discrétion","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.94P55yZfeipCGbsr"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_discretion.webp","_id":"94P55yZfeipCGbsr","system":{"description":"<p>Se déplacer en silence, sans se faire remarquer, passer inaperçu, se fondre dans</p>\n<p>l’anonymat, se cacher.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"agilite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890258,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Saut","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.9ICvksiNG6Bhm8CE"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_saut.webp","_id":"9ICvksiNG6Bhm8CE","system":{"description":"<p>Sauter par-dessus un obstacle ou sauter en contrebas ; rattraper une chute en la transformant en saut.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"agilite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890259,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Navigation","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.AXeWswf2Dth9ysvy"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_navigation.webp","_id":"AXeWswf2Dth9ysvy","system":{"description":"<p>Connaissance des manœuvres à accomplir sur un voilier, connaissance de la mer, de ses courants (voir Navigation, p325).</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"vue","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890259,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Séduction","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.AbM6lJ7DI2UAWLxj"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_seduction.webp","_id":"AbM6lJ7DI2UAWLxj","system":{"description":"<p>L’art d’être galant, de paraître attirant. Permet les conquêtes amoureuses.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"apparence","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Masse à 2 mains","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.BMAloiSbDKOu3b4C"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_masse_2_mains.webp","_id":"BMAloiSbDKOu3b4C","system":{"description":"<p>Ces compétences permettent l’utilisation des masses, gourdins, bâtons, pour attaquer, voire parer.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Chirurgie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.BlG2YPATIbnY3m9P"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp","_id":"BlG2YPATIbnY3m9P","system":{"description":"<p>L’art de soigner les blessures, panser, recoudre ; savoir se servir d’un rasoir. Chirurgie est utilisée pour accomplir premiers soins et soins complets sur toutes les blessures, et par extension, pour tous les actes de secourisme et de réanimation.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Montagne","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.BzqBOeqS6HvJhqey"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_montagne.webp","_id":"BzqBOeqS6HvJhqey","system":{"description":"<p>Par exemple pister un gibier en forêt demande l’usage de Survie en forêt, trouver une grotte pour s’abriter en montagne demande Survie en montagne. Survie en extérieur tient lieu de survie spécifique pour les plaines et collines non boisées.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Métallurgie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.CHyk96ypxMrg8VXh"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_metallurgie.webp","_id":"CHyk96ypxMrg8VXh","system":{"description":"<p>C’est au sens large le travail du métal, et principalement du fer. Battre le fer, forger, tremper, limer, poncer, riveter. Évaluer la qualité, la solidité, d’un objet de fer, une arme par exemple.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"force","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297533,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Equitation","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.F5iQNrZSeJsfyTnV"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_equitation.webp","_id":"F5iQNrZSeJsfyTnV","system":{"description":"<p>Monter à cheval, et, d’une manière générale, connaissance des chevaux. Peut s’appliquer aux autres montures de Rêve de Dragon : aligates, zyglutes, etc.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"agilite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Hache à 2 mains","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.F97wHYDsQ5UyvJnb"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_hache_a_2_mains.webp","_id":"F97wHYDsQ5UyvJnb","system":{"description":"<p>Ces deux compétences permettent l’utilisation des hachettes, cognées et haches de bataille, pour attaquer.</p>\n<p> </p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Charpenterie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.FqLWG6xjISKMLPiX"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_charpenterie.webp","_id":"FqLWG6xjISKMLPiX","system":{"description":"<p>C’est au sens large le travail du bois, charpenterie, menuiserie, ébénisterie. Évaluer la qualité, solidité, d’une structure de bois.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Astrologie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.GIIQm22Q4bBsmxpE"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_astrologie.webp","_id":"GIIQm22Q4bBsmxpE","system":{"description":"<p>Connaissance des étoiles et de leur signification symbolique. Calculer les nombres astraux gouvernant la chance de chaque individu. S’orienter aux étoiles (voir Astrologie, p155).</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"connaissance","xp":0,"defaut_carac":"vue","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890260,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Course","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.Jz4AZdDlSjsyoUsm"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_course.webp","_id":"Jz4AZdDlSjsyoUsm","system":{"description":"<p>Sprinter le plus vite possible, ou courir sur de longues distances en ménageant son souffle.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"agilite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Chant","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.LE4nA119la5cd0bC"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_chant.webp","_id":"LE4nA119la5cd0bC","system":{"description":"<p>Savoir chanter juste, se souvenir de mélodies, improviser.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"ouie","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Danse","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.LhP3Y0qCBHNp2atl"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_danse.webp","_id":"LhP3Y0qCBHNp2atl","system":{"description":"<p>Être capable de danser en mesure, de danser harmonieusement avec une personne</p>\n<p>ou un groupe, de charmer un public par une exhibition.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"agilite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Epée à 2 mains","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.MLIEbxSJHkY1m3No"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_epee_2_mains.webp","_id":"MLIEbxSJHkY1m3No","system":{"description":"<p>Ces compétences permettent l’utilisation des sept types d’épées de Rêve de Dragon pour attaquer ou parer.</p>\n<p> </p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Dessin","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.OVcZE4kfiPYEOzgm"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_dessin.webp","_id":"OVcZE4kfiPYEOzgm","system":{"description":"<p>Avoir le sens des proportions. Savoir dessiner, faire le portrait de quelqu’un, mais</p>\n<p>également savoir faire un schéma, une carte, un plan, aux proportions exactes.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"tir","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297534,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Orfèvrerie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.PMOjO2CdedH1UTyi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_orfevrerie.webp","_id":"PMOjO2CdedH1UTyi","system":{"description":"<p>Travail et connaissance des métaux précieux : or, argent, cuivre, étain, et par extension des pierres et perles précieuses. Évaluer la taille et la pureté d’une gemme, le prix d’un bijou.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297535,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Serrurerie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.PMnsXDyeB8w8ZG2k"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_serrurerie.webp","_id":"PMnsXDyeB8w8ZG2k","system":{"description":"<p>Compréhension des mécaniques et mécanismes, et plus particulièrement des serrures. Comprendre un mécanisme, le faire fonctionner, le réparer, le désarmer, le crocheter.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297535,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Forêt","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.PbvubzCxnOSnWLpG"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_foret.webp","_id":"PbvubzCxnOSnWLpG","system":{"description":"<p>Par exemple pister un gibier en forêt demande l’usage de Survie en forêt, trouver une grotte pour s’abriter en montagne demande Survie en montagne. Survie en extérieur tient lieu de survie spécifique pour les plaines et collines non boisées.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890261,"modifiedTime":1671048297535,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Botanique","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.PmwXYvmutlyQEonB"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_botanique.webp","_id":"PmwXYvmutlyQEonB","system":{"description":"<p>Identification des espèces végétales et de leurs propriétés. Permet de savoir si une plante connue pousse dans un milieu donné. Recherche de cette plante.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"connaissance","xp":0,"defaut_carac":"vue","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890262,"modifiedTime":1671048297536,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Bouclier","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.SJE3ghtswQwP1dIy"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_bouclier.webp","_id":"SJE3ghtswQwP1dIy","system":{"description":"<p>Utilisation de toutes les sortes de bouclierpour parer.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890262,"modifiedTime":1671048297536,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Alchimie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.TAKRb9CdMUhs9dd4"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_alchimie.webp","_id":"TAKRb9CdMUhs9dd4","system":{"description":"<p>Connaissance des recettes et préparations alchimiques. Identification, élaboration, des solutions diverses, breuvages, poudres, onguents, crèmes, etc. (voir Principes d’alchimie, p357).</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"connaissance","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890262,"modifiedTime":1671048297536,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Vigilance","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.VyAJK54OPjiRt8oH"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_vigilance.webp","_id":"VyAJK54OPjiRt8oH","system":{"description":"<p>Le talent d’être toujours sur ses gardes, prêt à déceler la moindre anomalie, de</p>\n<p>bruit, d’odeur, de mouvement, etc. Permet de ne pas être surpris en combat, par</p>\n<p>exemple. Indispensable pour monter sérieusement la garde.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"volonte","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890262,"modifiedTime":1671048297536,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Médecine","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.XK2TlYnhR8FlDaEi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_medecine.webp","_id":"XK2TlYnhR8FlDaEi","system":{"description":"<p>Diagnostic et soin des maladies. Connaissance des remèdes.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"connaissance","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297538,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Maroquinerie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.XYMQBxFKSs2nPW0J"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_maroquinerie.webp","_id":"XYMQBxFKSs2nPW0J","system":{"description":"<p>Travail du cuir et de la peau. Dépecer correctement un animal en vue de conserver la peau, préparation au tannage, tannage. Évaluer la qualité, la solidité, d’un travail de cuir.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297538,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Dague","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.XZNm5W8nTe8aCG61"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_dague.webp","_id":"XZNm5W8nTe8aCG61","system":{"description":"<p>Pour utiliser les Dagues et les Couteaux en combat</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297538,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Marais","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.azn3Sm7XYKP78huL"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_marais.webp","_id":"azn3Sm7XYKP78huL","system":{"description":"<p>Par exemple pister un gibier en forêt demande l’usage de Survie en forêt, trouver une grotte pour s’abriter en montagne demande Survie en montagne. Survie en extérieur tient lieu de survie spécifique pour les plaines et collines non boisées.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297538,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Voie d'Hypnos","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.bt2cR4aE6lIOeg4F"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_hypnos.webp","_id":"bt2cR4aE6lIOeg4F","system":{"description":"<p>Magie d’illusion, suggestion, invocation.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"draconic","xp":0,"defaut_carac":"reve","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297538,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Zoologie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.c5wursWW03ckpyqn"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_zoologie.webp","_id":"c5wursWW03ckpyqn","system":{"description":"<p>Connaissance des espèces animales, de leurs mœurs, leur des habitat.</p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"connaissance","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Masse à 1 main","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.cMHm3gQr9rUp4iPK"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_masse_1_main.webp","_id":"cMHm3gQr9rUp4iPK","system":{"description":"<p>Ces compétences permettent l’utilisation des masses, gourdins, bâtons, pour attaquer, voire parer.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Voie de Thanatos","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.dPlTQzvU3CEg5qKc"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp","_id":"dPlTQzvU3CEg5qKc","system":{"description":"<p>Magie noire des forces du cauchemar.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"draconic","xp":0,"defaut_carac":"reve","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Pickpocket","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.dT5cvI7q1HcrLaT1"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_pickpocket.webp","_id":"dT5cvI7q1HcrLaT1","system":{"description":"<p>Art extrêmement dangereux du vol à la tire.</p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890263,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Maçonnerie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.dwGVDTUJYP9FcmWM"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_maconnerie.webp","_id":"dwGVDTUJYP9FcmWM","system":{"description":"<p>C’est au sens large le travail de la pierre. Évaluer la qualité, la solidité d’une struc-</p>\n<p>ture maçonnée.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"vue","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890264,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Epée à 1 main","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.fPhPcCP3sbS6mfbS"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_epee_1_main.webp","_id":"fPhPcCP3sbS6mfbS","system":{"description":"<p>Groupées en une seule jusqu’au niveau zéro, ces compétences sont les principes de base du combat de mêlée. Corps à corps permet de se battre sans armes ; Es-quive permet d’esquiver toutes les sortes de coup ; Dague de mêlée permet l’utilisation de la dague au contact.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890264,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Escalade","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.gECPPcn6j3B3sWTS"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_escalade.webp","_id":"gECPPcn6j3B3sWTS","system":{"description":"<p>Escalader des obstacles, grimper à la corde, à un arbre, le long d’une paroi.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"force","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890264,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Légendes","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.i3wMVkXObzlDVZTG"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_legendes.webp","_id":"i3wMVkXObzlDVZTG","system":{"description":"<p>Connaissance des légendes et des faits du passé. Légendes tient lieu d’histoire.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"connaissance","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890264,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Fronde","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.iNXKIfaETtgSGA0S"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_fronde.webp","_id":"iNXKIfaETtgSGA0S","system":{"description":"<p>Utilisation de la fronde giratoire.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"tir","xp":0,"defaut_carac":"tir","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890264,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Arbalète","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.lt9VC7PkX4Faiduq"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_arbalete.webp","_id":"lt9VC7PkX4Faiduq","system":{"description":"<p>Utilisation de tous les types d’arbalètes.</p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"tir","xp":0,"defaut_carac":"tir","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890264,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Javelot","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.neuzZG2C5C0IJ1yk"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_javelot.webp","_id":"neuzZG2C5C0IJ1yk","system":{"description":"<p>Utilisation de la lance courte ou de la javeline en lancer.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"lancer","xp":0,"defaut_carac":"lancer","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890264,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Voie d'Oniros","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.nnR2UHelUaF8dxYn"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp","_id":"nnR2UHelUaF8dxYn","system":{"description":"<p>Magie s’appliquant au monde inanimé.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"draconic","xp":0,"defaut_carac":"reve","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890265,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Esquive","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.oFje22fZF1FaCQhN"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_esquive.webp","_id":"oFje22fZF1FaCQhN","system":{"description":"<p>Groupées en une seule jusqu’au niveau zéro, ces compétences sont les principes de base du combat de mêlée. Corps à corps permet de se battre sans armes ; Es-quive permet d’esquiver toutes les sortes de coup ; Dague de mêlée permet l’utilisation de la dague au contact.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"derobee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890265,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Cité","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.oHnSnCw1RAW5t15S"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_cite.webp","_id":"oHnSnCw1RAW5t15S","system":{"description":"<p>Se sentir à son aise dans un milieu urbain, dans une foule. Savoir s’orienter intuitivement dans le dédale d’une cité inconnue, et en déceler les dangers : coupeurs de bourse, escrocs, tout autant que patrouilles de gardes. Savoir à qui s’adresser.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"derobee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890265,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Jonglerie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.owCW3nZDvlJy1kCT"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_jonglerie.webp","_id":"owCW3nZDvlJy1kCT","system":{"description":"<p>Balles, quilles, couteaux, torches enflammées : l’art traditionnel du jongleur.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890265,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Natation","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.qBUtHhyjvrg1c34I"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_natation.webp","_id":"qBUtHhyjvrg1c34I","system":{"description":"<p>Nager, plonger.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"force","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890265,"modifiedTime":1671048297539,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Ecriture","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.qmIpUeedvjC8nGF1"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp","_id":"qmIpUeedvjC8nGF1","system":{"description":"<p>Lire et écrire. Savoir composer un texte, un poème. Connaissance générale des langues anciennes.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"connaissance","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Fléau","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.r79VAGS1fRUm4oAd"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_fleau.webp","_id":"r79VAGS1fRUm4oAd","system":{"description":"<p>Utilisation de tous les types de fléaux, pour attaquer.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Armes d'hast","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.rwsHwIDszSIPBkrO"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_armes_hast.webp","_id":"rwsHwIDszSIPBkrO","system":{"description":"<p>Utilisation de toutes les piques, vouges, hallebardes, toujours maniées à deux mains, pour attaquer.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Arc","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.tVbFkKSN4n0RSrFU"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_arc.webp","_id":"tVbFkKSN4n0RSrFU","system":{"description":"<p>Utilisation de tous les types d’arcs.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"tir","xp":0,"defaut_carac":"tir","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Dague de jet","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.thJy5AN0qePmfpJu"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_dague_jet.webp","_id":"thJy5AN0qePmfpJu","system":{"description":"<p>Utilisation de la dague en lancer.</p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"lancer","xp":0,"defaut_carac":"lancer","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Bricolage","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.tvIGIPaEJZBaySil"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_bricolage.webp","_id":"tvIGIPaEJZBaySil","system":{"description":"<p>L’art d’être inventif avec ses doigts, pour de petits aménagements ou réparations. Ne peut en aucun cas se substituer aux compétences d’artisanat, Charpenterie, Maçonnerie, etc. Bricolage est utilisé quand l’usage de ces compétences n’est pas pertinent.</p>\n<p> </p>","descriptionmj":"","niveau":-4,"default_diffLibre":0,"base":-4,"categorie":"generale","xp":0,"defaut_carac":"dexterite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Voie de Narcos","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.u1Peok1EYkBcVsmN"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_narcos.webp","_id":"u1Peok1EYkBcVsmN","system":{"description":"<p>Magie d’enchantement.</p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"draconic","xp":0,"defaut_carac":"reve","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Glaces","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.uGPqmorAYxv1jboC"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_glace.webp","_id":"uGPqmorAYxv1jboC","system":{"description":"<p>Par exemple pister un gibier en forêt demande l’usage de Survie en forêt, trouver une grotte pour s’abriter en montagne demande Survie en montagne. Survie en extérieur tient lieu de survie spécifique pour les plaines et collines non boisées.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Extérieur","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.ue5iDSm2f4efQDWO"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_exterieur.webp","_id":"ue5iDSm2f4efQDWO","system":{"description":"<p>Se sentir à son aise dans la nature, hors de toute civilisation, s’orienter. Construireun abri, allumer un feu en mauvaisesconditions, trouver de l’eau, pêcher, savoirExemplaire pour dépecer un gibier et l’accommoder sur un feu de braise. Quand un milieu particulier devient déterminant, utiliser à la place une des 6 survies spécifiques.</p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Survie en Désert","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.vDOAyWc2YnuhNnFF"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp","_id":"vDOAyWc2YnuhNnFF","system":{"description":"<p>Par exemple pister un gibier en forêt demande l’usage de Survie en forêt, trouver une grotte pour s’abriter en montagne demande Survie en montagne. Survie en extérieur tient lieu de survie spécifique pour les plaines et collines non boisées.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297540,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Fouet","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.vIQVQxUeiw36hztI"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_fouet.webp","_id":"vIQVQxUeiw36hztI","system":{"description":"<p>Utilisation du fouet.</p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"lancer","xp":0,"defaut_carac":"lancer","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297541,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Travestissement","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.w9QubIHdWEUorges"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_travestissement.webp","_id":"w9QubIHdWEUorges","system":{"description":"<p>L’art de se déguiser, de se grimer, de se rendre méconnaissable.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"apparence","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890266,"modifiedTime":1671048297541,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Hache à 1 main","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.wEfuLImdNX4BSXVi"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_hache_a_1_main.webp","_id":"wEfuLImdNX4BSXVi","system":{"description":"<p>Ces deux compétences permettent l’utilisation des hachettes, cognées et haches de bataille, pour attaquer.</p>\n<p> </p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890267,"modifiedTime":1671048297541,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Musique","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.wefdYe0kvWKioPmk"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_musique.webp","_id":"wefdYe0kvWKioPmk","system":{"description":"<p>Solfège et règles musicales, jeu d’un instrument. Musique donne droit à la connaissance d’un instrument de musique, un seul, à spécifier.</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"ouie","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890267,"modifiedTime":1671048297541,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Commerce","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.zO7Av9hJ2vdJiPgI"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp","_id":"zO7Av9hJ2vdJiPgI","system":{"description":"<p>Évaluer le prix d’une marchandise, la valeur d’une monnaie locale. Savoir</p>\n<p>jusqu’où l’on peut marchander (lequel marchandage doit être fait en jeu de rôle</p>\n<p>par le joueur lui-même).</p>\n<p> </p>","descriptionmj":"","niveau":-8,"default_diffLibre":0,"base":-8,"categorie":"particuliere","xp":0,"defaut_carac":"intellect","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890267,"modifiedTime":1671048297541,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Lance","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.zPTXua2Kq6TeBTTZ"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_lance.webp","_id":"zPTXua2Kq6TeBTTZ","system":{"description":"<p>Utilisation en mêlée de la lance courte et de la javeline, pour attaquer, voire parer. La lance n’est toujours qu’à une main.</p>\n<p> </p>","descriptionmj":"","niveau":-6,"default_diffLibre":0,"base":-6,"categorie":"melee","xp":0,"defaut_carac":"melee","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890267,"modifiedTime":1671048297541,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
||||
{"name":"Acrobatie","type":"competence","flags":{"core":{"sourceId":"Compendium.foundryvtt-reve-de-dragon.competences.zyNYa3hYtrOcF2jA"}},"img":"systems/foundryvtt-reve-de-dragon/icons/competence_acrobatie.webp","_id":"zyNYa3hYtrOcF2jA","system":{"description":"<p>Pirouettes, sauts périlleux, art du funambule, et d’une manière générale, toutes les performances d’agilité spécialisées.</p>\n<p> </p>","descriptionmj":"","niveau":-11,"default_diffLibre":0,"base":-11,"categorie":"specialisee","xp":0,"defaut_carac":"agilite","niveau_archetype":0,"xp_sort":0},"ownership":{"default":0,"Q4cUvqxCxMoTJXDL":3},"effects":[],"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.13","coreVersion":"10.291","createdTime":1671047890267,"modifiedTime":1671048297541,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user