forked from public/foundryvtt-reve-de-dragon
		
	Compare commits
	
		
			47 Commits
		
	
	
		
			5ac9c682d9
			...
			12.0.41
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 89bbe63340 | |||
| 149990e352 | |||
| 3e355784c7 | |||
| b92055d5dd | |||
| 220f8142f5 | |||
| a8bb00ad0b | |||
| 78e30b5503 | |||
| 069fef4720 | |||
| e32a7d7540 | |||
| 0773493851 | |||
| da982678b7 | |||
| c1066d70f6 | |||
| 5085ba5b54 | |||
| f37483a61d | |||
| 5357e53a5f | |||
| 764dde6296 | |||
| 681fbc3177 | |||
| 70e3e63001 | |||
| 7ed9a4a12b | |||
| acfab362a0 | |||
| 3d49a3de11 | |||
| 24518642a7 | |||
| d917f80e88 | |||
| b29027c61a | |||
| 6083dd41fa | |||
| 8969d5e0ed | |||
| 7d135a214f | |||
| 9d66a479c4 | |||
| 800b4a2f32 | |||
| 9fc21e6d97 | |||
| ce7f5381ca | |||
| 48acdaaca6 | |||
| 425c6af672 | |||
| 4281f76dfb | |||
| 8ebd6ec771 | |||
| 14391daa0b | |||
| ac29e1410e | |||
| 442ffe9b3a | |||
| d922e4fdd5 | |||
| a8dc07b4db | |||
| 40a47ee8a2 | |||
| c5633a9fc5 | |||
| 7e8da49912 | |||
| b524716ede | |||
| 72a9752820 | |||
| 8e578c6566 | |||
| a4b474970c | 
							
								
								
									
										44
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,4 +1,48 @@ | ||||
| # 12.0 | ||||
| ## 12.0.41 - La loupe d'Astrobazzarh | ||||
| - On peut de nouveau effectuer des tirages cachés | ||||
| - Le stress transformé est bien diminué lorsqu'on met le stress dans une compétence | ||||
|  | ||||
| ## 12.0.40 - Les mains d'Astrobazzarh | ||||
| - correction des attaques particulières en combat | ||||
| - correction de message sur les min/max liés aux modificateurs de races (s'applique uniquement sur la taille) | ||||
|  | ||||
| ## 12.0.39 - Les mains d'Astrobazzarh | ||||
| - les armes à 1 ou 2 mains fonctionnent dans les liens de jets de dés | ||||
| - commande `/jet` pour poster une demande de jet de dés | ||||
|  | ||||
| ## 12.0.38 - Les prévisions d'Astrobazzarh | ||||
| - Correction de modifications de personnages qui ne s'affichaient pas: | ||||
|   - changements d'endurance/vie/fatigue, transformé, ... | ||||
| - Migration des compétences "Ecriture" en "Écriture" dans les tâches, livres, oeuvres et méditations | ||||
| - Correction des jets de compétences de créatures | ||||
| - Premières préparations techniques pour le passage à Founry v13 | ||||
|   - liste des impacts d'un jet de dés (expérience, points de tâche, ...) | ||||
|   - utilisation de l'extension hbs pour tous les fichiers handlebars | ||||
|  | ||||
| ## 12.0.37 - Les enchantements d'Astrobazzarh | ||||
| - les potions ont un état, seules les potions liquides sont enchantables | ||||
| - les lancements de sorts du jour sont conservés jusqu'à chateau dormant | ||||
| - lorsqu'un joueur souhaite enchanter une potion, les sorts d'enchantements/purification/permanence doivent avoir été lancés auparavant | ||||
| - on peut enchanter des gemmes exactement comme des potions | ||||
|  | ||||
| ## 12.0.36 - L'alchimie d'Astrobazzarh | ||||
| - Nouveautés | ||||
|   - ajout d'un bouton pour enchanter les potions | ||||
|   - standardisation des boutons d'actions sur les items | ||||
|   - utilisations d'icones pour les actions de l'inventaire | ||||
| - Corrections: | ||||
|   - la commande /tmra sans paramètres fonctionne | ||||
|   - les jets d'encaissement depuis le tchat fonctionnent | ||||
|   - affichage de la vie/endurance en cas de blessures et remise à neuf | ||||
|   - les queues durant 12 heures ajoutées début Vaisseau ne durent plus 24 heures | ||||
| - Compendiums | ||||
|   - Corrections des remedes enchantables | ||||
|   - Corrections de descriptions pour proposer les jet de dés | ||||
|  | ||||
| ## 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, ... | ||||
|   | ||||
| @@ -44,13 +44,13 @@ export class ChatVente { | ||||
|     vente.nbLots = Math.max(0, vente.nbLots - quantite) | ||||
|     await chatMessage.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots) | ||||
|  | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente); | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.hbs', vente); | ||||
|     chatMessage.update({ content: html }); | ||||
|     chatMessage.render(true); | ||||
|   } | ||||
|  | ||||
|   static async displayAchatVente(vente) { | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente); | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.hbs', vente); | ||||
|     const chatMessage = await ChatMessage.create(RdDUtility.chatDataSetup(html)) | ||||
|     await chatMessage.setFlag(SYSTEM_RDD, NB_LOTS, vente.nbLots) | ||||
|     await chatMessage.setFlag(SYSTEM_RDD, DETAIL_VENTE, { | ||||
|   | ||||
| @@ -29,7 +29,7 @@ export class DialogItemAchat extends Dialog { | ||||
|     } | ||||
|  | ||||
|     DialogItemAchat.changeNombreLots(venteData, 1) | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData) | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.hbs`, venteData) | ||||
|     new DialogItemAchat(html, venteData).render(true) | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -20,7 +20,7 @@ export class DialogItemVente extends Dialog { | ||||
|       quantiteIllimite: item.isItemCommerce() ? quantiteMax == undefined : !item.parent, | ||||
|       isOwned:  item.parent, | ||||
|     } | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData); | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.hbs`, venteData); | ||||
|     return new DialogItemVente(venteData, html).render(true); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -12,13 +12,13 @@ import { RdDSheetUtility } from "./rdd-sheet-utility.js"; | ||||
| import { STATUSES } from "./settings/status-effects.js"; | ||||
| import { MAINS_DIRECTRICES } from "./actor.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 { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||
| import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js"; | ||||
| import { RdDCoeur } from "./coeur/rdd-coeur.js"; | ||||
| import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"; | ||||
| import { RdDItemRace } from "./item/race.js"; | ||||
| import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| @@ -30,7 +30,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|   /** @override */ | ||||
|   static get defaultOptions() { | ||||
|     return foundry.utils.mergeObject(RdDBaseActorReveSheet.defaultOptions, { | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.hbs", | ||||
|       width: 550, | ||||
|       showCompNiveauBase: false, | ||||
|       vueArchetype: false, | ||||
| @@ -126,80 +126,73 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|     }) | ||||
|  | ||||
|     this.html.find('.show-hide-competences').click(async event => { | ||||
|       this.options.showCompNiveauBase = !this.options.showCompNiveauBase; | ||||
|       this.render(true); | ||||
|       this.options.showCompNiveauBase = !this.options.showCompNiveauBase | ||||
|       this.render(true) | ||||
|     }); | ||||
|  | ||||
|     this.html.find('.button-tmr-visu').click(async event => this.actor.displayTMR("visu")) | ||||
|     this.html.find('.button-tmr-visu').click(async event => await this.actor.displayTMR("visu")) | ||||
|  | ||||
|     // Everything below here is only needed if the sheet is editable | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     this.html.find('.sheet-possession-attack').click(async event => { | ||||
|       const poss = RdDSheetUtility.getItem(event, this.actor) | ||||
|       this.actor.conjurerPossession(poss) | ||||
|       await this.actor.conjurerPossession(poss) | ||||
|     }) | ||||
|  | ||||
|     this.html.find('.subacteur-coeur-toggle a').click(async event => { | ||||
|       const subActorIdactorId = RdDSheetUtility.getEventItemData(event, 'subactor-id') | ||||
|       const coeurNombre = $(event.currentTarget).data('numero-coeur') | ||||
|       RdDCoeur.toggleSubActeurCoeur(this.actor.id, subActorIdactorId, coeurNombre) | ||||
|       await RdDCoeur.toggleSubActeurCoeur(this.actor.id, subActorIdactorId, coeurNombre) | ||||
|     }) | ||||
|     this.html.find('.subacteur-tendre-moment').click(async event => { | ||||
|       const subActorId = RdDSheetUtility.getEventItemData(event, 'subactor-id') | ||||
|       RdDCoeur.startSubActeurTendreMoment(this.actor.id, subActorId) | ||||
|       await RdDCoeur.startSubActeurTendreMoment(this.actor.id, subActorId) | ||||
|     }) | ||||
|     this.html.find('.subacteur-delete').click(async event => { | ||||
|       const li = RdDSheetUtility.getEventElement(event); | ||||
|       const subActorId = li.data("subactor-id"); | ||||
|       this.deleteSubActeur(subActorId, li); | ||||
|     }) | ||||
|     this.html.find("input.derivee-value[name='system.compteurs.stress.value']").change(async event => { | ||||
|       this.actor.updateCompteurValue("stress", parseInt(event.target.value)); | ||||
|     }); | ||||
|     this.html.find("input.derivee-value[name='system.compteurs.experience.value']").change(async event => { | ||||
|       this.actor.updateCompteurValue("experience", parseInt(event.target.value)); | ||||
|     }); | ||||
|     this.html.find("input.derivee-value[name='system.compteurs.stress.value']").change(async event => | ||||
|       await this.actor.updateCompteurValue("stress", parseInt(event.target.value)) | ||||
|     ); | ||||
|     this.html.find("input.derivee-value[name='system.compteurs.experience.value']").change(async event => | ||||
|       await this.actor.updateCompteurValue("experience", parseInt(event.target.value)) | ||||
|     ); | ||||
|  | ||||
|     this.html.find('.creer-tache').click(async event => this.createEmptyTache()); | ||||
|     this.html.find('.creer-une-oeuvre').click(async event => this.selectTypeOeuvreToCreate()); | ||||
|     this.html.find('.creer-tache-blessure-legere').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 2)); | ||||
|     this.html.find('.creer-tache-blessure-grave').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 4)); | ||||
|     this.html.find('.creer-tache-blessure-critique').click(async event => RdDItemBlessure.createTacheSoinBlessure(this.actor, 6)); | ||||
|     this.html.find('.creer-tache').click(async event => await this.createEmptyTache()); | ||||
|     this.html.find('.creer-une-oeuvre').click(async event => await this.selectTypeOeuvreToCreate()); | ||||
|     this.html.find('.creer-tache-blessure-legere').click(async event => await RdDItemBlessure.createTacheSoinBlessure(this.actor, 2)); | ||||
|     this.html.find('.creer-tache-blessure-grave').click(async event => await RdDItemBlessure.createTacheSoinBlessure(this.actor, 4)); | ||||
|     this.html.find('.creer-tache-blessure-critique').click(async event => await RdDItemBlessure.createTacheSoinBlessure(this.actor, 6)); | ||||
|  | ||||
|     this.html.find('.blessure-premierssoins-done').change(async event => { | ||||
|       const blessure = this.getBlessure(event); | ||||
|       await blessure?.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } }); | ||||
|       await this.getBlessure(event)?.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } }); | ||||
|     }); | ||||
|     this.html.find('.blessure-soinscomplets-done').change(async event => { | ||||
|       const blessure = this.getBlessure(event); | ||||
|       await blessure?.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } }) | ||||
|       await this.getBlessure(event)?.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } }) | ||||
|     }); | ||||
|     this.html.find('.blessure-premierssoins-bonus').change(async event => { | ||||
|       const blessure = this.getBlessure(event); | ||||
|       await blessure?.setSoinsBlessure({ premierssoins: { bonus: Number(event.currentTarget.value) } }) | ||||
|       await this.getBlessure(event)?.setSoinsBlessure({ premierssoins: { bonus: Number(event.currentTarget.value) } }) | ||||
|     }); | ||||
|     this.html.find('.blessure-soinscomplets-bonus').change(async event => { | ||||
|       const blessure = this.getBlessure(event); | ||||
|       await blessure?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } }) | ||||
|       await this.getBlessure(event)?.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 => await this.actor.rollCarac('chance-actuelle')) | ||||
|     this.html.find('.button-appel-chance').click(async event => await this.actor.rollAppelChance()) | ||||
|  | ||||
|     this.html.find('.button-appel-chance').click(async event => this.actor.rollAppelChance()) | ||||
|     this.html.find('[name="jet-astrologie"]').click(async event => await this.actor.astrologieNombresAstraux()) | ||||
|     this.html.find('.action-tache').click(async event => await this.actor.rollTache(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.meditation-label a').click(async event => await this.actor.rollMeditation(RdDSheetUtility.getItemId(event))) | ||||
|  | ||||
|     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('.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('.danse-label a').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('.oeuvre-label a').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('.recettecuisine-label a').click(async event => this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.action-chant').click(async event => await this.actor.rollChant(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.action-danse').click(async event => await this.actor.rollDanse(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.action-musique').click(async event => await this.actor.rollMusique(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.action-oeuvre').click(async event => await this.actor.rollOeuvre(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.action-jeu').click(async event => await this.actor.rollJeu(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.action-recettecuisine').click(async event => await this.actor.rollRecetteCuisine(RdDSheetUtility.getItemId(event))) | ||||
|  | ||||
|     this.html.find('.description-aleatoire').click(async event => new AppPersonnageAleatoire(this.actor).render(true)) | ||||
|     if (game.user.isGM) { | ||||
| @@ -215,17 +208,16 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|         await this.actor.deleteExperienceLog(0, key + 1); | ||||
|       }); | ||||
|       // Boutons spéciaux MJs | ||||
|       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('.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('.forcer-tmr-aleatoire').click(async event => await this.actor.reinsertionAleatoire("Action MJ")) | ||||
|       this.html.find('.don-de-haut-reve').click(async event => await this.actor.addDonDeHautReve()) | ||||
|       this.html.find('.afficher-tmr').click(async event => await this.actor.changeTMRVisible()) | ||||
|     } | ||||
|  | ||||
|     // Points de reve actuel | ||||
|     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('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true })) | ||||
|     this.html.find('.action-empoignade').click(async event => await 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 => await this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) | ||||
|  | ||||
|     // Initiative pour l'arme | ||||
|     this.html.find('.roll-init-arme').click(async event => { | ||||
| @@ -238,30 +230,34 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|     }) | ||||
|     // Display TMR | ||||
|  | ||||
|     this.html.find('.button-tmr').click(async event => this.actor.displayTMR("normal")) | ||||
|     this.html.find('.button-tmr-rapide').click(async event => this.actor.displayTMR("rapide")) | ||||
|     this.html.find('.button-tmr').click(async event => await this.actor.displayTMR("normal")) | ||||
|     this.html.find('.button-tmr-rapide').click(async event => await this.actor.displayTMR("rapide")) | ||||
|  | ||||
|     this.html.find('.button-repos').click(async event => await this.actor.repos()) | ||||
|  | ||||
|     this.html.find('.carac-xp-augmenter').click(async event => this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", ""))) | ||||
|     this.html.find('.competence-xp-augmenter').click(async event => this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.competence-stress-augmenter').click(async event => this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.carac-xp-augmenter').click(async event => await this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", ""))) | ||||
|     this.html.find('.competence-xp-augmenter').click(async event => await this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event))) | ||||
|     this.html.find('.competence-stress-augmenter').click(async event =>{ | ||||
|       await this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event)) | ||||
|       this.render(true) | ||||
|     }  | ||||
|   ) | ||||
|  | ||||
|     if (this.options.vueDetaillee) { | ||||
|       // On carac change | ||||
|       this.html.find('input.carac-xp').change(async event => { | ||||
|         let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", ""); | ||||
|         this.actor.updateCaracXP(caracName, parseInt(event.target.value)); | ||||
|       }); | ||||
|         let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "") | ||||
|         await this.actor.updateCaracXP(caracName, parseInt(event.target.value)) | ||||
|       }) | ||||
|       // On competence xp change | ||||
|       this.html.find('input.competence-xp').change(async event => { | ||||
|         let compName = event.currentTarget.attributes.compname.value; | ||||
|         this.actor.updateCompetenceXP(compName, parseInt(event.target.value)); | ||||
|       }); | ||||
|         let compName = event.currentTarget.attributes.compname.value | ||||
|         await this.actor.updateCompetenceXP(compName, parseInt(event.target.value)) | ||||
|       }) | ||||
|       this.html.find('input.competence-xp-sort').change(async event => { | ||||
|         let compName = event.currentTarget.attributes.compname.value; | ||||
|         this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value)); | ||||
|       }); | ||||
|         let compName = event.currentTarget.attributes.compname.value | ||||
|         await this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value)) | ||||
|       }) | ||||
|  | ||||
|       this.html.find('.toggle-archetype').click(async event => { | ||||
|         this.options.vueArchetype = !this.options.vueArchetype; | ||||
| @@ -270,27 +266,27 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|       // On competence archetype change | ||||
|       this.html.find('.competence-archetype').change(async event => { | ||||
|         let compName = event.currentTarget.attributes.compname.value; | ||||
|         this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value)); | ||||
|         await this.actor.updateCompetenceArchetype(compName, parseInt(event.target.value)); | ||||
|       }); | ||||
|       this.html.find('.nouvelle-incarnation').click(async event => this.actor.nouvelleIncarnation()) | ||||
|       this.html.find('.nouvelle-incarnation').click(async event => await this.actor.nouvelleIncarnation()) | ||||
|     } | ||||
|  | ||||
|     // On pts de reve change | ||||
|     this.html.find('.pointsreve-value').change(async event => this.actor.update({ "system.reve.reve.value": event.currentTarget.value })) | ||||
|     this.html.find('.seuil-reve-value').change(async event => this.actor.setPointsDeSeuil(event.currentTarget.value)) | ||||
|     this.html.find('.pointsreve-value').change(async event => await this.actor.update({ "system.reve.reve.value": event.currentTarget.value })) | ||||
|     this.html.find('.seuil-reve-value').change(async event => await this.actor.setPointsDeSeuil(event.currentTarget.value)) | ||||
|  | ||||
|     this.html.find('.stress-test').click(async event => this.actor.transformerStress()) | ||||
|     this.html.find('.moral-malheureux').click(async event => this.actor.jetDeMoral('malheureuse')) | ||||
|     this.html.find('.moral-neutre').click(async event => this.actor.jetDeMoral('neutre')) | ||||
|     this.html.find('.moral-heureux').click(async event => this.actor.jetDeMoral('heureuse')) | ||||
|     this.html.find('.button-ethylisme').click(async event => this.actor.jetEthylisme()) | ||||
|     this.html.find('.stress-test').click(async event => await this.actor.transformerStress()) | ||||
|     this.html.find('.moral-malheureux').click(async event => await this.actor.jetDeMoral('malheureuse')) | ||||
|     this.html.find('.moral-neutre').click(async event => await this.actor.jetDeMoral('neutre')) | ||||
|     this.html.find('.moral-heureux').click(async event => await this.actor.jetDeMoral('heureuse')) | ||||
|     this.html.find('.button-ethylisme').click(async event => await this.actor.jetEthylisme()) | ||||
|  | ||||
|     this.html.find('.ptreve-actuel-plus').click(async event => this.actor.reveActuelIncDec(1)) | ||||
|     this.html.find('.ptreve-actuel-moins').click(async event => this.actor.reveActuelIncDec(-1)) | ||||
|     this.html.find('.chance-actuelle-plus').click(async event => this.actor.chanceActuelleIncDec(1)) | ||||
|     this.html.find('.chance-actuelle-moins').click(async event => this.actor.chanceActuelleIncDec(-1)) | ||||
|     this.html.find('.fatigue-plus').click(async event => this.actor.santeIncDec("fatigue", 1)) | ||||
|     this.html.find('.fatigue-moins').click(async event => this.actor.santeIncDec("fatigue", -1)) | ||||
|     this.html.find('.ptreve-actuel-plus').click(async event => await this.actor.reveActuelIncDec(1)) | ||||
|     this.html.find('.ptreve-actuel-moins').click(async event => await this.actor.reveActuelIncDec(-1)) | ||||
|     this.html.find('.chance-actuelle-plus').click(async event => await this.actor.chanceActuelleIncDec(1)) | ||||
|     this.html.find('.chance-actuelle-moins').click(async event => await this.actor.chanceActuelleIncDec(-1)) | ||||
|     this.html.find('.fatigue-plus').click(async event => await this.actor.santeIncDec("fatigue", 1)) | ||||
|     this.html.find('.fatigue-moins').click(async event => await this.actor.santeIncDec("fatigue", -1)) | ||||
|   } | ||||
|  | ||||
|   getBlessure(event) { | ||||
| @@ -327,7 +323,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|   /* -------------------------------------------- */ | ||||
|   async selectTypeOeuvreToCreate() { | ||||
|     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) { | ||||
|       content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>` | ||||
|     } | ||||
|   | ||||
							
								
								
									
										420
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						
									
										420
									
								
								module/actor.js
									
									
									
									
									
								
							| @@ -32,7 +32,7 @@ import { RdDItemBlessure } from "./item/blessure.js"; | ||||
| import { AppAstrologie } from "./sommeil/app-astrologie.js"; | ||||
| import { RdDEmpoignade } from "./rdd-empoignade.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 { RdDCoeur } from "./coeur/rdd-coeur.js"; | ||||
| import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; | ||||
| @@ -42,6 +42,7 @@ import { RdDItemTete } from "./item/tete.js"; | ||||
| import { DialogSelect } from "./dialog-select.js"; | ||||
| import { PAS_DE_DRACONIC, POSSESSION_SANS_DRACONIC } from "./item/base-items.js"; | ||||
| import { RdDItemRace } from "./item/race.js"; | ||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | ||||
|  | ||||
| export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] | ||||
|  | ||||
| @@ -166,29 +167,30 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async $perteRevePotionsEnchantees() { | ||||
|     let potions = this.itemTypes[ITEM_TYPES.potion] | ||||
|       .filter(it => Grammar.includesLowerCaseNoAccent(it.system.categorie, 'enchanté') && !it.system.prpermanent) | ||||
|   async $perteReveEnchantementsChateauDormants() { | ||||
|     const toUpdate = this.items.filter(it => [ITEM_TYPES.potion, ITEM_TYPES.gemme].includes(it.type)) | ||||
|       .map(it => it.perteReveChateauDormant()) | ||||
|       .filter(it => it != undefined) | ||||
|  | ||||
|     const potionUpdates = await Promise.all(potions.map(async it => { | ||||
|       const nouveauReve = Math.max(it.system.pr - 1, 0) | ||||
|     if (toUpdate.length > 0) { | ||||
|       console.log('perte de rêve des enchantements', toUpdate) | ||||
|       const messageUpdates = await Promise.all( | ||||
|         toUpdate.map(async it => await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-pertereve-enchantement-chateaudormant.hbs`, it))) | ||||
|       ChatMessage.create({ | ||||
|         whisper: ChatUtility.getOwners(this), | ||||
|         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.html`, { | ||||
|           pr: nouveauReve, | ||||
|           alias: this.getAlias(), | ||||
|           potionName: it.name, | ||||
|           potionImg: it.img | ||||
|         }) | ||||
|         content: messageUpdates.reduce(Misc.joining('<br>')) | ||||
|       }) | ||||
|       return { | ||||
|         _id: it._id, | ||||
|         'system.pr': nouveauReve, | ||||
|         'system.quantite': nouveauReve > 0 ? it.system.quantite : 0 | ||||
|       } | ||||
|     })) | ||||
|       await this.updateEmbeddedDocuments('Item', toUpdate.map(it => it.update)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|     await this.updateEmbeddedDocuments('Item', potionUpdates); | ||||
|   async $suppressionLancementsSort() { | ||||
|     const updates = this.itemTypes[ITEM_TYPES.sort] | ||||
|       .filter(it => it.system.lancements.length > 0) | ||||
|       .map(it => { return { _id: it.id, 'system.lancements': [] } }) | ||||
|     if (updates.length > 0) { | ||||
|       await this.updateEmbeddedDocuments('Item', updates) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** -------------------------------------------- | ||||
| @@ -245,7 +247,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   } | ||||
|  | ||||
|   async _recuperationSante(message) { | ||||
|     const maladiesPoisons = this.getMaladiePoisons(); | ||||
|     const maladiesPoisons = this.getMaladiesPoisons(); | ||||
|     const isMaladeEmpoisonne = maladiesPoisons.length > 0; | ||||
|     this._messageRecuperationMaladiePoisons(maladiesPoisons, message); | ||||
|  | ||||
| @@ -253,7 +255,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     await this._recupererVie(message, isMaladeEmpoisonne); | ||||
|   } | ||||
|  | ||||
|   getMaladiePoisons() { | ||||
|   getMaladiesPoisons() { | ||||
|     return this.items.filter(item => item.type == 'maladie' || (item.type == 'poison' && item.system.active)); | ||||
|   } | ||||
|  | ||||
| @@ -283,13 +285,14 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       }; | ||||
|  | ||||
|       await this._recuperationSante(message) | ||||
|       await this._recupereMoralChateauDormant(message); | ||||
|       await this._recupereChance(); | ||||
|       await this.transformerStress(); | ||||
|       await this.retourSeuilDeReve(message); | ||||
|       await this.setBonusPotionSoin(0); | ||||
|       await this.retourSust(message); | ||||
|       await this.$perteRevePotionsEnchantees(); | ||||
|       await this._recupereMoralChateauDormant(message) | ||||
|       await this._recupereChance() | ||||
|       await this.transformerStress() | ||||
|       await this.retourSeuilDeReve(message) | ||||
|       await this.setBonusPotionSoin(0) | ||||
|       await this.retourSust(message) | ||||
|       await this.$perteReveEnchantementsChateauDormants() | ||||
|       await this.$suppressionLancementsSort() | ||||
|       await RdDCoeur.applyCoeurChateauDormant(this, message) | ||||
|       if (message.content != "") { | ||||
|         message.content = `A la fin Chateau Dormant, ${message.content}<br>Un nouveau jour se lève`; | ||||
| @@ -413,19 +416,18 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async remiseANeuf() { | ||||
|     ChatMessage.create({ | ||||
|       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 = { | ||||
|     await this.update({ | ||||
|       'system.sante.endurance.value': this.system.sante.endurance.max, | ||||
|       'system.sante.vie.value': this.system.sante.vie.max, | ||||
|       'system.sante.fatigue.value': 0, | ||||
|       '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 +531,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         jet_moral: false, | ||||
|         value: value | ||||
|       } | ||||
|     }); | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -626,7 +628,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     rollData.competence.system.defaut_carac = 'reve-actuel'; | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this, rollData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-reve-de-dragon.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-reve-de-dragon.hbs' }, | ||||
|       { | ||||
|         name: 'maitrise', | ||||
|         label: 'Maîtriser le Rêve de Dragon', | ||||
| @@ -734,7 +736,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       await competence.update({ | ||||
|         "system.xp": toXp, | ||||
|         "system.niveau": toNiveau, | ||||
|       }); | ||||
|       }, { render: false }) | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name); | ||||
|     } | ||||
| @@ -756,7 +758,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|           expérience requise: ${xpRequis} | ||||
|           niveau : ${fromNiveau} | ||||
|           archétype : ${competence.system.niveau_archetype}`); | ||||
|       return; | ||||
|       return | ||||
|     } | ||||
|     const xpUtilise = Math.max(0, Math.min(fromXpStress, xpRequis)); | ||||
|     const gainNiveau = (xpUtilise >= xpRequis || xpRequis <= 0) ? 1 : 0; | ||||
| @@ -765,7 +767,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     await competence.update({ | ||||
|       "system.xp": newXp, | ||||
|       "system.niveau": toNiveau, | ||||
|     }); | ||||
|     }, { render: false }) | ||||
|     const toXpStress = Math.max(0, fromXpStress - xpUtilise); | ||||
|     await this.update({ "system.compteurs.experience.value": toXpStress }); | ||||
|  | ||||
| @@ -781,7 +783,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       const toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie, competence.getCategories()); | ||||
|       this.notifyCompetencesTronc(competence, toNiveau); | ||||
|       const fromNiveau = competence.system.niveau; | ||||
|       await competence.update({ 'system.niveau': toNiveau }); | ||||
|       await competence.update({ 'system.niveau': toNiveau }, { render: false }) | ||||
|       await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name, true); | ||||
|     } | ||||
|   } | ||||
| @@ -806,10 +808,10 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       if (isNaN(toXp) || typeof (toXp) != 'number') toXp = 0; | ||||
|       const fromXp = competence.system.xp; | ||||
|       this.checkCompetenceXP(idOrName, toXp); | ||||
|       await competence.update({ 'system.xp': toXp }); | ||||
|       await competence.update({ 'system.xp': toXp }, { render: false }) | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name, true); | ||||
|       if (toXp > fromXp) { | ||||
|         RdDUtility.checkThanatosXP(idOrName); | ||||
|         RdDUtility.checkThanatosXP(competence) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| @@ -820,10 +822,10 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     if (competence) { | ||||
|       if (isNaN(toXpSort) || typeof (toXpSort) != 'number') toXpSort = 0; | ||||
|       const fromXpSort = competence.system.xp_sort; | ||||
|       await competence.update({ 'system.xp_sort': toXpSort }); | ||||
|       await competence.update({ 'system.xp_sort': toXpSort }, { render: false }) | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, competence.name, true); | ||||
|       if (toXpSort > fromXpSort) { | ||||
|         RdDUtility.checkThanatosXP(idOrName); | ||||
|         RdDUtility.checkThanatosXP(competence) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| @@ -832,7 +834,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   async updateCompetenceArchetype(idOrName, compValue) { | ||||
|     let competence = this.getCompetence(idOrName) | ||||
|     if (competence) { | ||||
|       await competence.update({ 'system.niveau_archetype': Math.max(compValue ?? 0, 0) }); | ||||
|       await competence.update({ 'system.niveau_archetype': Math.max(compValue ?? 0, 0) }) | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -993,13 +995,10 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async addSortReserve(itemId) { | ||||
|     if (itemId) { | ||||
|       const item = this.items.get(itemId) | ||||
|       if (item.type == ITEM_TYPES.sort && !item.system.isrituel) { | ||||
|         this.$createSortReserve(item) | ||||
|         return | ||||
|       } | ||||
|   async addSortReserve(item) { | ||||
|     if (item?.type == ITEM_TYPES.sort && !item.system.isrituel) { | ||||
|       this.$createSortReserve(item) | ||||
|       return | ||||
|     } | ||||
|     const selectSortReserve = { | ||||
|       title: "Créer un sort en réserve", | ||||
| @@ -1199,48 +1198,12 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       diffConditions: 0, | ||||
|       ajustementsForce: CONFIG.RDD.difficultesLibres | ||||
|     } | ||||
|     let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ethylisme.html', rollData); | ||||
|     let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ethylisme.hbs', rollData); | ||||
|     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) { | ||||
|     return (await DialogConsommer.create(this, item, onActionItem)).render(true); | ||||
|   async mangerNourriture(item) { | ||||
|     return (await DialogConsommer.create(this, item)).render(true); | ||||
|   } | ||||
|  | ||||
|   async actionLire(item) { | ||||
| @@ -1250,9 +1213,9 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async actionHerbe(item, onActionItem = async () => { }) { | ||||
|   async fabriquerDecoctionHerbe(item) { | ||||
|     if (item.isHerbeAPotion()) { | ||||
|       return DialogFabriquerPotion.create(this, item, onActionItem); | ||||
|       return DialogFabriquerPotion.create(this, item); | ||||
|     } | ||||
|     return; | ||||
|   } | ||||
| @@ -1428,7 +1391,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     ethylismeData.doses = ethylisme.nb_doses; | ||||
|  | ||||
|     await this.update({ 'system.compteurs.ethylisme': ethylisme }); | ||||
|     await RdDResolutionTable.displayRollData(ethylismeData, this, 'chat-resultat-ethylisme.html'); | ||||
|     await RdDRollResult.displayRollData(ethylismeData, this, 'chat-resultat-ethylisme.hbs'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -1469,7 +1432,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.hbs`, stressRollData) | ||||
|     }); | ||||
|  | ||||
|     const toStress = Math.max(fromStress - stressRollData.perte - 1, 0); | ||||
| @@ -1517,7 +1480,6 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   /* -------------------------------------------- */ | ||||
|   createCallbackExperience() { | ||||
|     return { | ||||
|       condition: r => r.rolled.isPart && r.finalLevel < 0 && game.settings.get("core", "rollMode") != 'selfroll', | ||||
|       action: r => this.appliquerAjoutExperience(r) | ||||
|     }; | ||||
|   } | ||||
| @@ -1525,7 +1487,6 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   /* -------------------------------------------- */ | ||||
|   createCallbackAppelAuMoral() { /* Si l'appel au moral est utilisé, on l'affiche dans le chat et on diminue éventuellement le moral */ | ||||
|     return { | ||||
|       condition: r => r.use.appelAuMoral && game.settings.get("core", "rollMode") != 'selfroll', | ||||
|       action: r => this._appliquerAppelMoral(r) | ||||
|     }; | ||||
|   } | ||||
| @@ -1554,7 +1515,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         if (display) { | ||||
|           ChatMessage.create({ | ||||
|             whisper: ChatUtility.getOwners(this), | ||||
|             content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html`, checkXp) | ||||
|             content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.hbs`, checkXp) | ||||
|           }); | ||||
|         } | ||||
|         return checkXp; | ||||
| @@ -1586,7 +1547,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         if (display) { | ||||
|           ChatMessage.create({ | ||||
|             whisper: ChatUtility.getOwners(this), | ||||
|             content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html`, checkXp) | ||||
|             content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.hbs`, checkXp) | ||||
|           }); | ||||
|         } | ||||
|         return checkXp; | ||||
| @@ -1596,13 +1557,16 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { | ||||
|     if (!Misc.hasConnectedGM()) { | ||||
|     if (!rollData.rolled.isPart || | ||||
|       rollData.finalLevel >= 0 || | ||||
|       game.settings.get("core", "rollMode") == 'selfroll' || | ||||
|       !Misc.hasConnectedGM()) { | ||||
|       return | ||||
|     } | ||||
|     hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) | ||||
|     let xpData = await this._appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence, rollData.jetResistance); | ||||
|     if (xpData.length) { | ||||
|       const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, { | ||||
|       const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.hbs`, { | ||||
|         actor: this, | ||||
|         xpData | ||||
|       }) | ||||
| @@ -1620,7 +1584,9 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _appliquerAppelMoral(rollData) { | ||||
|     if (!rollData.use.moral) return; | ||||
|     if (!rollData.use.moral || game.settings.get("core", "rollMode") == 'selfroll') { | ||||
|       return | ||||
|     } | ||||
|     if (rollData.rolled.isEchec || | ||||
|       (rollData.ajustements.diviseurSignificative && (rollData.rolled.roll * rollData.ajustements.diviseurSignificative > rollData.score))) { | ||||
|       rollData.perteMoralEchec = rollData.moral <= -3 ? 'dissolution' : 'perte'; | ||||
| @@ -1682,7 +1648,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     const dialog = await this.openRollDialog({ | ||||
|       name: 'lancer-un-sort', | ||||
|       label: 'Lancer un sort', | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html', | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.hbs', | ||||
|       rollData: { | ||||
|         carac: { 'reve': reve }, | ||||
|         forceCarac: { 'reve': reve }, | ||||
| @@ -1695,10 +1661,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         diffLibre: RdDItemSort.getDifficulte(sorts[0], -7), // Per default at startup | ||||
|         coutreve: Array(30).fill().map((item, index) => 1 + index), | ||||
|       }, | ||||
|       callbackAction: async r => { | ||||
|         await this._rollUnSortResult(r); | ||||
|         if (!r.isSortReserve) this.tmrApp?.close(); | ||||
|       } | ||||
|       callbacks: [{ action: r => this._rollUnSortResult(r) }] | ||||
|     }); | ||||
|     this.tmrApp?.setTMRPendingAction(dialog); | ||||
|   } | ||||
| @@ -1772,6 +1735,17 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         if (rollData.isSortReserve) { | ||||
|           await this.sortMisEnReserve(selectedSort, rollData.competence, rollData.tmr.coord, Number(selectedSort.system.ptreve_reel)); | ||||
|         } | ||||
|         else { | ||||
|           console.log('lancement de sort', rollData.selectedSort) | ||||
|           const precedents = rollData.selectedSort.system.lancements ?? [] | ||||
|           const lancements = [...precedents, { | ||||
|             timestamp: game.system.rdd.calendrier.getTimestamp(), | ||||
|             reve: rollData.selectedSort.system.ptreve_reel | ||||
|           }] | ||||
|           await this.updateEmbeddedDocuments('Item', | ||||
|             [{ _id: rollData.selectedSort._id, 'system.lancements': lancements }] | ||||
|           ) | ||||
|         } | ||||
|       } | ||||
|       else { | ||||
|         rollData.depenseReve = 0; | ||||
| @@ -1791,20 +1765,49 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     reveActuel = Math.max(reveActuel - rollData.depenseReve, 0); | ||||
|     await this.update({ "system.reve.reve.value": reveActuel }); | ||||
|  | ||||
|     // Final chat message | ||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-sort.html'); | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-sort.hbs'); | ||||
|  | ||||
|     if (reveActuel == 0) { // 0 points de reve | ||||
|       ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" }); | ||||
|     } | ||||
|     if (!rollData.isSortReserve) { | ||||
|       this.tmrApp?.close(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 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 RdDRollResult.displayRollData(rollData, this) | ||||
|     return rollData.rolled; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   gererExperience(rollData) { | ||||
|     const callback = this.createCallbackExperience(); | ||||
|     if (callback.condition(rollData)) { | ||||
|       callback.action(rollData); | ||||
|     } | ||||
|     this.createCallbackExperience().action(rollData); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -1817,7 +1820,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         name: nomTache, type: 'tache', | ||||
|         system: { | ||||
|           carac: 'intellect', | ||||
|           competence: 'Ecriture', | ||||
|           competence: 'Écriture', | ||||
|           difficulte: item.system.difficulte, | ||||
|           periodicite: "60 minutes", | ||||
|           fatigue: 2, | ||||
| @@ -1850,6 +1853,27 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     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.hbs', | ||||
|       rollData: { | ||||
|         alias: this.getAlias(), | ||||
|         carac: this.system.carac, | ||||
|         selectedCarac: this.getCaracByName(caracName), | ||||
|         selectedCaracName: caracName, | ||||
|         diffLibre: diff, | ||||
|         competence: competence, | ||||
|         show: { title: options?.title ?? '' } | ||||
|       }, | ||||
|       // TODO: | ||||
|       callbacks: [{ action: r => this.$onRollCompetence(r, options) }] | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollTache(id, options = {}) { | ||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||
| @@ -1860,7 +1884,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     await this.openRollDialog({ | ||||
|       name: 'jet-competence', | ||||
|       label: 'Jet de Tâche ' + tacheData.name, | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', | ||||
|       rollData: { | ||||
|         competence: compData, | ||||
|         tache: tacheData, | ||||
| @@ -1871,7 +1895,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|           [tacheData.system.carac]: foundry.utils.duplicate(this.system.carac[tacheData.system.carac]) | ||||
|         } | ||||
|       }, | ||||
|       callbackAction: r => this._tacheResult(r, options) | ||||
|       callbacks: [{ action: r => this._tacheResult(r, options) }] | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @@ -1891,17 +1915,17 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     } | ||||
|     rollData.tache.system.tentatives = rollData.tache.system.nb_jet_succes + rollData.tache.system.nb_jet_echec; | ||||
|  | ||||
|     this.updateEmbeddedDocuments('Item', [rollData.tache]); | ||||
|     this.santeIncDec("fatigue", rollData.tache.system.fatigue); | ||||
|     await this.updateEmbeddedDocuments('Item', [rollData.tache]); | ||||
|     await this.santeIncDec("fatigue", rollData.tache.system.fatigue); | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html'); | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-tache.hbs'); | ||||
|     if (options?.onRollAutomate) { | ||||
|       options.onRollAutomate(rollData); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _rollArt(artData, selected, oeuvre, callbackAction = r => this._resultArt(r)) { | ||||
|   async _rollArt(artData, selected, oeuvre, callbackAction = async r => await this._resultArt(r)) { | ||||
|     oeuvre.system.niveau = oeuvre.system.niveau ?? 0; | ||||
|     foundry.utils.mergeObject(artData, | ||||
|       { | ||||
| @@ -1923,10 +1947,10 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     await this.openRollDialog({ | ||||
|       name: `jet-${artData.art}`, | ||||
|       label: `${artData.verbe} ${oeuvre.name}`, | ||||
|       template: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html`, | ||||
|       template: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.hbs`, | ||||
|       rollData: artData, | ||||
|       callbackAction: callbackAction | ||||
|     }); | ||||
|       callbacks: [{ action: callbackAction }], | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -1935,7 +1959,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau); | ||||
|     artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite; | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`); | ||||
|     await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -2012,7 +2036,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       ui.notifications.info(`${platCuisine.system.quantite} rations de ${platCuisine.name} ont été ajoutés à votre équipement`); | ||||
|     } | ||||
|     cuisine.platCuisine = platCuisine; | ||||
|     await RdDResolutionTable.displayRollData(cuisine, this.name, `chat-resultat-${cuisine.art}.html`); | ||||
|     await RdDRollResult.displayRollData(cuisine, this.name, `chat-resultat-${cuisine.art}.hbs`); | ||||
|   } | ||||
|  | ||||
|   async preparerNourriture(item) { | ||||
| @@ -2086,7 +2110,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     }; | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this, meditationData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.hbs' }, | ||||
|       { | ||||
|         name: 'jet-meditation', | ||||
|         label: "Jet de méditation", | ||||
| @@ -2107,7 +2131,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       await this.createEmbeddedDocuments("Item", [RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditationRoll.meditation, meditationRoll.rolled)]); | ||||
|     } | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(meditationRoll, this.name, 'chat-resultat-meditation.html'); | ||||
|     await RdDRollResult.displayRollData(meditationRoll, this.name, 'chat-resultat-meditation.hbs'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -2159,7 +2183,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this, rollData, | ||||
|       { | ||||
|         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.html', | ||||
|         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.hbs', | ||||
|         close: async html => await this._onCloseRollDialog(html) | ||||
|       }, | ||||
|       { | ||||
| @@ -2194,7 +2218,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXp, toXp, `${rollData.competence.name} : signe draconique`); | ||||
|     } | ||||
|     await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]); | ||||
|     await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html'); | ||||
|     await RdDRollResult.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.hbs'); | ||||
|     this.tmrApp.close(); | ||||
|   } | ||||
|  | ||||
| @@ -2203,15 +2227,15 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     await this.openRollDialog({ | ||||
|       name: 'appelChance', | ||||
|       label: 'Appel à la chance', | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html', | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.hbs', | ||||
|       rollData: { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' }, | ||||
|       callbackAction: r => this._appelChanceResult(r, onSuccess, onEchec) | ||||
|       callbacks: [{ action: r => this.$appelChanceResult(r, onSuccess, onEchec) }] | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _appelChanceResult(rollData, onSuccess, onEchec) { | ||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-appelchance.html') | ||||
|   async $appelChanceResult(rollData, onSuccess, onEchec) { | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-appelchance.hbs') | ||||
|     if (rollData.rolled.isSuccess) { | ||||
|       await this.setFlag(SYSTEM_RDD, 'utilisationChance', true); | ||||
|       await this.chanceActuelleIncDec(-1); | ||||
| @@ -2503,7 +2527,6 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       }) | ||||
|     } | ||||
|     const blessure = this.getItem(blessureId, 'blessure') | ||||
|     console.log('TODO update blessure', this, blessureId, rollData, rollData.tache); | ||||
|     if (blessure && !blessure.system.premierssoins.done) { | ||||
|       const tache = rollData.tache; | ||||
|       if (rollData.rolled.isETotal) { | ||||
| @@ -2570,8 +2593,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async equiperObjet(itemID) { | ||||
|     let item = this.getEmbeddedDocument('Item', itemID); | ||||
|   async equiperObjet(item) { | ||||
|     if (item?.isEquipable()) { | ||||
|       const isEquipe = !item.system.equipe; | ||||
|       await item.update({ "system.equipe": isEquipe }); | ||||
| @@ -2590,7 +2612,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     for (const armure of armures) { | ||||
|       protection += await RdDDice.rollTotal(armure.system.protection.toString()); | ||||
|       if (dmg > 0 && attackerRoll.dmg.encaisserSpecial != "noarmure") { | ||||
|         armure.deteriorerArmure(dmg); | ||||
|         await armure.deteriorerArmure(dmg) | ||||
|         dmg = 0; | ||||
|       } | ||||
|     } | ||||
| @@ -2665,7 +2687,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|       rollData.competence.system.defaut_carac = caracTache; | ||||
|  | ||||
|       const dialog = await RdDRoll.create(this, rollData, | ||||
|         { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html' }, | ||||
|         { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.hbs' }, | ||||
|         { | ||||
|           name: 'tache-alchimique', | ||||
|           label: 'Tache Alchimique', | ||||
| @@ -2686,7 +2708,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _alchimieResult(rollData) { | ||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-alchimie.html'); | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-alchimie.hbs'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -2835,25 +2857,25 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async consommerPotionSoin(potionData) { | ||||
|     potionData.alias = this.name; | ||||
|     potionData.supprimer = true; | ||||
|   async consommerPotionSoin(potion) { | ||||
|     potion.alias = this.name; | ||||
|     potion.supprimer = true; | ||||
|  | ||||
|     if (potionData.system.magique) { | ||||
|     if (potion.system.magique) { | ||||
|       // Gestion de la résistance: | ||||
|       potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); | ||||
|       if (potionData.rolled.isEchec) { | ||||
|       potion.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); | ||||
|       if (potion.rolled.isEchec) { | ||||
|         await this.reveActuelIncDec(-1); | ||||
|         potionData.guerisonData = await this.buildPotionGuerisonList(potionData.system.puissance); | ||||
|         potionData.guerisonMinutes = potionData.guerisonData.pointsConsommes * 5; | ||||
|         potion.guerisonData = await this.buildPotionGuerisonList(potion.system.puissance); | ||||
|         potion.guerisonMinutes = potion.guerisonData.pointsConsommes * 5; | ||||
|       } | ||||
|     } | ||||
|     if (!potionData.system.magique || potionData.rolled.isSuccess) { | ||||
|       await this.setBonusPotionSoin(potionData.system.herbebonus); | ||||
|     if (!potion.system.magique || potion.rolled.isSuccess) { | ||||
|       await this.setBonusPotionSoin(potion.system.herbebonus); | ||||
|     } | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html`, potionData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.hbs`, potion) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @@ -2862,46 +2884,47 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async consommerPotionRepos(potionData) { | ||||
|     potionData.alias = this.name; | ||||
|     potionData.supprimer = true; | ||||
|   async consommerPotionRepos(potion) { | ||||
|     potion.alias = this.name; | ||||
|     potion.supprimer = true; | ||||
|  | ||||
|     if (potionData.system.magique) { | ||||
|     if (potion.system.magique) { | ||||
|       // Gestion de la résistance: | ||||
|       potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); | ||||
|       if (potionData.rolled.isEchec) { | ||||
|       potion.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); | ||||
|       if (potion.rolled.isEchec) { | ||||
|         await this.reveActuelIncDec(-1); | ||||
|         let fatigueActuelle = this.getFatigueActuelle(); | ||||
|         potionData.caseFatigueReel = Math.min(fatigueActuelle, potionData.system.puissance); | ||||
|         potionData.guerisonDureeUnite = (potionData.system.reposalchimique) ? "rounds" : "minutes"; | ||||
|         potionData.guerisonDureeValue = (potionData.system.reposalchimique) ? potionData.caseFatigueReel : potionData.caseFatigueReel * 5; | ||||
|         potionData.aphasiePermanente = false; | ||||
|         if (potionData.system.reposalchimique) { | ||||
|         potion.caseFatigueReel = Math.min(fatigueActuelle, potion.system.puissance); | ||||
|         potion.guerisonDureeUnite = (potion.system.reposalchimique) ? "rounds" : "minutes"; | ||||
|         potion.guerisonDureeValue = (potion.system.reposalchimique) ? potion.caseFatigueReel : potion.caseFatigueReel * 5; | ||||
|         potion.aphasiePermanente = false; | ||||
|         if (potion.system.reposalchimique) { | ||||
|           let chanceAphasie = await RdDDice.rollTotal("1d100"); | ||||
|           if (chanceAphasie <= potionData.system.pr) { | ||||
|             potionData.aphasiePermanente = true; | ||||
|           if (chanceAphasie <= potion.system.pr) { | ||||
|             potion.aphasiePermanente = true; | ||||
|           } | ||||
|         } | ||||
|         await this.santeIncDec("fatigue", -potionData.caseFatigueReel); | ||||
|         await this.santeIncDec("fatigue", -potion.caseFatigueReel); | ||||
|       } | ||||
|     } | ||||
|     if (!potionData.system.magique || potionData.rolled.isSuccess) { | ||||
|       this.bonusRepos = potionData.system.herbebonus; | ||||
|     if (!potion.system.magique || potion.rolled.isSuccess) { | ||||
|       this.bonusRepos = potion.system.herbebonus; | ||||
|     } | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html`, potionData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.hbs`, potion) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async fabriquerPotion(herbeData) { | ||||
|     let newPotion = { | ||||
|     const newPotion = { | ||||
|       name: `Potion de ${herbeData.system.categorie} (${herbeData.name})`, type: 'potion', | ||||
|       img: "systems/foundryvtt-reve-de-dragon/icons/objets/fiole_verre.webp", | ||||
|       system: { | ||||
|         quantite: 1, cout: 0, encombrement: 0.1, | ||||
|         categorie: herbeData.system.categorie, | ||||
|         etat: 'Liquide', | ||||
|         herbe: herbeData.name, | ||||
|         rarete: herbeData.system.rarete, | ||||
|         herbebrins: herbeData.nbBrins, | ||||
| @@ -2909,61 +2932,52 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         description: "" | ||||
|       } | ||||
|     } | ||||
|     await this.createEmbeddedDocuments('Item', [newPotion], { renderSheet: true }); | ||||
|  | ||||
|     let newQuantite = herbeData.system.quantite - herbeData.nbBrins; | ||||
|     let messageData = { | ||||
|       alias: this.getAlias(), | ||||
|       nbBrinsReste: newQuantite, | ||||
|       potion: newPotion, | ||||
|       herbe: herbeData | ||||
|     } | ||||
|     this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins); | ||||
|     await this.createEmbeddedDocuments('Item', [newPotion]) | ||||
|     await this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins) | ||||
|  | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html`, messageData) | ||||
|     }); | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.hbs`, { | ||||
|         alias: this.getAlias(), | ||||
|         nbBrinsReste: herbeData.system.quantite - herbeData.nbBrins, | ||||
|         potion: newPotion, | ||||
|         herbe: herbeData | ||||
|       }) | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async diminuerQuantiteObjet(id, nb, options = { supprimerSiZero: false }) { | ||||
|     const item = this.getItem(id); | ||||
|     if (item) { | ||||
|       await item.diminuerQuantite(nb, options); | ||||
|     } | ||||
|     await this.getItem(id)?.diminuerQuantite(nb, options); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async consommerPotionGenerique(potionData) { | ||||
|     potionData.alias = this.name; | ||||
|   async consommerPotionGenerique(potion) { | ||||
|     potion.alias = this.name; | ||||
|  | ||||
|     if (potionData.system.magique) { | ||||
|     if (potion.system.magique) { | ||||
|       // Gestion de la résistance: | ||||
|       potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); | ||||
|       if (potionData.rolled.isEchec) { | ||||
|       potion.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); | ||||
|       if (potion.rolled.isEchec) { | ||||
|         await this.reveActuelIncDec(-1); | ||||
|       } | ||||
|     } | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.html`, potionData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.hbs`, potion) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async consommerPotion(potion, onActionItem = async () => { }) { | ||||
|     const potionData = potion | ||||
|  | ||||
|     if (potionData.system.categorie.includes('Soin')) { | ||||
|       this.consommerPotionSoin(potionData); | ||||
|     } else if (potionData.system.categorie.includes('Repos')) { | ||||
|       this.consommerPotionRepos(potionData); | ||||
|   async consommerPotion(potion) { | ||||
|     if (potion.system.categorie.includes('Soin')) { | ||||
|       this.consommerPotionSoin(potion); | ||||
|     } else if (potion.system.categorie.includes('Repos')) { | ||||
|       this.consommerPotionRepos(potion); | ||||
|     } else { | ||||
|       this.consommerPotionGenerique(potionData); | ||||
|       this.consommerPotionGenerique(potion); | ||||
|     } | ||||
|     await this.diminuerQuantiteObjet(potion.id, 1, { supprimerSiZero: potionData.supprimer }); | ||||
|     await onActionItem() | ||||
|     await this.diminuerQuantiteObjet(potion.id, 1, { supprimerSiZero: potion.supprimer }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { RdDTextEditor } from "../apps/rdd-text-roll-editor.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 { RdDBaseActorSheet } from "./base-actor-sheet.js"; | ||||
|  | ||||
| @@ -26,16 +26,17 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { | ||||
|     // Everything below here is only needed if the sheet is editable | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     this.html.find('.button-encaissement').click(async event => this.actor.encaisser()) | ||||
|     this.html.find('.button-encaissement').click(async event => await this.actor.encaisser()) | ||||
|     this.html.find('.roll-carac').click(async event => { | ||||
|       this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes['data-carac-name'].value))}) | ||||
|     this.html.find('.roll-competence').click(async event => this.actor.rollCompetence(RdDSheetUtility.getItemId(event))); | ||||
|     this.html.find('.endurance-plus').click(async event => this.actor.santeIncDec("endurance", 1)); | ||||
|     this.html.find('.endurance-moins').click(async event => this.actor.santeIncDec("endurance", -1)); | ||||
|       await this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes['data-carac-name'].value)) | ||||
|     }) | ||||
|     this.html.find('.roll-competence').click(async event => await this.actor.rollCompetence(RdDSheetUtility.getItemId(event))); | ||||
|     this.html.find('.endurance-plus').click(async event => await this.actor.santeIncDec("endurance", 1)); | ||||
|     this.html.find('.endurance-moins').click(async event => await this.actor.santeIncDec("endurance", -1)); | ||||
|  | ||||
|     if (game.user.isGM) { | ||||
|       this.html.find('.button-remise-a-neuf').click(async event => this.actor.remiseANeuf()) | ||||
|       this.html.find('.delete-active-effect').click(async event => this.actor.removeEffect(this.html.find(event.currentTarget).parents(".active-effect").data('effect'))); | ||||
|       this.html.find('.button-remise-a-neuf').click(async event => await this.actor.remiseANeuf()) | ||||
|       this.html.find('.delete-active-effect').click(async event => await this.actor.removeEffect(this.html.find(event.currentTarget).parents(".active-effect").data('effect'))); | ||||
|       this.html.find('.enlever-tous-effets').click(async event => await this.actor.removeEffects()); | ||||
|     } | ||||
|     this.html.find('.competence-add').click(async event => | ||||
| @@ -55,14 +56,13 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { | ||||
|     if (this.options.vueDetaillee) { | ||||
|       // On carac change | ||||
|       this.html.find('.carac-value').change(async event => { | ||||
|         let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", ""); | ||||
|         this.actor.updateCarac(caracName, parseInt(event.target.value)); | ||||
|         let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "") | ||||
|         await this.actor.updateCarac(caracName, parseInt(event.target.value)) | ||||
|       }); | ||||
|       // On competence change | ||||
|       this.html.find('.competence-value').change(async event => { | ||||
|         let compName = event.currentTarget.attributes.compname.value; | ||||
|         //console.log("Competence changed :", compName); | ||||
|         this.actor.updateCompetence(compName, parseInt(event.target.value)); | ||||
|         let compName = event.currentTarget.attributes.compname.value | ||||
|         await this.actor.updateCompetence(compName, parseInt(event.target.value)) | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ import { RdDRoll } from "../rdd-roll.js"; | ||||
| import { RdDUtility } from "../rdd-utility.js"; | ||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.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 { RdDItemCompetenceCreature } from "../item-competencecreature.js"; | ||||
| import { RdDItemArme } from "../item-arme.js"; | ||||
| @@ -15,6 +15,7 @@ import { StatusEffects } from "../settings/status-effects.js"; | ||||
| import { Targets } from "../targets.js"; | ||||
| import { RdDConfirm } from "../rdd-confirm.js"; | ||||
| import { RdDCarac } from "../rdd-carac.js"; | ||||
| import { RdDRollResult } from "../rdd-roll-result.js"; | ||||
|  | ||||
| import { ChatUtility } from "../chat-utility.js"; | ||||
| import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js"; | ||||
| @@ -268,19 +269,11 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async openRollDialog({ name, label, template, rollData, callbackAction }) { | ||||
|   async openRollDialog({ name, label, template, rollData, callbacks }) { | ||||
|     const dialog = await RdDRoll.create(this, rollData, | ||||
|       { html: template, close: async html => await this._onCloseRollDialog(html) }, | ||||
|       { | ||||
|         name: name, | ||||
|         label: label, | ||||
|         callbacks: [ | ||||
|           this.createCallbackExperience(), | ||||
|           this.createCallbackAppelAuMoral(), | ||||
|           { action: callbackAction } | ||||
|         ] | ||||
|       }); | ||||
|     dialog.render(true); | ||||
|       { name: name, label: label, callbacks: [this.createCallbackExperience(), this.createCallbackAppelAuMoral()].concat(callbacks) }) | ||||
|     dialog.render(true) | ||||
|     return dialog | ||||
|   } | ||||
|  | ||||
| @@ -299,8 +292,8 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|     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', | ||||
|       label: competence ? 'Jet ' + Grammar.apostrophe('de', competence.name) : `Jet sans compétence (${compName})`, | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', | ||||
|       rollData: { | ||||
|         alias: this.getAlias(), | ||||
|         carac: this.system.carac, | ||||
| @@ -310,7 +303,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|         competence: competence, | ||||
|         show: { title: options?.title ?? '' } | ||||
|       }, | ||||
|       callbackAction: r => this.$onRollCompetence(r, options) | ||||
|       callbacks: [async r => this.$onRollCompetence(r, options)] | ||||
|     }); | ||||
|   } | ||||
|   /** | ||||
| @@ -353,16 +346,14 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|     const selectedCaracName = ['apparence', 'perception', 'force', 'reve'].find(it => carac[it] != undefined) | ||||
|  | ||||
|     await this.openRollDialog({ | ||||
|       name: `jet-${this.id}`, | ||||
|       label: `Jet de ${this.getAlias()}`, | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html', | ||||
|       rollData: { | ||||
|         alias: this.getAlias(), | ||||
|         carac: carac, | ||||
|         selectedCarac: carac[selectedCaracName], | ||||
|         selectedCaracName: selectedCaracName, | ||||
|         competences: this.itemTypes['competence'] | ||||
|       }, | ||||
|       callbackAction: r => this.$onRollCaracResult(r) | ||||
|       callbacks: [{ action: r => this.$onRollCaracResult(r) }] | ||||
|     }) | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -373,32 +364,38 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|     foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false }) | ||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||
|     let selectedCarac = this.getCaracByName(caracName) | ||||
|     console.log("selectedCarac", selectedCarac) | ||||
|     const title = 'Jet ' + Grammar.apostrophe('de', selectedCarac.label); | ||||
|     const jetResistance = options.resistance ? caracName : undefined; | ||||
|     await this.openRollDialog({ | ||||
|       name: 'jet-' + caracName, | ||||
|       label: 'Jet ' + Grammar.apostrophe('de', selectedCarac.label), | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html', | ||||
|       label: title, | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.hbs', | ||||
|       rollData: { | ||||
|         alias: this.getAlias(), | ||||
|         selectedCarac: selectedCarac, | ||||
|         competences: this.itemTypes['competence'], | ||||
|         diffLibre: options.diff ?? 0, | ||||
|         jetResistance: options.resistance ? caracName : undefined | ||||
|         jetResistance: jetResistance | ||||
|       }, | ||||
|       callbackAction: r => this.$onRollCaracResult(r) | ||||
|       callbacks: [{ action: r => this.$onRollCaracResult(r) }] | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async $onRollCaracResult(rollData) { | ||||
|     // Final chat message | ||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html'); | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-general.hbs'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) { | ||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||
|     const competence = this.getCompetence(idOrName); | ||||
|     let rollData = { carac: this.system.carac, competence: competence, arme: options.arme } | ||||
|     let rollData = { | ||||
|       carac: this.system.carac, | ||||
|       competence: competence, | ||||
|       arme: options.arme | ||||
|     } | ||||
|     if (competence.type == ITEM_TYPES.competencecreature) { | ||||
|       const token = RdDUtility.getSelectedToken(this) | ||||
|       const arme = RdDItemCompetenceCreature.armeCreature(competence) | ||||
| @@ -416,18 +413,18 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|       // Transformer la competence de créature | ||||
|       RdDItemCompetenceCreature.setRollDataCreature(rollData) | ||||
|     } | ||||
|  | ||||
|     const dialogLabel = 'Jet ' + Grammar.apostrophe('de', competence.name); | ||||
|     await this.openRollDialog({ | ||||
|       name: 'jet-competence', | ||||
|       label: 'Jet ' + Grammar.apostrophe('de', competence.name), | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', | ||||
|       label: dialogLabel, | ||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', | ||||
|       rollData: rollData, | ||||
|       callbackAction: r => this.$onRollCompetence(r, options) | ||||
|       callbacks: [{ action: r => this.$onRollCompetence(r, options) }] | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   async $onRollCompetence(rollData, options) { | ||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html') | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-competence.hbs') | ||||
|     if (options?.onRollAutomate) { | ||||
|       options.onRollAutomate(rollData); | ||||
|     } | ||||
| @@ -527,7 +524,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|     await ChatUtility.createChatWithRollMode( | ||||
|       { | ||||
|         roll: encaissement.roll, | ||||
|         content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement) | ||||
|         content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.hbs', encaissement) | ||||
|       }, | ||||
|       this | ||||
|     ) | ||||
| @@ -537,7 +534,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|       encaissement.isGM = true | ||||
|       ChatMessage.create({ | ||||
|         whisper: ChatUtility.getGMs(), | ||||
|         content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement) | ||||
|         content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.hbs', encaissement) | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| @@ -562,10 +559,8 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|       await entite.setEntiteReveAccordee(this); | ||||
|     } | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.html'); | ||||
|     if (rolled.isPart) { | ||||
|       await this.appliquerAjoutExperience(rollData, true); | ||||
|     } | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.hbs'); | ||||
|     await this.appliquerAjoutExperience(rollData, true); | ||||
|     return rolled.isSuccess; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -17,20 +17,20 @@ export class RdDBaseActorSangSheet extends RdDBaseActorReveSheet { | ||||
|     // Everything below here is only needed if the sheet is editable | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     this.html.find('.creer-blessure-legere').click(async event => RdDItemBlessure.createBlessure(this.actor, 2)); | ||||
|     this.html.find('.creer-blessure-grave').click(async event => RdDItemBlessure.createBlessure(this.actor, 4)); | ||||
|     this.html.find('.creer-blessure-critique').click(async event => RdDItemBlessure.createBlessure(this.actor, 6)); | ||||
|     this.html.find('.creer-blessure-legere').click(async event => await RdDItemBlessure.createBlessure(this.actor, 2)); | ||||
|     this.html.find('.creer-blessure-grave').click(async event => await RdDItemBlessure.createBlessure(this.actor, 4)); | ||||
|     this.html.find('.creer-blessure-critique').click(async event => await RdDItemBlessure.createBlessure(this.actor, 6)); | ||||
|  | ||||
|     this.html.find('.subir-blessure-contusion').click(async event => RdDItemBlessure.applyFullBlessure(this.actor, 0)); | ||||
|     this.html.find('.subir-blessure-legere').click(async event => RdDItemBlessure.applyFullBlessure(this.actor, 2)); | ||||
|     this.html.find('.subir-blessure-grave').click(async event => RdDItemBlessure.applyFullBlessure(this.actor, 4)); | ||||
|     this.html.find('.subir-blessure-critique').click(async event => RdDItemBlessure.applyFullBlessure(this.actor, 6)); | ||||
|     this.html.find('.subir-blessure-contusion').click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 0)); | ||||
|     this.html.find('.subir-blessure-legere').click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 2)); | ||||
|     this.html.find('.subir-blessure-grave').click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 4)); | ||||
|     this.html.find('.subir-blessure-critique').click(async event => await RdDItemBlessure.applyFullBlessure(this.actor, 6)); | ||||
|  | ||||
|     this.html.find('.jet-vie').click(async event => this.actor.jetDeVie()) | ||||
|     this.html.find('.jet-vie').click(async event => await this.actor.jetDeVie()) | ||||
|     this.html.find('.jet-endurance').click(async event => await this.jetEndurance()) | ||||
|  | ||||
|     this.html.find('.vie-plus').click(async event => this.actor.santeIncDec("vie", 1)) | ||||
|     this.html.find('.vie-moins').click(async event => this.actor.santeIncDec("vie", -1)) | ||||
|     this.html.find('.vie-plus').click(async event => await this.actor.santeIncDec("vie", 1)) | ||||
|     this.html.find('.vie-moins').click(async event => await this.actor.santeIncDec("vie", -1)) | ||||
|   } | ||||
|  | ||||
|   async jetEndurance() { | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { RdDUtility } from "../rdd-utility.js"; | ||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.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 { RdDDice } from "../rdd-dice.js"; | ||||
| import { RdDItemBlessure } from "../item/blessure.js"; | ||||
|   | ||||
| @@ -3,9 +3,11 @@ import { Misc } from "../misc.js"; | ||||
| import { DialogSplitItem } from "../dialog-split-item.js"; | ||||
| import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | ||||
| import { Monnaie } from "../item-monnaie.js"; | ||||
| import { RdDItem, ITEM_TYPES } from "../item.js"; | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { RdDItem } from "../item.js"; | ||||
| import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; | ||||
| import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js"; | ||||
| import { ItemAction } from "../item/item-actions.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| /** | ||||
| @@ -26,7 +28,7 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async getData() { | ||||
|     Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']); | ||||
|     Monnaie.validerMonnaies(this.actor) | ||||
|  | ||||
|     this.actor.computeEtatGeneral(); | ||||
|     let formData = { | ||||
| @@ -42,7 +44,7 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|       effects: this.actor.effects | ||||
|     } | ||||
|  | ||||
|     RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); | ||||
|     RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); | ||||
|     formData.calc = { | ||||
|       fortune: Monnaie.toSolsDeniers(this.actor.getFortune()), | ||||
|       prixTotalEquipement: this.actor.computePrixTotalEquipement(), | ||||
| @@ -54,6 +56,7 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|     formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); | ||||
|     formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature) | ||||
|       .forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it)) | ||||
|  | ||||
|     return formData; | ||||
|   } | ||||
|  | ||||
| @@ -77,109 +80,51 @@ 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 */ | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|     this.html = html; | ||||
|  | ||||
|     this.html.find('.actionItem').click(async event => await ItemAction.onActionItem(event, this.actor, this.options)) | ||||
|     this.html.find('.item-edit').click(async event => await this.itemActionEdit(event)) | ||||
|     this.html.find('.conteneur-name a').click(async event => { | ||||
|       RdDUtility.toggleAfficheContenu(this.getItemId(event)); | ||||
|       this.render(true); | ||||
|     }); | ||||
|     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()); | ||||
|       RdDUtility.toggleAfficheContenu(this.getItemId(event)) | ||||
|       this.render(true) | ||||
|     }) | ||||
|  | ||||
|     this.html.find('.actor-montrer').click(async event => await this.actor.postActorToChat()); | ||||
|  | ||||
|     this.html.find('.recherche') | ||||
|       .each((index, field) => { | ||||
|         this._rechercheSelectArea(field); | ||||
|       }) | ||||
|       .keyup(async event => this._rechercherKeyup(event)) | ||||
|       .change(async event => this._rechercherKeyup(event)); | ||||
|     this.html.find('.recherche').prop("disabled", false); | ||||
|       .change(async event => this._rechercherKeyup(event)) | ||||
|  | ||||
|     this.html.find('.recherche').prop("disabled", false) | ||||
|  | ||||
|     // Everything below here is only needed if the sheet is editable | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     this.html.find('.item-action').click(async event => { | ||||
|       const item = RdDSheetUtility.getItem(event, this.actor); | ||||
|       item?.actionPrincipale(this.actor, async () => this.render()) | ||||
|     }); | ||||
|     this.html.find('.item-equip-armure').click(async event => await this.actor.equiperObjet(this.getItem(event))) | ||||
|     this.html.find('.item-delete').click(async event => await RdDUtility.confirmActorItemDelete(this.getItem(event), this.actor)); | ||||
|     this.html.find('.item-quantite-plus').click(async event => await this.actor.itemQuantiteIncDec(this.getItemId(event), 1)); | ||||
|     this.html.find('.item-quantite-moins').click(async event => await this.actor.itemQuantiteIncDec(this.getItemId(event), -1)); | ||||
|  | ||||
|  | ||||
|     this.html.find('.item-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-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.selectObjetTypeToCreate(); | ||||
|     }); | ||||
|     this.html.find('.nettoyer-conteneurs').click(async event => { | ||||
|       this.actor.nettoyerConteneurs(); | ||||
|     }); | ||||
|     this.html.find('.creer-un-objet').click(async event => await this.selectObjetTypeToCreate()) | ||||
|     this.html.find('.nettoyer-conteneurs').click(async event => await this.actor.nettoyerConteneurs()) | ||||
|  | ||||
|     this.html.find('.vue-detaillee').click(async event => { | ||||
|       this.options.vueDetaillee = !this.options.vueDetaillee; | ||||
|       this.render(true); | ||||
|       this.options.vueDetaillee = !this.options.vueDetaillee | ||||
|       this.render(true) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   itemActionEdit(event) { | ||||
|     const item = this.getItem(event); | ||||
|     return item?.sheet.render(true); | ||||
|   } | ||||
|  | ||||
|   _rechercherKeyup(event) { | ||||
|     const currentTarget = event.currentTarget; | ||||
|     const nouvelleRecherche = this._optionRecherche(currentTarget); | ||||
| @@ -246,7 +191,7 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|   /* -------------------------------------------- */ | ||||
|   async selectObjetTypeToCreate() { | ||||
|     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) { | ||||
|       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 { Grammar } from "../grammar.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 { RdDAudio } from "../rdd-audio.js"; | ||||
| import { RdDConfirm } from "../rdd-confirm.js"; | ||||
| @@ -244,16 +244,19 @@ export class RdDBaseActor extends Actor { | ||||
|   async onUpdateActor(update, options, actorId) { } | ||||
|   async onDeleteItem(item, options, id) { | ||||
|     if (item.isInventaire()) { | ||||
|       this._removeItemFromConteneur(item) | ||||
|       await this._removeItemFromConteneur(item) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   _removeItemFromConteneur(item) { | ||||
|     this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id)) | ||||
|       .forEach(conteneur => { | ||||
|         const nouveauContenu = conteneur.system.contenu.filter(id => id != item.id); | ||||
|         conteneur.update({ 'system.contenu': nouveauContenu }); | ||||
|       }); | ||||
|   async _removeItemFromConteneur(item) { | ||||
|     const updates = this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id)) | ||||
|       .map(conteneur => { | ||||
|         const nouveauContenu = conteneur.system.contenu.filter(id => id != item.id) | ||||
|         return { _id: conteneur.id, 'system.contenu': nouveauContenu } | ||||
|       }) | ||||
|     if (updates.length > 0) { | ||||
|       await this.updateEmbeddedDocuments('Item', updates) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async onTimeChanging(oldTimestamp, newTimestamp) { | ||||
| @@ -414,7 +417,7 @@ export class RdDBaseActor extends Actor { | ||||
|       user: achat.userId, | ||||
|       speaker: { alias: (acheteur ?? vendeur).getAlias() }, | ||||
|       whisper: ChatUtility.getOwners(this), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem) | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.hbs', chatAchatItem) | ||||
|     }); | ||||
|  | ||||
|     if (!achat.vente.quantiteIllimite) { | ||||
| @@ -731,31 +734,26 @@ export class RdDBaseActor extends Actor { | ||||
|       name: this.getAlias(), | ||||
|       system: { description: this.system.description } | ||||
|     } | ||||
|     renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.html', chatData) | ||||
|     renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData) | ||||
|       .then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride))); | ||||
|   } | ||||
|  | ||||
|   actionImpossible(action) { | ||||
|     ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`) | ||||
|  | ||||
|   } | ||||
|  | ||||
|   async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } | ||||
|   async rollAppelChance() { this.actionImpossible("appel à la chance") } | ||||
|   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 incDecItemUse(itemId, inc = 1) { } | ||||
|   getItemUse(itemId) { return 0; } | ||||
|  | ||||
|   async finDeRound(options = { terminer: false }) { } | ||||
|   isActorCombat() { return false } | ||||
|   getCaracInit(competence) { return 0 } | ||||
|  | ||||
|   listActionsCombat() { return [] } | ||||
|   listActionsPossessions() { | ||||
|     return this.itemTypes[ITEM_TYPES.possession] | ||||
|   | ||||
| @@ -12,7 +12,7 @@ export class RdDCommerceSheet extends RdDBaseActorSheet { | ||||
|   /** @override */ | ||||
|   static get defaultOptions() { | ||||
|     return foundry.utils.mergeObject(super.defaultOptions, { | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.html", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.hbs", | ||||
|       width: 600, height: 720, | ||||
|       tabs: [] | ||||
|     }, { inplace: false }) | ||||
| @@ -45,6 +45,7 @@ export class RdDCommerceSheet extends RdDBaseActorSheet { | ||||
|     super.activateListeners(html); | ||||
|  | ||||
|     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; | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ export class RdDCreatureSheet extends RdDBaseActorSangSheet { | ||||
|   /** @override */ | ||||
|   static get defaultOptions() { | ||||
|     return foundry.utils.mergeObject(RdDBaseActorSangSheet.defaultOptions, { | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.hbs", | ||||
|       width: 640, height: 720 | ||||
|     }, { inplace: false }) | ||||
|   } | ||||
| @@ -26,15 +26,15 @@ export class RdDCreatureSheet extends RdDBaseActorSangSheet { | ||||
|     // On competence change | ||||
|     this.html.find('.creature-carac').change(async event => { | ||||
|       let compName = event.currentTarget.attributes.compname.value; | ||||
|       this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value)); | ||||
|       await this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value)); | ||||
|     }); | ||||
|     this.html.find('.creature-niveau').change(async event => { | ||||
|       let compName = event.currentTarget.attributes.compname.value; | ||||
|       this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value)); | ||||
|       await this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value)); | ||||
|     }); | ||||
|     this.html.find('.creature-dommages').change(async event => { | ||||
|       let compName = event.currentTarget.attributes.compname.value; | ||||
|       this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value)); | ||||
|       await this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value)); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { Grammar } from "../grammar.js"; | ||||
| import { ITEM_TYPES } from "../item.js"; | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { LIST_CARAC_AUTRES } from "../rdd-carac.js"; | ||||
| import { RdDBaseActorSang } from "./base-actor-sang.js"; | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet { | ||||
|   /** @override */ | ||||
|   static get defaultOptions() { | ||||
|     return foundry.utils.mergeObject(RdDBaseActorReveSheet.defaultOptions, { | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.hbs", | ||||
|       width: 640, height: 720, | ||||
|     }, { inplace: false }) | ||||
|   } | ||||
| @@ -33,15 +33,15 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet { | ||||
|     // On competence change | ||||
|     this.html.find('.creature-carac').change(async event => { | ||||
|       let compName = event.currentTarget.attributes.compname.value; | ||||
|       this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value)); | ||||
|       await this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value)); | ||||
|     }); | ||||
|     this.html.find('.creature-dommages').change(async event => { | ||||
|       let compName = event.currentTarget.attributes.compname.value; | ||||
|       this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value)); | ||||
|       await this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value)); | ||||
|     }) | ||||
|  | ||||
|     this.html.find('.resonance-add').click(async event => | ||||
|       DialogSelect.select({ | ||||
|       await DialogSelect.select({ | ||||
|         label: "Choisir un acteur à accorder", | ||||
|         list: game.actors.filter(it => it.isPersonnage() && it.prototypeToken.actorLink) | ||||
|       }, | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| 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 { RdDCarac } from "../rdd-carac.js"; | ||||
| import { RdDEncaisser } from "../rdd-roll-encaisser.js"; | ||||
|   | ||||
| @@ -6,8 +6,8 @@ import { ExportScriptarium } from "./export-scriptarium.js"; | ||||
| import { CATEGORIES_COMPETENCES, CATEGORIES_DRACONIC, Mapping } from "./mapping.js"; | ||||
|  | ||||
| export class RdDActorExportSheet extends RdDActorSheet { | ||||
|   static async init() { | ||||
|     await loadTemplates([ | ||||
|   static init() { | ||||
|     loadTemplates([ | ||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs", | ||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs", | ||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs", | ||||
| @@ -23,6 +23,7 @@ export class RdDActorExportSheet extends RdDActorSheet { | ||||
|     ]) | ||||
|     Actors.registerSheet(SYSTEM_RDD, RdDActorExportSheet, { types: ["personnage"], makeDefault: false, label: "Feuille simplifiée" }) | ||||
|   } | ||||
|  | ||||
|   static get defaultOptions() { | ||||
|     return foundry.utils.mergeObject(RdDActorSheet.defaultOptions, { | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/actor-encart-sheet.hbs", | ||||
| @@ -103,13 +104,12 @@ export class RdDActorExportSheet extends RdDActorSheet { | ||||
|     this.html.find('.click-blessure-add').click(async event => | ||||
|       await this.actor.ajouterBlessure({ | ||||
|         gravite: this.html.find(event.currentTarget).data('gravite') | ||||
|         // event.currentTarget.attributes['data-gravite'].value | ||||
|       }) | ||||
|     ) | ||||
|     this.html.find('.button-export').click(async event => { | ||||
|     this.html.find('.button-export').click(async event => await | ||||
|       ExportScriptarium.INSTANCE.exportActors([this.actor], | ||||
|         `${this.actor.uuid}-${this.actor.name}` | ||||
|       ) | ||||
|     }) | ||||
|     ) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { ACTOR_TYPES } from "../../item.js" | ||||
| import { ACTOR_TYPES } from "../../constants.js" | ||||
| import { Misc } from "../../misc.js" | ||||
| import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js" | ||||
| import { Mapping } from "./mapping.js" | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { Grammar } from "../../grammar.js" | ||||
| import { RdDItemArme } from "../../item-arme.js" | ||||
| import { RdDItemCompetence } from "../../item-competence.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 { RdDTimestamp } from "../../time/rdd-timestamp.js" | ||||
| import { RdDBonus } from "../../rdd-bonus.js" | ||||
|   | ||||
| @@ -7,7 +7,7 @@ export class RdDActorVehiculeSheet extends RdDBaseActorSheet { | ||||
|   /** @override */ | ||||
|   static get defaultOptions() { | ||||
|     return foundry.utils.mergeObject(RdDBaseActorSheet.defaultOptions, { | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.hbs", | ||||
|       width: 640, height: 720, | ||||
|     }, { inplace: false }) | ||||
|   } | ||||
| @@ -32,18 +32,10 @@ export class RdDActorVehiculeSheet extends RdDBaseActorSheet { | ||||
|     super.activateListeners(html); | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     this.html.find('.resistance-moins').click(async event => { | ||||
|       this.actor.vehicleIncDec("resistance", -1); | ||||
|     }); | ||||
|     this.html.find('.resistance-plus').click(async event => { | ||||
|       this.actor.vehicleIncDec("resistance", 1); | ||||
|     }); | ||||
|     this.html.find('.structure-moins').click(async event => { | ||||
|       this.actor.vehicleIncDec("structure", -1); | ||||
|     }); | ||||
|     this.html.find('.structure-plus').click(async event => { | ||||
|       this.actor.vehicleIncDec("structure", 1); | ||||
|     }); | ||||
|     this.html.find('.resistance-moins').click(async event => await this.actor.vehicleIncDec("resistance", -1)) | ||||
|     this.html.find('.resistance-plus').click(async event => await this.actor.vehicleIncDec("resistance", 1)) | ||||
|     this.html.find('.structure-moins').click(async event => await this.actor.vehicleIncDec("structure", -1)) | ||||
|     this.html.find('.structure-plus').click(async event => await this.actor.vehicleIncDec("structure", 1)) | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import { Grammar } from "../grammar.js"; | ||||
| import { Misc } from "../misc.js"; | ||||
| import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | ||||
| import { RdDItemTete } from "../item/tete.js"; | ||||
| import { ITEM_TYPES } from "../item.js"; | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
|  | ||||
| const WHITESPACES = "\\s+" | ||||
| const NUMERIC = "[\\+\\-]?\\d+" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import "./xregexp-all.js"; | ||||
| import { SystemCompendiums } from "../settings/system-compendiums.js"; | ||||
| import { ACTOR_TYPES } from "../item.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"; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import "../xregexp-all.js"; | ||||
| import { ACTOR_TYPES, ITEM_TYPES } from "../../item.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"; | ||||
|   | ||||
| @@ -5,7 +5,7 @@ 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_COMP = "(\\/(?<competence>[A-Za-z0-9À-ÖØ-öø-ÿ -]+))?" | ||||
| 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') | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export class TextRollFormula { | ||||
|  | ||||
|   async onRollText(event, actor) { | ||||
|     const node = TextRollManager.getNode(event) | ||||
|     const rollFormula = node.data('roll-formula') | ||||
|     const rollFormula = node.data('formula') | ||||
|     if (rollFormula) { | ||||
|       const roll = new Roll(rollFormula) | ||||
|       await roll.evaluate() | ||||
|   | ||||
| @@ -62,7 +62,6 @@ export class ChatUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|  | ||||
|   static removeMessages(socketData) { | ||||
|     if (Misc.isFirstConnectedGM()) { | ||||
|       ChatUtility.onRemoveMessages(socketData); | ||||
| @@ -97,7 +96,7 @@ export class ChatUtility { | ||||
|         } | ||||
|         break | ||||
|       case "gmroll": | ||||
|         messageData.whisper = ChatUtility.getOwners(actor) | ||||
|         messageData.whisper = actor ? ChatUtility.getOwners(actor) : ChatUtility.getUserAndGMs() | ||||
|         break | ||||
|       case "selfroll": | ||||
|         messageData.whisper = [game.user] | ||||
| @@ -108,7 +107,7 @@ export class ChatUtility { | ||||
|   } | ||||
|  | ||||
|   static getOwners(document) { | ||||
|     return game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) | ||||
|     return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user] | ||||
|   } | ||||
|  | ||||
|   static getUserAndGMs() { | ||||
| @@ -199,7 +198,7 @@ export class ChatUtility { | ||||
|   static async onCreateChatMessage(chatMessage, options, id) { | ||||
|     if (chatMessage.isAuthor) { | ||||
|       await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp()); | ||||
|       await chatMessage.update({ content: await RdDTextEditor.enrichHTML(chatMessage.content, undefined, {showLink:false}) }) | ||||
|       await chatMessage.update({ content: await RdDTextEditor.enrichHTML(chatMessage.content, undefined, { showLink: false }) }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -50,4 +50,59 @@ export const RDD_CONFIG = { | ||||
|     {value: "Rare", label: "Rare"}, | ||||
|     {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', | ||||
| } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ export class DialogChoixXpCarac extends Dialog { | ||||
|     dialogData = foundry.utils.mergeObject(dialogData, { | ||||
|       default: 'appliquer', | ||||
|       buttons: { | ||||
|         'appliquer': { icon:'<i class="fa-solid fa-check"></i>', label: "Ajouter la répartition", callback: it => this.appliquerSelection() } | ||||
|         'appliquer': { icon: '<i class="fa-solid fa-check"></i>', label: "Ajouter la répartition", callback: it => this.appliquerSelection() } | ||||
|       } | ||||
|     }) | ||||
|     super(dialogData, dialogOptions) | ||||
| @@ -37,18 +37,13 @@ export class DialogChoixXpCarac extends Dialog { | ||||
|   } | ||||
|  | ||||
|   activateListeners(html) { | ||||
|     //TODO | ||||
|     super.activateListeners(html) | ||||
|     this.html = html | ||||
|     this.html.find("li.xpCarac-option .xpCarac-moins").click(event => | ||||
|       this.ajouterXp(event, -1) | ||||
|     ) | ||||
|     this.html.find("li.xpCarac-option .xpCarac-plus").click(event => | ||||
|       this.ajouterXp(event, 1) | ||||
|     ) | ||||
|     this.html.find("li.xpCarac-option .xpCarac-moins").click(event => this.ajouterXp(event, -1)) | ||||
|     this.html.find("li.xpCarac-option .xpCarac-plus").click(event => this.ajouterXp(event, 1)) | ||||
|   } | ||||
|  | ||||
|   async ajouterXp(event, delta) { | ||||
|   ajouterXp(event, delta) { | ||||
|     const liCarac = this.html.find(event.currentTarget)?.parents("li.xpCarac-option") | ||||
|     const label = liCarac?.data("carac-label") | ||||
|     const carac = this.caracs.find(c => c.label == label) | ||||
|   | ||||
| @@ -27,7 +27,7 @@ export class DialogChronologie extends Dialog { | ||||
|       timestamp: game.system.rdd.calendrier.timestamp, | ||||
|       dateReel: game.system.rdd.calendrier.dateReel() | ||||
|     }; | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData); | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.hbs", dialogData); | ||||
|     const dialog = new DialogChronologie(html, dialogData); | ||||
|     dialog.render(true); | ||||
|   } | ||||
| @@ -100,7 +100,7 @@ export class DialogChronologie extends Dialog { | ||||
|   } | ||||
|  | ||||
|   async prepareChronologieEntry(journalParameters) { | ||||
|     return await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chronologie-entry.html", journalParameters); | ||||
|     return await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chronologie-entry.hbs", journalParameters); | ||||
|   } | ||||
|  | ||||
|   extractJournalParameters() { | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export class DialogCreateSigneDraconique extends Dialog { | ||||
|         })) | ||||
|     }; | ||||
|  | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.html", dialogData); | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.hbs", dialogData); | ||||
|     new DialogCreateSigneDraconique(dialogData, html) | ||||
|       .render(true); | ||||
|   } | ||||
| @@ -49,7 +49,7 @@ export class DialogCreateSigneDraconique extends Dialog { | ||||
|     actor.createEmbeddedDocuments("Item", [signe]); | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(actor), | ||||
|       content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", { | ||||
|       content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.hbs", { | ||||
|         signe: signe, | ||||
|         alias: actor.getAlias() | ||||
|       }) | ||||
|   | ||||
| @@ -1,88 +1,79 @@ | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDUtility } from "./rdd-utility.js"; | ||||
|  | ||||
| export class DialogFabriquerPotion extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async create(actor, item, onActionItem) { | ||||
|     const min = DialogFabriquerPotion.nombreBrinsMinimum(item); | ||||
|     if (item.system.quantite < min) { | ||||
|       ui.notifications.warn(`Vous avez ${item.system.quantite} brins de ${item.name}, il en faut au moins ${min} pour faire une potion!`); | ||||
|       return; | ||||
|   static async create(actor, item) { | ||||
|     const brinsMinimum = DialogFabriquerPotion.nombreBrinsMinimum(item) | ||||
|     if (item.system.quantite < brinsMinimum) { | ||||
|       ui.notifications.warn(`Vous avez ${item.system.quantite} brins de ${item.name}, il en faut au moins ${brinsMinimum} pour faire une potion!`) | ||||
|       return | ||||
|     } | ||||
|     let potionData = DialogFabriquerPotion.prepareData(actor, item); | ||||
|     const potionData = DialogFabriquerPotion.prepareData(item, brinsMinimum) | ||||
|     const options = { classes: ["dialogfabriquerpotion"], width: 600, height: 160, 'z-index': 99999 } | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-fabriquer-potion-base.hbs', potionData) | ||||
|  | ||||
|     const html = await renderTemplate( 'systems/foundryvtt-reve-de-dragon/templates/dialog-fabriquer-potion-base.html', potionData); | ||||
|  | ||||
|     let options = { classes: ["dialogfabriquerpotion"], width: 600, height: 160, 'z-index': 99999 }; | ||||
|     new DialogFabriquerPotion(actor, potionData, onActionItem, html, options).render(true); | ||||
|     new DialogFabriquerPotion(actor, potionData, html, options).render(true) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static prepareData(actor, item) { | ||||
|     let potionData = foundry.utils.duplicate(item) | ||||
|     potionData.nbBrinsSelect = RdDUtility.buildListOptions( | ||||
|       DialogFabriquerPotion.nombreBrinsMinimum(item), | ||||
|       DialogFabriquerPotion.nombreBrinsOptimal(item)); | ||||
|     potionData.nbBrins = Math.min(potionData.system.quantite, DialogFabriquerPotion.nombreBrinsOptimal(potionData)); | ||||
|     potionData.herbebonus = item.system.niveau; | ||||
|     potionData.buttonName = "Fabriquer"; | ||||
|     return potionData; | ||||
|   static prepareData(item, brinsMinimum) { | ||||
|     const brinsOptimal = DialogFabriquerPotion.nombreBrinsOptimal(item) | ||||
|     return foundry.utils.mergeObject(foundry.utils.duplicate(item), { | ||||
|       nbBrinsSelect: RdDUtility.buildListOptions(brinsMinimum, brinsOptimal), | ||||
|       nbBrins: Math.min(item.system.quantite, brinsOptimal), | ||||
|       herbebonus: item.system.niveau | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   constructor(actor, potionData, onActionItem, html, options) { | ||||
|   constructor(actor, potionData, html, options) { | ||||
|     const conf = { | ||||
|       title: `Fabriquer une potion de ${potionData.system.categorie}`, | ||||
|       content: html, | ||||
|       default: 'fabriquer', | ||||
|       buttons: { | ||||
|         'fabriquer': { | ||||
|           label: potionData.buttonName, callback: it => this.onFabriquer() | ||||
|         } | ||||
|         'fabriquer': { label: "Fabriquer", callback: it => this.onFabriquer() } | ||||
|       } | ||||
|     }; | ||||
|     } | ||||
|     super(conf, options) | ||||
|  | ||||
|     super(conf, options); | ||||
|  | ||||
|     this.actor = actor; | ||||
|     this.potionData = potionData; | ||||
|     this.onActionItem = onActionItem; | ||||
|     this.actor = actor | ||||
|     this.potionData = potionData | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|     this.html = html; | ||||
|     super.activateListeners(html) | ||||
|     this.html = html | ||||
|     this.html.find("[name='nbBrins']").change(event => { | ||||
|       this.potionData.nbBrins = Misc.toInt(event.currentTarget.value); | ||||
|       const brinsManquants = Math.max(0, DialogFabriquerPotion.nombreBrinsOptimal(this.potionData) - this.potionData.nbBrins); | ||||
|       this.potionData.nbBrins = Misc.toInt(event.currentTarget.value) | ||||
|       const brinsManquants = Math.max(0, DialogFabriquerPotion.nombreBrinsOptimal(this.potionData) - this.potionData.nbBrins) | ||||
|       this.potionData.herbebonus = Math.max(0, this.potionData.system.niveau - brinsManquants) | ||||
|     }); | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async onFabriquer() { | ||||
|     await this.html.find("[name='nbBrins']").change(); | ||||
|     await this.actor.fabriquerPotion(this.potionData); | ||||
|     this.close(); | ||||
|     await this.onActionItem() | ||||
|     await this.html.find("[name='nbBrins']").change() | ||||
|     await this.actor.fabriquerPotion(this.potionData) | ||||
|     this.close() | ||||
|   } | ||||
|  | ||||
|   static nombreBrinsMinimum(herbeData) { | ||||
|     switch (herbeData.system.categorie ?? '') { | ||||
|       case "Soin": return 1 + Math.max(0, 12 - 2 * herbeData.system.niveau); | ||||
|       case "Repos": return 1 + Math.max(0, 7 - 2 * herbeData.system.niveau); | ||||
|       case "Soin": return 1 + Math.max(0, 12 - 2 * herbeData.system.niveau) | ||||
|       case "Repos": return 1 + Math.max(0, 7 - 2 * herbeData.system.niveau) | ||||
|     } | ||||
|     return 1; | ||||
|     return 1 | ||||
|   } | ||||
|  | ||||
|   static nombreBrinsOptimal(herbeData) { | ||||
|     switch (herbeData.system.categorie ?? '') { | ||||
|       case "Soin": return 12 - herbeData.system.niveau; | ||||
|       case "Repos": return 7 - herbeData.system.niveau; | ||||
|       case "Soin": return 12 - herbeData.system.niveau | ||||
|       case "Repos": return 7 - herbeData.system.niveau | ||||
|     } | ||||
|     return 1; | ||||
|     return 1 | ||||
|   } | ||||
| } | ||||
| @@ -2,13 +2,13 @@ import { Misc } from "./misc.js"; | ||||
|  | ||||
| export class DialogConsommer extends Dialog { | ||||
|  | ||||
|   static async create(actor, item, onActionItem = async () => { }) { | ||||
|   static async create(actor, item) { | ||||
|     const consommerData = DialogConsommer.prepareData(actor, item); | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData); | ||||
|     return new DialogConsommer(actor, item, consommerData, html, onActionItem) | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.hbs', consommerData); | ||||
|     return new DialogConsommer(actor, item, consommerData, html) | ||||
|   } | ||||
|  | ||||
|   constructor(actor, item, consommerData, html, onActionItem = async () => { }) { | ||||
|   constructor(actor, item, consommerData, html) { | ||||
|     const options = { classes: ["dialogconsommer"], width: 350, height: 'fit-content', 'z-index': 99999 }; | ||||
|     let conf = { | ||||
|       title: consommerData.title, | ||||
| @@ -16,10 +16,7 @@ export class DialogConsommer extends Dialog { | ||||
|       default: consommerData.buttonName, | ||||
|       buttons: { | ||||
|         [consommerData.buttonName]: { | ||||
|           label: consommerData.buttonName, callback: async it => { | ||||
|             await this.onConsommer(); | ||||
|             await onActionItem(); | ||||
|           } | ||||
|           label: consommerData.buttonName, callback: async it => await this.onConsommer() | ||||
|         } | ||||
|       } | ||||
|     }; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ export class DialogSelect extends Dialog { | ||||
|   static extractIdNameImg(it) { return { id: it.id, name: it.name, img: it.img } } | ||||
|  | ||||
|   static async select(selectionData, onSelectChoice) { | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-select.html", selectionData) | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-select.hbs", selectionData) | ||||
|  | ||||
|     const dialogData = { | ||||
|       title: selectionData.title ?? selectionData.label, | ||||
|   | ||||
| @@ -7,7 +7,7 @@ export class DialogSplitItem extends Dialog { | ||||
|       item: item, | ||||
|       choix: { quantite: 1, max: item.system.quantite - 1 } | ||||
|     }; | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-split.html`, splitData); | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-split.hbs`, splitData); | ||||
|     return new DialogSplitItem(item, splitData, html, callback) | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ export class DialogValidationEncaissement extends Dialog { | ||||
|  | ||||
|   static async validerEncaissement(actor, rollData, armure, onEncaisser) { | ||||
|     const encaissement = await RdDUtility.jetEncaissement(actor, rollData, armure, { showDice: HIDE_DICE }); | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', { | ||||
|     const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.hbs', { | ||||
|       actor: actor, | ||||
|       rollData: rollData, | ||||
|       encaissement: encaissement | ||||
|   | ||||
							
								
								
									
										177
									
								
								module/enchantement/dialog-enchanter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								module/enchantement/dialog-enchanter.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| import { ITEM_TYPES } from "../constants.js" | ||||
| import { RdDItemSort } from "../item-sort.js" | ||||
| import { Misc } from "../misc.js" | ||||
|  | ||||
| export const ACTION_ITEM_ENCHANTER =  { | ||||
|   code: 'item-enchanter', label: 'Enchanter', icon: it => 'fa-solid fa-sparkles', | ||||
|   filter: it => game.user.isGM || DialogEnchanter.isEnchantable(it), | ||||
|   optionsFilter: options => options.editable, | ||||
|   action: (item, actor) => DialogEnchanter.enchanter(item) | ||||
| } | ||||
|  | ||||
| export class DialogEnchanter extends Dialog { | ||||
|  | ||||
|   static isEnchantable(item) { | ||||
|     if (!item.isEnchantementPossible) { | ||||
|       return false | ||||
|     } | ||||
|     if (game.user.isGM) { | ||||
|       return true | ||||
|     } | ||||
|     if (item.system.prpermanent) { | ||||
|       return false | ||||
|     } | ||||
|     if (!item.parent?.isHautRevant()) { | ||||
|       return false | ||||
|     } | ||||
|     return RdDItemSort.lancements(RdDItemSort.findEnchantement(item.parent)) > 0 | ||||
|       || RdDItemSort.lancements(RdDItemSort.findPurification(item.parent)) > 0 | ||||
|       || RdDItemSort.lancements(RdDItemSort.findPermanence(item.parent)) > 0 | ||||
|   } | ||||
|  | ||||
|   static dateEnchantement() { | ||||
|     return game.system.rdd.calendrier.getTimestamp().debutJournee().indexDate | ||||
|   } | ||||
|  | ||||
|   static async enchanter(item) { | ||||
|     const actor = item.parent | ||||
|     const sorts = { | ||||
|       enchantement: RdDItemSort.findEnchantement(actor), | ||||
|       purification: RdDItemSort.findPurification(actor), | ||||
|       permanence: RdDItemSort.findPermanence(actor) | ||||
|     } | ||||
|     const nouveauxpr = (sorts.enchantement?.system.lancements ?? []).map(it => it.reve) | ||||
|     const purification = (sorts.purification?.system.lancements ?? []).find(it => true) | ||||
|     const permanence = (sorts.permanence?.system.lancements ?? []).find(it => true) | ||||
|  | ||||
|     const enchanter = { | ||||
|       type: item.type == ITEM_TYPES.potion ? 'potion' : Misc.typeName('Item', item.type), | ||||
|       actor: actor, | ||||
|       item: item, | ||||
|       reve: item.system.pr, | ||||
|       sorts: sorts, | ||||
|       nouveauxpr: nouveauxpr, | ||||
|       purification: purification != undefined, | ||||
|       permanence: permanence != undefined, | ||||
|       options: { isGM: game.user.isGM } | ||||
|     } | ||||
|     if (!item.isEnchantementPossible) { | ||||
|       ui.notifications.info("Seuls les liquides et les gemmes sont enchantables") | ||||
|       return | ||||
|     } | ||||
|     if (item.system.prpermanent) { | ||||
|       ui.notifications.info(`La ${enchanter.type} est permanente`) | ||||
|       return | ||||
|     } | ||||
|     if (!game.user.isGM) { | ||||
|       if (!(actor?.isPersonnage() || actor?.isHautRevant())) { | ||||
|         ui.notifications.info(`Seul un haut rêvant peut enchanter une ${enchanter.type}`) | ||||
|         return | ||||
|       } | ||||
|       if (item.system.quantite != 1) { | ||||
|         ui.notifications.info(`Impossible d'enchanter ${item.system.quantite} ${enchanter.type}s ${item.system.quantite > 1 ? 'en une seule fois' : ''}`) | ||||
|         return | ||||
|       } | ||||
|       if (!(nouveauxpr.length > 0 || purification || permanence)) { | ||||
|         ui.notifications.info("Le haut-rêvant n'a lancé de rituel d'enchantement") | ||||
|         return | ||||
|       } | ||||
|       if (item.system.magique && item.system.purifie && !purification && !permanence) { | ||||
|         ui.notifications.info(`La ${enchanter.type} est déjà enchantée et doit être purifiée`) | ||||
|         return | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/enchantement/dialog-enchanter.hbs`, enchanter) | ||||
|     const dialog = new DialogEnchanter(enchanter, html) | ||||
|     dialog.render(true) | ||||
|   } | ||||
|  | ||||
|   constructor(enchanter, html) { | ||||
|     let options = { classes: ["dialog-enchanter"], width: 400, height: 'fit-content', 'z-index': 99999 } | ||||
|     let conf = { | ||||
|       title: `Enchanter une ${enchanter.type}`, | ||||
|       content: html, | ||||
|       default: "enchanter", | ||||
|       buttons: { | ||||
|         "enchanter": { label: "Enchanter", callback: it => this.onEnchanter() } | ||||
|       } | ||||
|     }; | ||||
|     super(conf, options) | ||||
|     this.html = html | ||||
|     this.enchanter = enchanter | ||||
|     this.item = enchanter.item | ||||
|   } | ||||
|  | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html) | ||||
|     this.html = html | ||||
|     this.html.find("input.enchantement").change(event => this.$onSelectEnchantement(event)) | ||||
|     this.html.find("input.reve").change(event => this.$onForceReve(event)) | ||||
|   } | ||||
|  | ||||
|   $onSelectEnchantement(event) { | ||||
|     const addReve = $(event.currentTarget).data('reve') | ||||
|     this.enchanter.idx = $(event.currentTarget).data('idx') | ||||
|     this.enchanter.reve = this.item.system.pr + Number(addReve) | ||||
|     this.html.find("input.reve").val(this.enchanter.reve) | ||||
|     for (let idx = 0; idx < this.enchanter.nouveauxpr.length; idx++) { | ||||
|       if (idx != this.enchanter.idx) { | ||||
|         this.html.find(`.enchantement[data-idx='${idx}']`).prop("checked", false) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   $onForceReve(event) { | ||||
|     const newReve = Number(event.currentTarget.value) | ||||
|     if (this.enchanter.reve != newReve) { | ||||
|       this.enchanter.idx = undefined | ||||
|     } | ||||
|     this.enchanter.reve = newReve | ||||
|   } | ||||
|  | ||||
|   async onEnchanter() { | ||||
|     foundry.utils.mergeObject(this.enchanter, | ||||
|       { | ||||
|         rendrepurifie: this.html.find("input.rendrepurifie").prop("checked"), | ||||
|         rendrepermanent: this.html.find("input.rendrepermanent").prop("checked"), | ||||
|         addreve: this.enchanter.reve != this.item.system.pr | ||||
|       }, | ||||
|       { inplace: true }) | ||||
|     const item = this.enchanter.item | ||||
|     const actor = this.enchanter.actor | ||||
|  | ||||
|     if (this.enchanter.reve == 0) { | ||||
|       await item.update({ | ||||
|         'system.pr': 0, | ||||
|         'system.magique': false, | ||||
|         'system.purifie': false, | ||||
|         'system.prpermanent': false, | ||||
|         'system.prdate': 0 | ||||
|       }) | ||||
|     } | ||||
|     else { | ||||
|       const isPurifiee = this.enchanter.addreve | ||||
|         ? (this.enchanter.rendrepurifie && (item.item.system.pr == 0 ? true : item.system.purifie)) | ||||
|         : (this.enchanter.rendrepurifie || item.system.purifie) | ||||
|       await item.update({ | ||||
|         'system.pr': this.enchanter.reve, | ||||
|         'system.magique': true, | ||||
|         'system.purifie': isPurifiee, | ||||
|         'system.prpermanent': item.system.prpermanent || this.enchanter.rendrepermanent, | ||||
|         'system.prdate': DialogEnchanter.dateEnchantement() | ||||
|       }) | ||||
|       if (actor) { | ||||
|         if (this.enchanter.rendrepurifie) { | ||||
|           await RdDItemSort.changeLancementsSort(this.enchanter.sorts.purification, it => it.slice(1)); | ||||
|         } | ||||
|         if (this.enchanter.rendrepermanent) { | ||||
|           await RdDItemSort.changeLancementsSort(this.enchanter.sorts.permanence, it => it.slice(1)); | ||||
|         } | ||||
|         if (this.enchanter.addreve && this.enchanter.idx != undefined) { | ||||
|           await RdDItemSort.changeLancementsSort(RdDItemSort.findEnchantement(actor), it => it.toSpliced(this.enchanter.idx, 1)) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { Grammar } from "./grammar.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 { RdDCombatManager } from "./rdd-combat.js"; | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
|  | ||||
| import { ITEM_TYPES } from "./item.js"; | ||||
| import { ITEM_TYPES } from "./constants.js"; | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { RdDCombatManager } from "./rdd-combat.js"; | ||||
|  | ||||
| export const CATEGORIES_COMPETENCES_CREATURES = { | ||||
| @@ -17,9 +18,11 @@ export class RdDItemCompetenceCreature extends Item { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static setRollDataCreature(rollData) { | ||||
|     rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.system.carac_value } } | ||||
|     rollData.competence.system.defaut_carac = "carac_creature" | ||||
|     rollData.selectedCarac = rollData.carac.carac_creature | ||||
|     const code = Grammar.toLowerCaseNoAccentNoSpace(rollData.competence.name); | ||||
|     const selectedCarac = { code: code, label: rollData.competence.name, value: rollData.competence.system.carac_value }; | ||||
|     rollData.carac = { [code]: selectedCarac } | ||||
|     rollData.competence.system.defaut_carac = code | ||||
|     rollData.selectedCarac = selectedCarac | ||||
|     rollData.arme = RdDItemCompetenceCreature.armeCreature(rollData.competence); | ||||
|   } | ||||
|  | ||||
| @@ -29,20 +32,20 @@ export class RdDItemCompetenceCreature extends Item { | ||||
|     if (categorieAttaque != undefined) { | ||||
|       // cloner pour ne pas modifier la compétence | ||||
|       return foundry.utils.mergeObject(item, { | ||||
|           action: item.isCompetencePossession() ? 'possession' : 'attaque', | ||||
|           system: { | ||||
|             competence: item.name, | ||||
|             cac: categorieAttaque == "naturelle" ? "naturelle" : "", | ||||
|             niveau: item.system.niveau, | ||||
|             initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), | ||||
|             equipe: true, | ||||
|             resistance: 100, | ||||
|             dommagesReels: item.system.dommages, | ||||
|             penetration: 0, | ||||
|             force: 0, | ||||
|             rapide: true, | ||||
|           } | ||||
|         }, { inplace: false, }); | ||||
|         action: item.isCompetencePossession() ? 'possession' : 'attaque', | ||||
|         system: { | ||||
|           competence: item.name, | ||||
|           cac: categorieAttaque == "naturelle" ? "naturelle" : "", | ||||
|           niveau: item.system.niveau, | ||||
|           initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), | ||||
|           equipe: true, | ||||
|           resistance: 100, | ||||
|           dommagesReels: item.system.dommages, | ||||
|           penetration: 0, | ||||
|           force: 0, | ||||
|           rapide: true, | ||||
|         } | ||||
|       }, { inplace: false, }); | ||||
|     } | ||||
|     return undefined; | ||||
|   } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { Misc } from "./misc.js"; | ||||
| import { LOG_HEAD } from "./constants.js"; | ||||
| import { ITEM_TYPES, LOG_HEAD } from "./constants.js"; | ||||
|  | ||||
| const MONNAIE_ETAIN = { | ||||
|   name: "Denier (étain)", type: 'monnaie', | ||||
| @@ -70,18 +70,17 @@ export class Monnaie { | ||||
|   } | ||||
|  | ||||
|   static getFortune(monnaies) { | ||||
|     return (monnaies??[]) | ||||
|     return (monnaies ?? []) | ||||
|       .map(m => Number(m.system.cout) * Number(m.system.quantite)) | ||||
|       .reduce(Misc.sum(), 0); | ||||
|   } | ||||
|  | ||||
|   static async optimiserFortune(actor, fortune) { | ||||
|     Monnaie.validerMonnaies(actor) | ||||
|     let resteEnDeniers = Math.round(fortune * 100); | ||||
|     let monnaies = actor.itemTypes['monnaie']; | ||||
|     let updates = []; | ||||
|     Monnaie.validerMonnaies(monnaies, actor); | ||||
|     const updates = [] | ||||
|  | ||||
|     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]) { | ||||
|       const itemPiece = parValeur[valeurDeniers]; | ||||
|       if (itemPiece) { | ||||
| @@ -102,8 +101,11 @@ export class Monnaie { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static validerMonnaies(monnaies, actor = undefined) { | ||||
|     monnaies.filter(it => VALEUR_DENIERS(it.system.cout) == 0) | ||||
|   static validerMonnaies(actor) { | ||||
|     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!`) | ||||
|       .forEach(message => { | ||||
|         ui.notifications.warn(message); | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| import { ACTOR_TYPES, ITEM_TYPES } from "./constants.js"; | ||||
| import { RdDItemSort } from "./item-sort.js"; | ||||
| import { RdDUtility } from "./rdd-utility.js"; | ||||
| import { RdDItemCompetence } from "./item-competence.js"; | ||||
| import { RdDHerbes } from "./rdd-herbes.js"; | ||||
| import { RdDGemme } from "./rdd-gemme.js"; | ||||
| import { HtmlUtility } from "./html-utility.js"; | ||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||
| import { SYSTEM_RDD } from "./constants.js"; | ||||
| @@ -11,9 +10,11 @@ import { SystemCompendiums } from "./settings/system-compendiums.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||
| import { ACTOR_TYPES, ITEM_TYPES, RdDItem } from "./item.js"; | ||||
| import { RdDItem } from "./item.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"; | ||||
| import { RdDItemGemme } from "./item/gemme.js"; | ||||
|  | ||||
| /** | ||||
|  * Extend the basic ItemSheet for RdD specific items | ||||
| @@ -26,8 +27,8 @@ export class RdDItemSheet extends ItemSheet { | ||||
|  | ||||
|   static defaultTemplate(type) { | ||||
|     return type ? | ||||
|       `systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html` : | ||||
|       "systems/foundryvtt-reve-de-dragon/templates/item-sheet.html"; | ||||
|       `systems/foundryvtt-reve-de-dragon/templates/item/${type}-sheet.hbs` : | ||||
|       "systems/foundryvtt-reve-de-dragon/templates/item/item-sheet.hbs"; | ||||
|   } | ||||
|  | ||||
|   static register(sheetClass) { | ||||
| @@ -132,13 +133,7 @@ export class RdDItemSheet extends ItemSheet { | ||||
|       formData.enchantement = await RdDTextEditor.enrichHTML(this.item.system.enchantement, this.item) | ||||
|       formData.sureffet = await RdDTextEditor.enrichHTML(this.item.system.sureffet, this.item) | ||||
|     } | ||||
|     if (this.item.type == ITEM_TYPES.gemme) { | ||||
|       formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); | ||||
|       RdDGemme.calculDataDerivees(this.item) | ||||
|     } | ||||
|     if (this.item.type == ITEM_TYPES.potion) { | ||||
|       RdDHerbes.calculFormData(formData, this.item) | ||||
|     } | ||||
|  | ||||
|     if (this.item.type == ITEM_TYPES.herbe) { | ||||
|       if (formData.options.isOwned && ['Soin', 'Repos'].includes(formData.system.categorie)) { | ||||
|         formData.isIngredientPotionBase = true; | ||||
| @@ -164,23 +159,19 @@ export class RdDItemSheet extends ItemSheet { | ||||
|  | ||||
|     HtmlUtility.showControlWhen(this.html.find(".item-cout"), ReglesOptionnelles.isUsing('afficher-prix-joueurs') | ||||
|       || game.user.isGM | ||||
|       || !this.item.isOwned); | ||||
|     HtmlUtility.showControlWhen(this.html.find(".item-magique"), this.item.isMagique()); | ||||
|       || !this.item.isOwned) | ||||
|     HtmlUtility.showControlWhen(this.html.find(".item-magique"), this.item.isMagique) | ||||
|  | ||||
|     // Everything below here is only needed if the sheet is editable | ||||
|     if (!this.options.editable) return; | ||||
|     if (!this.options.editable) return | ||||
|  | ||||
|     this.form.ondragstart = (event) => this._onDragStart(event); | ||||
|     this.form.ondrop = (event) => this._onDrop(event); | ||||
|     this.form.ondragstart = async event => await this._onDragStart(event) | ||||
|     this.form.ondrop = async event => await this._onDrop(event) | ||||
|  | ||||
|     // Select competence categorie | ||||
|     this.html.find(".categorie").change(event => this._onSelectCategorie(event)); | ||||
|     this.html.find(".categorie").change(async event => await this._onSelectCategorie(event)) | ||||
|  | ||||
|     this.html.find('.sheet-competence-xp').change((event) => { | ||||
|       if (this.item.isCompetencePersonnage()) { | ||||
|         RdDUtility.checkThanatosXP(this.item.name); | ||||
|       } | ||||
|     }); | ||||
|     this.html.find('.sheet-competence-xp').change(event => RdDUtility.checkThanatosXP(this.item)) | ||||
|     this.html.find(".item-cout input[name='system.cout']").change(event => { | ||||
|       if (this.item.isMonnaie()) { | ||||
|         const value = event.currentTarget.value; | ||||
| @@ -189,66 +180,60 @@ export class RdDItemSheet extends ItemSheet { | ||||
|         } | ||||
|       } | ||||
|     }) | ||||
|     this.html.find('.delete-bonus-case').click((event) => { | ||||
|       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('.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('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('.delete-bonus-case').click(async event => await this.supprimerBonusCase(event.currentTarget.attributes['data-deleteCoord'].value)) | ||||
|     this.html.find('.creer-tache-livre').click(async event => await this._getEventActor(event).creerTacheDepuisLivre(this.item)) | ||||
|     this.html.find('.creer-potion-base').click(async event => await this._getEventActor(event).fabriquerDecoctionHerbe(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('.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.actor) { | ||||
|       this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, this.getActionRenderItem())); | ||||
|       this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)); | ||||
|       this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor))); | ||||
|       this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); | ||||
|       this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat()); | ||||
|       this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, this.getActionRenderItem())); | ||||
|       this.html.find('.actionItem').click(async event => await ItemAction.onActionItem(event, this.actor, this.options)) | ||||
|  | ||||
|       // TODO: utiliser un itemAction? | ||||
|       this.html.find('.item-potion-consommer').click(async event => await this.itemActionConsommer(event)) | ||||
|  | ||||
|       this.html.find('.item-quantite-plus').click(async event => { | ||||
|         await this.actor.itemQuantiteIncDec(RdDSheetUtility.getItemId(event), 1) | ||||
|         this.render(); | ||||
|       }); | ||||
|         //this.render() | ||||
|       }) | ||||
|       this.html.find('.item-quantite-moins').click(async event => { | ||||
|         await this.actor.itemQuantiteIncDec(RdDSheetUtility.getItemId(event), -1) | ||||
|         this.render(); | ||||
|       }); | ||||
|         //this.render() | ||||
|       }) | ||||
|     } | ||||
|  | ||||
|     const updateItemTimestamp = (path, timestamp) => this.item.update({ [path]: foundry.utils.duplicate(timestamp) }) | ||||
|  | ||||
|     RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.debut', updateItemTimestamp); | ||||
|     RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.fin', updateItemTimestamp); | ||||
|     RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.debut', updateItemTimestamp) | ||||
|     RdDTimestamp.handleTimestampEditor(this.html, 'system.temporel.fin', updateItemTimestamp) | ||||
|   } | ||||
|  | ||||
|   getActionRenderItem() { | ||||
|     return async () => { | ||||
|       let item = this.item; | ||||
|       while (item) { | ||||
|         await item.sheet?.render() | ||||
|         item = this.actor.getContenant(item) | ||||
|       } | ||||
|   async itemActionDelete(event) { | ||||
|     const item = RdDSheetUtility.getItem(event, this.actor) | ||||
|     return await RdDUtility.confirmActorItemDelete(item, this.actor) | ||||
|   } | ||||
|  | ||||
|   async itemActionConsommer(event) { | ||||
|     const item = RdDSheetUtility.getItem(event, this.actor) | ||||
|     if (item) { | ||||
|       await actor.consommerPotion(item) | ||||
|       await RdDSheetUtility.renderItemBranch(this.actor, item) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   _getEventActor(event) { | ||||
|     let actorId = event.currentTarget.attributes['data-actor-id'].value; | ||||
|     let actor = game.actors.get(actorId); | ||||
|     return actor; | ||||
|   async itemActionSplit(event) { | ||||
|     const item = RdDSheetUtility.getItem(event, this.actor) | ||||
|     if (item) { | ||||
|       await RdDSheetUtility.splitItem(item, this.actor) | ||||
|       await RdDSheetUtility.renderItemBranch(this.actor, item) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   _getEventActor(event) { return game.actors.get(event.currentTarget.attributes['data-actor-id'].value) } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onSelectCategorie(event) { | ||||
| @@ -290,7 +275,7 @@ export class RdDItemSheet extends ItemSheet { | ||||
|         break | ||||
|     } | ||||
|  | ||||
|     return this.item.update(formData); | ||||
|     return this.item.update(formData) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -323,8 +308,9 @@ export class RdDItemSheet extends ItemSheet { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onDragStart(event) { | ||||
|   } | ||||
|   async _onDragStart(event) { } | ||||
|   async _onDropItem(event, dragData) { } | ||||
|   async _onDropActor(event, dragData) { } | ||||
|  | ||||
|   async _onDrop(event) { | ||||
|     // Try to extract the dragData | ||||
| @@ -350,13 +336,7 @@ export class RdDItemSheet extends ItemSheet { | ||||
|         return JSON.parse(eventData); | ||||
|       } | ||||
|     } catch (err) { } | ||||
|     return undefined; | ||||
|   } | ||||
|  | ||||
|   async _onDropItem(event, dragData) { | ||||
|   } | ||||
|  | ||||
|   async _onDropActor(event, dragData) { | ||||
|     return undefined | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { Grammar } from "./grammar.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 { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; | ||||
|  | ||||
| @@ -22,7 +22,21 @@ export class RdDItemSort extends Item { | ||||
|   } | ||||
|  | ||||
|   static addSpaceToNonNumeric(value) { | ||||
|     return Number.isNumeric(value) || ['-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes( String(value).charAt[0]) ? value : ' ' + RdDItemSort.toVar(value) | ||||
|     return Number.isNumeric(value) || ['-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(String(value).charAt[0]) ? value : ' ' + RdDItemSort.toVar(value) | ||||
|   } | ||||
|  | ||||
|   static lancements(sort) { return sort?.system.lancements.length ?? 0 } | ||||
|  | ||||
|   static findEnchantement(actor) { return RdDItemSort.findSort(actor, 'Enchantement', ['Narcos', 'N']) } | ||||
|   static findPermanence(actor) { return RdDItemSort.findSort(actor, 'Permanence', ['Narcos', 'N']) } | ||||
|   static findPurification(actor) { return RdDItemSort.findSort(actor, 'Purification', ['Narcos', 'N']) } | ||||
|  | ||||
|   static findSort(actor, name, draconics) { | ||||
|     return actor.itemTypes[ITEM_TYPES.sort].find(it => Grammar.includesLowerCaseNoAccent(it.name, name) | ||||
|       && (draconics == undefined || draconics.includes(it.system.draconic))) | ||||
|   } | ||||
|   static async changeLancementsSort(sort, changement) { | ||||
|     await sort?.update({ 'system.lancements': changement(sort.system.lancements) }); | ||||
|   } | ||||
|  | ||||
|   static toVar(value) { | ||||
| @@ -151,5 +165,4 @@ export class RdDItemSort extends Item { | ||||
|       .map(it => it.split(':')) | ||||
|       .map(it => { return { case: it[0], bonus: it[1] } }); | ||||
|   } | ||||
|  | ||||
| } | ||||
							
								
								
									
										218
									
								
								module/item.js
									
									
									
									
									
								
							
							
						
						
									
										218
									
								
								module/item.js
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| import { ITEM_TYPES } from "./constants.js"; | ||||
| import { DialogItemVente } from "./achat-vente/dialog-item-vente.js"; | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDHerbes } from "./rdd-herbes.js"; | ||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||
| import { RdDUtility } from "./rdd-utility.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_CREATURES } from "./item-competencecreature.js"; | ||||
| import { BASE_CORPS_A_CORPS, BASE_ESQUIVE } from "./item/base-items.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', | ||||
| } | ||||
| import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js"; | ||||
|  | ||||
| const typesInventaireMateriel = [ | ||||
|   ITEM_TYPES.arme, | ||||
| @@ -95,51 +41,47 @@ const typesObjetsTemporels = [ITEM_TYPES.blessure, ITEM_TYPES.poison, ITEM_TYPES | ||||
| const typesObjetsEquipable = [ITEM_TYPES.arme, ITEM_TYPES.armure, ITEM_TYPES.objet]; | ||||
| const typesEnvironnement = typesInventaireMateriel; | ||||
| const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc | ||||
| const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc | ||||
| densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/  | ||||
|    */ | ||||
|  | ||||
| export const defaultItemImg = { | ||||
|   competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", | ||||
|   competencecreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", | ||||
|   arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp", | ||||
|   armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp", | ||||
|   conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp", | ||||
|   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", | ||||
|   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", | ||||
|   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", | ||||
|   recettecuisine: "systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_1.webp", | ||||
|   musique: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp", | ||||
|   livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp", | ||||
|   maladie: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/maladie.webp", | ||||
|   poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp", | ||||
|   oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp", | ||||
|   meditation: "systems/foundryvtt-reve-de-dragon/icons/meditations_ecrits/meditation_alchimie.webp", | ||||
|   musique: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.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", | ||||
|   signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", | ||||
|   gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", | ||||
|   possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", | ||||
|   sort: "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", | ||||
|   empoignade: "systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp" | ||||
|   tete: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp", | ||||
| } | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| export class RdDItem extends Item { | ||||
|  | ||||
|   static get defaultIcon() { | ||||
|     return undefined; | ||||
|   } | ||||
| @@ -238,7 +180,6 @@ export class RdDItem extends Item { | ||||
|   isCompetenceCreature() { return this.type == ITEM_TYPES.competencecreature } | ||||
|   isConteneur() { return this.type == ITEM_TYPES.conteneur; } | ||||
|   isMonnaie() { return this.type == ITEM_TYPES.monnaie; } | ||||
|   isPotion() { return this.type == ITEM_TYPES.potion; } | ||||
|   isNourritureBoisson() { return this.type == ITEM_TYPES.nourritureboisson; } | ||||
|   isService() { return this.type == ITEM_TYPES.service; } | ||||
|  | ||||
| @@ -277,6 +218,12 @@ export class RdDItem extends Item { | ||||
|     return this.getEnvironnements(milieux).length > 0 | ||||
|   } | ||||
|  | ||||
|   get nameDisplay() { | ||||
|     return this.isMagique ? (this.name + ' <i class="fa-solid fa-sparkles"></i>') : this.name | ||||
|   } | ||||
|  | ||||
|   get isEnchantementPossible() { return false } | ||||
|  | ||||
|   getEnvironnements(milieux = undefined) { | ||||
|     const environnements = this.isInventaire() ? this.system.environnement : undefined; | ||||
|     if (milieux == undefined || !environnements) { | ||||
| @@ -356,13 +303,6 @@ export class RdDItem extends Item { | ||||
|  | ||||
|   getUtilisation() { | ||||
|     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.herbe: case ITEM_TYPES.faune: case ITEM_TYPES.ingredient: case ITEM_TYPES.plante: | ||||
|         switch (this.system.categorie) { | ||||
| @@ -392,7 +332,7 @@ export class RdDItem extends Item { | ||||
|     return this.type == ITEM_TYPES.objet && Grammar.includesLowerCaseNoAccent(this.name, 'cristal alchimique') && this.system.quantite > 0; | ||||
|   } | ||||
|  | ||||
|   isMagique() { | ||||
|   get isMagique() { | ||||
|     return this.system.magique | ||||
|   } | ||||
|  | ||||
| @@ -403,6 +343,7 @@ export class RdDItem extends Item { | ||||
|   isNomLike(texte) { | ||||
|     return Grammar.includesLowerCaseNoAccent(this.name, texte) | ||||
|   } | ||||
|  | ||||
|   isNomTypeLike(texte) { | ||||
|     return this.isNomLike(texte) || Grammar.includesLowerCaseNoAccent(Misc.typeName(this.type, 'Item'), texte) | ||||
|   } | ||||
| @@ -421,8 +362,6 @@ export class RdDItem extends Item { | ||||
|         return 0; | ||||
|       case ITEM_TYPES.herbe: | ||||
|         return this.getEncHerbe(); | ||||
|       case ITEM_TYPES.gemme: | ||||
|         return encPepin * this.system.taille; | ||||
|     } | ||||
|     return Math.max(this.system.encombrement ?? 0, 0); | ||||
|   } | ||||
| @@ -471,68 +410,47 @@ export class RdDItem extends Item { | ||||
|       // appliquer le pourcentage | ||||
|       return this.parent.calculerPrix(this); | ||||
|     } | ||||
|     return this.system.cout; | ||||
|     return this.system.cout | ||||
|   } | ||||
|  | ||||
|   prepareDerivedData() { | ||||
|     super.prepareDerivedData(); | ||||
|     if (this.isInventaire()) { | ||||
|       this.system.encTotal = this.getEncTotal(); | ||||
|       if (this.isPotion()) { | ||||
|         this.prepareDataPotion() | ||||
|       } | ||||
|       this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false }); | ||||
|       this.system.encTotal = this.getEncTotal() | ||||
|     } | ||||
|     this.equipable = this.isEquipable(); | ||||
|     this.equipable = this.isEquipable() | ||||
|   } | ||||
|  | ||||
|   prepareDataPotion() { | ||||
|     const categorie = Grammar.toLowerCaseNoAccent(this.system.categorie); | ||||
|     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); | ||||
|       } | ||||
|     } | ||||
|   itemActions() { | ||||
|     return COMMON_ACTIONS.concat(this.itemSpecificActions()).concat(DEFAULT_ACTIONS) | ||||
|   } | ||||
|  | ||||
|   getActionPrincipale(options = { warnIfNot: true }) { | ||||
|   itemSpecificActions() { | ||||
|     const actions = ITEM_ACTIONS[this.type] ?? [] | ||||
|     return actions | ||||
|   } | ||||
|  | ||||
|   isActionAllowed(code) { | ||||
|     switch (this.type) { | ||||
|       case ITEM_TYPES.conteneur: return 'Ouvrir'; | ||||
|     } | ||||
|     if (this.actor?.isPersonnage()) { | ||||
|       const warn = options.warnIfNot; | ||||
|       if (this.getUtilisationCuisine() == 'brut') { | ||||
|         return 'Cuisiner'; | ||||
|       } | ||||
|       switch (this.type) { | ||||
|         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.livre: return this._actionOrWarnQuantiteZero('Lire', warn); | ||||
|         case ITEM_TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined; | ||||
|         case ITEM_TYPES.queue: case ITEM_TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined; | ||||
|       } | ||||
|     } | ||||
|     return undefined; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   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; | ||||
|       case ITEM_TYPES.possession: | ||||
|       case ITEM_TYPES.empoignade: | ||||
|       case ITEM_TYPES.rencontre: | ||||
|       case ITEM_TYPES.signedraconique: | ||||
|         switch (code) { | ||||
|           case 'item-edit': | ||||
|           case 'item-delete': | ||||
|             return game.user.isGM | ||||
|         } | ||||
|       case ITEM_TYPES.maladie: | ||||
|       case ITEM_TYPES.poison: | ||||
|         return game.user.isGM | ||||
|       case ITEM_TYPES.casetmr: | ||||
|         switch (code) { | ||||
|           case 'item-delete': | ||||
|             return game.user.isGM | ||||
|         } | ||||
|     } | ||||
|     return true | ||||
|   } | ||||
|  | ||||
|   async diminuerQuantite(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) { | ||||
| @@ -673,7 +591,7 @@ export class RdDItem extends Item { | ||||
|   } | ||||
|  | ||||
|   getChatItemTemplate() { | ||||
|     return 'systems/foundryvtt-reve-de-dragon/templates/post-item.html'; | ||||
|     return 'systems/foundryvtt-reve-de-dragon/templates/post-item.hbs'; | ||||
|   } | ||||
|  | ||||
|   static propertyIfDefined(name, val, condition = true) { | ||||
| @@ -805,14 +723,6 @@ export class RdDItem extends Item { | ||||
|     ] | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   _potionChatData() { | ||||
|     return [ | ||||
|       `<b>Rareté</b>: ${this.system.rarete}`, | ||||
|       `<b>Catégorie</b>: ${this.system.categorie}`, | ||||
|       ...this._inventaireTemplateChatData() | ||||
|     ] | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   _queueChatData() { | ||||
|     function label(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 { 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"; | ||||
|   } | ||||
|  | ||||
|   deteriorerArmure(dmg) { | ||||
|   async deteriorerArmure(dmg) { | ||||
|     if (!ReglesOptionnelles.isUsing('deteriorationArmure') || this.system.protection == '0') { | ||||
|       return; | ||||
|     } | ||||
| @@ -22,12 +23,10 @@ export class RdDItemArmure extends RdDItem { | ||||
|       protection = this.calculProtectionDeterioree(); | ||||
|       ChatMessage.create({ content: `Votre armure ${this.name} s'est détériorée, elle protège maintenant de ${protection}` }); | ||||
|     } | ||||
|     this.update({ | ||||
|       system: { | ||||
|         deterioration: deterioration, | ||||
|         protection: protection | ||||
|       } | ||||
|     }); | ||||
|     await this.update({ | ||||
|       'system.deterioration': deterioration, | ||||
|       'system.protection': protection | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   calculProtectionDeterioree() { | ||||
|   | ||||
| @@ -30,7 +30,7 @@ export class RdDItemBlessure extends RdDItem { | ||||
|  | ||||
|   prepareDerivedData() { | ||||
|     super.prepareDerivedData(); | ||||
|     this.system.label = this.getLabelGravite() | ||||
|     this.system.label = RdDItemBlessure.getLabelGravite(this.system.gravite) | ||||
|   } | ||||
|  | ||||
|   static prepareTacheSoin(gravite) { | ||||
| @@ -43,29 +43,32 @@ export class RdDItemBlessure extends RdDItem { | ||||
|   } | ||||
|  | ||||
|   static async applyFullBlessure(actor, gravite) { | ||||
|     const definition = 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)); | ||||
|     } | ||||
|     const definition = foundry.utils.duplicate(RdDItemBlessure.getDefinition(gravite)) | ||||
|  | ||||
|     if (definition.vie) { | ||||
|       lostVie = definition.vie | ||||
|       actor.santeIncDec("vie", definition.vie) | ||||
|       await 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) | ||||
|  | ||||
|     ChatMessage.create({ | ||||
|       content: `Blessure ${definition.label} appliquée à ${actor.name}`+ | ||||
|         `<br>Perte d'endurance : ${lostEndurance}`+ | ||||
|         `<br>Perte de Vie : ${lostVie}`, | ||||
|       //TODO: hbs | ||||
|       content: `Blessure ${definition.label} appliquée à ${actor.name}<br>Perte d'endurance : ${lostEndurance} (${definition.endurance})<br>Perte de Vie : ${definition.vie}`, | ||||
|       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) { | ||||
| @@ -125,10 +128,10 @@ export class RdDItemBlessure extends RdDItem { | ||||
|     } | ||||
|     if (this.system.gravite > 0) { | ||||
|       const update = { system: { premierssoins: { bonus: 0 }, soinscomplets: { bonus: 0 } } } | ||||
|       const gravite = this.system.gravite; | ||||
|       const graviteMoindre = gravite - 2; | ||||
|       const gravite = this.system.gravite | ||||
|       const graviteMoindre = gravite - 2 | ||||
|       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); | ||||
|  | ||||
| @@ -158,11 +161,11 @@ export class RdDItemBlessure extends RdDItem { | ||||
|   } | ||||
|  | ||||
|   peutRetrograder(graviteMoindre, moindres) { | ||||
|     return moindres < RdDItemBlessure.getDefinition(graviteMoindre).max | ||||
|     return moindres < RdDItemBlessure.maxBlessures(graviteMoindre) | ||||
|   } | ||||
|  | ||||
|   async calculerFinPeriodeTemporel(debut) { | ||||
|     return await debut.nouveauJour().addJours(this.system.gravite); | ||||
|     return debut.nouveauJour().addJours(this.system.gravite); | ||||
|   } | ||||
|  | ||||
|   async onFinPeriode(oldTimestamp, newTimestamp) { | ||||
| @@ -182,16 +185,16 @@ export class RdDItemBlessure extends RdDItem { | ||||
|     return `systems/foundryvtt-reve-de-dragon/icons/sante/${soins ? 'blessure-soins' : img}.webp` | ||||
|   } | ||||
|  | ||||
|   getLabelGravite() { | ||||
|     return RdDItemBlessure.getDefinition(this.system.gravite).label | ||||
|   static getLabelGravite(gravite) { | ||||
|     return definitionsBlessures.find(it => it.gravite >= gravite).label | ||||
|   } | ||||
|  | ||||
|   static getDefinition(gravite) { | ||||
|     return definitionsBlessures.sort(Misc.ascending(it => it.gravite)) | ||||
|       .find(it => it.gravite >= gravite); | ||||
|     return definitionsBlessures.find(it => it.gravite >= gravite) | ||||
|   } | ||||
|  | ||||
|   static maxBlessures(gravite) { | ||||
|     return RdDItemBlessure.getDefinition(gravite).max | ||||
|     return definitionsBlessures.find(it => it.gravite >= gravite).max | ||||
|   } | ||||
|  | ||||
|   isContusion() { | ||||
| @@ -216,7 +219,7 @@ export class RdDItemBlessure extends RdDItem { | ||||
|       `<b>Heure et Date</b>: ${new RdDTimestamp(this.system.temporel.debut).formatDateHeure()}`, | ||||
|       RdDItem.propertyIfDefined('Blessé', this.parent?.name, this.parent), | ||||
|       `<b>Localisation</b>: ${this.system.localisation}`, | ||||
|       `<b>Gravité</b>: ${RdDItemBlessure.getDefinition(this.system.gravite).label}`, | ||||
|       `<b>Gravité</b>: ${this.system.label}`, | ||||
|       `<b>Difficulté des soins</b>: ${this.system.difficulte}`, | ||||
|       (this.system.soinscomplets.done ? | ||||
|         `<b>Bonus soins complets</b>: ${this.system.soinscomplets.bonus}` : | ||||
|   | ||||
							
								
								
									
										112
									
								
								module/item/gemme.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								module/item/gemme.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| import { RdDItem } from "../item.js"; | ||||
| import { ACTION_ITEM_ENCHANTER } from "../enchantement/dialog-enchanter.js"; | ||||
|  | ||||
| const tableGemmes = { | ||||
|   "almaze": { label: "Almaze", couleur: "Blanc" }, | ||||
|   "aquafane": { label: "Aquafane", couleur: "Vert Profond" }, | ||||
|   "asterite": { label: "Astérite", couleur: "Bleu, Violet ou Blanc" }, | ||||
|   "cyanolithe": { label: "Cyanolithe", couleur: "Bleu Intense" }, | ||||
|   "larmededragon": { label: "Larme de Dragon", couleur: "Rouge Intense" }, | ||||
|   "muska": { label: "Muska", couleur: "Violet Profond" }, | ||||
|   "nebuleuse": { label: "Nébuleuse", couleur: "Brouillard Intense" }, | ||||
|   "nebuleuse": { label: "Nébuleuse", couleur: "Brouillard Intense, Rose, Vert ou Bleu Pâle" }, | ||||
|   "oeildetigre": { label: "Oeil de Tigre", couleur: "Jaune" }, | ||||
|   "scarlatine": { label: "Scarlatine", couleur: "Rouge Clair ou Orangé" }, | ||||
|   "seliphane": { label: "Séliphane", couleur: "Vert Lumineux" }, | ||||
|   "tournelune": { label: "Tournelune", couleur: "Violet ou Bleu" }, | ||||
|   "zebraide": { label: "Zebraïde", couleur: "Bandes Bicolores, toutes couleurs" } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc | ||||
|  * densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/  | ||||
|  */ | ||||
| const encPepin = 0.0007; | ||||
|  | ||||
| /** | ||||
|  * Item pour gérer les gemmes | ||||
|  */ | ||||
| export class RdDItemGemme extends RdDItem { | ||||
|  | ||||
|   static getGemmeTypeOptionList() { | ||||
|     // TODO: look how to map object key-value pairs | ||||
|     let options = "" | ||||
|     for (let gemmeKey in tableGemmes) { | ||||
|       options += `<option value="${gemmeKey}">${tableGemmes[gemmeKey].label}</option>` | ||||
|     } | ||||
|     return options; | ||||
|   } | ||||
|  | ||||
|   static get defaultIcon() { | ||||
|     return "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp" | ||||
|   } | ||||
|  | ||||
|   get isEnchantementPossible() { | ||||
|     return this.enchantabilite > 0 | ||||
|   } | ||||
|  | ||||
|   get inertie() { return 7 - Number(this.system.purete) } | ||||
|   get enchantabilite() { return this.system.taille - this.inertie } | ||||
|  | ||||
|   getEnc() { | ||||
|     return encPepin * this.system.taille; | ||||
|   } | ||||
|  | ||||
|   itemSpecificActions() { | ||||
|     return [ACTION_ITEM_ENCHANTER] | ||||
|   } | ||||
|  | ||||
|   prepareDerivedData() { | ||||
|     super.prepareDerivedData() | ||||
|     this.system.cout = (this.system.taille * this.system.purete) + this.system.qualite | ||||
|     this.system.inertie = this.inertie | ||||
|     this.system.enchantabilite = this.enchantabilite | ||||
|   } | ||||
|  | ||||
|   getUtilisation() { | ||||
|     switch (this.system.categorie) { | ||||
|       case 'Alchimie': case 'Autre': case 'AlchimieAutre': | ||||
|         // TODO: distinguer les remèdes alchimiques enchantables/non | ||||
|         return 'alchimie' | ||||
|       case 'Cuisine': | ||||
|         return 'cuisine' | ||||
|       case 'Remede': case 'Repos': case 'Soin': | ||||
|         return 'soins' | ||||
|     } | ||||
|     return '' | ||||
|   } | ||||
|  | ||||
|   getProprietes() { | ||||
|     const proprietes = [ | ||||
|       `<b>Taille</b>: ${this.system.taille}`, | ||||
|       `<b>Pureté</b>: ${this.system.purete}`, | ||||
|       `<b>Inertie</b>: ${this.system.inertie}`, | ||||
|       `<b>Enchantabilité</b>: ${this.system.enchantabilite}` | ||||
|     ] | ||||
|     const proprietesMagiques = this.system.magique ? [ | ||||
|       `<b>Enchantée</b> <i class="fa-solid fa-sparkles"></i> ${this.system.purifie ? ', purifiée' : ''} ${this.system.prpermanent ? 'permanente' : ''} `, | ||||
|       `<b>Points de rêve</b>: ${this.system.pr}`, | ||||
|       `<b>Puissance</b>: ${this.system.puissance}`, | ||||
|     ] : [] | ||||
|     return proprietes | ||||
|       .concat(proprietesMagiques) | ||||
|       .concat(this._inventaireTemplateChatData()) | ||||
|       .filter(it => it != undefined) | ||||
|   } | ||||
|  | ||||
|   perteReveChateauDormant() { | ||||
|     if (this.system.magique && !this.system.prpermanent && this.system.pr > 0) { | ||||
|       const nouveauReve = Math.max(this.system.pr - 1, 0) | ||||
|       return { | ||||
|         alias: this.parent.getAlias(), | ||||
|         item: this, | ||||
|         update: { | ||||
|           _id: this.id, | ||||
|           'system.pr': nouveauReve, | ||||
|           'system.magique': nouveauReve > 0 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return undefined | ||||
|   } | ||||
| } | ||||
							
								
								
									
										146
									
								
								module/item/item-actions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								module/item/item-actions.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| 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 _SPLIT = { | ||||
|   code: 'item-split', label: 'Séparer le goupe', icon: it => 'fa-solid fa-unlink', | ||||
|   filter: it => Misc.toInt(it.system.quantite) > 1, | ||||
|   action: (item, actor) => RdDSheetUtility.splitItem(item, actor) | ||||
| } | ||||
|  | ||||
| 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.fabriquerDecoctionHerbe(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 _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, _SPLIT, _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], | ||||
|   queue: [_REFOULER], | ||||
|   sort: [_SORT_RESERVE], | ||||
|   service: [_ACHAT_SERVICE] | ||||
| } | ||||
|  | ||||
|  | ||||
| export class ItemAction { | ||||
|  | ||||
|   static applies(action, item, options) { | ||||
|     return action && item | ||||
|       && 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 async 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))) { | ||||
|       await action.action(item, actor) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -10,7 +10,7 @@ export class RdDItemMaladie extends RdDItem { | ||||
|   } | ||||
|  | ||||
|   async calculerFinPeriodeTemporel(debut) { | ||||
|     return await debut.addPeriode(this.system.periode.nombre, this.system.periode.unite); | ||||
|     return debut.addPeriode(this.system.periode.nombre, this.system.periode.unite); | ||||
|   } | ||||
|  | ||||
|   async onFinPeriode(oldTimestamp, newTimestamp) { | ||||
|   | ||||
| @@ -1,11 +1,8 @@ | ||||
| import { RdDItem } from "../item.js"; | ||||
| import { RdDItemQueue } from "./queue.js"; | ||||
|  | ||||
| export class RdDItemOmbre extends RdDItemQueue { | ||||
|  | ||||
| export class RdDItemOmbre extends RdDItem { | ||||
|   static get defaultIcon() { | ||||
|     return "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp"; | ||||
|   } | ||||
|  | ||||
|   async calculerFinPeriodeTemporel(debut) { | ||||
|     return await debut.appliquerDuree(this.system.duree, this.parent); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,7 @@ export class RdDItemPoison extends RdDItem { | ||||
|   } | ||||
|  | ||||
|   async calculerFinPeriodeTemporel(debut) { | ||||
|     return await debut.addPeriode(this.system.periode.nombre, this.system.periode.unite) ; | ||||
|     return debut.addPeriode(this.system.periode.nombre, this.system.periode.unite) ; | ||||
|   } | ||||
|  | ||||
|   async onFinPeriode(oldTimestamp, newTimestamp) { | ||||
|   | ||||
							
								
								
									
										105
									
								
								module/item/potion.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								module/item/potion.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| import { Grammar } from "../grammar.js"; | ||||
| import { RdDItem } from "../item.js"; | ||||
| import { SystemCompendiums } from "../settings/system-compendiums.js"; | ||||
| import { ACTION_ITEM_ENCHANTER } from "../enchantement/dialog-enchanter.js"; | ||||
|  | ||||
| // --- Actions sur les "potions" | ||||
| 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) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Item pour gérer les potions | ||||
|  */ | ||||
| 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" | ||||
|   } | ||||
|  | ||||
|   get isEnchantementPossible() { | ||||
|     return this.system.etat == 'Liquide' | ||||
|   } | ||||
|  | ||||
|   itemSpecificActions() { | ||||
|     return [_CONSOMMER_POTION, ACTION_ITEM_ENCHANTER] | ||||
|   } | ||||
|  | ||||
|   prepareDerivedData() { | ||||
|     super.prepareDerivedData() | ||||
|     this.system.puissance = this.system.magique ? this.calculPuissance() : 0 | ||||
|   } | ||||
|  | ||||
|   getUtilisation() { | ||||
|     switch (this.system.categorie) { | ||||
|       case 'Alchimie': case 'Autre': case 'AlchimieAutre': | ||||
|         // TODO: distinguer les remèdes alchimiques enchantables/non | ||||
|         return 'alchimie' | ||||
|       case 'Cuisine': | ||||
|         return 'cuisine' | ||||
|       case 'Remede': case 'Repos': case 'Soin': | ||||
|         return 'soins' | ||||
|     } | ||||
|     return '' | ||||
|   } | ||||
|  | ||||
|   getProprietes() { | ||||
|     const proprietes = [ | ||||
|       `<b>Rareté</b>: ${this.system.rarete} `, | ||||
|       `<b>Catégorie</b>: ${this.system.categorie}`, | ||||
|       `<b>Etat</b>: ${this.system.etat}` | ||||
|     ] | ||||
|     const proprietesMagiques = this.system.magique ? [ | ||||
|       `<b>Enchantée</b> <i class="fa-solid fa-sparkles"></i> ${this.system.purifie ? ', purifiée' : ''} ${this.system.prpermanent ? 'permanente' : ''} `, | ||||
|       `<b>Points de rêve</b>: ${this.system.pr}`, | ||||
|     ] : [] | ||||
|     return proprietes | ||||
|       .concat(proprietesMagiques) | ||||
|       .concat(this._inventaireTemplateChatData()) | ||||
|       .filter(it => it != undefined) | ||||
|   } | ||||
|  | ||||
|   perteReveChateauDormant() { | ||||
|     if (this.system.magique && !this.system.prpermanent && this.system.pr > 0) { | ||||
|       const nouveaupr = Math.max(this.system.pr - 1, 0) | ||||
|       return { | ||||
|         alias: this.parent.getAlias(), | ||||
|         item: this, | ||||
|         nouveaupr: nouveaupr, | ||||
|         update: { | ||||
|           _id: this.id, | ||||
|           'system.pr': nouveaupr, | ||||
|           'system.magique': nouveaupr > 0 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return undefined | ||||
|   } | ||||
|  | ||||
|   calculPuissance() { return this.system.herbebonus * this.system.pr } | ||||
|  | ||||
|   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; | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -6,8 +6,9 @@ export class RdDItemQueue extends RdDItem { | ||||
|     return "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp"; | ||||
|   } | ||||
|  | ||||
|   async calculerFinPeriodeTemporel(debut) { | ||||
|   async calculerFinPeriodeTemporel(timestamp) { | ||||
|     // décaller le début pour calcul correct si la queue dure 12h | ||||
|     const debut = timestamp.addMinutes(timestamp.indexMinute == 0 ? -1 : 0); | ||||
|     return await debut.appliquerDuree(this.system.duree, this.parent); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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 { LIST_CARAC_PERSONNAGE, RdDCarac } from "../rdd-carac.js"; | ||||
|  | ||||
| @@ -18,10 +19,12 @@ export class RdDItemRace extends RdDItem { | ||||
|         return false | ||||
|       } | ||||
|     } | ||||
|     const carac = RdDCarac.carac(code) | ||||
|     if (race.isMax(actor, code, value - 1)) { | ||||
|       ui.notifications.warn(`${value} est supérieure au maximum de ${carac.label}`) | ||||
|       return false | ||||
|     if (code == LIST_CARAC_PERSONNAGE.taille.code) { | ||||
|       const carac = RdDCarac.carac(code) | ||||
|       if (race.isMax(actor, code, value - 1)) { | ||||
|         ui.notifications.warn(`${value} est supérieure au maximum de ${carac.label}`) | ||||
|         return false | ||||
|       } | ||||
|     } | ||||
|     return true | ||||
|   } | ||||
| @@ -58,7 +61,8 @@ export class RdDItemRace extends RdDItem { | ||||
|     if (code == LIST_CARAC_PERSONNAGE.force.code) { | ||||
|       return value >= this.getForceMax(actor) | ||||
|     } | ||||
|     const max = foundry.utils.getProperty(this, path) ?? -1 | ||||
|     const pathMax = path.replace(".value", ".max"); | ||||
|     const max = foundry.utils.getProperty(this, pathMax) ?? -1 | ||||
|     return (max > 0 && value >= max) | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -4,9 +4,9 @@ const RARETE_FREQUENTE = { code: 'Frequente', label: 'Fréquente', frequence: 18 | ||||
| const RARETE_RARE = { code: 'Rare', label: 'Rare', frequence: 6, min: 3, max: 12 }; | ||||
| const RARETE_RARISSIME = { code: 'Rarissime', label: 'Rarissime', frequence: 2, min: 1, max: 4 }; | ||||
| const RARETE_INEXISTANT = { code: 'Inexistant', label: 'Inexistant', frequence: 0, min: 0, max: 0 }; | ||||
| const RARETE_EGALE = { code: 'eqal', label: 'Egal', frequence: 1, min: 1, max: 1 }; | ||||
| const RARETE_EGALE = { code: 'egal', label: 'Egal', frequence: 1, min: 1, max: 1 }; | ||||
|  | ||||
| const RARETES = [ | ||||
| export const RARETES = [ | ||||
|   RARETE_COMMUNE, | ||||
|   RARETE_FREQUENTE, | ||||
|   RARETE_RARE, | ||||
|   | ||||
| @@ -74,7 +74,7 @@ export class RdDRencontre extends RdDItem { | ||||
|   } | ||||
|  | ||||
|   async calculerFinPeriodeTemporel(debut) { | ||||
|     return await debut.nouvelleHeure().addHeures(12); | ||||
|     return debut.nouvelleHeure().addHeures(12); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -34,8 +34,8 @@ export class RdDItemInventaireSheet extends RdDItemSheet { | ||||
|     HtmlUtility.showControlWhen(this.html.find("div.description-milieu"), TYPE_ITEMS_NATURELS.includes(this.item.type)); | ||||
|  | ||||
|     if (!this.options.editable) return; | ||||
|     this.html.find("a.preparer-nourriture").click(event => this.preparerNourriture(event)); | ||||
|     this.html.find("a.manger-nourriture").click(event => this.mangerNourriture(event)); | ||||
|     this.html.find("a.preparer-nourriture").click(async event => await this.preparerNourriture(event)); | ||||
|     this.html.find("a.manger-nourriture").click(async event => await this.mangerNourriture(event)); | ||||
|  | ||||
|     this.html.find("input.input-selection-milieu").keypress(event => { | ||||
|       if (event.keyCode == '13') { | ||||
| @@ -43,11 +43,11 @@ export class RdDItemInventaireSheet extends RdDItemSheet { | ||||
|       } | ||||
|       event.stopPropagation(); | ||||
|     }) | ||||
|     this.html.find("a.milieu-add").click(event => this.onAddMilieu(event)); | ||||
|     this.html.find("div.environnement-milieu a.milieu-delete").click(event => this.onDeleteMilieu(event)); | ||||
|     this.html.find("div.environnement-milieu select.environnement-rarete").change(event => this.onChange(event, | ||||
|     this.html.find("a.milieu-add").click(async event => await this.onAddMilieu(event)); | ||||
|     this.html.find("div.environnement-milieu a.milieu-delete").click(async event => await this.onDeleteMilieu(event)); | ||||
|     this.html.find("div.environnement-milieu select.environnement-rarete").change(async event => await this.onChange(event, | ||||
|       updated => this.$changeRarete(event, updated))); | ||||
|     this.html.find("div.environnement-milieu input[name='environnement-frequence']").change(event => this.onChange(event, | ||||
|     this.html.find("div.environnement-milieu input[name='environnement-frequence']").change(async event => await this.onChange(event, | ||||
|       updated => this.$changeFrequence(event, updated))); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -15,15 +15,15 @@ export class RdDBlessureItemSheet extends RdDItemSheet { | ||||
|  | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     this.html.find('[name="premierssoins-done"]').change(async event => { | ||||
|       await this.item.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } }); | ||||
|     }); | ||||
|     this.html.find('[name="soinscomplets-done"]').change(async event => { | ||||
|     this.html.find('[name="premierssoins-done"]').change(async event => | ||||
|       await this.item.setSoinsBlessure({ premierssoins: { done: event.currentTarget.checked } }) | ||||
|     ) | ||||
|     this.html.find('[name="soinscomplets-done"]').change(async event => | ||||
|       await this.item.setSoinsBlessure({ soinscomplets: { done: event.currentTarget.checked } }) | ||||
|     }); | ||||
|     ) | ||||
|     this.html.find('[name="system-gravite"]').change(async event => { | ||||
|       const gravite = Number(event.currentTarget.value) | ||||
|       await this.item.setSoinsBlessure({ gravite: gravite, difficulte: - gravite }) | ||||
|     }); | ||||
|     }) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| 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 { RdDUtility } from "../rdd-utility.js"; | ||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | ||||
| @@ -29,9 +29,10 @@ export class RdDConteneurItemSheet extends RdDItemInventaireSheet { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   prepareConteneurData(formData) { | ||||
|     RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); | ||||
|     RdDUtility.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); | ||||
|     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) { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ export class RdDFauneItemSheet extends RdDItemInventaireSheet { | ||||
|  | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     html.find("a.linked-actor-delete").click(event => this.onDeleteLinkedActor()); | ||||
|     html.find("a.linked-actor-delete").click(async event => await this.onDeleteLinkedActor()); | ||||
|   } | ||||
|  | ||||
|   async _onDropActor(event, dragData) { | ||||
|   | ||||
							
								
								
									
										38
									
								
								module/item/sheet-gemme.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								module/item/sheet-gemme.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { DialogEnchanter } from "../enchantement/dialog-enchanter.js"; | ||||
| import { RdDTimestamp } from "../time/rdd-timestamp.js"; | ||||
| import { RdDItemGemme } from "./gemme.js"; | ||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | ||||
|  | ||||
| export class RdDGemmeItemSheet extends RdDItemInventaireSheet { | ||||
|  | ||||
|   static get ITEM_TYPE() { return ITEM_TYPES.gemme }; | ||||
|  | ||||
|   async getData() { | ||||
|     const formData = foundry.utils.mergeObject(await super.getData(), | ||||
|       { | ||||
|         inertie: this.item.inertie, | ||||
|         enchantabilite: this.item.enchantabilite, | ||||
|         isEnchantementPossible: this.item.isEnchantementPossible, | ||||
|         gemmeTypeList: RdDItemGemme.getGemmeTypeOptionList(), | ||||
|         dateActuelle: game.system.rdd.calendrier.dateCourante(), | ||||
|         enchantement: RdDTimestamp.splitIndexDate(this.item.system.prdate) | ||||
|       }) | ||||
|     return formData | ||||
|   } | ||||
|  | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|  | ||||
|     this.html.find('.item-enchanter').click((event) => DialogEnchanter.enchanter(this.item)) | ||||
|  | ||||
|     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}`) | ||||
|     }); | ||||
|  | ||||
|   } | ||||
| } | ||||
							
								
								
									
										57
									
								
								module/item/sheet-potion.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								module/item/sheet-potion.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { DialogEnchanter } from "../enchantement/dialog-enchanter.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); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async getData() { | ||||
|     const formData = await super.getData() | ||||
|     formData.isEnchantementPossible = this.item.isEnchantementPossible | ||||
|     formData.isSoins = this.item.categorie == 'Soin' | ||||
|     formData.isRepos = this.item.categorie == '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.item.system.prdate) | ||||
|     return formData | ||||
|   } | ||||
|  | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|  | ||||
|     this.html.find('.item-enchanter').click((event) => DialogEnchanter.enchanter(this.item)) | ||||
|  | ||||
|     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}`) | ||||
|     }); | ||||
|  | ||||
|   } | ||||
| } | ||||
| @@ -44,8 +44,8 @@ export class RdDRencontreItemSheet extends RdDItemSheet { | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|     if (!this.options.editable) return; | ||||
|     this.html.find("a.effet-add").click(event => this.onAddEffet(event)); | ||||
|     this.html.find("a.effet-delete").click(event => this.onDeleteEffet(event)); | ||||
|     this.html.find("a.effet-add").click(async event => await this.onAddEffet(event)); | ||||
|     this.html.find("a.effet-delete").click(async event => await this.onDeleteEffet(event)); | ||||
|   } | ||||
|  | ||||
|   async onAddEffet(event) { | ||||
|   | ||||
| @@ -36,9 +36,9 @@ export class RdDSigneDraconiqueItemSheet extends RdDItemSheet { | ||||
|  | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     html.find(".signe-aleatoire").click(event => this.setSigneAleatoire()); | ||||
|     html.find("input.select-tmr").change(event => this.onSelectTmr(event)); | ||||
|     html.find(".signe-xp-sort").change(event => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value))); | ||||
|     html.find(".signe-aleatoire").click(async event => await this.setSigneAleatoire()); | ||||
|     html.find("input.select-tmr").change(async event => await this.onSelectTmr(event)); | ||||
|     html.find(".signe-xp-sort").change(async event => await this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value))); | ||||
|   } | ||||
|  | ||||
|   async setSigneAleatoire() { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { RdDItem } from "../item.js"; | ||||
| import { Grammar } from "../grammar.js" | ||||
| import { ITEM_TYPES, RdDItem } from "../item.js" | ||||
| import { SystemCompendiums } from "../settings/system-compendiums.js" | ||||
|  | ||||
| const DON_HAUT_REVE = "Don de Haut-Rêve" | ||||
|   | ||||
| @@ -2,7 +2,8 @@ import { RdDBaseActor } from "./actor/base-actor.js"; | ||||
| import { LOG_HEAD, SYSTEM_RDD } from "./constants.js"; | ||||
| import { Grammar } from "./grammar.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 { RdDRaretes } from "./item/raretes.js"; | ||||
| import { VOIES_DRACONIC } from "./item-sort.js"; | ||||
| @@ -588,6 +589,55 @@ class _12_0_32_MigrationRaces extends Migration { | ||||
|   } | ||||
| } | ||||
|  | ||||
| class _12_0_37_MigrationAlchimieEtat extends Migration { | ||||
|   get code() { return "migration-alchimie-etat" } | ||||
|   get version() { return "12.0.37" } | ||||
|  | ||||
|   async migrate() { | ||||
|     await this.applyItemsUpdates(items => items | ||||
|       .filter(it => [ITEM_TYPES.potion].includes(it.type)) | ||||
|       .map(it => this.migratePotion(it)) | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   mappingCategorie(categorie) { | ||||
|     switch (categorie) { | ||||
|       case 'AlchimieEnchante': return 'Alchimie' | ||||
|       case 'ReposEnchante': return 'Repos' | ||||
|       case 'SoinEnchante': return 'Soin' | ||||
|       case 'AutreEnchante': return 'Autre' | ||||
|     } | ||||
|     return categorie | ||||
|   } | ||||
|  | ||||
|   mappingEtat(categorie) { | ||||
|     return ['Alchimie', 'Repos', 'Soin', 'Autre'].includes(categorie) ? 'Liquide' : 'Autre' | ||||
|   } | ||||
|  | ||||
|   migratePotion(potion) { | ||||
|     const newCategorie = this.mappingCategorie(potion.system.categorie) | ||||
|     return { | ||||
|       _id: potion.id, | ||||
|       'system.etat': this.mappingEtat(potion.system.categorie), | ||||
|       'system.magique': potion.system.pr > 0, | ||||
|       'system.categorie': newCategorie | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| class _12_0_38_TachesEcriture extends Migration { | ||||
|   get code() { return "migration-tache-ecriture" } | ||||
|   get version() { return "12.0.38" } | ||||
|  | ||||
|   async migrate() { | ||||
|     await this.applyItemsUpdates(items => items | ||||
|       .filter(it => [ITEM_TYPES.tache, ITEM_TYPES.livre, ITEM_TYPES.oeuvre, ITEM_TYPES.meditation].includes(it.type) ) | ||||
|       .filter(it => it.system.competence == 'Ecriture') | ||||
|       .map(it => { return { _id: it.id, 'system.competence': 'Écriture' } }) | ||||
|     ) | ||||
|   } | ||||
| } | ||||
|  | ||||
| export class Migrations { | ||||
|   static getMigrations() { | ||||
|     return [ | ||||
| @@ -609,6 +659,8 @@ export class Migrations { | ||||
|       new _11_2_20_MigrationAstrologie(), | ||||
|       new _12_0_26_MigrationVoieSorts(), | ||||
|       new _12_0_32_MigrationRaces(), | ||||
|       new _12_0_37_MigrationAlchimieEtat(), | ||||
|       new _12_0_38_TachesEcriture() | ||||
|     ]; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -238,7 +238,7 @@ export class Misc { | ||||
|   /* -------------------------------------------- */ | ||||
|   static findFirstLike(value, elements, options = {}) { | ||||
|     options = foundry.utils.mergeObject(DEFAULT_FIND_OPTIONS, options, { overwrite: true, inplace: false }); | ||||
|     const subset = this.findAllLike(value, elements, options); | ||||
|     const subset = this.findAllLike(value, elements, options) | ||||
|     if (subset.length == 0) { | ||||
|       console.log(`Aucune ${options.description} pour ${value}`); | ||||
|       return undefined | ||||
| @@ -263,7 +263,8 @@ export class Misc { | ||||
|     } | ||||
|     value = Grammar.toLowerCaseNoAccent(value); | ||||
|     const subset = elements.filter(options.preFilter) | ||||
|       .filter(it => Grammar.toLowerCaseNoAccent(options.mapper(it))?.includes(value)); | ||||
|       .filter(it => Grammar.toLowerCaseNoAccent(options.mapper(it))?.includes(value)) | ||||
|       .sort(Misc.ascending(it => options.mapper(it))) | ||||
|     if (subset.length == 0) { | ||||
|       options.onMessage(`Pas de ${options.description} correspondant à ${value}`); | ||||
|     } | ||||
|   | ||||
| @@ -57,7 +57,7 @@ export const LIST_CARAC_PERSONNAGE = { | ||||
| } | ||||
|  | ||||
| export const LIST_CARAC_AUTRES = { | ||||
|   'perception': { code: 'perception', label: 'Perception',  path: 'system.carac.perception.value' }, | ||||
|   'perception': { code: 'perception', label: 'Perception', path: 'system.carac.perception.value' }, | ||||
| } | ||||
|  | ||||
| const LIST_CARAC_DERIVEE = { | ||||
| @@ -75,12 +75,12 @@ const LIST_CARAC_ROLL = Object.values(LIST_CARAC_PERSONNAGE).filter(it => it.isC | ||||
|  | ||||
| export class RdDCarac { | ||||
|  | ||||
|   static caracDetails(name) { | ||||
|   static caracDetails(name, options = { onMessage: undefined }) { | ||||
|     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' }) | ||||
|     return Misc.findFirstLike(name, LIST_CARAC_ROLL, { mapper: it => it.label, description: 'caractéristique', onMessage: options.onMessage }) | ||||
|   } | ||||
|  | ||||
|   static carac(code) { | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||
| import { STATUSES } from "./settings/status-effects.js"; | ||||
| import { Targets } from "./targets.js"; | ||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| const premierRoundInit = [ | ||||
| @@ -361,7 +362,7 @@ export class RdDCombatManager extends Combat { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static listActionsActorCombatant( actor) { | ||||
|   static listActionsActorCombatant(actor) { | ||||
|     const possessions = actor.listActionsPossessions() | ||||
|     const actions = possessions.length > 0 | ||||
|       ? possessions | ||||
| @@ -542,7 +543,7 @@ export class RdDCombat { | ||||
|       case '.particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); | ||||
|       case '.parer-button': return this.parade(attackerRoll, armeParadeId); | ||||
|       case '.esquiver-button': return this.esquive(attackerRoll, compId, competence); | ||||
|       case '0encaisser-button': return this.encaisser(attackerRoll, defenderRoll); | ||||
|       case '.encaisser-button': return this.encaisser(attackerRoll, defenderRoll); | ||||
|       case '.echec-total-attaque': return this._onEchecTotal(attackerRoll); | ||||
|  | ||||
|       case '.appel-chance-attaque': return this.attacker.rollAppelChance( | ||||
| @@ -667,7 +668,7 @@ export class RdDCombat { | ||||
|         const activite = this._ajustementMouvement(this.defender) | ||||
|         const total = [portee, taille, activite].map(it => it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0) | ||||
|         ChatMessage.create({ | ||||
|           content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', { | ||||
|           content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.hbs', { | ||||
|             rollData: rollData, | ||||
|             attacker: _token, | ||||
|             isVisible: isVisible, | ||||
| @@ -734,7 +735,7 @@ export class RdDCombat { | ||||
|     await this.proposerAjustementTirLancer(rollData) | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this.attacker, rollData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs' }, | ||||
|       { | ||||
|         name: 'jet-attaque', | ||||
|         label: 'Attaque: ' + (arme?.name ?? competence.name), | ||||
| @@ -742,16 +743,23 @@ export class RdDCombat { | ||||
|           this.attacker.createCallbackExperience(), | ||||
|           this.attacker.createCallbackAppelAuMoral(), | ||||
|           { action: r => this.removeChatMessageActionsPasseArme(r.passeArme) }, | ||||
|           { condition: r => arme && !RdDCombat.isParticuliere(r), action: r => this.attacker.incDecItemUse(arme._id) }, | ||||
|           { condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) }, | ||||
|           { condition: RdDCombat.isParticuliere, action: r => this._onAttaqueParticuliere(r) }, | ||||
|           { condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) }, | ||||
|           { condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) }, | ||||
|           { action: r => this._increaseItemUse(r, arme) }, | ||||
|           { action: r => this._onAttaqueNormale(r) }, | ||||
|           { action: r => this._onAttaqueParticuliere(r) }, | ||||
|           { action: r => this._onAttaqueEchec(r) }, | ||||
|           { action: r => this._onAttaqueEchecTotal(r) }, | ||||
|         ] | ||||
|       }); | ||||
|     dialog.render(true); | ||||
|   } | ||||
|  | ||||
|   _increaseItemUse(rollData, arme) { | ||||
|     if (!arme || RdDCombat.isParticuliere(rollData)) { | ||||
|       return | ||||
|     } | ||||
|     this.attacker.incDecItemUse(arme._id) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _prepareAttaque(competence, arme) { | ||||
|     let rollData = { | ||||
| @@ -784,7 +792,9 @@ export class RdDCombat { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onAttaqueParticuliere(rollData) { | ||||
|  | ||||
|     if (!RdDCombat.isParticuliere(rollData)) { | ||||
|       return | ||||
|     } | ||||
|     const isMeleeDiffNegative = (rollData.competence.type == 'competencecreature' || rollData.selectedCarac.label == "Mêlée") && rollData.diffLibre < 0; | ||||
|     // force toujours, sauf empoignade | ||||
|     // finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum | ||||
| @@ -806,7 +816,7 @@ export class RdDCombat { | ||||
|     const choixParticuliere = await ChatMessage.create({ | ||||
|       alias: this.attacker.getAlias(), | ||||
|       whisper: ChatUtility.getOwners(this.attacker), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.hbs', { | ||||
|         alias: this.attacker.getAlias(), | ||||
|         attackerId: this.attackerId, | ||||
|         attackerToken: this.attackerToken, | ||||
| @@ -822,6 +832,12 @@ export class RdDCombat { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onAttaqueNormale(attackerRoll) { | ||||
|     if (!RdDCombat.isReussite(attackerRoll)) { | ||||
|       return | ||||
|     } | ||||
|     if (RdDCombat.isParticuliere(attackerRoll) && attackerRoll.particuliere == undefined) { | ||||
|       return | ||||
|     } | ||||
|     console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll); | ||||
|  | ||||
|     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); | ||||
| @@ -830,13 +846,13 @@ export class RdDCombat { | ||||
|       cible: this.defender?.getAlias() ?? 'la cible', | ||||
|       isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') | ||||
|     } | ||||
|     await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html'); | ||||
|     await RdDRollResult.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.hbs'); | ||||
|  | ||||
|     if (!await this.attacker.accorder(this.defender, 'avant-defense')) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     if (this.target) { | ||||
|     if (this.defender) { | ||||
|       await this._sendMessageDefense(attackerRoll, defenderRoll); | ||||
|     } | ||||
|   } | ||||
| @@ -895,7 +911,7 @@ export class RdDCombat { | ||||
|       speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), | ||||
|       alias: this.attacker?.getAlias(), | ||||
|       whisper: ChatUtility.getOwners(this.defender), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', paramDemandeDefense), | ||||
|     }); | ||||
|     // flag pour garder les jets d'attaque/defense | ||||
|     ChatUtility.setMessageData(choixDefense, 'defender-roll', defenderRoll); | ||||
| @@ -938,9 +954,12 @@ export class RdDCombat { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onAttaqueEchecTotal(attackerRoll) { | ||||
|     if (!RdDCombat.isEchecTotal(attackerRoll)) { | ||||
|       return | ||||
|     } | ||||
|     const choixEchecTotal = await ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this.attacker), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.hbs', { | ||||
|         attackerId: this.attackerId, | ||||
|         attacker: this.attacker, | ||||
|         attackerToken: this.attackerToken, | ||||
| @@ -965,8 +984,12 @@ export class RdDCombat { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onAttaqueEchec(rollData) { | ||||
|     if (!RdDCombat.isEchec(rollData)) { | ||||
|       return | ||||
|     } | ||||
|     console.log("RdDCombat.onAttaqueEchec >>>", rollData); | ||||
|     await RdDResolutionTable.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.html'); | ||||
|     await RdDRollResult.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.hbs'); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -979,7 +1002,7 @@ export class RdDCombat { | ||||
|  | ||||
|     this.removeChatMessageActionsPasseArme(rollData.passeArme); | ||||
|     rollData.particuliere = choix; | ||||
|     await this._onAttaqueNormale(rollData); | ||||
|     await this._onAttaqueNormale(rollData) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -995,7 +1018,7 @@ export class RdDCombat { | ||||
|     let rollData = this._prepareParade(attackerRoll, arme, competence); | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this.defender, rollData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs' }, | ||||
|       { | ||||
|         name: 'jet-parade', | ||||
|         label: 'Parade: ' + (arme ? arme.name : rollData.competence.name), | ||||
| @@ -1054,7 +1077,7 @@ export class RdDCombat { | ||||
|  | ||||
|     await this.computeRecul(defenderRoll); | ||||
|     await this.computeDeteriorationArme(defenderRoll); | ||||
|     await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html'); | ||||
|     await RdDRollResult.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.hbs'); | ||||
|     this.removeChatMessageActionsPasseArme(defenderRoll.passeArme); | ||||
|   } | ||||
|  | ||||
| @@ -1062,7 +1085,7 @@ export class RdDCombat { | ||||
|   async _onParadeEchec(defenderRoll) { | ||||
|     console.log("RdDCombat._onParadeEchec >>>", defenderRoll); | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html'); | ||||
|     await RdDRollResult.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.hbs'); | ||||
|  | ||||
|     this.removeChatMessageActionsPasseArme(defenderRoll.passeArme); | ||||
|     this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true }); | ||||
| @@ -1079,7 +1102,7 @@ export class RdDCombat { | ||||
|     let rollData = this._prepareEsquive(attackerRoll, esquive); | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this.defender, rollData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs' }, | ||||
|       { | ||||
|         name: 'jet-esquive', | ||||
|         label: 'Esquiver', | ||||
| @@ -1129,7 +1152,7 @@ export class RdDCombat { | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onEsquiveNormale(defenderRoll) { | ||||
|     console.log("RdDCombat._onEsquiveNormal >>>", defenderRoll); | ||||
|     await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html'); | ||||
|     await RdDRollResult.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.hbs'); | ||||
|     this.removeChatMessageActionsPasseArme(defenderRoll.passeArme); | ||||
|   } | ||||
|  | ||||
| @@ -1137,7 +1160,7 @@ export class RdDCombat { | ||||
|   async _onEsquiveEchec(defenderRoll) { | ||||
|     console.log("RdDCombat._onEsquiveEchec >>>", defenderRoll); | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html'); | ||||
|     await RdDRollResult.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.hbs'); | ||||
|  | ||||
|     this.removeChatMessageActionsPasseArme(defenderRoll.passeArme); | ||||
|     this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true }) | ||||
|   | ||||
| @@ -18,6 +18,7 @@ import { FenetreRechercheTirage } from "./tirage/fenetre-recherche-tirage.js"; | ||||
| import { TMRUtility } from "./tmr-utility.js"; | ||||
| import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js"; | ||||
| import { ChatUtility } from "./chat-utility.js"; | ||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | ||||
|  | ||||
| const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/; | ||||
|  | ||||
| @@ -128,6 +129,16 @@ export class RdDCommands { | ||||
|           <br><strong>/rdd vol déser +2</strong> effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés | ||||
|           ` | ||||
|     }); | ||||
|     this.registerCommand({ | ||||
|       path: ["/jet"], func: (content, msg, params) => this.askRollRdd(msg, params), | ||||
|       descr: `Poste dans le tchat un jet de dés à effectuer. Exemples: | ||||
|           <br><strong>/jet Vue Vigilance</strong> poste une demande de jet de VUE / Vigilance à 0 | ||||
|           <br><strong>/jet Vue</strong> poste une demande de jet de VUE à 0 | ||||
|           <br><strong>/jet Vue -2</strong> poste une demande de jet de VUE à -2 | ||||
|           <br><strong>/jet Vue Vigilance -2</strong> poste une demande de jet de VUE / Vigilance à -2 | ||||
|           <br><strong>/jet vol déser +2</strong> poste une demande de jet de VOLONTÉ / Survie en désert à +2 | ||||
|           ` | ||||
|     }); | ||||
|     this.registerCommand({ path: ["/ddr"], func: (content, msg, params) => this.rollDeDraconique(msg), descr: "Lance un Dé Draconique" }); | ||||
|  | ||||
|     this.registerCommand({ | ||||
| @@ -256,7 +267,7 @@ export class RdDCommands { | ||||
|     let commands = [] | ||||
|     this._buildSubTableHelp(commands, table ?? this.commandsTable); | ||||
|  | ||||
|     let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: commands }); | ||||
|     let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.hbs", { commands: commands }); | ||||
|     let d = new Dialog( | ||||
|       { | ||||
|         title: "Commandes disponibles dans le tchat", | ||||
| @@ -339,6 +350,25 @@ export class RdDCommands { | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   async askRollRdd(msg, params) { | ||||
|     if (params.length == 0) { | ||||
|       return false | ||||
|     } | ||||
|     else { | ||||
|       let length = params.length; | ||||
|       let diff = Number(params[length - 1]); | ||||
|       if (Number.isInteger(Number(diff))) { | ||||
|         length--; | ||||
|       } | ||||
|       else { | ||||
|         diff = 0; | ||||
|       } | ||||
|  | ||||
|       const carac = params[0]; | ||||
|       const competence = length > 1 ? '/' + Misc.join(params.slice(1, length), ' ') : '' | ||||
|       ChatMessage.create({ content: `@roll[${carac}${competence}/${diff}]` }) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollRdDNumeric(msg, carac, diff, significative = false) { | ||||
| @@ -349,7 +379,7 @@ export class RdDCommands { | ||||
|       show: { title: "Table de résolution" } | ||||
|     }; | ||||
|     await RdDResolutionTable.rollData(rollData); | ||||
|     return RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData)); | ||||
|     return RdDCommands._chatAnswer(msg, await RdDRollResult.buildRollDataHtml(rollData)); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -361,13 +391,14 @@ export class RdDCommands { | ||||
|   async getTMRAleatoire(msg, params) { | ||||
|     if (params.length < 2) { | ||||
|       let type = params[0] | ||||
|       const solvedTerrain = TMRUtility.findTMRLike(type)?.type | ||||
|       if (solvedTerrain){ | ||||
|         const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == solvedTerrain) : (it => true)) | ||||
|       const solvedTerrain = type ? TMRUtility.findTMRLike(type)?.type : undefined | ||||
|       const filter = solvedTerrain ? (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 false; | ||||
|     return false | ||||
|   } | ||||
|  | ||||
|   async findTMR(msg, params) { | ||||
|   | ||||
| @@ -1,13 +1,10 @@ | ||||
| /* -------------------------------------------- */ | ||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||
| import { RdDRoll } from "./rdd-roll.js"; | ||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||
| import { ChatUtility } from "./chat-utility.js"; | ||||
| import { STATUSES } from "./settings/status-effects.js"; | ||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||
| import { ITEM_TYPES } from "./item.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| import { ITEM_TYPES } from "./constants.js"; | ||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| export class RdDEmpoignade { | ||||
| @@ -160,7 +157,7 @@ export class RdDEmpoignade { | ||||
|     if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) { | ||||
|       ChatUtility.createChatWithRollMode( | ||||
|         { | ||||
|           content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.html`, { attacker: attacker, defender: defender }) | ||||
|           content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.hbs`, { attacker: attacker, defender: defender }) | ||||
|         }, | ||||
|         attacker | ||||
|       ) | ||||
| @@ -193,7 +190,7 @@ export class RdDEmpoignade { | ||||
|     } | ||||
|     if (empoignade.system.pointsemp >= 2) { | ||||
|       if (!empoignade.system.ausol) { | ||||
|         let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer.html'); | ||||
|         let msg = await RdDRollResult.displayRollData(rollData, attacker, 'chat-empoignade-entrainer.hbs'); | ||||
|         RdDEmpoignade.$storeRollEmpoignade(msg, rollData); | ||||
|       } | ||||
|     } else { | ||||
| @@ -217,7 +214,7 @@ export class RdDEmpoignade { | ||||
|     } | ||||
|     const msg = await ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(attacker), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-immobilise.html`, rollData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-immobilise.hbs`, rollData) | ||||
|     }) | ||||
|     RdDEmpoignade.$storeRollEmpoignade(msg, rollData); | ||||
|   } | ||||
| @@ -225,7 +222,7 @@ export class RdDEmpoignade { | ||||
|   /* -------------------------------------------- */ | ||||
|   static async $rollAttaqueEmpoignade(attacker, rollData, isNouvelle = false) { | ||||
|     const dialog = await RdDRoll.create(attacker, rollData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs' }, | ||||
|       { | ||||
|         name: 'jet-empoignade', | ||||
|         label: 'Empoigner', | ||||
| @@ -251,7 +248,7 @@ export class RdDEmpoignade { | ||||
|     if (rollData.rolled.isPart) { | ||||
|       rollData.particuliere = "finesse"; | ||||
|     } | ||||
|     let msg = await RdDResolutionTable.displayRollData(rollData, defender, 'chat-empoignade-resultat.html'); | ||||
|     let msg = await RdDRollResult.displayRollData(rollData, defender, 'chat-empoignade-resultat.hbs'); | ||||
|     RdDEmpoignade.$storeRollEmpoignade(msg, rollData); | ||||
|   } | ||||
|  | ||||
| @@ -288,7 +285,7 @@ export class RdDEmpoignade { | ||||
|   /* -------------------------------------------- */ | ||||
|   static async $rollDefenseEmpoignade(defender, defenderRoll) { | ||||
|     const dialog = await RdDRoll.create(defender, defenderRoll, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-empoignade.hbs' }, | ||||
|       { | ||||
|         name: 'empoignade', | ||||
|         label: 'Contrer', | ||||
| @@ -313,9 +310,9 @@ export class RdDEmpoignade { | ||||
|       RdDEmpoignade.$updateEtatEmpoignade(empoignade) | ||||
|     } | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.html') | ||||
|     await RdDRollResult.displayRollData(rollData, rollData.defender, 'chat-empoignade-resultat.hbs') | ||||
|     if (empoignade.system.pointsemp >= 2) { | ||||
|       let msg = await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-empoignade-entrainer.html'); | ||||
|       let msg = await RdDRollResult.displayRollData(rollData, rollData.attacker, 'chat-empoignade-entrainer.hbs'); | ||||
|       RdDEmpoignade.$storeRollEmpoignade(msg, rollData); | ||||
|     } | ||||
|   } | ||||
| @@ -359,7 +356,7 @@ export class RdDEmpoignade { | ||||
|     await attacker.setEffect(STATUSES.StatusProne, true); | ||||
|     await defender.setEffect(STATUSES.StatusProne, true); | ||||
|  | ||||
|     let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.html'); | ||||
|     let msg = await RdDRollResult.displayRollData(rollData, attacker, 'chat-empoignade-entrainer-sol.hbs'); | ||||
|     RdDEmpoignade.$storeRollEmpoignade(msg, rollData); | ||||
|   } | ||||
|  | ||||
| @@ -375,7 +372,7 @@ export class RdDEmpoignade { | ||||
|     await defender.setEffect(STATUSES.StatusProne, true); | ||||
|     await this.$deleteEmpoignade(empoignade) | ||||
|  | ||||
|     let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.html'); | ||||
|     let msg = await RdDRollResult.displayRollData(rollData, attacker, 'chat-empoignade-projeter-sol.hbs'); | ||||
|     RdDEmpoignade.$storeRollEmpoignade(msg, rollData); | ||||
|   } | ||||
|  | ||||
| @@ -402,7 +399,7 @@ export class RdDEmpoignade { | ||||
|     if (perteMode == "endquart") { | ||||
|       await defender.santeIncDec("endurance", -(3 * Math.floor(endValue / 4))); | ||||
|     } | ||||
|     let msg = await RdDResolutionTable.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.html'); | ||||
|     let msg = await RdDRollResult.displayRollData(rollData, attacker, 'chat-empoignade-perte-endurance.hbs'); | ||||
|     RdDEmpoignade.$storeRollEmpoignade(msg, rollData); | ||||
|   } | ||||
|  | ||||
| @@ -429,7 +426,6 @@ export class RdDEmpoignade { | ||||
|     return await Item.create({ | ||||
|       name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, | ||||
|       type: 'empoignade', | ||||
|       img: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", | ||||
|       system: { description: "", empoignadeid: foundry.utils.randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name } | ||||
|     }, | ||||
|       { | ||||
|   | ||||
| @@ -1,36 +0,0 @@ | ||||
|  | ||||
| const tableGemmes = { | ||||
|   "almaze": { label: "Almaze", couleur: "Blanc"}, | ||||
|   "aquafane": { label: "Aquafane", couleur: "Vert Profond"}, | ||||
|   "asterite": { label: "Astérite", couleur: "Bleu, Violet ou Blanc"}, | ||||
|   "cyanolithe": { label: "Cyanolithe", couleur: "Bleu Intense"}, | ||||
|   "larmededragon": { label: "Larme de Dragon", couleur: "Rouge Intense"}, | ||||
|   "muska": { label: "Muska", couleur: "Violet Profond"}, | ||||
|   "nebuleuse": { label: "Nébuleuse", couleur: "Brouillard Intense"}, | ||||
|   "nebuleuse": { label: "Nébuleuse", couleur: "Brouillard Intense, Rose, Vert ou Bleu Pâle"}, | ||||
|   "oeildetigre": { label: "Oeil de Tigre", couleur: "Jaune"}, | ||||
|   "scarlatine": { label: "Scarlatine", couleur: "Rouge Clair ou Orangé"}, | ||||
|   "seliphane": { label: "Séliphane", couleur: "Vert Lumineux"}, | ||||
|   "tournelune": { label: "Tournelune", couleur: "Violet ou Bleu"}, | ||||
|   "zebraide": { label: "Zebraïde", couleur: "Bandes Bicolores, toutes couleurs"} | ||||
| } | ||||
|  | ||||
| export class RdDGemme extends Item { | ||||
|  | ||||
|   static getGemmeTypeOptionList() { | ||||
|     // TODO: look how to map object key-value pairs | ||||
|     let options = "" | ||||
|     for (let gemmeKey in tableGemmes) { | ||||
|       options += `<option value="${gemmeKey}">${tableGemmes[gemmeKey].label}</option>` | ||||
|     } | ||||
|     return options; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   static calculDataDerivees(gemme) { | ||||
|     gemme.system.cout = (gemme.system.taille * gemme.system.purete) + gemme.system.qualite; | ||||
|     gemme.system.inertie = 7 - gemme.system.purete; | ||||
|     gemme.system.enchantabilite = gemme.system.taille - gemme.system.inertie; | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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 { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||
| import { ITEM_TYPES } from "./item.js"; | ||||
| import { ITEM_TYPES } from "./constants.js"; | ||||
|  | ||||
| export class RdDHotbar { | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,6 @@ import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js" | ||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js" | ||||
| import { RdDHotbar } from "./rdd-hotbar-drop.js" | ||||
| import { EffetsDraconiques } from "./tmr/effets-draconiques.js" | ||||
| import { RdDHerbes } from "./rdd-herbes.js" | ||||
| import { RdDDice } from "./rdd-dice.js" | ||||
| import { RdDPossession } from "./rdd-possession.js" | ||||
| import { Misc } from "./misc.js" | ||||
| @@ -76,7 +75,10 @@ import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire. | ||||
| import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | ||||
| import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" | ||||
| import { RdDJournalSheet } from "./journal/journal-sheet.js" | ||||
| import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js" | ||||
| import { RdDPotionItemSheet } from "./item/sheet-potion.js" | ||||
| import { RdDItemPotion } from "./item/potion.js" | ||||
| import { RdDItemGemme } from "./item/gemme.js" | ||||
| import { RdDGemmeItemSheet } from "./item/sheet-gemme.js" | ||||
|  | ||||
| /** | ||||
|  * RdD system | ||||
| @@ -87,9 +89,9 @@ export class SystemReveDeDragon { | ||||
|  | ||||
|   static start() { | ||||
|     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('ready', async () => await system.onReady()) | ||||
|     Hooks.once('ready', () => system.onReady()) | ||||
|   } | ||||
|  | ||||
|   constructor() { | ||||
| @@ -100,16 +102,18 @@ export class SystemReveDeDragon { | ||||
|     this.itemClasses = { | ||||
|       armure: RdDItemArmure, | ||||
|       blessure: RdDItemBlessure, | ||||
|       gemme: RdDItemGemme, | ||||
|       maladie: RdDItemMaladie, | ||||
|       ombre: RdDItemOmbre, | ||||
|       poison: RdDItemPoison, | ||||
|       potion: RdDItemPotion, | ||||
|       queue: RdDItemQueue, | ||||
|       tete: RdDItemTete, | ||||
|       race: RdDItemRace, | ||||
|       rencontre: RdDRencontre, | ||||
|       service: RdDItemService, | ||||
|       signedraconique: RdDItemSigneDraconique, | ||||
|       souffle: RdDItemSouffle, | ||||
|       tete: RdDItemTete, | ||||
|     } | ||||
|     this.actorClasses = { | ||||
|       commerce: RdDCommerce, | ||||
| @@ -123,14 +127,14 @@ export class SystemReveDeDragon { | ||||
|   /* -------------------------------------------- */ | ||||
|   /*  Foundry VTT Initialization                  */ | ||||
|   /* -------------------------------------------- */ | ||||
|   async onInit() { | ||||
|   onInit() { | ||||
|     game.system.rdd = this | ||||
|     this.AppAstrologie = AppAstrologie | ||||
|  | ||||
|     console.log(`Initializing Reve de Dragon System Settings`) | ||||
|  | ||||
|     // preload handlebars templates | ||||
|     await RdDUtility.preloadHandlebarsTemplates() | ||||
|     RdDUtility.preloadHandlebarsTemplates() | ||||
|     AppPersonnageAleatoire.preloadHandlebars() | ||||
|     RdDItemSort.preloadHandlebars() | ||||
|  | ||||
| @@ -187,24 +191,14 @@ export class SystemReveDeDragon { | ||||
|     Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }) | ||||
|     Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true }) | ||||
|     Items.unregisterSheet("core", ItemSheet) | ||||
|     await RdDActorExportSheet.init() | ||||
|  | ||||
|     RdDItemSheet.register(RdDSigneDraconiqueItemSheet) | ||||
|     RdDItemSheet.register(RdDRencontreItemSheet) | ||||
|     RdDItemSheet.register(RdDConteneurItemSheet) | ||||
|     RdDItemSheet.register(RdDHerbeItemSheet) | ||||
|     RdDItemSheet.register(RdDFauneItemSheet) | ||||
|     RdDItemSheet.register(RdDPlanteItemSheet) | ||||
|     RdDItemSheet.register(RdDIngredientItemSheet) | ||||
|     RdDItemSheet.register(RdDServiceItemSheet) | ||||
|     RdDItemSheet.register(RdDBlessureItemSheet) | ||||
|     RdDJournalSheet.register() | ||||
|     RdDActorExportSheet.init() | ||||
|  | ||||
|     Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, { | ||||
|       types: [ | ||||
|         "objet", "arme", "armure", "livre", "potion", "munition", | ||||
|         "monnaie", "nourritureboisson", "gemme", | ||||
|       ], makeDefault: true | ||||
|         "objet", "arme", "armure", "livre", "munition", | ||||
|         "monnaie", "nourritureboisson", | ||||
|       ], | ||||
|       makeDefault: true | ||||
|     }) | ||||
|     Items.registerSheet(SYSTEM_RDD, RdDItemSheet, { | ||||
|       types: [ | ||||
| @@ -214,8 +208,22 @@ export class SystemReveDeDragon { | ||||
|         "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve", | ||||
|         "nombreastral", "tache", "maladie", "poison", "possession", | ||||
|         "tarot", "extraitpoetique", "empoignade" | ||||
|       ], makeDefault: true | ||||
|       ], | ||||
|       makeDefault: true | ||||
|     }) | ||||
|      | ||||
|     RdDItemSheet.register(RdDBlessureItemSheet) | ||||
|     RdDItemSheet.register(RdDConteneurItemSheet) | ||||
|     RdDItemSheet.register(RdDFauneItemSheet) | ||||
|     RdDItemSheet.register(RdDGemmeItemSheet) | ||||
|     RdDItemSheet.register(RdDHerbeItemSheet) | ||||
|     RdDItemSheet.register(RdDIngredientItemSheet) | ||||
|     RdDItemSheet.register(RdDPlanteItemSheet) | ||||
|     RdDItemSheet.register(RdDPotionItemSheet) | ||||
|     RdDItemSheet.register(RdDRencontreItemSheet) | ||||
|     RdDItemSheet.register(RdDServiceItemSheet) | ||||
|     RdDItemSheet.register(RdDSigneDraconiqueItemSheet) | ||||
|     RdDJournalSheet.register() | ||||
|  | ||||
|     // préparation des différents modules | ||||
|     console.log(`Initializing Reve de Dragon Hooks and handlers`) | ||||
| @@ -316,7 +324,6 @@ export class SystemReveDeDragon { | ||||
|     } | ||||
|  | ||||
|     StatusEffects.onReady() | ||||
|     RdDHerbes.onReady() | ||||
|     RdDDice.onReady() | ||||
|  | ||||
|     RdDStatBlockParser.parseStatBlock() | ||||
|   | ||||
| @@ -117,7 +117,7 @@ export class RdDMeteo { | ||||
|     meteo.pluie.description = RdDMeteo.pluie(meteo.pluie.force); | ||||
|  | ||||
|     ChatMessage.create({ | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-meteo.html', meteo), | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-meteo.hbs', meteo), | ||||
|       whisper: ChatUtility.getGMs() | ||||
|     }); | ||||
|   } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ const words = ['pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i', | ||||
| export class RdDNameGen { | ||||
|  | ||||
|   static async proposeName(msg, params) { | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-command-nom.html`, { | ||||
|     const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-command-nom.hbs`, { | ||||
|       nom: await RdDNameGen.generate() | ||||
|     }); | ||||
|     ChatMessage.create({ content: html, whisper: ChatUtility.getGMs() }); | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| /* -------------------------------------------- */ | ||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||
| import { RdDRoll } from "./rdd-roll.js"; | ||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||
| import { Targets } from "./targets.js"; | ||||
| import { ITEM_TYPES } from "./item.js"; | ||||
| import { ITEM_TYPES } from "./constants.js"; | ||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | ||||
| import { Grammar } from "./grammar.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| /* On part du principe qu'une entité démarre tjs  | ||||
| @@ -91,14 +91,17 @@ export class RdDPossession { | ||||
|     } | ||||
|     RdDPossession.selectCompetenceDraconicOuPossession(rollData, defender) | ||||
|     rollData.diffLibre = RdDPossession.getInfoAttaque(rollData).diffLibre | ||||
|      | ||||
|  | ||||
|     await RdDPossession.$rollDefensePossession(defender, rollData); | ||||
|   } | ||||
|    | ||||
|  | ||||
|   static selectCompetenceDraconicOuPossession(rollData, rollingActor) { | ||||
|     rollData.competence = rollingActor.getDraconicOuPossession(); | ||||
|     if (rollingActor.isCreatureEntite()) { | ||||
|       RdDItemCompetenceCreature.setRollDataCreature(rollData) | ||||
|       const carac = rollingActor.system.carac | ||||
|       rollData.carac = carac | ||||
|       rollData.competence.system.defaut_carac = 'reve' | ||||
|       rollData.selectedCarac = carac.reve | ||||
|     } | ||||
|     else { | ||||
|       rollData.selectedCarac = rollingActor.system.carac.reve | ||||
| @@ -110,7 +113,7 @@ export class RdDPossession { | ||||
|   /* -------------------------------------------- */ | ||||
|   static async $rollAttaquePossession(attacker, rollData, isNouvelle = false) { | ||||
|     const dialog = await RdDRoll.create(attacker, rollData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs' }, | ||||
|       { | ||||
|         name: 'jet-possession', | ||||
|         label: rollData.isECNIDefender ? 'Conjurer la possession' : 'Possession', | ||||
| @@ -131,13 +134,13 @@ export class RdDPossession { | ||||
|     } | ||||
|     const possession = (rollData.isECNIDefender ? rollData.attacker : rollData.defender).getPossession(rollData.possession.system.possessionid) | ||||
|     RdDPossession.storePossessionAttaque(possession, rollData) | ||||
|     await RdDResolutionTable.displayRollData(rollData, rollData.defender, 'chat-resultat-possession.html'); | ||||
|     await RdDRollResult.displayRollData(rollData, rollData.defender, 'chat-resultat-possession.hbs'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async $rollDefensePossession(defender, rollData) { | ||||
|     const dialog = await RdDRoll.create(defender, rollData, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.html' }, | ||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-defense-possession.hbs' }, | ||||
|       { | ||||
|         name: 'possession', | ||||
|         label: 'Conjurer une Possession', | ||||
| @@ -171,10 +174,10 @@ export class RdDPossession { | ||||
|     rollData.possession = possession | ||||
|     RdDPossession.$updateEtatPossession(rollData.possession) | ||||
|  | ||||
|     await RdDResolutionTable.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.html') | ||||
|     await RdDRollResult.displayRollData(rollData, rollData.attacker, 'chat-resultat-possession.hbs') | ||||
|     if (rollData.possession.isPosseder || rollData.possession.isConjurer) { | ||||
|       // conjuration | ||||
|       victime.deleteEmbeddedDocuments("Item", [rollData.possession._id]) | ||||
|       await victime.deleteEmbeddedDocuments("Item", [rollData.possession._id]) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -54,7 +54,6 @@ export class RdDResolutionTable { | ||||
|     return this._computeCell(level, percentage); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static _computeRow(caracValue) { | ||||
|     let dataRow = [ | ||||
| @@ -89,24 +88,10 @@ export class RdDResolutionTable { | ||||
|     return resultat; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') { | ||||
|     return await ChatUtility.createChatWithRollMode( | ||||
|       { content: await RdDResolutionTable.buildRollDataHtml(rollData, template) }, | ||||
|       actor | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   static actorChatName(actor) { | ||||
|     return actor ?? game.user.name; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async buildRollDataHtml(rollData, template = 'chat-resultat-general.html') { | ||||
|     rollData.show = rollData.show || {}; | ||||
|     return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async rollData(rollData) { | ||||
|     rollData.rolled = await this.roll(rollData.caracValue, rollData.finalLevel, rollData); | ||||
| @@ -284,7 +269,7 @@ export class RdDResolutionTable { | ||||
|     maxCarac = Math.min(maxCarac, minCarac + 20); | ||||
|     minLevel = Math.max(minLevel, -10); | ||||
|     maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes); | ||||
|     return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.html', { | ||||
|     return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', { | ||||
|       carac: carac, | ||||
|       difficulte: level, | ||||
|       min: minLevel, | ||||
|   | ||||
| @@ -8,7 +8,7 @@ import { RdDUtility } from "./rdd-utility.js"; | ||||
| export class RdDEncaisser extends Dialog { | ||||
|  | ||||
|   static async encaisser(actor) { | ||||
|     let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html', | ||||
|     let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.hbs', | ||||
|       { ajustementsEncaissement: RdDUtility.getAjustementsEncaissement() } | ||||
|     ); | ||||
|     new RdDEncaisser(html, actor).render(true); | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export class RdDRollResolutionTable extends Dialog { | ||||
|     if (RdDRollResolutionTable.resolutionTable == undefined) { | ||||
|       const rollData = {} | ||||
|       RdDRollResolutionTable._setDefaultOptions(rollData); | ||||
|       let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', rollData); | ||||
|       let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.hbs', rollData); | ||||
|       RdDRollResolutionTable.resolutionTable = new RdDRollResolutionTable(rollData, html); | ||||
|       RdDRollResolutionTable.resolutionTable.render(true); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										17
									
								
								module/rdd-roll-result.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								module/rdd-roll-result.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| import { ChatUtility } from "./chat-utility.js"; | ||||
|  | ||||
| export class RdDRollResult { | ||||
|  | ||||
|   static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.hbs') { | ||||
|     const chatMessage = await ChatUtility.createChatWithRollMode( | ||||
|       { content: await RdDRollResult.buildRollDataHtml(rollData, template) }, | ||||
|       actor | ||||
|     ) | ||||
|     return chatMessage | ||||
|   } | ||||
|  | ||||
|   static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') { | ||||
|     rollData.show = rollData.show || {}; | ||||
|     return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData); | ||||
|   } | ||||
| } | ||||
| @@ -8,7 +8,7 @@ import { RdDCarac } from "./rdd-carac.js"; | ||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { ACTOR_TYPES } from "./item.js"; | ||||
| import { ACTOR_TYPES } from "./constants.js"; | ||||
|  | ||||
| /** | ||||
|  * Extend the base Dialog entity to select roll parameters | ||||
| @@ -137,7 +137,11 @@ export class RdDRoll extends Dialog { | ||||
|       this.rollData.selectedCarac = this.rollData.carac[this.actor.mapCarac(this.rollData.competence.system.defaut_carac)] | ||||
|     } | ||||
|     if (this.rollData.selectedCarac) { | ||||
|       this.html.find("[name='carac']").val(RdDCarac.caracDetails(this.rollData.selectedCarac.label).code) | ||||
|       this.html.find("[name='carac']").val( | ||||
|         RdDCarac.caracDetails(this.rollData.selectedCarac.label, { onMessage: m => { } })?.code | ||||
|         ?? this.rollData.selectedCarac.code | ||||
|         ?? Grammar.toLowerCaseNoAccentNoSpace(this.rollData.selectedCarac.label) | ||||
|       ) | ||||
|     } | ||||
|     if (this.rollData.selectedSort) { | ||||
|       this.setSelectedSort(this.rollData.selectedSort); | ||||
| @@ -265,15 +269,12 @@ export class RdDRoll extends Dialog { | ||||
|   } | ||||
|  | ||||
|   async onAction(action) { | ||||
|     this.rollData.forceDiceResult = Number.parseInt(this.html.find("[name='force-dice-result']").val()) ?? -1; | ||||
|     await RdDResolutionTable.rollData(this.rollData); | ||||
|     console.log("RdDRoll -=>", this.rollData, this.rollData.rolled); | ||||
|     if (action.callbacks) | ||||
|       for (let callback of action.callbacks) { | ||||
|         if (callback.condition == undefined || callback.condition(this.rollData)) { | ||||
|           await callback.action(this.rollData); | ||||
|         } | ||||
|       } | ||||
|     this.rollData.forceDiceResult = Number.parseInt(this.html.find("[name='force-dice-result']").val()) ?? -1 | ||||
|     await RdDResolutionTable.rollData(this.rollData) | ||||
|  | ||||
|     for (let callback of action.callbacks) { | ||||
|       await callback.action(this.rollData) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async setSelectedSort(sort) { | ||||
| @@ -282,7 +283,7 @@ export class RdDRoll extends Dialog { | ||||
|     this.rollData.bonus = RdDItemSort.getCaseBonus(sort, this.rollData.tmr.coord); | ||||
|     this.rollData.diffLibre = RdDItemSort.getDifficulte(sort, -7); | ||||
|     RdDItemSort.setCoutReveReel(sort); | ||||
|     const htmlSortDescription = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html", { sort: sort }); | ||||
|     const htmlSortDescription = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.hbs", { sort: sort }); | ||||
|     this.html.find(".sort-ou-rituel").text(sort.system.isrituel ? "rituel" : "sort"); | ||||
|     this.html.find(".bonus-case").text(`${this.rollData.bonus}%`); | ||||
|     this.html.find(".placeholder-description-sort").children().remove(); | ||||
| @@ -343,7 +344,7 @@ export class RdDRoll extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async buildAjustements(rollData) { | ||||
|     return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html`, rollData); | ||||
|     return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs`, rollData); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||
| import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js"; | ||||
|  | ||||
| export class RdDRollTables { | ||||
|   | ||||
| @@ -66,11 +66,13 @@ export class RdDSheetUtility { | ||||
|   } | ||||
|  | ||||
|   static async splitItem(item, actor, onSplit = () => { }) { | ||||
|     const dialog = await DialogSplitItem.create(item, async (item, split) => { | ||||
|     const _onSplit = async (item, split) => { | ||||
|       await RdDSheetUtility._onSplitItem(item, split, actor); | ||||
|       onSplit(); | ||||
|     }); | ||||
|     dialog.render(true); | ||||
|       await RdDSheetUtility.renderItemBranch(actor, item) | ||||
|     } | ||||
|     const dialog = await DialogSplitItem.create(item, _onSplit) | ||||
|     dialog.render(true) | ||||
|   } | ||||
|  | ||||
|   static async _onSplitItem(item, split, actor) { | ||||
| @@ -82,4 +84,11 @@ export class RdDSheetUtility { | ||||
|       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 { RdDRencontre } from "./item/rencontre.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"; | ||||
|  | ||||
| const TMR_DISPLAY_SIZE = { | ||||
| @@ -48,7 +48,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|  | ||||
|   static async create(actor, tmrData) { | ||||
|     await PixiTMR.init() | ||||
|     let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', tmrData); | ||||
|     let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', tmrData); | ||||
|     if (tmrData.mode != 'visu' && !game.user.isGM) { | ||||
|       ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatUtility.getGMs() }); | ||||
|     } | ||||
| @@ -212,7 +212,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|   } | ||||
|  | ||||
|   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' | ||||
|         ? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve' | ||||
|         : it => it.system.coord == coord | ||||
| @@ -241,7 +241,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     this._getTokensRencontres().forEach(t => this._trackToken(t)) | ||||
|     this._getTokensSortsReserve().forEach(t => this._trackToken(t)) | ||||
|   } | ||||
|    | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   updateTokens() { | ||||
|     this._removeTokens(t => true); | ||||
| @@ -271,8 +271,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|   } | ||||
|  | ||||
|   _getTokensSortsReserve() { | ||||
|     const sortsReserve = this.actor.itemTypes[ITEM_TYPES.sortreserve]; | ||||
|     return Misc.concat(sortsReserve.map(sortReserve => | ||||
|     return Misc.concat(this.sortsReserve.map(sortReserve => | ||||
|       EffetsDraconiques.sortReserve.tokens(this.pixiTMR, sortReserve, () => sortReserve.system.coord))) | ||||
|   } | ||||
|  | ||||
| @@ -498,7 +497,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|  | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this.actor), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.hbs`, rencData) | ||||
|     }); | ||||
|  | ||||
|     this.updateValuesDisplay(); | ||||
| @@ -725,7 +724,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     rollData.poesie = await Poetique.getExtrait(); | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this.actor), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.hbs`, rollData) | ||||
|     }); | ||||
|     if (rollData.rolled.isEchec) { | ||||
|       await this.close(); | ||||
| @@ -842,7 +841,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     rollData.poesie = await Poetique.getExtrait(); | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(this.actor), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.hbs`, rollData) | ||||
|     }); | ||||
|     if (rollData.rolled.isEchec) { | ||||
|       options.onConqueteEchec(rollData, options.effetDraconique); | ||||
| @@ -858,7 +857,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     rollData.isTMRCache = rollData.actor.isTMRCache(); | ||||
|     const dialog = await RdDRoll.create(this.actor, rollData, | ||||
|       { | ||||
|         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html', | ||||
|         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.hbs', | ||||
|       }, | ||||
|       { | ||||
|         name: rollData.maitrise.verbe, label: rollData.maitrise.action, | ||||
| @@ -908,8 +907,8 @@ export class RdDTMRDialog extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   lancerSortEnReserve(coord, sortId) { | ||||
|     let sorts = this.getSortsReserve(coord); | ||||
|     let sort = sorts.find(it => it.id == sortId); | ||||
|     const sort = this.getSortsReserve(coord) | ||||
|       .find(it => it.id == sortId); | ||||
|     if (sort) { | ||||
|       this.processSortReserve(sort); | ||||
|     } else { | ||||
| @@ -1099,7 +1098,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     if (!this.viewOnly && this.actor.isResonanceSigneDraconique(coord)) { | ||||
|       ChatMessage.create({ | ||||
|         whisper: ChatUtility.getOwners(this.actor), | ||||
|         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.html`, { | ||||
|         content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-resonance.hbs`, { | ||||
|           alias: this.actor.getAlias(), | ||||
|           typeTMR: TMRUtility.getTMRType(coord) | ||||
|         }) | ||||
|   | ||||
| @@ -52,7 +52,7 @@ export class RdDTokenHud { | ||||
|     }; | ||||
|     const controlIconCombat = html.find('.control-icon[data-action=combat]'); | ||||
|     await RdDTokenHud._configureSubMenu(controlIconCombat, | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.hbs', | ||||
|       hudData, | ||||
|       (event) => { | ||||
|         let initCommand = event.currentTarget.attributes['data-command']?.value; | ||||
| @@ -70,7 +70,7 @@ export class RdDTokenHud { | ||||
|   static async addExtensionHudCombat(html, combatant, token, actions) { | ||||
|     const hudData = { combatant, token, actions, commandes: [] }; | ||||
|     const controlIconTarget = html.find('.control-icon[data-action=target]'); | ||||
|     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData, | ||||
|     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData, | ||||
|       (event) => { | ||||
|         const actionIndex = event.currentTarget.attributes['data-action-index']?.value; | ||||
|         const action = hudData.actions[actionIndex]; | ||||
|   | ||||
| @@ -19,10 +19,12 @@ import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||
| import { ExperienceLog } from "./actor/experience-log.js"; | ||||
| import { RdDCoeur } from "./coeur/rdd-coeur.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 { 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 | ||||
| @@ -107,102 +109,105 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async preloadHandlebarsTemplates() { | ||||
|   static preloadHandlebarsTemplates() { | ||||
|     const templatePaths = [ | ||||
|       //Character Sheets | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-sheet.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor-vehicule-sheet.hbs', | ||||
|       // sous-parties de feuilles de personnages | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-buttons.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-hautreve.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/item-action-controls.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-buttons.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-etat.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-creature.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-compteurs-entitee.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-effects.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/header-hautreve.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/archetype.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/vue-detaillee.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/armures.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-entitee.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/competence.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/combat.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/blessures.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-main.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-derivee.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-creature.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-entitee.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/carac-total.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/competence.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/competence-categorie.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-competences.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/combat.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/blessures.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/possessions.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.hbs', | ||||
|       '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/taches.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/jeux.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/chirurgie.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/taches.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/jeus.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/alchimie.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/astrologie.hbs', | ||||
|       '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/haut-revant.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-signes-draconiques.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-rencontres.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts-reserve.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-meditations.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-casestmr.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html', | ||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html", | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queues.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-queue.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-souffles.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/dragon-tetes.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-signes-draconiques.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-rencontres.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-sorts-reserve.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-meditations.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/hr-casetmrs.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/xp-journal.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.hbs', | ||||
|       "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-suivants.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-item.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.hbs', | ||||
|       //Items | ||||
|       '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/item/boutons-comestible.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/icon-arme-broken.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/temporel.hbs', | ||||
|       '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-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/item/partial-inventaire.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/header-item.hbs', | ||||
|  | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/queue-sheet.hbs', | ||||
|       // partial enums | ||||
|       '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-caracteristiques.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-parade.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-potion.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-competence.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-draconic.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-heures.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-mortalite.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-niveau-ethylisme.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-periode.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categories.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-parade.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/enum-categorie-alchimie.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item/enum-etat-alchimie.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-queue.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-competence.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-draconic.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-heures.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-initpremierround.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-mortalite.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-niveau-ethylisme.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-periode.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-rarete.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.hbs', | ||||
|       // Partials | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enchantement/partial-enchantement.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/coeur/chat-effet-tendre-moment.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/coeur/afficher-coeur.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats-recherche.hbs', | ||||
| @@ -214,56 +219,55 @@ export class RdDUtility { | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/common/periodicite.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/common/enum-duree.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-astrologique.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-coeur.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-competences.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffLibre.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffFixe.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-item-hautrevant.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-item-frequence.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-competences.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffLibre.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffFixe.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-enctotal.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-forcer.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-moral.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-surenc.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-select-carac.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-item-hautrevant.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-item-frequence.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-item-description.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/roll/explain.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/resolution-table.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', | ||||
|       // Dialogs | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/sommeil/astrologie-gardien.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/sommeil/astrologie-joueur.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/sommeil/astrologie-theme.hbs', | ||||
|       // HUD | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', | ||||
|       // messages tchat | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-description.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-potionenchantee-chateaudormant.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-actor-competence-xp.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.hbs' | ||||
|     ]; | ||||
|      | ||||
|  | ||||
|     // foundry et options | ||||
|     Handlebars.registerHelper('RDD_CONFIG', path => RDD_CONFIG[path]) | ||||
|     Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name)); | ||||
| @@ -278,7 +282,7 @@ export class RdDUtility { | ||||
|       const html = options.fn(this); | ||||
|       return html.replace(rgx, "$& selected"); | ||||
|     }) | ||||
|      | ||||
|  | ||||
|     // logic | ||||
|     Handlebars.registerHelper('either', (a, b) => a ?? b); | ||||
|     // string manipulation | ||||
| @@ -294,9 +298,9 @@ export class RdDUtility { | ||||
|  | ||||
|     // math | ||||
|     Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); | ||||
|     Handlebars.registerHelper('repeat', function(n, block) { | ||||
|     Handlebars.registerHelper('repeat', function (n, block) { | ||||
|       let accum = ''; | ||||
|       for(let i = 0; i < n; ++i){ | ||||
|       for (let i = 0; i < n; ++i) { | ||||
|         accum += block.fn(i) | ||||
|       } | ||||
|       return accum | ||||
| @@ -334,6 +338,9 @@ export class RdDUtility { | ||||
|     Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field)); | ||||
|     // Items | ||||
|     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)) | ||||
|     Handlebars.registerHelper('item-name', (item) =>  item.nameDisplay) | ||||
|  | ||||
|     // TMRs | ||||
|     Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord)); | ||||
| @@ -341,7 +348,7 @@ export class RdDUtility { | ||||
|     Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type)); | ||||
|     Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord)); | ||||
|  | ||||
|     await loadTemplates(templatePaths); | ||||
|     loadTemplates(templatePaths); | ||||
|   } | ||||
|  | ||||
|   static getItem(itemId, actorId = undefined) { | ||||
| @@ -435,8 +442,8 @@ export class RdDUtility { | ||||
|     }; | ||||
|     if (!optionsArbre.templateItem) { | ||||
|       optionsArbre.templateItem = item.parent?.type == 'commerce' | ||||
|         ? "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.html" | ||||
|         : "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html"; | ||||
|         ? "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.hbs" | ||||
|         : "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.hbs"; | ||||
|     } | ||||
|     item.niveau = optionsArbre.profondeur; | ||||
|   } | ||||
| @@ -464,13 +471,38 @@ export class RdDUtility { | ||||
|     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) { | ||||
|     const actor = game.actors.get(actorId) | ||||
|     const item = actor?.items.get(itemId) | ||||
|     if (item) { | ||||
|       return RdDUtility.buildContenuConteneur(item, options, { ouvert: true, profondeur: 1 }); | ||||
|     if (item?.type == ITEM_TYPES.conteneur) { | ||||
|       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)) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -872,7 +904,7 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async confirmActorItemDelete(sheet, item, htmlToDelete) { | ||||
|   static async confirmActorItemDelete(item, actor) { | ||||
|     const itemId = item.id; | ||||
|     const confirmationSuppression = { | ||||
|       settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(), | ||||
| @@ -881,8 +913,7 @@ export class RdDUtility { | ||||
|       buttonLabel: "Supprimer", | ||||
|       onAction: () => { | ||||
|         console.log('Delete : ', itemId); | ||||
|         sheet.actor.deleteEmbeddedDocuments('Item', [itemId], { renderSheet: false }); | ||||
|         RdDUtility.slideOnDelete(sheet, htmlToDelete); | ||||
|         actor.deleteEmbeddedDocuments('Item', [itemId], { renderSheet: false }); | ||||
|       } | ||||
|     }; | ||||
|     if (item.isConteneurNonVide()) { | ||||
| @@ -895,8 +926,7 @@ export class RdDUtility { | ||||
|             label: "Supprimer conteneur et contenu", | ||||
|             callback: () => { | ||||
|               console.log("Delete : ", itemId); | ||||
|               sheet.actor.deleteAllConteneur(itemId, { renderSheet: false }); | ||||
|               RdDUtility.slideOnDelete(sheet, htmlToDelete); | ||||
|               actor.deleteAllConteneur(itemId, { renderSheet: false }); | ||||
|             } | ||||
|           } | ||||
|         }); | ||||
| @@ -934,8 +964,8 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /*-------------------------------------------- */ | ||||
|   static checkThanatosXP(compName) { | ||||
|     if (compName.includes('Thanatos')) { | ||||
|   static checkThanatosXP(item) { | ||||
|     if (item.isCompetencePersonnage() && item.name.includes('Thanatos')) { | ||||
|       let message = "Vous avez mis des points d'Expérience en Thanatos !<br>Vous devez réduire manuellement d'un même montant d'XP une autre compétence Draconique."; | ||||
|       ChatMessage.create({ | ||||
|         whisper: ChatUtility.getUserAndGMs(), | ||||
|   | ||||
| @@ -112,7 +112,7 @@ export class StatusEffects extends FormApplication { | ||||
|     const options = super.defaultOptions; | ||||
|     foundry.utils.mergeObject(options, { | ||||
|       id: "status-effects", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/settings/status-effects.html", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/settings/status-effects.hbs", | ||||
|       height: 800, | ||||
|       width: 350, | ||||
|       minimizable: false, | ||||
|   | ||||
| @@ -157,7 +157,7 @@ export class SystemCompendiums extends FormApplication { | ||||
|     const options = super.defaultOptions; | ||||
|     foundry.utils.mergeObject(options, { | ||||
|       id: "system-compendiums", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/settings/system-compendiums.html", | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/settings/system-compendiums.hbs", | ||||
|       height: 'fit-content', | ||||
|       width: 600, | ||||
|       minimizable: false, | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export class DialogRepos extends Dialog { | ||||
|         "heures": 4 | ||||
|       } | ||||
|     } | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-repos.html", actor); | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-repos.hbs", actor); | ||||
|     const dialog = new DialogRepos(html, actor); | ||||
|     dialog.render(true); | ||||
|   } | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export class DialogStress extends Dialog { | ||||
|         ) | ||||
|     }; | ||||
|  | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-stress.html", dialogData); | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-stress.hbs", dialogData); | ||||
|     new DialogStress(dialogData, html) | ||||
|       .render(true); | ||||
|   } | ||||
|   | ||||
| @@ -334,6 +334,10 @@ export class RdDTimestamp { | ||||
|     return this.nouvelleHeure().addHeures((12 + heure - this.heure) % 12); | ||||
|   } | ||||
|  | ||||
|   debutJournee() { | ||||
|     return RdDTimestamp.timestamp(this.annee, this.mois, this.jour) | ||||
|   } | ||||
|  | ||||
|   async appliquerDuree(duree, actor) { | ||||
|     const formule = FORMULES_DUREE.find(it => it.code == duree) ?? FORMULES_DUREE.find(it => it.code == ""); | ||||
|     return await formule.calcul(this, actor); | ||||
|   | ||||
| @@ -26,7 +26,7 @@ export class TMRRencontres { | ||||
|    * @param {*} forcedRoll  | ||||
|    */ | ||||
|   async rollRencontre(terrain, forcedRoll) { | ||||
|     const tmrType = TMRUtility.findTMRLike(terrain)?.type | ||||
|     const tmrType = TMRUtility.findTMRLike(terrain, { inclusMauvaise: true })?.type | ||||
|     if (tmrType == undefined) { | ||||
|       return undefined; | ||||
|     } | ||||
| @@ -38,7 +38,7 @@ export class TMRRencontres { | ||||
|     const frequence = it => it.system.frequence[tmrType]; | ||||
|     const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll); | ||||
|     if (row) { | ||||
|       await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item', {showSource: false}); | ||||
|       await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item', { showSource: false }); | ||||
|     } | ||||
|  | ||||
|     return row?.document; | ||||
|   | ||||
| @@ -22,7 +22,7 @@ export const TMRType = { | ||||
| export const FLEUVE_COORD = 'Fleuve' | ||||
|  | ||||
| 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" }, | ||||
|   B1: { type: TMRType.plaines.type, label: "Plaines d’Assorh" }, | ||||
|   C1: { type: TMRType.necropole.type, label: "Nécropole de Kroak" }, | ||||
| @@ -281,18 +281,18 @@ export class TMRUtility { | ||||
|     return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label; | ||||
|   } | ||||
|  | ||||
|   static findTMRLike(type, options = { inclusMauvaise: true }) { | ||||
|   static findTMRLike(type, options = { inclusMauvaise: false }) { | ||||
|     const choix = [...Object.values(TMRType)] | ||||
|     if (options.inclusMauvaise) { | ||||
|       choix.push({ name: 'Mauvaise', type: 'mauvaise'}); | ||||
|     } | ||||
|     const selection = Misc.findAllLike(type, choix) | ||||
|     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 | ||||
|     } | ||||
|     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 selection[0] | ||||
| @@ -357,7 +357,7 @@ export class TMRUtility { | ||||
|   } | ||||
|  | ||||
|   static filterTMR(filter) { | ||||
|     return Object.values(TMRMapping).filter(filter); | ||||
|     return Object.values(TMRMapping).filter(it => !it.generique && filter(it)) | ||||
|   } | ||||
|  | ||||
|   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 { PixiTMR } from "./pixi-tmr.js"; | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ import { Periple } from "./periple.js"; | ||||
| import { UrgenceDraconique } from "./urgence-draconique.js"; | ||||
| import { Grammar } from "../grammar.js"; | ||||
| import { AugmentationSeuil } from "./augmentation-seuil.js"; | ||||
| import { ITEM_TYPES } from "../item.js"; | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
|  | ||||
| export class EffetsDraconiques { | ||||
|   static carteTmr = new CarteTmr(); | ||||
|   | ||||
| @@ -113,7 +113,7 @@ export class EffetsRencontre { | ||||
|     }) | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(context.actor), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.hbs`, context) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @@ -128,7 +128,7 @@ export class EffetsRencontre { | ||||
|  | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getOwners(context.actor), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.html`, context) | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-reve-de-dragon.hbs`, context) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { RdDRollTables } from "../rdd-rolltables.js"; | ||||
| import { TMRUtility } from "../tmr-utility.js"; | ||||
| import { tmrTokenZIndex } from "../tmr-constants.js"; | ||||
| import { Draconique } from "./draconique.js"; | ||||
| import { ITEM_TYPES } from "../item.js"; | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { TMRAnimations } from "./animation.js"; | ||||
|  | ||||
| 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 { ChatUtility } from "../chat-utility.js" | ||||
| import { Misc } from "../misc.js" | ||||
|   | ||||
| @@ -300,7 +300,7 @@ system: | ||||
|     déchirure. Celle-là se contente de chercher à fuir en | ||||
|     cas d’agression, ou attaque toutes griffes dehors si elle se sent | ||||
|     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 | ||||
|     pointue.</p> | ||||
|   race: '' | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user