forked from public/foundryvtt-reve-de-dragon
		
	Compare commits
	
		
			40 Commits
		
	
	
		
			12.0.32
			...
			9fc21e6d97
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9fc21e6d97 | |||
| ce7f5381ca | |||
| 48acdaaca6 | |||
| 425c6af672 | |||
| 4281f76dfb | |||
| 8ebd6ec771 | |||
| 14391daa0b | |||
| ac29e1410e | |||
| 442ffe9b3a | |||
| d922e4fdd5 | |||
| a8dc07b4db | |||
| 40a47ee8a2 | |||
| c5633a9fc5 | |||
| 7e8da49912 | |||
| b524716ede | |||
| 72a9752820 | |||
| 8e578c6566 | |||
| 5ac9c682d9 | |||
| 6de19eb357 | |||
| 90d096a6df | |||
| c733644f3a | |||
| de9d3bbb48 | |||
| efdffd171c | |||
| 8406c8434a | |||
| a4b474970c | |||
| 135e5e46a0 | |||
| 969bc3b573 | |||
| a9eb101c9d | |||
| d53da1f011 | |||
| ab0f7e563f | |||
| 57c41a0218 | |||
| 1b75decb18 | |||
| 551438f514 | |||
| 792558ac84 | |||
| 06aff9a3c0 | |||
| 7e736a00d7 | |||
| b87f406093 | |||
| 785bd4b9ce | |||
| daca86b1df | |||
| aa52e26e1a | 
							
								
								
									
										24
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,4 +1,28 @@ | |||||||
| # 12.0 | # 12.0 | ||||||
|  | ## 12.0.36 - La cartte d'Astrobazzarh | ||||||
|  | - Fix: la commande /tmra fonctionne correctement sans paramètres | ||||||
|  |  | ||||||
|  | ## 12.0.35 - La Solution d'Astrobazzarh | ||||||
|  | - Fix problème d'initialisation des feuilles d'items | ||||||
|  |  | ||||||
|  | ## 12.0.34 - la tête d'Astrobazzarh | ||||||
|  | - support de liens "jets de dés" | ||||||
|  |   - on peut ajouter des liens "jet de dés" dans les journaux, descriptions, notes, maladresses, ... | ||||||
|  |   - avec la syntaxe `@roll[...]` on peut ajouter le lien vers: | ||||||
|  |     - un jet de caractéristique/compétence `@roll[carac/competence/difficulte]` / `@roll[carac/difficulte]` / `@roll[carac/competence]`  | ||||||
|  |     - une formule foundry `@roll[2d6]` pour lancer 2d6  | ||||||
|  |     - une manipulation alchimique `@roll[couleur vert-bleu]` | ||||||
|  |   - les liens "jet avec caractéristiques" s'appliquent: | ||||||
|  |     - à tous les tokens sélectionnés | ||||||
|  |     - sinon, à l'acteur propriétaire (dans le cas d'un Item) ou à l'acteur courant | ||||||
|  |     - sinon, au personnage du joueur | ||||||
|  |   - on peut poster les liens dans le tchat pour proposer un jet aux joueurs | ||||||
|  | - gestion des blocs secrets dans les descriptions | ||||||
|  |  | ||||||
|  | ## 12.0.33 - la vieillesse d'Astrobazzarh | ||||||
|  | - retour de l'expérience pour les joueurs | ||||||
|  | - suppression du message "Pas de caractéristique" sur les jets d'odorat-goût | ||||||
|  |  | ||||||
| ## 12.0.32 - les rêveries d'Astrobazzarh | ## 12.0.32 - les rêveries d'Astrobazzarh | ||||||
| - Ajout des Items Race pour gérer les ajustements liés aux races | - Ajout des Items Race pour gérer les ajustements liés aux races | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,13 +12,15 @@ import { RdDSheetUtility } from "./rdd-sheet-utility.js"; | |||||||
| import { STATUSES } from "./settings/status-effects.js"; | import { STATUSES } from "./settings/status-effects.js"; | ||||||
| import { MAINS_DIRECTRICES } from "./actor.js"; | import { MAINS_DIRECTRICES } from "./actor.js"; | ||||||
| import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js"; | import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js"; | ||||||
| import { ITEM_TYPES, RdDItem } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
|  | import { RdDItem } from "./item.js"; | ||||||
| import { RdDItemBlessure } from "./item/blessure.js"; | import { RdDItemBlessure } from "./item/blessure.js"; | ||||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||||
| import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js"; | import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js"; | ||||||
| import { RdDCoeur } from "./coeur/rdd-coeur.js"; | import { RdDCoeur } from "./coeur/rdd-coeur.js"; | ||||||
| import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"; | import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"; | ||||||
| import { RdDItemRace } from "./item/race.js"; | import { RdDItemRace } from "./item/race.js"; | ||||||
|  | import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| /** | /** | ||||||
| @@ -44,8 +46,8 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       cssClass: this.isEditable ? "editable" : "locked", |       cssClass: this.isEditable ? "editable" : "locked", | ||||||
|       limited: this.actor.limited, |       limited: this.actor.limited, | ||||||
|       owner: this.actor.isOwner, |       owner: this.actor.isOwner, | ||||||
|       biographie: await TextEditor.enrichHTML(this.actor.system.biographie, { async: true }), |       biographie: await RdDTextEditor.enrichHTML(this.actor.system.biographie, this.actor), | ||||||
|       notes: await TextEditor.enrichHTML(this.actor.system.notes, { async: true }), |       notes: await RdDTextEditor.enrichHTML(this.actor.system.notes, this.actor), | ||||||
|     }); |     }); | ||||||
|     foundry.utils.mergeObject(formData.calc, { |     foundry.utils.mergeObject(formData.calc, { | ||||||
|       surenc: this.actor.computeMalusSurEncombrement(), |       surenc: this.actor.computeMalusSurEncombrement(), | ||||||
| @@ -183,22 +185,19 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       await blessure?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } }) |       await blessure?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } }) | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     // Equip Inventory Item |  | ||||||
|     this.html.find('.item-equip').click(async event => this.actor.equiperObjet(RdDSheetUtility.getItemId(event))) |  | ||||||
|     this.html.find('.roll-chance-actuelle').click(async event => this.actor.rollCarac('chance-actuelle')) |     this.html.find('.roll-chance-actuelle').click(async event => this.actor.rollCarac('chance-actuelle')) | ||||||
|  |  | ||||||
|     this.html.find('.button-appel-chance').click(async event => this.actor.rollAppelChance()) |     this.html.find('.button-appel-chance').click(async event => this.actor.rollAppelChance()) | ||||||
|  |  | ||||||
|     this.html.find('[name="jet-astrologie"]').click(async event => this.actor.astrologieNombresAstraux()) |     this.html.find('[name="jet-astrologie"]').click(async event => this.actor.astrologieNombresAstraux()) | ||||||
|     this.html.find('.tache-label a').click(async event => this.actor.rollTache(RdDSheetUtility.getItemId(event))) |     this.html.find('.action-tache').click(async event => this.actor.rollTache(RdDSheetUtility.getItemId(event))) | ||||||
|     this.html.find('.meditation-label a').click(async event => this.actor.rollMeditation(RdDSheetUtility.getItemId(event))) |     this.html.find('.meditation-label a').click(async event => this.actor.rollMeditation(RdDSheetUtility.getItemId(event))) | ||||||
|  |  | ||||||
|     this.html.find('.chant-label a').click(async event => this.actor.rollChant(RdDSheetUtility.getItemId(event))) |     this.html.find('.action-chant').click(async event => this.actor.rollChant(RdDSheetUtility.getItemId(event))) | ||||||
|     this.html.find('.danse-label a').click(async event => this.actor.rollDanse(RdDSheetUtility.getItemId(event))) |     this.html.find('.action-danse').click(async event => this.actor.rollDanse(RdDSheetUtility.getItemId(event))) | ||||||
|     this.html.find('.musique-label a').click(async event => this.actor.rollMusique(RdDSheetUtility.getItemId(event))) |     this.html.find('.action-musique').click(async event => this.actor.rollMusique(RdDSheetUtility.getItemId(event))) | ||||||
|     this.html.find('.oeuvre-label a').click(async event => this.actor.rollOeuvre(RdDSheetUtility.getItemId(event))) |     this.html.find('.action-oeuvre').click(async event => this.actor.rollOeuvre(RdDSheetUtility.getItemId(event))) | ||||||
|     this.html.find('.jeu-label a').click(async event => this.actor.rollJeu(RdDSheetUtility.getItemId(event))) |     this.html.find('.action-jeu').click(async event => this.actor.rollJeu(RdDSheetUtility.getItemId(event))) | ||||||
|     this.html.find('.recettecuisine-label a').click(async event => this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event))) |     this.html.find('.action-recettecuisine').click(async event => 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(true)) | ||||||
|     if (game.user.isGM) { |     if (game.user.isGM) { | ||||||
| @@ -216,13 +215,12 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       // Boutons spéciaux MJs |       // Boutons spéciaux MJs | ||||||
|       this.html.find('.forcer-tmr-aleatoire').click(async event => this.actor.reinsertionAleatoire("Action MJ")) |       this.html.find('.forcer-tmr-aleatoire').click(async event => this.actor.reinsertionAleatoire("Action MJ")) | ||||||
|       this.html.find('.don-de-haut-reve').click(async event => this.actor.addDonDeHautReve()) |       this.html.find('.don-de-haut-reve').click(async event => this.actor.addDonDeHautReve()) | ||||||
|       this.html.find('.sortreserve-add').click(async event => this.actor.addSortReserve(RdDSheetUtility.getItemId(event))) |  | ||||||
|       this.html.find('.afficher-tmr').click(async event => this.actor.changeTMRVisible()) |       this.html.find('.afficher-tmr').click(async event => this.actor.changeTMRVisible()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Points de reve actuel |     // Points de reve actuel | ||||||
|     this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', true)) |     this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', {resistance:true})) | ||||||
|     this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) |     this.html.find('.action-empoignade').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) | ||||||
|  |  | ||||||
|     this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) |     this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) | ||||||
|  |  | ||||||
| @@ -326,7 +324,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async selectTypeOeuvreToCreate() { |   async selectTypeOeuvreToCreate() { | ||||||
|     let types = RdDItem.getTypesOeuvres(); |     let types = RdDItem.getTypesOeuvres(); | ||||||
|     let content = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`; |     let content = `<span class="generic-label">Selectionnez le type d'oeuvre</span><select class="item-type">`; | ||||||
|     for (let typeName of types) { |     for (let typeName of types) { | ||||||
|       content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>` |       content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>` | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										179
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						
									
										179
									
								
								module/actor.js
									
									
									
									
									
								
							| @@ -17,7 +17,7 @@ import { RdDItemSigneDraconique } from "./item/signedraconique.js"; | |||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; | import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; | ||||||
| import { Draconique } from "./tmr/draconique.js"; | import { Draconique } from "./tmr/draconique.js"; | ||||||
| import { LIST_CARAC, RdDCarac } from "./rdd-carac.js"; | import { LIST_CARAC_PERSONNAGE, RdDCarac } from "./rdd-carac.js"; | ||||||
| import { DialogConsommer } from "./dialog-item-consommer.js"; | import { DialogConsommer } from "./dialog-item-consommer.js"; | ||||||
| import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js"; | import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js"; | ||||||
| import { RollDataAjustements } from "./rolldata-ajustements.js"; | import { RollDataAjustements } from "./rolldata-ajustements.js"; | ||||||
| @@ -32,7 +32,7 @@ import { RdDItemBlessure } from "./item/blessure.js"; | |||||||
| import { AppAstrologie } from "./sommeil/app-astrologie.js"; | import { AppAstrologie } from "./sommeil/app-astrologie.js"; | ||||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||||
| import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js"; | import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js"; | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; | import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; | ||||||
| import { RdDCoeur } from "./coeur/rdd-coeur.js"; | import { RdDCoeur } from "./coeur/rdd-coeur.js"; | ||||||
| import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; | import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; | ||||||
| @@ -167,28 +167,22 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async $perteRevePotionsEnchantees() { |   async $perteRevePotionsEnchantees() { | ||||||
|     let potions = this.itemTypes[ITEM_TYPES.potion] |     const potionUpdates = this.itemTypes[ITEM_TYPES.potion].map(it => it.perteRevePotion()) | ||||||
|       .filter(it => Grammar.includesLowerCaseNoAccent(it.system.categorie, 'enchanté') && !it.system.prpermanent) |       .filter(it => it != undefined) | ||||||
|  |     if (potionUpdates.length > 0) { | ||||||
|     const potionUpdates = await Promise.all(potions.map(async it => { |       console.log('perte rêve de potions', potionUpdates) | ||||||
|       const nouveauReve = Math.max(it.system.pr - 1, 0) |       const messageUpdates = await Promise.all(potionUpdates.map(async p => await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, { | ||||||
|  |         pr: foundry.utils.getProperty(p, 'system.pr'), | ||||||
|  |         alias: this.getAlias(), | ||||||
|  |         potionName: p.name, | ||||||
|  |         potionImg: p.img | ||||||
|  |       }))) | ||||||
|       ChatMessage.create({ |       ChatMessage.create({ | ||||||
|         whisper: ChatUtility.getOwners(this), |         whisper: ChatUtility.getOwners(this), | ||||||
|         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, { |         content: messageUpdates.reduce(Misc.joining('<br>')) | ||||||
|           pr: nouveauReve, |  | ||||||
|           alias: this.getAlias(), |  | ||||||
|           potionName: it.name, |  | ||||||
|           potionImg: it.img |  | ||||||
|         }) |  | ||||||
|       }) |       }) | ||||||
|       return { |       await this.updateEmbeddedDocuments('Item', potionUpdates); | ||||||
|         _id: it._id, |     } | ||||||
|         'system.pr': nouveauReve, |  | ||||||
|         'system.quantite': nouveauReve > 0 ? it.system.quantite : 0 |  | ||||||
|       } |  | ||||||
|     })) |  | ||||||
|  |  | ||||||
|     await this.updateEmbeddedDocuments('Item', potionUpdates); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** -------------------------------------------- |   /** -------------------------------------------- | ||||||
| @@ -245,7 +239,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async _recuperationSante(message) { |   async _recuperationSante(message) { | ||||||
|     const maladiesPoisons = this.getMaladiePoisons(); |     const maladiesPoisons = this.getMaladiesPoisons(); | ||||||
|     const isMaladeEmpoisonne = maladiesPoisons.length > 0; |     const isMaladeEmpoisonne = maladiesPoisons.length > 0; | ||||||
|     this._messageRecuperationMaladiePoisons(maladiesPoisons, message); |     this._messageRecuperationMaladiePoisons(maladiesPoisons, message); | ||||||
|  |  | ||||||
| @@ -253,7 +247,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     await this._recupererVie(message, isMaladeEmpoisonne); |     await this._recupererVie(message, isMaladeEmpoisonne); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getMaladiePoisons() { |   getMaladiesPoisons() { | ||||||
|     return this.items.filter(item => item.type == 'maladie' || (item.type == 'poison' && item.system.active)); |     return this.items.filter(item => item.type == 'maladie' || (item.type == 'poison' && item.system.active)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -413,19 +407,18 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async remiseANeuf() { |   async remiseANeuf() { | ||||||
|     ChatMessage.create({ |     await this.update({ | ||||||
|       whisper: ChatUtility.getOwners(this), |  | ||||||
|       content: 'Remise à neuf de ' + this.name |  | ||||||
|     }); |  | ||||||
|     await this.supprimerBlessures(it => true); |  | ||||||
|     await this.removeEffects(e => e.id != STATUSES.StatusDemiReve); |  | ||||||
|     const updates = { |  | ||||||
|       'system.sante.endurance.value': this.system.sante.endurance.max, |       'system.sante.endurance.value': this.system.sante.endurance.max, | ||||||
|       'system.sante.vie.value': this.system.sante.vie.max, |       'system.sante.vie.value': this.system.sante.vie.max, | ||||||
|       'system.sante.fatigue.value': 0, |       'system.sante.fatigue.value': 0, | ||||||
|       'system.compteurs.ethylisme': { value: 1, nb_doses: 0, jet_moral: false } |       'system.compteurs.ethylisme': { value: 1, nb_doses: 0, jet_moral: false } | ||||||
|     }; |     }) | ||||||
|     await this.update(updates); |     await this.removeEffects(e => e.id != STATUSES.StatusDemiReve); | ||||||
|  |     await this.supprimerBlessures(it => true); | ||||||
|  |     await ChatMessage.create({ | ||||||
|  |       whisper: ChatUtility.getOwners(this), | ||||||
|  |       content: 'Remise à neuf de ' + this.name | ||||||
|  |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -529,7 +522,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         jet_moral: false, |         jet_moral: false, | ||||||
|         value: value |         value: value | ||||||
|       } |       } | ||||||
|     }); |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -662,15 +655,15 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async updateCarac(caracName, to) { |   async updateCarac(caracName, to) { | ||||||
|     to = Number(to) |     to = Number(to) | ||||||
|     if (!RdDItemRace.checkRacialMax(this, caracName, to)){ |     if (!RdDItemRace.checkRacialMax(this, caracName, to)) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     if (caracName == LIST_CARAC.reve.code) { |     if (caracName == LIST_CARAC_PERSONNAGE.reve.code) { | ||||||
|       if (to > Misc.toInt(this.system.reve.seuil.value)) { |       if (to > Misc.toInt(this.system.reve.seuil.value)) { | ||||||
|         this.setPointsDeSeuil(to); |         this.setPointsDeSeuil(to); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     if (caracName == LIST_CARAC.chance.code) { |     if (caracName == LIST_CARAC_PERSONNAGE.chance.code) { | ||||||
|       if (to > Misc.toInt(this.system.compteurs.chance.value)) { |       if (to > Misc.toInt(this.system.compteurs.chance.value)) { | ||||||
|         this.setPointsDeChance(to); |         this.setPointsDeChance(to); | ||||||
|       } |       } | ||||||
| @@ -993,13 +986,10 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async addSortReserve(itemId) { |   async addSortReserve(item) { | ||||||
|     if (itemId) { |     if (item?.type == ITEM_TYPES.sort && !item.system.isrituel) { | ||||||
|       const item = this.items.get(itemId) |       this.$createSortReserve(item) | ||||||
|       if (item.type == ITEM_TYPES.sort && !item.system.isrituel) { |       return | ||||||
|         this.$createSortReserve(item) |  | ||||||
|         return |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     const selectSortReserve = { |     const selectSortReserve = { | ||||||
|       title: "Créer un sort en réserve", |       title: "Créer un sort en réserve", | ||||||
| @@ -1203,42 +1193,6 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     new RdDRollDialogEthylisme(html, rollData, this, r => this.saouler(r.forceAlcool)).render(true); |     new RdDRollDialogEthylisme(html, rollData, this, r => this.saouler(r.forceAlcool)).render(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async actionPrincipale(item, onActionItem = async () => { }) { |  | ||||||
|     let result = await super.actionPrincipale(item, onActionItem) |  | ||||||
|     if (result) { return result } |  | ||||||
|  |  | ||||||
|     result = await this.actionNourritureboisson(item, onActionItem) |  | ||||||
|     if (result) { return result } |  | ||||||
|  |  | ||||||
|     switch (item.type) { |  | ||||||
|       case ITEM_TYPES.potion: return await this.consommerPotion(item, onActionItem); |  | ||||||
|       case ITEM_TYPES.livre: return await this.actionLire(item); |  | ||||||
|       case ITEM_TYPES.conteneur: return await item.sheet.render(true); |  | ||||||
|       case ITEM_TYPES.herbe: return await this.actionHerbe(item, onActionItem); |  | ||||||
|       case ITEM_TYPES.queue: case ITEM_TYPES.ombre: return await this.actionRefoulement(item); |  | ||||||
|     } |  | ||||||
|     return undefined |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async actionNourritureboisson(item, onActionItem) { |  | ||||||
|     switch (item.getUtilisationCuisine()) { |  | ||||||
|       case 'brut': { |  | ||||||
|         const utilisation = new Dialog({ |  | ||||||
|           title: "Nourriture brute", |  | ||||||
|           content: `Que faire de votre ${item.name}`, |  | ||||||
|           buttons: { |  | ||||||
|             'cuisiner': { icon: '<i class="fa-solid fa-utensils"></i>', label: 'Cuisiner', callback: async () => await this.preparerNourriture(item) }, |  | ||||||
|             'manger': { icon: '<i class="fa-solid fa-drumstick-bite"></i>', label: 'Manger cru', callback: async () => await this.mangerNourriture(item, onActionItem) } |  | ||||||
|           } |  | ||||||
|         }); |  | ||||||
|         return utilisation.render(true); |  | ||||||
|       } |  | ||||||
|       case 'pret': |  | ||||||
|         return await this.mangerNourriture(item, onActionItem); |  | ||||||
|     } |  | ||||||
|     return undefined; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async mangerNourriture(item, onActionItem) { |   async mangerNourriture(item, onActionItem) { | ||||||
|     return (await DialogConsommer.create(this, item, onActionItem)).render(true); |     return (await DialogConsommer.create(this, item, onActionItem)).render(true); | ||||||
|   } |   } | ||||||
| @@ -1387,7 +1341,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     await RdDResolutionTable.rollData(ethylismeData.jetVie); |     await RdDResolutionTable.rollData(ethylismeData.jetVie); | ||||||
|     this._gererExperience(ethylismeData.jetVie); |     this.gererExperience(ethylismeData.jetVie); | ||||||
|     RollDataAjustements.calcul(ethylismeData.jetVie, this); |     RollDataAjustements.calcul(ethylismeData.jetVie, this); | ||||||
|     if (ethylismeData.jetVie.rolled.isSuccess) { |     if (ethylismeData.jetVie.rolled.isSuccess) { | ||||||
|       ethylisme.nb_doses++; |       ethylisme.nb_doses++; | ||||||
| @@ -1419,7 +1373,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|           finalLevel: Number(ethylisme.value) + Number(this.system.compteurs.moral.value) |           finalLevel: Number(ethylisme.value) + Number(this.system.compteurs.moral.value) | ||||||
|         } |         } | ||||||
|         await RdDResolutionTable.rollData(ethylismeData.jetVolonte); |         await RdDResolutionTable.rollData(ethylismeData.jetVolonte); | ||||||
|         this._gererExperience(ethylismeData.jetVolonte); |         this.gererExperience(ethylismeData.jetVolonte); | ||||||
|         RollDataAjustements.calcul(ethylismeData.jetVolonte, this); |         RollDataAjustements.calcul(ethylismeData.jetVolonte, this); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -1596,7 +1550,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { |   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { | ||||||
|     if (!Misc.isFirstConnectedGM()) { |     if (!Misc.hasConnectedGM()) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) |     hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) | ||||||
| @@ -1799,38 +1753,8 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue |  | ||||||
|    * @param {*} caracName  |  | ||||||
|    * @param {*} compName  |  | ||||||
|    * @param {*} diff  |  | ||||||
|    * @param {*} options  |  | ||||||
|    * @returns  |  | ||||||
|    */ |  | ||||||
|   async doRollCaracCompetence(caracName, compName, diff, options = { title: "" }) { |  | ||||||
|     const carac = this.getCaracByName(caracName); |  | ||||||
|     if (!carac) { |  | ||||||
|       ui.notifications.warn(`${this.name} n'a pas de caractéristique correspondant à ${caracName}`) |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     const competence = this.getCompetence(compName); |  | ||||||
|     let rollData = { |  | ||||||
|       alias: this.getAlias(), |  | ||||||
|       caracValue: Number(carac.value), |  | ||||||
|       selectedCarac: carac, |  | ||||||
|       competence: competence, |  | ||||||
|       diffLibre: diff, |  | ||||||
|       show: { title: options?.title ?? '' } |  | ||||||
|     }; |  | ||||||
|     RollDataAjustements.calcul(rollData, this); |  | ||||||
|     await RdDResolutionTable.rollData(rollData); |  | ||||||
|     this._gererExperience(rollData); |  | ||||||
|     await RdDResolutionTable.displayRollData(rollData, this) |  | ||||||
|     return rollData.rolled; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _gererExperience(rollData) { |   gererExperience(rollData) { | ||||||
|     const callback = this.createCallbackExperience(); |     const callback = this.createCallbackExperience(); | ||||||
|     if (callback.condition(rollData)) { |     if (callback.condition(rollData)) { | ||||||
|       callback.action(rollData); |       callback.action(rollData); | ||||||
| @@ -1880,26 +1804,6 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     return undefined; |     return undefined; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) { |  | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |  | ||||||
|     const competence = this.getCompetence(compName); |  | ||||||
|     await this.openRollDialog({ |  | ||||||
|       name: 'jet-competence', |  | ||||||
|       label: 'Jet ' + Grammar.apostrophe('de', competence.name), |  | ||||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', |  | ||||||
|       rollData: { |  | ||||||
|         alias: this.getAlias(), |  | ||||||
|         carac: this.system.carac, |  | ||||||
|         selectedCarac: this.getCaracByName(caracName), |  | ||||||
|         selectedCaracName: caracName, |  | ||||||
|         diffLibre: diff, |  | ||||||
|         competence: competence, |  | ||||||
|         show: { title: options?.title ?? '' } |  | ||||||
|       }, |  | ||||||
|       callbackAction: r => this.$onRollCompetence(r, options) |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollTache(id, options = {}) { |   async rollTache(id, options = {}) { | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
| @@ -1941,8 +1845,8 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     } |     } | ||||||
|     rollData.tache.system.tentatives = rollData.tache.system.nb_jet_succes + rollData.tache.system.nb_jet_echec; |     rollData.tache.system.tentatives = rollData.tache.system.nb_jet_succes + rollData.tache.system.nb_jet_echec; | ||||||
|  |  | ||||||
|     this.updateEmbeddedDocuments('Item', [rollData.tache]); |     await this.updateEmbeddedDocuments('Item', [rollData.tache]); | ||||||
|     this.santeIncDec("fatigue", rollData.tache.system.fatigue); |     await this.santeIncDec("fatigue", rollData.tache.system.fatigue); | ||||||
|  |  | ||||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html'); |     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html'); | ||||||
|     if (options?.onRollAutomate) { |     if (options?.onRollAutomate) { | ||||||
| @@ -2620,8 +2524,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async equiperObjet(itemID) { |   async equiperObjet(item) { | ||||||
|     let item = this.getEmbeddedDocument('Item', itemID); |  | ||||||
|     if (item?.isEquipable()) { |     if (item?.isEquipable()) { | ||||||
|       const isEquipe = !item.system.equipe; |       const isEquipe = !item.system.equipe; | ||||||
|       await item.update({ "system.equipe": isEquipe }); |       await item.update({ "system.equipe": isEquipe }); | ||||||
| @@ -2640,7 +2543,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     for (const armure of armures) { |     for (const armure of armures) { | ||||||
|       protection += await RdDDice.rollTotal(armure.system.protection.toString()); |       protection += await RdDDice.rollTotal(armure.system.protection.toString()); | ||||||
|       if (dmg > 0 && attackerRoll.dmg.encaisserSpecial != "noarmure") { |       if (dmg > 0 && attackerRoll.dmg.encaisserSpecial != "noarmure") { | ||||||
|         armure.deteriorerArmure(dmg); |         await armure.deteriorerArmure(dmg) | ||||||
|         dmg = 0; |         dmg = 0; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
|  | import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js"; | ||||||
| import { Grammar } from "../grammar.js"; | import { Grammar } from "../grammar.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | ||||||
| import { RdDBaseActorSheet } from "./base-actor-sheet.js"; | import { RdDBaseActorSheet } from "./base-actor-sheet.js"; | ||||||
|  |  | ||||||
| @@ -27,7 +28,7 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { | |||||||
|  |  | ||||||
|     this.html.find('.button-encaissement').click(async event => this.actor.encaisser()) |     this.html.find('.button-encaissement').click(async event => this.actor.encaisser()) | ||||||
|     this.html.find('.roll-carac').click(async event => { |     this.html.find('.roll-carac').click(async event => { | ||||||
|       this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes['data-carac-name'].value))}); |       this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes['data-carac-name'].value))}) | ||||||
|     this.html.find('.roll-competence').click(async event => this.actor.rollCompetence(RdDSheetUtility.getItemId(event))); |     this.html.find('.roll-competence').click(async event => this.actor.rollCompetence(RdDSheetUtility.getItemId(event))); | ||||||
|     this.html.find('.endurance-plus').click(async event => this.actor.santeIncDec("endurance", 1)); |     this.html.find('.endurance-plus').click(async event => this.actor.santeIncDec("endurance", 1)); | ||||||
|     this.html.find('.endurance-moins').click(async event => this.actor.santeIncDec("endurance", -1)); |     this.html.find('.endurance-moins').click(async event => this.actor.santeIncDec("endurance", -1)); | ||||||
| @@ -47,6 +48,9 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { | |||||||
|         } |         } | ||||||
|       }], { renderSheet: true }) |       }], { 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.options.vueDetaillee) { |     if (this.options.vueDetaillee) { | ||||||
|       // On carac change |       // On carac change | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import { RdDRoll } from "../rdd-roll.js"; | |||||||
| import { RdDUtility } from "../rdd-utility.js"; | import { RdDUtility } from "../rdd-utility.js"; | ||||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | ||||||
| import { RdDBaseActor } from "./base-actor.js"; | import { RdDBaseActor } from "./base-actor.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { RdDItemCompetence } from "../item-competence.js"; | import { RdDItemCompetence } from "../item-competence.js"; | ||||||
| import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; | ||||||
| import { RdDItemArme } from "../item-arme.js"; | import { RdDItemArme } from "../item-arme.js"; | ||||||
| @@ -22,6 +22,7 @@ import { RdDCombat } from "../rdd-combat.js"; | |||||||
| import { RdDEmpoignade } from "../rdd-empoignade.js"; | import { RdDEmpoignade } from "../rdd-empoignade.js"; | ||||||
| import { RdDPossession } from "../rdd-possession.js"; | import { RdDPossession } from "../rdd-possession.js"; | ||||||
| import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js"; | import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js"; | ||||||
|  | import { RollDataAjustements } from "../rolldata-ajustements.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Classe de base pour les acteurs disposant de rêve (donc, pas des objets) |  * Classe de base pour les acteurs disposant de rêve (donc, pas des objets) | ||||||
| @@ -293,6 +294,57 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   createCallbackAppelAuMoral() { return this.createEmptyCallback(); } |   createCallbackAppelAuMoral() { return this.createEmptyCallback(); } | ||||||
|   async _onCloseRollDialog(html) { } |   async _onCloseRollDialog(html) { } | ||||||
|  |  | ||||||
|  |   async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) { | ||||||
|  |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
|  |     const competence = this.getCompetence(compName); | ||||||
|  |     await this.openRollDialog({ | ||||||
|  |       name: 'jet-competence', | ||||||
|  |       label: competence? 'Jet ' + Grammar.apostrophe('de', competence.name) : `Jet sans compétence (${compName})`, | ||||||
|  |       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', | ||||||
|  |       rollData: { | ||||||
|  |         alias: this.getAlias(), | ||||||
|  |         carac: this.system.carac, | ||||||
|  |         selectedCarac: this.getCaracByName(caracName), | ||||||
|  |         selectedCaracName: caracName, | ||||||
|  |         diffLibre: diff, | ||||||
|  |         competence: competence, | ||||||
|  |         show: { title: options?.title ?? '' } | ||||||
|  |       }, | ||||||
|  |       callbackAction: r => this.$onRollCompetence(r, options) | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |   /** | ||||||
|  |    * Méthode pour faire un jet prédéterminer 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) | ||||||
|  |    * @param {*} options | ||||||
|  |    * @returns le jet effectué | ||||||
|  |    */ | ||||||
|  |   async doRollCaracCompetence(caracName, compName, diff, options = { title: "" }) { | ||||||
|  |     const carac = this.getCaracByName(caracName); | ||||||
|  |     if (!carac) { | ||||||
|  |       ui.notifications.warn(`${this.name} n'a pas de caractéristique correspondant à ${caracName}`) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |     const competence = this.getCompetence(compName); | ||||||
|  |     let rollData = { | ||||||
|  |       alias: this.getAlias(), | ||||||
|  |       caracValue: Number(carac.value), | ||||||
|  |       selectedCarac: carac, | ||||||
|  |       competence: competence, | ||||||
|  |       diffLibre: diff ?? 0, | ||||||
|  |       show: { title: options?.title ?? '' } | ||||||
|  |     } | ||||||
|  |     RollDataAjustements.calcul(rollData, this); | ||||||
|  |     await RdDResolutionTable.rollData(rollData); | ||||||
|  |     this.gererExperience(rollData); | ||||||
|  |     await RdDResolutionTable.displayRollData(rollData, this) | ||||||
|  |     return rollData.rolled; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   gererExperience(rollData) { } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async roll() { |   async roll() { | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
| @@ -311,14 +363,14 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|         competences: this.itemTypes['competence'] |         competences: this.itemTypes['competence'] | ||||||
|       }, |       }, | ||||||
|       callbackAction: r => this.$onRollCaracResult(r) |       callbackAction: r => this.$onRollCaracResult(r) | ||||||
|     }); |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollCarac(caracName, jetResistance = undefined) { |   async rollCarac(caracName, options = {}) { | ||||||
|     if (Grammar.equalsInsensitive(caracName, 'taille')) { |     if (Grammar.equalsInsensitive(caracName, 'taille')) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|  |     foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false }) | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
|     let selectedCarac = this.getCaracByName(caracName) |     let selectedCarac = this.getCaracByName(caracName) | ||||||
|     console.log("selectedCarac", selectedCarac) |     console.log("selectedCarac", selectedCarac) | ||||||
| @@ -329,7 +381,8 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|       rollData: { |       rollData: { | ||||||
|         selectedCarac: selectedCarac, |         selectedCarac: selectedCarac, | ||||||
|         competences: this.itemTypes['competence'], |         competences: this.itemTypes['competence'], | ||||||
|         jetResistance: jetResistance ? caracName : undefined |         diffLibre: options.diff ?? 0, | ||||||
|  |         jetResistance: options.resistance ? caracName : undefined | ||||||
|       }, |       }, | ||||||
|       callbackAction: r => this.$onRollCaracResult(r) |       callbackAction: r => this.$onRollCaracResult(r) | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { RdDUtility } from "../rdd-utility.js"; | import { RdDUtility } from "../rdd-utility.js"; | ||||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | ||||||
| import { STATUSES } from "../settings/status-effects.js"; | import { STATUSES } from "../settings/status-effects.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { RdDBaseActorReve } from "./base-actor-reve.js"; | import { RdDBaseActorReve } from "./base-actor-reve.js"; | ||||||
| import { RdDDice } from "../rdd-dice.js"; | import { RdDDice } from "../rdd-dice.js"; | ||||||
| import { RdDItemBlessure } from "../item/blessure.js"; | import { RdDItemBlessure } from "../item/blessure.js"; | ||||||
|   | |||||||
| @@ -3,8 +3,11 @@ import { Misc } from "../misc.js"; | |||||||
| import { DialogSplitItem } from "../dialog-split-item.js"; | import { DialogSplitItem } from "../dialog-split-item.js"; | ||||||
| import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | ||||||
| import { Monnaie } from "../item-monnaie.js"; | import { Monnaie } from "../item-monnaie.js"; | ||||||
| import { RdDItem, ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { RdDItem } from "../item.js"; | ||||||
| import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; | ||||||
|  | import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js"; | ||||||
|  | import { ItemAction } from "../item/item-actions.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| /** | /** | ||||||
| @@ -25,7 +28,7 @@ export class RdDBaseActorSheet extends ActorSheet { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async getData() { |   async getData() { | ||||||
|     Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']); |     Monnaie.validerMonnaies(this.actor) | ||||||
|  |  | ||||||
|     this.actor.computeEtatGeneral(); |     this.actor.computeEtatGeneral(); | ||||||
|     let formData = { |     let formData = { | ||||||
| @@ -35,13 +38,13 @@ export class RdDBaseActorSheet extends ActorSheet { | |||||||
|       img: this.actor.img, |       img: this.actor.img, | ||||||
|       name: this.actor.name, |       name: this.actor.name, | ||||||
|       system: this.actor.system, |       system: this.actor.system, | ||||||
|       description: await TextEditor.enrichHTML(this.actor.system.description, { async: true }), |       description: await RdDTextEditor.enrichHTML(this.actor.system.description, this.actor), | ||||||
|       notesmj: await TextEditor.enrichHTML(this.actor.system.notesmj, { async: true }), |       notesmj: await RdDTextEditor.enrichHTML(this.actor.system.notesmj, this.actor), | ||||||
|       options: RdDSheetUtility.mergeDocumentRights(this.options, this.actor, this.isEditable), |       options: RdDSheetUtility.mergeDocumentRights(this.options, this.actor, this.isEditable), | ||||||
|       effects: this.actor.effects |       effects: this.actor.effects | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); |     RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); | ||||||
|     formData.calc = { |     formData.calc = { | ||||||
|       fortune: Monnaie.toSolsDeniers(this.actor.getFortune()), |       fortune: Monnaie.toSolsDeniers(this.actor.getFortune()), | ||||||
|       prixTotalEquipement: this.actor.computePrixTotalEquipement(), |       prixTotalEquipement: this.actor.computePrixTotalEquipement(), | ||||||
| @@ -53,6 +56,7 @@ export class RdDBaseActorSheet extends ActorSheet { | |||||||
|     formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); |     formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); | ||||||
|     formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature) |     formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature) | ||||||
|       .forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it)) |       .forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it)) | ||||||
|  |  | ||||||
|     return formData; |     return formData; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -76,95 +80,37 @@ export class RdDBaseActorSheet extends ActorSheet { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static filterItemsPerTypeForSheet(formData, itemTypes) { |  | ||||||
|     formData.blessures = Misc.arrayOrEmpty(itemTypes['blessure']); |  | ||||||
|     formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']); |  | ||||||
|     formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']); |  | ||||||
|     formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']); |  | ||||||
|     formData.poisons = Misc.arrayOrEmpty(itemTypes['poison']); |  | ||||||
|     formData.possessions = Misc.arrayOrEmpty(itemTypes['possession']); |  | ||||||
|     formData.maladiesPoisons = formData.maladies.concat(formData.poisons); |  | ||||||
|     formData.competences = (itemTypes['competence'] ?? []).concat(itemTypes['competencecreature'] ?? []); |  | ||||||
|     formData.sortsReserve = Misc.arrayOrEmpty(itemTypes['sortreserve']); |  | ||||||
|  |  | ||||||
|     formData.sorts = Misc.arrayOrEmpty(itemTypes['sort']); |  | ||||||
|     formData.rencontres = Misc.arrayOrEmpty(itemTypes['rencontre']); |  | ||||||
|     formData.casestmr = Misc.arrayOrEmpty(itemTypes['casetmr']); |  | ||||||
|     formData.signesdraconiques = Misc.arrayOrEmpty(itemTypes['signedraconique']); |  | ||||||
|     formData.queues = Misc.arrayOrEmpty(itemTypes['queue']); |  | ||||||
|     formData.souffles = Misc.arrayOrEmpty(itemTypes['souffle']); |  | ||||||
|     formData.ombres = Misc.arrayOrEmpty(itemTypes['ombre']); |  | ||||||
|     formData.tetes = Misc.arrayOrEmpty(itemTypes['tete']); |  | ||||||
|     formData.taches = Misc.arrayOrEmpty(itemTypes['tache']); |  | ||||||
|     formData.meditations = Misc.arrayOrEmpty(itemTypes['meditation']); |  | ||||||
|     formData.chants = Misc.arrayOrEmpty(itemTypes['chant']); |  | ||||||
|     formData.danses = Misc.arrayOrEmpty(itemTypes['danse']); |  | ||||||
|     formData.musiques = Misc.arrayOrEmpty(itemTypes['musique']); |  | ||||||
|     formData.oeuvres = Misc.arrayOrEmpty(itemTypes['oeuvre']); |  | ||||||
|     formData.jeux = Misc.arrayOrEmpty(itemTypes['jeu']); |  | ||||||
|  |  | ||||||
|     formData.services = Misc.arrayOrEmpty(itemTypes['service']); |  | ||||||
|     formData.conteneurs = Misc.arrayOrEmpty(itemTypes['conteneur']); |  | ||||||
|     formData.materiel = Misc.arrayOrEmpty(itemTypes['objet']); |  | ||||||
|     formData.armes = Misc.arrayOrEmpty(itemTypes['arme']); |  | ||||||
|     formData.armures = Misc.arrayOrEmpty(itemTypes['armure']); |  | ||||||
|     formData.munitions = Misc.arrayOrEmpty(itemTypes['munition']); |  | ||||||
|     formData.livres = Misc.arrayOrEmpty(itemTypes['livre']); |  | ||||||
|     formData.potions = Misc.arrayOrEmpty(itemTypes['potion']); |  | ||||||
|     formData.plantes = Misc.arrayOrEmpty(itemTypes['plante']); |  | ||||||
|     formData.ingredients = Misc.arrayOrEmpty(itemTypes['ingredient']); |  | ||||||
|     formData.faunes = Misc.arrayOrEmpty(itemTypes['faune']); |  | ||||||
|     formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']); |  | ||||||
|     formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']); |  | ||||||
|     formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']); |  | ||||||
|     formData.monnaies = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere()); |  | ||||||
|     formData.objets = Misc.arrayOrEmpty(itemTypes['objet']) |  | ||||||
|  |  | ||||||
|     formData.inventaires = RdDItem.getItemTypesInventaire('all') |  | ||||||
|       .map(t => Misc.arrayOrEmpty(itemTypes[t])) |  | ||||||
|       .reduce((a, b) => a.concat(b), []) |  | ||||||
|       .sort(Misc.ascending(it => it.name)); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */  /** @override */ |   /* -------------------------------------------- */  /** @override */ | ||||||
|   activateListeners(html) { |   activateListeners(html) { | ||||||
|     super.activateListeners(html); |     super.activateListeners(html); | ||||||
|     this.html = html; |     this.html = html; | ||||||
|  |  | ||||||
|  |     this.html.find('.actionItem').click(event => ItemAction.onActionItem(event, this.actor, this.options)) | ||||||
|  |     this.html.find('.item-edit').click(async event => this.itemActionEdit(event)) | ||||||
|     this.html.find('.conteneur-name a').click(async event => { |     this.html.find('.conteneur-name a').click(async event => { | ||||||
|       RdDUtility.toggleAfficheContenu(this.getItemId(event)); |       RdDUtility.toggleAfficheContenu(this.getItemId(event)) | ||||||
|       this.render(true); |       this.render(true) | ||||||
|     }); |     }) | ||||||
|  |  | ||||||
|     this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat()); |     this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat()); | ||||||
|     this.html.find('.item-edit').click(async event => this.getItem(event)?.sheet.render(true)) |  | ||||||
|     this.html.find('.item-montrer').click(async event => this.getItem(event)?.postItemToChat()); |  | ||||||
|  |  | ||||||
|     this.html.find('.recherche') |     this.html.find('.recherche') | ||||||
|       .each((index, field) => { |       .each((index, field) => { | ||||||
|         this._rechercheSelectArea(field); |         this._rechercheSelectArea(field); | ||||||
|       }) |       }) | ||||||
|       .keyup(async event => this._rechercherKeyup(event)) |       .keyup(async event => this._rechercherKeyup(event)) | ||||||
|       .change(async event => this._rechercherKeyup(event)); |       .change(async event => this._rechercherKeyup(event)) | ||||||
|     this.html.find('.recherche').prop("disabled", false); |  | ||||||
|  |     this.html.find('.recherche').prop("disabled", false) | ||||||
|  |  | ||||||
|     // Everything below here is only needed if the sheet is editable |     // Everything below here is only needed if the sheet is editable | ||||||
|     if (!this.options.editable) return; |     if (!this.options.editable) return; | ||||||
|  |  | ||||||
|     this.html.find('.item-action').click(async event => { |     this.html.find('.item-equip-armure').click(async event => this.actor.equiperObjet(this.getItem(event))) | ||||||
|       const item = RdDSheetUtility.getItem(event, this.actor); |     this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this.getItem(event), this.actor)); | ||||||
|       item?.actionPrincipale(this.actor, async () => this.render()) |     this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(this.getItem(event), this.actor)) | ||||||
|     }); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     this.html.find('.item-split').click(async event => { |  | ||||||
|       const item = this.getItem(event); |  | ||||||
|       RdDSheetUtility.splitItem(item, this.actor); |  | ||||||
|     }); |  | ||||||
|     this.html.find('.item-quantite-plus').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), 1)); |     this.html.find('.item-quantite-plus').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), 1)); | ||||||
|     this.html.find('.item-quantite-moins').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), -1)); |     this.html.find('.item-quantite-moins').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), -1)); | ||||||
|     this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, this.getItem(event))); |  | ||||||
|     this.html.find('.item-vendre').click(async event => this.vendre(this.getItem(event))); |  | ||||||
|  |  | ||||||
|     this.html.find('.creer-un-objet').click(async event => { |     this.html.find('.creer-un-objet').click(async event => { | ||||||
|       this.selectObjetTypeToCreate(); |       this.selectObjetTypeToCreate(); | ||||||
| @@ -179,6 +125,11 @@ export class RdDBaseActorSheet extends ActorSheet { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   itemActionEdit(event) { | ||||||
|  |     const item = this.getItem(event); | ||||||
|  |     return item?.sheet.render(true); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   _rechercherKeyup(event) { |   _rechercherKeyup(event) { | ||||||
|     const currentTarget = event.currentTarget; |     const currentTarget = event.currentTarget; | ||||||
|     const nouvelleRecherche = this._optionRecherche(currentTarget); |     const nouvelleRecherche = this._optionRecherche(currentTarget); | ||||||
| @@ -245,7 +196,7 @@ export class RdDBaseActorSheet extends ActorSheet { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async selectObjetTypeToCreate() { |   async selectObjetTypeToCreate() { | ||||||
|     let types = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type))); |     let types = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type))); | ||||||
|     let content = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`; |     let content = `<span class="generic-label">Selectionnez le type d'équipement</span><select class="item-type">`; | ||||||
|     for (let typeName of types) { |     for (let typeName of types) { | ||||||
|       content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>` |       content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>` | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ import { ChatUtility } from "../chat-utility.js"; | |||||||
| import { SYSTEM_SOCKET_ID } from "../constants.js"; | import { SYSTEM_SOCKET_ID } from "../constants.js"; | ||||||
| import { Grammar } from "../grammar.js"; | import { Grammar } from "../grammar.js"; | ||||||
| import { Monnaie } from "../item-monnaie.js"; | import { Monnaie } from "../item-monnaie.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { RdDAudio } from "../rdd-audio.js"; | import { RdDAudio } from "../rdd-audio.js"; | ||||||
| import { RdDConfirm } from "../rdd-confirm.js"; | import { RdDConfirm } from "../rdd-confirm.js"; | ||||||
| @@ -21,7 +21,7 @@ export class RdDBaseActor extends Actor { | |||||||
|  |  | ||||||
|   static $findCaracByName(carac, name) { |   static $findCaracByName(carac, name) { | ||||||
|     const caracList = Object.entries(carac); |     const caracList = Object.entries(carac); | ||||||
|     let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' }); |     let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique', onMessage: m => { } }); | ||||||
|     if (!entry || entry.length == 0) { |     if (!entry || entry.length == 0) { | ||||||
|       entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' }); |       entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' }); | ||||||
|     } |     } | ||||||
| @@ -81,7 +81,6 @@ export class RdDBaseActor extends Actor { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   static getRealActor(actorId, tokenId) { |   static getRealActor(actorId, tokenId) { | ||||||
|     if (tokenId) { |     if (tokenId) { | ||||||
|       let token = canvas.tokens.get(tokenId) |       let token = canvas.tokens.get(tokenId) | ||||||
| @@ -161,8 +160,11 @@ export class RdDBaseActor extends Actor { | |||||||
|     return RdDBaseActor.$findCaracByName(carac, name); |     return RdDBaseActor.$findCaracByName(carac, name); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   mapCarac(caracCode) { return caracCode } | ||||||
|  |  | ||||||
|   getCaracByName(name) { |   getCaracByName(name) { | ||||||
|     switch (Grammar.toLowerCaseNoAccent(name)) { |     name = this.mapCarac(Grammar.toLowerCaseNoAccent(name)) | ||||||
|  |     switch (name) { | ||||||
|       case 'reve-actuel': case 'reve actuel': |       case 'reve-actuel': case 'reve actuel': | ||||||
|         return this.getCaracReveActuel(); |         return this.getCaracReveActuel(); | ||||||
|       case 'chance-actuelle': case 'chance-actuelle': |       case 'chance-actuelle': case 'chance-actuelle': | ||||||
| @@ -735,25 +737,20 @@ export class RdDBaseActor extends Actor { | |||||||
|  |  | ||||||
|   actionImpossible(action) { |   actionImpossible(action) { | ||||||
|     ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`) |     ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`) | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } |   async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } | ||||||
|   async rollAppelChance() { this.actionImpossible("appel à la chance") } |   async rollAppelChance() { this.actionImpossible("appel à la chance") } | ||||||
|   async jetDeMoral() { this.actionImpossible("jet de moral") } |   async jetDeMoral() { this.actionImpossible("jet de moral") } | ||||||
|  |  | ||||||
|   async actionPrincipale(item, onActionItem = async () => { }) { |  | ||||||
|     switch (item.type) { |  | ||||||
|       case ITEM_TYPES.conteneur: return await item.sheet.render(true); |  | ||||||
|     } |  | ||||||
|     return undefined |  | ||||||
|   } |  | ||||||
|   async resetItemUse() { } |   async resetItemUse() { } | ||||||
|   async incDecItemUse(itemId, inc = 1) { } |   async incDecItemUse(itemId, inc = 1) { } | ||||||
|   getItemUse(itemId) { return 0; } |   getItemUse(itemId) { return 0; } | ||||||
|  |  | ||||||
|   async finDeRound(options = { terminer: false }) { } |   async finDeRound(options = { terminer: false }) { } | ||||||
|   isActorCombat() { return false } |   isActorCombat() { return false } | ||||||
|   getCaracInit(competence) { return 0 } |   getCaracInit(competence) { return 0 } | ||||||
|  |  | ||||||
|   listActionsCombat() { return [] } |   listActionsCombat() { return [] } | ||||||
|   listActionsPossessions() { |   listActionsPossessions() { | ||||||
|     return this.itemTypes[ITEM_TYPES.possession] |     return this.itemTypes[ITEM_TYPES.possession] | ||||||
|   | |||||||
| @@ -45,6 +45,7 @@ export class RdDCommerceSheet extends RdDBaseActorSheet { | |||||||
|     super.activateListeners(html); |     super.activateListeners(html); | ||||||
|  |  | ||||||
|     this.html.find('a.item-acheter').click(async event => await this.vente(this.getItem(event))); |     this.html.find('a.item-acheter').click(async event => await this.vente(this.getItem(event))); | ||||||
|  |     this.html.find('.service-acheter').click(async event => await this.vente(this.getItem(event))); | ||||||
|  |  | ||||||
|     if (!this.options.editable) return; |     if (!this.options.editable) return; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| import { ITEM_TYPES } from "../item.js"; | import { Grammar } from "../grammar.js"; | ||||||
|  | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { LIST_CARAC_AUTRES } from "../rdd-carac.js"; | ||||||
| import { RdDBaseActorSang } from "./base-actor-sang.js"; | import { RdDBaseActorSang } from "./base-actor-sang.js"; | ||||||
|  |  | ||||||
| export class RdDCreature extends RdDBaseActorSang { | export class RdDCreature extends RdDBaseActorSang { | ||||||
| @@ -32,4 +34,16 @@ export class RdDCreature extends RdDBaseActorSang { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   mapCarac(caracCode) { | ||||||
|  |     switch (caracCode) { | ||||||
|  |       case 'vue': case 'ouie': case 'odoratgout': case 'empathie': case 'perception': | ||||||
|  |         return 'perception' | ||||||
|  |       case 'agilite': | ||||||
|  |         return 'force' | ||||||
|  |       case 'force': case 'constitution': case 'taille': case 'reve': case 'volonte': | ||||||
|  |         return caracCode | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { RdDCarac } from "../rdd-carac.js"; | import { RdDCarac } from "../rdd-carac.js"; | ||||||
| import { RdDEncaisser } from "../rdd-roll-encaisser.js"; | import { RdDEncaisser } from "../rdd-roll-encaisser.js"; | ||||||
| @@ -117,4 +117,14 @@ export class RdDEntite extends RdDBaseActorReve { | |||||||
|       super.setEntiteReveAccordee(actor) |       super.setEntiteReveAccordee(actor) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   mapCarac(caracCode) { | ||||||
|  |     switch (caracCode) { | ||||||
|  |       case 'taille': | ||||||
|  |       case 'reve': | ||||||
|  |         return caracCode | ||||||
|  |     } | ||||||
|  |     return 'reve' | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,8 +6,8 @@ import { ExportScriptarium } from "./export-scriptarium.js"; | |||||||
| import { CATEGORIES_COMPETENCES, CATEGORIES_DRACONIC, Mapping } from "./mapping.js"; | import { CATEGORIES_COMPETENCES, CATEGORIES_DRACONIC, Mapping } from "./mapping.js"; | ||||||
|  |  | ||||||
| export class RdDActorExportSheet extends RdDActorSheet { | export class RdDActorExportSheet extends RdDActorSheet { | ||||||
|   static async init() { |   static init() { | ||||||
|     await loadTemplates([ |     loadTemplates([ | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs", |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs", | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs", |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs", | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs", |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs", | ||||||
| @@ -23,6 +23,7 @@ export class RdDActorExportSheet extends RdDActorSheet { | |||||||
|     ]) |     ]) | ||||||
|     Actors.registerSheet(SYSTEM_RDD, RdDActorExportSheet, { types: ["personnage"], makeDefault: false, label: "Feuille simplifiée" }) |     Actors.registerSheet(SYSTEM_RDD, RdDActorExportSheet, { types: ["personnage"], makeDefault: false, label: "Feuille simplifiée" }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static get defaultOptions() { |   static get defaultOptions() { | ||||||
|     return foundry.utils.mergeObject(RdDActorSheet.defaultOptions, { |     return foundry.utils.mergeObject(RdDActorSheet.defaultOptions, { | ||||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/actor-encart-sheet.hbs", |       template: "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/actor-encart-sheet.hbs", | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ACTOR_TYPES } from "../../item.js" | import { ACTOR_TYPES } from "../../constants.js" | ||||||
| import { Misc } from "../../misc.js" | import { Misc } from "../../misc.js" | ||||||
| import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js" | import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js" | ||||||
| import { Mapping } from "./mapping.js" | import { Mapping } from "./mapping.js" | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ import { Grammar } from "../../grammar.js" | |||||||
| import { RdDItemArme } from "../../item-arme.js" | import { RdDItemArme } from "../../item-arme.js" | ||||||
| import { RdDItemCompetence } from "../../item-competence.js" | import { RdDItemCompetence } from "../../item-competence.js" | ||||||
| import { RdDItemSort } from "../../item-sort.js" | import { RdDItemSort } from "../../item-sort.js" | ||||||
| import { ITEM_TYPES } from "../../item.js" | import { ITEM_TYPES } from "../../constants.js" | ||||||
| import { Misc } from "../../misc.js" | import { Misc } from "../../misc.js" | ||||||
| import { RdDTimestamp } from "../../time/rdd-timestamp.js" | import { RdDTimestamp } from "../../time/rdd-timestamp.js" | ||||||
| import { RdDBonus } from "../../rdd-bonus.js" | import { RdDBonus } from "../../rdd-bonus.js" | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import { Grammar } from "../grammar.js"; | |||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | ||||||
| import { RdDItemTete } from "../item/tete.js"; | import { RdDItemTete } from "../item/tete.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  |  | ||||||
| const WHITESPACES = "\\s+" | const WHITESPACES = "\\s+" | ||||||
| const NUMERIC = "[\\+\\-]?\\d+" | const NUMERIC = "[\\+\\-]?\\d+" | ||||||
| @@ -34,7 +34,6 @@ const XREGEXP_WEAPON_MANIEMENT = "(?<maniement>(" + Misc.join(Object.keys(MANIEM | |||||||
|  |  | ||||||
| const XREGEXP_SORT_VOIE = "(?<voies>[OHNT](\\/[OHNT])*)" | const XREGEXP_SORT_VOIE = "(?<voies>[OHNT](\\/[OHNT])*)" | ||||||
| const XREGEXP_SORT_NAME = "(?<name>[^\\(]+)" | const XREGEXP_SORT_NAME = "(?<name>[^\\(]+)" | ||||||
| // const XREGEXP_SORT_CASE = "(?<coord>([A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+|[A-M]\\d{1,2})+)" |  | ||||||
| const XREGEXP_SORT_CASE = "(?<coord>([A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+|[A-M]\\d{1,2}))" | const XREGEXP_SORT_CASE = "(?<coord>([A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+|[A-M]\\d{1,2}))" | ||||||
|  |  | ||||||
| const XREGEXP_SORT = "(" + XREGEXP_SORT_VOIE | const XREGEXP_SORT = "(" + XREGEXP_SORT_VOIE | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								module/apps/rdd-text-roll-editor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								module/apps/rdd-text-roll-editor.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | import "./xregexp-all.js"; | ||||||
|  | import { SystemCompendiums } from "../settings/system-compendiums.js"; | ||||||
|  | import { ACTOR_TYPES } from "../constants.js"; | ||||||
|  | import { TextRollAlchimie } from "./textroll/text-roll-alchimie.js"; | ||||||
|  | import { TextRollCaracCompetence } from "./textroll/text-roll-carac-competence.js"; | ||||||
|  | import { TextRollFormula } from "./textroll/text-roll-formula.js"; | ||||||
|  | import { TextRollManager } from "./textroll/text-roll-formatter.js"; | ||||||
|  |  | ||||||
|  | const TEXT_ROLL_MANAGERS = [ | ||||||
|  |   new TextRollAlchimie(), | ||||||
|  |   new TextRollCaracCompetence(), | ||||||
|  |   new TextRollFormula()] | ||||||
|  |  | ||||||
|  | export class RdDTextEditor { | ||||||
|  |   static registerChatCallbacks(html) { | ||||||
|  |     html.on("click", '.roll-text', async event => await RdDTextEditor.rollText(event)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async enrichHTML(text, object, options = {showlink:true}) { | ||||||
|  |     const context = { | ||||||
|  |       text, | ||||||
|  |       object, | ||||||
|  |       options, | ||||||
|  |       competences: await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage), | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (let manager of TEXT_ROLL_MANAGERS) { | ||||||
|  |       context.code = manager.code | ||||||
|  |       context.template = manager.template | ||||||
|  |       context.text = await manager.onReplaceRoll(context); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return await TextEditor.enrichHTML(context.text, { | ||||||
|  |       relativeTo: object, | ||||||
|  |       secrets: object?.isOwner, | ||||||
|  |       async: true | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async _applyReplaceAll(manager, context) { | ||||||
|  |     context.code = manager.code | ||||||
|  |     context.template = manager.template | ||||||
|  |     context.text = await manager.onReplaceRoll(context); | ||||||
|  |     return context.text | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static getEventElement(event) { | ||||||
|  |     return $(event.currentTarget)?.parents(".roll-text-link"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async rollText(event, actor) { | ||||||
|  |     const code = TextRollManager.getNode(event)?.data('code') | ||||||
|  |     const manager = TEXT_ROLL_MANAGERS.find(it => it.code == code) | ||||||
|  |     if (manager) { | ||||||
|  |       await manager.onRollText(event, actor) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async chatRollText(event) { | ||||||
|  |     const node = TextRollManager.getNode(event); | ||||||
|  |     if (node) { | ||||||
|  |       const code = node.data('code') | ||||||
|  |       const param = node.data('json') | ||||||
|  |       const manager = TEXT_ROLL_MANAGERS.find(it => it.code == code) | ||||||
|  |  | ||||||
|  |       const text = await TextRollManager.createRollText( | ||||||
|  |         { | ||||||
|  |           code, | ||||||
|  |           template: manager.template, | ||||||
|  |           options: { showLink: false } | ||||||
|  |         }, | ||||||
|  |         param) | ||||||
|  |       ChatMessage.create({ | ||||||
|  |         content: text | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										79
									
								
								module/apps/textroll/text-roll-alchimie.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								module/apps/textroll/text-roll-alchimie.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | import "../xregexp-all.js"; | ||||||
|  | import { ACTOR_TYPES, ITEM_TYPES } from "../../constants.js"; | ||||||
|  | import { RdDCarac } from "../../rdd-carac.js"; | ||||||
|  | import { RdDUtility } from "../../rdd-utility.js"; | ||||||
|  | import { RdDAlchimie } from "../../rdd-alchimie.js"; | ||||||
|  | import { TextRollManager } from "./text-roll-formatter.js"; | ||||||
|  |  | ||||||
|  | const REGEX_ALCHIMIE_TERMES = "(?<termes>(\\w|-)+)" | ||||||
|  | const REGEX_ALCHIMIE_MANIP = "(?<manip>(couleur|consistance))" | ||||||
|  | const XREGEXP_ROLL_ALCHIMIE = XRegExp("@roll\\[" + REGEX_ALCHIMIE_MANIP + "\\s+" + REGEX_ALCHIMIE_TERMES + "\\]", 'giu') | ||||||
|  | const XREGEXP_ROLL_ALCHIMIE_MANIP = XRegExp("@" + REGEX_ALCHIMIE_MANIP + "\\{" + REGEX_ALCHIMIE_TERMES + "\\}", 'giu') | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * classe pour gérer les jets d'alchimie | ||||||
|  |  */ | ||||||
|  | export class TextRollAlchimie { | ||||||
|  |   get code() { return 'alchimie' } | ||||||
|  |   get template() { return `systems/foundryvtt-reve-de-dragon/templates/apps/textroll/link-text-roll-alchimie.hbs` } | ||||||
|  |  | ||||||
|  |   async onReplaceRoll(context) { | ||||||
|  |     const handler = new AlchimieTextBuilder(context) | ||||||
|  |     return await handler.replaceAll() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onRollText(event, actor) { | ||||||
|  |     actor = this.getSelectedActor(actor) | ||||||
|  |     if (actor) { | ||||||
|  |       const node = TextRollManager.getNode(event) | ||||||
|  |       const recetteId = node.data('recetteid') | ||||||
|  |       const manip = node.data('manip') | ||||||
|  |       const termes = node.data('termes') | ||||||
|  |       if (recetteId) { | ||||||
|  |         await actor.effectuerTacheAlchimie(recetteId, manip, termes) | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         const carac = RdDCarac.caracDetails(RdDAlchimie.getCaracTache(manip)) | ||||||
|  |         const diff = RdDAlchimie.getDifficulte(termes) | ||||||
|  |         await actor.rollCaracCompetence(carac.code, 'Alchimie', diff) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getSelectedActor(actor) { | ||||||
|  |     actor = actor ?? RdDUtility.getSelectedActor() | ||||||
|  |     if (actor && actor.type == ACTOR_TYPES.personnage) { | ||||||
|  |       return actor | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class AlchimieTextBuilder { | ||||||
|  |   constructor(context) { | ||||||
|  |     this.context = context | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async replaceAll() { | ||||||
|  |     await XRegExp.forEach(this.context.text, XREGEXP_ROLL_ALCHIMIE, async (rollMatch, i) => await this.replaceMatch(rollMatch, i)) | ||||||
|  |     await XRegExp.forEach(this.context.text, XREGEXP_ROLL_ALCHIMIE_MANIP, async (rollMatch, i) => await this.replaceMatch(rollMatch, i)) | ||||||
|  |     return this.context.text | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async replaceMatch(rollMatch, i) { | ||||||
|  |     if (rollMatch.termes && rollMatch.manip) { | ||||||
|  |       const manip = rollMatch.manip | ||||||
|  |       const termes = rollMatch.termes | ||||||
|  |       const carac = RdDCarac.caracDetails(RdDAlchimie.getCaracTache(manip)) | ||||||
|  |       const diff = RdDAlchimie.getDifficulte(termes) | ||||||
|  |       const recette = (this.context.object instanceof Item && this.context.object.type == ITEM_TYPES.recettealchimique) ? this.context.object : undefined | ||||||
|  |       const replacement = await TextRollManager.createRollText(this.context, | ||||||
|  |         { | ||||||
|  |           code: this.context.code, | ||||||
|  |           manip, termes, carac, diff, recetteid: recette?.id, | ||||||
|  |         }) | ||||||
|  |       this.context.text = this.context.text.replace(rollMatch[0], replacement); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										98
									
								
								module/apps/textroll/text-roll-carac-competence.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								module/apps/textroll/text-roll-carac-competence.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | import "../xregexp-all.js"; | ||||||
|  | import { RdDCarac } from "../../rdd-carac.js"; | ||||||
|  | import { RdDItemCompetence } from "../../item-competence.js"; | ||||||
|  | import { RdDUtility } from "../../rdd-utility.js"; | ||||||
|  | import { TextRollManager } from "./text-roll-formatter.js"; | ||||||
|  |  | ||||||
|  | const REGECP_CARAC = "(?<carac>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)" | ||||||
|  | const REGEXP_COMP = "(\\/(?<competence>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?" | ||||||
|  | const REGEXP_DIFF = "(/(?<diff>[\\+\\-]?\\d+(d\\d+)?))?" | ||||||
|  | const REGEXP_ROLL_CARAC_COMP = REGECP_CARAC + REGEXP_COMP + REGEXP_DIFF | ||||||
|  | const XREGEXP_ROLL_CARAC_COMP = XRegExp("@roll\\[" + REGEXP_ROLL_CARAC_COMP + "\\]", 'giu') | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * classe pour gérer les jets de caractéristique/compétence depuis | ||||||
|  |  * les journaux/descriptions | ||||||
|  |  */ | ||||||
|  | export class TextRollCaracCompetence { | ||||||
|  |   get code() { return 'carac' } | ||||||
|  |   get template() { return `systems/foundryvtt-reve-de-dragon/templates/apps/textroll/link-text-roll-carac-competence.hbs` } | ||||||
|  |  | ||||||
|  |   async onReplaceRoll(context) { | ||||||
|  |     const handler = new CaracCompetenceTextBuilder(context) | ||||||
|  |     return await handler.replaceAll() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onRollText(event, actor) { | ||||||
|  |     const node = TextRollManager.getNode(event) | ||||||
|  |     const caracCode = node.data('carac-code') | ||||||
|  |     if (caracCode) { | ||||||
|  |       const competence = node.data('competence') | ||||||
|  |       const diff = await this.calculDiff(node) | ||||||
|  |       const actors = this.getSelectedActors(actor) | ||||||
|  |       actors.forEach(async it => await this.doRoll(it, caracCode, competence, diff)) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async calculDiff(node) { | ||||||
|  |     const diff = node.data('diff') ?? 0 | ||||||
|  |     if (!Number.isInteger(diff)) { | ||||||
|  |       const roll = new Roll(diff) | ||||||
|  |       await roll.evaluate() | ||||||
|  |       await roll.toMessage({ flavor: `La difficulté de ${diff} a donné ${roll.total}` }) | ||||||
|  |       return roll.total | ||||||
|  |     } | ||||||
|  |     return diff | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async doRoll(actor, caracCode, competence, diff) { | ||||||
|  |     caracCode = actor.mapCarac(caracCode) | ||||||
|  |     if (caracCode) { | ||||||
|  |       if (competence) { | ||||||
|  |         await actor.rollCaracCompetence(caracCode, competence, diff) | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         await actor.rollCarac(caracCode, { diff }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getSelectedActors(actor) { | ||||||
|  |     const selected = canvas.tokens.controlled.map(it => it.actor).filter(it => it) | ||||||
|  |     if (selected.length > 0) { | ||||||
|  |       return selected | ||||||
|  |     } | ||||||
|  |     actor = actor ?? RdDUtility.getSelectedActor() | ||||||
|  |     if (actor) { | ||||||
|  |       return [actor] | ||||||
|  |     } | ||||||
|  |     return [] | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class CaracCompetenceTextBuilder { | ||||||
|  |   constructor(context) { | ||||||
|  |     this.context = context | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async replaceAll() { | ||||||
|  |     await XRegExp.forEach(this.context.text, XREGEXP_ROLL_CARAC_COMP, async (rollMatch, i) => await this.replaceMatch(rollMatch, i)) | ||||||
|  |     return this.context.text | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async replaceMatch(rollMatch, i) { | ||||||
|  |     const carac = RdDCarac.caracDetails(rollMatch.carac) | ||||||
|  |     if (carac) { | ||||||
|  |       const competence = rollMatch.competence ? RdDItemCompetence.findCompetence(this.context.competences, rollMatch.competence) : undefined | ||||||
|  |       const replacement = await TextRollManager.createRollText(this.context, | ||||||
|  |         { | ||||||
|  |           code: this.context.code, | ||||||
|  |           carac: carac, | ||||||
|  |           competence: competence?.name, | ||||||
|  |           diff: rollMatch.diff, | ||||||
|  |         }) | ||||||
|  |       this.context.text = this.context.text.replace(rollMatch[0], replacement) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								module/apps/textroll/text-roll-formatter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								module/apps/textroll/text-roll-formatter.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  |  | ||||||
|  | export class TextRollManager { | ||||||
|  |  | ||||||
|  |   static async createRollText(context, param) { | ||||||
|  |     return await renderTemplate(context.template, { | ||||||
|  |       param, options: context.options | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static getNode(event) { | ||||||
|  |     return $(event.currentTarget)?.parents(".roll-text-link"); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								module/apps/textroll/text-roll-formula.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								module/apps/textroll/text-roll-formula.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | import "../xregexp-all.js"; | ||||||
|  | import { TextRollManager } from "./text-roll-formatter.js"; | ||||||
|  |  | ||||||
|  | const REGEXP_ROLL_FORMULA = "(?<formula>[^\\[\\]]+)" | ||||||
|  | const XREGEXP_ROLL_FORMULA = XRegExp("@roll\\[" + REGEXP_ROLL_FORMULA + "\\]", 'giu') | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * classe pour gérer les jets de dés (formules Foundry) | ||||||
|  |  */ | ||||||
|  | export class TextRollFormula { | ||||||
|  |   get code() { return 'formula' } | ||||||
|  |   get template() { return `systems/foundryvtt-reve-de-dragon/templates/apps/textroll/link-text-roll-formula.hbs` } | ||||||
|  |  | ||||||
|  |   async onReplaceRoll(context) { | ||||||
|  |     const handler = new FormulaTextBuilder(context) | ||||||
|  |     return await handler.replaceAll() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onRollText(event, actor) { | ||||||
|  |     const node = TextRollManager.getNode(event) | ||||||
|  |     const rollFormula = node.data('formula') | ||||||
|  |     if (rollFormula) { | ||||||
|  |       const roll = new Roll(rollFormula) | ||||||
|  |       await roll.evaluate() | ||||||
|  |       await roll.toMessage() | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class FormulaTextBuilder { | ||||||
|  |   constructor(context) { | ||||||
|  |     this.context = context | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async replaceAll() { | ||||||
|  |     await XRegExp.forEach(this.context.text, XREGEXP_ROLL_FORMULA, | ||||||
|  |       async (rollMatch, i) => await this.replaceMatch(rollMatch, i)) | ||||||
|  |     return this.context.text | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async replaceMatch(rollMatch, i) { | ||||||
|  |     if (rollMatch.formula) { | ||||||
|  |       const replacement = await TextRollManager.createRollText(this.context, | ||||||
|  |         { | ||||||
|  |           code: this.context.code, | ||||||
|  |           formula: rollMatch.formula, | ||||||
|  |         }) | ||||||
|  |       this.context.text = this.context.text.replace(rollMatch[0], replacement) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -2002,7 +2002,7 @@ XRegExp.exec = function (str, regex, pos, sticky) { | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
| XRegExp.forEach = function (str, regex, callback) { | XRegExp.forEach = async function (str, regex, callback) { | ||||||
|   var pos = 0; |   var pos = 0; | ||||||
|   var i = -1; |   var i = -1; | ||||||
|   var match; |   var match; | ||||||
| @@ -2014,7 +2014,7 @@ XRegExp.forEach = function (str, regex, callback) { | |||||||
|     // at least. Actually, because of the way `XRegExp.exec` caches globalized versions of |     // at least. Actually, because of the way `XRegExp.exec` caches globalized versions of | ||||||
|     // regexes, mutating the regex will not have any effect on the iteration or matched strings, |     // regexes, mutating the regex will not have any effect on the iteration or matched strings, | ||||||
|     // which is a nice side effect that brings extra safety. |     // which is a nice side effect that brings extra safety. | ||||||
|     callback(match, ++i, str, regex); |     await callback(match, ++i, str, regex); | ||||||
|     pos = match.index + (match[0].length || 1); |     pos = match.index + (match[0].length || 1); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
|  | import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -198,6 +199,7 @@ export class ChatUtility { | |||||||
|   static async onCreateChatMessage(chatMessage, options, id) { |   static async onCreateChatMessage(chatMessage, options, id) { | ||||||
|     if (chatMessage.isAuthor) { |     if (chatMessage.isAuthor) { | ||||||
|       await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp()); |       await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp()); | ||||||
|  |       await chatMessage.update({ content: await RdDTextEditor.enrichHTML(chatMessage.content, undefined, {showLink:false}) }) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| import { RdDBaseActor } from "../actor/base-actor.js"; | import { RdDBaseActor } from "../actor/base-actor.js"; | ||||||
| import { ChatUtility } from "../chat-utility.js"; | import { ChatUtility } from "../chat-utility.js"; | ||||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; |  | ||||||
|  |  | ||||||
| const INFO_COEUR = 'info-coeur'; | const INFO_COEUR = 'info-coeur'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,13 +1,13 @@ | |||||||
| export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon'; | export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon' | ||||||
| export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon'; | export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon' | ||||||
| export const LOG_HEAD = 'RdD | '; | export const LOG_HEAD = 'RdD | ' | ||||||
|  |  | ||||||
| export const HIDE_DICE = 'hide'; | export const HIDE_DICE = 'hide' | ||||||
| export const SHOW_DICE = 'show'; | export const SHOW_DICE = 'show' | ||||||
|  |  | ||||||
| export const ENTITE_INCARNE = 'incarne'; | export const ENTITE_INCARNE = 'incarne' | ||||||
| export const ENTITE_NONINCARNE = 'nonincarne'; | export const ENTITE_NONINCARNE = 'nonincarne' | ||||||
| export const ENTITE_BLURETTE = 'blurette'; | export const ENTITE_BLURETTE = 'blurette' | ||||||
|  |  | ||||||
| export const RDD_CONFIG = { | export const RDD_CONFIG = { | ||||||
|   niveauEthylisme : [ |   niveauEthylisme : [ | ||||||
| @@ -50,4 +50,59 @@ export const RDD_CONFIG = { | |||||||
|     {value: "Rare", label: "Rare"}, |     {value: "Rare", label: "Rare"}, | ||||||
|     {value: "Rarissime", label: "Rarissime"} |     {value: "Rarissime", label: "Rarissime"} | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export const ACTOR_TYPES = { | ||||||
|  |   personnage: 'personnage', | ||||||
|  |   creature: 'creature', | ||||||
|  |   entite: 'entite', | ||||||
|  |   commerce: 'commerce', | ||||||
|  |   vehicule: 'vehicule' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const ITEM_TYPES = { | ||||||
|  |   competence: 'competence', | ||||||
|  |   competencecreature: 'competencecreature', | ||||||
|  |   empoignade: 'empoignade', | ||||||
|  |   possession: 'possession', | ||||||
|  |   blessure: 'blessure', | ||||||
|  |   maladie: 'maladie', | ||||||
|  |   poison: 'poison', | ||||||
|  |   arme: 'arme', | ||||||
|  |   armure: 'armure', | ||||||
|  |   conteneur: 'conteneur', | ||||||
|  |   objet: 'objet', | ||||||
|  |   monnaie: 'monnaie', | ||||||
|  |   gemme: 'gemme', | ||||||
|  |   munition: 'munition', | ||||||
|  |   nourritureboisson: 'nourritureboisson', | ||||||
|  |   herbe: 'herbe', | ||||||
|  |   plante: 'plante', | ||||||
|  |   ingredient: 'ingredient', | ||||||
|  |   faune: 'faune', | ||||||
|  |   livre: 'livre', | ||||||
|  |   potion: 'potion', | ||||||
|  |   service: 'service', | ||||||
|  |   musique: 'musique', | ||||||
|  |   danse: 'danse', | ||||||
|  |   chant: 'chant', | ||||||
|  |   jeu: 'jeu', | ||||||
|  |   race: 'race', | ||||||
|  |   recettecuisine: 'recettecuisine', | ||||||
|  |   oeuvre: 'oeuvre', | ||||||
|  |   recettealchimique: 'recettealchimique', | ||||||
|  |   tache: 'tache', | ||||||
|  |   sort: 'sort', | ||||||
|  |   sortreserve: 'sortreserve', | ||||||
|  |   rencontre: 'rencontre', | ||||||
|  |   queue: 'queue', | ||||||
|  |   ombre: 'ombre', | ||||||
|  |   souffle: 'souffle', | ||||||
|  |   tete: 'tete', | ||||||
|  |   casetmr: 'casetmr', | ||||||
|  |   meditation: 'meditation', | ||||||
|  |   signedraconique: 'signedraconique', | ||||||
|  |   tarot: 'tarot', | ||||||
|  |   nombreastral: 'nombreastral', | ||||||
|  |   extraitpoetique: 'extraitpoetique', | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js" | import { RdDItemCompetenceCreature } from "./item-competencecreature.js" | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { BASE_CORPS_A_CORPS } from "./item/base-items.js"; | import { BASE_CORPS_A_CORPS } from "./item/base-items.js"; | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
|  |  | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
|  |  | ||||||
| export const CATEGORIES_COMPETENCES_CREATURES = { | export const CATEGORIES_COMPETENCES_CREATURES = { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { LOG_HEAD } from "./constants.js"; | import { ITEM_TYPES, LOG_HEAD } from "./constants.js"; | ||||||
|  |  | ||||||
| const MONNAIE_ETAIN = { | const MONNAIE_ETAIN = { | ||||||
|   name: "Denier (étain)", type: 'monnaie', |   name: "Denier (étain)", type: 'monnaie', | ||||||
| @@ -70,18 +70,17 @@ export class Monnaie { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getFortune(monnaies) { |   static getFortune(monnaies) { | ||||||
|     return (monnaies??[]) |     return (monnaies ?? []) | ||||||
|       .map(m => Number(m.system.cout) * Number(m.system.quantite)) |       .map(m => Number(m.system.cout) * Number(m.system.quantite)) | ||||||
|       .reduce(Misc.sum(), 0); |       .reduce(Misc.sum(), 0); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async optimiserFortune(actor, fortune) { |   static async optimiserFortune(actor, fortune) { | ||||||
|  |     Monnaie.validerMonnaies(actor) | ||||||
|     let resteEnDeniers = Math.round(fortune * 100); |     let resteEnDeniers = Math.round(fortune * 100); | ||||||
|     let monnaies = actor.itemTypes['monnaie']; |     const updates = [] | ||||||
|     let updates = []; |  | ||||||
|     Monnaie.validerMonnaies(monnaies, actor); |  | ||||||
|  |  | ||||||
|     let parValeur = Misc.classifyFirst(monnaies, it => VALEUR_DENIERS(it.system.cout)); |     const  parValeur = Misc.classifyFirst(actor.itemTypes[ITEM_TYPES.monnaie], it => VALEUR_DENIERS(it.system.cout)); | ||||||
|     for (let valeurDeniers of [1000, 100, 10, 1]) { |     for (let valeurDeniers of [1000, 100, 10, 1]) { | ||||||
|       const itemPiece = parValeur[valeurDeniers]; |       const itemPiece = parValeur[valeurDeniers]; | ||||||
|       if (itemPiece) { |       if (itemPiece) { | ||||||
| @@ -102,8 +101,11 @@ export class Monnaie { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static validerMonnaies(monnaies, actor = undefined) { |   static validerMonnaies(actor) { | ||||||
|     monnaies.filter(it => VALEUR_DENIERS(it.system.cout) == 0) |     if (!actor) { | ||||||
|  |       return | ||||||
|  |      } | ||||||
|  |     actor.itemTypes[ITEM_TYPES.monnaie]?.filter(it => VALEUR_DENIERS(it.system.cout) == 0) | ||||||
|       .map(it => `La  monnaie ${it.name} de l'acteur ${actor?.name ?? 'sélectionné'} a une valeur de 0!`) |       .map(it => `La  monnaie ${it.name} de l'acteur ${actor?.name ?? 'sélectionné'} a une valeur de 0!`) | ||||||
|       .forEach(message => { |       .forEach(message => { | ||||||
|         ui.notifications.warn(message); |         ui.notifications.warn(message); | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
|  | import { ACTOR_TYPES, ITEM_TYPES } from "./constants.js"; | ||||||
| import { RdDItemSort } from "./item-sort.js"; | import { RdDItemSort } from "./item-sort.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
| import { RdDAlchimie } from "./rdd-alchimie.js"; |  | ||||||
| import { RdDItemCompetence } from "./item-competence.js"; | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
| import { RdDHerbes } from "./rdd-herbes.js"; |  | ||||||
| import { RdDGemme } from "./rdd-gemme.js"; | import { RdDGemme } from "./rdd-gemme.js"; | ||||||
| import { HtmlUtility } from "./html-utility.js"; | import { HtmlUtility } from "./html-utility.js"; | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| @@ -12,8 +11,10 @@ import { SystemCompendiums } from "./settings/system-compendiums.js"; | |||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||||
| import { ITEM_TYPES, RdDItem } from "./item.js"; | import { RdDItem } from "./item.js"; | ||||||
| import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; | import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; | ||||||
|  | import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||||
|  | import { ItemAction } from "./item/item-actions.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Extend the basic ItemSheet for RdD specific items |  * Extend the basic ItemSheet for RdD specific items | ||||||
| @@ -26,8 +27,8 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|  |  | ||||||
|   static defaultTemplate(type) { |   static defaultTemplate(type) { | ||||||
|     return type ? |     return type ? | ||||||
|       `systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html` : |       `systems/foundryvtt-reve-de-dragon/templates/item/${type}-sheet.hbs` : | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/item-sheet.html"; |       "systems/foundryvtt-reve-de-dragon/templates/item/item-sheet.hbs"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static register(sheetClass) { |   static register(sheetClass) { | ||||||
| @@ -97,11 +98,11 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|       name: this.item.name, |       name: this.item.name, | ||||||
|       system: this.item.system, |       system: this.item.system, | ||||||
|       actorId: this.actor?.id, |       actorId: this.actor?.id, | ||||||
|       description: await TextEditor.enrichHTML(this.item.system.description, { async: true }), |       description: await RdDTextEditor.enrichHTML(this.item.system.description, this.item), | ||||||
|       descriptionmj: await TextEditor.enrichHTML(this.item.system.descriptionmj, { async: true }), |       descriptionmj: await RdDTextEditor.enrichHTML(this.item.system.descriptionmj, this.item), | ||||||
|       isComestible: this.item.getUtilisationCuisine(), |       isComestible: this.item.getUtilisationCuisine(), | ||||||
|       options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable), |       options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable), | ||||||
|       competences: await SystemCompendiums.getCompetences('personnage'), |       competences: await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage), | ||||||
|       categories: RdDItem.getCategories(this.item.type), |       categories: RdDItem.getCategories(this.item.type), | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -120,26 +121,23 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|       formData.competences = formData.competences.filter(it => it.isCompetenceArme()) |       formData.competences = formData.competences.filter(it => it.isCompetenceArme()) | ||||||
|     } |     } | ||||||
|     if (this.item.type == ITEM_TYPES.recettecuisine) { |     if (this.item.type == ITEM_TYPES.recettecuisine) { | ||||||
|       formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, { async: true }) |       formData.ingredients = await RdDTextEditor.enrichHTML(this.item.system.ingredients, this.item) | ||||||
|     } |     } | ||||||
|     if (this.item.type == ITEM_TYPES.extraitpoetique) { |     if (this.item.type == ITEM_TYPES.extraitpoetique) { | ||||||
|       formData.extrait = await TextEditor.enrichHTML(this.object.system.extrait, { async: true }) |       formData.extrait = await RdDTextEditor.enrichHTML(this.item.system.extrait, this.item) | ||||||
|       formData.texte = await TextEditor.enrichHTML(this.object.system.texte, { async: true }) |       formData.texte = await RdDTextEditor.enrichHTML(this.item.system.texte, this.item) | ||||||
|     } |     } | ||||||
|     if (this.item.type == ITEM_TYPES.recettealchimique) { |     if (this.item.type == ITEM_TYPES.recettealchimique) { | ||||||
|       RdDAlchimie.processManipulation(this.item, this.actor?.id); |       formData.manipulation = await RdDTextEditor.enrichHTML(this.item.system.manipulation, this.item) | ||||||
|       formData.manipulation_update = await TextEditor.enrichHTML(this.object.system.manipulation_update, { async: true }) |       formData.utilisation = await RdDTextEditor.enrichHTML(this.item.system.utilisation, this.item) | ||||||
|       formData.utilisation = await TextEditor.enrichHTML(this.object.system.utilisation, { async: true }) |       formData.enchantement = await RdDTextEditor.enrichHTML(this.item.system.enchantement, this.item) | ||||||
|       formData.enchantement = await TextEditor.enrichHTML(this.object.system.enchantement, { async: true }) |       formData.sureffet = await RdDTextEditor.enrichHTML(this.item.system.sureffet, this.item) | ||||||
|       formData.sureffet = await TextEditor.enrichHTML(this.object.system.sureffet, { async: true }) |  | ||||||
|     } |     } | ||||||
|     if (this.item.type == ITEM_TYPES.gemme) { |     if (this.item.type == ITEM_TYPES.gemme) { | ||||||
|       formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); |       formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); | ||||||
|       RdDGemme.calculDataDerivees(this.item) |       RdDGemme.calculDataDerivees(this.item) | ||||||
|     } |     } | ||||||
|     if (this.item.type == ITEM_TYPES.potion) { |  | ||||||
|       RdDHerbes.calculFormData(formData, this.item) |  | ||||||
|     } |  | ||||||
|     if (this.item.type == ITEM_TYPES.herbe) { |     if (this.item.type == ITEM_TYPES.herbe) { | ||||||
|       if (formData.options.isOwned && ['Soin', 'Repos'].includes(formData.system.categorie)) { |       if (formData.options.isOwned && ['Soin', 'Repos'].includes(formData.system.categorie)) { | ||||||
|         formData.isIngredientPotionBase = true; |         formData.isIngredientPotionBase = true; | ||||||
| @@ -194,38 +192,22 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|       this.supprimerBonusCase(event.currentTarget.attributes['data-deleteCoord'].value) |       this.supprimerBonusCase(event.currentTarget.attributes['data-deleteCoord'].value) | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     this.html.find('.date-enchantement').change((event) => { |  | ||||||
|       const jour = Number(this.html.find('input.date-enchantement[name="enchantement.jour"]').val()); |  | ||||||
|       const mois = RdDTimestamp.definition(this.html.find('select.date-enchantement[name="enchantement.mois"]').val()); |  | ||||||
|       const indexDate = game.system.rdd.calendrier.getIndexFromDate(jour, mois.heure); |  | ||||||
|       this.item.update({ 'system.prdate': indexDate }); |  | ||||||
|       console.warn(`Date d'enchantement modifiée ${jour}/${mois.heure}: ${indexDate}`) |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item)); |     this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item)); | ||||||
|     this.html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item, this.getActionRenderItem())); |  | ||||||
|     this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).actionHerbe(this.item)); |     this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).actionHerbe(this.item)); | ||||||
|     this.html.find('input[name="system.cacher_points_de_tache"]').change(async event => await this.item.update({ 'system.cacher_points_de_tache': event.currentTarget.checked })); |     this.html.find('input[name="system.cacher_points_de_tache"]').change(async event => await this.item.update({ 'system.cacher_points_de_tache': event.currentTarget.checked })); | ||||||
|  |  | ||||||
|     this.html.find('.alchimie-tache a').click((event) => { |     this.html.find('.roll-text').click(async event => await RdDTextEditor.rollText(event, this.actor)) | ||||||
|       let actor = this._getEventActor(event); |     this.html.find('.chat-roll-text').click(async event => await RdDTextEditor.chatRollText(event)) | ||||||
|       if (actor) { |  | ||||||
|         let recetteId = event.currentTarget.attributes['data-recette-id'].value; |  | ||||||
|         let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value; |  | ||||||
|         let tacheData = event.currentTarget.attributes['data-alchimie-data'].value; |  | ||||||
|         actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData); |  | ||||||
|       } else { |  | ||||||
|         ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique."); |  | ||||||
|       } |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     if (this.actor) { |     if (this.actor) { | ||||||
|       this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, this.getActionRenderItem())); |       // TODO | ||||||
|  |       this.html.find('.actionItem').click(event => ItemAction.onActionItem(event, this.actor, this.options)) | ||||||
|  |  | ||||||
|  |       this.html.find('.item-potion-consommer').click(event => this.itemActionConsommer(event)) | ||||||
|  |  | ||||||
|  |       this.html.find('.item-split').click( event => this.itemActionSplit(event)) | ||||||
|       this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)); |       this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)); | ||||||
|       this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor))); |       this.html.find('.item-delete').click(async event => this.itemActionDelete(event)); | ||||||
|       this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); |  | ||||||
|       this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat()); |  | ||||||
|       this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, this.getActionRenderItem())); |  | ||||||
|  |  | ||||||
|       this.html.find('.item-quantite-plus').click(async event => { |       this.html.find('.item-quantite-plus').click(async event => { | ||||||
|         await this.actor.itemQuantiteIncDec(RdDSheetUtility.getItemId(event), 1) |         await this.actor.itemQuantiteIncDec(RdDSheetUtility.getItemId(event), 1) | ||||||
| @@ -243,13 +225,24 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|     RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.fin', updateItemTimestamp); |     RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.fin', updateItemTimestamp); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getActionRenderItem() { |   itemActionDelete(event) { | ||||||
|     return async () => { |     const item = RdDSheetUtility.getItem(event, this.actor) | ||||||
|       let item = this.item; |     return RdDUtility.confirmActorItemDelete(item, this.actor) | ||||||
|       while (item) { |   } | ||||||
|         await item.sheet?.render() |  | ||||||
|         item = this.actor.getContenant(item) |   async itemActionConsommer(event) { | ||||||
|       } |     const item = RdDSheetUtility.getItem(event, this.actor) | ||||||
|  |     if (item) { | ||||||
|  |       await actor.consommerPotion(item) | ||||||
|  |       await RdDSheetUtility.renderItemBranch(this.actor, item) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async itemActionSplit(event) { | ||||||
|  |     const item = RdDSheetUtility.getItem(event, this.actor) | ||||||
|  |     if (item) { | ||||||
|  |       await RdDSheetUtility.splitItem(item, this.actor) | ||||||
|  |       await RdDSheetUtility.renderItemBranch(this.actor, item) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -272,7 +265,7 @@ export class RdDItemSheet extends ItemSheet { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async supprimerBonusCase(deleteCoord){ |   async supprimerBonusCase(deleteCoord) { | ||||||
|     if (this.item.type == ITEM_TYPES.sort) { |     if (this.item.type == ITEM_TYPES.sort) { | ||||||
|       const oldList = RdDItemSort.getBonusCaseList(this.item) |       const oldList = RdDItemSort.getBonusCaseList(this.item) | ||||||
|       const newList = oldList.filter(it => it.case != deleteCoord); |       const newList = oldList.filter(it => it.case != deleteCoord); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { RdDItemCompetence } from "./item-competence.js"; | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; | import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										204
									
								
								module/item.js
									
									
									
									
									
								
							
							
						
						
									
										204
									
								
								module/item.js
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | |||||||
|  | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { DialogItemVente } from "./achat-vente/dialog-item-vente.js"; | import { DialogItemVente } from "./achat-vente/dialog-item-vente.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDHerbes } from "./rdd-herbes.js"; |  | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
| import { SystemCompendiums } from "./settings/system-compendiums.js"; | import { SystemCompendiums } from "./settings/system-compendiums.js"; | ||||||
| @@ -9,61 +9,7 @@ import { RdDRaretes } from "./item/raretes.js"; | |||||||
| import { CATEGORIES_COMPETENCES } from "./item-competence.js"; | import { CATEGORIES_COMPETENCES } from "./item-competence.js"; | ||||||
| import { CATEGORIES_COMPETENCES_CREATURES } from "./item-competencecreature.js"; | import { CATEGORIES_COMPETENCES_CREATURES } from "./item-competencecreature.js"; | ||||||
| import { BASE_CORPS_A_CORPS, BASE_ESQUIVE } from "./item/base-items.js"; | import { BASE_CORPS_A_CORPS, BASE_ESQUIVE } from "./item/base-items.js"; | ||||||
|  | import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js"; | ||||||
| export const ACTOR_TYPES = { |  | ||||||
|   personnage: 'personnage', |  | ||||||
|   creature: 'creature', |  | ||||||
|   entite: 'entite', |  | ||||||
|   commerce: 'commerce', |  | ||||||
|   vehicule: 'vehicule' |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export const ITEM_TYPES = { |  | ||||||
|   competence: 'competence', |  | ||||||
|   competencecreature: 'competencecreature', |  | ||||||
|   empoignade: 'empoignade', |  | ||||||
|   possession: 'possession', |  | ||||||
|   blessure: 'blessure', |  | ||||||
|   maladie: 'maladie', |  | ||||||
|   poison: 'poison', |  | ||||||
|   arme: 'arme', |  | ||||||
|   armure: 'armure', |  | ||||||
|   conteneur: 'conteneur', |  | ||||||
|   objet: 'objet', |  | ||||||
|   monnaie: 'monnaie', |  | ||||||
|   gemme: 'gemme', |  | ||||||
|   munition: 'munition', |  | ||||||
|   nourritureboisson: 'nourritureboisson', |  | ||||||
|   herbe: 'herbe', |  | ||||||
|   plante: 'plante', |  | ||||||
|   ingredient: 'ingredient', |  | ||||||
|   faune: 'faune', |  | ||||||
|   livre: 'livre', |  | ||||||
|   potion: 'potion', |  | ||||||
|   service: 'service', |  | ||||||
|   musique: 'musique', |  | ||||||
|   danse: 'danse', |  | ||||||
|   chant: 'chant', |  | ||||||
|   jeu: 'jeu', |  | ||||||
|   race: 'race', |  | ||||||
|   recettecuisine: 'recettecuisine', |  | ||||||
|   oeuvre: 'oeuvre', |  | ||||||
|   recettealchimique: 'recettealchimique', |  | ||||||
|   tache: 'tache', |  | ||||||
|   sort: 'sort', |  | ||||||
|   sortreserve: 'sortreserve', |  | ||||||
|   rencontre: 'rencontre', |  | ||||||
|   queue: 'queue', |  | ||||||
|   ombre: 'ombre', |  | ||||||
|   souffle: 'souffle', |  | ||||||
|   tete: 'tete', |  | ||||||
|   casetmr: 'casetmr', |  | ||||||
|   meditation: 'meditation', |  | ||||||
|   signedraconique: 'signedraconique', |  | ||||||
|   tarot: 'tarot', |  | ||||||
|   nombreastral: 'nombreastral', |  | ||||||
|   extraitpoetique: 'extraitpoetique', |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const typesInventaireMateriel = [ | const typesInventaireMateriel = [ | ||||||
|   ITEM_TYPES.arme, |   ITEM_TYPES.arme, | ||||||
| @@ -100,41 +46,41 @@ densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierre | |||||||
|    */ |    */ | ||||||
|  |  | ||||||
| export const defaultItemImg = { | export const defaultItemImg = { | ||||||
|   competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", |  | ||||||
|   competencecreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", |  | ||||||
|   arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp", |   arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp", | ||||||
|   armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp", |   armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp", | ||||||
|   conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp", |  | ||||||
|   sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", |  | ||||||
|   herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp", |  | ||||||
|   faune: "systems/foundryvtt-reve-de-dragon/icons/faune/rongeur.webp", |  | ||||||
|   ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp", |  | ||||||
|   livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp", |  | ||||||
|   potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp", |  | ||||||
|   rencontre: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp", |  | ||||||
|   queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp", |  | ||||||
|   ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp", |  | ||||||
|   souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp", |  | ||||||
|   tete: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp", |  | ||||||
|   meditation: "systems/foundryvtt-reve-de-dragon/icons/meditations_ecrits/meditation_alchimie.webp", |  | ||||||
|   recettealchimique: "systems/foundryvtt-reve-de-dragon/icons/competence_alchimie.webp", |  | ||||||
|   chant: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp", |   chant: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp", | ||||||
|  |   competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", | ||||||
|  |   competencecreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", | ||||||
|  |   conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp", | ||||||
|   danse: "systems/foundryvtt-reve-de-dragon/icons/arts/danse_0.webp", |   danse: "systems/foundryvtt-reve-de-dragon/icons/arts/danse_0.webp", | ||||||
|  |   empoignade: "systems/foundryvtt-reve-de-dragon/icons/empoignade.webp", | ||||||
|  |   extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp", | ||||||
|  |   faune: "systems/foundryvtt-reve-de-dragon/icons/faune/rongeur.webp", | ||||||
|  |   gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", | ||||||
|  |   herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp", | ||||||
|  |   ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp", | ||||||
|   jeu: "systems/foundryvtt-reve-de-dragon/icons/arts/jeux_petasse.webp", |   jeu: "systems/foundryvtt-reve-de-dragon/icons/arts/jeux_petasse.webp", | ||||||
|   recettecuisine: "systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_1.webp", |   livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp", | ||||||
|   musique: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp", |  | ||||||
|   maladie: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/maladie.webp", |   maladie: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/maladie.webp", | ||||||
|   poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp", |   meditation: "systems/foundryvtt-reve-de-dragon/icons/meditations_ecrits/meditation_alchimie.webp", | ||||||
|   oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp", |   musique: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp", | ||||||
|   nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp", |   nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp", | ||||||
|  |   oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp", | ||||||
|  |   ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp", | ||||||
|  |   poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp", | ||||||
|  |   possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", | ||||||
|  |   potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp", | ||||||
|  |   queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp", | ||||||
|  |   recettealchimique: "systems/foundryvtt-reve-de-dragon/icons/competence_alchimie.webp", | ||||||
|  |   recettecuisine: "systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_1.webp", | ||||||
|  |   rencontre: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp", | ||||||
|   service: "systems/foundryvtt-reve-de-dragon/icons/services/lit.webp", |   service: "systems/foundryvtt-reve-de-dragon/icons/services/lit.webp", | ||||||
|   signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", |   signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", | ||||||
|   gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", |   sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", | ||||||
|   possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", |  | ||||||
|   sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", |   sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", | ||||||
|   extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp", |   souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp", | ||||||
|   tarot: "systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp", |   tarot: "systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp", | ||||||
|   empoignade: "systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp" |   tete: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp", | ||||||
| } | } | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| @@ -356,13 +302,6 @@ export class RdDItem extends Item { | |||||||
|  |  | ||||||
|   getUtilisation() { |   getUtilisation() { | ||||||
|     switch (this.type) { |     switch (this.type) { | ||||||
|       case ITEM_TYPES.potion: |  | ||||||
|         switch (this.system.categorie) { |  | ||||||
|           case 'Alchimie': case 'AlchimieEnchante': case 'AlchimieAutre': return 'alchimie' |  | ||||||
|           case 'Cuisine': return 'cuisine' |  | ||||||
|           case 'Remede': case 'Repos': case 'ReposEnchante': case 'Soin': case 'SoinEnchante': return 'soins' |  | ||||||
|         } |  | ||||||
|         return ''; |  | ||||||
|       case ITEM_TYPES.nourritureboisson: return 'cuisine'; |       case ITEM_TYPES.nourritureboisson: return 'cuisine'; | ||||||
|       case ITEM_TYPES.herbe: case ITEM_TYPES.faune: case ITEM_TYPES.ingredient: case ITEM_TYPES.plante: |       case ITEM_TYPES.herbe: case ITEM_TYPES.faune: case ITEM_TYPES.ingredient: case ITEM_TYPES.plante: | ||||||
|         switch (this.system.categorie) { |         switch (this.system.categorie) { | ||||||
| @@ -471,68 +410,51 @@ export class RdDItem extends Item { | |||||||
|       // appliquer le pourcentage |       // appliquer le pourcentage | ||||||
|       return this.parent.calculerPrix(this); |       return this.parent.calculerPrix(this); | ||||||
|     } |     } | ||||||
|     return this.system.cout; |     return this.system.cout | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   prepareDerivedData() { |   prepareDerivedData() { | ||||||
|     super.prepareDerivedData(); |     super.prepareDerivedData(); | ||||||
|     if (this.isInventaire()) { |     if (this.isInventaire()) { | ||||||
|       this.system.encTotal = this.getEncTotal(); |       this.system.encTotal = this.getEncTotal() | ||||||
|       if (this.isPotion()) { |  | ||||||
|         this.prepareDataPotion() |  | ||||||
|       } |  | ||||||
|       this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false }); |  | ||||||
|     } |     } | ||||||
|     this.equipable = this.isEquipable(); |     this.equipable = this.isEquipable() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   prepareDataPotion() { |   itemActions() { | ||||||
|     const categorie = Grammar.toLowerCaseNoAccent(this.system.categorie); |     return COMMON_ACTIONS.concat(this.itemSpecificActions()).concat(DEFAULT_ACTIONS) | ||||||
|     this.system.magique = categorie.includes('enchante'); |  | ||||||
|     if (this.system.magique) { |  | ||||||
|       if (categorie.includes('soin') || categorie.includes('repos')) { |  | ||||||
|         // TODO: utiliser calculPointsRepos / calculPointsGuerison |  | ||||||
|         this.system.puissance = RdDHerbes.calculPuissancePotion(this); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getActionPrincipale(options = { warnIfNot: true }) { |   itemSpecificActions() { | ||||||
|  |     const actions = ITEM_ACTIONS[this.type] ?? [] | ||||||
|  |     // const actorTypes = actions.actorTypes ?? [ACTOR_TYPES.personnage] | ||||||
|  |     // if (!actorTypes.includes(this.actor?.type)) { | ||||||
|  |     //   return [] | ||||||
|  |     // } | ||||||
|  |     return actions | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   isActionAllowed(code) { | ||||||
|     switch (this.type) { |     switch (this.type) { | ||||||
|       case ITEM_TYPES.conteneur: return 'Ouvrir'; |       case ITEM_TYPES.possession: | ||||||
|     } |       case ITEM_TYPES.empoignade: | ||||||
|     if (this.actor?.isPersonnage()) { |       case ITEM_TYPES.rencontre: | ||||||
|       const warn = options.warnIfNot; |       case ITEM_TYPES.signedraconique: | ||||||
|       if (this.getUtilisationCuisine() == 'brut') { |         switch (code) { | ||||||
|         return 'Cuisiner'; |           case 'item-edit': | ||||||
|       } |           case 'item-delete': | ||||||
|       switch (this.type) { |             return game.user.isGM | ||||||
|         case ITEM_TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn); |         } | ||||||
|         case ITEM_TYPES.potion: return this._actionOrWarnQuantiteZero('Consommer', warn); |       case ITEM_TYPES.maladie: | ||||||
|         case ITEM_TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn); |       case ITEM_TYPES.poison: | ||||||
|         case ITEM_TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined; |         return game.user.isGM | ||||||
|         case ITEM_TYPES.queue: case ITEM_TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined; |       case ITEM_TYPES.casetmr: | ||||||
|       } |         switch (code) { | ||||||
|     } |           case 'item-delete': | ||||||
|     return undefined; |             return game.user.isGM | ||||||
|   } |         } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async actionPrincipale(actor, onActionItem = async () => { }) { |  | ||||||
|     if (!this.getActionPrincipale()) { return } |  | ||||||
|     await actor?.actionPrincipale(this, onActionItem); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   _actionOrWarnQuantiteZero(actionName, warn) { |  | ||||||
|     if ((this.system.quantite ?? 0) <= 0) { |  | ||||||
|       if (warn) { |  | ||||||
|         ui.notifications.warn(`Vous n'avez plus de ${this.name}.`); |  | ||||||
|       } |  | ||||||
|       return undefined; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       return actionName; |  | ||||||
|     } |     } | ||||||
|  |     return true | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async diminuerQuantite(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) { |   async diminuerQuantite(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) { | ||||||
| @@ -805,14 +727,6 @@ export class RdDItem extends Item { | |||||||
|     ] |     ] | ||||||
|   } |   } | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _potionChatData() { |  | ||||||
|     return [ |  | ||||||
|       `<b>Rareté</b>: ${this.system.rarete}`, |  | ||||||
|       `<b>Catégorie</b>: ${this.system.categorie}`, |  | ||||||
|       ...this._inventaireTemplateChatData() |  | ||||||
|     ] |  | ||||||
|   } |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   _queueChatData() { |   _queueChatData() { | ||||||
|     function label(categorie) { |     function label(categorie) { | ||||||
|       switch (categorie) { |       switch (categorie) { | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { ITEM_TYPES, RdDItem } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { RdDItem } from "../item.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | ||||||
|  |  | ||||||
| @@ -10,7 +11,7 @@ export class RdDItemArmure extends RdDItem { | |||||||
|     return "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp"; |     return "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   deteriorerArmure(dmg) { |   async deteriorerArmure(dmg) { | ||||||
|     if (!ReglesOptionnelles.isUsing('deteriorationArmure') || this.system.protection == '0') { |     if (!ReglesOptionnelles.isUsing('deteriorationArmure') || this.system.protection == '0') { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @@ -22,12 +23,10 @@ export class RdDItemArmure extends RdDItem { | |||||||
|       protection = this.calculProtectionDeterioree(); |       protection = this.calculProtectionDeterioree(); | ||||||
|       ChatMessage.create({ content: `Votre armure ${this.name} s'est détériorée, elle protège maintenant de ${protection}` }); |       ChatMessage.create({ content: `Votre armure ${this.name} s'est détériorée, elle protège maintenant de ${protection}` }); | ||||||
|     } |     } | ||||||
|     this.update({ |     await this.update({ | ||||||
|       system: { |       'system.deterioration': deterioration, | ||||||
|         deterioration: deterioration, |       'system.protection': protection | ||||||
|         protection: protection |     }) | ||||||
|       } |  | ||||||
|     }); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   calculProtectionDeterioree() { |   calculProtectionDeterioree() { | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|  |  | ||||||
|   prepareDerivedData() { |   prepareDerivedData() { | ||||||
|     super.prepareDerivedData(); |     super.prepareDerivedData(); | ||||||
|     this.system.label = this.getLabelGravite() |     this.system.label = RdDItemBlessure.getLabelGravite(this.system.gravite) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static prepareTacheSoin(gravite) { |   static prepareTacheSoin(gravite) { | ||||||
| @@ -43,29 +43,32 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async applyFullBlessure(actor, gravite) { |   static async applyFullBlessure(actor, gravite) { | ||||||
|     const definition = RdDItemBlessure.getDefinition(gravite) |     const definition = foundry.utils.duplicate(RdDItemBlessure.getDefinition(gravite)) | ||||||
|      |  | ||||||
|     let lostEndurance = 0 |  | ||||||
|     let lostVie = 0 |  | ||||||
|     if (definition.endurance) { |  | ||||||
|       lostEndurance = new Roll(definition.endurance) |  | ||||||
|       await lostEndurance.roll(); |  | ||||||
|       actor.santeIncDec("endurance", -Number(lostEndurance.total)); |  | ||||||
|     } |  | ||||||
|     if (definition.vie) { |     if (definition.vie) { | ||||||
|       lostVie = definition.vie |       await actor.santeIncDec("vie", definition.vie) | ||||||
|       actor.santeIncDec("vie", definition.vie) |     } | ||||||
|  |     const lostEndurance = await RdDItemBlessure.rollLostEndurance(definition.endurance) | ||||||
|  |     if (lostEndurance) { | ||||||
|  |       await actor.santeIncDec("endurance", -Number(lostEndurance)); | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     await this.createBlessure(actor, gravite) |     await this.createBlessure(actor, gravite) | ||||||
|  |  | ||||||
|     ChatMessage.create({ |     ChatMessage.create({ | ||||||
|       content: `Blessure ${definition.label} appliquée à ${actor.name}`+ |       //TODO: hbs | ||||||
|         `<br>Perte d'endurance : ${lostEndurance}`+ |       content: `Blessure ${definition.label} appliquée à ${actor.name}<br>Perte d'endurance : ${lostEndurance} (${definition.endurance})<br>Perte de Vie : ${definition.vie}`, | ||||||
|         `<br>Perte de Vie : ${lostVie}`, |  | ||||||
|       whisper: ChatUtility.getOwners(actor) |       whisper: ChatUtility.getOwners(actor) | ||||||
|     }); |     }); | ||||||
|  |     actor.sheet?.render() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async rollLostEndurance(formula) { | ||||||
|  |     if (formula) { | ||||||
|  |       const roll = new Roll(formula) | ||||||
|  |       await roll.evaluate() | ||||||
|  |       return roll.total | ||||||
|  |     } | ||||||
|  |     return 0 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async createBlessure(actor, gravite, localisation = '', attackerToken) { |   static async createBlessure(actor, gravite, localisation = '', attackerToken) { | ||||||
| @@ -125,10 +128,10 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|     } |     } | ||||||
|     if (this.system.gravite > 0) { |     if (this.system.gravite > 0) { | ||||||
|       const update = { system: { premierssoins: { bonus: 0 }, soinscomplets: { bonus: 0 } } } |       const update = { system: { premierssoins: { bonus: 0 }, soinscomplets: { bonus: 0 } } } | ||||||
|       const gravite = this.system.gravite; |       const gravite = this.system.gravite | ||||||
|       const graviteMoindre = gravite - 2; |       const graviteMoindre = gravite - 2 | ||||||
|       const moindres = blessures.filter(it => it.system.gravite == graviteMoindre, 'blessures').length |       const moindres = blessures.filter(it => it.system.gravite == graviteMoindre, 'blessures').length | ||||||
|       const label = this.getLabelGravite(); |       const label = RdDItemBlessure.getLabelGravite(this.system.gravite) | ||||||
|  |  | ||||||
|       let rolled = await actor.jetRecuperationConstitution(this.system.soinscomplets.bonus, message); |       let rolled = await actor.jetRecuperationConstitution(this.system.soinscomplets.bonus, message); | ||||||
|  |  | ||||||
| @@ -158,7 +161,7 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   peutRetrograder(graviteMoindre, moindres) { |   peutRetrograder(graviteMoindre, moindres) { | ||||||
|     return moindres < RdDItemBlessure.getDefinition(graviteMoindre).max |     return moindres < RdDItemBlessure.maxBlessures(graviteMoindre) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async calculerFinPeriodeTemporel(debut) { |   async calculerFinPeriodeTemporel(debut) { | ||||||
| @@ -182,16 +185,16 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|     return `systems/foundryvtt-reve-de-dragon/icons/sante/${soins ? 'blessure-soins' : img}.webp` |     return `systems/foundryvtt-reve-de-dragon/icons/sante/${soins ? 'blessure-soins' : img}.webp` | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getLabelGravite() { |   static getLabelGravite(gravite) { | ||||||
|     return RdDItemBlessure.getDefinition(this.system.gravite).label |     return definitionsBlessures.find(it => it.gravite >= gravite).label | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getDefinition(gravite) { |   static getDefinition(gravite) { | ||||||
|     return definitionsBlessures.sort(Misc.ascending(it => it.gravite)) |     return definitionsBlessures.find(it => it.gravite >= gravite) | ||||||
|       .find(it => it.gravite >= gravite); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static maxBlessures(gravite) { |   static maxBlessures(gravite) { | ||||||
|     return RdDItemBlessure.getDefinition(gravite).max |     return definitionsBlessures.find(it => it.gravite >= gravite).max | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isContusion() { |   isContusion() { | ||||||
| @@ -216,7 +219,7 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|       `<b>Heure et Date</b>: ${new RdDTimestamp(this.system.temporel.debut).formatDateHeure()}`, |       `<b>Heure et Date</b>: ${new RdDTimestamp(this.system.temporel.debut).formatDateHeure()}`, | ||||||
|       RdDItem.propertyIfDefined('Blessé', this.parent?.name, this.parent), |       RdDItem.propertyIfDefined('Blessé', this.parent?.name, this.parent), | ||||||
|       `<b>Localisation</b>: ${this.system.localisation}`, |       `<b>Localisation</b>: ${this.system.localisation}`, | ||||||
|       `<b>Gravité</b>: ${RdDItemBlessure.getDefinition(this.system.gravite).label}`, |       `<b>Gravité</b>: ${this.system.label}`, | ||||||
|       `<b>Difficulté des soins</b>: ${this.system.difficulte}`, |       `<b>Difficulté des soins</b>: ${this.system.difficulte}`, | ||||||
|       (this.system.soinscomplets.done ? |       (this.system.soinscomplets.done ? | ||||||
|         `<b>Bonus soins complets</b>: ${this.system.soinscomplets.bonus}` : |         `<b>Bonus soins complets</b>: ${this.system.soinscomplets.bonus}` : | ||||||
|   | |||||||
							
								
								
									
										154
									
								
								module/item/item-actions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								module/item/item-actions.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | |||||||
|  | import { Misc } from "../misc.js" | ||||||
|  | import { RdDSheetUtility } from "../rdd-sheet-utility.js" | ||||||
|  | import { RdDUtility } from "../rdd-utility.js" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * TODO: | ||||||
|  |  * options.editable ? | ||||||
|  |  *  | ||||||
|  |  */ | ||||||
|  | const _SPACEHOLDER = { placeholder: true } | ||||||
|  |  | ||||||
|  | const _VENDRE = { | ||||||
|  |   code: 'item-vendre', label: 'Vendre ou donner', icon: it => 'fa-solid fa-comments-dollar', | ||||||
|  |   filter: it => Misc.toInt(it.system.quantite) > 0, | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => item.proposerVente() | ||||||
|  | } | ||||||
|  | const _ACHAT_SERVICE = { | ||||||
|  |   code: 'item-service-acheter', label: 'Acheter', icon: it => 'fa-regular fa-coins', | ||||||
|  |   //filter: it => Misc.toInt(it.system.quantite) > 0, | ||||||
|  |   //optionsFilter: options => options.editable, | ||||||
|  |   //action: (item, actor) => item.proposerVente() | ||||||
|  | } | ||||||
|  | const _MONTRER = { | ||||||
|  |   code: 'item-montrer', label: 'Montrer', icon: it => 'fa-solid fa-comment', | ||||||
|  |   action: (item, actor) => item.postItemToChat() | ||||||
|  | } | ||||||
|  | const _EDIT = { | ||||||
|  |   code: 'item-edit', label: 'Editer', icon: it => 'fa-solid fa-edit', | ||||||
|  |   action: (item, actor) => item.sheet.render(true) | ||||||
|  | } | ||||||
|  | const _DELETE = { | ||||||
|  |   code: 'item-delete', label: 'Supprimer', icon: it => 'fa-solid fa-trash', | ||||||
|  |   optionsFilter: options => options.editable && options.isOwner, | ||||||
|  |   action: (item, actor) => RdDUtility.confirmActorItemDelete(item, actor) | ||||||
|  | } | ||||||
|  | const _EQUIPER = { | ||||||
|  |   code: 'item-equip', label: 'Equiper', icon: it => it.system.equipe ? 'fa-solid fa-hand-rock' : 'fa-regular fa-hand-paper', | ||||||
|  |   filter: it => !it.estContenu && it.isEquipable(), | ||||||
|  |   action: (item, actor) => actor.equiperObjet(item) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const _CUISINER = { | ||||||
|  |   code: 'item-cuisiner', label: 'Cuisiner', icon: it => 'fa-solid fa-utensils', | ||||||
|  |   filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.preparerNourriture(item) | ||||||
|  | } | ||||||
|  | const _MANGER_CRU = { | ||||||
|  |   code: 'item-manger-cru', label: 'Manger cru', icon: it => 'fa-solid fa-drumstick-bite', | ||||||
|  |   filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.mangerNourriture(item) | ||||||
|  | } | ||||||
|  | const _MANGER = { | ||||||
|  |   code: 'item-manger', label: 'Manger', icon: it => 'fa-solid fa-utensils', | ||||||
|  |   filter: it => !(it.system.boisson), | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.mangerNourriture(item) | ||||||
|  | } | ||||||
|  | const _BOIRE = { | ||||||
|  |   code: 'item-boire', label: 'Boire', icon: it => 'fa-solid fa-glass-water', | ||||||
|  |   filter: it => it.system.boisson, | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.mangerNourriture(item) | ||||||
|  | } | ||||||
|  | const _DECOCTION = { | ||||||
|  |   code: 'item-decoction', label: 'Décoction', icon: it => 'fa-solid fa-flask-vial', | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.actionHerbe(item) | ||||||
|  | } | ||||||
|  | const _OUVRIR = { | ||||||
|  |   code: 'item-edit', label: 'Ouvrir', icon: it => 'fa-solid fa-eye', | ||||||
|  |   action: (item, actor) => item.sheet.render(true) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const _LIRE = { | ||||||
|  |   code: 'item-lire', label: 'Lire', icon: it => 'fa-solid fa-book-open', | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.actionLire(item) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const _REFOULER = { | ||||||
|  |   code: 'item-refouler', label: 'Refouler', icon: it => 'fa-solid fa-burst', | ||||||
|  |   filter: it => it.system.refoulement > 0, | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.actionRefoulement(item) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const _CONSOMMER_POTION = { | ||||||
|  |   code: 'item-potion-consommer', label: 'Consommer', icon: it => 'fa-solid fa-vial', | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => actor.consommerPotion(item) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const _ENCHANTER = { | ||||||
|  |   code: 'item-enchanter', label: 'Enchanter', icon: it => 'fa-solid fa-sparkles', | ||||||
|  |   filter: it => it.isEnchantable(), | ||||||
|  |   optionsFilter: options => options.editable, | ||||||
|  |   action: (item, actor) => item.enchanterPotion() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const _SORT_RESERVE = { | ||||||
|  |   code: 'item-sortreserve-add', label: 'Ajouter en réserve', icon: it => 'fa-solid fa-sparkles', | ||||||
|  |   filter: it => game.user.isGM && !it.system.isrituel, | ||||||
|  |   action: (item, actor) => actor.addSortReserve(item) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const COMMON_ACTIONS = [_EQUIPER] | ||||||
|  | export const DEFAULT_ACTIONS = [_SPACEHOLDER, _VENDRE, _MONTRER, _EDIT, _DELETE] | ||||||
|  |  | ||||||
|  | export const ITEM_ACTIONS = { | ||||||
|  |   faune: [_CUISINER, _MANGER_CRU], | ||||||
|  |   ingredient: [_CUISINER, _MANGER_CRU], | ||||||
|  |   conteneur: [_OUVRIR], | ||||||
|  |   herbe: [_DECOCTION, _CUISINER, _MANGER_CRU], | ||||||
|  |   livre: [_LIRE], | ||||||
|  |   nourritureboisson: [_MANGER, _BOIRE], | ||||||
|  |   ombre: [_REFOULER], | ||||||
|  |   plante: [_CUISINER, _MANGER_CRU], | ||||||
|  |   potion: [_CONSOMMER_POTION, _ENCHANTER], | ||||||
|  |   queue: [_REFOULER], | ||||||
|  |   sort: [_SORT_RESERVE], | ||||||
|  |   service: [_ACHAT_SERVICE] | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export class ItemAction { | ||||||
|  |  | ||||||
|  |   static applies(action, item, options) { | ||||||
|  |     return action | ||||||
|  |       && item.isActionAllowed(action.code) | ||||||
|  |       && (!action.filter || action.filter(item)) | ||||||
|  |       && (!action.optionsFilter || action.optionsFilter(options)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static icon(action, item) { | ||||||
|  |     if (action && action.icon) { | ||||||
|  |       return action.icon(item) | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static onActionItem(event, actor, options) { | ||||||
|  |     const item = RdDSheetUtility.getItem(event, actor) | ||||||
|  |     const code = $(event.currentTarget).data('code') | ||||||
|  |     const action = item.itemActions().find(it => it.code == code) | ||||||
|  |     if (action && (!action.optionsFilter || action.optionsFilter(options))) { | ||||||
|  |       action.action(item, actor) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										154
									
								
								module/item/potion.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								module/item/potion.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | |||||||
|  | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { Grammar } from "../grammar.js"; | ||||||
|  | import { RdDItem } from "../item.js"; | ||||||
|  | import { SystemCompendiums } from "../settings/system-compendiums.js"; | ||||||
|  | import { ITEM_ACTIONS } from "./item-actions.js"; | ||||||
|  | import { DialogEnchanter } from "./potion/dialog-enchanter.js"; | ||||||
|  |  | ||||||
|  | const POTION_MAGIQUE = ['AlchimieEnchante', 'ReposEnchante', 'SoinEnchante', 'AutreEnchante'] | ||||||
|  | const POTION_ENCHANTABLE = ['Alchimie', 'Repos', 'Soin', 'Autre'] | ||||||
|  |   .concat(POTION_MAGIQUE) | ||||||
|  |  | ||||||
|  | const MAP_CATEGORIE_ENCHANTEMENT = [ | ||||||
|  |   { basique: 'Alchimie', enchante: 'AlchimieEnchante' }, | ||||||
|  |   { basique: 'Repos', enchante: 'ReposEnchante' }, | ||||||
|  |   { basique: 'Soin', enchante: 'SoinEnchante' }, | ||||||
|  |   { basique: 'Autre', enchante: 'AutreEnchante' }] | ||||||
|  |  | ||||||
|  | export class RdDItemPotion extends RdDItem { | ||||||
|  |  | ||||||
|  |   static async herbesSoins() { | ||||||
|  |     return await RdDItemPotion.$listHerbes(it => Grammar.equalsInsensitive(it.system.categorie, 'Soin') && it.system.niveau > 0) | ||||||
|  |   } | ||||||
|  |   static async herbesRepos() { | ||||||
|  |     return await RdDItemPotion.$listHerbes(it => Grammar.equalsInsensitive(it.system.categorie, 'Repos') && it.system.niveau > 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async $listHerbes(filter) { | ||||||
|  |     const herbes = await SystemCompendiums.getWorldOrCompendiumItems('herbe', 'faune-flore-mineraux'); | ||||||
|  |     return herbes.filter(filter) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static get defaultIcon() { | ||||||
|  |     return "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp" | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareDerivedData() { | ||||||
|  |     super.prepareDerivedData() | ||||||
|  |     this.system.puissance = this.system.magique ? this.calculPuissance() : 0 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   isPotion() { return true } | ||||||
|  |   isEnchantable() { return POTION_ENCHANTABLE.includes(this.system.categorie) } | ||||||
|  |   isMagique() { return POTION_MAGIQUE.includes(this.system.categorie) } | ||||||
|  |  | ||||||
|  |   itemSpecificActions() { | ||||||
|  |     return ITEM_ACTIONS[ITEM_TYPES.potion] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getActions(options = { warnIfNot: true }) { | ||||||
|  |     const actionConsommer = this.prepareAction('Consommer', options.warnIfNot); | ||||||
|  |     if (this.isEnchantable()) { | ||||||
|  |       return [ | ||||||
|  |         actionConsommer, | ||||||
|  |         this.prepareAction('Enchanter', options.warnIfNot) | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |     return [ | ||||||
|  |       actionConsommer | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  |   // TDOD: purifier? | ||||||
|  |   getUtilisation() { | ||||||
|  |     switch (this.system.categorie) { | ||||||
|  |       case 'Alchimie': case 'AlchimieEnchante': | ||||||
|  |       case 'AlchimieAutre': | ||||||
|  |         return 'alchimie' | ||||||
|  |       case 'Cuisine': return 'cuisine' | ||||||
|  |       case 'Remede': case 'Repos': case 'ReposEnchante': case 'Soin': case 'SoinEnchante': | ||||||
|  |         return 'soins' | ||||||
|  |     } | ||||||
|  |     return '' | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   _potionChatData() { | ||||||
|  |     return [ | ||||||
|  |       `<b>Rareté</b>: ${this.system.rarete}`, | ||||||
|  |       `<b>Catégorie</b>: ${this.system.categorie}`, | ||||||
|  |       ...this._inventaireTemplateChatData() | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async enchanterPotion() { | ||||||
|  |     const actor = this.parent; | ||||||
|  |     if (actor && (!actor.isPersonnage() || !actor.isHautRevant())) { | ||||||
|  |       ui.notifications.info('Seul un haut rêvant peut enchanter une potion') | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |     const dailog = await DialogEnchanter.create(this, actor, (updates) => this.$onEnchanterPotion(updates)); | ||||||
|  |     dailog.render(true) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   perteRevePotion() { | ||||||
|  |     if (this.system.magique && !this.system.prpermanent && this.system.pr > 0) { | ||||||
|  |       const nouveauReve = Math.max(this.system.pr - 1, 0) | ||||||
|  |       return { | ||||||
|  |         _id: this.id, | ||||||
|  |         name: this.name, | ||||||
|  |         img: this.img, | ||||||
|  |         'system.pr': nouveauReve, | ||||||
|  |         'system.quantite': nouveauReve > 0 ? this.system.quantite : 0, | ||||||
|  |         'system.magique': nouveauReve > 0 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async $onEnchanterPotion(enchanter) { | ||||||
|  |     if (enchanter.nouveaupr == 0) { | ||||||
|  |       await this.update({ | ||||||
|  |         'system.pr': 0, | ||||||
|  |         'system.purifie': false, | ||||||
|  |         'system.magique': false, | ||||||
|  |         'system.categorie': this.categorieEnchantement().basique, | ||||||
|  |         'system.prpermanent': false, | ||||||
|  |         'system.prdate': 0, | ||||||
|  |         'system.quantite': this.parent ? 0 : this.system.quantite | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       await this.update({ | ||||||
|  |         'system.pr': enchanter.nouveaupr, | ||||||
|  |         'system.purifie': enchanter.purifier, | ||||||
|  |         'system.magique': true, | ||||||
|  |         'system.categorie': this.categorieEnchantement().enchante, | ||||||
|  |         'system.prpermanent': enchanter.prpermanent, | ||||||
|  |         'system.prdate': RdDItemPotion.dateEnchantement() | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |     this.sheet?.render(true) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   calculPuissance() { return this.system.herbebonus * this.system.pr } | ||||||
|  |  | ||||||
|  |   categorieEnchantement() { | ||||||
|  |     const categorie = this.system.categorie | ||||||
|  |     const categorieEnchantement = MAP_CATEGORIE_ENCHANTEMENT.find(it => [it.basique, it.enchante].includes(categorie)) | ||||||
|  |     return categorieEnchantement ?? { basique: categorie, enchante: categorie } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static dateEnchantement() { | ||||||
|  |     return game.system.rdd.calendrier.getTimestamp().debutJournee().indexDate | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static buildHerbesList(listeHerbes, max) { | ||||||
|  |     let list = {} | ||||||
|  |     for (let herbe of listeHerbes) { | ||||||
|  |       let brins = max - herbe.system.niveau; | ||||||
|  |       list[herbe.name] = `${herbe.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`; | ||||||
|  |     } | ||||||
|  |     list['Autre'] = 'Autre (Bonus: variable, Brins: variable)' | ||||||
|  |     return list; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								module/item/potion/dialog-enchanter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								module/item/potion/dialog-enchanter.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  |  | ||||||
|  | export class DialogEnchanter extends Dialog { | ||||||
|  |  | ||||||
|  |   static async create(item, actor, callback) { | ||||||
|  |     const enchanter = { | ||||||
|  |       actor: actor, | ||||||
|  |       item: item, | ||||||
|  |       nouveaupr: item.system.pr, | ||||||
|  |       prpermanent: item.system.prpermanent, | ||||||
|  |       purifier: false | ||||||
|  |     } | ||||||
|  |     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/item/potion/dialog-enchanter.hbs`, enchanter) | ||||||
|  |     return new DialogEnchanter(enchanter, html, callback) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   constructor(enchanter, html, callback) { | ||||||
|  |     let options = { classes: ["dialog-enchanter"], width: 400, height: 'fit-content', 'z-index': 99999 } | ||||||
|  |     let conf = { | ||||||
|  |       title: "Enchanter une potion", | ||||||
|  |       content: html, | ||||||
|  |       default: "enchanter", | ||||||
|  |       buttons: { | ||||||
|  |         "enchanter": { label: "Enchanter", callback: it => this.onEnchanter() } | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     super(conf, options) | ||||||
|  |  | ||||||
|  |     this.callback = callback | ||||||
|  |     this.enchanter = enchanter | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   activateListeners(html) { | ||||||
|  |     super.activateListeners(html) | ||||||
|  |     this.html = html | ||||||
|  |     this.html.find("input.nouveaupr").change(event => this.enchanter.nouveaupr = Number(event.currentTarget.value)) | ||||||
|  |     this.html.find("input.purifier").change(event => this.enchanter.purifier = event.currentTarget.checked) | ||||||
|  |     this.html.find("input.prpermanent").change(event => this.enchanter.prpermanent = event.currentTarget.checked) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   async onEnchanter() { | ||||||
|  |     await this.html.find(".nouveaupr").change() | ||||||
|  |     this.callback(this.enchanter); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,6 +1,7 @@ | |||||||
| import { ITEM_TYPES, RdDItem } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { RdDItem } from "../item.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { LIST_CARAC, RdDCarac } from "../rdd-carac.js"; | import { LIST_CARAC_PERSONNAGE, RdDCarac } from "../rdd-carac.js"; | ||||||
|  |  | ||||||
| export class RdDItemRace extends RdDItem { | export class RdDItemRace extends RdDItem { | ||||||
|  |  | ||||||
| @@ -12,7 +13,7 @@ export class RdDItemRace extends RdDItem { | |||||||
|  |  | ||||||
|   static checkRacialMax(actor, code, value) { |   static checkRacialMax(actor, code, value) { | ||||||
|     const race = RdDItemRace.getRace(actor) |     const race = RdDItemRace.getRace(actor) | ||||||
|     if (code == LIST_CARAC.force.code) { |     if (code == LIST_CARAC_PERSONNAGE.force.code) { | ||||||
|       if (!race.isForceValid(actor, value)) { |       if (!race.isForceValid(actor, value)) { | ||||||
|         ui.notifications.warn(race.system.carac.force.limitmessage) |         ui.notifications.warn(race.system.carac.force.limitmessage) | ||||||
|         return false |         return false | ||||||
| @@ -55,7 +56,7 @@ export class RdDItemRace extends RdDItem { | |||||||
|     if (value == undefined) { |     if (value == undefined) { | ||||||
|       value = path ? foundry.utils.getProperty(actor, path) : 0 |       value = path ? foundry.utils.getProperty(actor, path) : 0 | ||||||
|     } |     } | ||||||
|     if (code == LIST_CARAC.force.code) { |     if (code == LIST_CARAC_PERSONNAGE.force.code) { | ||||||
|       return value >= this.getForceMax(actor) |       return value >= this.getForceMax(actor) | ||||||
|     } |     } | ||||||
|     const max = foundry.utils.getProperty(this, path) ?? -1 |     const max = foundry.utils.getProperty(this, path) ?? -1 | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { RdDBaseActorSheet } from "../actor/base-actor-sheet.js"; | import { RdDBaseActorSheet } from "../actor/base-actor-sheet.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | ||||||
| import { RdDUtility } from "../rdd-utility.js"; | import { RdDUtility } from "../rdd-utility.js"; | ||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | ||||||
| @@ -29,9 +29,10 @@ export class RdDConteneurItemSheet extends RdDItemInventaireSheet { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   prepareConteneurData(formData) { |   prepareConteneurData(formData) { | ||||||
|     RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); |     RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); | ||||||
|     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); |     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); | ||||||
|     formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems; |     const subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems; | ||||||
|  |     formData.subItems = subItems | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async _onDragStart(event) { |   async _onDragStart(event) { | ||||||
|   | |||||||
							
								
								
									
										58
									
								
								module/item/sheet-potion.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								module/item/sheet-potion.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { RdDTimestamp } from "../time/rdd-timestamp.js"; | ||||||
|  | import { RdDItemPotion } from "./potion.js"; | ||||||
|  | import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export class RdDPotionItemSheet extends RdDItemInventaireSheet { | ||||||
|  |  | ||||||
|  |   static get ITEM_TYPE() { return ITEM_TYPES.potion }; | ||||||
|  |  | ||||||
|  |   static $calculBonusHerbe(formData, herbesList, max) { | ||||||
|  |     if (Number(formData.system.herbebrins)) { | ||||||
|  |       let herbe = herbesList.find(h => h.name.toLowerCase() == formData.system.herbe.toLowerCase()); | ||||||
|  |       if (herbe) { | ||||||
|  |         const brinsRequis = max - herbe.system.niveau; | ||||||
|  |         const brinsManquants = Math.max(brinsRequis - formData.system.herbebrins, 0); | ||||||
|  |         formData.system.herbebonus = Math.max(herbe.system.niveau - brinsManquants, 0); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   get potion(){ return this.item } | ||||||
|  |  | ||||||
|  |   async getData() { | ||||||
|  |     const formData = await super.getData() | ||||||
|  |     formData.enchantable = this.potion.isEnchantable() | ||||||
|  |     const enchantement = this.potion.categorieEnchantement() | ||||||
|  |     formData.isSoins = enchantement.basique == 'Soin' | ||||||
|  |     formData.isRepos = enchantement.basique == 'Repos' | ||||||
|  |     if (formData.isSoins) { | ||||||
|  |       const herbesSoins = await RdDItemPotion.herbesSoins() | ||||||
|  |       RdDPotionItemSheet.$calculBonusHerbe(formData, herbesSoins, 12); | ||||||
|  |       formData.herbesSoins = RdDItemPotion.buildHerbesList(herbesSoins, 12) | ||||||
|  |     } | ||||||
|  |     if (formData.isRepos) { | ||||||
|  |       const herbesRepos = await RdDItemPotion.herbesRepos() | ||||||
|  |       RdDPotionItemSheet.$calculBonusHerbe(formData, herbesRepos, 7); | ||||||
|  |       formData.herbesRepos = RdDItemPotion.buildHerbesList(herbesRepos, 7) | ||||||
|  |     } | ||||||
|  |     formData.dateActuelle = game.system.rdd.calendrier.dateCourante() | ||||||
|  |     formData.enchantement = RdDTimestamp.splitIndexDate(this.potion.system.prdate) | ||||||
|  |     return formData | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   activateListeners(html) { | ||||||
|  |     super.activateListeners(html); | ||||||
|  |  | ||||||
|  |     this.html.find('.item-enchanter').click((event) => this.potion.enchanterPotion()) | ||||||
|  |  | ||||||
|  |     this.html.find('.date-enchantement').change((event) => { | ||||||
|  |       const jour = Number(this.html.find('input.date-enchantement[name="enchantement.jour"]').val()) | ||||||
|  |       const mois = RdDTimestamp.definition(this.html.find('select.date-enchantement[name="enchantement.mois"]').val()) | ||||||
|  |       const indexDate = game.system.rdd.calendrier.getIndexFromDate(jour, mois.heure) | ||||||
|  |       this.potion.update({ 'system.prdate': indexDate }) | ||||||
|  |       console.warn(`Date d'enchantement modifiée ${jour}/${mois.heure}: ${indexDate}`) | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -106,7 +106,7 @@ export class RdDItemSigneDraconique extends RdDItem { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async randomSigneDescription() { |   static async randomSigneDescription() { | ||||||
|     return await RdDRollTables.drawTextFromRollTable("Signes draconiques", false); |     return await RdDRollTables.drawTextFromRollTable("Signes draconiques", {toChat:false}); | ||||||
|    } |    } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -1,5 +1,6 @@ | |||||||
|  | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { RdDItem } from "../item.js"; | ||||||
| import { Grammar } from "../grammar.js" | import { Grammar } from "../grammar.js" | ||||||
| import { ITEM_TYPES, RdDItem } from "../item.js" |  | ||||||
| import { SystemCompendiums } from "../settings/system-compendiums.js" | import { SystemCompendiums } from "../settings/system-compendiums.js" | ||||||
|  |  | ||||||
| const DON_HAUT_REVE = "Don de Haut-Rêve" | const DON_HAUT_REVE = "Don de Haut-Rêve" | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								module/journal/journal-sheet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								module/journal/journal-sheet.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js"; | ||||||
|  | import { SYSTEM_RDD } from "../constants.js"; | ||||||
|  | import { Misc } from "../misc.js"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export class RdDJournalSheet extends JournalTextPageSheet { | ||||||
|  |   static register() { | ||||||
|  |     DocumentSheetConfig.unregisterSheet(JournalEntryPage, "core", JournalTextPageSheet) | ||||||
|  |     DocumentSheetConfig.registerSheet(JournalEntryPage, | ||||||
|  |       SYSTEM_RDD, | ||||||
|  |       RdDJournalSheet, { | ||||||
|  |       types: ["text"], | ||||||
|  |       makeDefault: true, | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async getData(options) { | ||||||
|  |     const journalData = await super.getData(options); | ||||||
|  |     journalData.editor.content = await RdDTextEditor.enrichHTML(journalData.document.text.content, this.object) | ||||||
|  |     return journalData | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   activateListeners(html) { | ||||||
|  |     super.activateListeners(html); | ||||||
|  |  | ||||||
|  |     html.find('.roll-text').click(async event => await RdDTextEditor.rollText(event, this.actor)) | ||||||
|  |     html.find('.chat-roll-text').click(async event => await RdDTextEditor.chatRollText(event)) | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -2,7 +2,8 @@ import { RdDBaseActor } from "./actor/base-actor.js"; | |||||||
| import { LOG_HEAD, SYSTEM_RDD } from "./constants.js"; | import { LOG_HEAD, SYSTEM_RDD } from "./constants.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { Monnaie } from "./item-monnaie.js"; | import { Monnaie } from "./item-monnaie.js"; | ||||||
| import { RdDItem, ITEM_TYPES, ACTOR_TYPES } from "./item.js"; | import { ITEM_TYPES, ACTOR_TYPES } from "./constants.js"; | ||||||
|  | import { RdDItem } from "./item.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
| import { RdDRaretes } from "./item/raretes.js"; | import { RdDRaretes } from "./item/raretes.js"; | ||||||
| import { VOIES_DRACONIC } from "./item-sort.js"; | import { VOIES_DRACONIC } from "./item-sort.js"; | ||||||
|   | |||||||
| @@ -1,5 +1,12 @@ | |||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
|  |  | ||||||
|  | const DEFAULT_FIND_OPTIONS = { | ||||||
|  |   mapper: it => it.name, | ||||||
|  |   preFilter: it => true, | ||||||
|  |   description: 'valeur', | ||||||
|  |   onMessage: m => ui.notifications.info(m) | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * This class is intended as a placeholder for utility methods unrelated |  * This class is intended as a placeholder for utility methods unrelated | ||||||
|  * to actual classes of the game system or of FoundryVTT |  * to actual classes of the game system or of FoundryVTT | ||||||
| @@ -209,6 +216,10 @@ export class Misc { | |||||||
|   static isFirstConnectedGM() { |   static isFirstConnectedGM() { | ||||||
|     return game.user == Misc.firstConnectedGM(); |     return game.user == Misc.firstConnectedGM(); | ||||||
|   } |   } | ||||||
|  |    | ||||||
|  |   static hasConnectedGM() { | ||||||
|  |     return Misc.firstConnectedGM(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static firstConnectedGMId() { |   static firstConnectedGMId() { | ||||||
|     return Misc.firstConnectedGM()?.id; |     return Misc.firstConnectedGM()?.id; | ||||||
| @@ -226,13 +237,7 @@ export class Misc { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static findFirstLike(value, elements, options = {}) { |   static findFirstLike(value, elements, options = {}) { | ||||||
|     options = foundry.utils.mergeObject({ |     options = foundry.utils.mergeObject(DEFAULT_FIND_OPTIONS, options, { overwrite: true, inplace: false }); | ||||||
|       mapper: it => it.name, |  | ||||||
|       preFilter: it => true, |  | ||||||
|       description: 'valeur', |  | ||||||
|       onMessage: m => ui.notifications.info(m) |  | ||||||
|     }, options, { overwrite: true, inplace: false }); |  | ||||||
|  |  | ||||||
|     const subset = this.findAllLike(value, elements, options); |     const subset = this.findAllLike(value, elements, options); | ||||||
|     if (subset.length == 0) { |     if (subset.length == 0) { | ||||||
|       console.log(`Aucune ${options.description} pour ${value}`); |       console.log(`Aucune ${options.description} pour ${value}`); | ||||||
| @@ -251,13 +256,7 @@ export class Misc { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static findAllLike(value, elements, options = {}) { |   static findAllLike(value, elements, options = {}) { | ||||||
|     options = foundry.utils.mergeObject({ |     options = foundry.utils.mergeObject(DEFAULT_FIND_OPTIONS, options, { overwrite: true, inplace: false }); | ||||||
|       mapper: it => it.name, |  | ||||||
|       preFilter: it => true, |  | ||||||
|       description: 'valeur', |  | ||||||
|       onMessage: m => ui.notifications.info(m) |  | ||||||
|     }, options); |  | ||||||
|  |  | ||||||
|     if (!value) { |     if (!value) { | ||||||
|       options.onMessage(`Pas de ${options.description} correspondant à une valeur vide`); |       options.onMessage(`Pas de ${options.description} correspondant à une valeur vide`); | ||||||
|       return []; |       return []; | ||||||
|   | |||||||
| @@ -1,48 +1,8 @@ | |||||||
| /* -------------------------------------------- */ |  | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
|  |  | ||||||
| const matchOperations = new RegExp(/@(\w*){([\w\-]+)}/ig); |  | ||||||
| const matchOperationTerms = new RegExp(/@(\w*){([\w\-]+)}/i); |  | ||||||
| /* -------------------------------------------- */ |  | ||||||
| export class RdDAlchimie { | export class RdDAlchimie { | ||||||
|  |   static getDifficulte(termes) { | ||||||
|   /* -------------------------------------------- */ |     let elements = termes.split('-'); | ||||||
|   static processManipulation(recette, actorId = undefined) { |  | ||||||
|     let manip = recette.system.manipulation; |  | ||||||
|     let matchArray = manip.match(matchOperations); |  | ||||||
|     if (matchArray) { |  | ||||||
|       for (let matchStr of matchArray) { |  | ||||||
|         let result = matchStr.match(matchOperationTerms); |  | ||||||
|         if (result[1] && result[2]) { |  | ||||||
|           let commande = Misc.upperFirst(result[1]); |  | ||||||
|           let replacement = this[`_alchimie${commande}`](recette, result[2], actorId); |  | ||||||
|           manip = manip.replace(result[0], replacement); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     recette.system.manipulation_update = manip; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static _alchimieCouleur(recette, couleurs, actorId) { |  | ||||||
|     return RdDAlchimie._alchimieLink(recette, couleurs, actorId,  'couleur',  'Température'); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static _alchimieConsistance(recette, consistances, actorId) { |  | ||||||
|     return RdDAlchimie._alchimieLink(recette, consistances, actorId,  'consistance',  'Consistance'); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static _alchimieLink(recette, termes, actorId, tacheAlchimie, labelTache) { |  | ||||||
|     const difficulte = RdDAlchimie.getDifficulte(termes); |  | ||||||
|     const link = actorId ? ` <a data-recette-id="${recette._id}" data-actor-id="${actorId}" data-alchimie-tache="${tacheAlchimie}" data-alchimie-data="${termes}">` : ''; |  | ||||||
|     const endLink = actorId ? '</a>' : ''; |  | ||||||
|     return `<span class="alchimie-tache">${link}${labelTache} ${termes} (${difficulte})${endLink}</span>`; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static getDifficulte(aspects) { |  | ||||||
|     let elements = aspects.split('-'); |  | ||||||
|     let composantes = elements.length; |     let composantes = elements.length; | ||||||
|     let distincts = Object.keys(Misc.classifyFirst(elements, it => it)).length; |     let distincts = Object.keys(Misc.classifyFirst(elements, it => it)).length; | ||||||
|     if (distincts == 1) { |     if (distincts == 1) { | ||||||
| @@ -58,5 +18,4 @@ export class RdDAlchimie { | |||||||
|     } |     } | ||||||
|     return 'intellect'; |     return 'intellect'; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ const TABLE_CARACTERISTIQUES_DERIVEES = { | |||||||
|   32: { xp: 180, niveau: 11, poids: "1501-2000", poidsMin: 1501, poidsMax: 2000, plusdom: +11, sconst: 10, sust: 17 } |   32: { xp: 180, niveau: 11, poids: "1501-2000", poidsMin: 1501, poidsMax: 2000, plusdom: +11, sconst: 10, sust: 17 } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| export const LIST_CARAC = { | export const LIST_CARAC_PERSONNAGE = { | ||||||
|   'taille': { code: 'taille', label: 'Taille', isCarac: true, path: 'system.carac.taille.value' }, |   'taille': { code: 'taille', label: 'Taille', isCarac: true, path: 'system.carac.taille.value' }, | ||||||
|   'apparence': { code: 'apparence', label: 'Apparence', isCarac: true, path: 'system.carac.apparence.value' }, |   'apparence': { code: 'apparence', label: 'Apparence', isCarac: true, path: 'system.carac.apparence.value' }, | ||||||
|   'constitution': { code: 'constitution', label: 'Constitution', isCarac: true, path: 'system.carac.constitution.value' }, |   'constitution': { code: 'constitution', label: 'Constitution', isCarac: true, path: 'system.carac.constitution.value' }, | ||||||
| @@ -56,18 +56,43 @@ export const LIST_CARAC = { | |||||||
|   'beaute': { code: 'beaute', label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' } |   'beaute': { code: 'beaute', label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export const LIST_CARAC_AUTRES = { | ||||||
|  |   'perception': { code: 'perception', label: 'Perception',  path: 'system.carac.perception.value' }, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const LIST_CARAC_DERIVEE = { | ||||||
|  |   'melee': { code: "melee", label: 'Mêlée', path: 'system.carac.melee.value' }, | ||||||
|  |   'tir': { code: "tir", label: 'Tir', path: 'system.carac.tir.value' }, | ||||||
|  |   'lancer': { code: "lancer", label: 'Lancer', path: 'system.carac.lancer.value' }, | ||||||
|  |   'derobee': { code: "derobee", label: 'Dérobée', path: 'system.carac.derobee.value' }, | ||||||
|  |   'chance-actuelle': { code: "chance-actuelle", label: 'Chance actuelle', path: 'system.carac.lancer.value' }, | ||||||
|  |   'reve-actuel': { code: "reve-actuel", label: 'Rêve actuel', path: 'system.reve.reve.value' }, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const LIST_CARAC_ROLL = Object.values(LIST_CARAC_PERSONNAGE).filter(it => it.isCarac && it.code != 'taille') | ||||||
|  |   .concat(Object.values(LIST_CARAC_AUTRES)) | ||||||
|  |   .concat(Object.values(LIST_CARAC_DERIVEE)) | ||||||
|  |  | ||||||
| export class RdDCarac { | export class RdDCarac { | ||||||
|  |  | ||||||
|  |   static caracDetails(name) { | ||||||
|  |     let entry = Misc.findFirstLike(name, LIST_CARAC_ROLL, { mapper: it => it.code, description: 'caractéristique', onMessage: m => { } }) | ||||||
|  |     if (entry) { | ||||||
|  |       return entry | ||||||
|  |     } | ||||||
|  |     return Misc.findFirstLike(name, LIST_CARAC_ROLL, { mapper: it => it.label, description: 'caractéristique' }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static carac(code) { |   static carac(code) { | ||||||
|     return LIST_CARAC[code] |     return LIST_CARAC_PERSONNAGE[code] | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static label(code) { |   static label(code) { | ||||||
|     return  RdDCarac.carac(code)?.label ?? '---' |     return RdDCarac.carac(code)?.label ?? '---' | ||||||
|   }   |   } | ||||||
|  |  | ||||||
|   static caracs(filter = it => it.isCarac) { |   static caracs(filter = it => it.isCarac) { | ||||||
|     return Object.values(LIST_CARAC).filter(filter) |     return Object.values(LIST_CARAC_PERSONNAGE).filter(filter) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static isAgiliteOuDerobee(selectedCarac) { |   static isAgiliteOuDerobee(selectedCarac) { | ||||||
|   | |||||||
| @@ -472,15 +472,15 @@ export class RdDCombat { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static registerChatCallbacks(html) { |   static registerChatCallbacks(html) { | ||||||
|     for (let button of [ |     for (let button of [ | ||||||
|       '#parer-button', |       '.parer-button', | ||||||
|       '#esquiver-button', |       '.esquiver-button', | ||||||
|       '#particuliere-attaque', |       '.particuliere-attaque', | ||||||
|       '#encaisser-button', |       '.encaisser-button', | ||||||
|       '#appel-chance-defense', |       '.appel-chance-defense', | ||||||
|       '#appel-destinee-defense', |       '.appel-destinee-defense', | ||||||
|       '#appel-chance-attaque', |       '.appel-chance-attaque', | ||||||
|       '#appel-destinee-attaque', |       '.appel-destinee-attaque', | ||||||
|       '#echec-total-attaque', |       '.echec-total-attaque', | ||||||
|     ]) { |     ]) { | ||||||
|       html.on("click", button, event => { |       html.on("click", button, event => { | ||||||
|         const rddCombat = RdDCombat.rddCombatForAttackerAndDefender( |         const rddCombat = RdDCombat.rddCombatForAttackerAndDefender( | ||||||
| @@ -539,22 +539,22 @@ export class RdDCombat { | |||||||
|     const compId = event.currentTarget.attributes['data-compid']?.value; |     const compId = event.currentTarget.attributes['data-compid']?.value; | ||||||
|  |  | ||||||
|     switch (button) { |     switch (button) { | ||||||
|       case '#particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); |       case '.particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); | ||||||
|       case '#parer-button': return this.parade(attackerRoll, armeParadeId); |       case '.parer-button': return this.parade(attackerRoll, armeParadeId); | ||||||
|       case '#esquiver-button': return this.esquive(attackerRoll, compId, competence); |       case '.esquiver-button': return this.esquive(attackerRoll, compId, competence); | ||||||
|       case '#encaisser-button': return this.encaisser(attackerRoll, defenderRoll); |       case '.encaisser-button': return this.encaisser(attackerRoll, defenderRoll); | ||||||
|       case '#echec-total-attaque': return this._onEchecTotal(attackerRoll); |       case '.echec-total-attaque': return this._onEchecTotal(attackerRoll); | ||||||
|  |  | ||||||
|       case '#appel-chance-attaque': return this.attacker.rollAppelChance( |       case '.appel-chance-attaque': return this.attacker.rollAppelChance( | ||||||
|         () => this.attaqueChanceuse(attackerRoll), |         () => this.attaqueChanceuse(attackerRoll), | ||||||
|         () => this._onEchecTotal(attackerRoll)); |         () => this._onEchecTotal(attackerRoll)); | ||||||
|       case '#appel-chance-defense': return this.defender.rollAppelChance( |       case '.appel-chance-defense': return this.defender.rollAppelChance( | ||||||
|         () => this.defenseChanceuse(attackerRoll, defenderRoll), |         () => this.defenseChanceuse(attackerRoll, defenderRoll), | ||||||
|         () => this.afficherOptionsDefense(attackerRoll, defenderRoll, { defenseChance: true })); |         () => this.afficherOptionsDefense(attackerRoll, defenderRoll, { defenseChance: true })); | ||||||
|       case '#appel-destinee-attaque': return this.attacker.appelDestinee( |       case '.appel-destinee-attaque': return this.attacker.appelDestinee( | ||||||
|         () => this.attaqueSignificative(attackerRoll), |         () => this.attaqueSignificative(attackerRoll), | ||||||
|         () => { }); |         () => { }); | ||||||
|       case '#appel-destinee-defense': return this.defender.appelDestinee( |       case '.appel-destinee-defense': return this.defender.appelDestinee( | ||||||
|         () => this.defenseDestinee(defenderRoll), |         () => this.defenseDestinee(defenderRoll), | ||||||
|         () => { }); |         () => { }); | ||||||
|     } |     } | ||||||
| @@ -967,7 +967,6 @@ export class RdDCombat { | |||||||
|   async _onAttaqueEchec(rollData) { |   async _onAttaqueEchec(rollData) { | ||||||
|     console.log("RdDCombat.onAttaqueEchec >>>", rollData); |     console.log("RdDCombat.onAttaqueEchec >>>", rollData); | ||||||
|     await RdDResolutionTable.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.html'); |     await RdDResolutionTable.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.html'); | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -361,13 +361,14 @@ export class RdDCommands { | |||||||
|   async getTMRAleatoire(msg, params) { |   async getTMRAleatoire(msg, params) { | ||||||
|     if (params.length < 2) { |     if (params.length < 2) { | ||||||
|       let type = params[0] |       let type = params[0] | ||||||
|       const solvedTerrain = TMRUtility.findTMRLike(type)?.type |       const solvedTerrain = type ? TMRUtility.findTMRLike(type)?.type : undefined | ||||||
|       if (solvedTerrain){ |       const filter = solvedTerrain ? (it => it.type == solvedTerrain) : (it => true) | ||||||
|         const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == solvedTerrain) : (it => true)) |       if (type == undefined || solvedTerrain != undefined) { | ||||||
|  |         const tmr = await TMRUtility.getTMRAleatoire(filter) | ||||||
|         return RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`) |         return RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return false; |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async findTMR(msg, params) { |   async findTMR(msg, params) { | ||||||
|   | |||||||
| @@ -4,8 +4,7 @@ import { RdDRoll } from "./rdd-roll.js"; | |||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
| import { STATUSES } from "./settings/status-effects.js"; | import { STATUSES } from "./settings/status-effects.js"; | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { ITEM_TYPES } from "./item.js"; |  | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
|  |  | ||||||
| @@ -429,7 +428,6 @@ export class RdDEmpoignade { | |||||||
|     return await Item.create({ |     return await Item.create({ | ||||||
|       name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, |       name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, | ||||||
|       type: 'empoignade', |       type: 'empoignade', | ||||||
|       img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", |  | ||||||
|       system: { description: "", empoignadeid: foundry.utils.randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name } |       system: { description: "", empoignadeid: foundry.utils.randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name } | ||||||
|     }, |     }, | ||||||
|       { |       { | ||||||
|   | |||||||
| @@ -1,73 +0,0 @@ | |||||||
| import { Grammar } from "./grammar.js"; |  | ||||||
| import { SystemCompendiums } from "./settings/system-compendiums.js"; |  | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; |  | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ |  | ||||||
| export class RdDHerbes extends Item { |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static async onReady() { |  | ||||||
|     this.herbesSoins = await RdDHerbes.listCategorieHerbes('Soin'); |  | ||||||
|     this.herbesRepos = await RdDHerbes.listCategorieHerbes('Repos'); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static async listCategorieHerbes(categorie) { |  | ||||||
|     const herbes = await SystemCompendiums.getWorldOrCompendiumItems('herbe', 'faune-flore-mineraux'); |  | ||||||
|     return herbes.filter(it => Grammar.equalsInsensitive(it.system.categorie, categorie)); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static buildHerbesList(listeHerbes, max) { |  | ||||||
|     let list = {} |  | ||||||
|     for (let herbe of listeHerbes) { |  | ||||||
|       let brins = max - herbe.system.niveau; |  | ||||||
|       list[herbe.name] = `${herbe.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`; |  | ||||||
|     } |  | ||||||
|     list['Autre'] = 'Autre (Bonus: variable, Brins: variable)' |  | ||||||
|     return list; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static calculFormData(formData, item) { |  | ||||||
|     formData.isSoins = item.system.categorie.includes('Soin'); |  | ||||||
|     formData.isRepos = item.system.categorie.includes('Repos'); |  | ||||||
|     if (formData.isSoins) { |  | ||||||
|       RdDHerbes.calculBonusHerbe(formData, this.herbesSoins, 12); |  | ||||||
|     } |  | ||||||
|     if (formData.isRepos) { |  | ||||||
|       RdDHerbes.calculBonusHerbe(formData, this.herbesRepos, 7); |  | ||||||
|     } |  | ||||||
|     formData.herbesSoins = RdDHerbes.buildHerbesList(this.herbesSoins, 12); |  | ||||||
|     formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7); |  | ||||||
|     formData.dateActuelle = game.system.rdd.calendrier.dateCourante(); |  | ||||||
|     formData.enchantement = RdDTimestamp.splitIndexDate(item.system.prdate); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static calculPuissancePotion(potion) { |  | ||||||
|     return potion.system.herbebonus * potion.system.pr; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static calculPointsRepos(potion) { |  | ||||||
|     return potion.system.herbebonus * potion.system.pr; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static calculPointsGuerison(potion) { |  | ||||||
|     return potion.system.herbebonus * potion.system.pr; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static calculBonusHerbe(formData, herbesList, max) { |  | ||||||
|     if (Number(formData.system.herbebrins)) { |  | ||||||
|       let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase()); |  | ||||||
|       if (herbe) { |  | ||||||
|         const brinsRequis = max - herbe.system.niveau; |  | ||||||
|         const brinsManquants = Math.max(brinsRequis - formData.system.herbebrins, 0); |  | ||||||
|         formData.system.herbebonus = Math.max(herbe.system.niveau - brinsManquants, 0); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| }   |  | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { RdDItemArme } from "./item-arme.js"; | import { RdDItemArme } from "./item-arme.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
|  |  | ||||||
| export class RdDHotbar { | export class RdDHotbar { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,6 @@ import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js" | |||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js" | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js" | ||||||
| import { RdDHotbar } from "./rdd-hotbar-drop.js" | import { RdDHotbar } from "./rdd-hotbar-drop.js" | ||||||
| import { EffetsDraconiques } from "./tmr/effets-draconiques.js" | import { EffetsDraconiques } from "./tmr/effets-draconiques.js" | ||||||
| import { RdDHerbes } from "./rdd-herbes.js" |  | ||||||
| import { RdDDice } from "./rdd-dice.js" | import { RdDDice } from "./rdd-dice.js" | ||||||
| import { RdDPossession } from "./rdd-possession.js" | import { RdDPossession } from "./rdd-possession.js" | ||||||
| import { Misc } from "./misc.js" | import { Misc } from "./misc.js" | ||||||
| @@ -75,6 +74,9 @@ import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium | |||||||
| import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" | import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" | ||||||
| import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | ||||||
| import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" | import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" | ||||||
|  | import { RdDJournalSheet } from "./journal/journal-sheet.js" | ||||||
|  | import { RdDPotionItemSheet } from "./item/sheet-potion.js" | ||||||
|  | import { RdDItemPotion } from "./item/potion.js" | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * RdD system |  * RdD system | ||||||
| @@ -85,9 +87,9 @@ export class SystemReveDeDragon { | |||||||
|  |  | ||||||
|   static start() { |   static start() { | ||||||
|     const system = new SystemReveDeDragon() |     const system = new SystemReveDeDragon() | ||||||
|     Hooks.once('init', async () => await system.onInit()) |     Hooks.once('init', () => system.onInit()) | ||||||
|     Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d)) |     Hooks.once('diceSoNiceReady', (dice3d) => RdDDice.diceSoNiceReady(dice3d)) | ||||||
|     Hooks.once('ready', async () => await system.onReady()) |     Hooks.once('ready', () => system.onReady()) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   constructor() { |   constructor() { | ||||||
| @@ -103,6 +105,7 @@ export class SystemReveDeDragon { | |||||||
|       poison: RdDItemPoison, |       poison: RdDItemPoison, | ||||||
|       queue: RdDItemQueue, |       queue: RdDItemQueue, | ||||||
|       tete: RdDItemTete, |       tete: RdDItemTete, | ||||||
|  |       potion: RdDItemPotion, | ||||||
|       race: RdDItemRace, |       race: RdDItemRace, | ||||||
|       rencontre: RdDRencontre, |       rencontre: RdDRencontre, | ||||||
|       service: RdDItemService, |       service: RdDItemService, | ||||||
| @@ -121,7 +124,7 @@ export class SystemReveDeDragon { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   /*  Foundry VTT Initialization                  */ |   /*  Foundry VTT Initialization                  */ | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onInit() { |   onInit() { | ||||||
|     game.system.rdd = this |     game.system.rdd = this | ||||||
|     this.AppAstrologie = AppAstrologie |     this.AppAstrologie = AppAstrologie | ||||||
|  |  | ||||||
| @@ -185,7 +188,7 @@ export class SystemReveDeDragon { | |||||||
|     Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }) |     Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }) | ||||||
|     Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true }) |     Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true }) | ||||||
|     Items.unregisterSheet("core", ItemSheet) |     Items.unregisterSheet("core", ItemSheet) | ||||||
|     await RdDActorExportSheet.init() |     RdDActorExportSheet.init() | ||||||
|  |  | ||||||
|     RdDItemSheet.register(RdDSigneDraconiqueItemSheet) |     RdDItemSheet.register(RdDSigneDraconiqueItemSheet) | ||||||
|     RdDItemSheet.register(RdDRencontreItemSheet) |     RdDItemSheet.register(RdDRencontreItemSheet) | ||||||
| @@ -193,15 +196,18 @@ export class SystemReveDeDragon { | |||||||
|     RdDItemSheet.register(RdDHerbeItemSheet) |     RdDItemSheet.register(RdDHerbeItemSheet) | ||||||
|     RdDItemSheet.register(RdDFauneItemSheet) |     RdDItemSheet.register(RdDFauneItemSheet) | ||||||
|     RdDItemSheet.register(RdDPlanteItemSheet) |     RdDItemSheet.register(RdDPlanteItemSheet) | ||||||
|  |     RdDItemSheet.register(RdDPotionItemSheet) | ||||||
|     RdDItemSheet.register(RdDIngredientItemSheet) |     RdDItemSheet.register(RdDIngredientItemSheet) | ||||||
|     RdDItemSheet.register(RdDServiceItemSheet) |     RdDItemSheet.register(RdDServiceItemSheet) | ||||||
|     RdDItemSheet.register(RdDBlessureItemSheet) |     RdDItemSheet.register(RdDBlessureItemSheet) | ||||||
|  |     RdDJournalSheet.register() | ||||||
|  |  | ||||||
|     Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, { |     Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, { | ||||||
|       types: [ |       types: [ | ||||||
|         "objet", "arme", "armure", "livre", "potion", "munition", |         "objet", "arme", "armure", "livre", "munition", | ||||||
|         "monnaie", "nourritureboisson", "gemme", |         "monnaie", "nourritureboisson", "gemme", | ||||||
|       ], makeDefault: true |       ], | ||||||
|  |       makeDefault: true | ||||||
|     }) |     }) | ||||||
|     Items.registerSheet(SYSTEM_RDD, RdDItemSheet, { |     Items.registerSheet(SYSTEM_RDD, RdDItemSheet, { | ||||||
|       types: [ |       types: [ | ||||||
| @@ -211,7 +217,8 @@ export class SystemReveDeDragon { | |||||||
|         "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve", |         "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve", | ||||||
|         "nombreastral", "tache", "maladie", "poison", "possession", |         "nombreastral", "tache", "maladie", "poison", "possession", | ||||||
|         "tarot", "extraitpoetique", "empoignade" |         "tarot", "extraitpoetique", "empoignade" | ||||||
|       ], makeDefault: true |       ], | ||||||
|  |       makeDefault: true | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     // préparation des différents modules |     // préparation des différents modules | ||||||
| @@ -313,7 +320,6 @@ export class SystemReveDeDragon { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     StatusEffects.onReady() |     StatusEffects.onReady() | ||||||
|     RdDHerbes.onReady() |  | ||||||
|     RdDDice.onReady() |     RdDDice.onReady() | ||||||
|  |  | ||||||
|     RdDStatBlockParser.parseStatBlock() |     RdDStatBlockParser.parseStatBlock() | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js"; | |||||||
| import { RdDRoll } from "./rdd-roll.js"; | import { RdDRoll } from "./rdd-roll.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||||
| import { Targets } from "./targets.js"; | import { Targets } from "./targets.js"; | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| /* On part du principe qu'une entité démarre tjs  | /* On part du principe qu'une entité démarre tjs  | ||||||
| @@ -174,7 +174,7 @@ export class RdDPossession { | |||||||
|     await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html') |     await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html') | ||||||
|     if (rollData.possession.isPosseder || rollData.possession.isConjurer) { |     if (rollData.possession.isPosseder || rollData.possession.isConjurer) { | ||||||
|       // conjuration |       // conjuration | ||||||
|       victime.deleteEmbeddedDocuments("Item", [rollData.possession._id]) |       await victime.deleteEmbeddedDocuments("Item", [rollData.possession._id]) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import { RdDCarac } from "./rdd-carac.js"; | |||||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
|  | import { ACTOR_TYPES } from "./constants.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Extend the base Dialog entity to select roll parameters |  * Extend the base Dialog entity to select roll parameters | ||||||
| @@ -62,7 +63,7 @@ export class RdDRoll extends Dialog { | |||||||
|       forceDiceResult: -1 |       forceDiceResult: -1 | ||||||
|     } |     } | ||||||
|     // Mini patch :Ajout du rêve actuel |     // Mini patch :Ajout du rêve actuel | ||||||
|     if (actor.system.type == "personnage") { |     if (actor.type == ACTOR_TYPES.personnage) { | ||||||
|       defaultRollData.carac["reve-actuel"] = actor.system.reve.reve |       defaultRollData.carac["reve-actuel"] = actor.system.reve.reve | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -131,11 +132,16 @@ export class RdDRoll extends Dialog { | |||||||
|     console.log('RdDRoll.activateListeners', this.rollData); |     console.log('RdDRoll.activateListeners', this.rollData); | ||||||
|  |  | ||||||
|     // Update html, according to rollData |     // Update html, according to rollData | ||||||
|     if (this.rollData.competence) { |     if (!this.rollData.selectedCarac && this.rollData.competence) { | ||||||
|       const defaut_carac = this.rollData.competence.system.defaut_carac |  | ||||||
|       // Set the default carac from the competence item |       // Set the default carac from the competence item | ||||||
|       this.rollData.selectedCarac = this.rollData.carac[defaut_carac]; |       this.rollData.selectedCarac = this.rollData.carac[this.actor.mapCarac(this.rollData.competence.system.defaut_carac)] | ||||||
|       this.html.find("[name='carac']").val(defaut_carac); |     } | ||||||
|  |     if (this.rollData.selectedCarac) { | ||||||
|  |       this.html.find("[name='carac']").val( | ||||||
|  |         this.actor?.type == ACTOR_TYPES.personnage | ||||||
|  |           ? RdDCarac.caracDetails(this.rollData.selectedCarac.label).code | ||||||
|  |           : this.rollData.selectedCarac.label | ||||||
|  |       ) | ||||||
|     } |     } | ||||||
|     if (this.rollData.selectedSort) { |     if (this.rollData.selectedSort) { | ||||||
|       this.setSelectedSort(this.rollData.selectedSort); |       this.setSelectedSort(this.rollData.selectedSort); | ||||||
| @@ -173,7 +179,7 @@ export class RdDRoll extends Dialog { | |||||||
|       this.updateRollResult(html); |       this.updateRollResult(html); | ||||||
|       this.html.find("[name='diffLibre']").val(this.rollData.diffLibre); |       this.html.find("[name='diffLibre']").val(this.rollData.diffLibre); | ||||||
|     }); |     }); | ||||||
|     this.html.find('.roll-carac-competence').change((event) => { |     this.html.find('.roll-text').change((event) => { | ||||||
|       const competence = event.currentTarget.value |       const competence = event.currentTarget.value | ||||||
|       this.rollData.competence = this.rollData.competences.find(it => Grammar.equalsInsensitive(it.name, competence)) |       this.rollData.competence = this.rollData.competences.find(it => Grammar.equalsInsensitive(it.name, competence)) | ||||||
|       this.updateRollResult(html); |       this.updateRollResult(html); | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||||
| import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js"; | import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js"; | ||||||
|  |  | ||||||
| export class RdDRollTables { | export class RdDRollTables { | ||||||
| @@ -28,8 +29,8 @@ export class RdDRollTables { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async drawTextFromRollTable(tableName, toChat) { |   static async drawTextFromRollTable(tableName, options = {}) { | ||||||
|     const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat); |     const drawResult = await RdDRollTables.genericGetTableResult(tableName, options.toChat); | ||||||
|     return drawResult.text; |     return drawResult.text; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -103,7 +104,7 @@ export class RdDRollTables { | |||||||
|   static async getMaladresse(options = { toChat: false, arme: false }) { |   static async getMaladresse(options = { toChat: false, arme: false }) { | ||||||
|     return await RdDRollTables.drawTextFromRollTable( |     return await RdDRollTables.drawTextFromRollTable( | ||||||
|       options.arme ? "Maladresse armé" : "Maladresses non armé", |       options.arme ? "Maladresse armé" : "Maladresses non armé", | ||||||
|       options.toChat); |       options) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ export class RdDSheetUtility { | |||||||
|       await RdDSheetUtility._onSplitItem(item, split, actor); |       await RdDSheetUtility._onSplitItem(item, split, actor); | ||||||
|       onSplit(); |       onSplit(); | ||||||
|     }); |     }); | ||||||
|     dialog.render(true); |     dialog.render(true) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async _onSplitItem(item, split, actor) { |   static async _onSplitItem(item, split, actor) { | ||||||
| @@ -82,4 +82,11 @@ export class RdDSheetUtility { | |||||||
|       await actor.createEmbeddedDocuments('Item', [splitItem]) |       await actor.createEmbeddedDocuments('Item', [splitItem]) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static async renderItemBranch(actor, item) { | ||||||
|  |     while (item) { | ||||||
|  |       await item.sheet?.render() | ||||||
|  |       item = actor.getContenant(item) | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -16,7 +16,7 @@ import { RdDDice } from "./rdd-dice.js"; | |||||||
| import { STATUSES } from "./settings/status-effects.js"; | import { STATUSES } from "./settings/status-effects.js"; | ||||||
| import { RdDRencontre } from "./item/rencontre.js"; | import { RdDRencontre } from "./item/rencontre.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
| import { ITEM_TYPES } from "./item.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
|  |  | ||||||
| const TMR_DISPLAY_SIZE = { | const TMR_DISPLAY_SIZE = { | ||||||
| @@ -212,7 +212,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   getSortsReserve(coord) { |   getSortsReserve(coord) { | ||||||
|     return this.actor.itemTypes[ITEM_TYPES.sortreserve].filter(// Reserve sur une case fleuve ou normale |     return this.sortsReserve.filter(// Reserve sur une case fleuve ou normale | ||||||
|       TMRUtility.getTMR(coord).type == 'fleuve' |       TMRUtility.getTMR(coord).type == 'fleuve' | ||||||
|         ? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve' |         ? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve' | ||||||
|         : it => it.system.coord == coord |         : it => it.system.coord == coord | ||||||
| @@ -241,7 +241,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     this._getTokensRencontres().forEach(t => this._trackToken(t)) |     this._getTokensRencontres().forEach(t => this._trackToken(t)) | ||||||
|     this._getTokensSortsReserve().forEach(t => this._trackToken(t)) |     this._getTokensSortsReserve().forEach(t => this._trackToken(t)) | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   updateTokens() { |   updateTokens() { | ||||||
|     this._removeTokens(t => true); |     this._removeTokens(t => true); | ||||||
| @@ -271,8 +271,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   _getTokensSortsReserve() { |   _getTokensSortsReserve() { | ||||||
|     const sortsReserve = this.actor.itemTypes[ITEM_TYPES.sortreserve]; |     return Misc.concat(this.sortsReserve.map(sortReserve => | ||||||
|     return Misc.concat(sortsReserve.map(sortReserve => |  | ||||||
|       EffetsDraconiques.sortReserve.tokens(this.pixiTMR, sortReserve, () => sortReserve.system.coord))) |       EffetsDraconiques.sortReserve.tokens(this.pixiTMR, sortReserve, () => sortReserve.system.coord))) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -908,8 +907,8 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   lancerSortEnReserve(coord, sortId) { |   lancerSortEnReserve(coord, sortId) { | ||||||
|     let sorts = this.getSortsReserve(coord); |     const sort = this.getSortsReserve(coord) | ||||||
|     let sort = sorts.find(it => it.id == sortId); |       .find(it => it.id == sortId); | ||||||
|     if (sort) { |     if (sort) { | ||||||
|       this.processSortReserve(sort); |       this.processSortReserve(sort); | ||||||
|     } else { |     } else { | ||||||
|   | |||||||
| @@ -19,9 +19,12 @@ import { RdDEmpoignade } from "./rdd-empoignade.js"; | |||||||
| import { ExperienceLog } from "./actor/experience-log.js"; | import { ExperienceLog } from "./actor/experience-log.js"; | ||||||
| import { RdDCoeur } from "./coeur/rdd-coeur.js"; | import { RdDCoeur } from "./coeur/rdd-coeur.js"; | ||||||
| import { APP_ASTROLOGIE_REFRESH } from "./sommeil/app-astrologie.js"; | import { APP_ASTROLOGIE_REFRESH } from "./sommeil/app-astrologie.js"; | ||||||
| import { RDD_CONFIG } from "./constants.js"; | import { ITEM_TYPES, RDD_CONFIG } from "./constants.js"; | ||||||
| import { RdDBaseActor } from "./actor/base-actor.js"; | import { RdDBaseActor } from "./actor/base-actor.js"; | ||||||
| import { RdDCarac } from "./rdd-carac.js"; | import { RdDCarac } from "./rdd-carac.js"; | ||||||
|  | import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||||
|  | import { Monnaie } from "./item-monnaie.js"; | ||||||
|  | import { ItemAction } from "./item/item-actions.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| // This table starts at 0 -> niveau -10 | // This table starts at 0 -> niveau -10 | ||||||
| @@ -106,7 +109,7 @@ export class RdDUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async preloadHandlebarsTemplates() { |   static preloadHandlebarsTemplates() { | ||||||
|     const templatePaths = [ |     const templatePaths = [ | ||||||
|       //Character Sheets |       //Character Sheets | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html', | ||||||
| @@ -114,6 +117,7 @@ export class RdDUtility { | |||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html', | ||||||
|       // sous-parties de feuilles de personnages |       // sous-parties de feuilles de personnages | ||||||
|  |       'systems/foundryvtt-reve-de-dragon/templates/actor/item-action-controls.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-buttons.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/header-buttons.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.html', | ||||||
| @@ -128,48 +132,47 @@ export class RdDUtility { | |||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-entitee.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-entitee.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/competence.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/competence.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/combat.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/combat.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/resonances.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/resonances.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/taches.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/jeus.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/jeux.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.html', |  | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/chirurgie.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/chirurgie.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/non-haut-revant.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/haut-revant.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-signes-draconiques.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-signes-draconiques.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-rencontres.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-rencontres.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts-reserve.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts-reserve.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-meditations.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-meditations.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-casestmr.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-casetmrs.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.hbs', | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html", |       "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.hbs", | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.html', |       'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.hbs', | ||||||
|       //Items |       //Items | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs', | ||||||
| @@ -179,8 +182,9 @@ export class RdDUtility { | |||||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html', |       'systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html', |       'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html', |       'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html', |  | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/header-item.html', |       'systems/foundryvtt-reve-de-dragon/templates/header-item.html', | ||||||
|  |  | ||||||
|  |       'systems/foundryvtt-reve-de-dragon/templates/item/queue-sheet.hbs', | ||||||
|       // partial enums |       // partial enums | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html', | ||||||
| @@ -188,7 +192,7 @@ export class RdDUtility { | |||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categories.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-categories.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.html', |       'systems/foundryvtt-reve-de-dragon/templates/item/potion-enum-categorie.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-queue.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-queue.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html', |       'systems/foundryvtt-reve-de-dragon/templates/enum-competence.html', | ||||||
| @@ -262,7 +266,7 @@ export class RdDUtility { | |||||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html', |       'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html' |       'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html' | ||||||
|     ]; |     ]; | ||||||
|      |  | ||||||
|     // foundry et options |     // foundry et options | ||||||
|     Handlebars.registerHelper('RDD_CONFIG', path => RDD_CONFIG[path]) |     Handlebars.registerHelper('RDD_CONFIG', path => RDD_CONFIG[path]) | ||||||
|     Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name)); |     Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name)); | ||||||
| @@ -277,7 +281,7 @@ export class RdDUtility { | |||||||
|       const html = options.fn(this); |       const html = options.fn(this); | ||||||
|       return html.replace(rgx, "$& selected"); |       return html.replace(rgx, "$& selected"); | ||||||
|     }) |     }) | ||||||
|      |  | ||||||
|     // logic |     // logic | ||||||
|     Handlebars.registerHelper('either', (a, b) => a ?? b); |     Handlebars.registerHelper('either', (a, b) => a ?? b); | ||||||
|     // string manipulation |     // string manipulation | ||||||
| @@ -289,12 +293,13 @@ export class RdDUtility { | |||||||
|     Handlebars.registerHelper('grammar-apostrophe', (article, str) => Grammar.apostrophe(article, str)); |     Handlebars.registerHelper('grammar-apostrophe', (article, str) => Grammar.apostrophe(article, str)); | ||||||
|     Handlebars.registerHelper('grammar-un', str => Grammar.articleIndetermine(str)); |     Handlebars.registerHelper('grammar-un', str => Grammar.articleIndetermine(str)); | ||||||
|     Handlebars.registerHelper('grammar-accord', (genre, ...args) => Grammar.accord(genre, args)); |     Handlebars.registerHelper('grammar-accord', (genre, ...args) => Grammar.accord(genre, args)); | ||||||
|      |     Handlebars.registerHelper('json-stringify', object => JSON.stringify(object)) | ||||||
|  |  | ||||||
|     // math |     // math | ||||||
|     Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); |     Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); | ||||||
|     Handlebars.registerHelper('repeat', function(n, block) { |     Handlebars.registerHelper('repeat', function (n, block) { | ||||||
|       let accum = ''; |       let accum = ''; | ||||||
|       for(let i = 0; i < n; ++i){ |       for (let i = 0; i < n; ++i) { | ||||||
|         accum += block.fn(i) |         accum += block.fn(i) | ||||||
|       } |       } | ||||||
|       return accum |       return accum | ||||||
| @@ -332,6 +337,8 @@ export class RdDUtility { | |||||||
|     Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field)); |     Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field)); | ||||||
|     // Items |     // Items | ||||||
|     Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field)); |     Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field)); | ||||||
|  |     Handlebars.registerHelper('item-action-applies', (action, item, options) => ItemAction.applies(action, item, options)) | ||||||
|  |     Handlebars.registerHelper('item-action-icon', (action, item) => ItemAction.icon(action, item)) | ||||||
|  |  | ||||||
|     // TMRs |     // TMRs | ||||||
|     Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord)); |     Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord)); | ||||||
| @@ -339,7 +346,7 @@ export class RdDUtility { | |||||||
|     Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type)); |     Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type)); | ||||||
|     Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord)); |     Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord)); | ||||||
|  |  | ||||||
|     return loadTemplates(templatePaths); |     loadTemplates(templatePaths); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getItem(itemId, actorId = undefined) { |   static getItem(itemId, actorId = undefined) { | ||||||
| @@ -433,8 +440,8 @@ export class RdDUtility { | |||||||
|     }; |     }; | ||||||
|     if (!optionsArbre.templateItem) { |     if (!optionsArbre.templateItem) { | ||||||
|       optionsArbre.templateItem = item.parent?.type == 'commerce' |       optionsArbre.templateItem = item.parent?.type == 'commerce' | ||||||
|         ? "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.html" |         ? "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.hbs" | ||||||
|         : "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html"; |         : "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.hbs"; | ||||||
|     } |     } | ||||||
|     item.niveau = optionsArbre.profondeur; |     item.niveau = optionsArbre.profondeur; | ||||||
|   } |   } | ||||||
| @@ -462,13 +469,38 @@ export class RdDUtility { | |||||||
|     return ligneObjet; |     return ligneObjet; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static filterItemsPerTypeForSheet(formData, itemTypes) { | ||||||
|  |     Object.values(ITEM_TYPES).forEach(t => { | ||||||
|  |       formData[t + 's'] = Misc.arrayOrEmpty(itemTypes[t]) | ||||||
|  |       itemTypes[t].forEach(item => item.actions = item.itemActions()) | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     formData.maladiesPoisons = formData.maladies.concat(formData.poisons) | ||||||
|  |     formData.competences = formData.competences.concat(formData.competencecreatures) | ||||||
|  |     formData.monnaies = formData.monnaies.sort(Monnaie.triValeurEntiere()) | ||||||
|  |  | ||||||
|  |     formData.inventaires = RdDUtility.prepareInventaire(itemTypes) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static buildInventaireConteneur(actorId, itemId, options) { |   static buildInventaireConteneur(actorId, itemId, options) { | ||||||
|     const actor = game.actors.get(actorId) |     const actor = game.actors.get(actorId) | ||||||
|     const item = actor?.items.get(itemId) |     const item = actor?.items.get(itemId) | ||||||
|     if (item) { |     if (item?.type == ITEM_TYPES.conteneur) { | ||||||
|       return RdDUtility.buildContenuConteneur(item, options, { ouvert: true, profondeur: 1 }); |       const formData = {} | ||||||
|  |       RdDUtility.filterItemsPerTypeForSheet(formData, actor.itemTypes); | ||||||
|  |       RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); | ||||||
|  |       item.subItems = formData.conteneurs.find(it => it._id == itemId)?.subItems; | ||||||
|  |  | ||||||
|  |       return RdDUtility.buildContenuConteneur(item, options, { ouvert: true, profondeur: 1 }) | ||||||
|     } |     } | ||||||
|     return ''; |     return '' | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static prepareInventaire(itemTypes) { | ||||||
|  |     return RdDItem.getItemTypesInventaire('all') | ||||||
|  |       .map(t => Misc.arrayOrEmpty(itemTypes[t])) | ||||||
|  |       .reduce((a, b) => a.concat(b), []) | ||||||
|  |       .sort(Misc.ascending(it => it.name)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -695,6 +727,7 @@ export class RdDUtility { | |||||||
|     RdDCombat.registerChatCallbacks(html) |     RdDCombat.registerChatCallbacks(html) | ||||||
|     RdDEmpoignade.registerChatCallbacks(html) |     RdDEmpoignade.registerChatCallbacks(html) | ||||||
|     RdDCoeur.registerChatCallbacks(html) |     RdDCoeur.registerChatCallbacks(html) | ||||||
|  |     RdDTextEditor.registerChatCallbacks(html) | ||||||
|  |  | ||||||
|     // Gestion spécifique message passeurs |     // Gestion spécifique message passeurs | ||||||
|     html.on("click", '.tmr-passeur-coord a', event => { |     html.on("click", '.tmr-passeur-coord a', event => { | ||||||
| @@ -869,7 +902,7 @@ export class RdDUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async confirmActorItemDelete(sheet, item, htmlToDelete) { |   static async confirmActorItemDelete(item, actor) { | ||||||
|     const itemId = item.id; |     const itemId = item.id; | ||||||
|     const confirmationSuppression = { |     const confirmationSuppression = { | ||||||
|       settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(), |       settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(), | ||||||
| @@ -878,8 +911,7 @@ export class RdDUtility { | |||||||
|       buttonLabel: "Supprimer", |       buttonLabel: "Supprimer", | ||||||
|       onAction: () => { |       onAction: () => { | ||||||
|         console.log('Delete : ', itemId); |         console.log('Delete : ', itemId); | ||||||
|         sheet.actor.deleteEmbeddedDocuments('Item', [itemId], { renderSheet: false }); |         actor.deleteEmbeddedDocuments('Item', [itemId], { renderSheet: false }); | ||||||
|         RdDUtility.slideOnDelete(sheet, htmlToDelete); |  | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
|     if (item.isConteneurNonVide()) { |     if (item.isConteneurNonVide()) { | ||||||
| @@ -892,8 +924,7 @@ export class RdDUtility { | |||||||
|             label: "Supprimer conteneur et contenu", |             label: "Supprimer conteneur et contenu", | ||||||
|             callback: () => { |             callback: () => { | ||||||
|               console.log("Delete : ", itemId); |               console.log("Delete : ", itemId); | ||||||
|               sheet.actor.deleteAllConteneur(itemId, { renderSheet: false }); |               actor.deleteAllConteneur(itemId, { renderSheet: false }); | ||||||
|               RdDUtility.slideOnDelete(sheet, htmlToDelete); |  | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         }); |         }); | ||||||
|   | |||||||
| @@ -334,6 +334,10 @@ export class RdDTimestamp { | |||||||
|     return this.nouvelleHeure().addHeures((12 + heure - this.heure) % 12); |     return this.nouvelleHeure().addHeures((12 + heure - this.heure) % 12); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   debutJournee() { | ||||||
|  |     return RdDTimestamp.timestamp(this.annee, this.mois, this.jour) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async appliquerDuree(duree, actor) { |   async appliquerDuree(duree, actor) { | ||||||
|     const formule = FORMULES_DUREE.find(it => it.code == duree) ?? FORMULES_DUREE.find(it => it.code == ""); |     const formule = FORMULES_DUREE.find(it => it.code == duree) ?? FORMULES_DUREE.find(it => it.code == ""); | ||||||
|     return await formule.calcul(this, actor); |     return await formule.calcul(this, actor); | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ export class TMRRencontres { | |||||||
|    * @param {*} forcedRoll  |    * @param {*} forcedRoll  | ||||||
|    */ |    */ | ||||||
|   async rollRencontre(terrain, forcedRoll) { |   async rollRencontre(terrain, forcedRoll) { | ||||||
|     const tmrType = TMRUtility.findTMRLike(terrain)?.type |     const tmrType = TMRUtility.findTMRLike(terrain, { inclusMauvaise: true })?.type | ||||||
|     if (tmrType == undefined) { |     if (tmrType == undefined) { | ||||||
|       return undefined; |       return undefined; | ||||||
|     } |     } | ||||||
| @@ -38,7 +38,7 @@ export class TMRRencontres { | |||||||
|     const frequence = it => it.system.frequence[tmrType]; |     const frequence = it => it.system.frequence[tmrType]; | ||||||
|     const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll); |     const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll); | ||||||
|     if (row) { |     if (row) { | ||||||
|       await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item', {showSource: false}); |       await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item', { showSource: false }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return row?.document; |     return row?.document; | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ export const TMRType = { | |||||||
| export const FLEUVE_COORD = 'Fleuve' | export const FLEUVE_COORD = 'Fleuve' | ||||||
|  |  | ||||||
| const TMRMapping = { | const TMRMapping = { | ||||||
|   Fleuve: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, |   Fleuve: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli", generique: 'fleuve' }, | ||||||
|   A1: { type: TMRType.cite.type, label: "Cité Vide" }, |   A1: { type: TMRType.cite.type, label: "Cité Vide" }, | ||||||
|   B1: { type: TMRType.plaines.type, label: "Plaines d’Assorh" }, |   B1: { type: TMRType.plaines.type, label: "Plaines d’Assorh" }, | ||||||
|   C1: { type: TMRType.necropole.type, label: "Nécropole de Kroak" }, |   C1: { type: TMRType.necropole.type, label: "Nécropole de Kroak" }, | ||||||
| @@ -281,18 +281,18 @@ export class TMRUtility { | |||||||
|     return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label; |     return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static findTMRLike(type, options = { inclusMauvaise: true }) { |   static findTMRLike(type, options = { inclusMauvaise: false }) { | ||||||
|     const choix = [...Object.values(TMRType)] |     const choix = [...Object.values(TMRType)] | ||||||
|     if (options.inclusMauvaise) { |     if (options.inclusMauvaise) { | ||||||
|       choix.push({ name: 'Mauvaise', type: 'mauvaise'}); |       choix.push({ name: 'Mauvaise', type: 'mauvaise'}); | ||||||
|     } |     } | ||||||
|     const selection = Misc.findAllLike(type, choix) |     const selection = Misc.findAllLike(type, choix) | ||||||
|     if (selection.length == 0) { |     if (selection.length == 0) { | ||||||
|       ui.notifications.warn(`Un type de TMR doit être indiqué, '${type}' n'est pas trouvé dans ${choix}`); |       ui.notifications.warn(`Un type de TMR doit être indiqué, '${type}' n'est pas trouvé dans ${choix.map(it => it.name).reduce(Misc.joining(', '))}`); | ||||||
|       return undefined |       return undefined | ||||||
|     } |     } | ||||||
|     if (selection.length > 1) { |     if (selection.length > 1) { | ||||||
|       ui.notifications.warn(`Plusieurs types de TMR pourraient correspondre à '${type}': ${selection.map(it => it.name)}`); |       ui.notifications.warn(`Plusieurs types de TMR pourraient correspondre à '${type}': ${selection.map(it => it.name).reduce(Misc.joining(', '))}`); | ||||||
|       return undefined; |       return undefined; | ||||||
|     } |     } | ||||||
|     return selection[0] |     return selection[0] | ||||||
| @@ -357,7 +357,7 @@ export class TMRUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static filterTMR(filter) { |   static filterTMR(filter) { | ||||||
|     return Object.values(TMRMapping).filter(filter); |     return Object.values(TMRMapping).filter(it => !it.generique && filter(it)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getCasesType(type) { |   static getCasesType(type) { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { TMRUtility } from "../tmr-utility.js"; | import { TMRUtility } from "../tmr-utility.js"; | ||||||
| import { PixiTMR } from "./pixi-tmr.js"; | import { PixiTMR } from "./pixi-tmr.js"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ import { Periple } from "./periple.js"; | |||||||
| import { UrgenceDraconique } from "./urgence-draconique.js"; | import { UrgenceDraconique } from "./urgence-draconique.js"; | ||||||
| import { Grammar } from "../grammar.js"; | import { Grammar } from "../grammar.js"; | ||||||
| import { AugmentationSeuil } from "./augmentation-seuil.js"; | import { AugmentationSeuil } from "./augmentation-seuil.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  |  | ||||||
| export class EffetsDraconiques { | export class EffetsDraconiques { | ||||||
|   static carteTmr = new CarteTmr(); |   static carteTmr = new CarteTmr(); | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import { RdDRollTables } from "../rdd-rolltables.js"; | |||||||
| import { TMRUtility } from "../tmr-utility.js"; | import { TMRUtility } from "../tmr-utility.js"; | ||||||
| import { tmrTokenZIndex } from "../tmr-constants.js"; | import { tmrTokenZIndex } from "../tmr-constants.js"; | ||||||
| import { Draconique } from "./draconique.js"; | import { Draconique } from "./draconique.js"; | ||||||
| import { ITEM_TYPES } from "../item.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { TMRAnimations } from "./animation.js"; | import { TMRAnimations } from "./animation.js"; | ||||||
|  |  | ||||||
| export class UrgenceDraconique extends Draconique { | export class UrgenceDraconique extends Draconique { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ITEM_TYPES } from "../item.js" | import { ITEM_TYPES } from "../constants.js" | ||||||
| import { RdDItemCompetence } from "../item-competence.js" | import { RdDItemCompetence } from "../item-competence.js" | ||||||
| import { ChatUtility } from "../chat-utility.js" | import { ChatUtility } from "../chat-utility.js" | ||||||
| import { Misc } from "../misc.js" | import { Misc } from "../misc.js" | ||||||
|   | |||||||
| @@ -300,7 +300,7 @@ system: | |||||||
|     déchirure. Celle-là se contente de chercher à fuir en |     déchirure. Celle-là se contente de chercher à fuir en | ||||||
|     cas d’agression, ou attaque toutes griffes dehors si elle se sent |     cas d’agression, ou attaque toutes griffes dehors si elle se sent | ||||||
|     acculée. Pour la distinguer (visuellement) de la rieuse, |     acculée. Pour la distinguer (visuellement) de la rieuse, | ||||||
|     réussir VUE/Zoologie à -5. Les caractéristiques de |     réussir @roll[VUE/Zoologie/-5]. Les caractéristiques de | ||||||
|     combat indiquées ne s’appliquent qu’à la |     combat indiquées ne s’appliquent qu’à la | ||||||
|     pointue.</p> |     pointue.</p> | ||||||
|   race: '' |   race: '' | ||||||
|   | |||||||
| @@ -215,7 +215,7 @@ system: | |||||||
|     souffrir ses premiers malus à la course et au saut. La vitesse |     souffrir ses premiers malus à la course et au saut. La vitesse | ||||||
|     indiquée correspond à une allure plutôt lente. |     indiquée correspond à une allure plutôt lente. | ||||||
|     Contrairement aux autres animaux pour qui la vitesse de base est fixe, le |     Contrairement aux autres animaux pour qui la vitesse de base est fixe, le | ||||||
|     gardien des rêves peut rajouter jusqu’à 3d6 points |     gardien des rêves peut rajouter jusqu’à @roll[3d6] points | ||||||
|     à la vitesse de course de chaque individu. Cette nouvelle vitesse de |     à la vitesse de course de chaque individu. Cette nouvelle vitesse de | ||||||
|     course est rajoutée une fois pour toutes, mais peut être |     course est rajoutée une fois pour toutes, mais peut être | ||||||
|     modulée par un jet de course sur la table de Course animale.</p> |     modulée par un jet de course sur la table de Course animale.</p> | ||||||
|   | |||||||
| @@ -184,16 +184,16 @@ system: | |||||||
|       value: '+0' |       value: '+0' | ||||||
|       label: +dom |       label: +dom | ||||||
|       derivee: true |       derivee: true | ||||||
|     vitesse: |  | ||||||
|       type: string |  | ||||||
|       value: 12/28 |  | ||||||
|       label: Vitesse |  | ||||||
|       derivee: true |  | ||||||
|     encombrement: |     encombrement: | ||||||
|       type: number |       type: number | ||||||
|       value: 0 |       value: 0 | ||||||
|       label: Encombrement |       label: Encombrement | ||||||
|       derivee: false |       derivee: false | ||||||
|  |     vitesse: | ||||||
|  |       type: string | ||||||
|  |       value: 12/28 | ||||||
|  |       label: Vitesse | ||||||
|  |       derivee: true | ||||||
|     protection: |     protection: | ||||||
|       type: number |       type: number | ||||||
|       value: 4 |       value: 4 | ||||||
| @@ -207,28 +207,19 @@ system: | |||||||
|       value: 0 |       value: 0 | ||||||
|       label: Sur-encombrement |       label: Sur-encombrement | ||||||
|   description: >- |   description: >- | ||||||
|     <h1>Description</h1> |     <h1>Description</h1><p>Description Le chrasme (prononcer krasme) est une | ||||||
|  |     sorte de cafard géant à carapace de crabe aux jointures poilues. Il mesure | ||||||
|     <p>Description Le chrasme (prononcer krasme) est une sorte de cafard |     en moyenne 1 m de haut sur 1m50 de long, et peut peser jusqu’à 50 kg. Doté | ||||||
|     géant à carapace de crabe aux jointures poilues. Il mesure en |     de mandibules acérées et puissantes, il est redouté pour son venin | ||||||
|     moyenne 1 m de haut sur 1m50 de long, et peut peser jusqu’à 50 |     mortel.</p><h1>Mœurs</h1><p>Le chrasme vit dans les lieux sombres, cavernes | ||||||
|     kg. Doté de mandibules acérées et puissantes, il est |     et souterrains, où il se nourrit de tout. Paranos le Moindre affirme qu’à | ||||||
|     redouté pour son venin mortel.</p> |     défaut d’une meilleure chère, il peut même se sustenter de cailloux. Il | ||||||
|  |     déteste la lumière comme son cousin de petite taille, mais a toutefois un | ||||||
|     <h1>Mœurs</h1> |     comportement différent: au lieu de fuir, il entre dans une rage féroce et se | ||||||
|  |     rue sur le porteur de lumière pour le réduire en charpie. Savez-vous, cher | ||||||
|     <p>Le chrasme vit dans les lieux sombres, cavernes et souterrains, où |     Paranos, que vous nous faites un peu peur | ||||||
|     il se nourrit de tout. Paranos le Moindre affirme qu’à |     ?</p><h1>Venin</h1><p>@UUID[Compendium.foundryvtt-reve-de-dragon.maladies-et-poisons.Item.cFMUtU6LZG0mKeDl]{Venin | ||||||
|     défaut d’une meilleure chère, il peut même se |     de chrasme}</p><p></p> | ||||||
|     sustenter de cailloux. Il déteste la lumière comme son cousin |  | ||||||
|     de petite taille, mais a toutefois un comportement différent: au lieu |  | ||||||
|     de fuir, il entre dans une rage féroce et se rue sur le porteur de |  | ||||||
|     lumière pour le réduire en charpie. Savez-vous, cher Paranos, |  | ||||||
|     que vous nous faites un peu peur ?</p> |  | ||||||
|  |  | ||||||
|     <h1>Venin</h1> |  | ||||||
|     <p>@UUID[Compendium.foundryvtt-reve-de-dragon.maladies-et-poisons.Item.cFMUtU6LZG0mKeDl]{Venin |  | ||||||
|     de chrasme}</p> <p></p> |  | ||||||
|   race: '' |   race: '' | ||||||
|   notesmj: '' |   notesmj: '' | ||||||
| ownership: | ownership: | ||||||
| @@ -311,7 +302,13 @@ prototypeToken: | |||||||
|       texture: null |       texture: null | ||||||
| _stats: | _stats: | ||||||
|   systemId: foundryvtt-reve-de-dragon |   systemId: foundryvtt-reve-de-dragon | ||||||
|   systemVersion: 12.0.22 |   systemVersion: 12.0.32 | ||||||
|   coreVersion: '12.331' |   coreVersion: '12.331' | ||||||
|  |   createdTime: null | ||||||
|  |   modifiedTime: 1736537299708 | ||||||
|  |   lastModifiedBy: Hp9ImM4o9YRTSdfu | ||||||
|  |   compendiumSource: null | ||||||
|  |   duplicateSource: null | ||||||
|  | flags: {} | ||||||
| _key: '!actors!yL1XStIKWxGnhKvR' | _key: '!actors!yL1XStIKWxGnhKvR' | ||||||
|  |  | ||||||
|   | |||||||
| @@ -203,10 +203,10 @@ system: | |||||||
|  |  | ||||||
|     <p>En combat, quand un drakkule réussit une particulière et |     <p>En combat, quand un drakkule réussit une particulière et | ||||||
|     cause au moins une blessure légère, il reste accroché |     cause au moins une blessure légère, il reste accroché | ||||||
|     à sa victime qui perd alors automatiquement 1d6 points |     à sa victime qui perd alors automatiquement @roll[1d6] points | ||||||
|     d’endurance par round sous l’effet de la saignée. Quand |     d’endurance par round sous l’effet de la saignée. Quand | ||||||
|     l’endurance tombe à zéro, le drakkule continue à |     l’endurance tombe à zéro, le drakkule continue à | ||||||
|     la vider de son sang à raison de 1d6 points de vie par round. Le |     la vider de son sang à raison de @roll[1d6] points de vie par round. Le | ||||||
|     drakkule ne se détache que <em>blessé gravement </em>ou |     drakkule ne se détache que <em>blessé gravement </em>ou | ||||||
|     <em>sonné</em>. Pour se dégager, la victime ne peut utiliser |     <em>sonné</em>. Pour se dégager, la victime ne peut utiliser | ||||||
|     que Corps à corps (totaliser 2 points d’empoignade) ou une |     que Corps à corps (totaliser 2 points d’empoignade) ou une | ||||||
|   | |||||||
| @@ -137,7 +137,7 @@ system: | |||||||
|     elles-mêmes, leur grincement involontaire est une torture. Toute |     elles-mêmes, leur grincement involontaire est une torture. Toute | ||||||
|     personne se trouvant dans un rayon de 10m doit manquer un jet |     personne se trouvant dans un rayon de 10m doit manquer un jet | ||||||
|     d’OUÏE à +5. Si le jet réussit, perte de 1 point |     d’OUÏE à +5. Si le jet réussit, perte de 1 point | ||||||
|     d’endurance, puis jet de VOLONTÉ à -5. Si le jet de |     d’endurance, puis jet de @roll[volonté/-5]. Si le jet de | ||||||
|     VOLONTÉ échoue, le personnage est sonné |     VOLONTÉ échoue, le personnage est sonné | ||||||
|     jusqu’à la fin du round suivant.</p> |     jusqu’à la fin du round suivant.</p> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -174,8 +174,8 @@ system: | |||||||
|     agressivité s’appliquant aux humanoïdes. S’agissant |     agressivité s’appliquant aux humanoïdes. S’agissant | ||||||
|     d’un pouvoir inné, elles n’ont ni à monter dans |     d’un pouvoir inné, elles n’ont ni à monter dans | ||||||
|     les TMR, ni à dépenser de points de rêve. La victime |     les TMR, ni à dépenser de points de rêve. La victime | ||||||
|     doit jouer un jet de résistance standard, r-8, et en cas |     doit jouer un jet de résistance standard, @roll[reve-actuel/-8], et en cas | ||||||
|     d’échec, réussir un jet de VOLONTÉ à -3 |     d’échec, réussir un jet de @roll[Volonté/-3] | ||||||
|     pour pouvoir attaquer la harpie. Le JR n’est à jouer |     pour pouvoir attaquer la harpie. Le JR n’est à jouer | ||||||
|     qu’une seule fois, tandis qu’en cas d’échec, le jet |     qu’une seule fois, tandis qu’en cas d’échec, le jet | ||||||
|     de VOLONTÉ est à jouer tous les rounds. La non |     de VOLONTÉ est à jouer tous les rounds. La non | ||||||
|   | |||||||
| @@ -201,7 +201,7 @@ system: | |||||||
|  |  | ||||||
|     <p>La sirène a un chant attractif pouvant porter jusqu’à |     <p>La sirène a un chant attractif pouvant porter jusqu’à | ||||||
|     50 m. Toute personne, homme ou femme, percevant ce chant, même faible |     50 m. Toute personne, homme ou femme, percevant ce chant, même faible | ||||||
|     et lointain, doit tenter un jet de VOLONTÉ à -3. Sur toute |     et lointain, doit tenter un jet de  @roll[Volonté/-3]. Sur toute | ||||||
|     réussite, le personnage est libre de sa décision"; sur tout |     réussite, le personnage est libre de sa décision"; sur tout | ||||||
|     échec, il est irrésistiblement attiré vers la source du |     échec, il est irrésistiblement attiré vers la source du | ||||||
|     chant. Quand plusieurs sirènes chantent simultanément, le jet |     chant. Quand plusieurs sirènes chantent simultanément, le jet | ||||||
| @@ -220,7 +220,7 @@ system: | |||||||
|     corps, même visage. Certaines sirènes, plus rarement, donnent |     corps, même visage. Certaines sirènes, plus rarement, donnent | ||||||
|     des illusions d’hommes. Contrairement aux illusions des Yeux |     des illusions d’hommes. Contrairement aux illusions des Yeux | ||||||
|     d’Hypnos, l’illusion des sirènes donne lieu à un |     d’Hypnos, l’illusion des sirènes donne lieu à un | ||||||
|     jet de résistance (standard, r-8). Comme pour les chants, ce JR est |     jet de résistance (standard, @roll[reve-actuel/-8]). Comme pour les chants, ce JR est | ||||||
|     global : s’il réussit, toutes les sirènes apparaissent |     global : s’il réussit, toutes les sirènes apparaissent | ||||||
|     sous leur véritable apparence; s’il échoue, toutes sont |     sous leur véritable apparence; s’il échoue, toutes sont | ||||||
|     perçues sous leur apparence illusoire.</p> |     perçues sous leur apparence illusoire.</p> | ||||||
|   | |||||||
| @@ -228,8 +228,8 @@ system: | |||||||
|     désolations et autres lieux où Thanatos a laissé son |     désolations et autres lieux où Thanatos a laissé son | ||||||
|     empreinte. Ils possèdent le même pouvoir de non |     empreinte. Ils possèdent le même pouvoir de non | ||||||
|     agressivité s’appliquant aux humanoïdes que la harpie. La |     agressivité s’appliquant aux humanoïdes que la harpie. La | ||||||
|     victime doit jouer un jet de résistance standard, r-8, et en cas |     victime doit jouer un jet de résistance standard, @roll[reve-actuel/-8], et en cas | ||||||
|     d’échec, réussir un jet de VOLONTÉ à -3 |     d’échec, réussir un jet de @roll[Volonté/-3] | ||||||
|     pour pouvoir attaquer le tournedent. Le JR n’est à jouer |     pour pouvoir attaquer le tournedent. Le JR n’est à jouer | ||||||
|     qu’une seule fois, et en cas d’échec, le jet de |     qu’une seule fois, et en cas d’échec, le jet de | ||||||
|     VOLONTÉ est à jouer tous les rounds. La non agressivité |     VOLONTÉ est à jouer tous les rounds. La non agressivité | ||||||
|   | |||||||
| @@ -3897,7 +3897,7 @@ items: | |||||||
|           indexDate: -1 |           indexDate: -1 | ||||||
|           indexMinute: 0 |           indexMinute: 0 | ||||||
|       rarete: '' |       rarete: '' | ||||||
|       categorie: Remede |       categorie: Alchimie | ||||||
|       herbe: '' |       herbe: '' | ||||||
|       herbebrins: 0 |       herbebrins: 0 | ||||||
|       herbebonus: 0 |       herbebonus: 0 | ||||||
| @@ -5349,7 +5349,7 @@ items: | |||||||
|           indexDate: -1 |           indexDate: -1 | ||||||
|           indexMinute: 0 |           indexMinute: 0 | ||||||
|       rarete: '' |       rarete: '' | ||||||
|       categorie: Remede |       categorie: Alchimie | ||||||
|       herbe: '' |       herbe: '' | ||||||
|       herbebrins: 0 |       herbebrins: 0 | ||||||
|       herbebonus: 0 |       herbebonus: 0 | ||||||
| @@ -5605,7 +5605,7 @@ items: | |||||||
|           indexDate: -1 |           indexDate: -1 | ||||||
|           indexMinute: 0 |           indexMinute: 0 | ||||||
|       rarete: '' |       rarete: '' | ||||||
|       categorie: Remede |       categorie: Alchimie | ||||||
|       herbe: '' |       herbe: '' | ||||||
|       herbebrins: 0 |       herbebrins: 0 | ||||||
|       herbebonus: 0 |       herbebonus: 0 | ||||||
| @@ -5765,7 +5765,7 @@ items: | |||||||
|           indexDate: -1 |           indexDate: -1 | ||||||
|           indexMinute: 0 |           indexMinute: 0 | ||||||
|       rarete: '' |       rarete: '' | ||||||
|       categorie: Remede |       categorie: Alchimie | ||||||
|       herbe: '' |       herbe: '' | ||||||
|       herbebrins: 0 |       herbebrins: 0 | ||||||
|       herbebonus: 0 |       herbebonus: 0 | ||||||
| @@ -6437,7 +6437,7 @@ items: | |||||||
|           indexDate: -1 |           indexDate: -1 | ||||||
|           indexMinute: 0 |           indexMinute: 0 | ||||||
|       rarete: '' |       rarete: '' | ||||||
|       categorie: Remede |       categorie: Alchimie | ||||||
|       herbe: '' |       herbe: '' | ||||||
|       herbebrins: 0 |       herbebrins: 0 | ||||||
|       herbebonus: 0 |       herbebonus: 0 | ||||||
| @@ -7610,7 +7610,7 @@ items: | |||||||
|           indexDate: -1 |           indexDate: -1 | ||||||
|           indexMinute: 0 |           indexMinute: 0 | ||||||
|       rarete: '' |       rarete: '' | ||||||
|       categorie: Remede |       categorie: Alchimie | ||||||
|       herbe: '' |       herbe: '' | ||||||
|       herbebrins: 0 |       herbebrins: 0 | ||||||
|       herbebonus: 0 |       herbebonus: 0 | ||||||
| @@ -8010,7 +8010,7 @@ items: | |||||||
|         poussant dans les lieux frais et humides : marais ombragés, |         poussant dans les lieux frais et humides : marais ombragés, | ||||||
|         certaines forêts, et parfois vallées de montagne. Un peu |         certaines forêts, et parfois vallées de montagne. Un peu | ||||||
|         moins rare est la fausse endebrume, qui lui ressemble physiquement, mais |         moins rare est la fausse endebrume, qui lui ressemble physiquement, mais | ||||||
|         n'a aucune vertu. <br /><em>VUE/Botanique à -1 pour savoir |         n'a aucune vertu. <br /><em>@roll[VUE/Botanique/-1] pour savoir | ||||||
|         à quelle espèce on a affaire (jet obligatoire à |         à quelle espèce on a affaire (jet obligatoire à | ||||||
|         chaque cueillette).</em></p> |         chaque cueillette).</em></p> | ||||||
|  |  | ||||||
| @@ -8782,7 +8782,7 @@ items: | |||||||
|     system: |     system: | ||||||
|       description: |- |       description: |- | ||||||
|         <p>Poudre brune apparaissant sur les parois des grottes.</p> |         <p>Poudre brune apparaissant sur les parois des grottes.</p> | ||||||
|         <p>VUE/Alchimie à -1.</p> |         <p>@roll[VUE/Alchimie/-1].</p> | ||||||
|       descriptionmj: '' |       descriptionmj: '' | ||||||
|       encombrement: 0.001 |       encombrement: 0.001 | ||||||
|       quantite: 1 |       quantite: 1 | ||||||
| @@ -8818,7 +8818,7 @@ items: | |||||||
|         <p>Poudre blanche apparaissant sous l’écorce de nombreux |         <p>Poudre blanche apparaissant sous l’écorce de nombreux | ||||||
|         arbres,</p> |         arbres,</p> | ||||||
|  |  | ||||||
|         <p>VUE/Alchimie à 0.</p> |         <p>@roll[VUE/Alchimie/0].</p> | ||||||
|       descriptionmj: '' |       descriptionmj: '' | ||||||
|       encombrement: 0.001 |       encombrement: 0.001 | ||||||
|       quantite: 1 |       quantite: 1 | ||||||
| @@ -8854,7 +8854,7 @@ items: | |||||||
|         <p>Poudre rouge obtenue par disruption alchimique de la |         <p>Poudre rouge obtenue par disruption alchimique de la | ||||||
|         <em>chramaele</em>, minerai ayant l’apparence de la glaise.</p> |         <em>chramaele</em>, minerai ayant l’apparence de la glaise.</p> | ||||||
|  |  | ||||||
|         <p>VUE/Alchimie à -4</p> |         <p>@roll[VUE/Alchimie/-4]</p> | ||||||
|       descriptionmj: '' |       descriptionmj: '' | ||||||
|       encombrement: 0.001 |       encombrement: 0.001 | ||||||
|       quantite: 1 |       quantite: 1 | ||||||
| @@ -8899,7 +8899,7 @@ items: | |||||||
|         <p>Poudre noire obtenue par disruption alchimique du minerai |         <p>Poudre noire obtenue par disruption alchimique du minerai | ||||||
|         appelé <em>narthalide</em>, sorte de marne.</p> |         appelé <em>narthalide</em>, sorte de marne.</p> | ||||||
|  |  | ||||||
|         <p>VUE/Alchimie à -3</p> |         <p>@roll[VUE/Alchimie/-3]</p> | ||||||
|       descriptionmj: '' |       descriptionmj: '' | ||||||
|       encombrement: 0.001 |       encombrement: 0.001 | ||||||
|       quantite: 1 |       quantite: 1 | ||||||
| @@ -8941,7 +8941,7 @@ items: | |||||||
|         <p>Poudre bleuâtre obtenue par disruption alchimique du minerai |         <p>Poudre bleuâtre obtenue par disruption alchimique du minerai | ||||||
|         appelé <em>obbadine</em>,  sorte de tourbe.</p> |         appelé <em>obbadine</em>,  sorte de tourbe.</p> | ||||||
|  |  | ||||||
|         <p>VUE/Alchimie à -2</p> |         <p>@roll[VUE/Alchimie/-2]</p> | ||||||
|       descriptionmj: '' |       descriptionmj: '' | ||||||
|       encombrement: 0.001 |       encombrement: 0.001 | ||||||
|       quantite: 1 |       quantite: 1 | ||||||
| @@ -8983,7 +8983,7 @@ items: | |||||||
|         <p>Plus rare que le vert, poudre grisâtre apparaissant le long de |         <p>Plus rare que le vert, poudre grisâtre apparaissant le long de | ||||||
|         certaines lianes des marais.</p> |         certaines lianes des marais.</p> | ||||||
|  |  | ||||||
|         <p>VUE/Alchimie à -4</p> |         <p>@roll[VUE/Alchimie/-4]</p> | ||||||
|       descriptionmj: '' |       descriptionmj: '' | ||||||
|       encombrement: 0.001 |       encombrement: 0.001 | ||||||
|       quantite: 1 |       quantite: 1 | ||||||
| @@ -9019,7 +9019,7 @@ items: | |||||||
|         <p>Poudre verdâtre apparaissant sur les tiges de certains |         <p>Poudre verdâtre apparaissant sur les tiges de certains | ||||||
|         roseaux.</p> |         roseaux.</p> | ||||||
|  |  | ||||||
|         <p>VUE/Alchimie à -2</p> |         <p>@roll[VUE/Alchimie/-2]</p> | ||||||
|       descriptionmj: '' |       descriptionmj: '' | ||||||
|       encombrement: 0.001 |       encombrement: 0.001 | ||||||
|       quantite: 1 |       quantite: 1 | ||||||
|   | |||||||
| @@ -17,9 +17,8 @@ system: | |||||||
|     à long terme, mais tout autant de l’empathie pour bluffer lors |     à long terme, mais tout autant de l’empathie pour bluffer lors | ||||||
|     des surenchères.</p> |     des surenchères.</p> | ||||||
|  |  | ||||||
|     <p>Pour simuler une partie, jouer un jet de CHANCE à zéro |     <p>Pour simuler une partie, jouer un jet de @roll[chance/0] | ||||||
|     (ajusté astrologiquement), suivi d’un jet d’EMPATHIE/Jeu |     (ajusté astrologiquement), suivi d’un jet d’@roll[EMPATHIE/Jeu/0], et additionner les points de tâche obtenus par | ||||||
|     à zéro, et additionner les points de tâche obtenus par |  | ||||||
|     les deux jets. Le vainqueur est celui qui en totalise le plus.</p> |     les deux jets. Le vainqueur est celui qui en totalise le plus.</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   type: carte |   type: carte | ||||||
|   | |||||||
| @@ -104,7 +104,7 @@ system: | |||||||
|     Dès qu’il se sent lésé, offensé, victime |     Dès qu’il se sent lésé, offensé, victime | ||||||
|     d’un tort même insignifiant, il faut qu’il se venge |     d’un tort même insignifiant, il faut qu’il se venge | ||||||
|     et que sa vengeance soit mortelle. Il peut jouer un jet de |     et que sa vengeance soit mortelle. Il peut jouer un jet de | ||||||
|     VOLONTÉ/ moral à zéro. Si le jet réussit, il |     @roll[Volonté/0] (avec moral). Si le jet réussit, il | ||||||
|     peut encore laisser couver sa haine ; s’il échoue, il doit agir |     peut encore laisser couver sa haine ; s’il échoue, il doit agir | ||||||
|     immédiatement. Il est conseillé que le gardien des rêves |     immédiatement. Il est conseillé que le gardien des rêves | ||||||
|     prenne alors le contrôle du personnage s’il s’agit |     prenne alors le contrôle du personnage s’il s’agit | ||||||
|   | |||||||
| @@ -104,7 +104,7 @@ system: | |||||||
|     pareille. Son moral tombe directement à -3 et ne pourra pas remonter |     pareille. Son moral tombe directement à -3 et ne pourra pas remonter | ||||||
|     tant que durera la possession. Chaque fois qu’une action dangereuse se |     tant que durera la possession. Chaque fois qu’une action dangereuse se | ||||||
|     présente, incluant toute action de combat y compris l’esquive, |     présente, incluant toute action de combat y compris l’esquive, | ||||||
|     la victime doit jouer un jet de VOLONTÉ/moral à zéro. |     la victime doit jouer un jet de @roll[Volonté/0] avec moral. | ||||||
|     Si ce jet échoue, la victime ne fait rien que trembler et claquer des |     Si ce jet échoue, la victime ne fait rien que trembler et claquer des | ||||||
|     dents.</p> |     dents.</p> | ||||||
|   race: '' |   race: '' | ||||||
|   | |||||||
| @@ -132,8 +132,8 @@ system: | |||||||
|     les désolations et les ruines. Il combat avec son bec |     les désolations et les ruines. Il combat avec son bec | ||||||
|     acéré. Outre les dommages qu’il cause (+dom +1), chaque |     acéré. Outre les dommages qu’il cause (+dom +1), chaque | ||||||
|     fois qu’il porte un coup, même une simple |     fois qu’il porte un coup, même une simple | ||||||
|     contusion-éraflure, sa victime doit réussir un jet de points |     contusion-éraflure, sa victime doit réussir un jet de @roll[reve-actuel] | ||||||
|     de rêve actuels ajusté négativement au niveau de |     ajusté négativement au niveau de | ||||||
|     l’entité, ou perdre 1 point de chance. Les points de chance |     l’entité, ou perdre 1 point de chance. Les points de chance | ||||||
|     ainsi perdus peuvent être regagnés selon la règle |     ainsi perdus peuvent être regagnés selon la règle | ||||||
|     normale. Détruite, l’entité ne laisse pour tout vestige |     normale. Détruite, l’entité ne laisse pour tout vestige | ||||||
|   | |||||||
| @@ -158,8 +158,8 @@ system: | |||||||
|     <p>Les quauquemaires hantent les endroits lugubres et désolés, |     <p>Les quauquemaires hantent les endroits lugubres et désolés, | ||||||
|     les ruines principalement. Ils chantent au coucher du soleil, et leur chant |     les ruines principalement. Ils chantent au coucher du soleil, et leur chant | ||||||
|     est si lugubre, prometteur d’angoisse et de cauchemar, que quiconque |     est si lugubre, prometteur d’angoisse et de cauchemar, que quiconque | ||||||
|     l’entend et manque un jet de points de rêve actuels |     l’entend et manque un jet de points de @roll[reve-actuel] ajusté | ||||||
|     ajusté négativement au niveau de l’entité, ne |     négativement au niveau de l’entité, ne | ||||||
|     fait que des cauchemars hideux au cours de sa prochaine nuit de sommeil. En |     fait que des cauchemars hideux au cours de sa prochaine nuit de sommeil. En | ||||||
|     termes de règles, cela signifie : pas de souvenir de |     termes de règles, cela signifie : pas de souvenir de | ||||||
|     l’archétype et donc pas de jet de stress au matin ; pas de |     l’archétype et donc pas de jet de stress au matin ; pas de | ||||||
|   | |||||||
| @@ -134,8 +134,8 @@ system: | |||||||
|     nécropoles, catacombes et autres lieux de sépulture. Comme les |     nécropoles, catacombes et autres lieux de sépulture. Comme les | ||||||
|     autres entités, leur raison d’être est de |     autres entités, leur raison d’être est de | ||||||
|     détruire. Le spectacle d’un squelette est d’une horreur |     détruire. Le spectacle d’un squelette est d’une horreur | ||||||
|     tellement contre nature qu’il demande un jet de VOLONTÉ |     tellement contre nature qu’il demande un jet de @roll[Volonté/-3]. | ||||||
|     à -3. En cas d’échec, le personnage est frappé |     En cas d’échec, le personnage est frappé | ||||||
|     d’effroi. En termes de règles, il est en demi- surprise |     d’effroi. En termes de règles, il est en demi- surprise | ||||||
|     jusqu’à la fin du round suivant. Une fois détruit, les |     jusqu’à la fin du round suivant. Une fois détruit, les | ||||||
|     ossements constitutifs du squelette s’éparpillent sur le sol, |     ossements constitutifs du squelette s’éparpillent sur le sol, | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ system: | |||||||
|       indexDate: -1 |       indexDate: -1 | ||||||
|       indexMinute: 0 |       indexMinute: 0 | ||||||
|   rarete: '' |   rarete: '' | ||||||
|   categorie: Remede |   categorie: Alchimie | ||||||
|   herbe: '' |   herbe: '' | ||||||
|   herbebrins: 0 |   herbebrins: 0 | ||||||
|   herbebonus: 0 |   herbebonus: 0 | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ system: | |||||||
|       indexDate: -1 |       indexDate: -1 | ||||||
|       indexMinute: 0 |       indexMinute: 0 | ||||||
|   rarete: '' |   rarete: '' | ||||||
|   categorie: Remede |   categorie: Alchimie | ||||||
|   herbe: '' |   herbe: '' | ||||||
|   herbebrins: 0 |   herbebrins: 0 | ||||||
|   herbebonus: 0 |   herbebonus: 0 | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ system: | |||||||
|       indexDate: -1 |       indexDate: -1 | ||||||
|       indexMinute: 0 |       indexMinute: 0 | ||||||
|   rarete: '' |   rarete: '' | ||||||
|   categorie: Remede |   categorie: Alchimie | ||||||
|   herbe: '' |   herbe: '' | ||||||
|   herbebrins: 0 |   herbebrins: 0 | ||||||
|   herbebonus: 0 |   herbebonus: 0 | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ system: | |||||||
|       indexDate: -1 |       indexDate: -1 | ||||||
|       indexMinute: 0 |       indexMinute: 0 | ||||||
|   rarete: '' |   rarete: '' | ||||||
|   categorie: Remede |   categorie: Alchimie | ||||||
|   herbe: '' |   herbe: '' | ||||||
|   herbebrins: 0 |   herbebrins: 0 | ||||||
|   herbebonus: 0 |   herbebonus: 0 | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ system: | |||||||
|       indexDate: -1 |       indexDate: -1 | ||||||
|       indexMinute: 0 |       indexMinute: 0 | ||||||
|   rarete: '' |   rarete: '' | ||||||
|   categorie: Remede |   categorie: Alchimie | ||||||
|   herbe: '' |   herbe: '' | ||||||
|   herbebrins: 0 |   herbebrins: 0 | ||||||
|   herbebonus: 0 |   herbebonus: 0 | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ system: | |||||||
|       indexDate: -1 |       indexDate: -1 | ||||||
|       indexMinute: 0 |       indexMinute: 0 | ||||||
|   rarete: '' |   rarete: '' | ||||||
|   categorie: Remede |   categorie: Alchimie | ||||||
|   herbe: '' |   herbe: '' | ||||||
|   herbebrins: 0 |   herbebrins: 0 | ||||||
|   herbebonus: 0 |   herbebonus: 0 | ||||||
|   | |||||||
| @@ -19,8 +19,8 @@ system: | |||||||
|     dans une pipe ou préparée en décoction. Dans les deux |     dans une pipe ou préparée en décoction. Dans les deux | ||||||
|     cas, une dose doit être composée de 7 brins. Dès la dose |     cas, une dose doit être composée de 7 brins. Dès la dose | ||||||
|     absorbée (bue ou fumée), le consommateur doit jouer un JR |     absorbée (bue ou fumée), le consommateur doit jouer un JR | ||||||
|     r-force, c’est-à-dire un jet de points de rêve |     r-force, c’est-à-dire un jet de @roll[reve-actuel] ajusté | ||||||
|     ajusté négativement à la force de l’herbe. Si le |      négativement à la force de l’herbe. Si le | ||||||
|     JR réussit, aucun effet ne se produit"; s’il échoue, le |     JR réussit, aucun effet ne se produit"; s’il échoue, le | ||||||
|     consommateur gagne immédiatement un nombre de points de rêve |     consommateur gagne immédiatement un nombre de points de rêve | ||||||
|     égal à la force de l’herbe, puis en échange, |     égal à la force de l’herbe, puis en échange, | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ effects: [] | |||||||
| system: | system: | ||||||
|   description: |- |   description: |- | ||||||
|     <p>Poudre brune apparaissant sur les parois des grottes.</p> |     <p>Poudre brune apparaissant sur les parois des grottes.</p> | ||||||
|     <p>VUE/Alchimie à -1.</p> |     <p>@roll[VUE/Alchimie/-1].</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   encombrement: 0.001 |   encombrement: 0.001 | ||||||
|   quantite: 1 |   quantite: 1 | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ system: | |||||||
|     <p>Poudre blanche apparaissant sous l’écorce de nombreux |     <p>Poudre blanche apparaissant sous l’écorce de nombreux | ||||||
|     arbres,</p> |     arbres,</p> | ||||||
|  |  | ||||||
|     <p>VUE/Alchimie à 0.</p> |     <p>@roll[VUE/Alchimie/0].</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   encombrement: 0.001 |   encombrement: 0.001 | ||||||
|   quantite: 1 |   quantite: 1 | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ system: | |||||||
|     <p>Poudre rouge obtenue par disruption alchimique de la <em>chramaele</em>, |     <p>Poudre rouge obtenue par disruption alchimique de la <em>chramaele</em>, | ||||||
|     minerai ayant l’apparence de la glaise.</p> |     minerai ayant l’apparence de la glaise.</p> | ||||||
|  |  | ||||||
|     <p>VUE/Alchimie à -4</p> |     <p>@roll[VUE/Alchimie/-4]</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   encombrement: 0.001 |   encombrement: 0.001 | ||||||
|   quantite: 1 |   quantite: 1 | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ system: | |||||||
|     <p>Poudre noire obtenue par disruption alchimique du minerai appelé |     <p>Poudre noire obtenue par disruption alchimique du minerai appelé | ||||||
|     <em>narthalide</em>, sorte de marne.</p> |     <em>narthalide</em>, sorte de marne.</p> | ||||||
|  |  | ||||||
|     <p>VUE/Alchimie à -3</p> |     <p>@roll[VUE/Alchimie/-3]</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   encombrement: 0.001 |   encombrement: 0.001 | ||||||
|   quantite: 1 |   quantite: 1 | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ system: | |||||||
|     <p>Poudre bleuâtre obtenue par disruption alchimique du minerai |     <p>Poudre bleuâtre obtenue par disruption alchimique du minerai | ||||||
|     appelé <em>obbadine</em>,  sorte de tourbe.</p> |     appelé <em>obbadine</em>,  sorte de tourbe.</p> | ||||||
|  |  | ||||||
|     <p>VUE/Alchimie à -2</p> |     <p>@roll[VUE/Alchimie/-2]</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   encombrement: 0.001 |   encombrement: 0.001 | ||||||
|   quantite: 1 |   quantite: 1 | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ system: | |||||||
|     <p>Plus rare que le vert, poudre grisâtre apparaissant le long de |     <p>Plus rare que le vert, poudre grisâtre apparaissant le long de | ||||||
|     certaines lianes des marais.</p> |     certaines lianes des marais.</p> | ||||||
|  |  | ||||||
|     <p>VUE/Alchimie à -4</p> |     <p>@roll[VUE/Alchimie/-4]</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   encombrement: 0.001 |   encombrement: 0.001 | ||||||
|   quantite: 1 |   quantite: 1 | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ effects: [] | |||||||
| system: | system: | ||||||
|   description: |- |   description: |- | ||||||
|     <p>Poudre verdâtre apparaissant sur les tiges de certains roseaux.</p> |     <p>Poudre verdâtre apparaissant sur les tiges de certains roseaux.</p> | ||||||
|     <p>VUE/Alchimie à -2</p> |     <p>@roll[VUE/Alchimie/-2]</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   encombrement: 0.001 |   encombrement: 0.001 | ||||||
|   quantite: 1 |   quantite: 1 | ||||||
|   | |||||||
| @@ -506,8 +506,8 @@ system: | |||||||
|     <p style="box-sizing: border-box; user-select: text; color: #191813; |     <p style="box-sizing: border-box; user-select: text; color: #191813; | ||||||
|     font-family: CaslonAntique; font-size: 16px; letter-spacing: 1px; |     font-family: CaslonAntique; font-size: 16px; letter-spacing: 1px; | ||||||
|     text-align: justify; background-color: #f5f5f0;"><strong style="box-sizing: |     text-align: justify; background-color: #f5f5f0;"><strong style="box-sizing: | ||||||
|     border-box; user-select: text;">VOLONTÉ/moral à - |     border-box; user-select: text;">@roll[Volonté/Cuisibe] (avec moral) à - | ||||||
|     (degré d’exotisme) + (Cuisine)</strong></p> |     (degré d’exotisme) </strong></p> | ||||||
|  |  | ||||||
|     <p style="box-sizing: border-box; user-select: text; color: #191813; |     <p style="box-sizing: border-box; user-select: text; color: #191813; | ||||||
|     font-family: CaslonAntique; font-size: 16px; letter-spacing: 1px; |     font-family: CaslonAntique; font-size: 16px; letter-spacing: 1px; | ||||||
|   | |||||||
| @@ -23,31 +23,29 @@ system: | |||||||
|  |  | ||||||
|     <p>Les points de VUE perdus ne peuvent être regagnés que quand |     <p>Les points de VUE perdus ne peuvent être regagnés que quand | ||||||
|     la maladie est entièrement guérie. À chaque point de |     la maladie est entièrement guérie. À chaque point de | ||||||
|     vie regagné, jouer un jet de CONSTITUTION ajusté |     vie regagné, jouer un jet de @roll[Constitution] ajusté | ||||||
|     négativement par les points de vie toujours manquants. Puis selon le |     négativement par les points de vie toujours manquants. Puis selon le | ||||||
|     résultat:</p> |     résultat:</p> | ||||||
|  |  | ||||||
|     <ul> |     <ul> | ||||||
|  |  | ||||||
|     <li><strong><em>Particulière            |     <li><strong><em>Particulière</em></strong>  Regain de 2 points | ||||||
|                       |     de VUE</li> | ||||||
|     </em></strong>Regain de 2 points de VUE</li> |  | ||||||
|  |  | ||||||
|     <li><strong><em>Normale et significative</em></strong>      |     <li><strong><em>Normale et significative</em></strong>  Regain de 1 | ||||||
|     Regain de 1 point de VUE</li> |     point de VUE</li> | ||||||
|  |  | ||||||
|     <li><strong><em>Échec et Échec particulier</em></strong>  |     <li><strong><em>Échec et Échec particulier</em></strong>   | ||||||
|     Aucun regain</li> |     Aucun regain</li> | ||||||
|  |  | ||||||
|     <li><strong><em>Échec total</em>          |     <li><strong><em>Échec total</em></strong>  Aggravation, | ||||||
|                           |     re-perte d’un point de VUE</li> | ||||||
|     </strong>Aggravation, re-perte d’un point de VUE</li> |  | ||||||
|  |  | ||||||
|     </ul> |     </ul> | ||||||
|  |  | ||||||
|     <p>Si tous les points de vie ont été regagnés et |     <p>Si tous les points de vie ont été regagnés et | ||||||
|     qu’il manque toujours un ou plusieurs points de VUE, jouer un jet de |     qu’il manque toujours un ou plusieurs points de VUE, jouer un jet de | ||||||
|     CONSTITUTION à zéro toutes les 12 heures, et appliquer les |     @roll[Constitution/0] toutes les 12 heures, et appliquer les | ||||||
|     mêmes résultats que ci-dessus.</p> |     mêmes résultats que ci-dessus.</p> | ||||||
|  |  | ||||||
|     <p>Une potion d’herbes de soin enchantée peut faire regagner |     <p>Une potion d’herbes de soin enchantée peut faire regagner | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ type: ombre | |||||||
| img: systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp | img: systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp | ||||||
| effects: [] | effects: [] | ||||||
| system: | system: | ||||||
|   description: <p>Prise immédiate de 3d6 points de fatigue.</p> |   description: <p>Prise immédiate de @roll[3d6] points de fatigue.</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   temporel: |   temporel: | ||||||
|     debut: |     debut: | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| _id: OjG8XRbeYtq2jcgB | _id: OjG8XRbeYtq2jcgB | ||||||
| name: Casser 3d6 oeufs en les jetant à terre | name: Casser @roll[3d6] oeufs en les jetant à terre | ||||||
| type: queue | type: queue | ||||||
| img: systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp | img: systems/foundryvtt-reve-de-dragon/icons/queues/desir_lancinant.webp | ||||||
| effects: [] | effects: [] | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ type: queue | |||||||
| img: systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp | img: systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp | ||||||
| effects: [] | effects: [] | ||||||
| system: | system: | ||||||
|   description: <p>Prise immédiate de 3d6 points de fatigue.</p> |   description: <p>Prise immédiate de @roll[3d6] points de fatigue.</p> | ||||||
|   descriptionmj: '' |   descriptionmj: '' | ||||||
|   temporel: |   temporel: | ||||||
|     debut: |     debut: | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| _id: F8G3rdU1nfJzYwYR | _id: F8G3rdU1nfJzYwYR | ||||||
| name: Garder sur soi 3d6 kilos de cailloux | name: Garder sur soi @roll[3d6] kilos de cailloux | ||||||
| type: queue | type: queue | ||||||
| img: systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp | img: systems/foundryvtt-reve-de-dragon/icons/queues/idee_fixe.webp | ||||||
| effects: [] | effects: [] | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user