Stress amélioré
Commande: /stress Ouvre une fenêtre pour gérer finement le stress (ou l'expérience) Commande: /stress <v> <motif> <nom> Stress donné à un acteur/joueur avec un nom proche Notifications des joueurs qui reçoivent du stress
This commit is contained in:
		| @@ -1002,17 +1002,34 @@ export class RdDActor extends Actor { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async updateCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { |   async updateCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { | ||||||
|     await this.update({ [`data.compteurs.${fieldName}.value`]: fieldValue }); |     await this.update({ [`data.compteurs.${fieldName}.value`]: fieldValue }); | ||||||
|     if (fieldName == 'stress') { |     await this.addStressExperienceLog(fieldName, fieldValue, 'forcé: '+raison); | ||||||
|       await this.updateExperienceLog('stress', fieldValue, raison); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async addCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { |   async addCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { | ||||||
|     let oldValue = (Misc.templateData(this)).compteurs[fieldName].value; |     let oldValue = (Misc.templateData(this)).compteurs[fieldName].value; | ||||||
|     await this.update({ [`data.compteurs.${fieldName}.value`]: Number(oldValue) + Number(fieldValue) }); |     await this.update({ [`data.compteurs.${fieldName}.value`]: Number(oldValue) + Number(fieldValue) }); | ||||||
|     if (fieldName == 'stress') { |     await this.addStressExperienceLog(fieldName, fieldValue, raison); | ||||||
|       await this.updateExperienceLog('stress', fieldValue, raison); |   } | ||||||
|  |  | ||||||
|  |   async addStressExperienceLog(fieldName, fieldValue, raison) { | ||||||
|  |     switch (fieldName) { | ||||||
|  |       case 'stress': case 'experience': | ||||||
|  |         await this.updateExperienceLog(fieldName, fieldValue, raison); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   distribuerStress(compteur, stress, motif) { | ||||||
|  |     if (game.user.isGM && this.hasPlayerOwner && this.isPersonnage()) { | ||||||
|  |       switch (compteur) { | ||||||
|  |          case 'stress': case 'experience': | ||||||
|  |            const message = `${this.name} a reçu ${stress} points ${compteur == 'stress' ? "de stress" : "d'expérience"} (raison : ${motif})`; | ||||||
|  |            this.addCompteurValue(compteur, stress, motif); | ||||||
|  |            ui.notifications.info(message); | ||||||
|  |            game.users.players.filter(player => player.active && player.character?.id == this.id) | ||||||
|  |             .forEach(player => ChatUtility.notifyUser(player.id, 'info', message)); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										72
									
								
								module/dialog-stress.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								module/dialog-stress.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | import { Misc } from "./misc.js"; | ||||||
|  |  | ||||||
|  | export class DialogStress extends Dialog { | ||||||
|  |  | ||||||
|  |   static async distribuerStress() { | ||||||
|  |     let dialogData = { | ||||||
|  |       motif: "Motif", | ||||||
|  |       stress: 10, | ||||||
|  |       immediat: false, | ||||||
|  |       actors: game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage()) | ||||||
|  |         .map(actor => { | ||||||
|  |           let actorData = duplicate(Misc.data(actor)); | ||||||
|  |           actorData.selected = actor.hasPlayerOwner; | ||||||
|  |           return actorData; | ||||||
|  |         }) | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-stress.html", dialogData); | ||||||
|  |     new DialogStress(dialogData, html) | ||||||
|  |       .render(true); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   constructor(dialogData, html) { | ||||||
|  |     let options = { classes: ["DialogStress"], width: 400, height: 320, 'z-index': 99999 }; | ||||||
|  |     let conf = { | ||||||
|  |       title: "Donner du stress", | ||||||
|  |       content: html, | ||||||
|  |       buttons: { | ||||||
|  |         "Stress": { label: "Stress !", callback: it => { this._onStress(); } } | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     super(conf, options); | ||||||
|  |     this.dialogData = dialogData; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onStress() { | ||||||
|  |     this.validerStress(); | ||||||
|  |     const compteur = this.dialogData.immediat ? 'experience' : 'stress'; | ||||||
|  |     const stress = this.dialogData.stress; | ||||||
|  |     const motif = this.dialogData.motif; | ||||||
|  |  | ||||||
|  |     this.dialogData.actors.filter(it => it.selected) | ||||||
|  |       .map(it => game.actors.get(it._id)) | ||||||
|  |       .forEach(actor => actor.distribuerStress(compteur, stress, motif)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   validerStress() { | ||||||
|  |     this.dialogData.motif = $("[name='motif']").val(); | ||||||
|  |     this.dialogData.stress = $("[name='stress']").val(); | ||||||
|  |     this.dialogData.immediat = $("[name='immediat']").prop("checked");; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   activateListeners(html) { | ||||||
|  |     super.activateListeners(html); | ||||||
|  |     html.find(".select-actor").change((event) => this.onSelectActor(event)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   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; | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -133,6 +133,16 @@ export class Misc { | |||||||
|     return game.user.id == Misc.connectedGMOrUser(); |     return game.user.id == Misc.connectedGMOrUser(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static findPlayer(name) { | ||||||
|  |     return Misc.findFirstLike(name, game.users, it=>it.name,'joueurs'); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static findActor(name, actors = game.actors, description= 'acteurs') { | ||||||
|  |     return Misc.findFirstLike(name, actors, it=>it.name, description); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static findFirstLike(value, elements, mapper = it=>it.name, description = 'valeurs') { |   static findFirstLike(value, elements, mapper = it=>it.name, description = 'valeurs') { | ||||||
|     value = Grammar.toLowerCaseNoAccent(value); |     value = Grammar.toLowerCaseNoAccent(value); | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
|  |  | ||||||
| import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js"; | import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js"; | ||||||
|  | import { DialogStress } from "./dialog-stress.js"; | ||||||
| import { RdDItemCompetence } from "./item-competence.js"; | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDCarac } from "./rdd-carac.js"; | import { RdDCarac } from "./rdd-carac.js"; | ||||||
| @@ -97,11 +98,12 @@ export class RdDCommands { | |||||||
|       }); |       }); | ||||||
|  |  | ||||||
|       rddCommands.registerCommand({ |       rddCommands.registerCommand({ | ||||||
|         path: ["/stress"], func: (content, msg, params) => RdDUtility.distribuerStress(params[0], params[1], params[2]), |         path: ["/stress"], func: (content, msg, params) => rddCommands.distribuerStress(params), | ||||||
|         descr: `Distribue du stress aux personnages. Exemples: |         descr: `Distribue du stress aux personnages. Exemples: | ||||||
|  |           <br><strong>/stress</strong> : Ouvre une fenêtre pour donner du stress ou de l'expérience à un ensemble de personnages | ||||||
|           <br><strong>/stress 6</strong> : Distribue 6 points des Stress à tout les personnages joueurs, sans raison renseignée |           <br><strong>/stress 6</strong> : Distribue 6 points des Stress à tout les personnages joueurs, sans raison renseignée | ||||||
|           <br><strong>/stress 6 Tigre</strong> : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre Vert |           <br><strong>/stress 6 Tigre</strong> : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre (Vert) | ||||||
|           <br><strong>/stress 6 Glou Paulo</strong> : Distribue 6 points de Stres à l'acteur connecté au joueur Paulo, à cause d'un Glou` |           <br><strong>/stress 6 Glou Paulo</strong> : Distribue 6 points de Stress au personnage Paulon ou au personnage joueur Paulo, à cause d'un Glou` | ||||||
|       }); |       }); | ||||||
|  |  | ||||||
|       game.system.rdd.commands = rddCommands; |       game.system.rdd.commands = rddCommands; | ||||||
| @@ -289,7 +291,7 @@ export class RdDCommands { | |||||||
|       finalLevel: diff, |       finalLevel: diff, | ||||||
|       showDice: true, |       showDice: true, | ||||||
|       diviseurSignificative: significative ? 2 : 1, |       diviseurSignificative: significative ? 2 : 1, | ||||||
|       show: { title: "Table de résolution"} |       show: { title: "Table de résolution" } | ||||||
|     }; |     }; | ||||||
|     await RdDResolutionTable.rollData(rollData); |     await RdDResolutionTable.rollData(rollData); | ||||||
|     RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData)); |     RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData)); | ||||||
| @@ -297,7 +299,7 @@ export class RdDCommands { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollDeDraconique(msg) { |   async rollDeDraconique(msg) { | ||||||
|     let ddr = await RdDDice.rollTotal("1dr + 7", { showDice:true }); |     let ddr = await RdDDice.rollTotal("1dr + 7", { showDice: true }); | ||||||
|     RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`); |     RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -351,5 +353,41 @@ export class RdDCommands { | |||||||
|     }); |     }); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async distribuerStress(params) { | ||||||
|  |     if (!game.user.isGM) { | ||||||
|  |       ui.notifications.warn("Seul le MJ est autorisé à utiliser la commande /stress"); | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (params.length == 0) { | ||||||
|  |       DialogStress.distribuerStress(); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       let stress = params[0] | ||||||
|  |       if (stress == undefined) { | ||||||
|  |         ui.notifications.warn("Pas de valeur de stress à distribuer!"); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       let motif = params[1]; | ||||||
|  |       let name = params[2]; | ||||||
|  |       if (name == undefined) { | ||||||
|  |         for (let actor of game.actors) { | ||||||
|  |           actor.distribuerStress('stress', stress, motif); | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         //console.log(stressValue, nomJoueur); | ||||||
|  |         let actor = Misc.findActor(name, game.actors.filter(it => it.hasPlayerOwner)) ?? Misc.findPlayer(name)?.character | ||||||
|  |         if (actor) { | ||||||
|  |           actor.distribuerStress('stress', stress, motif); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |           ui.notifications.warn(`Pas de personnage ou de joueur correspondant à ${name}!`); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -887,32 +887,6 @@ export class RdDUtility { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /*-------------------------------------------- */ |  | ||||||
|   static distribuerStress(stressValue, raison = 'Inconnu', nomJoueur = undefined) { |  | ||||||
|     if (game.user.isGM) { |  | ||||||
|       if (stressValue == undefined){ |  | ||||||
|         ui.notifications.warn("Pas de valeur de stress à distribuer!"); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|       if (nomJoueur == undefined) { |  | ||||||
|         for (let actor of game.actors) { |  | ||||||
|           if (actor.hasPlayerOwner && actor.isPersonnage() ) { |  | ||||||
|             actor.addCompteurValue('stress', stressValue, raison); |  | ||||||
|             ui.notifications.info(`${actor.name} a reçu ${stressValue} points de Stress (raison : ${raison})`); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         //console.log(stressValue, nomJoueur); |  | ||||||
|         let joueur = game.users.find(user => user.name.toLowerCase() == nomJoueur.toLowerCase()); |  | ||||||
|         //console.log("Player", joueur, joueur.character ); |  | ||||||
|         joueur.character.addCompteurValue('stress', stressValue, raison); |  | ||||||
|         ui.notifications.info(`${joueur.character.name} a reçu ${stressValue} points de Stress (raison : ${raison})`); |  | ||||||
|       } |  | ||||||
|     } else { |  | ||||||
|       ui.notifications.warn("Seul le MJ est autorisé à utiliser la commande /stress"); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /*-------------------------------------------- */ |   /*-------------------------------------------- */ | ||||||
|   static async onRenderChatMessage(app, html, msg) { |   static async onRenderChatMessage(app, html, msg) { | ||||||
|     // TODO  |     // TODO  | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								templates/dialog-stress.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								templates/dialog-stress.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | <form class="rdddialog"> | ||||||
|  |   <div class="flexcol"> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="motif">Motif</label> | ||||||
|  |       <input type="text" name="motif" value="{{motif}}" data-dtype="String" /> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="stress">Stress</label> | ||||||
|  |       <input type="number" name="stress" value="{{stress}}" data-dtype="Number" /> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="immediat">Expérience immédiate</label> | ||||||
|  |       <input class="flex-shrink" type="checkbox" name="immediat" {{#if immediat}}checked{{/if}} /> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-group"> | ||||||
|  |       <label for="actors">Personnages 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> | ||||||
|  |   </div> | ||||||
|  | </form> | ||||||
		Reference in New Issue
	
	Block a user