Draft: Gestion des signes draconiques #452
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -2,3 +2,4 @@ | ||||
| .idea | ||||
| todo.txt | ||||
| todo.md | ||||
| /.vscode | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								icons/heures/de-heures.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								icons/heures/de-heures.webp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 4.3 KiB | 
							
								
								
									
										
											BIN
										
									
								
								icons/tmr/signe_draconique.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								icons/tmr/signe_draconique.webp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 35 KiB | 
| @@ -223,6 +223,11 @@ export class RdDActorSheet extends ActorSheet { | ||||
|       const item = this.actor.items.get(li.data("item-id")); | ||||
|       item.sheet.render(true); | ||||
|     }); | ||||
|     html.find('.display-label a').click((event) => { | ||||
|       let myID = event.currentTarget.attributes['data-item-id'].value; | ||||
|       const item = this.actor.getEmbeddedDocument('Item', myID); | ||||
|       item.sheet.render(true); | ||||
|     }); | ||||
|     html.find('.rencontre-delete').click(ev => { | ||||
|       const li = $(ev.currentTarget).parents(".item"); | ||||
|       const rencontreKey = li.data("item-id"); | ||||
| @@ -428,26 +433,6 @@ export class RdDActorSheet extends ActorSheet { | ||||
|     html.find('.enlever-tous-effets').click((event) => { | ||||
|       this.actor.enleverTousLesEffets(); | ||||
|     }); | ||||
|     // Display info about queue | ||||
|     html.find('.queuesouffle-label a').click((event) => { | ||||
|       let myID = event.currentTarget.attributes['data-item-id'].value; | ||||
|       const item = this.actor.getEmbeddedDocument('Item', myID); | ||||
|       item.sheet.render(true); | ||||
|     }); | ||||
|     // Info sort | ||||
|     html.find('.sort-label a').click((event) => { | ||||
|       let myID = event.currentTarget.attributes['data-id'].value; | ||||
|       const item = this.actor.getEmbeddedDocument('Item', myID); | ||||
|       item.sheet.render(true); | ||||
|     }); | ||||
|     // Info sort | ||||
|     html.find('.case-label a').click((event) => { | ||||
|       let myID = event.currentTarget.attributes['data-id'].value; | ||||
|       const item = this.actor.getEmbeddedDocument('Item', myID); | ||||
|       item.sheet.render(true); | ||||
|     }); | ||||
|  | ||||
|     // Display info about queue | ||||
|     html.find('.conteneur-name a').click((event) => { | ||||
|       let myID = event.currentTarget.attributes['data-item-id'].value; | ||||
|       RdDUtility.toggleAfficheContenu(myID); | ||||
|   | ||||
							
								
								
									
										284
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						
									
										284
									
								
								module/actor.js
									
									
									
									
									
								
							| @@ -19,6 +19,7 @@ import { RdDItemArme } from "./item-arme.js"; | ||||
| import { RdDAlchimie } from "./rdd-alchimie.js"; | ||||
| import { StatusEffects } from "./status-effects.js"; | ||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||
| import { RdDItemSigneDraconique } from "./item-signedraconique.js"; | ||||
| import { ReglesOptionelles } from "./regles-optionelles.js"; | ||||
| import { TMRRencontres } from "./tmr-rencontres.js"; | ||||
| import { Poetique } from "./poetique.js"; | ||||
| @@ -193,7 +194,7 @@ export class RdDActor extends Actor { | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   isHautRevant() { | ||||
|     return Misc.templateData(this).attributs.hautrevant.value != "" | ||||
|     return this.isPersonnage() && Misc.templateData(this).attributs.hautrevant.value != "" | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   getFatigueActuelle() { | ||||
| @@ -650,8 +651,7 @@ export class RdDActor extends Actor { | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       const roll = new Roll("1dr").evaluate(); | ||||
|       let deRecuperation = roll.total; | ||||
|       let deRecuperation = await RdDDice.rollTotal("1dr"); | ||||
|       console.log("recuperationReve", deRecuperation); | ||||
|       if (deRecuperation >= 7) { | ||||
|         // Rêve de Dragon ! | ||||
| @@ -743,7 +743,7 @@ export class RdDActor extends Actor { | ||||
|       // TODO: un dialogue pour demander le type de tête? | ||||
|       rollData.tete = true; | ||||
|     } | ||||
|     rollData.poesie = Poetique.getExtrait(); | ||||
|     rollData.poesie = await Poetique.getExtrait(); | ||||
|  | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), | ||||
| @@ -1088,10 +1088,16 @@ export class RdDActor extends Actor { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   computeIsHautRevant() { | ||||
|     const tplData = Misc.templateData(this); | ||||
|     tplData.attributs.hautrevant.value = this.listItemsData('tete').find(it => Grammar.toLowerCaseNoAccent(it.name) == 'don de haut-reve') | ||||
|       ? "Haut rêvant" | ||||
|       : ""; | ||||
|     if (this.isPersonnage()) { | ||||
|       Misc.templateData(this).attributs.hautrevant.value = this.hasItemNamed('tete', 'don de haut-reve') | ||||
|         ? "Haut rêvant" | ||||
|         : ""; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   hasItemNamed(type, name) { | ||||
|     name = Grammar.toLowerCaseNoAccent(name); | ||||
|     return this.listItemsData(type).find(it => Grammar.toLowerCaseNoAccent(it.name) == name); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -1184,7 +1190,7 @@ export class RdDActor extends Actor { | ||||
|   /* -------------------------------------------- */ | ||||
|   async ajouterRefoulement(value = 1) { | ||||
|     let refoulement = Misc.templateData(this).reve.refoulement.value + value; | ||||
|     let total = new Roll("1d20").evaluate({ async: false }).total; | ||||
|     let total = await RdDDice.rollTotal("1d20"); | ||||
|     if (total <= refoulement) { | ||||
|       refoulement = 0; | ||||
|       await this.ajouterSouffle({ chat: true }); | ||||
| @@ -1266,7 +1272,7 @@ export class RdDActor extends Actor { | ||||
|       whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name) | ||||
|     }); | ||||
|     const innaccessible = this.buildTMRInnaccessible(); | ||||
|     let tmr = TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord)); | ||||
|     let tmr = await TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord)); | ||||
|     this.updateCoordTMR(tmr.coord); | ||||
|     this.cacheTMR(); | ||||
|     return tmr; | ||||
| @@ -1395,25 +1401,6 @@ export class RdDActor extends Actor { | ||||
|     return RdDCarac.calculSConst(Misc.templateData(this).carac.constitution.value); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async testSiSonne(sante, endurance) { | ||||
|     const roll = new Roll("1d20").evaluate(); | ||||
|     roll.showDice = true; | ||||
|     RdDDice.show(roll); | ||||
|     let result = { | ||||
|       roll: roll, | ||||
|       sonne: roll.total > endurance || roll.total == 20 // 20 is always a failure | ||||
|     } | ||||
|     if (roll.total == 1) { | ||||
|       await this.ajoutXpConstitution(1); // +1 XP ! | ||||
|       ChatMessage.create({ content: `${this.name} a obenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement).` }); | ||||
|     } | ||||
|     if (result.sonne) { | ||||
|       await this.setSonne(); | ||||
|       sante.sonne.value = true; | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   async ajoutXpConstitution(xp) { | ||||
|     await this.update({ "data.carac.constitution.xp": Misc.toInt(Misc.templateData(this).carac.constitution.xp) + xp }); | ||||
| @@ -1428,48 +1415,71 @@ export class RdDActor extends Actor { | ||||
|     return this.countBlessures(Misc.templateData(this).blessures[name].liste); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async testSiSonne(sante, endurance) { | ||||
|     const result = await this._jetEndurance(endurance); | ||||
|     if (result.roll.total == 1) { | ||||
|       ChatMessage.create({ content: await this._gainXpConstitutionJetEndurance() }); | ||||
|     } | ||||
|     sante.sonne.value ||= result.sonne; | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async jetEndurance() { | ||||
|     let myRoll = new Roll("1d20").roll(); | ||||
|     myRoll.showDice = true; | ||||
|     await RdDDice.show(myRoll); | ||||
|  | ||||
|     const actorData = Misc.data(this); | ||||
|     let msgText = "Jet d'Endurance : " + myRoll.total + " / " + actorData.data.sante.endurance.value + "<br>"; | ||||
|     if (myRoll.total == 1 || (myRoll.total != 20 && myRoll.total <= actorData.data.sante.endurance.value)) { | ||||
|       msgText += `${this.name} a réussi son Jet d'Endurance !`; | ||||
|       if (myRoll.total == 1) { | ||||
|         await this.ajoutXpConstitution(); | ||||
|         msgText += `et gagne 1 Point d'Experience en Constitution`; | ||||
|       } | ||||
|     } else { | ||||
|       await this.setSonne(); | ||||
|       msgText += `${this.name} a échoué son Jet d'Endurance et devient Sonné`; | ||||
|     } | ||||
|     const endurance = actorData.data.sante.endurance.value; | ||||
|  | ||||
|     const result = await this._jetEndurance(actorData.data.sante.endurance.value) | ||||
|     const message = { | ||||
|       content: msgText, | ||||
|       content: "Jet d'Endurance : " + result.roll.total + " / " + endurance + "<br>", | ||||
|       whisper: ChatMessage.getWhisperRecipients(game.user.name) | ||||
|     }; | ||||
|     if (result.sonne) { | ||||
|       message.content += `${this.name} a échoué son Jet d'Endurance et devient Sonné`; | ||||
|     } | ||||
|     else if (result.roll.total == 1) { | ||||
|       message.content += await this._gainXpConstitutionJetEndurance(); | ||||
|     } | ||||
|     else { | ||||
|       message.content += `${this.name} a réussi son Jet d'Endurance !`; | ||||
|     } | ||||
|  | ||||
|     ChatMessage.create(message); | ||||
|   } | ||||
|  | ||||
|   async _gainXpConstitutionJetEndurance() { | ||||
|     await this.ajoutXpConstitution(1); // +1 XP ! | ||||
|     return `${this.name} a obtenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement.`; | ||||
|   } | ||||
|  | ||||
|   async _jetEndurance(endurance) { | ||||
|     const roll = await RdDDice.roll("1d20", { showDice: true }); | ||||
|     let result = { | ||||
|       roll: roll, | ||||
|       sonne: roll.total > endurance || roll.total == 20 // 20 is always a failure | ||||
|     } | ||||
|     if (result.sonne) { | ||||
|       await this.setSonne(); | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async jetVie() { | ||||
|     let myRoll = new Roll("1d20").roll(); | ||||
|     myRoll.showDice = true; | ||||
|     await RdDDice.show(myRoll); | ||||
|  | ||||
|     let roll = await RdDDice.roll("1d20", { showDice: true }); | ||||
|     const actorData = Misc.data(this); | ||||
|     let msgText = "Jet de Vie : " + myRoll.total + " / " + actorData.data.sante.vie.value + "<br>"; | ||||
|     if (myRoll.total <= actorData.data.sante.vie.value) { | ||||
|     let msgText = "Jet de Vie : " + roll.total + " / " + actorData.data.sante.vie.value + "<br>"; | ||||
|     if (roll.total <= actorData.data.sante.vie.value) { | ||||
|       msgText += "Jet réussi, pas de perte de point de vie (prochain jet dans 1 round pour 1 critique, SC minutes pour une grave)"; | ||||
|       if (myRoll.total == 1) { | ||||
|       if (roll.total == 1) { | ||||
|         msgText += "La durée entre 2 jets de vie est multipliée par 20 (20 rounds pour une critique, SCx20 minutes pour une grave)"; | ||||
|       } | ||||
|     } else { | ||||
|       msgText += "Jet échoué, vous perdez 1 point de vie"; | ||||
|       await this.santeIncDec("vie", -1); | ||||
|       if (myRoll.total == 20) { | ||||
|       if (roll.total == 20) { | ||||
|         msgText += "Votre personnage est mort !!!!!"; | ||||
|       } | ||||
|     } | ||||
| @@ -1482,7 +1492,7 @@ export class RdDActor extends Actor { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async santeIncDec(name, inc, options = { isCritique: false, ethylisme: false }) { | ||||
|     if (name=='fatigue' && !ReglesOptionelles.isUsing("appliquer-fatigue")) { | ||||
|     if (name == 'fatigue' && !ReglesOptionelles.isUsing("appliquer-fatigue")) { | ||||
|       return; | ||||
|     } | ||||
|     const sante = duplicate(Misc.templateData(this).sante); | ||||
| @@ -1582,8 +1592,7 @@ export class RdDActor extends Actor { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async jetDeMoral(situation, messageReussi = undefined, messageManque = undefined) { | ||||
|     let jetMoral = new Roll("1d20").roll(); | ||||
|     RdDDice.show(jetMoral); | ||||
|     let jetMoral = await RdDDice.roll("1d20", { showDice: true }); | ||||
|     let moralActuel = Misc.toInt(Misc.templateData(this).compteurs.moral.value); | ||||
|     const difficulte = 10 + moralActuel; | ||||
|     const succes = jetMoral.total <= difficulte; | ||||
| @@ -1687,11 +1696,11 @@ export class RdDActor extends Actor { | ||||
|     RdDResolutionTable.displayRollData(jetVieView, this, 'chat-resultat-ethylisme.html'); | ||||
|  | ||||
|     if (rollEthylisme.isEchec) { | ||||
|       let enduranceLostRoll = new Roll("1d6").roll(); | ||||
|       let enduranceLostRoll = await RdDDice.roll("1d6"); | ||||
|       // enduranceLostRoll.showDice = true; | ||||
|       RdDDice.show(enduranceLostRoll); | ||||
|       let enduranceLost = enduranceLostRoll.total; | ||||
|       let perteEndurance = await this.santeIncDec("endurance", -enduranceLost, {ethylisme: true}); | ||||
|       let perteEndurance = await this.santeIncDec("endurance", -enduranceLost, { ethylisme: true }); | ||||
|       let jetEnduranceView = { | ||||
|         ethylismeEtape: 'Endurance', | ||||
|         enduranceLost: perteEndurance.perte, | ||||
| @@ -1725,7 +1734,7 @@ export class RdDActor extends Actor { | ||||
|       RdDResolutionTable.displayRollData(jetVolonteView, this, 'chat-resultat-ethylisme.html'); | ||||
|     } | ||||
|  | ||||
|     await this.update({'data.compteurs.ethylisme': ethylisme}); | ||||
|     await this.update({ 'data.compteurs.ethylisme': ethylisme }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -2097,9 +2106,11 @@ export class RdDActor extends Actor { | ||||
|  | ||||
|     let draconicList = this.computeDraconicAndSortIndex(sortList); | ||||
|     const actorData = Misc.data(this); | ||||
|     const reve = duplicate(actorData.data.carac.reve); | ||||
|     let rollData = { | ||||
|       forceCarac: { 'reve': duplicate(actorData.data.carac.reve) }, | ||||
|       selectedCarac: duplicate(actorData.data.carac.reve), | ||||
|       carac: { 'reve': reve }, | ||||
|       forceCarac: { 'reve': reve }, | ||||
|       selectedCarac: reve, | ||||
|       draconicList: draconicList, | ||||
|       sortList: sortList, | ||||
|       competence: draconicList[0], | ||||
| @@ -2107,10 +2118,8 @@ export class RdDActor extends Actor { | ||||
|       tmr: TMRUtility.getTMR(coord), | ||||
|       diffLibre: RdDItemSort.getDifficulte(sortList[0], -7), // Per default at startup | ||||
|       coutreve: Array(30).fill().map((item, index) => 1 + index), | ||||
|       carac: { 'reve': duplicate(actorData.data.carac.reve) } | ||||
|     } | ||||
|  | ||||
|     if (this.currentTMR) this.currentTMR.minimize(); // Hide | ||||
|     const dialog = await RdDRoll.create(this, rollData, | ||||
|       { | ||||
|         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html', | ||||
| @@ -2283,7 +2292,7 @@ export class RdDActor extends Actor { | ||||
|     RdDResolutionTable.displayRollData(rollData, this) | ||||
|     return rollData.rolled; | ||||
|   } | ||||
|    | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _appliquerExperienceRollData(rollData) { | ||||
|     const callback = this.createCallbackExperience(); | ||||
| @@ -2320,6 +2329,11 @@ export class RdDActor extends Actor { | ||||
|     dialog.render(true); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _competenceResult(rollData) { | ||||
|     RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html') | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async creerTacheDepuisLivre(item, options = { renderSheet: true }) { | ||||
|     const itemData = Misc.data(item); | ||||
| @@ -2544,24 +2558,15 @@ export class RdDActor extends Actor { | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollMeditation(id) { | ||||
|     let meditation = Misc.data(this.getMeditation(id)); | ||||
|     let competence = Misc.data(this.getCompetence(meditation.data.competence)); | ||||
|     competence.data.defaut_carac = "intellect"; // Meditation = tjs avec intellect | ||||
|     let meditationData = { | ||||
|       competence: competence, | ||||
|       meditation: meditation, | ||||
|       conditionMeditation: { | ||||
|         isHeure: false, | ||||
|         isVeture: false, | ||||
|         isComportement: false, | ||||
|         isPurification: false, | ||||
|       }, | ||||
|       competence: duplicate(Misc.data(this.getCompetence(meditation.data.competence))), | ||||
|       meditation: duplicate(meditation), | ||||
|       conditionMeditation: { isHeure: false, isVeture: false, isComportement: false, isPurification: false }, | ||||
|       diffConditions: 0, | ||||
|       use: { libre: false, conditions: true, }, | ||||
|       carac: {} | ||||
|       carac: { "intellect": Misc.templateData(this).carac.intellect } | ||||
|     }; | ||||
|     meditationData.carac["intellect"] = Misc.templateData(this).carac["intellect"]; | ||||
|  | ||||
|     console.log("rollMeditation !!!", meditationData); | ||||
|     meditationData.competence.data.defaut_carac = "intellect"; // Meditation = tjs avec intellect | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this, meditationData, | ||||
|       { | ||||
| @@ -2573,7 +2578,7 @@ export class RdDActor extends Actor { | ||||
|         label: "Jet de méditation", | ||||
|         callbacks: [ | ||||
|           this.createCallbackExperience(), | ||||
|           { condition: r => r.rolled.isETotal, action: r => this._meditationETotal(r) }, | ||||
|           { condition: r => r.rolled.isEPart, action: r => this._meditationEPart(r) }, | ||||
|           { action: r => this._meditationResult(r) } | ||||
|         ] | ||||
|       }); | ||||
| @@ -2584,27 +2589,92 @@ export class RdDActor extends Actor { | ||||
|   async _meditationResult(meditationData) { | ||||
|     this.santeIncDec("fatigue", 2); | ||||
|  | ||||
|     meditationData.diffLecture = -7; | ||||
|     if (meditationData.rolled.isPart) | ||||
|       meditationData.diffLecture = 0; | ||||
|     else if (meditationData.rolled.isSign) | ||||
|       meditationData.diffLecture = -3; | ||||
|     const signeData = RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditationData.meditation, meditationData.rolled) | ||||
|     if (signeData) { | ||||
|       await this.createEmbeddedDocuments("Item", [signeData]); | ||||
|     } | ||||
|  | ||||
|     RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _meditationETotal(meditationData) { | ||||
|     meditationData.meditation.data.malus--; | ||||
|     this.updateEmbeddedDocuments('Item', [meditationData.meditation]); | ||||
|   _meditationEPart(meditationData) { | ||||
|     this.updateEmbeddedDocuments('Item', [{ _id: meditation._id, 'data.malus': meditationData.meditation.data.malus - 1 }]); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _getSignesDraconiques(coord) { | ||||
|     const type = TMRUtility.getTMRType(coord); | ||||
|     return this.listItemsData("signedraconique").filter(it => it.data.typesTMR.includes(type)); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _competenceResult(rollData) { | ||||
|     RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html') | ||||
|   isResonanceSigneDraconique(coord) { | ||||
|     return this._getSignesDraconiques(coord).length > 0; | ||||
|   } | ||||
|   async _moralDecrease(rollData) { | ||||
|     RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html') | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollLireSigneDraconique(coord) { | ||||
|     if (!this.isHautRevant()) { | ||||
|       ui.notifications.info("Seul un haut rêvant peut lire un signe draconique!"); | ||||
|       return; | ||||
|     } | ||||
|     let signes = this._getSignesDraconiques(coord); | ||||
|     if (signes.length == 0) { | ||||
|       ui.notifications.info(`Aucun signe draconiques en ${coord} !`); | ||||
|       return; | ||||
|     } | ||||
|     if (this.currentTMR) this.currentTMR.minimize(); // Hide | ||||
|  | ||||
|     let draconicList = this.getDraconicList() | ||||
|       .map(draconic => duplicate(Misc.data(draconic))) | ||||
|       .map(draconic => { draconic.data.defaut_carac = "intellect"; return draconic; }); | ||||
|  | ||||
|     const intellect = Misc.templateData(this).carac.intellect; | ||||
|     let rollData = { | ||||
|       carac: { 'intellect': intellect }, | ||||
|       selectedCarac: intellect, | ||||
|       competence: draconicList[0], | ||||
|       draconicList: draconicList, | ||||
|       signe: signes[0], | ||||
|       signes: signes, | ||||
|       tmr: TMRUtility.getTMR(coord), | ||||
|       diffLibre: Misc.data(signes[0]).data.difficulte, | ||||
|     } | ||||
|  | ||||
|     const dialog = await RdDRoll.create(this, rollData, | ||||
|       { | ||||
|         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.html', | ||||
|         options: { height: 600 }, | ||||
|         close: html => { this.currentTMR.maximize() } // Re-display TMR | ||||
|       }, | ||||
|       { | ||||
|         name: 'lire-signe-draconique', | ||||
|         label: 'Lire le signe draconique', | ||||
|         callbacks: [ | ||||
|           this.createCallbackExperience(), | ||||
|           { action: r => this._rollLireSigneDraconique(r) } | ||||
|         ] | ||||
|       } | ||||
|     ); | ||||
|     dialog.render(true); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _rollLireSigneDraconique(rollData) { | ||||
|     const compData = rollData.competence; | ||||
|     if (!RdDItemCompetence.isDraconic(compData)) { | ||||
|       ui.notifications.error(`La compétence ${compData.name} n'est pas une compétence draconique`); | ||||
|       return; | ||||
|     } | ||||
|     rollData.xpSort = RdDItemSigneDraconique.getXpSortSigneDraconique(rollData.rolled.code, rollData.signe); | ||||
|     if (rollData.xpSort > 0) { | ||||
|       await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'data.xp_sort': Misc.toInt(compData.data.xp_sort) + rollData.xpSort }]); | ||||
|     } | ||||
|     await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]); | ||||
|     RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html'); | ||||
|     this.currentTMR.close(); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -2840,6 +2910,7 @@ export class RdDActor extends Actor { | ||||
|       fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance), | ||||
|       draconic: this.getDraconicList(), | ||||
|       sort: this.getSortList(), | ||||
|       signes: this.listItemsData("signedraconique"), | ||||
|       caracReve: actorData.data.carac.reve.value, | ||||
|       pointsReve: this.getReveActuel(), | ||||
|       isRapide: isRapide | ||||
| @@ -2904,14 +2975,14 @@ export class RdDActor extends Actor { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   computeArmure(attackerRoll) { | ||||
|   async computeArmure(attackerRoll) { | ||||
|     let dmg = (attackerRoll.dmg.dmgArme ?? 0) + (attackerRoll.dmg.dmgActor ?? 0); | ||||
|     let armeData = attackerRoll.arme; | ||||
|     let protection = 0; | ||||
|     const armures = this.items.map(it => Misc.data(it)) | ||||
|       .filter(it => it.type == "armure" && it.data.equipe); | ||||
|     for (const itemData of armures) { | ||||
|       protection += new Roll(itemData.data.protection.toString()).roll().total; | ||||
|       protection += await RdDDice.rollTotal(itemData.data.protection.toString()); | ||||
|       if (dmg > 0) { | ||||
|         this._deteriorerArmure(itemData, dmg); | ||||
|         dmg = 0; | ||||
| @@ -2972,7 +3043,7 @@ export class RdDActor extends Actor { | ||||
|     console.log("encaisserDommages", rollData) | ||||
|  | ||||
|     let santeOrig = duplicate(Misc.templateData(this).sante); | ||||
|     let encaissement = this.jetEncaissement(rollData); | ||||
|     let encaissement = await this.jetEncaissement(rollData); | ||||
|  | ||||
|     this.ajouterBlessure(encaissement); // Will upate the result table | ||||
|     const perteVie = this.isEntiteCauchemar() | ||||
| @@ -3011,29 +3082,34 @@ export class RdDActor extends Actor { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   jetEncaissement(rollData) { | ||||
|     const roll = new Roll("2d10").roll(); | ||||
|     roll.showDice = true; | ||||
|     RdDDice.show(roll, game.settings.get("core", "rollMode")); | ||||
|   async jetEncaissement(rollData) { | ||||
|     const roll = await RdDDice.roll("2d10", { showDice: true }); | ||||
|  | ||||
|     const armure = this.computeArmure(rollData); | ||||
|     const armure = await this.computeArmure(rollData); | ||||
|     const jetTotal = roll.total + rollData.dmg.total - armure; | ||||
|  | ||||
|     let encaissement = RdDUtility.selectEncaissement(jetTotal, rollData.dmg.mortalite) | ||||
|     let over20 = Math.max(jetTotal - 20, 0); | ||||
|     encaissement.dmg = rollData.dmg; | ||||
|     encaissement.dmg.loc = rollData.dmg.loc ?? RdDUtility.getLocalisation(this.data.type); | ||||
|     encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.data.type); | ||||
|     encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' | ||||
|     encaissement.roll = roll; | ||||
|     encaissement.armure = armure; | ||||
|     encaissement.total = jetTotal; | ||||
|     encaissement.vie = RdDUtility._evaluatePerte(encaissement.vie, over20); | ||||
|     encaissement.endurance = RdDUtility._evaluatePerte(encaissement.endurance, over20); | ||||
|     encaissement.vie = await RdDActor._evaluatePerte(encaissement.vie, over20); | ||||
|     encaissement.endurance = await RdDActor._evaluatePerte(encaissement.endurance, over20); | ||||
|     encaissement.penetration = rollData.arme?.data.penetration ?? 0; | ||||
|  | ||||
|     return encaissement; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async _evaluatePerte(formula, over20) { | ||||
|     let perte = new Roll(formula, { over20: over20 }); | ||||
|     await perte.evaluate({ async: true }); | ||||
|     return perte.total; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   ajouterBlessure(encaissement) { | ||||
|     const actorData = Misc.data(this); | ||||
| @@ -3306,7 +3382,7 @@ export class RdDActor extends Actor { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async achatVente(vendeurId, acheteurId, venteData, chatMessageIdVente) { | ||||
|     if (vendeurId == acheteurId){ | ||||
|     if (vendeurId == acheteurId) { | ||||
|       ui.notifications.info("Inutile de se vendre à soi-même"); | ||||
|       return; | ||||
|     } | ||||
| @@ -3615,7 +3691,7 @@ export class RdDActor extends Actor { | ||||
|         potionData.reussiteReve = true; | ||||
|         potionData.aphasiePermanente = false; | ||||
|         if (potionData.data.reposalchimique) { | ||||
|           let chanceAphasie = new Roll("1d100").evaluate({ async: false }).total; | ||||
|           let chanceAphasie = await RdDDice.rollTotal("1d100"); | ||||
|           if (chanceAphasie <= potionData.data.pr) { | ||||
|             potionData.aphasiePermanente = true; | ||||
|           } | ||||
|   | ||||
							
								
								
									
										122
									
								
								module/dialog-create-signedraconique.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								module/dialog-create-signedraconique.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| import { ChatUtility } from "./chat-utility.js"; | ||||
| import { HtmlUtility } from "./html-utility.js"; | ||||
| import { RdDItemSigneDraconique } from "./item-signedraconique.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDRollTables } from "./rdd-rolltables.js"; | ||||
| import { TMRType, TMRUtility } from "./tmr-utility.js"; | ||||
|  | ||||
| export class DialogCreateSigneDraconique extends Dialog { | ||||
|  | ||||
|   static async createSigneForActors() { | ||||
|     let dialogData = { | ||||
|       signe: await RdDItemSigneDraconique.randomSigneDraconique(), | ||||
|       actors: game.actors.filter(actor => actor.isHautRevant()).map(it => duplicate(Misc.data(it))) | ||||
|     }; | ||||
|     dialogData.tmrs = TMRUtility.listSelectedTMR(dialogData.signe.data.typesTMR ?? []); | ||||
|     dialogData.actors.forEach(it => it.selected = false); | ||||
|  | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-create-signedraconique.html", dialogData); | ||||
|     new DialogCreateSigneDraconique(dialogData, html) | ||||
|       .render(true); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   constructor(dialogData, html, callback) { | ||||
|     let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 650, 'z-index': 99999 }; | ||||
|  | ||||
|     let conf = { | ||||
|       title: "Créer un signe", | ||||
|       content: html, | ||||
|       default: "Ajouter aux haut-rêvants", | ||||
|       buttons: { | ||||
|         "Ajouter aux haut-rêvants": { label: "Ajouter aux haut-rêvants", callback: it => { this._onCreerSigneActeurs(); } } | ||||
|       } | ||||
|     }; | ||||
|     super(conf, options); | ||||
|     this.dialogData = dialogData; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   async _onCreerSigneActeurs() { | ||||
|     this.validerSigne(); | ||||
|     this.dialogData.actors.filter(it => it.selected).map(it => game.actors.get(it._id)) | ||||
|       .forEach(actor => this._createSigneForActor(actor, this.dialogData.signe)); | ||||
|   } | ||||
|  | ||||
|   async _createSigneForActor(actor, signe) { | ||||
|     actor.createEmbeddedDocuments("Item", [signe]); | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getWhisperRecipientsAndGMs(Misc.data(actor).name), | ||||
|       content: await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html", { | ||||
|         signe: signe, | ||||
|         alias: Misc.data(actor).name | ||||
|       }) | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   validerSigne() { | ||||
|     this.dialogData.signe.name = $("[name='signe.name']").val(); | ||||
|     this.dialogData.signe.data.valeur.norm = $("[name='signe.data.valeur.norm']").val(); | ||||
|     this.dialogData.signe.data.valeur.sign = $("[name='signe.data.valeur.sign']").val(); | ||||
|     this.dialogData.signe.data.valeur.part = $("[name='signe.data.valeur.part']").val(); | ||||
|     this.dialogData.signe.data.difficulte = $("[name='signe.data.difficulte']").val(); | ||||
|     this.dialogData.signe.data.ephemere = $("[name='signe.data.ephemere']").prop("checked"); | ||||
|     this.dialogData.signe.data.duree = $("[name='signe.data.duree']").val(); | ||||
|     this.dialogData.signe.data.typesTMR = $(".select-tmr").val(); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|     this.setEphemere(this.dialogData.signe.data.ephemere); | ||||
|     html.find(".signe-aleatoire").click(event => this.setSigneAleatoire()); | ||||
|     html.find("[name='signe.data.ephemere']").change((event) => this.setEphemere(event.currentTarget.checked)); | ||||
|     // html.find(".select-tmr").change((event) => this.onSelectTmr(event)); | ||||
|     html.find(".select-actor").change((event) => this.onSelectActor(event)); | ||||
|     html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event)); | ||||
|   } | ||||
|   async setSigneAleatoire() { | ||||
|     const newSigne = await RdDItemSigneDraconique.randomSigneDraconique(); | ||||
|  | ||||
|     $("[name='signe.name']").val(newSigne.name); | ||||
|     $("[name='signe.data.valeur.norm']").val(newSigne.data.valeur.norm); | ||||
|     $("[name='signe.data.valeur.sign']").val(newSigne.data.valeur.sign); | ||||
|     $("[name='signe.data.valeur.part']").val(newSigne.data.valeur.part); | ||||
|     $("[name='signe.data.difficulte']").val(newSigne.data.difficulte); | ||||
|     $("[name='signe.data.duree']").val(newSigne.data.duree); | ||||
|     $("[name='signe.data.ephemere']").prop("checked", newSigne.data.ephemere); | ||||
|     $(".select-tmr").val(newSigne.data.typesTMR); | ||||
|     this.setEphemere(newSigne.data.ephemere); | ||||
|   } | ||||
|  | ||||
|   async setEphemere(ephemere) { | ||||
|     this.dialogData.signe.data.ephemere = ephemere; | ||||
|     HtmlUtility._showControlWhen($(".signe-data-duree"), ephemere); | ||||
|   } | ||||
|  | ||||
|   // async onSelectTmr(event) { | ||||
|   //   event.preventDefault(); | ||||
|   //   this.dialogData.signe.data.typesTMR = $(".select-tmr").val(); | ||||
|   // } | ||||
|  | ||||
|   async onSelectActor(event) { | ||||
|     event.preventDefault(); | ||||
|     const options = event.currentTarget.options; | ||||
|     for (var i = 0; i < options.length; i++) { // looping over the options | ||||
|       const actorId = options[i].attributes["data-actor-id"].value; | ||||
|       const actor = this.dialogData.actors.find(it => it._id == actorId); | ||||
|       if (actor) { | ||||
|         actor.selected = options[i].selected; | ||||
|       } | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   onValeurXpSort(event) { | ||||
|     const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0; | ||||
|     const xp = Number(event.currentTarget.value); | ||||
|     const oldValeur = this.dialogData.signe.data.valeur; | ||||
|     this.dialogData.signe.data.valeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -51,8 +51,9 @@ export class RdDItemSheet extends ItemSheet { | ||||
|   /** @override */ | ||||
|   setPosition(options = {}) { | ||||
|     const position = super.setPosition(options); | ||||
|     const sheetHeader = this.element.find(".sheet-header"); | ||||
|     const sheetBody = this.element.find(".sheet-body"); | ||||
|     const bodyHeight = position.height - 192; | ||||
|     const bodyHeight = position.height - sheetHeader[0].clientHeight; | ||||
|     sheetBody.css("height", bodyHeight); | ||||
|     return position; | ||||
|   } | ||||
|   | ||||
							
								
								
									
										104
									
								
								module/item-signedraconique-sheet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								module/item-signedraconique-sheet.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| import { RdDItemSigneDraconique } from "./item-signedraconique.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { TMRType, TMRUtility } from "./tmr-utility.js"; | ||||
|  | ||||
| /** | ||||
|  * Item sheet pour signes draconiques | ||||
|  * @extends {ItemSheet} | ||||
|  */ | ||||
| export class RdDSigneDraconiqueItemSheet extends ItemSheet { | ||||
|  | ||||
|   /** @override */ | ||||
|   static get defaultOptions() { | ||||
|     return mergeObject(super.defaultOptions, { | ||||
|       classes: ["foundryvtt-reve-de-dragon", "sheet", "item"], | ||||
|       template: "systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html", | ||||
|       width: 550, | ||||
|       height: 550 | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _getHeaderButtons() { | ||||
|     let buttons = super._getHeaderButtons(); | ||||
|     buttons.unshift({ class: "post", icon: "fas fa-comment", onclick: ev => this.item.postItem() }); | ||||
|     return buttons; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   /** @override */ | ||||
|   setPosition(options = {}) { | ||||
|     const position = super.setPosition(options); | ||||
|     const sheetHeader = this.element.find(".sheet-header"); | ||||
|     const sheetBody = this.element.find(".sheet-body"); | ||||
|     const bodyHeight = position.height - sheetHeader[0].clientHeight; | ||||
|     sheetBody.css("height", bodyHeight); | ||||
|     return position; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async getData() { | ||||
|     const formData = duplicate(Misc.data(this.object)); | ||||
|     mergeObject(formData, { | ||||
|       title: formData.name, | ||||
|       isGM: game.user.isGM, | ||||
|       owner: this.document.isOwner, | ||||
|       isOwned: this.actor ? true : false, | ||||
|       actorId: this.actor?.id, | ||||
|       editable: this.isEditable, | ||||
|       cssClass: this.isEditable ? "editable" : "locked", | ||||
|     }); | ||||
|     formData.tmrs = TMRUtility.listSelectedTMR(formData.data.typesTMR ?? []); | ||||
|     return formData; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   /** @override */ | ||||
|   activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|  | ||||
|     if (!this.options.editable) return; | ||||
|  | ||||
|     html.find(".signe-aleatoire").click(event => this.setSigneAleatoire()); | ||||
|     html.find(".select-tmr").change((event) => this.onSelectTmr(event)); | ||||
|     html.find(".signe-xp-sort").change((event) => this.onValeurXpSort(event.currentTarget.attributes['data-typereussite']?.value, Number(event.currentTarget.value))); | ||||
|   } | ||||
|  | ||||
|   async setSigneAleatoire() { | ||||
|     const newSigne = await RdDItemSigneDraconique.randomSigneDraconique(); | ||||
|     // $("[name='signe.name']").val(newSigne.name); | ||||
|     // $("[name='signe.data.valeur.norm']").val(newSigne.data.valeur.norm); | ||||
|     // $("[name='signe.data.valeur.sign']").val(newSigne.data.valeur.sign); | ||||
|     // $("[name='signe.data.valeur.part']").val(newSigne.data.valeur.part); | ||||
|     // $("[name='signe.data.difficulte']").val(newSigne.data.difficulte); | ||||
|     // $("[name='signe.data.duree']").val(newSigne.data.duree); | ||||
|     // $("[name='signe.data.ephemere']").prop("checked", newSigne.data.ephemere); | ||||
|     // $(".select-tmr").val(newSigne.data.typesTMR); | ||||
|     // this.setEphemere(newSigne.data.ephemere); | ||||
|     this.object.update(newSigne); | ||||
|   } | ||||
|  | ||||
|   async onSelectTmr(event) { | ||||
|     event.preventDefault(); | ||||
|     const selectedTMR = $(".select-tmr").val(); | ||||
|     this.object.update({ 'data.typesTMR': selectedTMR }); | ||||
|   } | ||||
|  | ||||
|   async onValeurXpSort(event) { | ||||
|     const codeReussite = event.currentTarget.attributes['data-typereussite']?.value ?? 0; | ||||
|     const xp = Number(event.currentTarget.value); | ||||
|     const oldValeur = Misc.templateData(this.object).valeur; | ||||
|     const newValeur = RdDItemSigneDraconique.calculValeursXpSort(codeReussite, xp, oldValeur); | ||||
|     await this.object.update({ 'data.valeur': newValeur }); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   get template() { | ||||
|     return `systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html`; | ||||
|   } | ||||
|  | ||||
|   get title() { | ||||
|     return `Signe draconique: ${this.object.name}`; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										100
									
								
								module/item-signedraconique.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								module/item-signedraconique.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
| import { RdDRollTables } from "./rdd-rolltables.js"; | ||||
| import { TMRType } from "./tmr-utility.js"; | ||||
|  | ||||
| const tableSignesIndicatifs = [ | ||||
|   { rarete: "Très facile", difficulte: 0, xp: 6, nbCases: 14 }, | ||||
|   { rarete: "Facile", difficulte: -2, xp: 10, nbCases: 10 }, | ||||
|   { rarete: "Moyen", difficulte: -3, xp: 15, nbCases: 7 }, | ||||
|   { rarete: "Difficile", difficulte: -5, xp: 20, nbCases: 4 }, | ||||
|   { rarete: "Ardu", difficulte: -8, xp: 30, nbCases: 1 } | ||||
|  | ||||
| ] | ||||
| export class RdDItemSigneDraconique { | ||||
|  | ||||
|   static prepareSigneDraconiqueMeditation(meditation, rolled) { | ||||
|     if (rolled.isSuccess != undefined) { | ||||
|       meditation = Misc.data(meditation); | ||||
|       return { | ||||
|         name: "de la " + meditation.name, | ||||
|         type: "signedraconique", | ||||
|         img: meditation.img, | ||||
|         data: { | ||||
|           "typesTMR": [Misc.upperFirst(meditation.data.tmr)], | ||||
|           "difficulte": RdDItemSigneDraconique.getDiffSigneMeditation(rolled.code), | ||||
|           "ephemere": true, | ||||
|           "duree": "1 round", | ||||
|           "valeur": { "norm": 3, "sign": 5, "part": 10 } | ||||
|         } | ||||
|       }; | ||||
|     } | ||||
|     return undefined; | ||||
|   } | ||||
|  | ||||
|   static getDiffSigneMeditation(code) { | ||||
|     switch (code) { | ||||
|       case "norm": return -7; | ||||
|       case "sign": return -3; | ||||
|       case "part": return 0; | ||||
|     } | ||||
|     return undefined; | ||||
|   } | ||||
|  | ||||
|   static getXpSortSigneDraconique(code, signe) { | ||||
|     return Misc.data(signe).data.valeur[code] ?? 0; | ||||
|   } | ||||
|  | ||||
|   static calculValeursXpSort(qualite, valeur, avant) { | ||||
|     switch (qualite) { | ||||
|       case "norm": | ||||
|         return { | ||||
|           norm: valeur, | ||||
|           sign: Math.max(valeur, avant.sign), | ||||
|           part: Math.max(valeur, avant.part) | ||||
|         } | ||||
|       case "sign": | ||||
|         return { | ||||
|           norm: Math.min(valeur, avant.norm), | ||||
|           sign: valeur, | ||||
|           part: Math.max(valeur, avant.part) | ||||
|         } | ||||
|       case "part": | ||||
|         return { | ||||
|           norm: Math.min(valeur, avant.norm), | ||||
|           sign: Math.min(valeur, avant.sign), | ||||
|           part: valeur | ||||
|         } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static async randomSigneDraconique() { | ||||
|     let modele = await RdDDice.rollOneOf(tableSignesIndicatifs); | ||||
|     return { | ||||
|       name: await RdDItemSigneDraconique.randomSigneDescription(), | ||||
|       type: "signedraconique", | ||||
|       img: 'systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp', | ||||
|       data: { | ||||
|         typesTMR: await RdDItemSigneDraconique.randomTmrs(modele.nbCases), | ||||
|         ephemere: true, | ||||
|         duree: "1 round", | ||||
|         difficulte: modele.difficulte, | ||||
|         valeur: { norm: modele.xp, sign: modele.xp, part: Math.floor(modele.xp * 1.5) }, | ||||
|       } | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   static async randomTmrs(nbTmr = undefined) { | ||||
|     let tmrs = Object.values(TMRType).map(value => Misc.upperFirst(value.name)); | ||||
|     let keep = nbTmr ?? (await RdDDice.rollTotal("1d" + TMRType.length) + 1); | ||||
|     for (let i = tmrs.length; i > keep; i--) { | ||||
|       tmrs.splice(await RdDDice.rollTotal("1d" + i), 1); | ||||
|     } | ||||
|     return tmrs; | ||||
|   } | ||||
|  | ||||
|   static async randomSigneDescription() { | ||||
|     return await RdDRollTables.drawTextFromRollTable("Signes draconiques", false); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -25,6 +25,7 @@ export class RdDItem extends Item { | ||||
|   isConteneur() { | ||||
|     return Misc.data(this).type == 'conteneur'; | ||||
|   } | ||||
|  | ||||
|   isVide() { | ||||
|     return this.isConteneur() && (Misc.templateData(this).contenu ?? []).length == 0; | ||||
|   } | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
|  | ||||
| /** | ||||
|  * This class is intended as a placeholder for utility methods unrelated | ||||
| @@ -22,13 +23,13 @@ export class Misc { | ||||
|     return (a, b) => a + b; | ||||
|   } | ||||
|  | ||||
|   static ascending(orderFunction = x=>x) { | ||||
|   static ascending(orderFunction = x => x) { | ||||
|     return (a, b) => Misc.sortingBy(orderFunction(a), orderFunction(b)); | ||||
|   }   | ||||
|   } | ||||
|  | ||||
|   static descending(orderFunction = x=>x) { | ||||
|   static descending(orderFunction = x => x) { | ||||
|     return (a, b) => Misc.sortingBy(orderFunction(b), orderFunction(a)); | ||||
|   }   | ||||
|   } | ||||
|  | ||||
|   static sortingBy(a, b) { | ||||
|     if (a > b) return 1; | ||||
| @@ -49,7 +50,7 @@ export class Misc { | ||||
|   } | ||||
|  | ||||
|   static keepDecimals(num, decimals) { | ||||
|     if (decimals<=0 || decimals>6) return num; | ||||
|     if (decimals <= 0 || decimals > 6) return num; | ||||
|     const decimal = Math.pow(10, parseInt(decimals)); | ||||
|     return Math.round(num * decimal) / decimal; | ||||
|   } | ||||
| @@ -92,10 +93,6 @@ export class Misc { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static rollOneOf(array) { | ||||
|     return array[new Roll("1d" + array.length).evaluate({ async: false }).total - 1]; | ||||
|   } | ||||
|  | ||||
|   static distinct(array) { | ||||
|     return [...new Set(array)]; | ||||
|   } | ||||
| @@ -112,7 +109,7 @@ export class Misc { | ||||
|   } | ||||
|  | ||||
|   static connectedGMOrUser(ownerId = undefined) { | ||||
|     if (ownerId && game.user.id == ownerId){ | ||||
|     if (ownerId && game.user.id == ownerId) { | ||||
|       return ownerId; | ||||
|     } | ||||
|     return (game.user.isGM ? game.user.id : game.users.entities.find(u => u.isGM && u.active)?.id) ?? game.user.id; | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { Misc } from "./misc.js" | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
|  | ||||
| const poesieHautReve = [ | ||||
|   { | ||||
| @@ -64,8 +65,8 @@ const poesieHautReve = [ | ||||
| ] | ||||
|  | ||||
| export class Poetique { | ||||
|   static getExtrait(){ | ||||
|     return Misc.rollOneOf(poesieHautReve); | ||||
|   static async getExtrait(){ | ||||
|     return await RdDDice.rollOneOf(poesieHautReve); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -5,6 +5,8 @@ import { HtmlUtility } from "./html-utility.js"; | ||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||
| import { RdDUtility } from "./rdd-utility.js"; | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import {RdDDice } from "./rdd-dice.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/' | ||||
| @@ -124,9 +126,9 @@ export class RdDCalendrier extends Application { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   ajouterNombreAstral(index) { | ||||
|   async ajouterNombreAstral(index) { | ||||
|     return { | ||||
|       nombreAstral: new Roll("1d12").evaluate( {async:false} ).total, | ||||
|       nombreAstral: await RdDDice.rollTotal("1dh"), | ||||
|       valeursFausses: [], | ||||
|       index: index | ||||
|     } | ||||
| @@ -278,11 +280,10 @@ export class RdDCalendrier extends Application { | ||||
|       request.isValid = true; | ||||
|       if (!request.rolled.isSuccess) { | ||||
|         request.isValid = false; | ||||
|         let nbAstralFaux = new Roll("1d11").evaluate( { async: false} ).total; | ||||
|         nbAstral = nbAstral==nbAstralFaux ? 12 : nbAstralFaux; | ||||
|         nbAstral = await RdDDice.rollTotal("1dhr"+nbAstral); | ||||
|         // Mise à jour des nombres astraux du joueur | ||||
|         let astralData = this.listeNombreAstral.find((nombreAstral, i) => nombreAstral.index == request.date); | ||||
|         astralData.valeursFausses.push({ actorId: request.id, nombreAstral: nbAstralFaux }); | ||||
|         astralData.valeursFausses.push({ actorId: request.id, nombreAstral: nbAstral }); | ||||
|         game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral); | ||||
|       } | ||||
|       request.nbAstral = nbAstral; | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| /* -------------------------------------------- */ | ||||
|  | ||||
| import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js"; | ||||
| import { RdDItemCompetence } from "./item-competence.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDCarac } from "./rdd-carac.js"; | ||||
| @@ -82,6 +83,17 @@ export class RdDCommands { | ||||
|         descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples: | ||||
|           <br><strong>/astro Lyre</strong>` | ||||
|       }); | ||||
|  | ||||
|       rddCommands.registerCommand({ | ||||
|         path: ["/signe", "+"], func: (content, msg, params) => rddCommands.creerSignesDraconiques(), | ||||
|         descr: "Crée un signe draconique et l'ajoute aux haut-rêvants choisis." | ||||
|       }); | ||||
|  | ||||
|       rddCommands.registerCommand({ | ||||
|         path: ["/signe", "-"], func: (content, msg, params) => rddCommands.supprimerSignesDraconiquesEphemeres(), | ||||
|         descr: "Supprime les signes draconiques éphémères" | ||||
|       }); | ||||
|  | ||||
|       game.system.rdd.commands = rddCommands; | ||||
|     } | ||||
|   } | ||||
| @@ -271,16 +283,14 @@ export class RdDCommands { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollDeDraconique(msg) { | ||||
|     let ddr = new Roll("1dr + 7").evaluate(); | ||||
|     ddr.showDice = true; | ||||
|     await RdDDice.showDiceSoNice(ddr); | ||||
|     RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`); | ||||
|     let ddr = await RdDDice.rollTotal("1dr + 7", { showDice:true }); | ||||
|     RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`); | ||||
|   } | ||||
|  | ||||
|   getTMRAleatoire(msg, params) { | ||||
|   async getTMRAleatoire(msg, params) { | ||||
|     if (params.length < 2) { | ||||
|       let type = params[0]; | ||||
|       const tmr = TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true)); | ||||
|       const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true)); | ||||
|       RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`); | ||||
|     } | ||||
|     else { | ||||
| @@ -312,5 +322,20 @@ export class RdDCommands { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async creerSignesDraconiques() { | ||||
|     DialogCreateSigneDraconique.createSigneForActors(); | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   async supprimerSignesDraconiquesEphemeres() { | ||||
|     game.actors.forEach(actor => { | ||||
|       const ephemeres = actor.filterItems(item => Misc.data(item).type = 'signedraconique' && Misc.data(item).data.ephemere) | ||||
|         .map(item => item.id); | ||||
|       if (ephemeres.length > 0) { | ||||
|         actor.deleteEmbeddedDocuments("Item", ephemeres); | ||||
|       } | ||||
|     }); | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -25,7 +25,7 @@ export class De7 extends Die { | ||||
|     return { | ||||
|       type: "d7", | ||||
|       font: "HeuresDraconiques", | ||||
|       fontScale : 0.7, | ||||
|       fontScale: 0.7, | ||||
|       labels: ['1', '2', '3', '4', '5', '6', 'd', '0'], | ||||
|       system: system | ||||
|     } | ||||
| @@ -36,7 +36,7 @@ export class De7 extends Die { | ||||
|     super(termData); | ||||
|   } | ||||
|  | ||||
|   evaluate() { | ||||
|   async evaluate() { | ||||
|     super.evaluate(); | ||||
|     this.explode("x=8"); | ||||
|     return this; | ||||
| @@ -62,7 +62,7 @@ export class DeDraconique extends Die { | ||||
|     return { | ||||
|       type: "dr", | ||||
|       font: "HeuresDraconiques", | ||||
|       fontScale : 0.7, | ||||
|       fontScale: 0.7, | ||||
|       labels: ['1', '2', '3', '4', '5', '6', 'd', '0'], | ||||
|       system: system | ||||
|     } | ||||
| @@ -73,7 +73,7 @@ export class DeDraconique extends Die { | ||||
|     super(termData); | ||||
|   } | ||||
|  | ||||
|   evaluate() { | ||||
|   async evaluate() { | ||||
|     super.evaluate(); | ||||
|     this.explode("x=7"); | ||||
|     return this; | ||||
| @@ -113,7 +113,7 @@ export class DeHeure extends Die { | ||||
|   } | ||||
|  | ||||
|   static getResultLabel(result) { | ||||
|     return img(imagesHeures[result-1]); | ||||
|     return img(imagesHeures[result - 1]); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -124,6 +124,24 @@ export class RdDDice { | ||||
|     CONFIG.Dice.terms[DeHeure.DENOMINATION] = DeHeure; | ||||
|   } | ||||
|  | ||||
|   static async roll(formula, options = { showDice: false }) { | ||||
|     const roll = new Roll(formula); | ||||
|     await roll.evaluate({ async: true }); | ||||
|     if (options.showDice) { | ||||
|       roll.showDice = options.showDice; | ||||
|     } | ||||
|     await RdDDice.show(roll, game.settings.get("core", "rollMode")); | ||||
|     return roll; | ||||
|   } | ||||
|  | ||||
|   static async rollTotal(formula) { | ||||
|     return await RdDDice.roll(formula).total; | ||||
|   } | ||||
|  | ||||
|   static async rollOneOf(array) { | ||||
|     return array[await RdDDice.rollTotal(`1d${array.length} - 1`)]; | ||||
|   } | ||||
|  | ||||
|   static diceSoNiceReady(dice3d) { | ||||
|     for (const system of Object.keys(dice3d.DiceFactory.systems)) { | ||||
|       dice3d.addDicePreset(De7.diceSoNiceData(system)); | ||||
|   | ||||
| @@ -31,6 +31,7 @@ import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; | ||||
| import { RdDHerbes } from "./rdd-herbes.js"; | ||||
| import { RdDItem } from "./item.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
| import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| /*  Foundry VTT Initialization                  */ | ||||
| @@ -117,7 +118,7 @@ Hooks.once("init", async function () { | ||||
|     config: true, | ||||
|     default: true, | ||||
|     type: Boolean | ||||
|   });   | ||||
|   }); | ||||
|   /* -------------------------------------------- */ | ||||
|   game.settings.register("foundryvtt-reve-de-dragon", "appliquer-famine-soif", { | ||||
|     name: "Notifier de la famine et la soif pour", | ||||
| @@ -131,7 +132,7 @@ Hooks.once("init", async function () { | ||||
|       "famine-soif": "la famine et la soif", | ||||
|     }, | ||||
|     default: "aucun" | ||||
|   });   | ||||
|   }); | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   // Set an initiative formula for the system  | ||||
| @@ -167,6 +168,11 @@ Hooks.once("init", async function () { | ||||
|   Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }); | ||||
|   Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorEntiteSheet, { types: ["entite"], makeDefault: true }); | ||||
|   Items.unregisterSheet("core", ItemSheet); | ||||
|   Items.registerSheet("foundryvtt-reve-de-dragon", RdDSigneDraconiqueItemSheet, { | ||||
|     label: "Signe draconique", | ||||
|     types: ["signedraconique"], | ||||
|     makeDefault: true | ||||
|   }); | ||||
|   Items.registerSheet("foundryvtt-reve-de-dragon", RdDItemSheet, { makeDefault: true }); | ||||
|   CONFIG.Combat.documentClass = RdDCombatManager; | ||||
|  | ||||
| @@ -176,7 +182,7 @@ Hooks.once("init", async function () { | ||||
|   RdDDice.init(); | ||||
|   RdDCommands.init(); | ||||
|   RdDCombat.init(); | ||||
|   RdDCombatManager.init(), | ||||
|   RdDCombatManager.init(); | ||||
|   RdDTokenHud.init(); | ||||
|   RdDActor.init(); | ||||
|   RddCompendiumOrganiser.init(); | ||||
| @@ -198,12 +204,12 @@ function messageDeBienvenue() { | ||||
|       ` }); | ||||
|   } | ||||
| } | ||||
|    | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| /*  Foundry VTT Initialization                  */ | ||||
| /* -------------------------------------------- */ | ||||
| Hooks.once("ready", function () { | ||||
|    | ||||
|  | ||||
|   StatusEffects.onReady(); | ||||
|   RdDHerbes.initializeHerbes(); | ||||
|  | ||||
|   | ||||
| @@ -1,14 +1,17 @@ | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
|  | ||||
| const words = [ 'pore', 'pre', 'flor', 'lane', 'turlu', 'pin', 'a', 'alph', 'i', 'onse', 'iane', 'ane', 'zach', 'arri', 'ba', 'bo', 'bi',  | ||||
|                 'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la','al' , 'pul', 'one', 'ner', 'nur' ]; | ||||
|               'alta', 'par', 'pir', 'zor', 'zir', 'de', 'pol', 'tran', 'no', 'la', 'al' , 'pul', 'one', 'ner', 'nur', 'mac', 'mery', | ||||
|               'cat', 'do', 'di', 'der', 'er', 'el', 'far', 'fer', 'go', 'guer', 'hot', 'jor', 'jar', 'ji', 'kri', 'ket', 'lor', 'hur', | ||||
|               'lar', 'lir', 'lu', 'pot', 'pro', 'pra', 'pit', 'qua', 'qui', 're', 'ral', 'sal', 'sen', 'ted', 'to', 'ta', 'lars', 'ver', | ||||
|               'vin', 'ov', 'wal', 'ry', 'ly', '' ]; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| export class RdDNameGen { | ||||
|  | ||||
|   static getName( msg, params ) { | ||||
|     let name = Misc.upperFirst( Misc.rollOneOf(words) + Misc.rollOneOf(words) ) | ||||
|   static async getName( msg, params ) { | ||||
|     let name = Misc.upperFirst( await RdDDice.rollOneOf(words) + await RdDDice.rollOneOf(words) ) | ||||
|     //console.log(name); | ||||
|     ChatMessage.create( { content: `Nom : ${name}`, whisper: ChatMessage.getWhisperRecipients("GM") } ); | ||||
|   } | ||||
|   | ||||
| @@ -149,10 +149,7 @@ export class RdDResolutionTable { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async rollChances(chances, diviseur) { | ||||
|     let myRoll = new Roll("1d100").evaluate( {async: false} ); | ||||
|     myRoll.showDice = chances.showDice; | ||||
|     await RdDDice.show(myRoll); | ||||
|     chances.roll = myRoll.total; | ||||
|     chances.roll = await RdDDice.rollTotal("1d100", {showDice:chances.showDice}); | ||||
|     mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true }); | ||||
|     return chances; | ||||
|   } | ||||
|   | ||||
| @@ -205,6 +205,11 @@ export class RdDRoll extends Dialog { | ||||
|       this.updateRollResult(); | ||||
|       $("#diffLibre").val(this.rollData.diffLibre); | ||||
|     }); | ||||
|     html.find('.roll-signedraconique').change((event) => { | ||||
|       let sortKey = Misc.toInt(event.currentTarget.value); | ||||
|       this.setSelectedSigneDraconique(this.rollData.signes[sortKey]); | ||||
|       this.updateRollResult(); | ||||
|     }); | ||||
|     html.find('#ptreve-variable').change((event) => { | ||||
|       let ptreve = Misc.toInt(event.currentTarget.value); | ||||
|       this.rollData.selectedSort.data.ptreve_reel = ptreve; | ||||
| @@ -276,6 +281,12 @@ export class RdDRoll extends Dialog { | ||||
|     HtmlUtility._showControlWhen($(".div-sort-ptreve-fixe"), !coutVariable); | ||||
|   } | ||||
|  | ||||
|   async setSelectedSigneDraconique(signe){ | ||||
|     this.rollData.signe = signe; | ||||
|     this.rollData.diffLibre =  Misc.data(signe).data.difficulte, | ||||
|     $(".signe-difficulte").text(Misc.toSignedString(this.rollData.diffLibre)); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateRollResult() { | ||||
|     let rollData = this.rollData; | ||||
|   | ||||
| @@ -8,31 +8,20 @@ export class RdDRollTables { | ||||
|     const table = await pack.getDocument(entry._id); | ||||
|     const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"}); | ||||
|     console.log("RdDRollTables", tableName, toChat, ":", draw); | ||||
|     return draw; | ||||
|     return draw.results.length > 0 ? draw.results[0] : undefined; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async drawItemFromRollTable(tableName, toChat) { | ||||
|     const draw = await RdDRollTables.genericGetTableResult(tableName, toChat); | ||||
|     const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined; | ||||
|     if (drawnItemRef.data.collection) { | ||||
|       console.log(drawnItemRef); | ||||
|       const pack = game.packs.get(drawnItemRef.data.collection); | ||||
|       return await pack.getDocument(drawnItemRef.data.resultId); | ||||
|     } | ||||
|     ui.notifications.warn("le tirage ne correspond pas à une entrée d'un Compendium") | ||||
|     return drawnItemRef.text; | ||||
|   static async drawItemFromRollTable(tableName, toChat = false) { | ||||
|     const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat); | ||||
|     const pack = game.packs.get(drawResult.data.collection); | ||||
|     return await pack.getDocument(drawResult.data.resultId); | ||||
|   } | ||||
|    | ||||
|   /* -------------------------------------------- */ | ||||
|   static async drawTextFromRollTable(tableName, toChat) { | ||||
|     const draw = await RdDRollTables.genericGetTableResult(tableName, toChat); | ||||
|     const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined; | ||||
|     if (drawnItemRef.collection) { | ||||
|       ui.notifications.warn("le tirage correspond à une entrée d'un Compendium, on attendait un texte") | ||||
|       return await pack.getDocument(drawnItemRef.resultId); | ||||
|     } | ||||
|     return drawnItemRef.text; | ||||
|     const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat); | ||||
|     return drawResult.data.text; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import { Draconique } from "./tmr/draconique.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { HtmlUtility } from "./html-utility.js"; | ||||
| import { ReglesOptionelles } from "./regles-optionelles.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| export class RdDTMRDialog extends Dialog { | ||||
| @@ -59,8 +60,8 @@ export class RdDTMRDialog extends Dialog { | ||||
|     this.rencontreState = 'aucune'; | ||||
|     this.pixiApp = new PIXI.Application({ width: 720, height: 860 }); | ||||
|  | ||||
|     this.pixiTMR  = new PixiTMR(this, this.pixiApp); | ||||
|     this.cacheTMR = (game.user.isGM) ? false: actor.isTMRCache(); | ||||
|     this.pixiTMR = new PixiTMR(this, this.pixiApp); | ||||
|     this.cacheTMR = (game.user.isGM) ? false : actor.isTMRCache(); | ||||
|  | ||||
|     this.callbacksOnAnimate = []; | ||||
|     if (!this.viewOnly) { | ||||
| @@ -69,7 +70,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     } | ||||
|  | ||||
|     // load the texture we need | ||||
|     this.pixiTMR.load( (loader, resources) => this.createPixiSprites() ); | ||||
|     this.pixiTMR.load((loader, resources) => this.createPixiSprites()); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -142,20 +143,25 @@ export class RdDTMRDialog extends Dialog { | ||||
|   _tokenSortEnReserve(sortEnReserve) { | ||||
|     return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortEnReserve.sort, () => sortEnReserve.coord); | ||||
|   } | ||||
|  | ||||
|   _tokenDemiReve() { | ||||
|     const actorData = Misc.data(this.actor); | ||||
|     return EffetsDraconiques.demiReve.token(this.pixiTMR, actorData, () => actorData.data.reve.tmrpos.coord); | ||||
|   } | ||||
|  | ||||
|   _updateDemiReve() { | ||||
|     if ( !this.cacheTMR) { | ||||
|     if (!this.cacheTMR) { | ||||
|       this._setTokenPosition(this.demiReve); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   _getActorCoord() { | ||||
|     return Misc.data(this.actor).data.reve.tmrpos.coord; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async moveFromKey( move ) { | ||||
|     let pos = TMRUtility.convertToCellPos(Misc.data(this.actor).data.reve.tmrpos.coord); | ||||
|   async moveFromKey(move) { | ||||
|     let pos = TMRUtility.convertToCellPos(this._getActorCoord()); | ||||
|  | ||||
|     if (move == 'top') pos.y -= 1; | ||||
|     if (move == 'bottom') pos.y += 1; | ||||
| @@ -165,7 +171,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|       if (move == 'top-left') pos.y -= 1; | ||||
|       if (move == 'top-right') pos.y -= 1; | ||||
|     } else { | ||||
|       if (move == 'bottom-left')  pos.y += 1; | ||||
|       if (move == 'bottom-left') pos.y += 1; | ||||
|       if (move == 'bottom-right') pos.y += 1; | ||||
|     } | ||||
|  | ||||
| @@ -178,52 +184,54 @@ export class RdDTMRDialog extends Dialog { | ||||
|   async activateListeners(html) { | ||||
|     super.activateListeners(html); | ||||
|  | ||||
|     HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue")); | ||||
|     document.getElementById("tmrrow1").insertCell(0).append(this.pixiApp.view); | ||||
|  | ||||
|     if (this.viewOnly) { | ||||
|       html.find('#lancer-sort').remove(); | ||||
|     } | ||||
|     else { | ||||
|       // Roll Sort | ||||
|       html.find('#lancer-sort').click((event) => { | ||||
|         this.actor.rollUnSort(Misc.data(this.actor).data.reve.tmrpos.coord); | ||||
|       }); | ||||
|     } | ||||
|     if (this.viewOnly) { | ||||
|       html.find('.lancer-sort').remove(); | ||||
|       html.find('.lire-signe-draconique').remove(); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     HtmlUtility._showControlWhen($(".appliquerFatigue"), ReglesOptionelles.isUsing("appliquer-fatigue")); | ||||
|     HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord())); | ||||
|  | ||||
|     // Roll Sort | ||||
|     html.find('.lancer-sort').click((event) => { | ||||
|       this.actor.rollUnSort(this._getActorCoord()); | ||||
|     }); | ||||
|     html.find('.lire-signe-draconique').click((event) => { | ||||
|       this.actor.rollLireSigneDraconique(this._getActorCoord()); | ||||
|     }); | ||||
|  | ||||
|     html.find('#dir-top').click((event) => { | ||||
|       this.moveFromKey("top"); | ||||
|     } ); | ||||
|     }); | ||||
|     html.find('#dir-top-left').click((event) => { | ||||
|       this.moveFromKey("top-left"); | ||||
|     } ); | ||||
|     }); | ||||
|     html.find('#dir-top-right').click((event) => { | ||||
|       this.moveFromKey("top-right"); | ||||
|     } ); | ||||
|     }); | ||||
|     html.find('#dir-bottom-left').click((event) => { | ||||
|       this.moveFromKey("bottom-left"); | ||||
|     } ); | ||||
|     }); | ||||
|     html.find('#dir-bottom-right').click((event) => { | ||||
|       this.moveFromKey("bottom-right"); | ||||
|     } ); | ||||
|     }); | ||||
|     html.find('#dir-bottom').click((event) => { | ||||
|       this.moveFromKey("bottom"); | ||||
|     } ); | ||||
|     }); | ||||
|  | ||||
|      | ||||
|     // Gestion du cout de montée en points de rêve | ||||
|     let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse(); | ||||
|     if (ReglesOptionelles.isUsing("appliquer-fatigue")){ | ||||
|     if (ReglesOptionelles.isUsing("appliquer-fatigue")) { | ||||
|       this.cumulFatigue += this.fatigueParCase; | ||||
|     } | ||||
|     await this.actor.reveActuelIncDec(reveCout); | ||||
|  | ||||
|     // Le reste... | ||||
|     this.updateValuesDisplay(); | ||||
|     let tmr = TMRUtility.getTMR(Misc.data(this.actor).data.reve.tmrpos.coord); | ||||
|     let tmr = TMRUtility.getTMR(this._getActorCoord()); | ||||
|     await this.manageRencontre(tmr, () => { | ||||
|       this.postRencontre(tmr); | ||||
|     }); | ||||
| @@ -231,16 +239,18 @@ export class RdDTMRDialog extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   updateValuesDisplay() { | ||||
|     HtmlUtility._showControlWhen($(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord())); | ||||
|  | ||||
|     let ptsreve = document.getElementById("tmr-pointsreve-value"); | ||||
|     const actorData = Misc.data(this.actor); | ||||
|     ptsreve.innerHTML = actorData.data.reve.reve.value; | ||||
|     const coord = this._getActorCoord(); | ||||
|  | ||||
|     let tmrpos = document.getElementById("tmr-pos"); | ||||
|     if ( this.cacheTMR ) { | ||||
|       tmrpos.innerHTML = '?? ('+ TMRUtility.getTMRType( actorData.data.reve.tmrpos.coord ) + ')';   | ||||
|     if (this.cacheTMR) { | ||||
|       tmrpos.innerHTML = '?? (' + TMRUtility.getTMRType(coord) + ')'; | ||||
|     } else { | ||||
|       let tmr = TMRUtility.getTMR(actorData.data.reve.tmrpos.coord); | ||||
|       tmrpos.innerHTML = actorData.data.reve.tmrpos.coord + " (" + tmr.label + ")"; | ||||
|       tmrpos.innerHTML = coord + " (" + TMRUtility.getTMRLabel(coord) + ")"; | ||||
|     } | ||||
|  | ||||
|     let etat = document.getElementById("tmr-etatgeneral-value"); | ||||
| @@ -249,7 +259,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     let refoulement = document.getElementById("tmr-refoulement-value"); | ||||
|     refoulement.innerHTML = actorData.data.reve.refoulement.value; | ||||
|  | ||||
|     if (ReglesOptionelles.isUsing("appliquer-fatigue")){ | ||||
|     if (ReglesOptionelles.isUsing("appliquer-fatigue")) { | ||||
|       let fatigueItem = document.getElementById("tmr-fatigue-table"); | ||||
|       //console.log("Refresh : ", actorData.data.sante.fatigue.value); | ||||
|       fatigueItem.innerHTML = "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(actorData.data.sante.fatigue.value, actorData.data.sante.endurance.max).html() + "</table>"; | ||||
| @@ -373,7 +383,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|       rencontre: this.currentRencontre, | ||||
|       nbRounds: 1, | ||||
|       canClose: false, | ||||
|       tmr: TMRUtility.getTMR(Misc.data(this.actor).data.reve.tmrpos.coord) | ||||
|       tmr: TMRUtility.getTMR(this._getActorCoord()) | ||||
|     } | ||||
|  | ||||
|     await this._tentativeMaitrise(rencontreData); | ||||
| @@ -414,7 +424,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     else if (rencData.rolled.isEchec && rencData.rencontre.isPersistant) { | ||||
|       setTimeout(() => { | ||||
|         rencData.nbRounds++; | ||||
|         if (ReglesOptionelles.isUsing("appliquer-fatigue")){ | ||||
|         if (ReglesOptionelles.isUsing("appliquer-fatigue")) { | ||||
|           this.cumulFatigue += this.fatigueParCase; | ||||
|         } | ||||
|         this._tentativeMaitrise(rencData); | ||||
| @@ -523,11 +533,11 @@ export class RdDTMRDialog extends Dialog { | ||||
|     if (rencontre) { | ||||
|       return rencontre; | ||||
|     } | ||||
|     let myRoll = new Roll("1d7").evaluate( { async: false} ).total; | ||||
|     let myRoll = await RdDDice.rollTotal("1d7"); | ||||
|     if (TMRUtility.isForceRencontre() || myRoll == 7) { | ||||
|       return await this.rencontreTMRRoll(tmr, this.actor.isRencontreSpeciale()); | ||||
|     } | ||||
|     let locTMR = (this.cacheTMR) ? "??": tmr.label + " (" + tmr.coord + ")"; | ||||
|     let locTMR = (this.cacheTMR) ? "??" : tmr.label + " (" + tmr.coord + ")"; | ||||
|     this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR); | ||||
|   } | ||||
|  | ||||
| @@ -584,7 +594,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|       await this._rollMaitriseCaseHumide(rollData); | ||||
|       return; | ||||
|     } | ||||
|     rollData.poesie = Poetique.getExtrait(); | ||||
|     rollData.poesie = await Poetique.getExtrait(); | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData) | ||||
| @@ -701,7 +711,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|     } | ||||
|     this.toclose = rollData.rolled.isEchec; | ||||
|  | ||||
|     rollData.poesie = Poetique.getExtrait(); | ||||
|     rollData.poesie = await Poetique.getExtrait(); | ||||
|     ChatMessage.create({ | ||||
|       whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData) | ||||
| @@ -852,7 +862,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async _onClickTMRPos(eventPos) { | ||||
|     let currentPos = TMRUtility.convertToCellPos(Misc.data(this.actor).data.reve.tmrpos.coord); | ||||
|     let currentPos = TMRUtility.convertToCellPos(this._getActorCoord()); | ||||
|  | ||||
|     console.log("deplacerDemiReve >>>>", currentPos, eventPos); | ||||
|  | ||||
| @@ -861,7 +871,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|  | ||||
|     // Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter) | ||||
|     let deplacementType = this._calculDeplacement(targetCoord, currentCoord, currentPos, eventPos); | ||||
|      | ||||
|  | ||||
|     // Si le deplacement est valide | ||||
|     if (deplacementType == 'normal' || deplacementType == 'saut') { | ||||
|       await this._deplacerDemiReve(targetCoord, deplacementType); | ||||
| @@ -901,8 +911,8 @@ export class RdDTMRDialog extends Dialog { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   externalRefresh( tmrData ) { | ||||
|     this.cacheTMR = (game.user.isGM) ? false: this.actor.isTMRCache(); | ||||
|   externalRefresh(tmrData) { | ||||
|     this.cacheTMR = (game.user.isGM) ? false : this.actor.isTMRCache(); | ||||
|     this.createPixiSprites(); | ||||
|     this.forceDemiRevePositionView(); | ||||
|     this.updateValuesDisplay(); | ||||
| @@ -920,11 +930,10 @@ export class RdDTMRDialog extends Dialog { | ||||
|     // Gestion cases spéciales type Trou noir, etc | ||||
|     tmr = await this.manageTmrInnaccessible(tmr); | ||||
|  | ||||
|     this.actor.updateCoordTMR(tmr.coord); | ||||
|     await this.actor.updateCoordTMR(tmr.coord); | ||||
|  | ||||
|     this._updateDemiReve(); | ||||
|     if (ReglesOptionelles.isUsing("appliquer-fatigue")){ | ||||
|     if (ReglesOptionelles.isUsing("appliquer-fatigue")) { | ||||
|       this.cumulFatigue += this.fatigueParCase; | ||||
|     } | ||||
|     this.updateValuesDisplay(); | ||||
| @@ -998,7 +1007,7 @@ export class RdDTMRDialog extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   _setTokenPosition(token) { | ||||
|     if ( !this.cacheTMR) { | ||||
|     if (!this.cacheTMR) { | ||||
|       this.pixiTMR.setPosition(token.sprite, TMRUtility.convertToCellPos(token.coordTMR())); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import { Grammar } from "./grammar.js"; | ||||
| import { TMRUtility } from "./tmr-utility.js"; | ||||
| import { DialogItemAchat } from "./dialog-item-achat.js"; | ||||
| import { ReglesOptionelles } from "./regles-optionelles.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| // This table starts at 0 -> niveau -10 | ||||
| @@ -140,6 +141,7 @@ export class RdDUtility { | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item-monnaie-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item-meditation-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/competence-carac-defaut.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/competence-base.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/enum-aspect-tarot.html', | ||||
| @@ -204,7 +206,8 @@ export class RdDUtility { | ||||
|       '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-fabriquer-potion-base.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html' | ||||
|     ]; | ||||
|  | ||||
|     Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null')); | ||||
| @@ -271,6 +274,7 @@ export class RdDUtility { | ||||
|     formData.munitions = this.checkNull(formData.itemsByType['munition']); | ||||
|     formData.herbes = this.checkNull(formData.itemsByType['herbe']); | ||||
|     formData.sorts = this.checkNull(formData.itemsByType['sort']); | ||||
|     formData.signesdraconiques = this.checkNull(formData.itemsByType['signedraconique']); | ||||
|     formData.queues = this.checkNull(formData.itemsByType['queue']); | ||||
|     formData.souffles = this.checkNull(formData.itemsByType['souffle']); | ||||
|     formData.ombres = this.checkNull(formData.itemsByType['ombre']); | ||||
| @@ -441,8 +445,8 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static getLocalisation(type = 'personnage') { | ||||
|     let result = new Roll("1d20").roll().total; | ||||
|   static async getLocalisation(type = 'personnage') { | ||||
|     let result = await RdDDice.rollTotal("1d20"); | ||||
|     let txt = "" | ||||
|     if (type == 'personnage') { | ||||
|       if (result <= 3) txt = "Jambe, genou, pied, jarret"; | ||||
| @@ -474,15 +478,6 @@ export class RdDUtility { | ||||
|     return duplicate(table[0]); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static _evaluatePerte(formula, over20) { | ||||
|     console.log("_evaluatePerte", formula, over20); | ||||
|     let perte = new Roll(formula, { over20: over20 }); | ||||
|     perte.evaluate(); | ||||
|     return perte.total; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static currentFatigueMalus(value, max) { | ||||
|     if (ReglesOptionelles.isUsing("appliquer-fatigue")) { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
| import { TMRUtility } from "./tmr-utility.js"; | ||||
| import { TMRType } from "./tmr-utility.js"; | ||||
|  | ||||
| @@ -268,7 +269,7 @@ const rencontresStandard = [ | ||||
|   { code: "reflet", name: "Reflet d'ancien Rêve", type: "reflet", genre: "m", force: "2d6", isPersistant: true }, | ||||
|   { code: "tbblanc", name: "Tourbillon blanc", type: "tbblanc", genre: "m", force: "2d6", isPersistant: true }, | ||||
|   { code: "tbnoir", name: "Tourbillon noir", type: "tbnoir", genre: "m", force: "2d8", isPersistant: true }, | ||||
|   { code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1ddr + 7", refoulement: 2, quitterTMR: true } | ||||
|   { code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1dr + 7", refoulement: 2, quitterTMR: true } | ||||
| ]; | ||||
|  | ||||
| const rencontresPresentCite = [ | ||||
| @@ -324,7 +325,7 @@ export class TMRRencontres { | ||||
|       return false; | ||||
|     } | ||||
|     if (!roll || roll <= 0 || roll > 100) { | ||||
|       roll = new Roll("1d100").evaluate().total; | ||||
|       roll = await RdDDice.rollTotal("1d100"); | ||||
|     } | ||||
|     let rencontre = await TMRRencontres.getRencontreAleatoire(terrain, roll); | ||||
|     ChatMessage.create({ | ||||
| @@ -356,15 +357,13 @@ export class TMRRencontres { | ||||
|   /* -------------------------------------------- */ | ||||
|   static async getRencontreAleatoire(terrain, roll = undefined) { | ||||
|     if (!roll || roll <= 0 || roll > 100) { | ||||
|       roll = new Roll("1d100").evaluate({ async: false }).total; | ||||
|       roll = await RdDDice.rollTotal("1d100"); | ||||
|     } | ||||
|     terrain = Grammar.toLowerCaseNoAccent(terrain); | ||||
|     //console.log("getRencontreAleatoire", terrain, roll); | ||||
|     const code = tableRencontres[terrain].find(it => it.range[0] <= roll && roll <= it.range[1]).code; | ||||
|     const rencontre = duplicate(rencontresStandard.find(it => it.code == code)); | ||||
|     rencontre.roll = roll; | ||||
|     await TMRRencontres.evaluerForceRencontre(rencontre); | ||||
|     //console.log(rencontre); | ||||
|     return rencontre; | ||||
|   } | ||||
|  | ||||
| @@ -373,20 +372,14 @@ export class TMRRencontres { | ||||
|     const rencontre = duplicate( | ||||
|       (index && index >= 0 && index < mauvaisesRencontres.length) | ||||
|         ? mauvaisesRencontres[index] | ||||
|         : Misc.rollOneOf(mauvaisesRencontres)); | ||||
|         : await RdDDice.rollOneOf(mauvaisesRencontres)); | ||||
|     await TMRRencontres.evaluerForceRencontre(rencontre); | ||||
|     return rencontre; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async evaluerForceRencontre(rencontre) { | ||||
|     if (TMRRencontres.isReveDeDragon(rencontre)) { | ||||
|       const ddr =  new Roll("1dr + 7").evaluate(); | ||||
|       rencontre.force = 7 + ddr.total; | ||||
|     } | ||||
|     else { | ||||
|       rencontre.force = new Roll(rencontre.force).evaluate({ async: false }).total; | ||||
|     } | ||||
|     rencontre.force = await new Roll(rencontre.force).evaluate().total; | ||||
|     return rencontre.force; | ||||
|   } | ||||
|  | ||||
| @@ -426,14 +419,14 @@ export class TMRRencontres { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static msgEchecPasseurFou(tmrData) { | ||||
|   static async msgEchecPasseurFou(tmrData) { | ||||
|     tmrData.sortReserve = Misc.templateData(tmrData.actor).reve.reserve.list[0]; | ||||
|     if (tmrData.sortReserve) { | ||||
|       // Passeur fou positionne sur la case d'un ort en réserve // TODO : Choisir le sort le plus loin ou au hasard | ||||
|       tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord); | ||||
|     } else { | ||||
|       // Déplacement aléatoire de la force du Passeur Fou | ||||
|       const newCoord = Misc.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force)); | ||||
|       const newCoord = await RdDDice.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force)); | ||||
|       tmrData.newTMR = TMRUtility.getTMR(newCoord); | ||||
|     } | ||||
|     if (tmrData.sortReserve) { | ||||
| @@ -472,7 +465,7 @@ export class TMRRencontres { | ||||
|   static async _toubillonner(tmrDialog, actor, cases) { | ||||
|     let coord = Misc.templateData(actor).reve.tmrpos.coord; | ||||
|     for (let i = 0; i < cases; i++) { | ||||
|       coord = TMRUtility.deplaceTMRAleatoire(actor, coord).coord; | ||||
|       coord = await TMRUtility.deplaceTMRAleatoire(actor, coord).coord; | ||||
|     } | ||||
|     await tmrDialog.forceDemiRevePosition(coord) | ||||
|   } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { TMRRencontres } from "./tmr-rencontres.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { Grammar } from "./grammar.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| const TMRMapping = { | ||||
| @@ -346,6 +347,12 @@ export class TMRUtility { | ||||
|     return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label; | ||||
|   } | ||||
|  | ||||
|   static listSelectedTMR(typesTMR) { | ||||
|     return Object.values(TMRType).map(value => Misc.upperFirst(value.name)) | ||||
|       .sort() | ||||
|       .map(name => { return { name: name, selected: typesTMR.includes(name) } }); | ||||
|   } | ||||
|  | ||||
|   static isCaseHumide(tmr) { | ||||
|     return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais'; | ||||
|   } | ||||
| @@ -380,13 +387,13 @@ export class TMRUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static getDirectionPattern() { | ||||
|     return Misc.rollOneOf(tmrRandomMovePatten); | ||||
|   static async getDirectionPattern() { | ||||
|     return await RdDDice.rollOneOf(tmrRandomMovePatten); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static deplaceTMRAleatoire(actor, coord) { | ||||
|     return TMRUtility.deplaceTMRSelonPattern(actor, coord, TMRUtility.getDirectionPattern(), 1); | ||||
|   static async deplaceTMRAleatoire(actor, coord) { | ||||
|     return TMRUtility.deplaceTMRSelonPattern(actor, coord, await TMRUtility.getDirectionPattern(), 1); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -418,8 +425,8 @@ export class TMRUtility { | ||||
|     return TMRUtility.filterTMR(filter).map(it => it.coord); | ||||
|   } | ||||
|  | ||||
|   static getTMRAleatoire(filter = it => true) { | ||||
|     return Misc.rollOneOf(TMRUtility.filterTMR(filter)) | ||||
|   static async getTMRAleatoire(filter = it => true) { | ||||
|     return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter)) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { Grammar } from "../grammar.js"; | ||||
| import { Misc } from "../misc.js"; | ||||
| import { RdDDice } from "../rdd-dice.js"; | ||||
| import { tmrColors, tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js"; | ||||
| import { Draconique } from "./draconique.js"; | ||||
|  | ||||
| @@ -31,7 +32,7 @@ export class Conquete extends Draconique { | ||||
|   async _creerConquete(actor, queue) { | ||||
|     let existants = actor.data.items.filter(it => this.isCase(it)).map(it => Misc.data(it).data.coord); | ||||
|     let possibles = TMRUtility.filterTMR(tmr => !TMRUtility.isCaseHumide(tmr) && !existants.includes(tmr.coord)); | ||||
|     let conquete = Misc.rollOneOf(possibles); | ||||
|     let conquete =await RdDDice.rollOneOf(possibles); | ||||
|     await this.createCaseTmr(actor, 'Conquête: ' + conquete.label, conquete, queue.id); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ export class Debordement extends Draconique { | ||||
|   manualMessage() { return false } | ||||
|   async onActorCreateOwned(actor, souffle) { | ||||
|     const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); | ||||
|     const tmr = TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord))); | ||||
|     const tmr = await TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord))); | ||||
|     await this.createCaseTmr(actor, 'Debordement: ' + tmr.label, tmr, souffle.id); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { Grammar } from "../grammar.js"; | ||||
| import { Misc } from "../misc.js"; | ||||
| import { RdDDice } from "../rdd-dice.js"; | ||||
| import { tmrColors, tmrConstants, tmrTokenZIndex, TMRType, TMRUtility } from "../tmr-utility.js"; | ||||
| import { Draconique } from "./draconique.js"; | ||||
|  | ||||
| @@ -13,7 +14,7 @@ export class Desorientation extends Draconique { | ||||
|   manualMessage() { return false } | ||||
|  | ||||
|   async onActorCreateOwned(actor, souffle) { | ||||
|     const type = Misc.rollOneOf(this._typesPossibles(actor)); | ||||
|     const type = await RdDDice.rollOneOf(this._typesPossibles(actor)); | ||||
|     console.log("désorientation", type); | ||||
|     souffle.name += ": " + TMRType[type].name; | ||||
|     await this._creerCasesTmr(actor, type, souffle); | ||||
|   | ||||
| @@ -13,7 +13,7 @@ export class Pelerinage extends Draconique { | ||||
|   manualMessage() { return false } | ||||
|  | ||||
|   async onActorCreateOwned(actor, queue) {  | ||||
|     let tmr = TMRUtility.getTMRAleatoire(); | ||||
|     let tmr = await TMRUtility.getTMRAleatoire(); | ||||
|     await this.createCaseTmr(actor, 'Pèlerinage: ' + tmr.label, tmr, queue.id); | ||||
|   } | ||||
|    | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { Grammar } from "../grammar.js"; | ||||
| import { tmrColors, tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js"; | ||||
| import { RdDDice } from "../rdd-dice.js"; | ||||
| import { tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js"; | ||||
| import { Draconique } from "./draconique.js"; | ||||
|  | ||||
| export class Periple extends Draconique { | ||||
| @@ -13,7 +14,7 @@ export class Periple extends Draconique { | ||||
|   manualMessage() { return false } | ||||
|  | ||||
|   async onActorCreateOwned(actor, souffle) { | ||||
|     let terrain = new Roll("1d2").evaluate().total == 1 ? 'sanctuaire' : 'necropole'; | ||||
|     let terrain = (await RdDDice.rollTotal("1d2")) == 1 ? 'sanctuaire' : 'necropole'; | ||||
|     let tmrs = TMRUtility.getListTMR(terrain); | ||||
|     for (let tmr of tmrs) { | ||||
|       await this.createCaseTmr(actor, 'Périple: ' + tmr.label, tmr, souffle.id); | ||||
|   | ||||
| @@ -12,7 +12,7 @@ export class ReserveExtensible extends Draconique { | ||||
|   manualMessage() { return "Vous pouvez re-configurer votre Réserve extensible" } | ||||
|   async onActorCreateOwned(actor, tete) { | ||||
|     const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); | ||||
|     const tmr = TMRUtility.getTMRAleatoire(it => !(it.type == 'fleuve' || existants.includes(it.coord))); | ||||
|     const tmr = await TMRUtility.getTMRAleatoire(it => !(it.type == 'fleuve' || existants.includes(it.coord))); | ||||
|     await this.createCaseTmr(actor, "Nouvelle Réserve extensible", tmr, tete.id); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ export class TrouNoir extends Draconique { | ||||
|  | ||||
|   async onActorCreateOwned(actor, souffle) { | ||||
|     const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); | ||||
|     const tmr = TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord))); | ||||
|     const tmr = await TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord))); | ||||
|     await this.createCaseTmr(actor, 'Trou noir: ' + tmr.label, tmr, souffle.id); | ||||
|   } | ||||
|  | ||||
|   | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -577,7 +577,7 @@ | ||||
| "Item": { | ||||
|   "types": ["objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle",  | ||||
|             "tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique",  | ||||
|             "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson" ], | ||||
|             "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "signedraconique" ], | ||||
|   "objet": { | ||||
|     "description": "", | ||||
|     "quantite": 1, | ||||
| @@ -868,6 +868,18 @@ | ||||
|     "encombrement": 0, | ||||
|     "quantite": 1, | ||||
|     "cout": 0 | ||||
|   }, | ||||
|   "signedraconique": { | ||||
|     "typesTMR": [], | ||||
|     "ephemere": true, | ||||
|     "duree": "1 round", | ||||
|     "difficulte": 0, | ||||
|     "valeur": { | ||||
|       "norm": 3, | ||||
|       "sign": 5, | ||||
|       "part": 10 | ||||
|     }, | ||||
|     "description": "" | ||||
|   } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -310,7 +310,7 @@ | ||||
|         <ul class="item-list alterne-list"> | ||||
|           {{#each taches as |tache id|}} | ||||
|           <li class="item flexrow list-item" data-item-id="{{tache._id}}"><span class="competence-title tache-label"><a>{{tache.name}} ({{tache.data.points_de_tache_courant}}/{{tache.data.points_de_tache}})</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a> | ||||
|               <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
| @@ -340,7 +340,7 @@ | ||||
|         <ul class="item-list alterne-list"> | ||||
|           {{#each jeux as |jeu id|}} | ||||
|           <li class="item flexrow list-item" data-item-id="{{jeu._id}}"><span class="competence-title jeu-label"><a>{{jeu.name}} (base {{jeu.data.base}})</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a> | ||||
|               <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
| @@ -351,7 +351,7 @@ | ||||
|         <ul class="item-list alterne-list"> | ||||
|           {{#each recettesAlchimiques as |recette id|}} | ||||
|           <li class="item flexrow list-item" data-item-id="{{recette._id}}"><span class="competence-title recette-label item-edit"><a>{{recette.name}}</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a> | ||||
|               <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
| @@ -384,20 +384,28 @@ | ||||
|             </li> | ||||
|             {{/if}} | ||||
|             <li class="item flexrow"> | ||||
|               <span class="competence-label">Demi rêve :</span>  | ||||
|               <span> | ||||
|               {{#if options.isGM}} | ||||
|                 {{caseTmr-label data.reve.tmrpos.coord}} | ||||
|               <span class="competence-label flex-shrink">Demi rêve : | ||||
|                 <span>{{caseTmr-label data.reve.tmrpos.coord}}</span> | ||||
|               </span>  | ||||
|               <span> | ||||
|                 <input class="competence-value" type="text" name="data.reve.tmrpos.coord" value="{{data.reve.tmrpos.coord}}" data-dtype="String"/> | ||||
|               </span>  | ||||
|                | ||||
|               {{else}} | ||||
|               <span class="competence-label flex-shrink">Demi rêve : | ||||
|                 {{#unless hautreve.cacheTMR}} | ||||
|                 <span>{{caseTmr-label data.reve.tmrpos.coord}}</span> | ||||
|                 {{/unless}} | ||||
|               </span>  | ||||
|               <span> | ||||
|                 {{#if hautreve.cacheTMR}} | ||||
|                 ?? | ||||
|                 {{else}} | ||||
|                 {{caseTmr-label data.reve.tmrpos.coord}} | ||||
|                 {{data.reve.tmrpos.coord}} | ||||
|                 {{/if}} | ||||
|               {{/if}} | ||||
|               </span> | ||||
|               {{/if}} | ||||
|             </li> | ||||
|             {{/if}} | ||||
|             <li class="item flexrow"> | ||||
| @@ -414,45 +422,65 @@ | ||||
|               <span class="competence-label">Refoulement : </span> | ||||
|               <span> | ||||
|               {{#if options.isGM}} | ||||
|                 <input class="competence-value" type="text" name="data.reve.refoulement.value" value="{{data.reve.refoulement.value}}" data-dtype="Number"/> | ||||
|               <input class="competence-value" type="text" name="data.reve.refoulement.value" value="{{data.reve.refoulement.value}}" data-dtype="Number"/> | ||||
|               {{else}} | ||||
|                 {{data.reve.refoulement.value}} | ||||
|               {{data.reve.refoulement.value}} | ||||
|               {{/if}} | ||||
|               </span> | ||||
|             </li> | ||||
|           </ul> | ||||
|         </div> | ||||
|         <hr> | ||||
|         {{#if data.attributs.hautrevant.value}} | ||||
|         <h3>Sorts:</h3> | ||||
|             </span> | ||||
|           </li> | ||||
|         </ul> | ||||
|       </div> | ||||
|       <hr> | ||||
|       {{#if data.attributs.hautrevant.value}} | ||||
|         {{#if options.isGM}} | ||||
|         <h3>Signes draconiques</h3> | ||||
|         <ul class="item-list alterne-list"> | ||||
|           {{#each sorts as |mysort key|}} | ||||
|           <li class="item list-item flexrow" data-item-id="{{mysort._id}}" data-attribute="{{key}}"> | ||||
|             <span class="sort-label"> <a data-id="{{mysort._id}}">{{mysort.name}}</a></span>  | ||||
|             <span>{{mysort.data.draconic}} / {{mysort.data.difficulte}}</span> | ||||
|             <div class="item-controls"> | ||||
|           {{#each signesdraconiques as |signe key|}} | ||||
|           <li class="item list-item flexrow" data-item-id="{{signe._id}}" data-attribute="{{key}}"> | ||||
|             <span class="display-label flex-grow"> <a data-item-id="{{signe._id}}">{{signe.name}}</a></span>  | ||||
|             <span class="flex-shrink">{{signe.data.difficulte}}</span> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
|           {{/each}} | ||||
|         </ul> | ||||
|  | ||||
|         <h3>Sorts en Réserve:</h3> | ||||
|         {{/if}} | ||||
|         <h3>Sorts:</h3> | ||||
|         <ul class="item-list alterne-list"> | ||||
|           {{#each hautreve.sortsReserve as |reserve key|}} | ||||
|           <li class="item list-item flexrow" data-item-id="{{mysort._id}}" data-attribute="{{key}}"> | ||||
|             <img class="sheet-competence-img" src="{{reserve.sort.img}}" /> | ||||
|             <span class="sort-label"> {{reserve.sort.name}} - {{reserve.coord}} - {{caseTmr-label reserve.coord}} - r{{reserve.sort.data.ptreve_reel}}</span>  | ||||
|           {{#each sorts as |sort key|}} | ||||
|           <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}"> | ||||
|             <span class="display-label flex-grow"> <a data-item-id="{{sort._id}}">{{sort.name}}</a></span>  | ||||
|             <span>{{sort.data.draconic}} / {{sort.data.difficulte}}</span> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
|           {{/each}} | ||||
|         </ul> | ||||
|  | ||||
|          | ||||
|         <h3>Sorts en Réserve:</h3> | ||||
|         <ul class="item-list alterne-list"> | ||||
|           {{#each hautreve.sortsReserve as |reserve key|}} | ||||
|           <li class="item list-item flexrow" data-item-id="{{reserve._id}}" data-attribute="{{key}}"> | ||||
|             <img class="sheet-competence-img" src="{{reserve.sort.img}}" /> | ||||
|             <span class="display-label flex-grow">{{reserve.sort.name}}</span>  | ||||
|             <span class="flex-shrink">r{{reserve.sort.data.ptreve_reel}}</span>  | ||||
|             <span class="flex-shrink">{{reserve.coord}}</span>  | ||||
|             <span>{{caseTmr-label reserve.coord}}</span>  | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
|           {{/each}} | ||||
|         </ul> | ||||
|          | ||||
|         <h3>Méditations:</h3> | ||||
|         <ul class="item-list"> | ||||
|           {{#each meditations as |meditation key|}} | ||||
|           <li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}"> | ||||
|             <span class="meditation-label"><a data-id="{{meditation._id}}">{{meditation.name}} - {{meditation.data.competence}}</a></span>  | ||||
|             <div class="item-controls"> | ||||
|             <span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.data.competence}}</a></span>  | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-edit" title="Editer"><i class="fas fa-edit"></i></a> | ||||
|               <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
| @@ -466,8 +494,8 @@ | ||||
|         <ul class="flex-group-left"> | ||||
|           {{#each queues as |queue key|}} | ||||
|           <li class="item flexrow" data-attribute={{key}} data-item-id="{{queue._id}}"> | ||||
|             <span class="queuesouffle-label"> <a data-item-id="{{queue._id}}">{{queue.name}}</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <span class="display-label flex-grow"><a data-item-id="{{queue._id}}">{{queue.name}}</a></span> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
| @@ -477,8 +505,8 @@ | ||||
|         <ul class="item-list"> | ||||
|           {{#each souffles as |souffle key|}} | ||||
|           <li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}"> | ||||
|             <span class="queuesouffle-label"> <a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <span class="display-label flex-grow"><a data-item-id="{{souffle._id}}">{{souffle.name}}</a></span> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
| @@ -488,8 +516,8 @@ | ||||
|         <ul class="item-list"> | ||||
|           {{#each tetes as |tete key|}} | ||||
|           <li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}"> | ||||
|             <span class="queuesouffle-label"> <a data-item-id="{{tete._id}}">{{tete.name}}</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <span class="display-label flex-grow"><a data-item-id="{{tete._id}}">{{tete.name}}</a></span> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
| @@ -499,8 +527,8 @@ | ||||
|         <ul class="item-list"> | ||||
|           {{#each ombres as |ombre key|}} | ||||
|           <li class="item flexrow" data-attribute={{key}} data-item-id="{{ombre._id}}"> | ||||
|             <span class="queuesouffle-label"> <a data-item-id="{{ombre._id}}">{{ombre.name}}</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <span class="display-label flex-grow"><a data-item-id="{{ombre._id}}">{{ombre.name}}</a></span> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
| @@ -512,8 +540,12 @@ | ||||
|         <ul class="item-list"> | ||||
|           {{#each hautreve.rencontres as |rencontre key|}} | ||||
|           <li class="item flexrow" data-item-id="{{key}}" data-attribute="{{key}}"> | ||||
|             <span class="case-label"><a data-id="{{key}}">{{rencontre.rencontre.name}} - {{rencontre.coord}} {{#if rencontre.rencontre.date}}({{rencontre.rencontre.date}} - {{rencontre.rencontre.heure}}){{/if}}</a></span>  | ||||
|             <div class="item-controls"> | ||||
|             <span class="display-label flex-grow"><a data-item-id="{{key}}">{{rencontre.rencontre.name}} - {{rencontre.coord}}</a></span>  | ||||
|             <span class="flex-shrink">{{caseTmr-label reserve.coord}}</span>  | ||||
|             {{#if rencontre.rencontre.date}} | ||||
|             <span>({{rencontre.rencontre.date}} - {{rencontre.rencontre.heure}})</span>  | ||||
|             {{/if}} | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control rencontre-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|             </div> | ||||
|           </li> | ||||
| @@ -523,11 +555,11 @@ | ||||
|         <h3>Cases Spéciales:</h3> | ||||
|         <ul class="item-list"> | ||||
|           {{#each hautreve.casesTmr as |casetmr key|}} | ||||
|           <li class="item" data-item-id="{{casetmr._id}}" data-attribute="{{key}}"> | ||||
|             <span class="item-controls"> | ||||
|           <li class="item flexrow" data-item-id="{{casetmr._id}}" data-attribute="{{key}}"> | ||||
|             <span class="display-label"><a data-item-id="{{casetmr._id}}">{{casetmr.name}}</a></span>  | ||||
|             <span class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|             </span> | ||||
|             <span class="case-label"><a data-id="{{casetmr._id}}">{{casetmr.name}}</a></span>  | ||||
|           </li> | ||||
|           {{/each}} | ||||
|         </ul> | ||||
| @@ -544,7 +576,7 @@ | ||||
|             <span class="competence-title competence-label">{{piece.name}}</span> | ||||
|             <span class="competence-title competence-label">{{piece.data.quantite}}</span> | ||||
|             <span class="competence-title"><a class="monnaie-plus">+</a><a class="monnaie-moins">-</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control item-edit" title="Editer"><i class="fas fa-edit"></i></a> | ||||
|               <a class="item-control item-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|           </div> | ||||
| @@ -589,7 +621,7 @@ | ||||
|           <li class="item flexrow list-item" data-actor-id="{{monture.id}}"> | ||||
|             <img class="sheet-competence-img" src="{{monture.img}}" title="{{monture.name}}"/> | ||||
|             <span class="competence-title subacteur-label"><a>{{monture.name}}</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control subacteur-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|           </div> | ||||
|           </li> | ||||
| @@ -604,7 +636,7 @@ | ||||
|             <span class="competence-title subacteur-label"><a>{{vehicule.name}}</a></span> | ||||
|             <span class="competence-title">{{vehicule.categorie}}</span> | ||||
|             <span class="competence-title">{{vehicule.structure}}</span> | ||||
|             <div class="item-controls"> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control subacteur-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|           </div> | ||||
|           </li> | ||||
| @@ -617,7 +649,7 @@ | ||||
|           <li class="item flexrow list-item" data-actor-id="{{suivant.id}}"> | ||||
|             <img class="sheet-competence-img" src="{{suivant.img}}" title="{{suivant.name}}"/> | ||||
|             <span class="competence-title subacteur-label"><a>{{suivant.name}}</a></span> | ||||
|             <div class="item-controls"> | ||||
|             <div class="item-controls flex-shrink"> | ||||
|               <a class="item-control subacteur-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|           </div> | ||||
|           </li> | ||||
|   | ||||
							
								
								
									
										11
									
								
								templates/chat-resultat-lecture-signedraconique.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								templates/chat-resultat-lecture-signedraconique.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| <img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}" /> | ||||
| <h4>{{alias}} lit le signe {{signe.name}}</h4> | ||||
| {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} | ||||
| <hr> | ||||
| <div> | ||||
|   {{#if rolled.isSuccess}} | ||||
|   Vous avez gagné {{xpSort}} points d'expérience en sorts dans la {{competence.name}}. | ||||
|   {{else}} | ||||
|   Vous n'avez pas pu interpréter le signe draconique. | ||||
|   {{/if}} | ||||
| </div> | ||||
| @@ -6,11 +6,10 @@ | ||||
| <hr> | ||||
| <div> | ||||
|   {{#if rolled.isSuccess}} | ||||
|   {{alias}} aperçoit un signe Draconique fugitif, qu'il faut aller lire en <strong>{{meditation.data.tmr}}</strong> en réussissant un test <strong>d'INTELLECT/Draconic à {{diffLecture}}</strong>. | ||||
|   Selon le résultat de votre lecture, vous gagnerez les points suivants en Sort: 3 pour une Normale, 5 pour une Significative, 10 pour une Particulière. | ||||
|   Vous apercevez un signe draconique éphémère, qu'il faut aller lire en <strong>{{meditation.data.tmr}}</strong>. | ||||
|   {{else}} | ||||
|   {{alias}} a échoué dans sa méditation et ne voit aucun signe Draconique. | ||||
|   Votre méditation ne porte pas ses fruits, vous ne voyez aucun signe Draconique. | ||||
|   {{/if}} | ||||
|   <br><span>Vous vous êtes fatigué de 2 cases.</span> | ||||
|   {{#if rolled.isETotal}}<br><span>Votre échec total augmente de 1 la difficulté de la méditation!</span>{{/if~}} | ||||
|   {{#if rolled.isEPart}}<br><span>Votre échec {{#if rolled.isETotal}}total{{else}}particulier{{/if}} augmente de 1 la difficulté de la méditation!</span>{{/if~}} | ||||
| </div> | ||||
|   | ||||
							
								
								
									
										7
									
								
								templates/chat-signe-draconique-actor.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								templates/chat-signe-draconique-actor.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <h4><img class="chat-icon" src="{{signe.img}}" alt="{{signe.name}}" /> | ||||
|   {{alias}} perçoit {{signe.name}} | ||||
| </h4> | ||||
| <p>Pour le lire ce signe draconique, rendez-vous dans les | ||||
|   Terres Médianes du Rêve et trouvez une case de résonnance. | ||||
|   {{#if signe.data.ephemere}}C'est un signe éphémère, qui ne restera présent que pour {{signe.data.duree}}{{/if}} | ||||
| </p> | ||||
							
								
								
									
										52
									
								
								templates/dialog-create-signedraconique.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								templates/dialog-create-signedraconique.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <form class="skill-roll-dialog"> | ||||
|   <div> | ||||
|     <h4>Paramétrer le signe draconique | ||||
|       <span class="chat-card-button-area"> | ||||
|         <a class="signe-aleatoire chat-card-button">Signe aléatoire</a> | ||||
|       </span> | ||||
|       <br><input type="text" name="signe.name" value="{{signe.name}}" data-dtype="String" /> | ||||
|     </h4> | ||||
|   </div> | ||||
|   <div class="form-group"> | ||||
|     <label for="signe.data.difficulte">Difficulte</label> | ||||
|     <input type="number" name="signe.data.difficulte" value="{{signe.data.difficulte}}" data-dtype="Number" /> | ||||
|   </div> | ||||
|   <div class="form-group"> | ||||
|     <label for="signe.data.valeur.norm">Expérience en sorts</label> | ||||
|     <div class="flexrow"> | ||||
|       <input class="signe-xp-sort" type="number" name="signe.data.valeur.norm" data-typereussite="norm" | ||||
|         value="{{signe.data.valeur.norm}}" min="1" max="100" data-dtype="Number" /> | ||||
|       <span>Sign.</span> | ||||
|       <input class="signe-xp-sort" type="number" name="signe.data.valeur.sign" data-typereussite="sign" | ||||
|         value="{{signe.data.valeur.sign}}" min="1" max="100" data-dtype="Number" /> | ||||
|       <span>Part.</span> | ||||
|       <input class="signe-xp-sort" type="number" name="signe.data.valeur.part" data-typereussite="part" | ||||
|         value="{{signe.data.valeur.part}}" min="1" max="100" data-dtype="Number" /> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="form-group flexrow"> | ||||
|       <label for="signe.data.ephemere">Ephémère</label> | ||||
|       <input class="flex-shrink" type="checkbox" name="signe.data.ephemere" {{#if signe.data.ephemere}}checked{{/if}} /> | ||||
|       <span> | ||||
|         <input type="text" name="signe.data.duree" value="{{signe.data.duree}}" data-dtype="String" /> | ||||
|       </span> | ||||
|   </div> | ||||
|   <div class="form-group"> | ||||
|     <label for="tmrs">Terres médianes</label> | ||||
|     <select class="select-tmr" name="tmrs" id="tmrs" size="{{tmrs.length}}" multiple> | ||||
|       {{#each tmrs as |tmr key|}} | ||||
|       <option value="{{tmr.name}}" {{#if tmr.selected}}selected{{/if}}>{{tmr.name}}</option> | ||||
|       {{/each}} | ||||
|     </select> | ||||
|   </div> | ||||
|   <div class="form-group"> | ||||
|     <label for="actors">Haut-rêvants concernés</label> | ||||
|     <select class="select-actor" id="actors" size="7" multiple> | ||||
|       {{#each actors as |actor key|}} | ||||
|       <option value="{{actor.name}}" data-actor-id="{{actor._id}}" {{#if actor.selected}}selected{{/if}}>{{actor.name}}</option> | ||||
|       {{/each}} | ||||
|     </select> | ||||
|   </div> | ||||
|  | ||||
|  | ||||
| </form> | ||||
							
								
								
									
										48
									
								
								templates/dialog-roll-signedraconique.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								templates/dialog-roll-signedraconique.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| {{log 'lecture signe draconique' this}} | ||||
| <form class="dialog-roll-sort"> | ||||
|   <h2>Lire le signe draconique | ||||
|     <select name="signe-draconique" class="roll-signedraconique flex-grow" data-dtype="String"> | ||||
|       {{#select signe}} | ||||
|       {{#each signes as |signe key|}} | ||||
|       <option value={{key}}>{{this.name}}</option> | ||||
|       {{/each}} | ||||
|       {{/select}} | ||||
|     </select> | ||||
|   </h2> | ||||
|   <img class="chat-icon" src="{{competence.img}}" alt="{{competence.name}}" /> | ||||
|   <div class="grid grid-2col"> | ||||
|     <div class="flex-group-left"> | ||||
|       <div class="flexrow"> | ||||
|         <label for="tmr">TMR - {{tmr.coord}}:</label><label name="tmr">{{tmr.label}}</label> | ||||
|       </div> | ||||
|       <div class="flexrow"> | ||||
|         <label for="carac">{{selectedCarac.label}}:</label><label name="carac">{{selectedCarac.value}}</label> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="flex-group-left"> | ||||
|       <div class="flexrow"> | ||||
|         <label for="competence">Draconic:</label> | ||||
|         <select name="competence" class="roll-draconic" data-dtype="String"> | ||||
|           {{#select draconic}} | ||||
|           {{#each draconicList as |draconic key|}} | ||||
|           <option value={{key}}>{{draconic.name}} : {{numberFormat draconic.data.niveau decimals=0 sign=true}} | ||||
|           </option> | ||||
|           {{/each}} | ||||
|           {{/select}} | ||||
|         </select> | ||||
|       </div> | ||||
|       <div class="flexrow"> | ||||
|         <label>Difficulté</label> | ||||
|         <label class="signe-difficulte">{{diffLibre}}</label> | ||||
|       </div> | ||||
|       {{>"systems/foundryvtt-reve-de-dragon/templates/partial-roll-diffCondition.html"}} | ||||
|       <div id="tableAjustements" class="flexrow"></div> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <div id="tableResolution"></div> | ||||
|   <div id="tableProbaReussite"></div> | ||||
| </form> | ||||
|  | ||||
| <script> | ||||
| </script> | ||||
| @@ -1,4 +1,3 @@ | ||||
| {{log 'lancer de sort' this}} | ||||
| <form class="dialog-roll-sort"> | ||||
|   <h2>Lancer le <span class="sort-ou-rituel">{{#if sort.data.isrituel}}rituel{{else}}sort{{/if}}</span>: | ||||
|     <select name="sort" class="roll-sort flex-grow" data-dtype="String"> | ||||
|   | ||||
| @@ -14,8 +14,11 @@ | ||||
|         <img class="small-button-direction" id='dir-bottom' src='systems/foundryvtt-reve-de-dragon/styles/img/ui/dir-bottom.svg'> | ||||
|         <img class="small-button-direction" id='dir-bottom-right' src='systems/foundryvtt-reve-de-dragon/styles/img/ui/dir-bottom-right.svg'> | ||||
|       </div> | ||||
|       <div class="flex-group-center"> | ||||
|         <a id="lancer-sort">Lancer un Sort</a> | ||||
|       <div class="flex-group-center lire-signe-draconique"> | ||||
|         <a>Lire un signe draconique</a> | ||||
|       </div> | ||||
|       <div class="flex-group-center lancer-sort"> | ||||
|         <a>Lancer un Sort</a> | ||||
|       </div> | ||||
|       <hr> | ||||
|       <div class="flex-group-center"> | ||||
|   | ||||
| @@ -29,15 +29,15 @@ | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|         <label for="xp">Difficulté</label> | ||||
|         <input class="attribute-value" type="text" name="data.difficulte" value="{{data.difficulte}}" data-dtype="Number"/> | ||||
|         <input class="attribute-value" type="number" name="data.difficulte" value="{{data.difficulte}}" data-dtype="Number"/> | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|         <label for="xp">Points de tâches</label> | ||||
|         <input class="attribute-value" type="text" name="data.points_de_tache" value="{{data.points_de_tache}}" data-dtype="Number"/> | ||||
|         <input class="attribute-value" type="number" name="data.points_de_tache" value="{{data.points_de_tache}}" data-dtype="Number"/> | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|         <label for="xp">Expérience</label> | ||||
|         <input class="attribute-value" type="text" name="data.xp" value="{{data.xp}}" data-dtype="String"/> | ||||
|         <input class="attribute-value" type="number" name="data.xp" value="{{data.xp}}" data-dtype="Number"/> | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|         <label for="xp">Niveau minimum</label> | ||||
| @@ -49,15 +49,15 @@ | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|         <label for="xp">Encombrement </label> | ||||
|         <input class="attribute-value" type="text" name="data.encombrement" value="{{data.encombrement}}" data-dtype="Number"/> | ||||
|         <input class="attribute-value" type="number" name="data.encombrement" value="{{data.encombrement}}" data-dtype="Number"/> | ||||
|       </div> | ||||
|       <div class="form-group"> | ||||
|         <label>Quantité </label> | ||||
|         <input class="attribute-value" type="text" name="data.quantite" value="{{data.quantite}}" data-dtype="Number" /> | ||||
|         <input class="attribute-value" type="number" name="data.quantite" value="{{data.quantite}}" data-dtype="Number" /> | ||||
|       </div> | ||||
|       <div class="form-group item-cout"> | ||||
|         <label for="xp">Prix (sols) </label> | ||||
|         <input class="attribute-value" type="text" name="data.cout" value="{{data.cout}}" data-dtype="Number"/> | ||||
|         <input class="attribute-value" type="number" name="data.cout" value="{{data.cout}}" data-dtype="Number"/> | ||||
|       </div> | ||||
|       <div class="flexcol"> | ||||
|         <span><label>Description : </label></span> | ||||
|   | ||||
							
								
								
									
										56
									
								
								templates/item-signedraconique-sheet.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								templates/item-signedraconique-sheet.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| <form class="{{cssClass}}" autocomplete="off"> | ||||
|   <header class="sheet-header"> | ||||
|     <img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" /> | ||||
|     <div class="header-fields"> | ||||
|       <h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1> | ||||
|       <a class="signe-aleatoire chat-card-button">Signe aléatoire</a> | ||||
|     </div> | ||||
|   </header> | ||||
|    | ||||
|   {{!-- Sheet Body --}} | ||||
|   <section class="sheet-body"> | ||||
|     <div class="form-group"> | ||||
|       <label for="data.difficulte">Difficulte</label> | ||||
|       <input class="attribute-value" type="number" name="data.difficulte" value="{{data.difficulte}}" | ||||
|         data-dtype="Number" /> | ||||
|     </div> | ||||
|     <div class="form-group"> | ||||
|       <label for="data.valeur.norm">Expérience en sorts</label> | ||||
|       <div class="flexrow"> | ||||
|         <input class="signe-xp-sort" type="number" name="data.valeur.norm" data-typereussite="norm" | ||||
|           value="{{data.valeur.norm}}" min="1" max="100" data-dtype="Number" /> | ||||
|         <span>Sign.</span> | ||||
|         <input class="signe-xp-sort" type="number" name="data.valeur.sign" data-typereussite="sign" | ||||
|           value="{{data.valeur.sign}}" min="1" max="100" data-dtype="Number" /> | ||||
|         <span>Part.</span> | ||||
|         <input class="signe-xp-sort" type="number" name="data.valeur.part" data-typereussite="part" | ||||
|           value="{{data.valeur.part}}" min="1" max="100" data-dtype="Number" /> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="form-group"> | ||||
|       <label for="data.ephemere">Ephémère</label> | ||||
|       <input class="attribute-value" type="checkbox" name="data.ephemere" {{#if data.ephemere}}checked{{/if}} /> | ||||
|     </div> | ||||
|     {{#if data.ephemere}} | ||||
|     <div class="form-group"> | ||||
|       <label for="data.duree">Durée</label> | ||||
|       <input class="attribute-value" type="text" name="data.duree" value="{{data.duree}}" data-dtype="String" /> | ||||
|     </div> | ||||
|     {{/if}} | ||||
|     <div class="form-group"> | ||||
|       <label for="tmrs">Terres médianes</label> | ||||
|       <select class="select-tmr attribute-value" name="tmrs" id="tmrs" size={{tmrs.length}} multiple /> | ||||
|       {{#each tmrs as |tmr key|}} | ||||
|       <option class="option-tmr" value="{{tmr.name}}" {{#if tmr.selected}}selected{{/if}}>{{tmr.name}}</option> | ||||
|       {{/each}} | ||||
|       </select> | ||||
|     </div> | ||||
|     <div class="flexcol"> | ||||
|       <span><label>Description : </label></span> | ||||
|       <div class="form-group editor"> | ||||
|         {{editor content=data.description target="data.description" button=true owner=owner editable=editable}} | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
|  | ||||
| </form> | ||||
		Reference in New Issue
	
	Block a user