Compare commits

..
117 Commits
Author SHA1 Message Date
fabres 3a55d8e912 Update changelog.md
Release Creation / build (release) Successful in 1m2s
2026-08-06 09:07:33 +02:00
fabres 7caeb0c918 Update changelog.md 2026-08-06 09:06:49 +02:00
fabres 188e7676fa docs: changelog des updates depuis 14.0.0 (migration V14, sommeil, tests) 2026-08-06 09:04:17 +02:00
fabres bb56a3a809 docs: documentation des tests (orchestrateur, liste, API) 2026-08-04 21:37:37 +02:00
fabres ac2e2027a0 test: orchestrateur run-all-tests.sh (demande démarrage monde, rapport final) 2026-08-04 21:36:12 +02:00
fabres dca201c5e2 fix: tc-header.sh utilise adminPassword au lieu de password (review #1) 2026-08-04 21:13:57 +02:00
fabres 5db30ddeb3 test: ajout 22 scripts TC (TC-08 a TC-31) + tc-header.sh partage 2026-08-04 21:08:43 +02:00
fabres 3758d0ca85 fix: compat V14 - _onFirstRender (HTMLElement.show), fermeture dialog TMR 2026-07-27 21:17:50 +02:00
VincentVk d8cfd02807 Regrouper les classes de combat
Elles sont souvent touchées ensemble

Préparation aux changements pour utiliser les Combatants
(pour gérer les empoignades/possessions en cours)

Renommages:
- RdDCombat -> PasseArmes
- RdDCombatManager -> RdDCombat
2026-07-26 22:58:25 +02:00
VincentVk 9aca2c32ef Fix assign dans constructeur
Pas possible de faire Object.assign(this.position car position == null
2026-07-26 22:57:17 +02:00
fabres 882aa5fbcb test: TC-07 feuilles item (44 types)
- creation + ouverture sheet pour les 44 types d'item
- verification scroll via .sheet-body overflow-y:auto
- 4/4 passed, 0 failed
2026-07-24 08:51:07 +02:00
fabres 1272cfdfd1 test: ajout plan de test et scripts TC-01 a TC-06
- rdd_test_plan.md : plan global, 227 cas, 33 sections
- TC-01 : infrastructure coeur (15/15)
- TC-02 : acteur personnage (7/7)
- TC-03 : acteur creature (11/11)
- TC-04 : acteur entite + subtypes + possession (14/14)
- TC-05 : acteur vehicule + structure/resistance (10/10)
- TC-06 : acteur commerce + achat/vente simules (14/14)

Scripts atomiques, async polling, page-state race-free
2026-07-24 08:08:04 +02:00
fabres 2348b2262b fix: champ age en StringField pour compat V14
- age passe de NumberField a StringField (evite erreur validation V14
  'must be a number' sur les acteurs existants)
- beaute reste en NumberField (utilise en calcul)
- expose RdDDice sur game.system.rdd.Dice
2026-07-24 08:07:10 +02:00
fabres 81cb3bb6bd fix: DialogV2 - formes imbriquees, boutons, styles et positionnement
- retire les <form> dans les templates DialogV2 (absorbe par V2)
- ajoute window: {frame, positioned} et enleve height:fit-content (bloquait deplacement vertical)
- ajoute buttons: [Fermer] sur tous les DialogV2 qui en manquaient
- style des dialogs chronologie, calendar-editor, stress
- corrige duplication des boutons calendrier a chaque re-render
- HandlebarsApplicationMixin sur FenetreRechercheTirage
- corrige selecteurs :input→input,select,textarea (jQuery→natif)
- ajoute banniere ASCII console au demarrage
2026-07-22 01:10:24 +02:00
fabres e0e3d4f230 fix: DialogV2 requiert au moins un bouton (buttons vides interdit en V14) 2026-07-22 00:35:47 +02:00
fabres 3afd111711 PUsh all v14 Stuff 2026-07-22 00:31:16 +02:00
fabres 1c288b654a fix: migration V14 - rollMode→messageMode, Token HUD, data-message-id
- remplace core.rollMode → core.messageMode (setting V14)
- migre toutes les cles (gmroll→gm, selfroll→self, blindroll→blind)
- corrige le hook renderTokenHUD pour recuperer le tokenId via app.document
- ajoute un bouton combat personnalise si absent du HUD V14
- corrige le toggle combat : isCombat manquant et guard si hors combat
- chat-utility : data-document-id→data-message-id pour les messages V14
- rdd-utility : idem pour findChatMessage/getChatMessageId
- roll-part-possession : getBestDraconic peut retourner undefined
- distance.mjs : Token→foundry.canvas.placeables.Token
2026-07-22 00:29:56 +02:00
fabres a5843888c0 fix: migration V14 et corrections diverses
migration v14:
- remplace CONFIG.Dice.rollModes → CONFIG.ChatMessage.modes
- canvas optionnel (?.tokens) dans ~27 fichiers
- async/await migrations, waitForRoll, effet draconique
- supprime _warnedAppV1, data-message-id→data-document-id
- corrige sheet registration Items.registerSheet

tmr:
- bouton Lancer un Sort visible en mode visu
- _ensureTMRButtons() en fallback JS
- await d'animation avant render
- corrigé doublon carteTMR.js

css:
- scrollbar (.item-sheet-scrollable-body) sur les 44 fiches item
- normalisation multiligne de tous les less/item/*.less
- style du dialogue description aléatoire (app-personnage-aleatoire)
- hr-sorts et sort réserves en flex-row

dialogue description:
- type=button sur les boutons (évite submit form → crash)
- randomControl passe this.actor au lieu de this.current
- DEFINITION_HEURES : ajout propriété manquante heure

d意:
- supprime 6 fichiers debug (phase*.txt/png, sheets-*.txt/png)
- system.json nom anglais→français
- token-hud : guard token undefined
- item-sort.js : guard sort?.system dans helpers Handlebars
2026-07-22 00:29:56 +02:00
fabres 7d9ebd601a chore: deplace 10 fichiers .js V1 inutilises vers _deprecated/ 2026-07-22 00:29:56 +02:00
fabres 25e3df1f5d Migration Foundry v14 : classes V1→V2, corrections CSS et bugs
- 21 classes Dialog → DialogV2
- 2 classes Application → ApplicationV2 + HandlebarsApplicationMixin
- 1 classe FormApplication → ApplicationV2
- 10 appels new Dialog() → DialogV2 (rdd-confirm, rdd-commands, etc.)
- base-actor-sheet.mjs : 3 appels new Dialog → DialogV2
- Sheet journal : JournalTextPageSheet → JournalEntryPageProseMirrorSheet
- CSS : backdrop-filter, box-shadow, bordures V2 supprimes pour calendar/astrologie
- FenetreRechercheTirage : _getWindowControls + dragDrop ajoutes
- HtmlUtility.showControlWhen : compat jQuery + DOM natif
- rdd-main.js : init calendrier en setTimeout
- Constantes : duplicate → deepClone, _id → id
- renderTemplate global → foundry.applications.handlebars.renderTemplate
2026-07-22 00:29:56 +02:00
fabres 84ce2f78d7 appv2: correction des éditeurs ProseMirror et scrollbar sur les fiches d'acteur
- Migration des fiches acteur V2 : racine <form> → <section>
  (DocumentSheetV2 encapsule déjà dans <form>, élimine les formulaires imbriqués)
- Ajout de submitOnChange: true sur la feuille de base acteur
  (nécessaire pour que les événements change des éditeurs déclenchent la mise à jour)
- Ajout de toggled=true + wrapper <fieldset><div><label> sur tous les formInput
  (comportement identique aux fiches d'objet)
- CSS : .window-content > section ajouté à côté de > form
  (évite la perte du flex layout et des scrollbar en passant de form à section)
- Modèles acteur : passage de StringField à HTMLField pour les champs
  description/notes/biographie/notesmj (permet le rendu ProseMirror)
- Ajout de systemFields dans le contexte _prepareContext()
2026-07-22 00:29:56 +02:00
fabres 8fddbe698c docs: ajoute TODO-v14.md pour suivi compatibilité Foundry v14 2026-07-22 00:29:56 +02:00
fabres d0a434fb0b refactor(styles): migre toutes les directives CSS inline vers LESS
- Remplace les vieilles règles table (mortes) des dialog-gerer-herbes
  et dialog-gerer-ingredients par des règles flex scoped
- Dialog-gerer-herbes/potions/ingredients/deniers : style= flex/gap/padding
  → classes LESS par dialog avec nth-child
- actor-sheet.hbs : gap+flex-wrap → .oeuvre-buttons,
  height:200px → .tab.hautreve
- carac-derivee.hbs : style sur .sust-buttons → déplacé dans LESS
- regles-optionnelles.hbs : width:100% → .btn-voir-tables-encaissement
- dialog-lancer-recette (hbs+js) : status colors → classes .status-*
- roll-part-appelmoral.hbs : font-size conditionnel → classe .moral-low
- rdd-utility.js : span style → .resultat-created
- rdd-import-stats.js : textarea style → #statBlock
- base-actor-sheet.js : select style → .qty-amount
- export-scriptarium/*.hbs : flex-grow, margin-bottom → classes
- app-personnage-aleatoire.hbs : text-align → .random-char-right

Seuls 2 styles dynamiques persistent : background-image option
(partial-roll-coeur.hbs) et width fillPercent barre (inventaire-item.hbs).
2026-07-22 00:29:56 +02:00
fabres 27b232776c fix(dialogs): évite bringToFront du dialog lors du re-render hook
Le hook updateItem/createItem/deleteItem appelait render(true)
déclenchant bringToFront() (ligne 598 ApplicationV2) qui
passait le dialog devant la fiche item ouverte. Utilise
render() sans force pour re-rendre sans changer le z-index.
2026-07-22 00:29:56 +02:00
fabres d06f1de433 fix(dialogs): refresh gestion herbes/potions/ingredients après édition fiche
Souscrit aux hooks updateItem/createItem/deleteItem pour
re-render le dialog quand un item de l'acteur change.
Nettoyage des hooks via _onClose().
2026-07-22 00:29:56 +02:00
fabres 54fc1e8e1a fix(migration): StatusEffects + SystemCompendiums -> ApplicationV2
Plus aucun FormApplication V1 dans module/settings/.
- Tous les settings menus migrés vers HandlebarsApplicationMixin(ApplicationV2)
- Templates sans wrapper <form>
- Scrollbar via LESS pour #status-effects et #system-compendiums
- Listeners jQuery -> DOM natif dans _onRender
2026-07-22 00:29:56 +02:00
fabres 70092ffd8f fix(migration): OptionsAvancees -> ApplicationV2
Migration V1→V2 identique à ReglesOptionnelles.
+ scrollbar dans LESS (#options-avancees > .window-content)
2026-07-22 00:29:56 +02:00
fabres 36b33890db fix(css): titres tables encaissement alternatives lisibles
h2 dans .encaissement-tables utilise --rdd-color-text-primary
(noir) au lieu de l'héritage blanc/clair du thème.
2026-07-22 00:29:56 +02:00
fabres ec2bf050d4 fix(v2): scrollbar ReglesOptionnelles -> .window-content overflow-y:auto
Le DOM réel n'a PAS .window-app ni .applicationv2 sur le form.
La structure: <form id=regles-optionnelles class=application> >
  .window-content. overflow: hidden dans le core V2 étouffe
le contenu. Fix: #regles-optionnelles > .window-content { overflow-y: auto; }
2026-07-22 00:29:56 +02:00
fabres 00edfe8201 fix(v2): scrollbar dans LESS, pas de style inline/template
Les rules flex+overflow pour les forms AppV2 sont dans
foundryvtt-reve-de-dragon.less. Plus aucun style inline
dans _onRender ni <style> dans les templates.
2026-07-22 00:29:56 +02:00
fabres 6fdb07a4e8 fix(v2): scrollbar via .regles-optionnelles.applicationv2 > .window-content
Le id de DEFAULT_OPTIONS est l'id d'application ui.windows,
PAS l'id DOM (#application-N). Les classes ({classes}) sont
appliquées sur .window-app. CSS ciblé via la classe fonctionne.
2026-07-22 00:29:56 +02:00
fabres c4f9150fdb fix(v2): scrollbar inline via _onRender flex styles
Le CSS via template ne fonctionnait pas car l'id V2 n'est pas
un sélecteur DOM fiable. On apply les styles flex/overflow
directement sur this.element et son premier enfant dans _onRender.
2026-07-22 00:29:56 +02:00
fabres 8400d88677 fix(v2): scrollbar dans DialogEncaissementTables aussi 2026-07-22 00:29:56 +02:00
fabres 93a1478cba fix(v2): scrollbar dans ReglesOptionnelles form overflow-y
Le formulaire ne scrollait pas car le form V2 (tag:'form')
n'avait pas de hauteur contrainte + overflow. Fix via CSS
ciblant #regles-optionnelles .window-content form > div.
2026-07-22 00:29:56 +02:00
fabres 51b05d025a fix(v2): wrapper single root element dans les templates
ApplicationV2 exige un unique élément racine par part.
regles-optionnelles.hbs et dialog-encaissement-tables.hbs
enveloppés dans un <div>.
2026-07-22 00:29:56 +02:00
fabres 348536556a fix(migration): ReglesOptionnelles + DialogEncaissementTables -> ApplicationV2
V1 FormApplication déprécié depuis Foundry v13. Migration vers
HandlebarsApplicationMixin(ApplicationV2) :
- DEFAULT_OPTIONS statique remplace defaultOptions getter
- _prepareContext() async remplace getData()
- _onRender() avec DOM natif remplace activateListeners(html)
- PARTS remplace template
- form: {} sub-object remplace closeOnSubmit/submitOnChange plats
- Templates sans <form> wrapper (V2 l'injecte via tag:'form')
2026-07-22 00:29:56 +02:00
fabres afabba430a feat(encaissement): tables révisées optionnelles + consultation dialog
- Nouveau setting 'tables-encaissement-revisees' dans Options alternatives
- Paliers fins (01-20+), pertes statiques, '@end0' vide endurance à 0
- Dialog de consultation avec les 2 tables (mortel/non-mortel)
- Lien 'Voir les tables d'encaissement' dans le menu Règles optionnelles (MJ)
2026-07-22 00:29:56 +02:00
fabres 3e63054b9d refactor(regles): fusion des Règles customs dans Règles optionnelles -> section Options alternatives, suppress fichiers 2026-07-22 00:29:56 +02:00
fabres 07997576cd style(sust): boutons Repas externe et Rations harmonisés avec chat-card-button 2026-07-22 00:29:56 +02:00
fabres d216e8fcf6 fix(sheets): ajout des sections environnement (inventaire) et temporel (blessure, maladie, poison, rencontre, signedraconique) manquantes dans les sheets V2 2026-07-22 00:29:56 +02:00
fabres 29cdcca1bb fix(cd): message stress journal : perte fixe de 1, reste X, conversion Y en xp 2026-07-22 00:29:56 +02:00
fabres 8c9c8f3345 feat(cd): journal enrichi avec stress, perte enchantements, moral 2026-07-22 00:29:56 +02:00
fabres 8e748a1d94 feat(cd): message statut MJ + journal de suivi stress/moral/events par jour 2026-07-22 00:29:56 +02:00
fabres 7599db07ad feat(repos): nouveau mode sommeil avec sélection heures, dialogs CD intégrés, toolbar équipement 2026-07-22 00:29:56 +02:00
fabres 1db733f379 fix(rations): ne plus afficher 'rien à manger' quand les compteurs sont déjà pleins 2026-07-22 00:29:56 +02:00
fabres 07a48fb3cc refactor(sheets): migration item sheets v13 (models, apps, templates, moins + common/mixins) 2026-07-22 00:29:53 +02:00
fabres f52575f413 fix(rations): consomme assez d'unités pour remplir sust/eau en 1 clic + alerte si vide 2026-07-22 00:26:52 +02:00
fabres 5969009eb1 feat(inventaire): boutons +Ration/+Eau, cartouche chat compact
- Boutons +Ration et +Eau dans l'onglet Équipement
- Incrémente la quantité si l'item existe déjà, sinon le crée
- Nouveau template post-item-compact.hbs pour l'aperçu chat
- _MONTRER utilise désormais le cartouche compact
- postItemToChatCompact() awaitable, champs filtrés par type d'inventaire
2026-07-22 00:26:52 +02:00
VincentVk 37a33691ff 14.0.1 - Les imprécisions de Tétragor
Release Creation / build (release) Failing after 14s
2026-07-21 22:45:47 +02:00
VincentVk ce7271b569 Fix: ouverture des items
Fix appel methode sur objet SANS_COMPETENCE, qui n'etait pas
un RdDItem / RdDItemCompetence
2026-07-21 22:28:06 +02:00
VincentVk 5dbd7c3784 Fix Description aléatoire 2026-07-17 03:07:30 +02:00
fabres a55904742b fix(encombrement): exclure le poids propre des conteneurs du total
- Les conteneurs n'ajoutent plus leur propre encombrement au total
  (seuls les objets qu'ils contiennent sont comptés)
- Ajout indicateur visuel quand une compétence atteint son niveau d'archétype
  (bordure dorée + icône ✓)
2026-07-14 22:08:32 +02:00
fabres ded584ccc8 feat(inventaire): tri par quantité, dialogues de gestion, duplication cachée des livres lus
Release Creation / build (release) Successful in 1m45s
- Remplace le tri 'Manuel' par un tri 'Quantité' dans l'inventaire
- Supprime _onDrop / _onSortItem (obsolètes sans tri manuel)
- Nouveau dialogue 'Gérer ses deniers' (ApplicationV2)
- Nouveau dialogue 'Gérer ses potions' (ApplicationV2)
- Boutons herbes/ingrédients/potions/deniers déplacés dans l'onglet Équipement
- Dialogues herbes/ingrédients harmonisés (alterne-list, contrôles +/-)
- Ajout titre 'Livres lus' et en-têtes alignés
- Ajout estCopieLue au schéma livre (template.json)
- creerCopieLue() extrait dans base-actor.js
- Filtre estCopieLue dans prepareInventaire/buildContenuConteneur
2026-07-14 18:56:38 +02:00
fabres ac10de85cf Gestion des livres lus et des herbes 2026-07-14 08:28:44 +02:00
VincentVk b9fec47311 Correction du but des recettes alchimiques 2026-07-14 01:21:52 +02:00
VincentVk 7d5903aa84 Support des tâches à plusieurs
Release Creation / build (release) Successful in 1m50s
2026-07-11 16:12:15 +02:00
VincentVk 66a8eb0e8a Images de la barre de menu droite 2026-07-11 01:16:10 +02:00
VincentVk 6636ebb77c Améliorations des titres des fenêtres de jets 2026-07-10 23:37:42 +02:00
VincentVk 89207df01d Correction d'updates non affichés 2026-07-10 20:34:16 +02:00
VincentVk 000e16f8b7 Amélioration sur les voies de Draconic
- Ne pas proposer les voies de Draconic à -11 pour lire un signe
  draconic ou lancer un sort
- Trier les voies par ordre décroissant pour le sorts à voies multiples
- Les rencontres et les maîtrises dans les TMR peuvent être vaincues
  sans draconic si les voies sont négatives
2026-07-10 19:26:34 +02:00
VincentVk bbbc817e5f Pas de lecture avec Draconic à -11 2026-07-10 18:13:29 +02:00
VincentVk b89dd3845a Visibilité des jets /rdd 2026-07-10 18:07:08 +02:00
VincentVk 6c239b8ed9 Suppression de TMR "Inconnu" pour signes 2026-07-10 16:50:41 +02:00
VincentVk e42e12f56f Publish version 1.1.1
Release Creation / build (release) Successful in 1m1s
2026-06-29 23:11:01 +02:00
VincentVk 32f99e35ef Using nodejs 24 for release actions
Release Creation / build (release) Failing after 1m19s
2026-06-29 01:00:17 +02:00
VincentVk ae42bc4aa4 Using nodejs 24 for release actions 2026-06-29 00:56:07 +02:00
VincentVk 089c0c2243 Correction des couleurs des tooltips d'aide foundry
Release Creation / build (release) Failing after 1m1s
2026-06-28 23:49:56 +02:00
VincentVk e34449631c Optimisation fenêtre de jets
La fenêtre de jet pour les attaques à distance prenait
trop de hauteur sur petit écran.

La difficulté était mal visualisée par les joueurs (et confondue
avec les conditions)

Le d100 de la zone "tricher" était un peu trop gros

Les ajustements sont organisés plus logiquement: difficulté,
conditions, ajustements à cocher
2026-06-20 18:38:48 +02:00
VincentVk f8a20b90ff Génération aléatoire d'archétype 2026-06-20 18:38:48 +02:00
VincentVk 749eb5ee13 upgrade publish action 2026-06-20 18:38:47 +02:00
VincentVk 17cb8a2e06 13.0.45
Release Creation / build (release) Successful in 1m23s
2026-06-16 23:02:39 +02:00
VincentVk 933256da66 Nouvelle correction du manifest
Release Creation / build (release) Has been cancelled
Le manifest versionné, téléchargé dans le système, pointe maintenant
sur le manifest latest.

Le lien manifest foundry est celui du manifest de la version.
2026-06-16 22:59:36 +02:00
VincentVk a58b171fb4 13.0.44 - Le dépôt d'Illisys
Release Creation / build (release) Successful in 1m5s
- le manifest pointe maintenant toujours vers la dernière version
- changement des liens dans le system.json
2026-06-15 21:26:03 +02:00
VincentVk 2eac969261 Update system.json
even if not necessary, it was referencing previous repository
2026-06-14 22:41:04 +02:00
fabres e6612fe024 Make default release as latest 2026-06-14 21:57:55 +02:00
fabres 18b9e4c7a8 Updte gitignore 2026-06-14 21:55:48 +02:00
VincentVk fcaebe6334 Correction des jets impossibles
Release Creation / build (release) Successful in 1m58s
2026-06-12 00:26:54 +02:00
VincentVk c4033707be macro signe draconique
Release Creation / build (release) Successful in 1m48s
2026-06-03 00:56:52 +02:00
VincentVk 8b83369d5a On peut choisir la difficulté de résistance
La difficulté des jets de résistance est libre
2026-06-03 00:46:15 +02:00
VincentVk e9183df59c le Guerrier Sorde n'est pas joueur 2026-06-03 00:46:15 +02:00
VincentVk 45ccac3489 Mineur - rendu monnaies 2026-06-03 00:39:12 +02:00
VincentVk c41db974ff Corrections description aléatoire 2026-06-03 00:39:12 +02:00
VincentVk 875e121a09 Merge pull request '13.0.41 -mode de visibilité des jets' (#808) from feature/v13-corrections into v13
Release Creation / build (release) Successful in 1m0s
Reviewed-on: https, #808
2026-05-29 02:08:11 +02:00
VincentVk 12e0e6397c mode de visibilité des jets 2026-05-29 02:01:30 +02:00
VincentVk 93b74574ad pas de stress/sommeil pour personnage non lié
Release Creation / build (release) Successful in 1m32s
2026-05-29 01:53:35 +02:00
VincentVk 1765cb2ef9 Mode de visibilité des jets 2026-05-29 01:53:35 +02:00
VincentVk 0cbd7a6deb Merge pull request '13.0.39 - La défense d'Illisys' (#806) from feature/v13-corrections into v13
Release Creation / build (release) Successful in 1m1s
Reviewed-on: https, #806
2026-05-10 15:06:35 +02:00
VincentVk aec4364889 Type de jet: Jet de résistance 2026-05-09 23:14:28 +02:00
VincentVk f17996b1c8 Difficultés attaque/défense sur appel à la chance 2026-05-09 22:41:47 +02:00
VincentVk 14a4b34bbd Correction jets de compétence des invocations 2026-05-09 22:41:02 +02:00
VincentVk 1777eced30 Correction des catégories de parades 2026-05-09 21:42:09 +02:00
VincentVk 9bdda32d54 Merge pull request 'Set version changelog 13.0.38' (#805) from feature/v13-corrections into v13
Release Creation / build (release) Successful in 2m29s
Reviewed-on: https, #805
2026-05-05 23:55:45 +02:00
VincentVk 3fe53d7ff0 Set version changelog 13.0.38 2026-05-05 23:55:16 +02:00
VincentVk c839d4633d Merge pull request '## 13.0.37 - L'urgence d'Illisys' (#804) from feature/v13-corrections into v13
Reviewed-on: https, #804
2026-05-05 23:54:19 +02:00
VincentVk 24753bfc29 Appel chance RollDialogV2 2026-05-05 23:51:04 +02:00
VincentVk e7acb0c4f2 Fix v14 Dés dice-so-nice 2026-05-05 21:51:01 +02:00
VincentVk 7535e5f340 Fix v14: /roll dans le tchat 2026-05-05 21:48:24 +02:00
VincentVk d2326e5a25 Fix: liste des actions disponibles
- ajout du haut-rêve
- possibilité de ne lister que les armes équipées
2026-05-05 02:12:48 +02:00
VincentVk e2afc24601 Message en cas d'erreur de migration 2026-05-02 16:46:25 +02:00
VincentVk f220e3a394 Merge pull request 'Version 13.0.37' (#803) from feature/v13-corrections into v13
Release Creation / build (release) Successful in 1m28s
Reviewed-on: https, #803
2026-05-02 16:37:40 +02:00
VincentVk 1d9348b701 Version 13.0.37 2026-05-02 16:36:51 +02:00
VincentVk d96dff988e Merge pull request 'isNewerVersion' (#802) from feature/v13-corrections into v13
Reviewed-on: https, #802
2026-05-02 16:35:21 +02:00
VincentVk 9966a33524 Correction Migration avec Foundry14
Accès à méthode isNewerVersion à travers foundry.utils
2026-05-02 16:32:19 +02:00
VincentVk 7fb0ee1659 await ChatMessage.create
ChatMessage.create est async, il faut donc de préférence
l'appeler avec un await.

Des effets secondaires avaient lieu (ordre de messages, updates
ultérieurs parfois pas pris en compte)
2026-05-02 00:42:45 +02:00
VincentVk d15d0989a3 Remise à zéro du refoulement après souffle 2026-05-01 23:56:17 +02:00
VincentVk 704c99e418 Correction: modification de coeurs 2026-05-01 23:38:05 +02:00
VincentVk 9ccc068333 Amélioration du moral
Les bon moments sont affichés en tooltips sur le moral

Simplification moralIncDec: Utilisation d'un seul update
2026-05-01 23:20:58 +02:00
VincentVk 6b0a6a268e Merge pull request '13.0.36 - Les rêveries d'Illisys' (#801) from feature/v13-corrections into v13
Release Creation / build (release) Successful in 1m45s
Reviewed-on: https, #801
2026-04-30 18:25:47 +02:00
VincentVk c7da930556 Boutons dans les listes d'équipement
Affichage amélioré en évitant les retours à la ligne
Meilleur affichage des -/+
2026-04-30 00:05:31 +02:00
VincentVk e9e2eba9b5 Support v14: commandes dans chatMessage en html 2026-04-29 22:53:23 +02:00
VincentVk 423dcaf53e Cuisiner depuis l'équipement 2026-04-29 22:53:23 +02:00
VincentVk a01086ff28 Amélioration champs input
- ajout de min et max quand utile
- ordre et regroupement des attributs:
   - préférence pour name en premier
   - regroupement de class/type/data-dtype
   - regroupement value/min/max
2026-04-29 22:53:22 +02:00
VincentVk 76e651cf19 Corrections mineures 2026-04-28 19:21:00 +02:00
VincentVk eaee50511a Fix v14: attaque à distance 2026-04-28 19:10:38 +02:00
VincentVk d1832917bc Message de dommage sur entité
Plutôt que de dire "ne subit aucun dommage", une gravité de blessure
indicative est donnée
2026-04-28 19:09:08 +02:00
VincentVk 277799088f Affichage des jeux 2026-04-28 19:07:24 +02:00
VincentVk 0398fbdbd1 Fix: Pas d'affichage de feuille sur encaissement 2026-04-28 19:07:00 +02:00
645 changed files with 23785 additions and 9280 deletions
+28
View File
@@ -0,0 +1,28 @@
# Session Summary: v13 Migration — DataModel + _id/duplicate Cleanup + template.json removal
## Done
### `duplicate()` → `deepClone()` (finding #10, 36 files)
`foundry.utils.duplicate()``foundry.utils.deepClone()` across the system. `deepClone` preserves Document prototypes where `duplicate` stripped them.
### `_id` → `id` on Documents (finding #11, finding #7, ~25 sites)
- 21 read accesses migrated during initial sweep
- Review sweep caught 3 more: `rdd-combat.js:148` (combatant._id), `rdd-combat.js:898` (esquive e._id), `rdd-tmr-dialog.js:261` (casetmr._id)
- Also fixed: `actor.js:1844` (selectedSort._id), `actor.js:2884` (herbeData._id), `base-actor.js:404` (conteneur c._id)
- Remaining `_id` references are on POJOs (`toObject()`/migration data) — correct.
### `_onClose` → `super._onClose()` (finding #9)
All dialog `_onClose` overrides now call `super._onClose()` for proper HandlebarsApplicationMixin cleanup.
### Actor DataModel Migration (3 phases)
- Phase 1: 5 DataModels in `module/models/` + helpers + `CONFIG.Actor.dataModels` registration
- Phase 2: `prepareActorData()` chain → DataModel `prepareDerivedData()` in each model
- Phase 3: template.json deletion, dead code cleanup
### `template.json` elimination (like `fvtt-hawkmoon-cyd`)
- `template.json` deleted. Foundry v13+ uses `documentTypes` in system.json.
- Added `documentTypes.Actor` (5 types) + `documentTypes.Item` (44 types) with `htmlFields`
- Fixed CI/CD files referencing template.json
## Still remaining (v14-blocking)
V1 Application/Dialog classes (24 `extends Dialog`, 6+ V1 sheets) cannot run in v14 — findings #1#6.
+6 -5
View File
@@ -32,13 +32,13 @@ jobs:
env:
version: ${{steps.get_version.outputs.version-without-v}}
url: https://gitea.scriptarium.org/${{gitea.repository}}
manifest: https://gitea.scriptarium.org/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json
manifest: "https://gitea.scriptarium.org/Scriptarium/foundryvtt-reve-de-dragon/releases/download/latest/system.json"
download: https://gitea.scriptarium.org/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/rddsystem.zip
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: "18" # Use the node version your project requires
node-version: "24" # Use the node version your project requires
- name: Install dependencies
run: npm install
@@ -47,7 +47,7 @@ jobs:
run: node ./tools/packCompendiumsToDist.mjs
- name: Create ZIP file
run: zip -r ./rddsystem.zip system.json template.json README.md LICENSE.txt assets/ css/ fonts/ icons lang/ module/ packs/ pic/ sounds/ styles/ templates/
run: zip -r ./rddsystem.zip system.json README.md LICENSE.txt assets/ css/ fonts/ icons lang/ module/ packs/ pic/ sounds/ styles/ templates/
- name: setup go
uses: actions/setup-go@v3
@@ -64,12 +64,13 @@ jobs:
api_key: "${{secrets.RDD_PUBLISH_RELEASE}}"
- name: Publish to Foundry server
uses: djlechuck/foundryvtt-publish-package-action@v1
uses: djlechuck/foundryvtt-publish-package-action@v1.1.1
with:
token: ${{ secrets.RDD_PUBLISH_RELEASE_FOUNDRY }}
id: "foundryvtt-reve-de-dragon"
version: ${{github.event.release.tag_name}}
manifest: "https://gitea.scriptarium.org/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json"
manifest: https://gitea.scriptarium.org/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json
notes: "https://gitea.scriptarium.org/Scriptarium/foundryvtt-reve-de-dragon/raw/branch/v13/changelog.md"
compatibility-minimum: "13"
compatibility-verified: "13"
node-version: "24"
+4
View File
@@ -12,3 +12,7 @@ todo.md
/packs/*/CURRENT
/packs/*/LOG
/packs/*/LOCK
.github/
*.bak
/AGENTS.md
/regles/
-1
View File
@@ -12,7 +12,6 @@ test:
stage: test
script:
- python -mjson.tool 'system.json' > /dev/null
- python -mjson.tool 'template.json' > /dev/null
build:
stage: build
+68
View File
@@ -0,0 +1,68 @@
# TODO v14 — Compatibilité Foundry VTT
## ✅ Bloquant — terminé
### 1. ✅ Sheets acteur V1 → V2
- V1 déplacés vers `_deprecated/module/actor/` (10 fichiers `.js`)
- V2 dans `module/applications/sheets/` (fichiers `.mjs`)
### 2. ✅ Sheet journal V1 → V2
- `module/journal/journal-sheet.mjs``extends JournalEntryPageProseMirrorSheet`
- `_prepareContentContext` override → `RdDTextEditor.enrichHTML()`
- `_onRender` → roll-text/chat-roll-text click listeners
### 3. ✅ 24 classes `extends Dialog` → V2
- Toutes converties en `extends foundry.applications.api.DialogV2`
- `module/tirage/fenetre-recherche-tirage.js``FenetreRechercheTirage` migré V1 App → V2 ApplicationV2
- `module/sommeil/dialog-nouveau-repos-cd.js``new Dialog(...)` direct → `DialogV2.wait()`
### 4. ✅ 3 classes `extends Application` → V2
- `module/tirage/fenetre-recherche-tirage.js` — FAIT (ApplicationV2)
- `module/time/rdd-calendrier.js` (RdDCalendrier) — FAIT (ApplicationV2)
- `module/sommeil/app-astrologie.js` (AppAstrologie) — FAIT (ApplicationV2)
### 5. ✅ 1 classe `extends FormApplication` → V2
- `module/actor/random/app-personnage-aleatoire.js` — FAIT (ApplicationV2)
### 6. ✅ 7 appels `new Dialog({...})` directs → DialogV2
Tous convertis. +3 autres dans `module/applications/sheets/base-actor-sheet.mjs` & `personnage-sheet.mjs`.
## 🟠 Haute priorité
### 7. ✅ `_id` dans `updateEmbeddedDocuments` → utiliser `.id` — **FAIT** (10 occ. changées, 2 déjà OK, 1 string param)
### 8. ✅ `bringToFront()` sur apps V1 → adapter
Rétrocompatibilité V2 gère. Pas d'erreur constatée (les apps converties utilisent V2).
### 9. ✅ `_onClose()` sans `super._onClose()` → **FAIT**
- `module/dialog-gerer-potions.js:45-49`
- `module/dialog-gerer-ingredients.js:45-49`
- `module/dialog-gerer-herbes.js:47-51`
## 🟡 Priorité moyenne
### 10. ✅ `foundry.utils.duplicate()` → `deepClone()` — **FAIT** (36 fichiers)
### 11. ✅ `._id` en lecture → `.id` — **FAIT** (21 occ. changées, 11 conservées sur objets de données)
~45 occurrences : `item._id`, `actor._id`, `combatant._id`, `token._id`
### 12. `render(true)` sur apps V2 → `render({force: true})`
Rétrocompatibilité V2 normalise booléen → pas prioritaire.
~60 occurrences dans module/ — nos fichiers convertis l'utilisent déjà.
### 13. ✅ Incohérence registration sheets
`module/applications/sheets/common-item-sheet.mjs``Items.registerSheet()``foundry.documents.collections.Items.registerSheet()`
## 🟢 Basse priorité / Info
### 14. ✅ `canvas` sans vérification `ready`
27 occurrences dans 11 fichiers sécurisées avec `?.`
### 15. ✅ `element[0]` jQuery
`module/tirage/fenetre-recherche-tirage.js:213` — déjà résolu par refacto antérieur
### 16. ✅ `_warnedAppV1 = true`
Supprimé de `rdd-calendrier.js`; restant dans `_deprecated/` ignoré
### 17. ✅ `system.json` — nom de langue
`"name": "English"``"Français"` pour ne pas tromper sur `lang/fr.json`
@@ -2,7 +2,7 @@ import { RdDUtility } from "./rdd-utility.js";
import { HtmlUtility } from "./html-utility.js";
import { RdDBonus } from "./rdd-bonus.js";
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
import { RdDCombat } from "./combat/rdd-combat.js";
import { CARACS, RdDCarac } from "./rdd-carac.js";
import { DialogSplitItem } from "./dialog-split-item.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
@@ -13,7 +13,7 @@ import { ACTOR_TYPES, ITEM_TYPES } from "./constants.js";
import { RdDItem } from "./item.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemBlessure } from "./item/blessure.js";
import { RdDEmpoignade } from "./rdd-empoignade.js";
import { RdDEmpoignade } from "./combat/rdd-empoignade.js";
import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js";
import { RdDCoeur } from "./coeur/rdd-coeur.js";
import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js";
@@ -31,7 +31,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
static get defaultOptions() {
return foundry.utils.mergeObject(RdDBaseActorReveSheet.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.hbs",
width: 550,
width: 640,
showCompNiveauBase: false,
vueArchetype: false,
}, { inplace: false })
@@ -70,6 +70,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
fatigue: RdDUtility.calculFatigueHtml(formData.system.sante.fatigue.value, formData.system.sante.endurance.max)
})
this.amendTacheCommunes(formData)
formData.competences.forEach(item => {
item.system.isHidden = this.options.recherche
@@ -100,20 +101,38 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
cacheTMR: this.actor.isTMRCache()
}
formData.livresLus = formData.livres.filter(l => l.system.estCopieLue)
formData.livres = formData.livres.filter(l => !l.system.estCopieLue)
formData.race = actor.itemTypes[ITEM_TYPES.race].find(it => true)
formData.subacteurs = {
vehicules: this.actor.listeVehicules(),
montures: this.actor.listeMontures(),
suivants: this.actor.listeSuivants()
}
if (this.actor.getBestDraconic().system.niveau > -11 && !this.actor.isHautRevant()) {
if (this.actor.getDraconics().find(it => it.system.niveau > -11) && !this.actor.isHautRevant()) {
ui.notifications.error(`${this.actor.name} a des compétences draconiques, mais pas le don de Haut-Rêve!
<br>Ajoutez-lui la tête "Don de Haut-Rêve" pour lui permettre d'utiliser ses compétences et d'accéder aux terres médianes du rêve`);
}
}
else {
console.error("Ouverture actor-sheet avec un acteur non personnage")
}
return formData;
}
amendTacheCommunes(formData) {
formData.taches
.forEach(tache => {
if (tache.isTacheCommune()) {
const tacheCommune = tache.getTacheOuCommune()
tache.system = foundry.utils.deepClone(tacheCommune.system)
tache.system.tacheCommuneId = tache.system.tacheCommuneId
}
return tache
})
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
@@ -195,7 +214,24 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.action-jeu').click(async event => await this.actor.rollJeu(RdDSheetUtility.getItemId(event)))
this.html.find('.action-recettecuisine').click(async event => await this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event)))
this.html.find('.description-aleatoire').click(async event => new AppPersonnageAleatoire(this.actor).render(true))
this.html.find('.description-aleatoire').click(async event => new AppPersonnageAleatoire(this.actor).render({ force: true }))
this.html.find('.gerer-herbes').click(async event => {
const { DialogGererHerbes } = await import("./dialog-gerer-herbes.js")
DialogGererHerbes.create(this.actor)
})
this.html.find('.gerer-ingredients').click(async event => {
const { DialogGererIngredients } = await import("./dialog-gerer-ingredients.js")
DialogGererIngredients.create(this.actor)
})
this.html.find('.gerer-deniers').click(async event => {
const { DialogGererDeniers } = await import("./dialog-gerer-deniers.js")
DialogGererDeniers.create(this.actor)
})
this.html.find('.gerer-potions').click(async event => {
const { DialogGererPotions } = await import("./dialog-gerer-potions.js")
DialogGererPotions.create(this.actor)
})
if (game.user.isGM) {
// experience log
this.html.find('.experiencelog-delete').click(async event => {
@@ -216,7 +252,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
// Points de reve actuel
this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollReveActuel({ resistance: false }))
this.html.find('.button-reve-resistance').click(async event => await this.actor.rollReveActuel({ diff: -8, resistance: true }))
this.html.find('.button-reve-resistance').click(async event => await this.actor.rollReveResistance())
this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
this.html.find('.roll-arme').click(async event => {
@@ -229,7 +265,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.roll-init-arme').click(async event => {
let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id)
if (combatant) {
RdDCombatManager.rollInitiativeAction(combatant._id, this._getActionCombat(event));
RdDCombat.rollInitiativeAction(combatant.id, this._getActionCombat(event));
} else {
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
}
@@ -275,6 +311,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
await this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value));
});
this.html.find('.nouvelle-incarnation').click(async event => await this.actor.nouvelleIncarnation())
this.html.find('.repartition-archetype-aleatoire').click(async event => await this.actor.repartitionArchetypeAleatoire())
}
// On pts de reve change
@@ -286,6 +323,8 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
this.html.find('.moral-neutre').click(async event => await this.actor.jetDeMoral(MORAL.NEUTRE))
this.html.find('.moral-heureux').click(async event => await this.actor.jetDeMoral(MORAL.HEUREUX))
this.html.find('.button-ethylisme').click(async event => await this.actor.jetEthylisme())
this.html.find('.btn-sust-externe').click(async event => await this.actor.mangerExterne())
this.html.find('.btn-sust-rations').click(async event => await this.actor.mangerRations())
this.html.find('.ptreve-actuel-plus').click(async event => await this.actor.reveActuelIncDec(1))
this.html.find('.ptreve-actuel-moins').click(async event => await this.actor.reveActuelIncDec(-1))
@@ -334,18 +373,13 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
}
content += '</select>';
let dialog = new Dialog({
new foundry.applications.api.DialogV2({
title: "Créer une oeuvre",
content: content,
buttons: {
create: {
icon: '<i class="fas fa-check"></i>',
label: "Créer l'oeuvre",
callback: () => this.actor.createItem($(".item-type").val())
}
}
});
dialog.render(true);
content,
buttons: [
{ label: "Créer l'oeuvre", action: "create", icon: "fa-solid fa-check", callback: () => this.actor.createItem($(".item-type").val()) }
]
}).render({ force: true });
}
/* -------------------------------------------- */
@@ -391,7 +425,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
async _onSplitItem(item, split) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split);
const splitItem = foundry.utils.duplicate(item);
const splitItem = foundry.utils.deepClone(item);
splitItem.system.quantite = split;
await this.actor.createEmbeddedDocuments('Item', [splitItem])
}
@@ -14,7 +14,7 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet {
/** @override */
static get defaultOptions() {
return foundry.utils.mergeObject(RdDBaseActorSheet.defaultOptions, {
width: 550
width: 640
});
}
@@ -36,7 +36,7 @@ export class RdDBaseActorSangSheet extends RdDBaseActorReveSheet {
async jetEndurance() {
const endurance = this.actor.getEnduranceActuelle()
const result = await this.actor.jetEndurance(endurance);
ChatMessage.create({
await ChatMessage.create({
content: `Jet d'Endurance : ${result.jetEndurance} / ${endurance}
<br>${this.actor.name} a ${result.sonne ? 'échoué' : 'réussi'} son Jet d'Endurance ${result.sonne ? 'et devient Sonné' : ''}`,
whisper: ChatUtility.getOwners(this.actor)
@@ -8,6 +8,8 @@ import { RdDItem } from "../item.js";
import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js";
import { ItemAction } from "../item/item-actions.js";
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
import { DialogVerifierIngredients } from "../dialog-verifier-ingredients.js";
import { DialogLancerRecette } from "../dialog-lancer-recette.js";
/* -------------------------------------------- */
/**
@@ -23,7 +25,9 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
classes: ["rdd", "sheet", "actor"],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
vueDetaillee: false
scrollY: [".sheet-body"],
vueDetaillee: false,
triEquipement: 'name'
}, { inplace: false })
}
@@ -45,7 +49,7 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
effects: this.actor.effects
}
RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes, this.options.triEquipement);
formData.calc = {
fortune: Monnaie.toSolsDeniers(this.actor.getFortune()),
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
@@ -88,6 +92,8 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
this.html.find('.actionItem').click(async event => await ItemAction.onActionItem(event, this.actor, this.options))
this.html.find('.item-edit').click(async event => await this.itemActionEdit(event))
this.html.find('.item-verify-ingredients').click(async event => await this._onVerifyIngredients(event))
this.html.find('.item-lancer-recette').click(async event => await this._onLancerRecette(event))
this.html.find('.conteneur-name a').click(async event => {
RdDUtility.toggleAfficheContenu(this.getItemId(event))
this.render(true)
@@ -104,6 +110,16 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
this.html.find('.recherche').prop("disabled", false)
this.html.find('.item-list .item').dblclick(async event => {
const item = this.getItem(event)
if (item) item.sheet.render(true)
})
this.html.find('.tri-equipement').change(event => {
this.options.triEquipement = event.currentTarget.value;
this.render(true);
})
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
@@ -111,9 +127,71 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
this.html.find('.item-delete').click(async event => await RdDUtility.confirmActorItemDelete(this.getItem(event), this.actor));
this.html.find('.item-quantite-plus').click(async event => await this.actor.itemQuantiteIncDec(this.getItemId(event), 1));
this.html.find('.item-quantite-moins').click(async event => await this.actor.itemQuantiteIncDec(this.getItemId(event), -1));
this.html.find('.item-quantite').change(async event => {
const input = event.currentTarget;
const item = this.actor.items.get(input.dataset.itemId);
if (item) {
const newQty = Math.max(0, parseInt(input.value) || 0);
await item.update({ 'system.quantite': newQty });
if (newQty === 0) this.render(true);
}
})
this.html.find('.item-quantite').on('contextmenu', async event => {
event.preventDefault()
const item = this.getItem(event)
if (!item?.isInventaire()) return
new foundry.applications.api.DialogV2({
title: `Quantité — ${item.name}`,
content: `<p>Réduire la quantité de :</p>
<select class="qty-amount">
<option value="1">1</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="all">Tout jeter</option>
</select>`,
buttons: [
{ action: "reduce", label: "Retirer", icon: "fa-solid fa-minus", callback: (event, button, dialog) => {
const amount = dialog.element.querySelector('.qty-amount').value
if (amount === 'all') {
item.delete()
this.render({ force: true })
} else {
item.update({ 'system.quantite': Math.max(0, item.system.quantite - parseInt(amount)) })
}
}}
]
}).render({ force: true })
})
this.html.find('.creer-un-objet').click(async event => await this.selectObjetTypeToCreate())
this.html.find('.nettoyer-conteneurs').click(async event => await this.actor.nettoyerConteneurs())
this.html.find('.quick-add-ration').click(async event => {
const existante = this.actor.items.find(it => it.type === "nourritureboisson" && it.name === "Ration")
if (existante) {
await existante.update({ "system.quantite": Math.max(0, Number(existante.system.quantite) + 1) })
} else {
await this.actor.createEmbeddedDocuments('Item', [{
name: "Ration", type: "nourritureboisson",
img: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
system: { sust: 1, encombrement: 0.1, quantite: 1, cout: 0.1, boisson: false }
}], { renderSheet: false })
}
this.render(true)
})
this.html.find('.quick-add-eau').click(async event => {
const existante = this.actor.items.find(it => it.type === "nourritureboisson" && it.name === "Eau")
if (existante) {
await existante.update({ "system.quantite": Math.max(0, Number(existante.system.quantite) + 1) })
} else {
await this.actor.createEmbeddedDocuments('Item', [{
name: "Eau", type: "nourritureboisson",
img: "systems/foundryvtt-reve-de-dragon/icons/objets/outre.webp",
system: { desaltere: 1, encombrement: 0.1, quantite: 1, cout: 0.05, boisson: true }
}], { renderSheet: false })
}
this.render(true)
})
this.html.find('.vue-detaillee').click(async event => {
this.options.vueDetaillee = !this.options.vueDetaillee
@@ -122,8 +200,29 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
}
itemActionEdit(event) {
const item = this.getItem(event);
return item?.sheet.render(true);
const item = this.getItem(event)
if (item) item.sheet.render(true)
}
/* -------------------------------------------- */
async _onVerifyIngredients(event) {
event.preventDefault()
const item = this.getItem(event)
if (!item || item.type !== ITEM_TYPES.recettealchimique) return
DialogVerifierIngredients.create(item, this.actor)
}
/* -------------------------------------------- */
async _onLancerRecette(event) {
event.preventDefault()
const item = this.getItem(event)
if (!item || item.type !== ITEM_TYPES.recettealchimique) return
const ingredients = Misc.safeJsonParse(item.system.ingredients, [])
if (!ingredients.length) {
ui.notifications.warn('Cette recette n\'a pas d\'ingrédients définis.')
return
}
DialogLancerRecette.create(item, this.actor)
}
_rechercherKeyup(event) {
@@ -180,15 +279,28 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
/* -------------------------------------------- */
async _onDropItem(event, dragData) {
const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id')
const previousItemIds = new Set(this.actor.items.keys())
const dropParams = await RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur)
if (dropParams) {
const callSuper = await this.actor.processDropItem(dropParams)
if (callSuper) {
await super._onDropItem(event, dragData)
}
// For external drops onto a container row, place the new item inside
if (destItemId && dropParams.sourceActorId !== this.actor.id) {
const container = this.actor.items.get(destItemId)
if (container?.isConteneur()) {
const dropped = [...this.actor.items].find(i => !previousItemIds.has(i.id))
if (dropped && !this.actor.findConteneur(dropped)) {
await this.actor.ajouterDansConteneur(dropped, container, () => {})
}
}
}
}
}
/* -------------------------------------------- */
async selectObjetTypeToCreate() {
let types = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type)));
@@ -197,18 +309,13 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
}
content += '</select>';
let d = new Dialog({
new foundry.applications.api.DialogV2({
title: "Créer un équipement",
content: content,
buttons: {
create: {
icon: '<i class="fas fa-check"></i>',
label: "Créer l'objet",
callback: () => this.actor.createItem($(".item-type").val())
}
}
});
d.render(true);
content,
buttons: [
{ action: "create", label: "Créer l'objet", icon: "fa-solid fa-check", callback: () => this.actor.createItem($(".item-type").val()) }
]
}).render({ force: true });
}
getTypesInventaire() {
@@ -237,7 +344,7 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
async _onSplitItem(item, split) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split);
const splitItem = foundry.utils.duplicate(item);
const splitItem = foundry.utils.deepClone(item);
splitItem.system.quantite = split;
await this.actor.createEmbeddedDocuments('Item', [splitItem])
}
+87 -1
View File
@@ -1 +1,87 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><defs><filter id="shadow-1" height="300%" width="300%" x="-100%" y="-100%"><feFlood flood-color="rgba(201, 201, 201, 1)" result="flood"></feFlood><feComposite in="flood" in2="SourceGraphic" operator="atop" result="composite"></feComposite>0<feOffset dx="230" dy="300" result="offset"></feOffset><feComposite in="SourceGraphic" in2="offset" operator="over"></feComposite></filter></defs><g class="" transform="translate(-100,0)" style=""><path d="m375.483 251.243-109.98 51.138.213 183.381L477.01 266.346l-86.993-21.81zm-12.736 108.626-5.947 14.699-48.604-8.955 5.007-12.832a141.306 141.306 0 0 0 13.51-11.358 167.184 167.184 0 0 0 16.566-17.517 170.478 170.478 0 0 0 12.606-17.958 115.607 115.607 0 0 0 9.514-17.97l14.068 2.51q-9.37 22.334-30.361 44.43-13.296 13.64-20.645 18.636zM121.603 244.334l-84.71 21.763L246.474 486V302.38l-109.946-51.137zm19.147 50.852a28.72 28.72 0 0 1 24.273 6.802 53.052 53.052 0 0 1 11.226 14.188l-13.081 2.676a28.542 28.542 0 0 0-5.388-7.374q-5.185-4.876-11.262-3.853l-.487.095a6.458 6.458 0 0 0-5.162 4.448c-.856 2.378-.238 5.554 1.796 9.371q4.08 7.6 10.81 9.027a23.785 23.785 0 0 0 8.563-.203l1.867-.344 5.791 10.822q-6.398 1.427-8.23 3.282-3.21 3.14.429 9.93a17.042 17.042 0 0 0 6.089 6.696 10.406 10.406 0 0 0 7.385 1.534l.416-.083q4.757-.964 5.079-4.757c.261-2.57-.655-5.744-2.748-9.514l12.38-2.545a49.247 49.247 0 0 1 4.103 11.226 19.956 19.956 0 0 1-.642 9.383 11.702 11.702 0 0 1-3.96 5.411 19.575 19.575 0 0 1-8.027 3.235l-1.19.214a27.971 27.971 0 0 1-17.494-2.7 32.193 32.193 0 0 1-14.128-14.092q-3.627-6.79-2.604-12.19a8.396 8.396 0 0 1 2.521-4.947h-.071q-1.844.31-7.04-2.497a32.11 32.11 0 0 1-12.916-13.593q-5.245-9.764-3.282-18.398 1.962-8.634 13.676-11zM27.19 248.865l108.78-116.309a7.135 7.135 0 0 1 1.427 0h.154q3.14.345 2.842 3.71a19.36 19.36 0 0 1-3.294 8.1 39.376 39.376 0 0 1-9.728 10.405q-3.912 2.938-15.044 9.514-12.796 7.505-19.55 14.77a92.535 92.535 0 0 0-11.513 14.486l32.907 3.758 8.182-12.963-20.967-2.378a36.415 36.415 0 0 1 4.757-3.83q2.379-1.605 8.444-5.125l6.422-3.747a92.975 92.975 0 0 0 12.903-8.776 61.472 61.472 0 0 0 12.51-14.414q6.84-10.846 6.494-17.957c-.19-3.949-2.105-6.434-5.684-7.505l79.798-85.161-102.097 179.576-5.708 10.06zm367.238-71.974q-3.817-5.458-3.758-8.515c0-2.033 1.19-3.199 3.568-3.448h.57a11.892 11.892 0 0 1 6.91 2.247 29.85 29.85 0 0 1 7.837 8.051q3.687 5.28 3.71 8.397c0 2.093-1.188 3.258-3.496 3.567h-.594a11.75 11.75 0 0 1-6.957-2.378 29.79 29.79 0 0 1-7.79-7.885zm-109.41-141.52 83.948 89.634h-1.189c-.38 0-.975 0-1.463.107q-7.825.892-8.324 6.862-.5 5.97 5.03 13.747a53.778 53.778 0 0 0 6.375 7.374 37.901 37.901 0 0 0 10.144 6.897q-2.117 2.89-.702 7.98a37.283 37.283 0 0 0 5.613 11.096 55.122 55.122 0 0 0 15.223 14.806q8.098 5.268 16.066 4.935.81 0 1.618-.13 8.776-.988 9.228-7.873a16.114 16.114 0 0 0-.463-4.853l58.689 62.686-91.572-22.941-6.1-10.703zm98.22 104.927 2.45 2.617c.451.57.903 1.189 1.355 1.784 1.808 2.592 2.723 4.757 2.723 6.529 0 1.771-1.034 2.782-3.127 3.02h-.512a10.346 10.346 0 0 1-6.077-1.95 22.596 22.596 0 0 1-6.184-6.137c-1.974-2.83-2.937-5.102-2.878-6.814.06-1.713 1.118-2.7 3.187-2.937h.524a10.263 10.263 0 0 1 6.005 1.879 19.147 19.147 0 0 1 2.533 2.01zM255.987 26 137.456 231.026l118.532 55.05 118.604-55.05zm-1.19 208.463q-17.529 0-24.58-12.273-7.053-12.273-7.053-34.988 0-22.714 7.052-35.047 7.052-12.332 24.582-12.344 17.53 0 24.582 12.332 7.052 12.333 7.052 35.047 0 22.715-7.052 34.988-7.053 12.273-24.582 12.285zm10.538-71.807q2.497 7.968 2.497 24.546 0 15.817-2.497 24.201-2.498 8.384-10.537 8.325-8.04 0-10.632-8.325-2.593-8.324-2.593-24.2 0-16.579 2.593-24.547t10.632-7.968q8.015-.012 10.513 7.956z" fill="#fff" fill-opacity="1" filter="url(#shadow-1)" transform="translate(128, 128) scale(0.5, 0.5) rotate(-30, 256, 256) skewX(0) skewY(0)"></path></g></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 649.20972 359.75745"
version="1.1"
id="svg6"
sodipodi:docname="_d100.svg"
width="649.20972"
height="359.75745"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2202"
inkscape:window-height="1379"
id="namedview8"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="1.4355469"
inkscape:cx="366.48667"
inkscape:cy="102.06012"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6">
<inkscape:grid
type="xygrid"
id="grid837"
originx="110.48667"
originy="-153.93988" />
</sodipodi:namedview>
<g
class=""
id="g4"
style="fill:#ffffff"
transform="translate(-94.621782,-91.536548)">
<path
d="m 375.483,251.243 -109.98,51.138 0.213,183.381 211.294,-219.416 -86.993,-21.81 z m -12.736,108.626 -5.947,14.699 -48.604,-8.955 5.007,-12.832 a 141.306,141.306 0 0 0 13.51,-11.358 167.184,167.184 0 0 0 16.566,-17.517 170.478,170.478 0 0 0 12.606,-17.958 115.607,115.607 0 0 0 9.514,-17.97 l 14.068,2.51 q -9.37,22.334 -30.361,44.43 -13.296,13.64 -20.645,18.636 z M 121.603,244.334 36.893,266.097 246.474,486 V 302.38 L 136.528,251.243 Z m 19.147,50.852 a 28.72,28.72 0 0 1 24.273,6.802 53.052,53.052 0 0 1 11.226,14.188 l -13.081,2.676 a 28.542,28.542 0 0 0 -5.388,-7.374 q -5.185,-4.876 -11.262,-3.853 l -0.487,0.095 a 6.458,6.458 0 0 0 -5.162,4.448 c -0.856,2.378 -0.238,5.554 1.796,9.371 q 4.08,7.6 10.81,9.027 a 23.785,23.785 0 0 0 8.563,-0.203 l 1.867,-0.344 5.791,10.822 q -6.398,1.427 -8.23,3.282 -3.21,3.14 0.429,9.93 a 17.042,17.042 0 0 0 6.089,6.696 10.406,10.406 0 0 0 7.385,1.534 l 0.416,-0.083 q 4.757,-0.964 5.079,-4.757 c 0.261,-2.57 -0.655,-5.744 -2.748,-9.514 l 12.38,-2.545 a 49.247,49.247 0 0 1 4.103,11.226 19.956,19.956 0 0 1 -0.642,9.383 11.702,11.702 0 0 1 -3.96,5.411 19.575,19.575 0 0 1 -8.027,3.235 l -1.19,0.214 a 27.971,27.971 0 0 1 -17.494,-2.7 32.193,32.193 0 0 1 -14.128,-14.092 q -3.627,-6.79 -2.604,-12.19 a 8.396,8.396 0 0 1 2.521,-4.947 h -0.071 q -1.844,0.31 -7.04,-2.497 a 32.11,32.11 0 0 1 -12.916,-13.593 q -5.245,-9.764 -3.282,-18.398 1.962,-8.634 13.676,-11 z M 27.19,248.865 135.97,132.556 a 7.135,7.135 0 0 1 1.427,0 h 0.154 q 3.14,0.345 2.842,3.71 a 19.36,19.36 0 0 1 -3.294,8.1 39.376,39.376 0 0 1 -9.728,10.405 q -3.912,2.938 -15.044,9.514 -12.796,7.505 -19.55,14.77 a 92.535,92.535 0 0 0 -11.513,14.486 l 32.907,3.758 8.182,-12.963 -20.967,-2.378 a 36.415,36.415 0 0 1 4.757,-3.83 q 2.379,-1.605 8.444,-5.125 l 6.422,-3.747 a 92.975,92.975 0 0 0 12.903,-8.776 61.472,61.472 0 0 0 12.51,-14.414 q 6.84,-10.846 6.494,-17.957 c -0.19,-3.949 -2.105,-6.434 -5.684,-7.505 l 79.798,-85.161 -102.097,179.576 -5.708,10.06 z m 367.238,-71.974 q -3.817,-5.458 -3.758,-8.515 c 0,-2.033 1.19,-3.199 3.568,-3.448 h 0.57 a 11.892,11.892 0 0 1 6.91,2.247 29.85,29.85 0 0 1 7.837,8.051 q 3.687,5.28 3.71,8.397 c 0,2.093 -1.188,3.258 -3.496,3.567 h -0.594 a 11.75,11.75 0 0 1 -6.957,-2.378 29.79,29.79 0 0 1 -7.79,-7.885 z m -109.41,-141.52 83.948,89.634 h -1.189 c -0.38,0 -0.975,0 -1.463,0.107 q -7.825,0.892 -8.324,6.862 -0.5,5.97 5.03,13.747 a 53.778,53.778 0 0 0 6.375,7.374 37.901,37.901 0 0 0 10.144,6.897 q -2.117,2.89 -0.702,7.98 a 37.283,37.283 0 0 0 5.613,11.096 55.122,55.122 0 0 0 15.223,14.806 q 8.098,5.268 16.066,4.935 0.81,0 1.618,-0.13 8.776,-0.988 9.228,-7.873 a 16.114,16.114 0 0 0 -0.463,-4.853 l 58.689,62.686 -91.572,-22.941 -6.1,-10.703 z m 98.22,104.927 2.45,2.617 c 0.451,0.57 0.903,1.189 1.355,1.784 1.808,2.592 2.723,4.757 2.723,6.529 0,1.771 -1.034,2.782 -3.127,3.02 h -0.512 a 10.346,10.346 0 0 1 -6.077,-1.95 22.596,22.596 0 0 1 -6.184,-6.137 c -1.974,-2.83 -2.937,-5.102 -2.878,-6.814 0.06,-1.713 1.118,-2.7 3.187,-2.937 h 0.524 a 10.263,10.263 0 0 1 6.005,1.879 19.147,19.147 0 0 1 2.533,2.01 z M 255.987,26 137.456,231.026 l 118.532,55.05 118.604,-55.05 z m -1.19,208.463 q -17.529,0 -24.58,-12.273 -7.053,-12.273 -7.053,-34.988 0,-22.714 7.052,-35.047 7.052,-12.332 24.582,-12.344 17.53,0 24.582,12.332 7.052,12.333 7.052,35.047 0,22.715 -7.052,34.988 -7.053,12.273 -24.582,12.285 z m 10.538,-71.807 q 2.497,7.968 2.497,24.546 0,15.817 -2.497,24.201 -2.498,8.384 -10.537,8.325 -8.04,0 -10.632,-8.325 -2.593,-8.324 -2.593,-24.2 0,-16.579 2.593,-24.547 2.593,-7.968 10.632,-7.968 8.015,-0.012 10.513,7.956 z"
fill="#ffffff"
fill-opacity="1"
transform="matrix(0.69282032,-0.4,0.4,0.69282032,-23.762003,181.038)"
id="path2"
style="fill:#ffffff" />
</g>
<g
class=""
id="g4-4"
style="fill:#ffffff"
transform="rotate(12.267903,709.7839,1245.6727)">
<path
d="m 375.483,251.243 -109.98,51.138 0.213,183.381 211.294,-219.416 -86.993,-21.81 z m -12.736,108.626 -5.947,14.699 -48.604,-8.955 5.007,-12.832 a 141.306,141.306 0 0 0 13.51,-11.358 167.184,167.184 0 0 0 16.566,-17.517 170.478,170.478 0 0 0 12.606,-17.958 115.607,115.607 0 0 0 9.514,-17.97 l 14.068,2.51 q -9.37,22.334 -30.361,44.43 -13.296,13.64 -20.645,18.636 z M 121.603,244.334 36.893,266.097 246.474,486 V 302.38 L 136.528,251.243 Z m 19.147,50.852 a 28.72,28.72 0 0 1 24.273,6.802 53.052,53.052 0 0 1 11.226,14.188 l -13.081,2.676 a 28.542,28.542 0 0 0 -5.388,-7.374 q -5.185,-4.876 -11.262,-3.853 l -0.487,0.095 a 6.458,6.458 0 0 0 -5.162,4.448 c -0.856,2.378 -0.238,5.554 1.796,9.371 q 4.08,7.6 10.81,9.027 a 23.785,23.785 0 0 0 8.563,-0.203 l 1.867,-0.344 5.791,10.822 q -6.398,1.427 -8.23,3.282 -3.21,3.14 0.429,9.93 a 17.042,17.042 0 0 0 6.089,6.696 10.406,10.406 0 0 0 7.385,1.534 l 0.416,-0.083 q 4.757,-0.964 5.079,-4.757 c 0.261,-2.57 -0.655,-5.744 -2.748,-9.514 l 12.38,-2.545 a 49.247,49.247 0 0 1 4.103,11.226 19.956,19.956 0 0 1 -0.642,9.383 11.702,11.702 0 0 1 -3.96,5.411 19.575,19.575 0 0 1 -8.027,3.235 l -1.19,0.214 a 27.971,27.971 0 0 1 -17.494,-2.7 32.193,32.193 0 0 1 -14.128,-14.092 q -3.627,-6.79 -2.604,-12.19 a 8.396,8.396 0 0 1 2.521,-4.947 h -0.071 q -1.844,0.31 -7.04,-2.497 a 32.11,32.11 0 0 1 -12.916,-13.593 q -5.245,-9.764 -3.282,-18.398 1.962,-8.634 13.676,-11 z M 27.19,248.865 135.97,132.556 a 7.135,7.135 0 0 1 1.427,0 h 0.154 q 3.14,0.345 2.842,3.71 a 19.36,19.36 0 0 1 -3.294,8.1 39.376,39.376 0 0 1 -9.728,10.405 q -3.912,2.938 -15.044,9.514 -12.796,7.505 -19.55,14.77 a 92.535,92.535 0 0 0 -11.513,14.486 l 32.907,3.758 8.182,-12.963 -20.967,-2.378 a 36.415,36.415 0 0 1 4.757,-3.83 q 2.379,-1.605 8.444,-5.125 l 6.422,-3.747 a 92.975,92.975 0 0 0 12.903,-8.776 61.472,61.472 0 0 0 12.51,-14.414 q 6.84,-10.846 6.494,-17.957 c -0.19,-3.949 -2.105,-6.434 -5.684,-7.505 l 79.798,-85.161 -102.097,179.576 -5.708,10.06 z m 367.238,-71.974 q -3.817,-5.458 -3.758,-8.515 c 0,-2.033 1.19,-3.199 3.568,-3.448 h 0.57 a 11.892,11.892 0 0 1 6.91,2.247 29.85,29.85 0 0 1 7.837,8.051 q 3.687,5.28 3.71,8.397 c 0,2.093 -1.188,3.258 -3.496,3.567 h -0.594 a 11.75,11.75 0 0 1 -6.957,-2.378 29.79,29.79 0 0 1 -7.79,-7.885 z m -109.41,-141.52 83.948,89.634 h -1.189 c -0.38,0 -0.975,0 -1.463,0.107 q -7.825,0.892 -8.324,6.862 -0.5,5.97 5.03,13.747 a 53.778,53.778 0 0 0 6.375,7.374 37.901,37.901 0 0 0 10.144,6.897 q -2.117,2.89 -0.702,7.98 a 37.283,37.283 0 0 0 5.613,11.096 55.122,55.122 0 0 0 15.223,14.806 q 8.098,5.268 16.066,4.935 0.81,0 1.618,-0.13 8.776,-0.988 9.228,-7.873 a 16.114,16.114 0 0 0 -0.463,-4.853 l 58.689,62.686 -91.572,-22.941 -6.1,-10.703 z m 98.22,104.927 2.45,2.617 c 0.451,0.57 0.903,1.189 1.355,1.784 1.808,2.592 2.723,4.757 2.723,6.529 0,1.771 -1.034,2.782 -3.127,3.02 h -0.512 a 10.346,10.346 0 0 1 -6.077,-1.95 22.596,22.596 0 0 1 -6.184,-6.137 c -1.974,-2.83 -2.937,-5.102 -2.878,-6.814 0.06,-1.713 1.118,-2.7 3.187,-2.937 h 0.524 a 10.263,10.263 0 0 1 6.005,1.879 19.147,19.147 0 0 1 2.533,2.01 z M 255.987,26 137.456,231.026 l 118.532,55.05 118.604,-55.05 z m -1.19,208.463 q -17.529,0 -24.58,-12.273 -7.053,-12.273 -7.053,-34.988 0,-22.714 7.052,-35.047 7.052,-12.332 24.582,-12.344 17.53,0 24.582,12.332 7.052,12.333 7.052,35.047 0,22.715 -7.052,34.988 -7.053,12.273 -24.582,12.285 z m 10.538,-71.807 q 2.497,7.968 2.497,24.546 0,15.817 -2.497,24.201 -2.498,8.384 -10.537,8.325 -8.04,0 -10.632,-8.325 -2.593,-8.324 -2.593,-24.2 0,-16.579 2.593,-24.547 2.593,-7.968 10.632,-7.968 8.015,-0.012 10.513,7.956 z"
fill="#ffffff"
fill-opacity="1"
transform="matrix(0.69282032,-0.4,0.4,0.69282032,-23.762003,181.038)"
id="path2-6"
style="fill:#ffffff" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.7 KiB

-449
View File
@@ -1,449 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512.07 512" style="enable-background:new 0 0 512.07 512;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{fill:#DCDCDC;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="icon_x5F_sidebar_x5F_chat" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M180,480.93c14-15.25,27.95-29.3,40.56-44.47c14.18-17.05,23.54-36.69,26.34-59.05
c1.66-13.29-0.67-25.98-5.04-38.48c-1.8-5.15-5.7-5.52-10.23-5.78c-18.92-1.08-37.99-1.21-56.71-3.83
c-40-5.59-76.63-19.99-107.18-47.16c-36.18-32.19-46.99-77.73-26.93-122.29c15.37-34.14,40.96-59.17,71.93-78.94
c47.68-30.44,100.22-45.65,156.55-49.23c41.61-2.64,81.81,2.91,120.81,17.42c26.15,9.73,48.71,24.87,66.74,46.2
c29.1,34.42,32.23,80.62,8.86,120.58c-23.61,40.37-58.93,67.06-100.58,86.28c-10.17,4.7-20.81,8.38-31.3,12.36
c-4.3,1.63-6.47,4.24-6.8,9.02c-2.04,29.43-14.23,54.78-32.77,77.05c-29.18,35.06-66,59.86-107.6,77.9
C184.67,479.39,182.56,480.01,180,480.93z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_rolltable">
<g>
<g>
<g>
<path class="st2" d="M255.1,55.46c6.7,2.37,12.64,3.53,17.63,6.38c47.83,27.36,95.49,55,143.19,82.58
c1.76,1.02,3.5,2.14,5.06,3.43c4.67,3.85,4.73,8.08-0.19,11.57c-4.48,3.18-9.3,5.9-14.07,8.66
c-43.81,25.34-87.68,50.58-131.43,76.01c-12.79,7.43-25.19,8.02-38.18,0.44c-47.26-27.53-94.66-54.81-141.95-82.29
c-11.67-6.78-11.5-10.86,0.17-17.61c45.93-26.57,91.78-53.27,137.82-79.64C240.07,61.03,247.84,58.57,255.1,55.46z
M256.6,177.07c8.18-2.74,15.83-4.76,23.02-7.85c6.75-2.9,11.12-8.42,11.32-16.12c0.2-7.86-4.55-13.18-10.98-16.36
c-16.34-8.07-32.92-8.99-48.94,0.93c-13.18,8.17-13.33,23.46,0.28,30.9C238.94,172.75,248.01,174.3,256.6,177.07z
M139.44,174.49c10.51,0.36,20.31-1.78,28.43-8.85c7.92-6.9,8.07-17.96,0.6-25.36c-13.09-12.97-44.39-13.07-57.62-0.19
c-8.94,8.7-8.15,19.73,2.02,27.08C120.8,172.91,129.82,174.83,139.44,174.49z M371.05,174.5c13.13,0.01,20.45-1.93,27.72-7.04
c11.22-7.88,11.04-21.8-0.38-29.44c-14.58-9.76-37.05-9.78-51.54-0.06c-11.6,7.78-11.75,21.98-0.23,29.88
C354.29,173.1,362.88,175.12,371.05,174.5z M257.2,200.1c-10.74-0.21-20.43,1.8-28.51,8.53c-9.63,8.02-9.2,19.91,0.7,27.6
c13.81,10.71,40.59,10.4,54.05-0.63c9.82-8.05,9.29-21.21-1.19-28.54C274.59,201.7,265.94,199.86,257.2,200.1z M255.77,105.95
c10.86-0.08,20.49-2.25,28.35-9.28c8.51-7.61,8.52-17.75,0.3-25.54c-13.52-12.81-43.78-12.59-57.1,0.4
c-7.45,7.27-7.44,17.61,0.19,24.78C235.62,103.93,245.78,105.61,255.77,105.95z"/>
</g>
<g>
<path class="st2" d="M73.56,270.29c-0.01-23.47-0.01-46.95,0-70.42c0-2.24-0.04-4.5,0.09-6.73c0.55-9.08,4.45-11.43,12.3-7.03
c14.77,8.29,29.43,16.78,44.1,25.25c31.29,18.06,62.49,36.27,93.87,54.16c13.59,7.75,19.9,19.03,19.84,34.61
c-0.18,47.56-0.07,95.12-0.07,142.68c0,1.02,0,2.04-0.03,3.06c-0.37,10.88-4.46,13.26-13.91,7.81
c-46.51-26.8-93.02-53.6-139.43-80.56c-11.08-6.44-16.76-16.38-16.77-29.35C73.56,319.28,73.57,294.79,73.56,270.29z
M238.89,301.12c-1.04-15.22-9.94-29.1-25.87-37.67c-12.78-6.88-25.53,0.97-25.17,15.07c0.45,18,8.76,32.2,24.15,41.47
C226.27,328.58,238.87,320.93,238.89,301.12z M238.88,424.25c-0.03-14.84-11.77-33.85-24.91-40.35
c-13.82-6.83-27.24,1.36-26.24,16.4c1.14,17.22,9.44,30.68,24.03,39.63C226.22,448.8,238.92,441.17,238.88,424.25z
M78.36,336.56c-0.07,16.35,12.18,35.46,26.64,41.57c13.6,5.74,24.53-1.52,24.14-16.28c-0.47-17.75-9.44-30.82-23.63-40.54
c-5.85-4.01-12.62-5.05-19.12-1.43C80,323.43,78.2,329.62,78.36,336.56z M78.16,216.83c1.81,17.43,9.33,31.66,25.03,40.21
c13.84,7.55,26.4-0.25,25.96-15.46c-0.51-17.56-9.43-30.51-23.26-40.31c-5.78-4.1-12.64-5.27-19.16-1.76
C80.09,203.09,78.12,209.49,78.16,216.83z"/>
</g>
<g>
<path class="st2" d="M438.48,269.36c0,23.88-0.09,47.77,0.04,71.65c0.08,14.95-5.66,26.05-19.04,33.69
c-45.56,26.01-90.87,52.43-136.3,78.66c-1.93,1.11-4.02,2.03-6.14,2.72c-4.13,1.36-6.9-0.45-7.9-4.42
c-0.69-2.73-0.78-5.65-0.78-8.49c-0.04-48.18,0.04-96.35-0.07-144.53c-0.03-14.73,6.49-25.32,19.04-32.56
c44.18-25.53,88.36-51.07,132.54-76.6c1.24-0.71,2.5-1.39,3.75-2.08c11.32-6.2,14.8-4.14,14.84,9.08
C438.53,220.78,438.48,245.07,438.48,269.36z M273.14,421.22c0.05,19.9,12.39,27.34,26.79,18.9
c14.92-8.75,23.03-22.32,24.24-39.46c1.09-15.44-12.22-24.3-25.6-16.81C282.99,392.57,274.73,406.59,273.14,421.22z
M273.19,300.58c-0.25,19.57,10.43,26.62,25.43,19.95c14.02-6.23,26.59-26.94,25.75-42.41c-0.77-14.26-13.04-21.55-25.73-14.51
C283.1,272.22,275.12,286.19,273.19,300.58z M378.55,373.28c0.05-21.14-11.77-28.95-25.77-20.61
c-15.26,9.09-24.61,22.51-24.5,41.07c0.1,15.52,11.79,22.77,25.39,15.25C369.25,400.38,377.63,386.78,378.55,373.28z
M433.65,340.47c0.1-20.18-12.26-27.99-26.62-19.24c-14.51,8.85-23.33,22.09-24,39.66c-0.62,16.14,11.34,23.92,25.59,16.37
C424.57,368.82,431.83,354.54,433.65,340.47z M378.56,249.19c0.11-16.72-10.87-24.46-24.88-17.53
c-15.12,7.48-26.59,27.54-25.35,44.37c0.88,11.94,10.06,18.07,21.51,14.37C365.3,285.38,378.44,266.54,378.56,249.19z
M433.67,217.08c0.11-15.23-9.9-22.9-23.27-17.86c-16.2,6.12-29.92,29.74-27.12,46.71c1.73,10.53,10.4,15.95,20.67,12.93
C419.6,254.24,433.54,234.65,433.67,217.08z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_actor" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M194.72,240.85c-18.71-10.84-37.43-21.65-56.1-32.56c-4.38-2.56-3.72-6.78-3.09-10.93
c4.53-29.87,16.49-56.68,33.54-81.37c22.53-32.64,51.22-59.09,83.04-82.38c1.94-1.42,4.08-2.55,6.44-4.01
c2.95,1.91,5.76,3.52,8.35,5.44c34.2,25.36,64.61,54.39,87.21,90.87c13.92,22.47,23.34,46.63,27.11,72.93
c0.74,5.19-0.6,8.42-5.19,11.05c-17.12,9.83-34.08,19.93-51.1,29.92c-0.35-0.42-0.7-0.84-1.06-1.26
c7.2-7.59,13.9-15.74,21.74-22.61c6.97-6.11,8.08-12.73,6.54-21.27c-5.03-27.96-18.41-51.68-36.13-73.32
c-14.99-18.3-32.86-33.43-51.91-47.27c-3.26-2.37-6.29-3.56-10-0.89c-28.94,20.8-54.74,44.63-72.73,75.88
c-9.25,16.07-15.58,33.21-17.65,51.81c-0.5,4.49,0.65,7.78,3.76,10.99c9.23,9.52,18.23,19.25,27.32,28.9L194.72,240.85z"/>
</g>
<g>
<path class="st2" d="M168.55,345.65c-12.76,3.01-23.81-2.22-35.94-5.83c-3.63,12.02-1.15,22.71,4.28,33.16
c-0.52,0.49-1.04,0.98-1.56,1.47c-7.28-3.95-14.57-7.89-22.66-12.28c-0.94,40.71,5.85,79.96,12.76,120.22
c-9.73,0-18.21,0-28.31,0c0-4.71-0.17-8.65,0.03-12.57c2.77-54.5,0.73-108.5-16.69-160.88c-1.7-5.12-1.02-8.86,2.98-12.56
c15.25-14.13,30.3-28.49,45.51-42.67c1.86-1.73,4.21-2.92,7.2-4.95c12.66,31.79,36.38,51.55,65.92,65.71
c-23.56,4.18-43.99-5.23-64.98-14.12C142.45,319.03,153.45,333.5,168.55,345.65z"/>
</g>
<g>
<path class="st2" d="M378.56,342.15c-11.2,1.29-21.2,6.91-34.38,4.02c17.38-13.12,29.62-28.02,35.34-49.86
c-22.86,11.18-44.29,22.27-69.86,17.87c29.22-14.58,53.47-34,65.19-66.51c3.09,2.11,5.44,3.31,7.29,5.04
c15.49,14.48,30.83,29.13,46.36,43.57c3.94,3.66,4.92,7.36,3.13,12.52c-12.8,37.05-17.33,75.43-17.57,114.4
c-0.11,17.53,0.54,35.07,0.78,52.6c0.02,1.77-0.35,3.55-0.66,6.4c-8.97,0-17.6,0-27.36,0c6.32-39.97,13.54-79.18,12.38-120.61
c-8.84,4.81-16.27,8.85-23.71,12.89c-0.49-0.48-0.97-0.96-1.46-1.44C378.33,363.41,381.6,353.68,378.56,342.15z"/>
</g>
<g>
<path class="st2" d="M207.81,179.57c3.71-5.83,8.78-8.93,15.2-8.75c5.91,0.17,10.65,3.14,13.82,8.68
c-3.37,5.93-8.7,7.74-14.45,7.81C216.53,187.39,211.48,185.04,207.81,179.57z"/>
</g>
<g>
<path class="st2" d="M277.66,179.72c3.23-6.12,7.85-9.04,14-9c6.15,0.04,10.67,3.08,13.58,8.58c-2.43,6.15-7.58,7.55-12.87,7.82
C286.5,187.42,281.29,185.46,277.66,179.72z"/>
</g>
<g>
<path class="st2" d="M194.81,240.77c0,0-0.08,0.08-0.08,0.08C194.72,240.85,194.81,240.77,194.81,240.77z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_scene" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M141.31,362.45c10.55-10.81,21.11-21.61,32.39-33.17c-4.23-4.4-7.78-8.52-11.78-12.13
c-4.39-3.96-5.23-7.87-1.64-12.78c2.36-3.24,4.31-6.78,7.52-11.92c29.68,29.65,58.51,58.45,88.28,88.2
c29.63-29.58,58.38-58.28,88.43-88.27c3.76,6.48,7.17,11.44,9.48,16.88c0.68,1.6-1.26,4.92-2.82,6.75
c-3.78,4.43-8.04,8.45-12.61,13.15c3.87,4.06,7.01,7.46,10.26,10.75c6.02,6.1,12.2,12.04,18.09,18.27
c1.5,1.58,2.14,3.98,2.19,6.78c-11.12-2.35-15.32-13.36-25.7-18.87c-4.53,5.37-9.27,11-14.4,17.08
c4.03,8.46,15.77,12.55,18.84,22.89c-0.64,0.7-1.28,1.4-1.92,2.1c-2.18-1.32-4.7-2.29-6.49-4.01
c-7.5-7.21-14.75-14.68-22.17-21.99c-1.69-1.67-3.67-3.05-6.41-5.3c-5.41,5.88-10.51,11.42-16,17.4
c1.57,1.94,2.93,3.92,4.6,5.61c7.3,7.42,14.75,14.69,22,22.16c1.66,1.71,2.69,4.01,3.13,6.87
c-10.84-2.35-15.01-13.32-25.2-18.68c-4.93,5.38-10.02,10.94-15.43,16.85c4.67,9.02,15.38,13.49,19.26,23.07
c-0.54,0.67-1.09,1.34-1.63,2.01c-2.14-1.31-4.59-2.29-6.35-3.98c-7.49-7.22-14.75-14.69-22.17-21.99
c-1.69-1.66-3.68-3.01-5.89-4.79c-3.8,3-7.23,5.71-11.03,8.71c-3.77-2.97-7.19-5.68-11.01-8.69c-2.19,1.75-4.19,3.08-5.87,4.74
c-7.42,7.3-14.69,14.75-22.16,22c-1.73,1.67-4.02,2.76-6.91,3.23c2.31-10.77,13.12-15.02,18.63-25.24
c-5.42-4.76-11.09-9.74-17.21-15.11c-8.81,4.1-12.9,15.32-22.79,18.83c-0.62-0.47-1.25-0.95-1.87-1.42
c1.25-2.13,2.15-4.6,3.81-6.33c7.21-7.5,14.68-14.75,21.99-22.17c1.67-1.7,3.05-3.67,5.27-6.37
c-5.69-5.59-11.06-10.87-16.79-16.51c-2.48,2-4.47,3.36-6.16,5.02c-7.42,7.3-14.69,14.75-22.16,22c-1.71,1.66-4,2.72-6.87,3.19
c2.16-10.9,13.44-14.89,18.41-25.47c-5.23-4.81-10.76-9.89-16.39-15.06c-9.69,4.24-13.75,16.43-24.15,19.15
C143.03,364.74,142.17,363.6,141.31,362.45z"/>
</g>
<g>
<path class="st2" d="M441,403.48c-16.69-27.59-33.44-55.13-50.04-82.77c-42.46-70.68-84.85-141.39-127.26-212.1
c-1.34-2.23-2.47-4.58-4.3-8.02c13.34-3.15,24.63-8.77,32.97-20.46c1.71,2.53,2.89,3.85,3.6,5.4
c28.28,61.55,56.51,123.12,84.77,184.68c19.15,41.72,38.37,83.41,57.51,125.14c1.18,2.58,1.92,5.36,2.86,8.04L441,403.48z"/>
</g>
<g>
<path class="st2" d="M217.61,82.38c2.39,3.13,3.85,4.73,4.95,6.53c4.59,7.48,8.69,15.3,13.71,22.47
c4.35,6.21,4.12,11.18,0.16,17.73c-47.28,78.28-94.26,156.74-141.31,235.16c-6.51,10.85-13.01,21.71-19.54,32.55
c-1.13,1.88-2.39,3.68-4.72,4.92C119.57,295.76,168.27,189.77,217.61,82.38z"/>
</g>
<g>
<path class="st2" d="M477.25,255.92c-10.87-10.64-21.54-21.09-32.91-32.23c-5.58,5.75-10.68,11.01-16.24,16.75
c1.84,2.26,3.31,4.39,5.1,6.21c7.43,7.56,15,15,22.43,22.56c2.12,2.16,4.52,4.52-0.17,8.58c-7.22-6.76-14.48-13.55-21.88-20.47
c-6.08,5.51-11.66,10.57-17.97,16.3c7.88,8.42,14.65,15.65,21.42,22.88c-0.62,0.85-1.25,1.7-1.87,2.56
c-2.14-1.03-4.53-1.72-6.36-3.13c-13.8-10.59-21.18-25.52-27.46-41.16c-5.78-14.38-8.33-11.03,4.45-23.75
c7.23-7.19,14.4-14.44,21.65-21.61c1.71-1.69,3.62-3.17,5.84-5.08c1.73,1.12,3.41,1.86,4.63,3.06
c13.32,13.21,26.59,26.48,39.81,39.79C479.85,249.34,482.22,251.73,477.25,255.92z"/>
</g>
<g>
<path class="st2" d="M68.55,223.56c-12.92,10.59-22.16,23.11-34.32,32.22c-0.78-0.53-1.57-1.06-2.35-1.59
c0.43-1.85,0.25-4.3,1.39-5.46c14.33-14.51,28.84-28.83,43.34-43.18c0.39-0.38,1.12-0.42,1.97-0.71
c0.75,0.34,1.86,0.54,2.53,1.2c10.88,10.75,21.84,21.43,32.39,32.51c1.47,1.54,1.83,5.55,0.94,7.69
c-4.29,10.36-8.17,21.11-14.15,30.47c-5.16,8.08-12.9,14.53-19.62,21.58c-0.65,0.69-2.18,0.54-5.2,1.2
c3.65-11.71,15.03-15.79,20.22-26.77c-5.23-4.62-10.83-9.57-16.64-14.7c-9.41,4.67-13.78,15.49-23.35,19.4
c-0.67-0.54-1.35-1.07-2.02-1.61c1.11-1.99,1.87-4.32,3.4-5.91c7.07-7.35,14.38-14.47,21.55-21.72c1.84-1.86,3.48-3.92,6.4-7.23
C79.61,235.25,74.35,229.69,68.55,223.56z"/>
</g>
<g>
<path class="st2" d="M256.05,428.1c7.93,7.53,16.37,15.55,24.7,23.47c-8.21,8.27-16.4,16.51-24.37,24.54
c-8.23-7.98-16.67-16.16-25.11-24.34C239.8,443.62,248.21,435.58,256.05,428.1z"/>
</g>
<g>
<path class="st2" d="M254.88,73.27c6.48-5.93,12.68-11.6,18.52-16.94C275.4,65.47,265.2,75.93,254.88,73.27z"/>
</g>
<g>
<path class="st2" d="M238.87,49.47c0.54-7.99,6.12-13.62,15.88-13.57c-4.81,4.98-9.61,9.96-14.42,14.93
C239.84,50.38,239.35,49.92,238.87,49.47z"/>
</g>
<g>
<polygon class="st2" points="441.11,403.38 441.22,403.67 441,403.48 "/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_item" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M86.57,379.95c0-48.58,0-96.33,0-143.79c5.64-2.82,112.01-3.19,119.52-0.33c0.25,2.68,0.79,5.83,0.8,8.98
c0.07,26.94,0.01,53.88,0.08,80.83c0.01,3.17,0.51,6.33,0.85,10.3c32.36,0,63.92,0,97.01,0c0-33.87,0-66.95,0-99.19
c6.41-3.36,112.58-3.86,119.48-1.35c2.55,5.28,2.8,137.43-0.09,144.56C312.19,379.95,199.8,379.95,86.57,379.95z"/>
</g>
<g>
<path class="st2" d="M351.95,96.52c0,37.52,0,74.24,0,111.87c-15.41,0-30.07,0-45.61,0c-0.81-5.04-1.56-9.72-2.59-16.15
c-31.78-0.12-63.35-0.24-95.41,0.16c-1.01,5.85-1.81,10.52-2.76,16c-15.49,0-30.54,0-46.27,0c-0.48-3.17-1.18-5.7-1.19-8.24
c-0.08-31.43-0.09-62.85-0.03-94.28c0.02-8.73,1.64-10.33,10.48-10.33c58.36-0.05,116.72-0.03,175.09,0.01
C346.04,95.56,348.42,96.09,351.95,96.52z"/>
</g>
<g>
<path class="st2" d="M132.51,208.42c-9.52,0-18.03,0-27.47,0c0-37.52,0-74.16,0-111.86c9.22,0,17.87,0,27.47,0
C132.51,133.9,132.51,170.54,132.51,208.42z"/>
</g>
<g>
<path class="st2" d="M378.57,96.39c10.31,0,18.82,0,29.12,0c0.27,37.43,0.14,74.07,0.08,111.82c-10.01,0-18.66,0-29.13,0
C378.39,170.99,378.51,134.35,378.57,96.39z"/>
</g>
<g>
<path class="st2" d="M107.03,407.31c99.7,0,198.42,0,297.14,0c0.31,0.74,0.62,1.47,0.93,2.21c-3.8,2.18-7.48,4.61-11.44,6.42
c-1.72,0.78-4.02,0.36-6.06,0.36c-87.72,0.01-175.44-0.01-263.17,0.06C117.35,416.37,111.13,415.25,107.03,407.31z"/>
</g>
<g>
<path class="st2" d="M280.03,311.38c-16.62,0-31.68,0-47.61,0c0-31.35,0-61.94,0-93.7c15.6-1.68,30.82-0.85,47.53-0.45
C280.76,248.97,280.56,279.53,280.03,311.38z M267.36,293.14c0.39-3.77,0.85-6.35,0.89-8.94c0.12-7.13-0.2-14.28,0.21-21.39
c0.17-2.85,1.14-6.13,2.88-8.31c8.15-10.27,8.56-19.5,0.67-27.25c-8.45-8.3-21.51-8.87-30.61-1.33
c-8.41,6.98-10.24,17.21-3.09,25.35c4.73,5.38,5.6,10.91,5.4,17.36c-0.17,5.7-0.14,11.42,0.05,17.12
c0.08,2.32,0.82,4.63,1.34,7.39C252.64,293.14,259.56,293.14,267.36,293.14z"/>
</g>
<g>
<path class="st2" d="M459.64,208.46c-9.05,0-17.17,0-26.05,0c-0.44-3.46-1.09-6.2-1.09-8.93c-0.07-31.16-0.05-62.33-0.04-93.49
c0-1.22,0.07-2.44,0.15-3.66c0.3-4.41,2.7-6.57,7.1-6.7c4.5-0.13,6.66,2.09,7.24,6.46c4.34,32.91,8.76,65.81,13.07,98.73
C460.3,202.98,459.83,205.2,459.64,208.46z"/>
</g>
<g>
<path class="st2" d="M77.56,97.23c0,36.74,0,73.41,0,111.08c-8.48,0-16.35,0-25.02,0c-0.25-2.71-0.9-5.08-0.6-7.34
c4.21-32.52,8.49-65.04,12.9-97.53C65.84,96.02,68.83,94.5,77.56,97.23z"/>
</g>
<g>
<path class="st2" d="M451.71,362.72c0-42.84,0-84.74,0-127.72c3.45-0.21,6.42-0.39,10.08-0.61c0.46,3.5,1.09,6.04,1.1,8.58
c0.06,34.46-0.08,68.92,0.12,103.38C463.06,354.24,458.99,358.62,451.71,362.72z"/>
</g>
<g>
<path class="st2" d="M50.26,234.87c2.86,0,5.32,0,7.56,0c2.47,5.02,3.24,118.46,0.9,126.79c-5.37-3.13-9.67-6.58-9.66-13.41
c0.02-35.65-0.01-71.31,0.05-106.96C49.12,239.34,49.79,237.4,50.26,234.87z"/>
</g>
<g>
<path class="st2" d="M51.56,390.71c7.99,7.72,15.99,15.44,25.01,24.15c-9.12,2.16-16.82,2.02-24.49,0.42
c-1.03-0.21-2.41-2.03-2.45-3.14c-0.23-6.78-0.11-13.57-0.11-20.36C50.2,391.43,50.88,391.07,51.56,390.71z"/>
</g>
<g>
<path class="st2" d="M436.46,413.79c8.05-7.65,16.1-15.3,24.15-22.95c0.61,0.34,1.23,0.69,1.84,1.03
c0,6.76,0.19,13.52-0.17,20.26c-0.07,1.29-2.24,3.46-3.53,3.53c-7.16,0.35-14.35,0.17-21.53,0.17
C436.96,415.15,436.71,414.47,436.46,413.79z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_fight" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M98.54,121.71c7.19,0.33,14.38,0.67,22.81,1.06c1.18-7.93,2.28-15.34,3.38-22.75
c0.65-0.23,1.3-0.46,1.95-0.69c70.17,84.04,140.34,168.07,211.57,253.38c-9.84,8.24-18.85,15.78-28.82,24.13
C238.18,291.6,167.84,207.47,97.5,123.34C97.85,122.8,98.2,122.26,98.54,121.71z"/>
</g>
<g>
<path class="st2" d="M74.25,462.04c-10.75-7.58-20.15-14.21-30.69-21.64C87.39,378.65,130.68,317.64,175,255.19
c8.95,10.7,16.69,19.95,24.95,29.82C158.02,344.06,116.54,402.48,74.25,462.04z"/>
</g>
<g>
<path class="st2" d="M425.22,103.01c0.37,2.17,1.08,4.12,0.96,6.02c-1.52,23.89-10.41,44.55-26.71,62.21
c-17.85,19.34-40.04,31.93-63.81,42.21c-1.98,0.86-4.11,1.36-7.64,2.49c1.24-4.12,1.91-6.97,2.94-9.69
c6.52-17.26,11.93-34.75,11.33-53.5c-0.09-2.84-0.01-5.86-0.93-8.47c-2.37-6.7,0.06-11.13,5.24-15.36
c8.52-6.96,16.52-14.54,24.94-21.63c1.91-1.61,4.59-3.05,6.99-3.2c14.23-0.85,28.48-1.32,42.72-1.86
C422.24,102.2,423.23,102.61,425.22,103.01z"/>
</g>
<g>
<path class="st2" d="M291.85,453.14c-4.87-5.91-8.93-10.84-14.08-17.09c41.71-34.89,82.71-69.18,124.58-104.2
c4.79,5.78,8.96,10.8,14.01,16.89C374.53,383.82,333.55,418.17,291.85,453.14z"/>
</g>
<g>
<path class="st2" d="M273.79,115.61c10.76,7.57,20.25,14.24,30.73,21.61c-17.52,24.77-34.23,48.41-51.86,73.34
c-8.76-10.27-16.69-19.55-25.21-29.54C242.84,159.29,257.83,138.14,273.79,115.61z"/>
</g>
<g>
<path class="st2" d="M310.02,250.99c3.13-1.7,6.08-3.97,9.41-5.02c21.89-6.92,42.92-15.68,62.36-28.02
c29.04-18.43,51.93-42.06,63.17-75.38c4.67-13.85,6.52-28.16,6.18-42.77c-0.05-2.01-0.01-4.02-0.01-6.78
c3.9-2.17,7.86-4.37,12.69-7.05c1.31,3.33,2.56,5.61,3.12,8.05c3.1,13.52,1.31,26.78-2.57,39.85
c-16.18,54.48-81.45,113.08-140.32,120.1c-4.27,0.51-8.65,0.07-12.98,0.07C310.71,253.03,310.37,252.01,310.02,250.99z"/>
</g>
<g>
<path class="st2" d="M389.79,472.78c-11.28-13.51-21.9-26.23-33.01-39.54c8.13-9.93,17.68-16.81,28.3-24.44
c11.08,13.21,21.71,25.89,33.02,39.37C409.83,457.64,400.05,464.37,389.79,472.78z"/>
</g>
<g>
<path class="st2" d="M321.15,118.13c-11.98-8.39-23.18-16.22-35.16-24.61c4.46-12.23,8.63-23.66,13.37-36.67
c17.45,12.36,33.25,23.54,50.46,35.73C339.82,101.49,330.87,109.47,321.15,118.13z"/>
</g>
<g>
<path class="st2" d="M98.58,95.77c-7.12-0.81-13.28-1.35-19.35-2.36c-1.23-0.2-2.8-2.02-3.15-3.37
c-2.23-8.67-4.18-17.41-6.14-26.14c-0.15-0.68,0.35-1.51,0.74-2.98c1.89,0.47,3.64,0.68,5.2,1.33
c6.2,2.59,12.29,5.47,18.53,7.94c4.9,1.94,7.04,5.25,6.33,10.43C100.13,85.01,99.49,89.39,98.58,95.77z"/>
</g>
<g>
<path class="st2" d="M263.6,72.75c-4.58-8.72-9.17-17.44-14.34-27.29c9.64-1.5,17.2,0.6,26.32,3.04
c-3.26,8.72-6.26,16.73-9.26,24.75C265.41,73.08,264.5,72.92,263.6,72.75z"/>
</g>
<g>
<path class="st2" d="M328.1,39.22c10.42,7.7,21.69,12.69,29.96,23.17C349.73,64.21,326.41,46.59,328.1,39.22z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_compendium" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M172.73,49.37c21.98,0,43.98,0,66.87,0c0,137.52,0,274.28,0,412.73c-22.56,0.64-44.71,0.55-66.23,0.05
C170.22,455.66,169.78,57.56,172.73,49.37z M200.52,429.88c3.18-7.29,2.79-312.57-0.29-318.12c-6.66,0-13.58,0-20.13,0
c-3.18,7.31-2.79,312.56,0.29,318.12C187.06,429.88,193.98,429.88,200.52,429.88z M210.72,299.22
c-3.15,7.38-2.74,125.16,0.33,130.65c6.67,0,13.59,0,21.35,0c0-43.84,0-86.81,0-130.65
C224.64,299.22,217.72,299.22,210.72,299.22z"/>
</g>
<g>
<path class="st2" d="M145.38,142.76c0,85.62,0,170.31,0,256.67c-17.42,1.03-34.25,0.66-51.8,0.12
c-0.49-3.88-1.14-6.62-1.14-9.36c-0.05-79.17-0.06-158.34-0.03-237.52c0-9.54,1.47-10.94,11.07-11
c11.02-0.07,22.04-0.07,33.06,0.03C139.11,141.74,141.67,142.3,145.38,142.76z"/>
</g>
<g>
<path class="st2" d="M363.52,456.03c-12.7,2.35-23.74,4.39-35.68,6.6c-1.26-4.11-2.57-7.24-3.16-10.5
c-10.85-60.07-21.6-120.15-32.38-180.23c-7.75-43.2-15.53-86.4-23.26-129.6c-0.49-2.72-0.59-5.51-1-9.55
c12.13-2.2,23.57-4.27,36.31-6.58C324.11,236.33,343.65,345.24,363.52,456.03z"/>
</g>
<g>
<path class="st2" d="M30.77,95.93c12.29,0,23.52,0,35.63,0c0.49,3.12,1.29,5.83,1.29,8.53c0.07,53.47,0.07,106.95,0.02,160.42
c0,2.37-0.57,4.75-0.98,8c-11.97,0-23.53,0-35.96,0C30.77,213.88,30.77,155.54,30.77,95.93z"/>
</g>
<g>
<path class="st2" d="M367.58,238.23c7-3.03,12.81-5.54,20.08-8.69c31.66,74.22,62.88,147.39,94.52,221.55
c-7.17,3.14-12.98,5.68-20.06,8.77C430.48,385.69,399.26,312.48,367.58,238.23z"/>
</g>
<g>
<path class="st2" d="M65.98,461.62c-11.43,0-22.81,0-35.96,0c-0.23-38.48-0.1-76.1-0.08-114.56c13.02,0,24.42,0,35.56,0
C68.27,352.44,68.8,453.4,65.98,461.62z"/>
</g>
<g>
<path class="st2" d="M145.31,461.62c-17.64,0-34.34,0-51.98,0c0-12.22,0-23.59,0-34.65c5.83-2.99,44.82-3.3,51.98-0.36
C145.31,437.66,145.31,449.07,145.31,461.62z"/>
</g>
<g>
<path class="st2" d="M66.94,299.04c0,7.68,0,14,0,20c-5.68,3.23-28.48,3.6-36.48,0.32c0-5.15-0.23-10.92,0.17-16.64
c0.09-1.3,2.32-3.48,3.61-3.52C44.72,298.91,55.21,299.04,66.94,299.04z"/>
</g>
<g>
<path class="st2" d="M344.77,183.51c1.37-6.24,13.25-11.41,18.86-8.56C361.93,179.91,351.56,184.78,344.77,183.51z"/>
</g>
<g>
<path class="st2" d="M376.69,203.79c-1.47,1.58-2.66,3.99-4.46,4.57c-4.85,1.58-9.26,6.71-16.33,2.77
c5.69-6.11,12.27-7.7,18.8-9.41C375.37,202.41,376.03,203.1,376.69,203.79z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_settings" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M167.35,468.66c-13.39-1.77-50.61-24-55.69-33.14c1.08-1.73,2.27-3.8,3.62-5.75
c9.08-13.11,15.46-27.19,17.17-43.32c2.08-19.66-8.6-38.21-26.93-45.65c-18.45-7.49-36.8-5.28-55.13,0.52
c-2.27,0.72-4.61,1.24-7.95,2.13c-8.74-20.07-13.97-40.42-16.04-62.21c3.72-1,6.27-1.51,8.71-2.36
c10.15-3.55,20.93-5.98,30.28-11.03c32.02-17.29,37.2-51.45,11.57-77.58c-7.69-7.84-18.02-13.11-27.21-19.46
c-1.8-1.24-3.88-2.08-6.88-3.65c7.46-20.81,19.04-38.63,32.65-56.07c2.6,1.58,4.49,2.63,6.28,3.83
c12.84,8.66,26.44,15.16,42.16,16.87c27.62,3.01,49.81-16.05,50.75-43.89c0.44-12.98-0.7-25.69-5.26-37.95
c-0.57-1.52-0.94-3.13-1.27-4.72c-0.16-0.77-0.03-1.6-0.03-3.56c19.48-9.06,40.19-13.46,62.14-15.74
c1.02,3.75,1.82,6.21,2.34,8.72c3.47,16.64,9.06,32.26,21.51,44.52c15.73,15.49,38.24,17.59,56.71,5.52
c12.09-7.9,21.07-18.51,27.72-31.22c1.77-3.4,3.56-6.79,5.82-11.11c21.09,7.8,39.67,18.42,56.8,32.93
c-1.64,2.8-2.68,4.95-4.05,6.86C388.21,94.64,382,108.15,380,123.56c-3.04,23.55,11.24,44.26,34.61,49.71
c15.81,3.69,31.2,1.62,46.42-3.22c2.48-0.79,5-1.42,8.46-2.39c8.98,19.98,13.9,40.42,16.18,62.37c-3.8,0.94-6.46,1.76-9.18,2.25
c-16.65,3.01-31.7,9.36-43.86,21.42c-17.55,17.41-17.87,44.76-1.08,62.94c9.09,9.85,19.19,18.29,31.47,23.91
c1.97,0.9,3.73,2.29,6.35,3.94c-7.98,20.35-18.77,38.4-32.84,55.12c-3.06-1.75-5.24-2.79-7.18-4.15
c-11.9-8.34-24.87-13.72-39.36-15.81c-25.9-3.73-48.07,12.39-52.41,38.17c-2.51,14.96-0.26,29.24,4.49,43.36
c0.89,2.64,1.57,5.34,2.63,8.96c-20.39,9.22-41.13,13.92-63.52,15.93c-1.27-5.66-2.36-10.56-3.47-15.47
c-2.68-11.93-7.48-22.97-15.18-32.45c-19.22-23.66-48.23-25.35-70.63-3.31c-8,7.87-13.67,18.12-20.35,27.33
C170.02,464.25,168.74,466.5,167.35,468.66z M255.86,400.9c76.17,1.14,145.09-60.6,145.17-144.58
c0.07-81.43-64.18-146.3-147.02-145.43c-80.82,0.84-143.17,67.24-143.11,145.2C110.95,336.29,175.57,400.89,255.86,400.9z"/>
</g>
<g>
<path class="st2" d="M255.9,375.07c-66.32-0.01-119.05-52.79-119.18-119.01c-0.12-60.41,46.51-119.03,119.17-119.37
c66.88-0.31,119,51.98,119.5,119.66C375.87,322.28,322.28,375.08,255.9,375.07z M256.32,367.82
c61.81,0.01,112.28-50.05,111.82-111.65c-0.45-60.76-47.78-111.81-111.76-112.13c-63.11-0.31-112.37,51.07-112.41,112.06
C143.95,318.19,193.87,367.82,256.32,367.82z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_journal" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M448.42,92.12c-17.01,7.17-36.38,3.32-52.81,13.34c13.35,7.59,25.04,14.25,36.73,20.9
c-0.07,0.7-0.15,1.39-0.22,2.09c-10.32,2.08-20.63,4.16-30.95,6.23c-0.13,0.63-0.27,1.25-0.4,1.88
c14.07,8.7,28.14,17.4,42.66,26.38c-0.79,3.42-1.29,6.39-2.17,9.24c-9.51,30.75-25.84,57.54-47.17,81.49
c-28.41,31.88-43.98,69.29-47.66,111.76c-0.21,2.39-0.8,4.75-1.37,8.08c-3.69,0.38-7.21,1.06-10.74,1.07
c-52.87,0.07-105.74-0.15-158.6,0.15c-23.87,0.13-41.44,11.18-51.15,33.28c-13.04,29.65,8.96,66.89,45.53,62.06
c6.73-0.89,13.59-0.76,20.39-1.1c0.18,0.69,0.36,1.39,0.54,2.08c-1.95,1.11-3.78,2.8-5.87,3.23
c-13.93,2.87-27.83,6.21-41.92,7.89c-9.63,1.15-19.71,0.93-29.3-0.54c-25.73-3.96-39.5-20.96-46.09-44.94
c-7.68-27.98-4.86-55.9,1.11-83.65c2.48-11.54,6.41-22.77,9.52-34.19c1.48-5.44,4.92-7.99,10.38-8.84
c14.32-2.22,28.6-4.7,42.88-7.15c2.31-0.4,4.55-1.17,8.35-2.18c-12.43-12.92-23.92-24.85-35.68-37.07
c10.82-18.72,21.31-36.6,31.53-54.63c10.13-17.88,18.72-36.44,25.46-57.28c-4.1-0.52-6.79-1.1-9.48-1.17
c-19.98-0.48-39.99-0.43-59.95-1.38c-24.37-1.15-41.44-13.86-51.3-35.78c-9.41-20.93-7.08-40.88,7.01-59.34
c19.06-24.97,49.5-32.54,79.33-22.79c21.47,7.01,43.03,8.54,65.03,9.07c24.68,0.59,49.38,1.73,74.03,1.02
c37.08-1.07,74.08-3.17,111.05-7.28c35.35-3.93,63.98,16.8,71.28,52.84C448.69,88.4,448.42,90.05,448.42,92.12z M159.2,70.78
c0-1.99,0.18-2.66-0.04-3.16c-0.48-1.12-1.19-2.13-1.74-3.22c-6.25-12.36-16.75-18.76-29.81-22.21
c-18.28-4.83-36.2-6.22-53.53,3.12c-21.82,11.76-31.94,33.41-26.21,55.84c5.97,23.41,24.48,37.29,49.57,37.18
c17.77-0.08,24.02-8.04,17.19-24.49c-5.04-12.13-12.63-23.2-19.09-34.74c-1.22-2.18-2.46-4.34-4.73-8.33
C114.8,70.78,137.01,70.78,159.2,70.78z M125.86,137.58c1.23,0.84,1.72,1.47,2.22,1.47c10.98,0.11,21.98,0.38,32.94-0.05
c1.75-0.07,4.42-3.12,4.9-5.2c3.31-14.42,3.93-28.99,1.39-43.67c-1-5.82-3.9-8.4-9.91-8.3c-12.83,0.22-25.67,0.01-38.51,0.11
c-2.02,0.02-4.04,0.76-6.94,1.34C121.1,101.11,132.77,117.32,125.86,137.58z"/>
</g>
<g>
<path class="st2" d="M437.3,403.69c-12.05,6.13-24.1,12.27-36.16,18.4c0.06,0.71,0.11,1.41,0.17,2.12
c24.23,2.92,48.45,5.83,72.88,8.77c0.85,2.39,1.74,4.21,2.15,6.14c4.1,19.37-9.24,40.07-28.6,44.05
c-5.16,1.06-10.51,1.63-15.78,1.64c-68.14,0.11-136.27,0.08-204.41,0.06c-2.4,0-4.79-0.23-9.27-0.46
c10.87-12.42,17.06-25.54,17.43-40.56c0.37-14.77-2.14-29.17-10.26-43.31c3.8-0.56,6.28-1.23,8.77-1.24
c60.59-0.06,121.18-0.1,181.76,0.05c7,0.02,13.99,1.22,20.99,1.88C437.07,402.06,437.18,402.88,437.3,403.69z"/>
</g>
<g>
<path class="st2" d="M208.78,442.37c-2.84,0.3-5.59,0.73-8.35,0.86c-11.77,0.56-23.55,0.9-35.32,1.59
c-11.74,0.69-20.7-11.09-17.7-23.56c2.84-11.78,14.12-20.41,27.04-20.71C193.39,400.09,213.19,416.86,208.78,442.37z"/>
</g>
</g>
</g>
</g>
<g id="icon_x5F_sidebar_x5F_music" class="st0">
<g class="st1">
<g>
<g>
<path class="st2" d="M261.65,225.6c0.7,2.64,1.55,5.26,2.07,7.94c1.62,8.25,2.65,8.79,11.01,8.46c15-0.58,29.14,2.2,41.74,11.16
c14.6,10.37,19.64,25.5,21.71,42.14c2.78,22.32-10.19,36.76-25.52,49.9c-0.44,0.37-1.09,0.54-1.67,0.69
c-0.37,0.09-0.8-0.03-1.59-0.08c-3.15-4.92-2.8-9.59,0.96-14.33c6.14-7.74,11.54-15.89,12.05-26.24
c1.24-25.02-14.28-44.09-39.26-47.94c-4.59-0.71-9.31-0.53-15-0.81c0.44,4.72,0.51,7.73,1.03,10.66
c8.8,49.42,17.66,98.83,26.47,148.26c1.07,6.03,2.01,12.08,2.81,18.15c1.93,14.59-2.85,26.51-14.6,35.46
c-18.51,14.1-39.18,15.5-60.44,8.72c-16.02-5.1-25.76-22.74-22.74-38.34c3.49-18.02,17.24-29.36,35.42-29.2
c17.96,0.16,31.41,11.98,34.49,30.27c0.42,2.52,1.01,5.02,1.49,7.33c10.2,0.4,17.08-7.88,15.5-18.5
c-3.27-22-6.51-44.01-10.45-65.89c-5.72-31.73-12.04-63.35-18.15-95.01c-0.4-2.07-1.27-4.05-2.29-7.23
c-7.24,4.84-12.49,9.93-15.47,17.08c-5.54,13.32-3.63,26.35,1.74,39.25c1.25,3.01,1.98,6.23,2.95,9.35
c-0.69,0.48-1.39,0.96-2.08,1.44c-1.98-1.63-4.28-2.98-5.89-4.92c-14.99-18.11-14.14-48.78,1.75-66.18
c2.06-2.26,4.06-4.69,6.52-6.45c5.79-4.17,9.56-8.69,8.28-16.73c-0.43-2.71,3.11-6.04,4.83-9.09
C260.1,225.14,260.88,225.37,261.65,225.6z"/>
</g>
<g>
<path class="st2" d="M242.98,129.77c-0.54-2.18-1.24-3.66-1.24-5.15c0.06-27.65,5.24-53.97,20.63-77.55
c0.78-1.19,1.62-2.36,2.52-3.47c15.38-18.96,34.82-17.62,45.72,4.2c15.14,30.31,13.51,60.55-6.91,87.73
c-13.67,18.2-29.81,34.59-45.42,51.26c-18.14,19.38-36.83,38.27-50.39,61.34c-4.74,8.07-9.5,16.33-12.73,25.07
c-8.46,22.81-4.26,43.77,11.57,62.22c9.81,11.44,22.06,19.31,36.6,23.44c5.39,1.53,7.9,4.61,6.35,11.29
c-2.86,0-5.84,0.44-8.66-0.07c-31-5.57-50.06-25.12-60.87-53.46c-11.63-30.51-8.06-59.85,11.23-86
c15.34-20.81,32.18-40.57,49.3-59.97c15.92-18.03,33.27-34.79,49.64-52.44c11.16-12.03,12.87-27,10.85-42.48
c-1.06-8.1-5.98-13.73-14.13-16.01c-7.39-2.07-12.75,1.54-17.1,6.79c-2.57,3.1-5.27,6.57-6.35,10.32
c-3.64,12.7-7.02,25.51-9.61,38.46C252.62,122.04,249,126,242.98,129.77z"/>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 28 KiB

+80
View File
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 512 512"
style="height: 256px; width: 256px;"
version="1.1"
id="svg6"
sodipodi:docname="icon_sidebar_tables.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1956"
inkscape:window-height="1125"
id="namedview8"
showgrid="false"
inkscape:zoom="0.71777344"
inkscape:cx="403.50636"
inkscape:cy="-55.697677"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<g
id="g838"
transform="matrix(0.52656879,-0.75618342,0.76711498,0.53418097,-33.85852,326.4134)"
style="fill:#ffffff;stroke:none">
<g
class=""
id="g4-5"
style="fill:#ffffff;stroke:none"
transform="matrix(0.76010883,0,0,0.77788021,-69.057255,5.6807692)">
<path
d="m 375.483,251.243 -109.98,51.138 0.213,183.381 211.294,-219.416 -86.993,-21.81 z m -12.736,108.626 -5.947,14.699 -48.604,-8.955 5.007,-12.832 a 141.306,141.306 0 0 0 13.51,-11.358 167.184,167.184 0 0 0 16.566,-17.517 170.478,170.478 0 0 0 12.606,-17.958 115.607,115.607 0 0 0 9.514,-17.97 l 14.068,2.51 q -9.37,22.334 -30.361,44.43 -13.296,13.64 -20.645,18.636 z M 121.603,244.334 36.893,266.097 246.474,486 V 302.38 L 136.528,251.243 Z m 19.147,50.852 a 28.72,28.72 0 0 1 24.273,6.802 53.052,53.052 0 0 1 11.226,14.188 l -13.081,2.676 a 28.542,28.542 0 0 0 -5.388,-7.374 q -5.185,-4.876 -11.262,-3.853 l -0.487,0.095 a 6.458,6.458 0 0 0 -5.162,4.448 c -0.856,2.378 -0.238,5.554 1.796,9.371 q 4.08,7.6 10.81,9.027 a 23.785,23.785 0 0 0 8.563,-0.203 l 1.867,-0.344 5.791,10.822 q -6.398,1.427 -8.23,3.282 -3.21,3.14 0.429,9.93 a 17.042,17.042 0 0 0 6.089,6.696 10.406,10.406 0 0 0 7.385,1.534 l 0.416,-0.083 q 4.757,-0.964 5.079,-4.757 c 0.261,-2.57 -0.655,-5.744 -2.748,-9.514 l 12.38,-2.545 a 49.247,49.247 0 0 1 4.103,11.226 19.956,19.956 0 0 1 -0.642,9.383 11.702,11.702 0 0 1 -3.96,5.411 19.575,19.575 0 0 1 -8.027,3.235 l -1.19,0.214 a 27.971,27.971 0 0 1 -17.494,-2.7 32.193,32.193 0 0 1 -14.128,-14.092 q -3.627,-6.79 -2.604,-12.19 a 8.396,8.396 0 0 1 2.521,-4.947 h -0.071 q -1.844,0.31 -7.04,-2.497 a 32.11,32.11 0 0 1 -12.916,-13.593 q -5.245,-9.764 -3.282,-18.398 1.962,-8.634 13.676,-11 z M 27.19,248.865 135.97,132.556 a 7.135,7.135 0 0 1 1.427,0 h 0.154 q 3.14,0.345 2.842,3.71 a 19.36,19.36 0 0 1 -3.294,8.1 39.376,39.376 0 0 1 -9.728,10.405 q -3.912,2.938 -15.044,9.514 -12.796,7.505 -19.55,14.77 a 92.535,92.535 0 0 0 -11.513,14.486 l 32.907,3.758 8.182,-12.963 -20.967,-2.378 a 36.415,36.415 0 0 1 4.757,-3.83 q 2.379,-1.605 8.444,-5.125 l 6.422,-3.747 a 92.975,92.975 0 0 0 12.903,-8.776 61.472,61.472 0 0 0 12.51,-14.414 q 6.84,-10.846 6.494,-17.957 c -0.19,-3.949 -2.105,-6.434 -5.684,-7.505 l 79.798,-85.161 -102.097,179.576 -5.708,10.06 z m 367.238,-71.974 q -3.817,-5.458 -3.758,-8.515 c 0,-2.033 1.19,-3.199 3.568,-3.448 h 0.57 a 11.892,11.892 0 0 1 6.91,2.247 29.85,29.85 0 0 1 7.837,8.051 q 3.687,5.28 3.71,8.397 c 0,2.093 -1.188,3.258 -3.496,3.567 h -0.594 a 11.75,11.75 0 0 1 -6.957,-2.378 29.79,29.79 0 0 1 -7.79,-7.885 z m -109.41,-141.52 83.948,89.634 h -1.189 c -0.38,0 -0.975,0 -1.463,0.107 q -7.825,0.892 -8.324,6.862 -0.5,5.97 5.03,13.747 a 53.778,53.778 0 0 0 6.375,7.374 37.901,37.901 0 0 0 10.144,6.897 q -2.117,2.89 -0.702,7.98 a 37.283,37.283 0 0 0 5.613,11.096 55.122,55.122 0 0 0 15.223,14.806 q 8.098,5.268 16.066,4.935 0.81,0 1.618,-0.13 8.776,-0.988 9.228,-7.873 a 16.114,16.114 0 0 0 -0.463,-4.853 l 58.689,62.686 -91.572,-22.941 -6.1,-10.703 z m 98.22,104.927 2.45,2.617 c 0.451,0.57 0.903,1.189 1.355,1.784 1.808,2.592 2.723,4.757 2.723,6.529 0,1.771 -1.034,2.782 -3.127,3.02 h -0.512 a 10.346,10.346 0 0 1 -6.077,-1.95 22.596,22.596 0 0 1 -6.184,-6.137 c -1.974,-2.83 -2.937,-5.102 -2.878,-6.814 0.06,-1.713 1.118,-2.7 3.187,-2.937 h 0.524 a 10.263,10.263 0 0 1 6.005,1.879 19.147,19.147 0 0 1 2.533,2.01 z M 255.987,26 137.456,231.026 l 118.532,55.05 118.604,-55.05 z m -1.19,208.463 q -17.529,0 -24.58,-12.273 -7.053,-12.273 -7.053,-34.988 0,-22.714 7.052,-35.047 7.052,-12.332 24.582,-12.344 17.53,0 24.582,12.332 7.052,12.333 7.052,35.047 0,22.715 -7.052,34.988 -7.053,12.273 -24.582,12.285 z m 10.538,-71.807 q 2.497,7.968 2.497,24.546 0,15.817 -2.497,24.201 -2.498,8.384 -10.537,8.325 -8.04,0 -10.632,-8.325 -2.593,-8.324 -2.593,-24.2 0,-16.579 2.593,-24.547 2.593,-7.968 10.632,-7.968 8.015,-0.012 10.513,7.956 z"
fill="#ffffff"
fill-opacity="1"
transform="matrix(0.69282032,-0.4,0.4,0.69282032,-23.762003,181.038)"
id="path2-65"
style="fill:#ffffff;stroke:none" />
</g>
<g
class=""
id="g4-4"
style="fill:#ffffff;stroke:none"
transform="matrix(0.74275157,0.16528633,-0.16151022,0.76011713,216.37438,-18.305353)">
<path
d="m 375.483,251.243 -109.98,51.138 0.213,183.381 211.294,-219.416 -86.993,-21.81 z m -12.736,108.626 -5.947,14.699 -48.604,-8.955 5.007,-12.832 a 141.306,141.306 0 0 0 13.51,-11.358 167.184,167.184 0 0 0 16.566,-17.517 170.478,170.478 0 0 0 12.606,-17.958 115.607,115.607 0 0 0 9.514,-17.97 l 14.068,2.51 q -9.37,22.334 -30.361,44.43 -13.296,13.64 -20.645,18.636 z M 121.603,244.334 36.893,266.097 246.474,486 V 302.38 L 136.528,251.243 Z m 19.147,50.852 a 28.72,28.72 0 0 1 24.273,6.802 53.052,53.052 0 0 1 11.226,14.188 l -13.081,2.676 a 28.542,28.542 0 0 0 -5.388,-7.374 q -5.185,-4.876 -11.262,-3.853 l -0.487,0.095 a 6.458,6.458 0 0 0 -5.162,4.448 c -0.856,2.378 -0.238,5.554 1.796,9.371 q 4.08,7.6 10.81,9.027 a 23.785,23.785 0 0 0 8.563,-0.203 l 1.867,-0.344 5.791,10.822 q -6.398,1.427 -8.23,3.282 -3.21,3.14 0.429,9.93 a 17.042,17.042 0 0 0 6.089,6.696 10.406,10.406 0 0 0 7.385,1.534 l 0.416,-0.083 q 4.757,-0.964 5.079,-4.757 c 0.261,-2.57 -0.655,-5.744 -2.748,-9.514 l 12.38,-2.545 a 49.247,49.247 0 0 1 4.103,11.226 19.956,19.956 0 0 1 -0.642,9.383 11.702,11.702 0 0 1 -3.96,5.411 19.575,19.575 0 0 1 -8.027,3.235 l -1.19,0.214 a 27.971,27.971 0 0 1 -17.494,-2.7 32.193,32.193 0 0 1 -14.128,-14.092 q -3.627,-6.79 -2.604,-12.19 a 8.396,8.396 0 0 1 2.521,-4.947 h -0.071 q -1.844,0.31 -7.04,-2.497 a 32.11,32.11 0 0 1 -12.916,-13.593 q -5.245,-9.764 -3.282,-18.398 1.962,-8.634 13.676,-11 z M 27.19,248.865 135.97,132.556 a 7.135,7.135 0 0 1 1.427,0 h 0.154 q 3.14,0.345 2.842,3.71 a 19.36,19.36 0 0 1 -3.294,8.1 39.376,39.376 0 0 1 -9.728,10.405 q -3.912,2.938 -15.044,9.514 -12.796,7.505 -19.55,14.77 a 92.535,92.535 0 0 0 -11.513,14.486 l 32.907,3.758 8.182,-12.963 -20.967,-2.378 a 36.415,36.415 0 0 1 4.757,-3.83 q 2.379,-1.605 8.444,-5.125 l 6.422,-3.747 a 92.975,92.975 0 0 0 12.903,-8.776 61.472,61.472 0 0 0 12.51,-14.414 q 6.84,-10.846 6.494,-17.957 c -0.19,-3.949 -2.105,-6.434 -5.684,-7.505 l 79.798,-85.161 -102.097,179.576 -5.708,10.06 z m 367.238,-71.974 q -3.817,-5.458 -3.758,-8.515 c 0,-2.033 1.19,-3.199 3.568,-3.448 h 0.57 a 11.892,11.892 0 0 1 6.91,2.247 29.85,29.85 0 0 1 7.837,8.051 q 3.687,5.28 3.71,8.397 c 0,2.093 -1.188,3.258 -3.496,3.567 h -0.594 a 11.75,11.75 0 0 1 -6.957,-2.378 29.79,29.79 0 0 1 -7.79,-7.885 z m -109.41,-141.52 83.948,89.634 h -1.189 c -0.38,0 -0.975,0 -1.463,0.107 q -7.825,0.892 -8.324,6.862 -0.5,5.97 5.03,13.747 a 53.778,53.778 0 0 0 6.375,7.374 37.901,37.901 0 0 0 10.144,6.897 q -2.117,2.89 -0.702,7.98 a 37.283,37.283 0 0 0 5.613,11.096 55.122,55.122 0 0 0 15.223,14.806 q 8.098,5.268 16.066,4.935 0.81,0 1.618,-0.13 8.776,-0.988 9.228,-7.873 a 16.114,16.114 0 0 0 -0.463,-4.853 l 58.689,62.686 -91.572,-22.941 -6.1,-10.703 z m 98.22,104.927 2.45,2.617 c 0.451,0.57 0.903,1.189 1.355,1.784 1.808,2.592 2.723,4.757 2.723,6.529 0,1.771 -1.034,2.782 -3.127,3.02 h -0.512 a 10.346,10.346 0 0 1 -6.077,-1.95 22.596,22.596 0 0 1 -6.184,-6.137 c -1.974,-2.83 -2.937,-5.102 -2.878,-6.814 0.06,-1.713 1.118,-2.7 3.187,-2.937 h 0.524 a 10.263,10.263 0 0 1 6.005,1.879 19.147,19.147 0 0 1 2.533,2.01 z M 255.987,26 137.456,231.026 l 118.532,55.05 118.604,-55.05 z m -1.19,208.463 q -17.529,0 -24.58,-12.273 -7.053,-12.273 -7.053,-34.988 0,-22.714 7.052,-35.047 7.052,-12.332 24.582,-12.344 17.53,0 24.582,12.332 7.052,12.333 7.052,35.047 0,22.715 -7.052,34.988 -7.053,12.273 -24.582,12.285 z m 10.538,-71.807 q 2.497,7.968 2.497,24.546 0,15.817 -2.497,24.201 -2.498,8.384 -10.537,8.325 -8.04,0 -10.632,-8.325 -2.593,-8.324 -2.593,-24.2 0,-16.579 2.593,-24.547 2.593,-7.968 10.632,-7.968 8.015,-0.012 10.513,7.956 z"
fill="#ffffff"
fill-opacity="1"
transform="matrix(0.69282032,-0.4,0.4,0.69282032,-23.762003,181.038)"
id="path2-6"
style="fill:#ffffff;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

+181
View File
@@ -1,5 +1,186 @@
# 13.0
## 14.0.2 - Le grang ménage de Tétragor
### Migration Foundry V14
- Migration des classes restantes de V1 vers V2 (ApplicationV2)
- OptionsAvancees, StatusEffects, SystemCompendiums, ReglesOptionnelles,
DialogEncaissementTables
- DialogV2: formes imbriquées, boutons, styles et positionnement corrigés
- DialogV2 requiert au moins un bouton (boutons vides interdits en V14)
- templates avec wrapper à racine unique
- correction des éditeurs ProseMirror et des scrollbar sur les fiches d'acteur
- rollMode → messageMode, Token HUD, data-message-id
- champ age en StringField pour compat V14
- compat V14: _onFirstRender (HTMLElement.show) pour les jets de dés,
fermeture des dialogs TMR après lecture d'un signe draconique
- 10 fichiers .js V1 inutilisés déplacés vers _deprecated/
- scrollbar des applications V2 corrigées (LESS, plus de style inline)
- migration de toutes les directives CSS inline vers LESS
- titres des tables d'encaissement alternatives lisibles
- le dialog ne passe plus au premier plan lors du re-render (hook)
- refresh des dialogs herbes/potions/ingrédients après édition de fiche
- TODO-v14.md pour le suivi de la compatibilité V14
### Feuilles d'items
- migration des feuilles d'items vers V2 (models, apps, templates, less + common/mixins)
- ajout des sections environnement (inventaire) et temporel (blessure, maladie,
poison, rencontre, signe draconique) manquantes dans les sheets V2
### Sommeil & Château Dormant
- nouveau mode sommeil avec sélection des heures de repos
- dialogs Château Dormant intégrés, toolbar équipement
- message de statut MJ + journal de suivi stress/moral/événements par jour
- journal enrichi avec stress, perte d'enchantements, moral
- message stress journal: perte fixe de 1, reste X, conversion Y en xp
- boutons Repas externe et Rations harmonisés avec les cartouches de tchat
### Inventaire
- boutons +Ration/+Eau et cartouche de tchat compacte
- consommation des rations: assez d'unités pour remplir sustentation/eau en un
clic + alerte si vide
- ne plus afficher « rien à manger » quand les compteurs sont déjà pleins
### Règles & encaissement
- fusion des Règles customs dans Règles optionnelles (section Options alternatives)
- tables d'encaissement révisées optionnelles + dialog de consultation
### Divers
- regroupement des classes de combat
- fix assign dans les constructeurs
### Tests automatisés
- plan de test (227 cas, 33 sections) + scripts TC-01 à TC-07
- 22 scripts TC supplémentaires (TC-08 à TC-31) avec fonctions partagées
- orchestrateur run-all-tests.sh (sélection, exécution, rapport final)
- documentation du lancement des tests dans test/README.md
## 14.0.1 - Les imprécisions de Tétragor
- correction de l'indicateur de remplissage des conteneurs
- correction de l'ouverture des objets utilisant la liste des compétences
- correction de la description aléatoires
## 14.0.0 - Les rangements de Tétragor
- Amélioration de la gestion de l'équipement
- gestion des deniers
- gestion de herbes & plantes
- gestion des ingrédients
- gestion des potions
- indicateur de remplissage des conteneurs
- tri par nom / type / encombrement / quantité
- Le but des recettes alchimiques est affiché et éditable
## 13.0.48 - Les vagabondages d'Illisys
- Gestion des tâches à plusieurs
- Les tâches du monde peuvent être configurées pour être effectuées à plusieurs
- Une tâche à plusieurs ajoutée à un personnage permet au personnage de contribuer à la tâche commune
- suppression du type de TMR "Inconnu" des feuilles de création de signes draconiques (ce type sert uniquement pour le cas où une case saisie à la main est incorrecte)
- les jets de dés /rdd utilisent le mode de visibilité sélectionné
- Voies de Draconic
- Ne pas proposer les voies de Draconic à -11 pour lire un signe draconic ou lancer un sort
- Trier les voies par ordre décroissant pour le sorts à voies multiples
- Les rencontres et les maîtrises dans les TMR peuvent être vaincues sans
draconic si les voies sont négatives
- correction d'updates non affichés
- Améliorations des titres des fenêtres de jets
## 13.0.47 - Les goûts et les couleurs d'Illisys
- Correction des couleurs des tooltips d'aide foundry
## 13.0.46 - L'archétype d'Illisys
- ajout d'une génération d'archétype aléatoire
- respecte les niveaux d'archétype déjà alloués
- l'archétype alloué est supérieur au niveau actuel (si c'est possible)
- les compétences supérieures à 0 ont plus de chances d'avoir les niveaux d'archétype élevés
- si tous les niveaux d'archétype supérieurs à une compétences sont déjà alloué,
l'archétype est au niveau actuel de la compétence
- Amélioration de l'affichage de la fenêtre de jets:
- La difficultée est déplacée dans la colonne des ajustements
- les ajustements sont mieux alignés
- les ajustements sont mieux ordonnés
- Les indications d'ajustements de tir prennent moins de place
- l'icône d100 est redessinée pour être mieux centrée
## 13.0.45 - L'endépôté d'Illisys
- nouvelle correction du manifest
## 13.0.44 - Le dépôt d'Illisys
- le manifest pointe maintenant toujours vers la dernière version
- changement des liens dans le system.json
## 13.0.43 - L'urgence d'Illisys
- correction urgente des jets
## 13.0.42 - La rebellion d'Illisys
- on peut choisir la difficulté des jets de résistances
- la macro signe draconique fonctionne de nouveau (ajout et suppression)
- le Guerrier Sorde n'est pas joueur et ne cuisine pas (pas de message si compétence Jeu / Cuisine manquent)
- Corrections V14
- Les descriptions aléatoires fonctionnent de nouveau
## 13.0.41 - Le miroir d'Illisys
- les mode de visibilité des jets sont bien pris en compte
## 13.0.40 - Le miroir d'Illisys
- pas de stress ou de sommeil pour les personnage non liés
## 13.0.39 - La défense d'Illisys
- mise à jour de version foundry-cli
- correction des catégories de parades des compendiums
- des ne pouvaient pas parer (exemple: le bouclier du guerrier sorde)
- les difficultés des jets d'attaque/défense après appel à la chance sont conservées
- L'absence des compétences cuisine/jeu ne bloque plus l'accès à la fenêtre de jets (cas des invocations)
## 13.0.38 - L'urgence d'Illisys
- Corrections v14
- on peut utiliser les commandes foundry dans le tchat (par exemple, /roll 1d6)
- les dés customisés Dice-So-Nice (heure, rencontres, dé draconique) fonctionnent
- Le Haut-rêve est de nouveau proposé dans les options d'initiative
- Nouvelle règle optionnelle: choisir si seules les armes équipées sont proposées en combat
- L'appel à la chance utilise la nouvelle fenêtre de jet de dés
## 13.0.37 - Le bonheur des zyglutes d'Illisys
- Corrections v14
- correction du problème liè à Foundry 14 qui peut empêcher d'utiliser les fenêtres de jets à cause de migrations mal effectuées
- Les bon moments sont affichés en tooltip sur le moral
- Les modifications de coeurs fonctionnent de nouveau
- Le refoulement est remis à zéro après avoir refoulé et reçu un souffle
## 13.0.36 - Les rêveries d'Illisys
- Corrections v14
- les attaques à distance n'empèchent plus la fenêtre d'attaque de s'ouvrir
- les commandes (/help, ...) fonctionnent en v14
- Les feuilles d'acteurs ne s'ouvrent plus lors d'un changement (par exemple en cas d'encaissement)
- Les jeux sont correctement affichés
- Ajout d'une gravité de blessure sur les encaissement d'entités
- Amélioration de champs numériques: ajout de min et max quand c'est utile
- correction pour cuisiner depuis l'équipement
- les boutons dans les listes d'équipement sont mieux affichés sans retour à la ligne
## 13.0.35 - Les travaux d'Illisys
- Correction du recul contre une entité de cauchemar (qui utilise le rêve comme force)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
.arme-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.armure-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.blessure-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.casetmr-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.chant-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.competence-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.competencecreature-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.conteneur-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.danse-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.empoignade-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.extraitpoetique-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.faune-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.gemme-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.herbe-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.ingredient-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.jeu-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.livre-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.maladie-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.meditation-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+1
View File
@@ -3,5 +3,6 @@
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+2 -1
View File
@@ -1,7 +1,8 @@
// Styles pour la feuille d'objet Monnaie
// Styles pour la feuille d'objet Munition
.munition-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.musique-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.nombreastral-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.nourritureboisson-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.objet-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.oeuvre-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.ombre-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.plante-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.poison-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.possession-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.potion-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.queue-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.race-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+12
View File
@@ -0,0 +1,12 @@
.recettealchimique-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
.ingredient-row {
display: flex;
gap: 4px;
align-items: center;
padding: 2px 0;
}
}
+5
View File
@@ -0,0 +1,5 @@
.recettecuisine-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.rencontre-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.service-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.signedraconique-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.sort-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.sortreserve-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.souffle-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.tache-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+2 -1
View File
@@ -1,7 +1,8 @@
// Styles pour la feuille d'objet Monnaie
// Styles pour la feuille d'objet Tarot
.tarot-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+5
View File
@@ -0,0 +1,5 @@
.tete-content {
.item-sheet-common();
.item-sheet-header();
.item-sheet-scrollable-body();
}
+20 -5
View File
@@ -32,6 +32,7 @@
display: flex;
flex-direction: column;
}
roll-conditions roll-section[name="rollmode"],
roll-type {
button[data-checked="true"] {
@@ -64,6 +65,13 @@
flex-direction: row;
align-items: anchor-center;
margin: 0 0.2rem;
label {
text-align:left;
min-width: 55%;
display: flex;
flex-direction: row;
}
}
roll-resume {
@@ -241,11 +249,18 @@
padding: 0;
filter: invert(0.8);
}
roll-conditions roll-section[name="tricher"] img {
/* image de d100 */
max-width: 2.5rem;
max-height: 2.5rem;
}
roll-conditions roll-section[name="tricher"] {
label {
display: flex;
flex-direction: row;
img {
/* image de d100 */
max-width: 2rem;
max-height: 2rem;
}
}
}
roll-buttons {
display: flex;
+26 -4
View File
@@ -74,9 +74,31 @@
}
}
.item-sheet-scrollable-body() {
max-height: 75vh;
overflow: hidden;
> section {
display: flex;
flex-direction: column;
min-height: 0;
height: 100%;
}
.sheet-header {
flex-shrink: 0;
}
.sheet-body {
overflow-y: auto;
flex: 1;
min-height: 0;
}
}
.item-sheet-header() {
background: #011d33 url(../assets/ui/bg_header.webp) no-repeat left top;
color: rgba(255, 255, 255, 1);
.sheet-header {
background: #011d33 url(../assets/ui/bg_header.webp) no-repeat left top;
}
.sheet-header-row {
display: flex;
flex-direction: row;
@@ -86,7 +108,7 @@
font-family: CaslonAntique;
font-size: 2.5rem;
font-weight: normal;
color: var(--window-header-title-color);
color: var(--window-header-title-color, #fff);
margin: 4px;
height: 3rem;
}
@@ -100,8 +122,8 @@
input[type="date"],
input[type="time"]
) {
color: rgba(255, 255, 255, 0.75);
background: rgba(255, 255, 255, 0.1);
color: #fff;
background: rgba(0, 0, 0, 0.2);
border: 0 none;
margin-bottom: 0.2rem;
}
+14
View File
@@ -0,0 +1,14 @@
// Supprimer tous les items du monde
// Coller ce code dans une macro Foundry (type script)
const count = game.items.size
if (!count) return ui.notifications.info("Aucun item dans le monde.")
const confirmed = await Dialog.confirm({
title: "Supprimer tous les items",
content: `<p>⚠️ <b>${count} items</b> vont être définitivement supprimés.</p>`,
})
if (!confirmed) return
await Item.deleteDocuments(game.items.map(i => i.id))
ui.notifications.info(`${count} items supprimés.`)
+1 -1
View File
@@ -12,7 +12,7 @@ export class ChatVente {
return undefined;
}
const nbLots = chatMessage.getFlag(SYSTEM_RDD, NB_LOTS)
const detail = foundry.utils.duplicate(chatMessage.getFlag(SYSTEM_RDD, DETAIL_VENTE))
const detail = foundry.utils.deepClone(chatMessage.getFlag(SYSTEM_RDD, DETAIL_VENTE))
if (!detail.item) {
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
return undefined;
+57 -59
View File
@@ -1,10 +1,9 @@
import { renderTemplate } from "../constants.js";
import { Misc } from "../misc.js";
import { RdDUtility } from "../rdd-utility.js";
import { ChatVente } from "./chat-vente.js";
export class DialogItemAchat extends Dialog {
import { renderTemplate } from "../constants.js"
import { Misc } from "../misc.js"
import { RdDUtility } from "../rdd-utility.js"
import { ChatVente } from "./chat-vente.js"
export class DialogItemAchat extends foundry.applications.api.DialogV2 {
static preparerAchat(chatButton) {
return ChatVente.getDetailAchatVente(RdDUtility.findChatMessageId(chatButton))
}
@@ -21,57 +20,64 @@ export class DialogItemAchat extends Dialog {
choix: { seForcer: false, supprimerSiZero: true },
prixLot,
isVente: prixLot > 0,
isConsommable: item.type == 'nourritureboisson' && acheteur?.isPersonnage(),
isConsommable: item.type == "nourritureboisson" && acheteur?.isPersonnage(),
chatMessageIdVente
}
if (venteData.vendeur?.id == venteData.acheteur?.id) {
ui.notifications.info("Inutile de se vendre à soi-même")
return
}
DialogItemAchat.changeNombreLots(venteData, 1)
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.hbs`, venteData)
new DialogItemAchat(html, venteData).render(true)
const content = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.hbs", venteData)
new DialogItemAchat(content, venteData).render({ force: true })
}
static changeNombreLots(venteData, nombreLots) {
venteData.choix.nombreLots = nombreLots;
venteData.prixTotal = (nombreLots * venteData.prixLot).toFixed(2);
venteData.choix.nombreLots = nombreLots
venteData.prixTotal = (nombreLots * venteData.prixLot).toFixed(2)
if (venteData.isConsommable) {
const doses = nombreLots * venteData.tailleLot;
venteData.totalSust = Misc.keepDecimals(doses * (venteData.item.system.sust ?? 0), 2);
const doses = nombreLots * venteData.tailleLot
venteData.totalSust = Misc.keepDecimals(doses * (venteData.item.system.sust ?? 0), 2)
venteData.totalDesaltere = venteData.item.system.boisson
? Misc.keepDecimals(doses * (venteData.item.system.desaltere ?? 0), 2)
: 0;
: 0
}
}
constructor(html, venteData) {
let options = { classes: ["dialogachat"], width: 400, height: 'fit-content', 'z-index': 99999 };
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
const buttons = {};
constructor(content, venteData) {
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre"
const buttons = []
if (venteData.isConsommable) {
buttons["consommer"] = { label: venteData.item.system.boisson ? "Boire" : "Manger", callback: it => this.onAchatConsommer() }
buttons.push({
label: venteData.item.system.boisson ? "Boire" : "Manger",
action: "consommer",
callback: () => this.onAchatConsommer()
})
}
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
buttons["decliner"] = { label: "cliner", callback: it => { } };
const acheteur = venteData.acheteur?.name ?? 'Un acheteur';
const vendeur = venteData.vendeur?.name ?? 'Un vendeur';
let conf = {
buttons.push({ label: actionAchat, action: actionAchat, callback: () => this.onAchat() })
buttons.push({ label: "Décliner", action: "decliner", callback: () => {} })
const acheteur = venteData.acheteur?.name ?? "Un acheteur"
const vendeur = venteData.vendeur?.name ?? "Un vendeur"
super({
title: `${acheteur} - ${actionAchat} à ${vendeur}`,
content: html,
default: actionAchat,
buttons: buttons
};
content,
classes: ["dialogachat"],
position: { width: 400, height: 'fit-content' },
buttons
})
this.venteData = venteData
}
super(conf, options);
this.venteData = venteData;
_onRender(context) {
super._onRender(context)
this.element.querySelector(".nombreLots")?.addEventListener("change", event => this.setNombreLots(Number(event.currentTarget.value)))
this.element.querySelector(".se-forcer")?.addEventListener("change", event => this.setSeForcer(event))
}
async onAchat() {
await this.html.find(".nombreLots").change();
(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
const el = this.element
el.querySelector(".nombreLots")?.dispatchEvent(new Event("change"))
;(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
userId: game.user.id,
vendeurId: this.venteData.vendeur?.id,
acheteurId: this.venteData.acheteur?.id,
@@ -79,42 +85,34 @@ export class DialogItemAchat extends Dialog {
chatMessageIdVente: this.venteData.chatMessageIdVente,
choix: this.venteData.choix,
vente: this.venteData
});
})
}
async onAchatConsommer() {
this.venteData.choix.consommer = true;
await this.onAchat();
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
this.html = html;
this.html.find(".nombreLots").change(event => this.setNombreLots(Number(event.currentTarget.value)));
this.html.find(".se-forcer").change(event => this.setSeForcer(event));
this.venteData.choix.consommer = true
await this.onAchat()
}
setSeForcer(event) {
this.venteData.choix.seForcer = event.currentTarget.checked;
this.venteData.choix.seForcer = event.currentTarget.checked
}
setNombreLots(nbLots) {
if (!this.venteData.quantiteIllimite) {
if (!this.venteData.quantiteIllimite && nbLots > this.venteData.nbLots) {
if (nbLots > this.venteData.nbLots) {
ui.notifications.warn(`Seulement ${this.venteData.nbLots} lots disponibles, vous ne pouvez pas en prendre ${nbLots}`)
}
nbLots = Math.min(nbLots, this.venteData.nbLots);
nbLots = Math.min(nbLots, this.venteData.nbLots)
}
DialogItemAchat.changeNombreLots(this.venteData, nbLots);
this.html.find(".nombreLots").val(nbLots);
this.html.find(".prixTotal").text(this.venteData.prixTotal);
this.html.find("span.total-sust").text(this.venteData.totalSust);
this.html.find("span.total-desaltere").text(this.venteData.totalDesaltere);
DialogItemAchat.changeNombreLots(this.venteData, nbLots)
const el = this.element
const nbl = el.querySelector(".nombreLots")
if (nbl) nbl.value = nbLots
const pt = el.querySelector(".prixTotal")
if (pt) pt.textContent = this.venteData.prixTotal
const sust = el.querySelector("span.total-sust")
if (sust) sust.textContent = this.venteData.totalSust
const des = el.querySelector("span.total-desaltere")
if (des) des.textContent = this.venteData.totalDesaltere
}
}
}
+58 -53
View File
@@ -1,14 +1,13 @@
import { renderTemplate } from "../constants.js";
import { renderTemplate } from "../constants.js"
import { HtmlUtility } from "../html-utility.js";
import { RdDUtility } from "../rdd-utility.js";
import { ChatVente } from "./chat-vente.js";
export class DialogItemVente extends Dialog {
export class DialogItemVente extends foundry.applications.api.DialogV2 {
static async display({ item, quantiteMax = undefined }) {
const quantite = quantiteMax ?? item.getQuantite() ?? 1;
const quantite = quantiteMax ?? item.getQuantite() ?? 1
const venteData = {
item: item,
item,
alias: item.actor?.name ?? game.user.name,
vendeurId: item.actor?.id,
prixOrigine: item.calculerPrixCommercant(),
@@ -19,93 +18,99 @@ export class DialogItemVente extends Dialog {
maxLots: quantite,
quantiteMax: quantite,
quantiteIllimite: item.isItemCommerce() ? quantiteMax == undefined : !item.parent,
isOwned: item.parent,
isOwned: item.parent,
}
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.hbs`, venteData);
return new DialogItemVente(venteData, html).render(true);
const content = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.hbs", venteData)
const dialog = new DialogItemVente(venteData, content)
dialog.render({ force: true })
return dialog
}
constructor(venteData, html) {
let options = { classes: ["dialogvente"], width: 400, height: 'fit-content', 'z-index': 99999 };
let conf = {
constructor(venteData, content) {
super({
title: "Proposer",
content: html,
default: "proposer",
buttons: { "proposer": { label: "Proposer", callback: it => { this.onProposer(it); } } }
};
super(conf, options);
this.venteData = venteData;
content,
classes: ["dialogvente"],
position: { width: 400, height: 'fit-content' },
buttons: [
{ label: "Proposer", action: "proposer", callback: () => this.onProposer() }
]
})
this.venteData = venteData
}
activateListeners(html) {
super.activateListeners(html);
this.html = html;
this.html.find(".tailleLot").change(event => this.setTailleLot(Number(event.currentTarget.value)));
this.html.find(".nbLots").change(event => this.setNbLots(Number(event.currentTarget.value)));
this.html.find(".quantiteIllimite").change(event => this.setQuantiteIllimite(event.currentTarget.checked));
this.html.find(".prixLot").change(event => this.setPrixLot(Number(event.currentTarget.value)));
this.setQuantiteIllimite(this.venteData.quantiteIllimite);
_onRender(context) {
super._onRender(context)
const el = this.element
el.querySelector(".tailleLot")?.addEventListener("change", event => this.setTailleLot(Number(event.currentTarget.value)))
el.querySelector(".nbLots")?.addEventListener("change", event => this.setNbLots(Number(event.currentTarget.value)))
el.querySelector(".quantiteIllimite")?.addEventListener("change", event => this.setQuantiteIllimite(event.currentTarget.checked))
el.querySelector(".prixLot")?.addEventListener("change", event => this.setPrixLot(Number(event.currentTarget.value)))
this.setQuantiteIllimite(this.venteData.quantiteIllimite)
}
async onProposer(it) {
this.updateVente(this.getChoixVente());
this.venteData["properties"] = this.venteData.item.getProprietes();
async onProposer() {
this.updateVente(this.getChoixVente())
this.venteData["properties"] = this.venteData.item.getProprietes()
if (this.venteData.isOwned) {
if (this.venteData.nbLots * this.venteData.tailleLot > this.venteData.quantiteMax) {
ui.notifications.warn(`Vous avez ${this.venteData.quantiteMax} ${this.venteData.item.name}, ce n'est pas suffisant pour vendre ${this.venteData.nbLots} de ${this.venteData.tailleLot}`)
return;
return
}
}
await ChatVente.displayAchatVente(this.venteData)
}
updateVente(update) {
foundry.utils.mergeObject(this.venteData, update);
foundry.utils.mergeObject(this.venteData, update)
}
getChoixVente() {
const el = this.element
return {
nbLots: Number(this.html.find(".nbLots").val()),
tailleLot: Number(this.html.find(".tailleLot").val()),
quantiteIllimite: this.html.find(".quantiteIllimite").is(':checked'),
prixLot: Number(this.html.find(".prixLot").val())
};
nbLots: Number(el.querySelector(".nbLots")?.value ?? 0),
tailleLot: Number(el.querySelector(".tailleLot")?.value ?? 0),
quantiteIllimite: el.querySelector(".quantiteIllimite")?.checked ?? false,
prixLot: Number(el.querySelector(".prixLot")?.value ?? 0)
}
}
/* -------------------------------------------- */
setPrixLot(prixLot) {
this.venteData.prixLot = prixLot;
this.venteData.prixLot = prixLot
}
setTailleLot(tailleLot) {
const maxLots = Math.floor(this.venteData.quantiteMax / tailleLot);
const maxLots = Math.floor(this.venteData.quantiteMax / tailleLot)
this.updateVente({
tailleLot,
nbLots: Math.min(maxLots, this.venteData.nbLots),
maxLots: maxLots,
maxLots,
prixLot: (tailleLot * this.venteData.prixOrigine).toFixed(2)
});
this.html.find(".prixLot").val(this.venteData.prixLot);
this.html.find(".nbLots").val(this.venteData.nbLots);
this.html.find(".nbLots").attr("max", this.venteData.maxLots)
})
const el = this.element
const prix = el.querySelector(".prixLot")
if (prix) prix.value = this.venteData.prixLot
const nb = el.querySelector(".nbLots")
if (nb) {
nb.value = this.venteData.nbLots
nb.setAttribute("max", this.venteData.maxLots)
}
}
setNbLots(nbLots) {
this.updateVente({
nbLots: this.venteData.isOwned ? Math.max(0, Math.min(nbLots, this.venteData.maxLots)) : nbLots
})
this.html.find(".nbLots").val(this.venteData.nbLots);
const nb = this.element.querySelector(".nbLots")
if (nb) nb.value = this.venteData.nbLots
}
setQuantiteIllimite(checked) {
this.updateVente({ quantiteIllimite: checked })
this.html.find(".label-quantiteIllimite").text(this.venteData.quantiteIllimite ? "Illimités" : "disponibles");
HtmlUtility.showControlWhen(this.html.find(".nbLots"), !this.venteData.quantiteIllimite)
const el = this.element
const label = el.querySelector(".label-quantiteIllimite")
if (label) label.textContent = checked ? "Illimités" : "disponibles"
const nb = el.querySelector(".nbLots")
if (nb) HtmlUtility.showControlWhen(nb, !checked)
}
}
}
+391 -279
View File
File diff suppressed because it is too large Load Diff
+58 -41
View File
@@ -9,7 +9,7 @@ import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
import { RdDBaseActor } from "./base-actor.js";
import { ITEM_TYPES } from "../constants.js";
import { StatusEffects, STATUSES } from "../settings/status-effects.js";
import { Targets } from "../targets.js";
import { Targets } from "../combat/targets.js";
import { RdDConfirm } from "../rdd-confirm.js";
import { CARACS, RdDCarac } from "../rdd-carac.js";
import { RdDRollResult } from "../rdd-roll-result.js";
@@ -19,19 +19,19 @@ import { RdDItemCompetence } from "../item-competence.js";
import { ChatUtility } from "../chat-utility.js";
import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js";
import { RdDCombat } from "../rdd-combat.js";
import { RdDEmpoignade } from "../rdd-empoignade.js";
import { RdDPossession } from "../rdd-possession.js";
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES_CREATURES } from "../item/base-items.js";
import { PasseArme } from "../combat/passe-arme.mjs";
import { RdDEmpoignade } from "../combat/rdd-empoignade.js";
import { RdDPossession } from "../combat/rdd-possession.js";
import { RdDPossessionV2 } from "../combat/rdd-possession-v2.mjs";
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES_CREATURES, SANS_DRACONIC } from "../item/base-items.js";
import { RollDataAjustements } from "../rolldata-ajustements-v1.js";
import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs";
import RollDialog from "../roll/roll-dialog.mjs";
import { DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE } from "../roll/roll-constants.mjs";
import { DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP, ROLL_TYPE_REVE_RESISTANCE } from "../roll/roll-constants.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js";
import { PART_COMP } from "../roll/roll-part-comp.mjs";
import { RdDInitiative } from "../initiative.mjs";
import { RdDInitiative } from "../combat/initiative.mjs";
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
import { RdDPossessionV2 } from "../rdd-possession-v2.mjs";
/**
* Classe de base pour les acteurs disposant de rêve (donc, pas des objets)
@@ -40,13 +40,6 @@ import { RdDPossessionV2 } from "../rdd-possession-v2.mjs";
*/
export class RdDBaseActorReve extends RdDBaseActor {
prepareActorData() {
super.prepareActorData()
this.system.attributs.plusdom.value = this.getBonusDegat()
this.system.sante.endurance.max = this.getEnduranceMax()
this.system.sante.endurance.value = Math.min(this.system.sante.endurance.value, this.system.sante.endurance.max)
}
getCarac() {
const carac = super.getCarac()
foundry.utils.mergeObject(carac, this.getCaracReveActuel())
@@ -103,17 +96,18 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
getDraconics() { return [] }
getDraconicOuPossession() {
getDraconicOuNaturel(options = {possession: false}) {
return [
...this.getDraconics(),
...this.itemTypes[ITEM_TYPES.competencecreature].filter(it => it.isCompetencePossession()),
this.getConjurationNaturelle()
options.possession ? this.getConjurationNaturelle() : SANS_DRACONIC
].sort(Misc.descending(it => it.system.niveau));
}
getConjurations() {
return this.getDraconicOuPossession()
.map(it => this.toActionConjuration(it))
getBestDraconic(options = {possession: false}) {
return this.getDraconicOuNaturel(options)
.find(it => true)
}
getConjurationNaturelle() {
@@ -145,7 +139,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
}
listActions({ isAttaque = false, isEquipe = false }) {
listActions() {
return this.itemTypes[ITEM_TYPES.competencecreature]
.filter(it => it.isAttaque())
.map(it => it.attaqueCreature())
@@ -156,7 +150,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
async remiseANeuf() { }
async ajoutExperience(rollData, hideChatMessage = 'show') { }
computeResumeBlessure() { return []}
computeResumeBlessure() { return [] }
countBlessures(filter = it => !it.isContusion()) { return 0 }
async santeIncDec(name, inc, isCritique) { }
@@ -169,10 +163,11 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
async finDeRoundSuppressionEffetsTermines(options) {
for (let effect of this.getEffects()) {
const effects = this.getEffects();
for (let effect of effects) {
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
await effect.delete();
ChatMessage.create({ content: `${this.getAlias()} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
await effect.delete()
await ChatMessage.create({ content: `${this.getAlias()} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` })
}
}
}
@@ -316,7 +311,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
const competence = this.getCompetence(compName);
const rollData = {
ids: { actorId: this.id },
type: { allowed: DEFAULT_ROLL_TYPES, current: PART_COMP },
type: { allowed: DEFAULT_ROLL_TYPES, current: ROLL_TYPE_COMP },
selected: {
carac: { key: caracName },
comp: { key: competence.name },
@@ -347,7 +342,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
});
}
/**
* Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue
* Méthode pour faire un jet prédéterminé sans ouvrir la fenêtre de dialogue
*
* @param {*} caracName code ou label de la caractéristique. On peut utiliser 'intel' pour Intellect.
* @param {*} compName nom de compétence ou nom abrégé.
* @param {*} diff difficulté (0 si undefined)
@@ -367,12 +363,13 @@ export class RdDBaseActorReve extends RdDBaseActor {
selectedCarac: carac,
competence: competence,
diffLibre: diff ?? 0,
current: { rollmode: { key: game.settings.get("core", "messageMode") } },
show: { title: options?.title ?? '' }
}
RollDataAjustements.calcul(rollData, this);
await RdDResolutionTable.rollData(rollData);
this.ajoutExperience(rollData);
await RdDResolutionTable.displayRollData(rollData, this)
await RdDRollResult.displayRollData(rollData, this)
return rollData.rolled;
}
@@ -383,7 +380,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
ids: { actorId: this.id },
type: {
allowed: DEFAULT_ROLL_TYPES,
current: PART_COMP,
current: ROLL_TYPE_COMP,
},
selected: {
diff: { type: DIFF.DEFAUT }
@@ -411,13 +408,33 @@ export class RdDBaseActorReve extends RdDBaseActor {
})
}
/* -------------------------------------------- */
async rollReveResistance(diff = -8) {
return await RollDialog.create(
{
ids: { actorId: this.id },
type: {
allowed: [ROLL_TYPE_REVE_RESISTANCE],
current: ROLL_TYPE_REVE_RESISTANCE,
resistance: true
},
selected: {
carac: { key: CARACS.REVE_ACTUEL, forced: true },
comp: { key: undefined, forced: true },
diff: { type: DIFF.DEFAUT, value: diff }
}
},
{
onRollDone: (dialog, roll) => RollDialog.onRollDoneClose(dialog, roll)
})
}
async rollReveActuel({ diff = 0, resistance = false }) {
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
type: {
allowed: [PART_COMP],
current: PART_COMP,
allowed: [ROLL_TYPE_REVE_RESISTANCE],
current: ROLL_TYPE_REVE_RESISTANCE,
resistance: resistance
},
selected: {
@@ -439,8 +456,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
const rollData = {
ids: { actorId: this.id },
type: {
allowed: options.resistance ? [PART_COMP] : DEFAULT_ROLL_TYPES,
current: PART_COMP,
allowed: options.resistance ? [ROLL_TYPE_COMP] : DEFAULT_ROLL_TYPES,
current: options.resistance ? ROLL_TYPE_COMP : ROLL_TYPE_COMP,
resistance: options.resistance
},
selected: {
@@ -508,7 +525,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
RdDPossession.onAttaquePossession(target, this, competence)
}
else {
RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme)
PasseArme.rddCombatTarget(target, this, token).attaque(competence, arme)
}
});
return
@@ -543,7 +560,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
return
}
RdDCombat.rddCombatTarget(target, this, token).attaqueV2();
PasseArme.rddCombatTarget(target, this, token).attaqueV2();
})
}
else {
@@ -607,7 +624,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
// TODO: vérifier si c'est possible, sinon simplifier
return RdDPossession.onAttaquePossession(target, this, comp);
}
RdDCombat.rddCombatTarget(target, this, token).attaque(comp, arme, maniement)
PasseArme.rddCombatTarget(target, this, token).attaque(comp, arme, maniement)
})
}
@@ -615,7 +632,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
RdDPossessionV2.rollAttaquePossession(this)
}
verifierForceMin(item) { }
async verifierForceMin(item) { }
/* -------------------------------------------- */
async encaisser() { await RdDEncaisser.encaisser(this) }
@@ -673,12 +690,12 @@ export class RdDBaseActorReve extends RdDBaseActor {
{ actor: this }))
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
encaissement = foundry.utils.duplicate(encaissement)
encaissement = foundry.utils.deepClone(encaissement)
encaissement.isGM = true
ChatMessage.create({
await ChatMessage.create({
whisper: ChatUtility.getGMs(),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.hbs', encaissement)
});
})
}
}
+6 -14
View File
@@ -17,19 +17,12 @@ import { CARACS } from "../rdd-carac.js";
*/
export class RdDBaseActorSang extends RdDBaseActorReve {
async _preUpdate(changed, options, user) {
const updatedEndurance = changed?.system?.sante?.endurance
if (updatedEndurance && options.diff) {
await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0)
}
}
prepareActorData() {
this.system.sante.vie.max = Math.ceil((this.getTaille() + this.getConstitution()) / 2)
this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max)
super.prepareActorData()
this.system.attributs.encombrement.value = this.getEncombrementMax()
return super._preUpdate(changed, options, user)
}
getCarac() {
@@ -109,7 +102,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
/* -------------------------------------------- */
async onAppliquerJetEncaissement(encaissement, attackerToken) {
const santeOrig = foundry.utils.duplicate(this.system.sante);
const santeOrig = foundry.utils.deepClone(this.system.sante);
const blessure = this.nouvelleBlessure(encaissement.gravite, {
localisation: encaissement.dmg?.loc.label ?? '',
origine: attackerToken?.name ?? ''
@@ -124,7 +117,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
await rollPerteEndurance.evaluate()
blessure.system.endurance = rollPerteEndurance.total
}
const isCritique = blessure.system.gravite >= 6;
const isCritique = blessure.system.gravite >= 6 || encaissement._reduireEndAZero;
if (isCritique) {
blessure.system.endurance = this.getEnduranceActuelle()
}
@@ -156,7 +149,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
if (!this.system.sante[name]) {
return
}
const sante = foundry.utils.duplicate(this.system.sante)
const sante = foundry.utils.deepClone(this.system.sante)
const compteur = sante[name]
const result = { sonne: false }
let perteEndurance = 0
@@ -351,11 +344,10 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
/* -------------------------------------------- */
async jetDeVie() {
if (this.isDead()) {
ChatMessage.create({
return await ChatMessage.create({
content: `Jet de Vie: ${this.getAlias()} est déjà mort, ce n'est pas la peine d'en rajouter !!!!!`,
whisper: ChatUtility.getOwners(this)
})
return
}
const jetDeVie = await RdDDice.roll("1d20");
const sConst = this.getSConst();
@@ -380,7 +372,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
else if (prochainJet > 0) {
msgText += `<br>Prochain jet de vie dans ${prochainJet} ${isCritique ? 'round' : 'minute'}${prochainJet > 1 ? 's' : ''} ${isCritique ? '(état critique)' : '(état grave)'}`
}
ChatMessage.create({
return await ChatMessage.create({
content: msgText,
whisper: ChatUtility.getOwners(this)
})
+31 -25
View File
@@ -91,7 +91,7 @@ export class RdDBaseActor extends Actor {
}
static getRealActor(actorId, tokenId) {
const actor = tokenId ? canvas.tokens.get(tokenId)?.actor : undefined
const actor = tokenId ? canvas?.tokens?.get(tokenId)?.actor : undefined
return actor ?? game.actors.get(actorId)
}
@@ -147,10 +147,8 @@ export class RdDBaseActor extends Actor {
return this.name
}
isPersonnageJoueur() { return false }
getCarac() {
return foundry.utils.duplicate(this.system.carac)
return foundry.utils.deepClone(this.system.carac)
}
findCaracByName(name) {
@@ -240,26 +238,23 @@ export class RdDBaseActor extends Actor {
renderAfterDelay(currentCounter) {
setTimeout(async () => {
if (currentCounter == this.refreshDelayCounter) {
this.sheet?.render(true)
this.sheet?.render()
this.refreshDelayCounter = 0
}
else {
this.renderAfterDelay(this.refreshDelayCounter)
}
}, 30)
}, 50)
}
/* -------------------------------------------- */
prepareData() {
super.prepareData()
this.prepareActorData()
this.cleanupConteneurs()
this.computeEtatGeneral()
this.computeEncTotal()
}
prepareActorData() { }
async computeEtatGeneral() { }
/* -------------------------------------------- */
@@ -267,6 +262,7 @@ export class RdDBaseActor extends Actor {
return game.users.players.find(player => player.active && player.character?.id == this.id);
}
isPersonnageJoueur() { return false }
isCreatureOuEntite() { return this.isCreature() || this.isEntite() }
isCreature() { return false }
isEntite() { return false }
@@ -384,8 +380,8 @@ export class RdDBaseActor extends Actor {
}
async onTimeChanging(oldTimestamp, newTimestamp) {
this.items.filter(it => it.isFinPeriode(oldTimestamp, newTimestamp))
.forEach(async it => await it.onFinPeriodeTemporel(oldTimestamp, newTimestamp))
await Promise.all(this.items.filter(it => it.isFinPeriode(oldTimestamp, newTimestamp))
.map(async it => await it.onFinPeriodeTemporel(oldTimestamp, newTimestamp)))
}
async creerObjetParMJ(object) {
@@ -405,7 +401,7 @@ export class RdDBaseActor extends Actor {
if (Misc.isOwnerPlayer(this)) {
let updates = this.itemTypes[ITEM_TYPES.conteneur]
.filter(c => c.system.contenu.filter(id => this.getItem(id) == undefined).length > 0)
.map(c => { return { _id: c._id, 'system.contenu': c.system.contenu.filter(id => this.getItem(id) != undefined) } });
.map(c => { return { _id: c.id, 'system.contenu': c.system.contenu.filter(id => this.getItem(id) != undefined) } });
if (updates.length > 0) {
await this.updateEmbeddedDocuments("Item", updates)
}
@@ -450,7 +446,7 @@ export class RdDBaseActor extends Actor {
msg = "Vous n'avez pas assez d'argent pour payer cette somme !";
}
ChatMessage.create({
await ChatMessage.create({
whisper: ChatUtility.getOwners(this),
content: msg
})
@@ -494,7 +490,7 @@ export class RdDBaseActor extends Actor {
await Monnaie.optimiserFortune(this, sols + this.getFortune());
RdDAudio.PlayContextAudio("argent"); // Petit son
ChatMessage.create({
await ChatMessage.create({
whisper: ChatUtility.getOwners(this),
content: `Vous avez reçu <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.`
})
@@ -546,9 +542,9 @@ export class RdDBaseActor extends Actor {
if (cout > 0) {
RdDAudio.PlayContextAudio("argent");
}
const chatAchatItem = foundry.utils.duplicate(achat.vente);
const chatAchatItem = foundry.utils.deepClone(achat.vente);
chatAchatItem.quantiteTotal = quantite;
ChatMessage.create({
await ChatMessage.create({
user: achat.userId,
speaker: { alias: (acheteur ?? vendeur).getAlias() },
whisper: ChatUtility.getOwners(this),
@@ -653,6 +649,7 @@ export class RdDBaseActor extends Actor {
else {
const wasSurenc = this.isSurenc()
this.encTotal = this.items.filter(it => RdDItem.getItemTypesInventaire().includes(it.type))
.filter(it => it.type !== ITEM_TYPES.conteneur)
.map(it => it.getEncTotal()).reduce(Misc.sum(), 0)
const isSurenc = this.isSurenc()
if (isSurenc != wasSurenc) {
@@ -712,8 +709,8 @@ export class RdDBaseActor extends Actor {
}
}
}
await this.computeEncTotal()
}
await this.computeEncTotal()
return result;
}
@@ -851,7 +848,7 @@ export class RdDBaseActor extends Actor {
sourceActor.buildSubConteneurObjetList(itemId, itemsList); // Get itemId list
const itemsDataToCreate = itemsList.map(it => sourceActor.getItem(it.id))
.map(it => foundry.utils.duplicate(it))
.map(it => foundry.utils.deepClone(it))
.map(it => { it.system.contenu = []; return it; });
let newItems = await this.createEmbeddedDocuments('Item', itemsDataToCreate);
@@ -893,19 +890,32 @@ export class RdDBaseActor extends Actor {
system: { description: this.system.description }
}
renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData)
.then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
.then(async html => await ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
}
actionImpossible(action) {
ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`)
}
async doRollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
}
ajoutExperience(rollData) { }
isAlcoolise() { return false }
async jetEthylisme() { this.actionImpossible("jet d'éthylisme") }
async rollAppelChance() { this.actionImpossible("appel à la chance") }
async jetDeMoral() { this.actionImpossible("jet de moral") }
async creerCopieLue(item) {
if (item.type !== ITEM_TYPES.livre) return
const existante = this.items.find(i => i.type === 'livre' && i.system.estCopieLue && i.name === item.name)
if (existante) return
const copie = item.toObject()
copie.system.estCopieLue = true
copie.system.lu = true
copie.system.quantite = 0
delete copie._id
await this.createEmbeddedDocuments('Item', [copie], { renderSheet: false })
}
async resetItemUse() { }
async incDecItemUse(itemId, shouldIncrease = true) { }
getItemUse(itemId) { return 0; }
@@ -914,11 +924,7 @@ export class RdDBaseActor extends Actor {
isActorCombat() { return false }
getCaracInit(competence) { return 0 }
listAttaques() {
return this.listActions({ isAttaque: true, isEquipe: false })
}
listActions({ isAttaque = false, isEquipe = false }) { return [] }
listActions() { return [] }
listActionsPossessions() {
return this.itemTypes[ITEM_TYPES.possession]
+1
View File
@@ -83,6 +83,7 @@ export class RdDEntite extends RdDBaseActorReve {
if (this.isEntiteNonIncarnee()) {
return
}
encaissement.isEntiteIncarnee = true
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance);
foundry.utils.mergeObject(encaissement, { resteEndurance: perteEndurance.newValue, endurance: perteEndurance.perte })
}
+138 -131
View File
@@ -5,26 +5,98 @@ import { RdDDice } from "../../rdd-dice.js";
import { RdDNameGen } from "../../rdd-namegen.js";
import { RdDTimestamp } from "../../time/rdd-timestamp.js";
const PATHS = [
'name',
'system.sexe',
'system.age',
'system.taille',
'system.poids',
'system.main',
'system.heure',
'system.cheveux',
'system.yeux'
]
const RANDOM_VALUES = {
'system.sexe': { 'masculin': 1, 'féminin': 1 },
'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 },
'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains': 3, 'châtain clair': 5, 'blonds': 4, 'blond platine': 1, 'roux carotte': 1, 'roux cuivré': 3, 'chauve': 1 },
'system.yeux': { 'noirs': 2, 'noisette': 3, 'brun-vert': 4, 'verts': 3, 'bleu clair': 3, 'bleu gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 },
async function randomFrom(values) {
const max = Object.values(values).reduce(Misc.sum(), 0)
const total = await RdDDice.rollTotal(`1d${max}`)
let sum = 0
for (let entry of Object.entries(values)) {
sum = sum + entry[1]
if (sum >= total) {
return entry[0]
}
}
return Object.keys(values)[0]
}
export class AppPersonnageAleatoire extends FormApplication {
async function randomTailleCm(taille) {
const infoTaille = RdDCarac.getCaracDerivee(taille)
const infoTailleSup = RdDCarac.getCaracDerivee(taille + 1)
const variation = (infoTailleSup.taille - infoTaille.taille) + Math.floor((infoTaille.poidsMax - infoTaille.poidsMin) / 2)
const base = infoTaille.taille
const total = await RdDDice.rollTotal(`1d${variation} -1d ${variation} + ${base}`)
const cm = total % 100
const dm = cm < 10 ? '0' : ''
const m = (total - cm) / 100
return `${m}m${dm}${cm}`
}
async function randomPoidsKg(taille) {
const infoTaille = RdDCarac.getCaracDerivee(taille)
const range = infoTaille.poidsMax - infoTaille.poidsMin + 1
const total = await RdDDice.rollTotal(`1d${range} + ${infoTaille.poidsMin}`)
return total + ' kg'
}
async function randomHeure() {
return RdDTimestamp.defHeure(await RdDDice.rollHeure({ rollMode: "self", showDice: SHOW_DICE })).key
}
const CONTROL_UNKNOWN = { name: 'unknown', path: '', getter: (act) => { undefined }, random: async act => undefined }
const TABLE_SEXES = { 'masculin': 1, 'féminin': 1 };
const TABLE_MAINS = { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 };
const TABLE_COULEURS_CHEVEUX = {
'noirs': 2,
'bruns': 5,
'châtains': 3,
'châtain clair': 5,
'blonds': 4,
'blond platine': 1,
'roux carotte': 1,
'roux cuivré': 3,
'chauve': 1
};
const TABLE_COULEURS_YEUX = {
'noirs': 2,
'noisette': 3,
'brun-vert': 4,
'verts': 3,
'bleu clair': 3,
'bleu gris': 2,
'gris': 1,
'mauves': 1,
'indigos': 1
};
const CONTROLS = [
{ name: 'name', path: 'name', getter: (act) => act.name, random: async act => await RdDNameGen.generate() },
{ name: 'sexe', path: 'system.sexe', getter: act => act.system.sexe, random: async act => await randomFrom(TABLE_SEXES) },
{ name: 'age', path: 'system.age', getter: act => act.system.age, random: async act => await RdDDice.rollTotal('(2d4kl)*10 + 1d7xo + 2d20kl') },
{ name: 'taille', path: 'system.taille', getter: act => act.system.taille, random: async act => await randomTailleCm(act.system.carac.taille.value) },
{ name: 'poids', path: 'system.poids', getter: act => act.system.poids, random: async act => await randomPoidsKg(act.system.carac.taille.value) },
{ name: 'main', path: 'system.main', getter: act => act.system.main, random: async act => await randomFrom(TABLE_MAINS) },
{ name: 'heure', path: 'system.heure', getter: act => act.system.heure, random: async act => await randomHeure() },
{ name: 'cheveux', path: 'system.cheveux', getter: act => act.system.cheveux, random: async act => await randomFrom(TABLE_COULEURS_CHEVEUX) },
{ name: 'yeux', path: 'system.yeux', getter: act => act.system.yeux, random: async act => await randomFrom(TABLE_COULEURS_YEUX) },
]
const { HandlebarsApplicationMixin } = foundry.applications.api;
export class AppPersonnageAleatoire extends HandlebarsApplicationMixin(foundry.applications.api.ApplicationV2) {
static PARTS = {
main: { template: "systems/foundryvtt-reve-de-dragon/templates/actor/random/app-personnage-aleatoire.hbs" }
}
static DEFAULT_OPTIONS = {
classes: ['app-personnage-aleatoire'],
window: {
title: "Génération aléatoire",
controls: []
},
position: {
width: 600,
height: 600
}
}
static preloadHandlebars() {
foundry.applications.handlebars.loadTemplates([
'systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs',
@@ -32,165 +104,100 @@ export class AppPersonnageAleatoire extends FormApplication {
])
}
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
template: "systems/foundryvtt-reve-de-dragon/templates/actor/random/app-personnage-aleatoire.hbs",
title: "Génération aléatoire",
width: 'fit-content',
height: 'fit-content',
classes: ['app-personnage-aleatoire'],
popOut: true,
resizable: true
}, { inplace: false })
}
constructor(actor) {
super({})
this.actor = actor
this.current = foundry.utils.duplicate(actor)
this.checked = {
'name': false,
'system.sexe': (this.actor.system.sexe ?? '') == '',
'system.age': this.actor.system.age == 0,
'system.taille': (this.actor.system.taille ?? '') == '',
'system.poids': (this.actor.system.poids ?? '') == '',
'system.main': (this.actor.system.main ?? '') == '',
'system.heure': (this.actor.system.heure ?? '') == '',
'system.cheveux': (this.actor.system.cheveux ?? '') == '',
'system.yeux': (this.actor.system.yeux ?? '') == '',
}
this.current = Object.fromEntries(CONTROLS.map(it => [it.name, it.getter(this.actor)]));
this.checked = Object.fromEntries(CONTROLS.map(it => [it.name, [0, '', undefined].includes(this.current[it.name])]))
}
async getData(options) {
return foundry.utils.mergeObject(await super.getData(options), {
_prepareContext() {
return {
actor: this.actor,
current: this.current,
checked: this.checked,
options: { isGM: game.user.isGM }
})
}
}
activateListeners(html) {
super.activateListeners(html)
this.html = html
this.html.find("button.button-cancel").click(async event => await this.close())
this.html.find("button.button-apply").click(async event => await this.onApply())
_onRender(context, options) {
super._onRender(context, options)
this.html = $(this.element)
this.html.find("input.current-value").change(async event => await this.onChange(event))
this.html.find("div.random-field[data-path='system.heure'] select.current-value").change(async event => await this.onChange(event))
this.html.find('a[data-action="sexe-masculin"]').click(async event => await this.onSexe('masculin'))
this.html.find('a[data-action="sexe-feminin"]').click(async event => await this.onSexe('féminin'))
this.html.find("a.random").click(async event => await this.onRandom(event))
this.html.find("a.reset").click(async event => await this.onReset(event))
this.html.find("a.randomize-selected").click(async event => await this.onRandomizeSelected())
this.html.find("input.check-for-random").click(async event => await this.onCheckForRandom(event))
this.html.find("div.random-field[data-field-name='heure'] select.current-value").change(async event => await this.onChange(event))
this.html.find('a[data-action="sexe-masculin"]').click(async event => await this.onSexe('masculin'))
this.html.find('a[data-action="sexe-feminin"]').click(async event => await this.onSexe('féminin'))
this.html.find("button.button-cancel").click(async event => await this.close())
this.html.find("button.button-apply").click(async event => await this.onApply())
}
async _updateObject(event, formData) { }
async onApply() {
const updates = Object.fromEntries(
PATHS.filter(path => game.user.isGM || path != 'name')
.map(path => [path, this.current[path]])
CONTROLS.filter(control => game.user.isGM || control.name != 'name')
.map(control => [control.path, this.current[control.name]])
)
await this.actor.update(updates)
await this.close()
}
getPath(selector) {
getName(selector) {
const fields = this.html.find(selector).parents("div.random-field:first")
return fields[0].attributes['data-path'].value
return fields[0].attributes['data-field-name'].value
}
getControl(name) {
return CONTROLS.find(it => it.name == name) ?? CONTROL_UNKNOWN
}
async onSexe(sexe) {
this.current['system.sexe'] = sexe
this.render()
this.current['sexe'] = sexe
this.render({ force: true })
}
async onChange(event) {
const path = this.getPath(event.currentTarget)
this.current[path] = event.currentTarget.value
const name = this.getName(event.currentTarget)
const control = this.getControl(name)
this.current[control.name] = event.currentTarget.value
this.render({ force: true })
}
async onRandom(event) {
const path = this.getPath(event.currentTarget)
await this.setRandom(path);
this.render()
const name = this.getName(event.currentTarget)
const control = this.getControl(name)
await this.randomControl(control)
this.render({ force: true })
}
async onReset(event) {
const path = this.getPath(event.currentTarget)
this.current[path] = this.actor[path]
await this.render()
const name = this.getName(event.currentTarget)
const control = this.getControl(name)
this.current[control.name] = control.getter(this.actor)
this.render({ force: true })
}
async onCheckForRandom(event) {
const path = this.getPath(event.currentTarget)
this.checked[path] = event.currentTarget.checked
this.render()
const name = this.getName(event.currentTarget)
this.checked[name] = event.currentTarget.checked
this.render({ force: true })
}
async onRandomizeSelected() {
const paths = this.html.find("input.check-for-random:checked")
const controls = this.html.find("input.check-for-random:checked")
.parents("div.random-field")
.toArray()
.map(it => it.attributes['data-path'].value)
await Promise.all(paths.map(path => this.setRandom(path)))
this.render()
.map(it => this.getControl(it.attributes['data-field-name'].value))
await Promise.all(controls.map(it => this.randomControl(it)))
this.render({ force: true })
}
async setRandom(path) {
this.current[path] = await this.random(path);
async randomControl(control) {
this.current[control.name] = await control.random(this.actor)
}
async random(path) {
switch (path) {
case 'name':
return await RdDNameGen.generate()
case 'system.sexe':
case 'system.main':
case 'system.cheveux':
case 'system.yeux':
return await this.randomFromMap(RANDOM_VALUES[path])
case 'system.poids':
return await this.randomPoids()
case 'system.taille':
return await this.randomTaille()
case 'system.age':
return await RdDDice.rollTotal('(2d4kl)*10 + 1d7xo + 2d20kl')
case 'system.heure':
return RdDTimestamp.defHeure(await RdDDice.rollHeure({ rollMode: "selfroll", showDice: SHOW_DICE })).key
}
return 'unknown'
}
async randomFromMap(valuesMap) {
const max = Object.values(valuesMap).reduce(Misc.sum(), 0)
const total = await RdDDice.rollTotal(`1d${max}`)
let sum = 0
for (let entry of Object.entries(valuesMap)) {
sum = sum + entry[1]
if (sum >= total) {
return entry[0]
}
}
return Object.keys(valuesMap)[0]
}
async randomPoids() {
const caracTaille = RdDCarac.getCaracDerivee(this.current.system.carac.taille.value)
const range = caracTaille.poidsMax - caracTaille.poidsMin + 1
const total = await RdDDice.rollTotal(`1d${range} + ${caracTaille.poidsMin}`)
return total + ' kg'
}
async randomTaille() {
const caracTaille = RdDCarac.getCaracDerivee(this.current.system.carac.taille.value)
const base = this.current.system.carac.taille.value * 2 + 60 + caracTaille.poidsMin
const variation = Math.floor((caracTaille.poidsMax - caracTaille.poidsMin + base / 5) / 2)
const total = await RdDDice.rollTotal(`2d${variation} + ${base}`)
const cm = total % 100
const dm = cm < 10 ? '0' : ''
const m = (total - cm) / 100
return `${m}m${dm}${cm}`
}
}
+52 -5
View File
@@ -1,5 +1,52 @@
export { default as RdDItemBaseSheet} from "./common-item-sheet.mjs"
export { default as RdDMonnaieSheet } from "./monnaie-sheet.mjs"
export { default as RdDMunitionSheet } from "./munition-sheet.mjs"
export { default as RdDTarotSheet } from "./tarot-sheet.mjs"
export { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
export { RdDCreatureSheetV2 } from "./creature-sheet.mjs"
export { RdDActorVehiculeSheetV2 } from "./vehicule-sheet.mjs"
export { RdDCommerceSheetV2 } from "./commerce-sheet.mjs"
export { RdDActorEntiteSheetV2 } from "./entite-sheet.mjs"
export { RdDActorSheetV2 } from "./personnage-sheet.mjs"
export { RdDActorExportSheetV2 } from "./export-encart-sheet.mjs"
export { default as RdDItemBaseSheet} from "./common-item-sheet.mjs"
export { default as RdDMonnaieSheet } from "./monnaie-sheet.mjs"
export { default as RdDMunitionSheet } from "./munition-sheet.mjs"
export { default as RdDTarotSheet } from "./tarot-sheet.mjs"
export { default as RdDTeteSheet } from "./tete-sheet.mjs"
export { default as RdDQueueSheet } from "./queue-sheet.mjs"
export { default as RdDSouffleSheet } from "./souffle-sheet.mjs"
export { default as RdDOmbreSheet } from "./ombre-sheet.mjs"
export { default as RdDChantSheet } from "./chant-sheet.mjs"
export { default as RdDMusiqueSheet } from "./musique-sheet.mjs"
export { default as RdDDanseSheet } from "./danse-sheet.mjs"
export { default as RdDJeuSheet } from "./jeu-sheet.mjs"
export { default as RdDRecetteAlchimiqueSheet } from "./recettealchimique-sheet.mjs"
export { default as RdDRecetteCuisineSheet } from "./recettecuisine-sheet.mjs"
export { default as RdDArmeSheet } from "./arme-sheet.mjs"
export { default as RdDArmureSheet } from "./armure-sheet.mjs"
export { default as RdDObjetSheet } from "./objet-sheet.mjs"
export { default as RdDConteneurSheet } from "./conteneur-sheet.mjs"
export { default as RdDNourritureBoissonSheet } from "./nourritureboisson-sheet.mjs"
export { default as RdDGemmeSheet } from "./gemme-sheet.mjs"
export { default as RdDServiceSheet } from "./service-sheet.mjs"
export { default as RdDTacheSheet } from "./tache-sheet.mjs"
export { default as RdDBlessureSheet } from "./blessure-sheet.mjs"
export { default as RdDMaladieSheet } from "./maladie-sheet.mjs"
export { default as RdDPoisonSheet } from "./poison-sheet.mjs"
export { default as RdDCompetenceSheet } from "./competence-sheet.mjs"
export { default as RdDCompetenceCreatureSheet } from "./competencecreature-sheet.mjs"
export { default as RdDPotionSheet } from "./potion-sheet.mjs"
export { default as RdDSigneDraconiqueSheet } from "./signedraconique-sheet.mjs"
export { default as RdDSortSheet } from "./sort-sheet.mjs"
export { default as RdDRaceSheet } from "./race-sheet.mjs"
export { default as RdDRencontreSheet } from "./rencontre-sheet.mjs"
export { default as RdDEmpoignadeSheet } from "./empoignade-sheet.mjs"
export { default as RdDPossessionSheet } from "./possession-sheet.mjs"
export { default as RdDLivreSheet } from "./livre-sheet.mjs"
export { default as RdDFauneSheet } from "./faune-sheet.mjs"
export { default as RdDHerbeSheet } from "./herbe-sheet.mjs"
export { default as RdDPlanteSheet } from "./plante-sheet.mjs"
export { default as RdDIngredientSheet } from "./ingredient-sheet.mjs"
export { default as RdDExtraitPoetiqueSheet } from "./extraitpoetique-sheet.mjs"
export { default as RdDNombreAstralSheet } from "./nombreastral-sheet.mjs"
export { default as RdDCaseTMRSheet } from "./casetmr-sheet.mjs"
export { default as RdDSortReserveSheet } from "./sortreserve-sheet.mjs"
export { default as RdDMeditationSheet } from "./meditation-sheet.mjs"
export { default as RdDOeuvreSheet } from "./oeuvre-sheet.mjs"
+92
View File
@@ -0,0 +1,92 @@
import { TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE } from "../../common/_module.mjs";
import { ITEM_TYPES, ACTOR_TYPES } from "../../constants.js";
import { SystemCompendiums } from "../../settings/system-compendiums.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDArmeSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.arme; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE]; }
static MORTALITE_CHOICES = {
mortel: "Mortel",
"non-mortel": "Non mortel",
empoignade: "Empoignade",
}
static CATEGORIE_PARADE_CHOICES = {
"sans-armes": "Sans arme",
"armes-naturelles": "Armes naturelles",
hast: "Armes d'hast",
batons: "Bâtons",
boucliers: "Boucliers",
dagues: "Dagues",
"epees-courtes": "Epées courtes",
"epees-longues": "Epées longues",
"epees-lourdes": "Epées lourdes",
haches: "Haches",
lances: "Lances",
masses: "Masses",
}
static INIT_CHOICES = {
hast: "Armes Hast",
lance: "Lance",
baton: "Bâton",
doubledragonne: "Double Dragonne",
esparlongue: "Esparlongue",
epeedragonne: "Epée Dragonne",
epeebatarde: "Epée Bâtarde",
epeecyane: "Epée Cyane",
epeesorde: "Epée Sorde",
grandehache: "Grande Hache",
hachebataille: "Hache de Bataille",
epeegnome: "Epée Gnome",
masse: "Masse",
gourdin: "Gourdin",
fleau: "Fléaux",
dague: "Dague",
armenaturelle: "Armes Naturelles",
autre: "Autres",
}
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "arme"],
position: { width: 448 },
window: { contentClasses: ["arme-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/arme.hbs",
},
};
async _prepareContext() {
const competences = (await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage))
.filter(it => it.isCompetenceArme())
const competenceMeleeChoices = {}
const competenceLancerChoices = {}
const competenceTirChoices = {}
competences.forEach(c => {
const label = c.name
switch (c.system.categorie) {
case 'melee': competenceMeleeChoices[label] = label; break
case 'lancer': competenceLancerChoices[label] = label; break
case 'tir': competenceTirChoices[label] = label; break
}
})
return Object.assign(
await super._prepareContext(),
{
competenceMeleeChoices,
competenceLancerChoices,
competenceTirChoices,
mortaliteChoices: RdDArmeSheet.MORTALITE_CHOICES,
categorieParadeChoices: RdDArmeSheet.CATEGORIE_PARADE_CHOICES,
initChoices: RdDArmeSheet.INIT_CHOICES,
}
);
}
}
@@ -0,0 +1,23 @@
import { TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDArmureSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.armure; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "armure"],
position: { width: 448 },
window: { contentClasses: ["armure-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/armure.hbs",
},
};
}
@@ -0,0 +1,460 @@
const { HandlebarsApplicationMixin } = foundry.applications.api
import { RdDUtility } from "../../rdd-utility.js"
import { Misc } from "../../misc.js"
import { DialogSplitItem } from "../../dialog-split-item.js"
import { RdDSheetUtility } from "../../rdd-sheet-utility.js"
import { Monnaie } from "../../item-monnaie.js"
import { ITEM_TYPES } from "../../constants.js"
import { RdDItem } from "../../item.js"
import { RdDTextEditor } from "../../apps/rdd-text-roll-editor.js"
import { ItemAction } from "../../item/item-actions.js"
import { DialogVerifierIngredients } from "../../dialog-verifier-ingredients.js"
import { DialogLancerRecette } from "../../dialog-lancer-recette.js"
import { ChatUtility } from "../../chat-utility.js"
import { RdDItemBlessure } from "../../item/blessure.js"
import { Grammar } from "../../grammar.js"
import { SYSTEM_RDD } from "../../constants.js"
export class RdDBaseActorSheetV2 extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
get actor() { return this.document }
// Was this.options.* — custom state
vueDetaillee = false
triEquipement = "name"
recherche = undefined
static TYPE = undefined
static DEFAULT_OPTIONS = {
classes: ["rdd", "sheet", "actor"],
position: { width: 640 },
form: { submitOnChange: true, closeOnSubmit: false },
window: { resizable: true, controls: [] },
actions: {
postToChat: RdDBaseActorSheetV2._onPostToChat,
},
}
//#region Registration
static register() {
foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, this, {
types: [this.TYPE],
makeDefault: true,
})
}
static async registerAll(...sheetClasses) {
const handlebars = []
sheetClasses.forEach(sheetClass => {
if (sheetClass.PARTS) {
Object.values(sheetClass.PARTS).forEach(part => {
if (part.template) handlebars.push(part.template)
})
}
sheetClass.register()
})
await foundry.applications.handlebars.loadTemplates(Misc.distinct(handlebars))
}
//#endregion
//#region Data
async _prepareContext() {
Monnaie.validerMonnaies(this.actor)
this.actor.computeEtatGeneral()
this._sheetOptions = foundry.utils.mergeObject(
RdDSheetUtility.mergeDocumentRights({ ...this.options }, this.actor, this.isEditable),
{ vueDetaillee: this.vueDetaillee, triEquipement: this.triEquipement, recherche: this.recherche },
{ inplace: false }
)
const ctx = {
title: this.title,
id: this.actor.id,
type: this.actor.type,
img: this.actor.img,
name: this.actor.name,
system: this.actor.system,
systemFields: this.actor.system.schema.fields,
description: await RdDTextEditor.enrichHTML(this.actor.system.description, this.actor),
notesmj: await RdDTextEditor.enrichHTML(this.actor.system.notesmj, this.actor),
options: this._sheetOptions,
effects: this.actor.effects,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
limited: this.actor.limited,
owner: this.actor.isOwner,
}
RdDUtility.filterItemsPerTypeForSheet(ctx, this.actor.itemTypes, this.triEquipement)
ctx.calc = {
fortune: Monnaie.toSolsDeniers(this.actor.getFortune()),
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
encTotal: this.actor.getEncTotal(),
}
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(ctx.conteneurs, ctx.inventaires)
this._appliquerRechercheObjets(ctx.conteneurs, ctx.inventaires)
ctx.conteneurs = RdDUtility.conteneursRacine(ctx.conteneurs)
ctx.competences.filter(it => it.type == ITEM_TYPES.competencecreature)
.forEach(it => it.isdommages = it.isDommages())
return ctx
}
_appliquerRechercheObjets(conteneurs, inventaires) {
if (this.recherche?.text) {
const recherche = this.recherche
const allVisible = inventaires.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id)
let addVisible = conteneurs.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id)
do {
allVisible.push(...addVisible)
const parentsIds = conteneurs.filter(it => it.system.contenu.find(id => allVisible.includes(id))).map(it => it.id)
addVisible = parentsIds.filter(id => !allVisible.includes(id))
}
while (addVisible.length > 0)
inventaires.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
conteneurs.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
}
else {
inventaires.forEach(it => it.system.isHidden = false)
conteneurs.forEach(it => it.system.isHidden = false)
}
}
//#endregion
//#region Rendering
async _renderFrame(options) {
const frame = await super._renderFrame(options)
return frame
}
async _onRender(context, options) {
await super._onRender(context, options)
this.html = $(this.element)
const nav = this.element.querySelector(".sheet-tabs")
if (nav) {
const tab = this.tabGroups?.primary || nav.querySelector("[data-tab]")?.dataset.tab
if (tab) this.changeTab(tab, "primary", { force: true })
}
this.html.find(".actionItem").click(async event => await ItemAction.onActionItem(event, this.actor, this._sheetOptions))
this.html.find(".item-edit").click(async event => await this._onItemEdit(event))
this.html.find(".item-verify-ingredients").click(async event => await this._onVerifyIngredients(event))
this.html.find(".item-lancer-recette").click(async event => await this._onLancerRecette(event))
this.html.find(".conteneur-name a").click(async event => {
RdDUtility.toggleAfficheContenu(this._getItemId(event))
this.render({ force: true })
})
this.html.find(".actor-montrer").click(async event => await this.actor.postActorToChat())
this.html.find(".recherche")
.each((_index, field) => this._rechercheSelectArea(field))
.keyup(async event => this._rechercherKeyup(event))
.change(async event => this._rechercherKeyup(event))
this.html.find(".recherche").prop("disabled", false)
this.html.find(".item-list .item").dblclick(async event => {
const item = this._getItem(event)
if (item) item.sheet.render({ force: true })
})
this.html.find(".tri-equipement").change(event => {
this.triEquipement = event.currentTarget.value
this.render({ force: true })
})
if (!this.isEditable) return
this.html.find(".item-equip-armure").click(async event => await this.actor.equiperObjet(this._getItem(event)))
this.html.find(".item-delete").click(async event => await RdDUtility.confirmActorItemDelete(this._getItem(event), this.actor))
this.html.find(".item-quantite-plus").click(async event => await this.actor.itemQuantiteIncDec(this._getItemId(event), 1))
this.html.find(".item-quantite-moins").click(async event => await this.actor.itemQuantiteIncDec(this._getItemId(event), -1))
this.html.find(".item-quantite").change(async event => {
const input = event.currentTarget
const item = this.actor.items.get(input.dataset.itemId)
if (item) {
const newQty = Math.max(0, parseInt(input.value) || 0)
await item.update({ "system.quantite": newQty })
if (newQty === 0) this.render({ force: true })
}
})
this.html.find(".item-quantite").on("contextmenu", async event => {
event.preventDefault()
const item = this._getItem(event)
if (!item?.isInventaire()) return
new foundry.applications.api.DialogV2({
title: `Quantité — ${item.name}`,
content: `<p>Réduire la quantité de :</p>
<select class="qty-amount">
<option value="1">1</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="all">Tout jeter</option>
</select>`,
buttons: [
{ action: "reduce", label: "Retirer", icon: "fa-solid fa-minus", callback: (event, button, dialog) => {
const amount = dialog.element.querySelector(".qty-amount").value
if (amount === "all") {
item.delete()
this.render({ force: true })
} else {
item.update({ "system.quantite": Math.max(0, item.system.quantite - parseInt(amount)) })
}
}},
],
}).render({ force: true })
})
this.html.find(".creer-un-objet").click(async event => await this._selectObjetTypeToCreate())
this.html.find(".nettoyer-conteneurs").click(async event => await this.actor.nettoyerConteneurs())
this.html.find(".quick-add-ration").click(async event => {
const existante = this.actor.items.find(it => it.type === "nourritureboisson" && it.name === "Ration")
if (existante) {
await existante.update({ "system.quantite": Math.max(0, Number(existante.system.quantite) + 1) })
} else {
await this.actor.createEmbeddedDocuments("Item", [{
name: "Ration", type: "nourritureboisson",
img: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
system: { sust: 1, encombrement: 0.1, quantite: 1, cout: 0.1, boisson: false },
}], { renderSheet: false })
}
this.render({ force: true })
})
this.html.find(".quick-add-eau").click(async event => {
const existante = this.actor.items.find(it => it.type === "nourritureboisson" && it.name === "Eau")
if (existante) {
await existante.update({ "system.quantite": Math.max(0, Number(existante.system.quantite) + 1) })
} else {
await this.actor.createEmbeddedDocuments("Item", [{
name: "Eau", type: "nourritureboisson",
img: "systems/foundryvtt-reve-de-dragon/icons/objets/outre.webp",
system: { desaltere: 1, encombrement: 0.1, quantite: 1, cout: 0.05, boisson: true },
}], { renderSheet: false })
}
this.render({ force: true })
})
this.html.find(".vue-detaillee").click(async event => {
this.vueDetaillee = !this.vueDetaillee
this.render({ force: true })
})
// Revel listeners (was base-actor-reve-sheet.js)
this.html.find(".button-encaissement").click(async event => await this.actor.encaisser())
this.html.find(".roll-carac").click(async event => {
await this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes["data-carac-name"].value))
})
this.html.find(".roll-competence").click(async event => await this.actor.rollCompetence(this._getItemId(event)))
this.html.find(".endurance-plus").click(async event => await this.actor.santeIncDec("endurance", 1))
this.html.find(".endurance-moins").click(async event => await this.actor.santeIncDec("endurance", -1))
if (game.user.isGM) {
this.html.find(".button-remise-a-neuf").click(async event => await this.actor.remiseANeuf())
this.html.find(".delete-active-effect").click(async event => await this.actor.removeEffect(this.html.find(event.currentTarget).parents(".active-effect").data("effect")))
this.html.find(".enlever-tous-effets").click(async event => await this.actor.removeEffects())
}
this.html.find(".competence-add").click(async event =>
await this.actor.createEmbeddedDocuments("Item", [{
type: ITEM_TYPES.competencecreature,
name: "Nouvelle competence",
img: "systems/foundryvtt-reve-de-dragon/icons/compcreature-serres.webp",
system: { carac_value: this.actor.getForce() },
}], { renderSheet: true })
)
this.html.find(".roll-text").click(async event => await RdDTextEditor.rollText(event, this.actor))
this.html.find(".chat-roll-text").click(async event => await RdDTextEditor.chatRollText(event))
if (this.vueDetaillee) {
this.html.find(".carac-value").change(async event => {
if (event.currentTarget.name.includes("carac.")) {
const caracName = event.currentTarget.name.replace("carac.", "")
await this.actor.updateCarac(caracName, parseInt(event.currentTarget.value))
}
})
this.html.find(".competence-value").change(async event => {
const compName = event.currentTarget.attributes.compname.value
await this.actor.updateCompetence(compName, parseInt(event.currentTarget.value))
})
}
// Sang listeners (was base-actor-sang-sheet.js)
this.html.find(".creer-blessure-legere").click(async event => await RdDItemBlessure.createBlessure(this.actor, 2))
this.html.find(".creer-blessure-grave").click(async event => await RdDItemBlessure.createBlessure(this.actor, 4))
this.html.find(".creer-blessure-critique").click(async event => await RdDItemBlessure.createBlessure(this.actor, 6))
this.html.find(".subir-blessure-contusion").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 0))
this.html.find(".subir-blessure-legere").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 2))
this.html.find(".subir-blessure-grave").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 4))
this.html.find(".subir-blessure-critique").click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 6))
this.html.find(".jet-vie").click(async event => await this.actor.jetDeVie())
this.html.find(".jet-endurance").click(async event => await this._jetEndurance())
this.html.find(".vie-plus").click(async event => await this.actor.santeIncDec("vie", 1))
this.html.find(".vie-moins").click(async event => await this.actor.santeIncDec("vie", -1))
}
async _jetEndurance() {
const endurance = this.actor.getEnduranceActuelle()
const result = await this.actor.jetEndurance(endurance)
await ChatMessage.create({
content: `Jet d'Endurance : ${result.jetEndurance} / ${endurance}
<br>${this.actor.name} a ${result.sonne ? "échoué" : "réussi"} son Jet d'Endurance ${result.sonne ? "et devient Sonné" : ""}`,
whisper: ChatUtility.getOwners(this.actor),
})
}
_rechercherKeyup(event) {
const currentTarget = event.currentTarget
const nouvelleRecherche = this._optionRecherche(currentTarget)
if (this.recherche?.text != nouvelleRecherche?.text) {
this.recherche = nouvelleRecherche
if (this._timerRecherche) clearTimeout(this._timerRecherche)
this._timerRecherche = setTimeout(() => {
this._timerRecherche = undefined
this.render({ force: true })
}, 500)
}
}
_rechercheSelectArea(field) {
if (this.recherche) {
field.focus()
field.setSelectionRange(this.recherche.start, this.recherche.end)
}
}
_optionRecherche(target) {
if (!target.value?.length) return undefined
return {
text: target.value,
start: target.selectionStart,
end: target.selectionEnd,
}
}
//#endregion
//#region Drop
async _onDropItem(event, item) {
const destItemId = this.html.find(event.target)?.closest(".item").attr("data-item-id")
const previousItemIds = new Set(this.actor.items.keys())
const dropParams = await RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, { uuid: item.uuid }, this.objetVersConteneur)
if (dropParams) {
const callSuper = await this.actor.processDropItem(dropParams)
if (callSuper) {
await super._onDropItem(event, item)
}
if (destItemId && dropParams.sourceActorId !== this.actor.id) {
const container = this.actor.items.get(destItemId)
if (container?.isConteneur()) {
const dropped = [...this.actor.items].find(i => !previousItemIds.has(i.id))
if (dropped && !this.actor.findConteneur(dropped)) {
await this.actor.ajouterDansConteneur(dropped, container, () => {})
}
}
}
}
}
async _onDropActor(event, actor) {
this.actor.addSubActeur(actor)
await super._onDropActor(event, actor)
}
//#endregion
//#region Helpers
_getItemId(event) {
return RdDSheetUtility.getItemId(event)
}
_getItem(event) {
return RdDSheetUtility.getItem(event, this.actor)
}
async _onItemEdit(event) {
const item = this._getItem(event)
if (item) item.sheet.render({ force: true })
}
async _onVerifyIngredients(event) {
event.preventDefault()
const item = this._getItem(event)
if (!item || item.type !== ITEM_TYPES.recettealchimique) return
DialogVerifierIngredients.create(item, this.actor)
}
async _onLancerRecette(event) {
event.preventDefault()
const item = this._getItem(event)
if (!item || item.type !== ITEM_TYPES.recettealchimique) return
const ingredients = Misc.safeJsonParse(item.system.ingredients, [])
if (!ingredients.length) {
ui.notifications.warn("Cette recette n'a pas d'ingrédients définis.")
return
}
DialogLancerRecette.create(item, this.actor)
}
//#endregion
//#region Actions
static async _onPostToChat(event, target) {
await this.actor.postActorToChat()
}
//#endregion
//#region Item operations
async _selectObjetTypeToCreate() {
const types = this._getTypesInventaire().sort(Misc.ascending(type => Misc.typeName("Item", type)))
let content = `<span class="generic-label">Selectionnez le type d'équipement</span><select class="item-type">`
for (const typeName of types) {
content += `<option value="${typeName}">${Misc.typeName("Item", typeName)}</option>`
}
content += "</select>"
new foundry.applications.api.DialogV2({
title: "Créer un équipement",
content,
buttons: [
{ action: "create", label: "Créer l'objet", icon: "fa-solid fa-check", callback: () => this.actor.createItem($(".item-type").val()) },
],
}).render({ force: true })
}
_getTypesInventaire() {
return RdDItem.getItemTypesInventaire()
}
async splitItem(item) {
const dialog = await DialogSplitItem.create(item, (it, split) => this._onSplitItem(it, split))
dialog.render({ force: true })
}
async _onSplitItem(item, split) {
if (split >= 1 && split < item.system.quantite) {
await item.diminuerQuantite(split)
const splitItem = foundry.utils.deepClone(item)
splitItem.system.quantite = split
await this.actor.createEmbeddedDocuments("Item", [splitItem])
}
}
vendre(item) {
item?.proposerVente(this.actor.getQuantiteDisponible(item))
}
//#endregion
}
@@ -0,0 +1,17 @@
import { TEMPLATE_DESCRIPTION } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDBlessureSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.blessure; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{ classes: ["fvtt-rdd", "item", "blessure"], position: { width: 448 }, window: { contentClasses: ["blessure-content"] } });
static PARTS = {
main: { template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/blessure.hbs" },
};
}
@@ -0,0 +1,23 @@
import { TEMPLATE_DESCRIPTION } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDCaseTMRSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.casetmr; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "casetmr"],
position: { width: 448 },
window: { contentClasses: ["casetmr-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/casetmr.hbs",
},
};
}
@@ -0,0 +1,26 @@
import { TEMPLATE_DESCRIPTION } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
import { CommonAppreciable } from "../../common/appreciable.mjs";
const TEMPLATE_APPRECIABLE = new CommonAppreciable();
export default class RdDChantSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.chant; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_APPRECIABLE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "chant"],
position: { width: 448 },
window: { contentClasses: ["chant-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/chant.hbs",
},
};
}
@@ -0,0 +1,52 @@
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
import { RdDItem } from "../../item.js"
import { ACTOR_TYPES } from "../../constants.js"
export class RdDCommerceSheetV2 extends RdDBaseActorSheetV2 {
static TYPE = ACTOR_TYPES.commerce
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
position: { width: 600, height: 720 },
})
static PARTS = {
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.hbs" },
}
get title() {
if (this.actor.token && this.actor.token !== this.actor.prototypeToken) {
return this.actor.token.name
}
return super.title
}
async _prepareContext() {
const ctx = await super._prepareContext()
if (this.actor.token && this.actor.token !== this.actor.prototypeToken) {
foundry.utils.mergeObject(ctx, {
title: this.actor.token.name,
token: { img: this.actor.token.texture.src },
}, { overwrite: true })
}
return ctx
}
async _onRender(context, options) {
await super._onRender(context, options)
if (!this.isEditable) return
this.html.find("input.item-quantite").change(async event => {
const newQuantite = Math.max(0, Number.parseInt(this.html.find(event.currentTarget).val()))
await this._getItem(event)?.update({ "system.quantite": newQuantite })
})
this.html.find("input.item-cout").change(async event => {
const newCout = Math.max(0, Number(this.html.find(event.currentTarget).val()))
await this._getItem(event)?.update({ "system.cout": newCout })
})
}
_getTypesInventaire() {
return RdDItem.getItemTypesInventaire("all")
}
}
@@ -18,7 +18,7 @@ export default class RdDItemBaseSheet extends HandlebarsApplicationMixin(foundry
static register(sheetClass) {
const itemType = sheetClass.ITEM_TYPE
Items.registerSheet(SYSTEM_RDD, sheetClass, {
foundry.documents.collections.Items.registerSheet(SYSTEM_RDD, sheetClass, {
label: Misc.typeName('Item', itemType),
types: [itemType],
makeDefault: true
@@ -63,13 +63,15 @@ export default class RdDItemBaseSheet extends HandlebarsApplicationMixin(foundry
resizable: true,
},
actions: {
editImage: RdDItemBaseSheet.#onEditImage,
editImage: RdDItemBaseSheet._onEditImage,
postToChat: RdDItemBaseSheet._onPostToChat,
proposerVente: RdDItemBaseSheet._onProposerVente,
}
}
/** @override */
async _prepareContext() {
return {
const ctx = {
item: this.document,
options: RdDSheetUtility.getOptions(this.document, this.isEditable),
fields: this.document.schema.fields,
@@ -77,7 +79,12 @@ export default class RdDItemBaseSheet extends HandlebarsApplicationMixin(foundry
system: this.document.system,
source: this.document.toObject(),
isEditable: this.isEditable,
canVendre: this.document.isInventaire?.() && this.document.isVideOuNonConteneur?.(),
}
for (const tpl of this.constructor.TEMPLATES) {
Object.assign(ctx, await tpl.prepareContext(this.document))
}
return ctx
}
// #region Actions
@@ -91,7 +98,7 @@ export default class RdDItemBaseSheet extends HandlebarsApplicationMixin(foundry
* @returns {Promise}
* @private
*/
static async #onEditImage(event, target) {
static async _onEditImage(event, target) {
const attr = target.dataset.edit
const current = foundry.utils.getProperty(this.document, attr)
const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}
@@ -107,5 +114,40 @@ export default class RdDItemBaseSheet extends HandlebarsApplicationMixin(foundry
})
return fp.browse()
}
static async _onPostToChat(event, target) {
await this.document.postItemToChat()
}
static async _onProposerVente(event, target) {
await this.document.proposerVente(1)
}
/** @override */
async _renderFrame(options) {
const frame = await super._renderFrame(options)
const header = frame.querySelector(".window-header")
if (header) {
const closeBtn = header.querySelector("button[data-action=close]")
const chatBtn = document.createElement("button")
chatBtn.type = "button"
chatBtn.className = "header-control icon fa-solid fa-comment"
chatBtn.dataset.action = "postToChat"
chatBtn.dataset.tooltip = "Poster dans le chat"
chatBtn.ariaLabel = "Poster dans le chat"
header.insertBefore(chatBtn, closeBtn)
if (this.document.isInventaire?.() && this.document.isVideOuNonConteneur?.()) {
const sellBtn = document.createElement("button")
sellBtn.type = "button"
sellBtn.className = "header-control icon fa-solid fa-comments-dollar"
sellBtn.dataset.action = "proposerVente"
sellBtn.dataset.tooltip = "Proposer à la vente"
sellBtn.ariaLabel = "Proposer à la vente"
header.insertBefore(sellBtn, chatBtn)
}
}
return frame
}
// #endregion
}
@@ -0,0 +1,17 @@
import { TEMPLATE_DESCRIPTION } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDCompetenceSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.competence; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{ classes: ["fvtt-rdd", "item", "competence"], position: { width: 448 }, window: { contentClasses: ["competence-content"] } });
static PARTS = {
main: { template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/competence.hbs" },
};
}
@@ -0,0 +1,17 @@
import { TEMPLATE_DESCRIPTION } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDCompetenceCreatureSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.competencecreature; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{ classes: ["fvtt-rdd", "item", "competencecreature"], position: { width: 448 }, window: { contentClasses: ["competencecreature-content"] } });
static PARTS = {
main: { template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/competencecreature.hbs" },
};
}
@@ -0,0 +1,31 @@
import { TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDConteneurSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.conteneur; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "conteneur"],
position: { width: 448 },
window: { contentClasses: ["conteneur-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/conteneur.hbs",
},
};
async _prepareContext() {
return Object.assign(
await super._prepareContext(),
{
actorId: this.document.parent?.id,
}
);
}
}
@@ -0,0 +1,33 @@
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
import { ACTOR_TYPES } from "../../constants.js"
export class RdDCreatureSheetV2 extends RdDBaseActorSheetV2 {
static TYPE = ACTOR_TYPES.creature
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
position: { width: 640, height: 720 },
})
static PARTS = {
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.hbs" },
}
async _onRender(context, options) {
await super._onRender(context, options)
if (!this.isEditable) return
this.html.find(".creature-carac").change(async event => {
const compName = event.currentTarget.attributes.compname.value
await this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value))
})
this.html.find(".creature-niveau").change(async event => {
const compName = event.currentTarget.attributes.compname.value
await this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value))
})
this.html.find(".creature-dommages").change(async event => {
const compName = event.currentTarget.attributes.compname.value
await this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value))
})
}
}
@@ -0,0 +1,34 @@
import { TEMPLATE_DESCRIPTION } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
import { CommonAppreciable } from "../../common/appreciable.mjs";
const TEMPLATE_APPRECIABLE = new CommonAppreciable();
export default class RdDDanseSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.danse; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_APPRECIABLE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "danse"],
position: { width: 448 },
window: { contentClasses: ["danse-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/danse.hbs",
},
};
async _prepareContext() {
return Object.assign(
await super._prepareContext(),
{
typeChoices: { recreative: "Récreative", soliste: "Soliste" },
}
);
}
}
@@ -0,0 +1,17 @@
import { TEMPLATE_DESCRIPTION } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDEmpoignadeSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.empoignade; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{ classes: ["fvtt-rdd", "item", "empoignade"], position: { width: 448 }, window: { contentClasses: ["empoignade-content"] } });
static PARTS = {
main: { template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/empoignade.hbs" },
};
}
@@ -0,0 +1,81 @@
import { RdDBaseActorSheetV2 } from "./base-actor-sheet.mjs"
import { RdDSheetUtility } from "../../rdd-sheet-utility.js"
import { RdDUtility } from "../../rdd-utility.js"
import { DialogSelect } from "../../dialog-select.js"
import { ACTOR_TYPES } from "../../constants.js"
export class RdDActorEntiteSheetV2 extends RdDBaseActorSheetV2 {
static TYPE = ACTOR_TYPES.entite
static DEFAULT_OPTIONS = Object.assign({}, RdDBaseActorSheetV2.DEFAULT_OPTIONS, {
position: { width: 640, height: 720 },
})
static PARTS = {
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.hbs" },
}
async _prepareContext() {
const ctx = await super._prepareContext()
ctx.niveau = this.actor.getNiveau()
const { niveau: _, ...caracRest } = ctx.system.carac
ctx.system = { ...ctx.system, carac: caracRest }
ctx.resonances = this.actor.system.sante.resonnance.actors
.map(actorId => game.actors.get(actorId))
.filter(actor => actor != undefined)
.map(actor => ({ id: actor.id, name: actor.name, img: actor.img }))
return ctx
}
async _onRender(context, options) {
await super._onRender(context, options)
if (!this.isEditable) return
this.html.find(".creature-carac").change(async event => {
const compName = event.currentTarget.attributes.compname.value
await this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value))
})
this.html.find(".creature-dommages").change(async event => {
const compName = event.currentTarget.attributes.compname.value
await this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value))
})
this.html.find(".resonance-add").click(async event =>
await DialogSelect.select({
label: "Choisir un acteur à accorder",
list: game.actors.filter(it => true),
},
it => this._resonanceAdd(it.id))
)
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.confirmSubActeurDelete(this, actorResonance, li, () => {
this._resonanceDelete(actorId)
RdDUtility.slideOnDelete(this, li)
})
}
})
}
async _onDropActor(event, dragData) {
const dropActor = fromUuidSync(dragData.uuid)
await this.actor.setEntiteReveAccordee(dropActor)
await super._onDropActor(event, dragData)
}
async _resonanceAdd(actorId) {
const newResonances = [...this.actor.system.sante.resonnance.actors, actorId]
await this.actor.update({ "system.sante.resonnance.actors": newResonances })
}
async _resonanceDelete(actorId) {
console.log("Delete : ", actorId)
const newResonances = this.actor.system.sante.resonnance.actors.filter(id => id !== actorId)
await this.actor.update({ "system.sante.resonnance.actors": newResonances }, { render: false })
}
}
@@ -0,0 +1,118 @@
import { RdDActorSheetV2 } from "./personnage-sheet.mjs"
import { SYSTEM_RDD } from "../../constants.js"
import { Misc } from "../../misc.js"
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js"
import { ExportScriptarium } from "../../actor/export-scriptarium/export-scriptarium.js"
import { CATEGORIES_COMPETENCES_BASE, CATEGORIES_DRACONIC, Mapping } from "../../actor/export-scriptarium/mapping.js"
export class RdDActorExportSheetV2 extends RdDActorSheetV2 {
static TYPE = "personnage"
static DEFAULT_OPTIONS = Object.assign({}, RdDActorSheetV2.DEFAULT_OPTIONS, {
position: { width: 550 },
})
static PARTS = {
form: { template: "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/actor-encart-sheet.hbs" },
}
showCompNiveauBase = false
vueArchetype = false
static async init() {
await foundry.applications.handlebars.loadTemplates([
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme-titre.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-compteur.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac-derivee-compteur.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/competences.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/esquive.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/fatigue.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/protection.hbs",
"systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/sort.hbs",
])
}
static register() {
foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, this, {
types: ["personnage"],
makeDefault: false,
label: "Feuille simplifiée",
})
}
async _prepareContext() {
const ctx = await super._prepareContext()
ctx.context = Mapping.prepareContext(this.actor)
ctx.attaques = this.actor.listActionsAttaque()
ctx.export = this._getMappingValues(ctx.context, this.actor)
ctx.competences = this._getCompetences(CATEGORIES_COMPETENCES_BASE)
ctx.draconic = this._getCompetences(CATEGORIES_DRACONIC)
const legeres = this.actor.countBlessures(it => it.isLegere())
const graves = this.actor.countBlessures(it => it.isGrave())
const critiques = this.actor.countBlessures(it => it.isCritique())
ctx.etat = {
surenc: this.actor.computeMalusSurEncombrement(),
fatigue: {
value: this.actor.getFatigueActuelle(),
max: this.actor.getFatigueMax(),
malus: this.actor.malusFatigue(),
},
blessures: legeres + graves + critiques,
blessure: [legeres > 0, legeres > 1, legeres > 2, legeres > 3, legeres > 4, graves > 0, graves > 1, critiques > 0],
}
ctx.options.exportScriptarium = OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM)
return ctx
}
_getMappingValues(context, actor) {
return Object.fromEntries(Mapping.getMapping().map(it => [it.column, {
colName: it.colName ?? it.column,
column: it.column,
rollClass: it.rollClass,
value: String(it.getter(actor, context)),
}]))
}
_getCompetences(categories) {
const competences = Mapping.getCompetencesCategorie(this.actor, categories)
if (competences.length == 0) return ""
const byCategories = Mapping.competencesByCategoriesByNiveau(competences, categories)
const listByCategories = Object.values(byCategories)
.map(it => it.competencesParNiveau)
.map(byNiveau => {
const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending())
if (niveaux.length == 0) return undefined
const listCategorieByNiveau = niveaux.map(niveau => {
const list = byNiveau[niveau].sort(Misc.ascending(it => it.name))
return { niveau, list }
})
return Misc.concat(listCategorieByNiveau)
}).filter(it => it != undefined)
return Misc.concat(listByCategories)
}
async _onRender(context, options) {
await super._onRender(context, options)
this.html.find(".click-blessure-remove").click(async event =>
await this.actor.supprimerBlessure({
gravite: this.html.find(event.currentTarget).data("gravite"),
})
)
this.html.find(".click-blessure-add").click(async event => {
const blessure = this.actor.nouvelleBlessure(this.html.find(event.currentTarget).data("gravite"))
await this.actor.createEmbeddedDocuments("Item", [blessure])
})
this.html.find(".button-export").click(async event => await
ExportScriptarium.INSTANCE.exportActors([this.actor],
`${this.actor.uuid}-${this.actor.name}`
)
)
}
}
@@ -0,0 +1,21 @@
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDExtraitPoetiqueSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.extraitpoetique; }
static get TEMPLATES() { return []; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "extraitpoetique"],
position: { width: 448 },
window: { contentClasses: ["extraitpoetique-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/extraitpoetique.hbs",
},
};
}
@@ -0,0 +1,23 @@
import { TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE, TEMPLATE_COMESTIBLE } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDFauneSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.faune; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE, TEMPLATE_COMESTIBLE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "faune"],
position: { width: 448 },
window: { contentClasses: ["faune-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/faune.hbs",
},
};
}
@@ -0,0 +1,64 @@
import { TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import { RdDItemGemme } from "../../item/gemme.js";
import { RdDTimestamp } from "../../time/rdd-timestamp.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDGemmeSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.gemme; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "gemme"],
position: { width: 448 },
window: { contentClasses: ["gemme-content"] },
actions: {
enchanter: RdDGemmeSheet.#onEnchanter,
},
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/gemme.hbs",
},
};
async _prepareContext() {
const item = this.document
const enchantement = RdDTimestamp.splitIndexDate(item.system.prdate)
return Object.assign(
await super._prepareContext(),
{
gemmeTypeList: RdDItemGemme.getGemmeTypeOptionList(),
isEnchantementPossible: item.isEnchantementPossible,
dateActuelle: game.system.rdd.calendrier.dateCourante(),
enchantement,
}
);
}
_onChangeForm(event, formData) {
const obj = formData?.object
if (!obj) return super._onChangeForm(event, formData)
if (event.target?.classList?.contains('date-enchantement')) {
const jour = Number(this.element?.querySelector('input.date-enchantement[name="enchantement.jour"]')?.value)
const moisEl = this.element?.querySelector('select.date-enchantement[name="enchantement.mois"]')
if (moisEl) {
const mois = RdDTimestamp.definition(moisEl.value)
const indexDate = game.system.rdd.calendrier.getIndexFromDate(jour, mois.heure)
obj['system.prdate'] = indexDate
delete obj['enchantement.jour']
delete obj['enchantement.mois']
}
}
return super._onChangeForm(event, formData)
}
static async #onEnchanter(event, target) {
const { DialogEnchanter } = await import("../../enchantement/dialog-enchanter.js")
DialogEnchanter.enchanter(this.document)
}
}
@@ -0,0 +1,42 @@
import { TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE, TEMPLATE_COMESTIBLE } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDHerbeSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.herbe; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE, TEMPLATE_COMESTIBLE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "herbe"],
position: { width: 448 },
window: { contentClasses: ["herbe-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/herbe.hbs",
},
};
async _prepareContext() {
const ctx = await super._prepareContext()
ctx.isBrut = this.document.getUtilisationCuisine() === 'brut'
return ctx
}
async _onRender(context, options) {
await super._onRender(context, options)
this.element.querySelector('.preparer-nourriture')?.addEventListener('click', async () => {
const actor = this.document.parent
if (actor) await actor.preparerNourriture(this.document)
})
this.element.querySelector('.manger-nourriture')?.addEventListener('click', async () => {
const actor = this.document.parent
if (actor) await actor.mangerNourriture(this.document)
})
}
}
@@ -0,0 +1,42 @@
import { TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE, TEMPLATE_COMESTIBLE } from "../../common/_module.mjs";
import { ITEM_TYPES } from "../../constants.js";
import RdDItemBaseSheet from "./common-item-sheet.mjs";
export default class RdDIngredientSheet extends RdDItemBaseSheet {
static get ITEM_TYPE() { return ITEM_TYPES.ingredient; }
static get TEMPLATES() { return [TEMPLATE_DESCRIPTION, TEMPLATE_INVENTAIRE, TEMPLATE_COMESTIBLE]; }
static DEFAULT_OPTIONS = Object.assign({},
RdDItemBaseSheet.DEFAULT_OPTIONS,
{
classes: ["fvtt-rdd", "item", "ingredient"],
position: { width: 448 },
window: { contentClasses: ["ingredient-content"] },
});
static PARTS = {
main: {
template: "systems/foundryvtt-reve-de-dragon/templates/sheets/item/ingredient.hbs",
},
};
async _prepareContext() {
const ctx = await super._prepareContext()
ctx.isBrut = this.document.getUtilisationCuisine() === 'brut'
return ctx
}
async _onRender(context, options) {
await super._onRender(context, options)
this.element.querySelector('.preparer-nourriture')?.addEventListener('click', async () => {
const actor = this.document.parent
if (actor) await actor.preparerNourriture(this.document)
})
this.element.querySelector('.manger-nourriture')?.addEventListener('click', async () => {
const actor = this.document.parent
if (actor) await actor.mangerNourriture(this.document)
})
}
}

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