Compare commits
	
		
			12 Commits
		
	
	
		
			12.0.42
			...
			foundryvtt
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 61eee66ebe | |||
| c75d10f69b | |||
| 333bb051c1 | |||
| 1bf247db33 | |||
| 49fc2c9b0a | |||
| 9013376096 | |||
| 972459a08d | |||
| 1607629365 | |||
| 8f7efdad87 | |||
| 2dbe0dea4a | |||
| 5fc455fbad | |||
| 8a7e4d3a9e | 
							
								
								
									
										11
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,6 +1,17 @@ | ||||
|  ---  | ||||
| # v10.7 - L'os de Semolosse | ||||
|  | ||||
| ## v10.7.16 - la morsure de Semolosse | ||||
| - correction de l'affichage des objets suite à confusion | ||||
| - correction de liens dans la liste des équipements | ||||
|  | ||||
| ## v10.7.14 - l'expérience de Semolosse | ||||
| - Affichage des personnages accordés sur les fiches des entités | ||||
| - Refonte du journal d'expérience | ||||
|   - disponible pour les personnages des joueurs | ||||
|   - explication "comptable" des changements (dépense ou ajout, changements de niveaux, ...) | ||||
| - tri alphabétique des différentes listes (sorts, recettes, oeuvres, ...) | ||||
|  | ||||
| ## v10.7.13 - l'armure de Semolosse | ||||
| - Fix: en cas d'armure variable, la détérioration diminue le dé d'armure | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,6 @@ | ||||
| import { RdDActorSheet } from "./actor-sheet.js"; | ||||
| import { RdDSheetUtility } from "./rdd-sheet-utility.js"; | ||||
| import { RdDUtility } from "./rdd-utility.js"; | ||||
|  | ||||
| export class RdDActorEntiteSheet extends RdDActorSheet { | ||||
|  | ||||
| @@ -13,6 +15,12 @@ export class RdDActorEntiteSheet extends RdDActorSheet { | ||||
|       dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }] | ||||
|     }); | ||||
|   } | ||||
|   async getData() { | ||||
|     let formData = await super.getData(); | ||||
|     formData.resonances = this.actor.system.sante.resonnance.actors.map(actorId => game.actors.get(actorId)) | ||||
|       .map(actor => { return { id: actor.id, name: actor.name, img: actor.img } }) | ||||
|     return formData | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   /** @override */ | ||||
| @@ -35,6 +43,23 @@ export class RdDActorEntiteSheet extends RdDActorSheet { | ||||
|       let compName = event.currentTarget.attributes.compname.value; | ||||
|       this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value)); | ||||
|     }); | ||||
|     this.html.find('.resonance-delete').click(async event => { | ||||
|       const li = RdDSheetUtility.getEventElement(event); | ||||
|       const actorId = li.data("actor-id"); | ||||
|       if (actorId) { | ||||
|         const actorResonance = game.actors.get(actorId); | ||||
|         RdDUtility.confirmerSuppressionSubacteur(this, actorResonance, li, () => { | ||||
|           console.log('Delete : ', actorId); | ||||
|           this.removeSubacteur(actorId); | ||||
|           RdDUtility.slideOnDelete(this, li); | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   async removeSubacteur(actorId) { | ||||
|     let newResonances = this.actor.system.sante.resonnance.actors.filter(id => id != actorId); | ||||
|     await this.actor.update({ 'system.sante.resonnance.actors': newResonances }, { renderSheet: false }); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -129,7 +129,11 @@ export class RdDActorSheet extends RdDBaseActorSheet { | ||||
|       const actorId = li.data("actor-id"); | ||||
|       if (actorId) { | ||||
|         const subActor = game.actors.get(actorId); | ||||
|         RdDUtility.confirmerSuppressionSubacteur(this, subActor, li); | ||||
|         RdDUtility.confirmerSuppressionSubacteur(this, subActor, li, () => { | ||||
|           console.log('Delete : ', subActor.id); | ||||
|           this.actor.removeSubacteur(subActor.id); | ||||
|           RdDUtility.slideOnDelete(this, li); | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|     this.html.find('.experiencelog-delete').click(async event => { | ||||
| @@ -142,6 +146,13 @@ export class RdDActorSheet extends RdDBaseActorSheet { | ||||
|       const key = Number(li.data("key") ?? -1); | ||||
|       await this.actor.deleteExperienceLog(0, key + 1); | ||||
|     }); | ||||
|     this.html.find("input.derivee-value[name='system.compteurs.stress.value']").change(async event => { | ||||
|       this.actor.updateCompteurValue("stress", parseInt(event.target.value)); | ||||
|     }); | ||||
|     this.html.find("input.derivee-value[name='system.compteurs.experience.value']").change(async event => { | ||||
|       this.actor.updateCompteurValue("experience", parseInt(event.target.value)); | ||||
|     }); | ||||
|  | ||||
|     this.html.find('.encaisser-direct').click(async event => { | ||||
|       this.actor.encaisser(); | ||||
|     }) | ||||
| @@ -445,9 +456,9 @@ export class RdDActorSheet extends RdDBaseActorSheet { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async selectTypeOeuvreToCreate() { | ||||
|     let typeObjets = RdDItem.getTypesOeuvres(); | ||||
|     let types = RdDItem.getTypesOeuvres(); | ||||
|     let content = `<span class="competence-label">Selectionnez le type d'oeuvre</span><select class="item-type">`; | ||||
|     for (let typeName of typeObjets) { | ||||
|     for (let typeName of types) { | ||||
|       content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>` | ||||
|     } | ||||
|     content += '</select>'; | ||||
|   | ||||
							
								
								
									
										257
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						
									
										257
									
								
								module/actor.js
									
									
									
									
									
								
							| @@ -37,6 +37,7 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||
| import { RdDItemBlessure } from "./item/blessure.js"; | ||||
| import { AppAstrologie } from "./sommeil/app-astrologie.js"; | ||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||
| import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js"; | ||||
|  | ||||
| const POSSESSION_SANS_DRACONIC = { | ||||
|   img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp', | ||||
| @@ -821,31 +822,40 @@ export class RdDActor extends RdDBaseActor { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateCarac(caracName, caracValue) { | ||||
|   async updateCarac(caracName, to) { | ||||
|     if (caracName == "force") { | ||||
|       if (Number(caracValue) > this.getTaille() + 4) { | ||||
|       if (Number(to) > this.getTaille() + 4) { | ||||
|         ui.notifications.warn("Votre FORCE doit être au maximum de TAILLE+4"); | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
|     if (caracName == "reve") { | ||||
|       if (caracValue > Misc.toInt(this.system.reve.seuil.value)) { | ||||
|         this.setPointsDeSeuil(caracValue); | ||||
|       if (to > Misc.toInt(this.system.reve.seuil.value)) { | ||||
|         this.setPointsDeSeuil(to); | ||||
|       } | ||||
|     } | ||||
|     if (caracName == "chance") { | ||||
|       if (caracValue > Misc.toInt(this.system.compteurs.chance.value)) { | ||||
|         this.setPointsDeChance(caracValue); | ||||
|       if (to > Misc.toInt(this.system.compteurs.chance.value)) { | ||||
|         this.setPointsDeChance(to); | ||||
|       } | ||||
|     } | ||||
|     await this.update({ [`system.carac.${caracName}.value`]: caracValue }); | ||||
|     let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName); | ||||
|     const from = selectedCarac.value | ||||
|     await this.update({ [`system.carac.${caracName}.value`]: to }); | ||||
|     await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateCaracXP(caracName, caracXP) { | ||||
|   async updateCaracXP(caracName, to) { | ||||
|     if (caracName == 'Taille') { | ||||
|       return; | ||||
|     } | ||||
|     let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName); | ||||
|     if (!selectedCarac.derivee) { | ||||
|       const from = Number(selectedCarac.xp); | ||||
|       await this.update({ [`system.carac.${caracName}.xp`]: to }); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, caracName); | ||||
|     } | ||||
|     this.checkCaracXP(caracName); | ||||
|   } | ||||
|  | ||||
| @@ -857,16 +867,19 @@ export class RdDActor extends RdDBaseActor { | ||||
|     let carac = RdDActor._findCaracByName(this.system.carac, caracName); | ||||
|     if (carac) { | ||||
|       carac = duplicate(carac); | ||||
|       let xp = Number(carac.xp); | ||||
|       let value = Number(carac.value); | ||||
|       while (xp >= RdDCarac.getCaracNextXp(value) && xp > 0) { | ||||
|         xp -= RdDCarac.getCaracNextXp(value); | ||||
|         value++; | ||||
|       const fromXp = Number(carac.xp); | ||||
|       const fromValue = Number(carac.value); | ||||
|       let toXp = fromXp; | ||||
|       let toValue = fromValue; | ||||
|       while (toXp >= RdDCarac.getCaracNextXp(toValue) && toXp > 0) { | ||||
|         toXp -= RdDCarac.getCaracNextXp(toValue); | ||||
|         toValue++; | ||||
|       } | ||||
|       carac.xp = xp; | ||||
|       carac.value = value; | ||||
|       carac.xp = toXp; | ||||
|       carac.value = toValue; | ||||
|       await this.update({ [`system.carac.${caracName}`]: carac }); | ||||
|       this.updateExperienceLog("Carac +", xp, caracName + " passée à " + value); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XPCARAC, fromXp, toXp, caracName); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.CARAC, fromValue, toValue, caracName); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -874,17 +887,20 @@ export class RdDActor extends RdDBaseActor { | ||||
|   async updateCompetenceXPAuto(idOrName) { | ||||
|     let competence = this.getCompetence(idOrName); | ||||
|     if (competence) { | ||||
|       let xp = Number(competence.system.xp); | ||||
|       let niveau = Number(competence.system.niveau); | ||||
|       while (xp >= RdDItemCompetence.getCompetenceNextXp(niveau) && xp > 0) { | ||||
|         xp -= RdDItemCompetence.getCompetenceNextXp(niveau); | ||||
|         niveau++; | ||||
|       const fromXp = Number(competence.system.xp); | ||||
|       const fromNiveau = Number(competence.system.niveau); | ||||
|       let toXp = fromXp; | ||||
|       let toNiveau = fromNiveau; | ||||
|       while (toXp >= RdDItemCompetence.getCompetenceNextXp(toNiveau) && toXp > 0) { | ||||
|         toXp -= RdDItemCompetence.getCompetenceNextXp(toNiveau); | ||||
|         toNiveau++; | ||||
|       } | ||||
|       await competence.update({ | ||||
|         "system.xp": xp, | ||||
|         "system.niveau": niveau, | ||||
|         "system.xp": toXp, | ||||
|         "system.niveau": toNiveau, | ||||
|       }); | ||||
|       this.updateExperienceLog("Compétence +", xp, competence.name + " passée à " + niveau); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -893,29 +909,33 @@ export class RdDActor extends RdDBaseActor { | ||||
|     if (!competence) { | ||||
|       return; | ||||
|     } | ||||
|     const stress = this.system.compteurs.experience.value; | ||||
|     const niveau = Number(competence.system.niveau); | ||||
|     const xpSuivant = RdDItemCompetence.getCompetenceNextXp(niveau); | ||||
|     const xpRequis = xpSuivant - competence.system.xp; | ||||
|     if (stress <= 0 || niveau >= competence.system.niveau_archetype) { | ||||
|     const fromXp = competence.system.xp; | ||||
|     const fromXpStress = this.system.compteurs.experience.value; | ||||
|     const fromNiveau = Number(competence.system.niveau); | ||||
|     const xpSuivant = RdDItemCompetence.getCompetenceNextXp(fromNiveau); | ||||
|     const xpRequis = xpSuivant - fromXp; | ||||
|     if (fromXpStress <= 0 || fromNiveau >= competence.system.niveau_archetype) { | ||||
|       ui.notifications.info(`La compétence ne peut pas augmenter! | ||||
|           stress disponible: ${stress} | ||||
|           stress disponible: ${fromXpStress} | ||||
|           expérience requise: ${xpRequis} | ||||
|           niveau : ${niveau} | ||||
|           niveau : ${fromNiveau} | ||||
|           archétype : ${competence.system.niveau_archetype}`); | ||||
|       return; | ||||
|     } | ||||
|     const xpUtilise = Math.max(0, Math.min(stress, xpRequis)); | ||||
|     const xpUtilise = Math.max(0, Math.min(fromXpStress, xpRequis)); | ||||
|     const gainNiveau = (xpUtilise >= xpRequis || xpRequis <= 0) ? 1 : 0; | ||||
|     const nouveauNiveau = niveau + gainNiveau; | ||||
|     const nouveauXp = gainNiveau > 0 ? Math.max(competence.system.xp - xpSuivant, 0) : (competence.system.xp + xpUtilise); | ||||
|     const toNiveau = fromNiveau + gainNiveau; | ||||
|     const newXp = gainNiveau > 0 ? Math.max(fromXp - xpSuivant, 0) : (fromXp + xpUtilise); | ||||
|     await competence.update({ | ||||
|       "system.xp": nouveauXp, | ||||
|       "system.niveau": nouveauNiveau, | ||||
|       "system.xp": newXp, | ||||
|       "system.niveau": toNiveau, | ||||
|     }); | ||||
|     const stressTransformeRestant = Math.max(0, stress - xpUtilise); | ||||
|     await this.update({ "system.compteurs.experience.value": stressTransformeRestant }); | ||||
|     this.updateExperienceLog('Dépense stress', xpUtilise, `Stress en ${competence.name} ${gainNiveau ? "pour passer à " + nouveauNiveau : ""}`); | ||||
|     const toXpStress = Math.max(0, fromXpStress - xpUtilise); | ||||
|     await this.update({ "system.compteurs.experience.value": toXpStress }); | ||||
|  | ||||
|     await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpStress, toXpStress, `Dépense stress`); | ||||
|     await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, newXp, competence.name); | ||||
|     await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -941,49 +961,57 @@ export class RdDActor extends RdDBaseActor { | ||||
|   async updateCompetence(idOrName, compValue) { | ||||
|     let competence = this.getCompetence(idOrName); | ||||
|     if (competence) { | ||||
|       let nouveauNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie); | ||||
|       const tronc = RdDItemCompetence.getListTronc(competence.name).filter(it => { | ||||
|         const comp = this.getCompetence(it); | ||||
|         const niveauTr = competence ? competence.system.niveau : 0; | ||||
|         return niveauTr < 0 && niveauTr < nouveauNiveau; | ||||
|       }); | ||||
|       if (tronc.length > 0) { | ||||
|         let message = "Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : "; | ||||
|         for (let troncName of tronc) { | ||||
|           message += "<br>" + troncName; | ||||
|         } | ||||
|         ui.notifications.info(message); | ||||
|       let toNiveau = compValue ?? RdDItemCompetence.getNiveauBase(competence.system.categorie); | ||||
|       this.notifyCompetencesTronc(competence, toNiveau); | ||||
|       const fromNiveau = competence.system.niveau; | ||||
|       await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau': toNiveau }]); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.NIVEAU, fromNiveau, toNiveau, competence.name, true); | ||||
|     } else { | ||||
|       console.log("Competence not found", idOrName); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   notifyCompetencesTronc(competence, toNiveau) { | ||||
|     const listTronc = RdDItemCompetence.getListTronc(competence.name).filter(it => { | ||||
|       const autreComp = this.getCompetence(it); | ||||
|       const niveauTr = autreComp?.system.niveau ?? 0; | ||||
|       return niveauTr < 0 && niveauTr < toNiveau; | ||||
|     }); | ||||
|     if (listTronc.length > 0) { | ||||
|       ui.notifications.info( | ||||
|         "Vous avez modifié une compétence 'tronc'. Vérifiez que les compétences suivantes évoluent ensemble jusqu'au niveau 0 : <br>" | ||||
|         + Misc.join(listTronc, '<br>')); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateCompetenceXP(idOrName, toXp) { | ||||
|     let competence = this.getCompetence(idOrName); | ||||
|     if (competence) { | ||||
|       if (isNaN(toXp) || typeof (toXp) != 'number') toXp = 0; | ||||
|       const fromXp = competence.system.xp; | ||||
|       this.checkCompetenceXP(idOrName, toXp); | ||||
|       await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.xp': toXp }]); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XP, fromXp, toXp, competence.name, true); | ||||
|       if (toXp > fromXp) { | ||||
|         RdDUtility.checkThanatosXP(idOrName); | ||||
|       } | ||||
|       const update = { _id: competence.id, 'system.niveau': nouveauNiveau }; | ||||
|       await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity | ||||
|     } else { | ||||
|       console.log("Competence not found", idOrName); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateCompetenceXP(idOrName, newXp) { | ||||
|   async updateCompetenceXPSort(idOrName, toXpSort) { | ||||
|     let competence = this.getCompetence(idOrName); | ||||
|     if (competence) { | ||||
|       if (isNaN(newXp) || typeof (newXp) != 'number') newXp = 0; | ||||
|       this.checkCompetenceXP(idOrName, newXp); | ||||
|       const update = { _id: competence.id, 'system.xp': newXp }; | ||||
|       await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity | ||||
|       this.updateExperienceLog("XP", newXp, "XP modifié en " + competence.name); | ||||
|     } else { | ||||
|       console.log("Competence not found", idOrName); | ||||
|     } | ||||
|     RdDUtility.checkThanatosXP(idOrName); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateCompetenceXPSort(idOrName, compValue) { | ||||
|     let competence = this.getCompetence(idOrName); | ||||
|     if (competence) { | ||||
|       if (isNaN(compValue) || typeof (compValue) != 'number') compValue = 0; | ||||
|       const update = { _id: competence.id, 'system.xp_sort': compValue }; | ||||
|       await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity | ||||
|       this.updateExperienceLog("XP Sort", compValue, "XP modifié en sort de " + competence.name); | ||||
|       if (isNaN(toXpSort) || typeof (toXpSort) != 'number') toXpSort = 0; | ||||
|       const fromXpSort = competence.system.xp_sort; | ||||
|       await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.xp_sort': toXpSort }]); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, competence.name, true); | ||||
|       if (toXpSort > fromXpSort) { | ||||
|         RdDUtility.checkThanatosXP(idOrName); | ||||
|       } | ||||
|     } else { | ||||
|       console.log("Competence not found", idOrName); | ||||
|     } | ||||
| @@ -993,26 +1021,12 @@ export class RdDActor extends RdDBaseActor { | ||||
|   async updateCompetenceArchetype(idOrName, compValue) { | ||||
|     let competence = this.getCompetence(idOrName); | ||||
|     if (competence) { | ||||
|       compValue = compValue ?? 0; | ||||
|       const update = { _id: competence.id, 'system.niveau_archetype': compValue }; | ||||
|       await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity | ||||
|       await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, 'system.niveau_archetype': Math.max(compValue ?? 0, 0) }]); | ||||
|     } else { | ||||
|       console.log("Competence not found", idOrName); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateExperienceLog(modeXP, valeurXP, raisonXP = 'Inconnue') { | ||||
|     let d = new Date(); | ||||
|     let expLog = duplicate(this.system.experiencelog); | ||||
|     expLog.push({ | ||||
|       mode: Misc.upperFirst(modeXP), valeur: valeurXP, raison: Misc.upperFirst(raisonXP), | ||||
|       daterdd: game.system.rdd.calendrier.dateCourante(), | ||||
|       datereel: `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}` | ||||
|     }); | ||||
|     await this.update({ [`system.experiencelog`]: expLog }); | ||||
|   } | ||||
|  | ||||
|   async deleteExperienceLog(from, count) { | ||||
|     if (from >= 0 && count > 0) { | ||||
|       let expLog = duplicate(this.system.experiencelog); | ||||
| @@ -1021,24 +1035,27 @@ export class RdDActor extends RdDBaseActor { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { | ||||
|     await this.update({ [`system.compteurs.${fieldName}.value`]: fieldValue }); | ||||
|     await this.addStressExperienceLog(fieldName, fieldValue, 'forcé: ' + raison); | ||||
|   async updateCompteurValue(fieldName, to) { | ||||
|     const from = this.system.compteurs[fieldName].value | ||||
|     await this.update({ [`system.compteurs.${fieldName}.value`]: to }); | ||||
|     await this.addStressExperienceLog(fieldName, from, to, fieldName, true); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async addCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { | ||||
|     let oldValue = this.system.compteurs[fieldName].value; | ||||
|     await this.update({ [`system.compteurs.${fieldName}.value`]: Number(oldValue) + Number(fieldValue) }); | ||||
|     await this.addStressExperienceLog(fieldName, fieldValue, raison); | ||||
|   async addCompteurValue(fieldName, add, raison) { | ||||
|     let from = this.system.compteurs[fieldName].value; | ||||
|     const to = Number(from) + Number(add); | ||||
|     await this.update({ [`system.compteurs.${fieldName}.value`]: to }); | ||||
|     await this.addStressExperienceLog(fieldName, from, to, raison); | ||||
|   } | ||||
|  | ||||
|   async addStressExperienceLog(fieldName, fieldValue, raison) { | ||||
|     switch (fieldName) { | ||||
|       case 'stress': case 'experience': | ||||
|         await this.updateExperienceLog(fieldName, fieldValue, raison); | ||||
|   async addStressExperienceLog(topic, from, to, raison, manuel) { | ||||
|     switch (topic) { | ||||
|       case 'stress': | ||||
|         return await ExperienceLog.add(this, XP_TOPIC.STRESS, from, to, raison, manuel) | ||||
|       case 'experience': | ||||
|         return await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, from, to, raison, manuel) | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -1843,14 +1860,14 @@ export class RdDActor extends RdDBaseActor { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async transformerStress() { | ||||
|     const stress = Number(this.system.compteurs.stress.value); | ||||
|     if (this.system.sommeil?.insomnie || stress <= 0) { | ||||
|     const fromStress = Number(this.system.compteurs.stress.value); | ||||
|     if (this.system.sommeil?.insomnie || fromStress <= 0) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     const stressRoll = await this._stressRoll(this.getReveActuel()); | ||||
|  | ||||
|     const conversion = Math.floor(stress * stressRoll.factor / 100); | ||||
|     const conversion = Math.floor(fromStress * stressRoll.factor / 100); | ||||
|     let dissolution = Math.max(0, Number(this.system.compteurs.dissolution.value)); | ||||
|     let exaltation = Math.max(0, Number(this.system.compteurs.exaltation.value)); | ||||
|     const annule = Math.min(dissolution, exaltation); | ||||
| @@ -1862,8 +1879,8 @@ export class RdDActor extends RdDBaseActor { | ||||
|       alias: this.name, | ||||
|       selectedCarac: this.system.carac.reve, | ||||
|       rolled: stressRoll, | ||||
|       stress: stress, | ||||
|       perte: Math.min(conversion, stress), | ||||
|       stress: fromStress, | ||||
|       perte: Math.min(conversion, fromStress), | ||||
|       convertis: conversion - perteDissolution, | ||||
|       xp: conversion - perteDissolution + exaltation, | ||||
|       dissolution: dissolution, | ||||
| @@ -1875,15 +1892,18 @@ export class RdDActor extends RdDBaseActor { | ||||
|       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData) | ||||
|     }); | ||||
|  | ||||
|     const toStress = Math.max(fromStress - stressRollData.perte - 1, 0); | ||||
|     const fromXpSress = Number(this.system.compteurs.experience.value); | ||||
|     const toXpStress = fromXpSress + Number(stressRollData.xp); | ||||
|     const updates = { | ||||
|       "system.compteurs.stress.value": Math.max(stress - stressRollData.perte - 1, 0), | ||||
|       "system.compteurs.experience.value": Number(this.system.compteurs.experience.value) + Number(stressRollData.xp), | ||||
|       "system.compteurs.stress.value": toStress, | ||||
|       "system.compteurs.experience.value": toXpStress, | ||||
|       "system.compteurs.dissolution.value": dissolution - perteDissolution, | ||||
|       "system.compteurs.exaltation.value": 0 | ||||
|     } | ||||
|     await this.update(updates); | ||||
|  | ||||
|     this.updateExperienceLog('XP', stressRollData.xp, "Transformation du stress"); | ||||
|     await ExperienceLog.add(this, XP_TOPIC.STRESS, fromStress, toStress, 'Transformation') | ||||
|     await ExperienceLog.add(this, XP_TOPIC.TRANSFORM, fromXpSress, toXpStress, 'Transformation') | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -2709,8 +2729,10 @@ export class RdDActor extends RdDBaseActor { | ||||
|     } | ||||
|     rollData.xpSort = RdDItemSigneDraconique.getXpSortSigneDraconique(rollData.rolled.code, rollData.signe); | ||||
|     if (rollData.xpSort > 0) { | ||||
|       await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': Misc.toInt(compData.system.xp_sort) + rollData.xpSort }]); | ||||
|       await this.updateExperienceLog("XP Sort", rollData.xpSort, "Signe draconique en " + rollData.competence.name); | ||||
|       const fromXp = Number(compData.system.xp_sort); | ||||
|       const toXp = fromXp + rollData.xpSort; | ||||
|       await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': toXp }]); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXp, toXp, `${rollData.competence.name} : signe draconique`); | ||||
|     } | ||||
|     await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]); | ||||
|     await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html'); | ||||
| @@ -2824,11 +2846,12 @@ export class RdDActor extends RdDBaseActor { | ||||
|   /* -------------------------------------------- */ | ||||
|   async _xpCompetence(xpData) { | ||||
|     if (xpData.competence) { | ||||
|       const newXp = Misc.toInt(xpData.competence.system.xp) + xpData.xpCompetence; | ||||
|       let update = { _id: xpData.competence._id, 'system.xp': newXp }; | ||||
|       const from = Number(xpData.competence.system.xp); | ||||
|       const to = from + xpData.xpCompetence; | ||||
|       let update = { _id: xpData.competence._id, 'system.xp': to }; | ||||
|       await this.updateEmbeddedDocuments('Item', [update]); | ||||
|       xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false); | ||||
|       this.updateExperienceLog("XP", xpData.xpCompetence, "XP gagné en " + xpData.competence.name); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XP, from, to, xpData.competence.name); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -2838,10 +2861,12 @@ export class RdDActor extends RdDBaseActor { | ||||
|       let carac = duplicate(this.system.carac); | ||||
|       let selectedCarac = RdDActor._findCaracByName(carac, xpData.caracName); | ||||
|       if (!selectedCarac.derivee) { | ||||
|         selectedCarac.xp = Misc.toInt(selectedCarac.xp) + xpData.xpCarac; | ||||
|         const from = Number(selectedCarac.xp); | ||||
|         const to = from + xpData.xpCarac; | ||||
|         selectedCarac.xp = to; | ||||
|         await this.update({ "system.carac": carac }); | ||||
|         xpData.checkCarac = await this.checkCaracXP(selectedCarac.label, false); | ||||
|         this.updateExperienceLog("XP", xpData.xpCarac, "XP gagné en " + xpData.caracName); | ||||
|         await ExperienceLog.add(this, XP_TOPIC.XPCARAC, from, to, xpData.caracName); | ||||
|       } else { | ||||
|         xpData.caracRepartitionManuelle = true; | ||||
|       } | ||||
|   | ||||
| @@ -50,16 +50,16 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|       encTotal: await this.actor.computeEncTotal(), | ||||
|     } | ||||
|  | ||||
|     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets); | ||||
|     this._appliquerRechercheObjets(formData.objets, formData.conteneurs); | ||||
|     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); | ||||
|     this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires); | ||||
|     formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); | ||||
|     return formData; | ||||
|   } | ||||
|  | ||||
|   _appliquerRechercheObjets(objets, conteneurs) { | ||||
|   _appliquerRechercheObjets(conteneurs, inventaires) { | ||||
|     if (this.options.recherche?.text) { | ||||
|       const recherche = this.options.recherche; | ||||
|       const allVisible = objets.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id); | ||||
|       const allVisible = inventaires.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id); | ||||
|       let addVisible = conteneurs.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id) | ||||
|       do { | ||||
|         allVisible.push(...addVisible) | ||||
| @@ -67,11 +67,11 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|         addVisible = parentsIds.filter(id => !allVisible.includes(id)) | ||||
|       } | ||||
|       while (addVisible.length > 0) | ||||
|       objets.forEach(it => it.system.isHidden = !allVisible.includes(it.id)) | ||||
|       inventaires.forEach(it => it.system.isHidden = !allVisible.includes(it.id)) | ||||
|       conteneurs.forEach(it => it.system.isHidden = !allVisible.includes(it.id)) | ||||
|     } | ||||
|     else { | ||||
|       objets.forEach(it => it.system.isHidden = false) | ||||
|       inventaires.forEach(it => it.system.isHidden = false) | ||||
|       conteneurs.forEach(it => it.system.isHidden = false) | ||||
|     } | ||||
|   } | ||||
| @@ -118,9 +118,10 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|     formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']); | ||||
|     formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']); | ||||
|     formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']); | ||||
|     formData.monnaie = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere()); | ||||
|     formData.monnaies = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere()); | ||||
|     formData.objets = Misc.arrayOrEmpty(itemTypes['objet']) | ||||
|  | ||||
|     formData.objets = RdDItem.getItemTypesInventaire('all') | ||||
|     formData.inventaires = RdDItem.getItemTypesInventaire('all') | ||||
|       .map(t => Misc.arrayOrEmpty(itemTypes[t])) | ||||
|       .reduce((a, b) => a.concat(b), []) | ||||
|       .sort(Misc.ascending(it => it.name)); | ||||
| @@ -230,9 +231,9 @@ export class RdDBaseActorSheet extends ActorSheet { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async selectObjetTypeToCreate() { | ||||
|     let typeObjets = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type))); | ||||
|     let types = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type))); | ||||
|     let content = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`; | ||||
|     for (let typeName of typeObjets) { | ||||
|     for (let typeName of types) { | ||||
|       content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>` | ||||
|     } | ||||
|     content += '</select>'; | ||||
|   | ||||
							
								
								
									
										39
									
								
								module/actor/experience-log.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								module/actor/experience-log.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
|  | ||||
| export const XP_TOPIC = { | ||||
|   XP: { code: 'xp', label: 'xp' }, | ||||
|   XPSORT: { code: 'xpsort', label: 'xp sort' }, | ||||
|   NIVEAU: { code: 'niveau', label: 'Niveau' }, | ||||
|   XPCARAC: { code: 'xpcarac', label: 'xp carac' }, | ||||
|   CARAC: { code: 'carac', label: 'Carac' }, | ||||
|   STRESS: { code: 'stress', label: 'Stress' }, | ||||
|   TRANSFORM: { code: 'xps', label: 'Transformé' }, | ||||
| } | ||||
|  | ||||
| export class ExperienceLog { | ||||
|  | ||||
|   static async add(actor, topic, from, to, raison, manuel = false) { | ||||
|     if (!actor.hasPlayerOwner || !actor.isPersonnage()) { | ||||
|       return | ||||
|     } | ||||
|     if (from == to) { | ||||
|       return | ||||
|     } | ||||
|     const newXpLog = { | ||||
|       mode: topic?.code ?? topic, | ||||
|       raison: (manuel ? '(manuel) ' : '') + raison, | ||||
|       from: from, | ||||
|       to: to, | ||||
|       valeur: to - from, | ||||
|       daterdd: game.system.rdd.calendrier.dateCourante(), | ||||
|       datereel: game.system.rdd.calendrier.dateReel().replace('T', ' ') | ||||
|     }; | ||||
|     console.log('ExperienceLog.add', newXpLog) | ||||
|     const newExperienceLog = (actor.system.experiencelog ?? []).concat([newXpLog]); | ||||
|     await actor.update({ [`system.experiencelog`]: newExperienceLog }); | ||||
|   } | ||||
|  | ||||
|   static labelTopic(topic) { | ||||
|     const xpt = Object.values(XP_TOPIC).find(it => it.code == topic); | ||||
|     return xpt?.label ?? xpt?.code ?? topic; | ||||
|   } | ||||
| } | ||||
| @@ -25,23 +25,13 @@ export class DialogChronologie extends Dialog { | ||||
|       journalId: game.settings.get(SYSTEM_RDD, LATEST_USED_JOURNAL_ID), | ||||
|       journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)), | ||||
|       timestamp: game.system.rdd.calendrier.timestamp, | ||||
|       dateReel: DialogChronologie.getCurrentDateTime() | ||||
|       dateReel: game.system.rdd.calendrier.dateReel() | ||||
|     }; | ||||
|     const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData); | ||||
|     const dialog = new DialogChronologie(html, dialogData); | ||||
|     dialog.render(true); | ||||
|   } | ||||
|  | ||||
|   static getCurrentDateTime() { | ||||
|     return new Date().toLocaleString("sv-SE", { | ||||
|       year: "numeric", | ||||
|       month: "2-digit", | ||||
|       day: "2-digit", | ||||
|       hour: "2-digit", | ||||
|       minute: "2-digit" | ||||
|     }).replace(" ", "T"); | ||||
|   } | ||||
|  | ||||
|   constructor(html, dialogData) { | ||||
|     const options = { | ||||
|       classes: ["DialogChronologie"], | ||||
| @@ -124,7 +114,7 @@ export class DialogChronologie extends Dialog { | ||||
|         heure: RdDTimestamp.definition(this.html.find("form.rdddialogchrono :input[name='chronologie.heure']").val()), | ||||
|         minute: this.html.find("form.rdddialogchrono :input[name='chronologie.minute']").val(), | ||||
|       }, | ||||
|       dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val().replace('T', ' ') | ||||
|       dateReel: this.html.find("form.rdddialogchrono :input[name='dateReel']").val() | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -15,6 +15,7 @@ export const TYPES = { | ||||
|   conteneur: 'conteneur', | ||||
|   sort: 'sort', | ||||
|   herbe: 'herbe', | ||||
|   plante: 'plante', | ||||
|   faune: 'faune', | ||||
|   ingredient: 'ingredient', | ||||
|   livre: 'livre', | ||||
| @@ -34,6 +35,8 @@ export const TYPES = { | ||||
|   maladie: 'maladie', | ||||
|   poison: 'poison', | ||||
|   oeuvre: 'oeuvre', | ||||
|   monnaie: 'monnaie', | ||||
|   munition: 'munition', | ||||
|   nourritureboisson: 'nourritureboisson', | ||||
|   service: 'service', | ||||
|   signedraconique: 'signedraconique', | ||||
| @@ -42,7 +45,8 @@ export const TYPES = { | ||||
|   sortreserve: 'sortreserve', | ||||
|   extraitpoetique: 'extraitpoetique', | ||||
|   tarot: 'tarot', | ||||
|   empoignade: 'empoignade' | ||||
|   empoignade: 'empoignade', | ||||
|   objet: 'objet' | ||||
| } | ||||
| const typesInventaireMateriel = [ | ||||
|   TYPES.arme, | ||||
|   | ||||
| @@ -29,7 +29,7 @@ export class RdDConteneurItemSheet extends RdDItemInventaireSheet { | ||||
|   /* -------------------------------------------- */ | ||||
|   prepareConteneurData(formData) { | ||||
|     RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); | ||||
|     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets); | ||||
|     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); | ||||
|     formData.subItems = formData.conteneurs.find(it => it._id == this.item.id)?.subItems; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||
| import { RdDRaretes } from "./item/raretes.js"; | ||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||
| import { ExperienceLog } from "./actor/experience-log.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| // This table starts at 0 -> niveau -10 | ||||
| @@ -136,6 +137,7 @@ export class RdDUtility { | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/blessure.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/maladies-poisons.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/possessions.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/resonances.hbs', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/taches.html', | ||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/oeuvres.html', | ||||
| @@ -283,6 +285,9 @@ export class RdDUtility { | ||||
|     Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite()); | ||||
|     Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field)); | ||||
|     Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field)); | ||||
|  | ||||
|     Handlebars.registerHelper('experienceLog-topic', topic => ExperienceLog.labelTopic(topic)); | ||||
|  | ||||
|     return loadTemplates(templatePaths); | ||||
|   } | ||||
|  | ||||
| @@ -334,13 +339,13 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static buildArbreDeConteneurs(conteneurs, objets) { | ||||
|   static buildArbreDeConteneurs(conteneurs, inventaires) { | ||||
|     let objetVersConteneur = {}; | ||||
|     // Attribution des objets aux conteneurs | ||||
|     for (let conteneur of conteneurs) { | ||||
|       conteneur.subItems = []; | ||||
|       for (let id of conteneur.system.contenu ?? []) { | ||||
|         let objet = objets.find(objet => (id == objet._id)); | ||||
|         let objet = inventaires.find(objet => (id == objet._id)); | ||||
|         if (objet) { | ||||
|           objet.estContenu = true; // Permet de filtrer ce qui est porté dans le template | ||||
|           objetVersConteneur[id] = conteneur._id; | ||||
| @@ -349,20 +354,20 @@ export class RdDUtility { | ||||
|       } | ||||
|     } | ||||
|     for (let conteneur of conteneurs) { | ||||
|       conteneur.system.encTotal = RdDUtility.calculEncContenu(conteneur, objets); | ||||
|       conteneur.system.encTotal = RdDUtility.calculEncContenu(conteneur, inventaires); | ||||
|     } | ||||
|     return objetVersConteneur; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static calculEncContenu(conteneur, objets) { | ||||
|   static calculEncContenu(conteneur, inventaires) { | ||||
|     const contenus = (conteneur.system.contenu ?? []).filter(id => id != undefined) | ||||
|       .map(id => objets.find(it => (id == it.id))) | ||||
|       .map(id => inventaires.find(it => (id == it.id))) | ||||
|       .filter(it => it); | ||||
|     let enc = Number(conteneur.system.encombrement ?? 0) * Number(conteneur.system.quantite ?? 1); | ||||
|     for (let contenu of contenus) { | ||||
|       if (contenu.type == 'conteneur') { | ||||
|         enc += RdDUtility.calculEncContenu(contenu, objets); | ||||
|         enc += RdDUtility.calculEncContenu(contenu, inventaires); | ||||
|       } | ||||
|       else { | ||||
|         enc += Number(contenu.system.encombrement ?? 0) * Number(contenu.system.quantite ?? 1) | ||||
| @@ -859,17 +864,13 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete) { | ||||
|   static confirmerSuppressionSubacteur(sheet, subActor, htmlToDelete, onSuppression = ()=>{}) { | ||||
|     RdDConfirm.confirmer({ | ||||
|       settingConfirmer: "confirmation-supprimer-lien-acteur", | ||||
|       content: `<p>Etes vous certain de vouloir supprimer le lien vers ${subActor.name} ?</p>`, | ||||
|       title: 'Confirmer la suppression', | ||||
|       buttonLabel: 'Supprimer le lien', | ||||
|       onAction: () => { | ||||
|         console.log('Delete : ', subActor.id); | ||||
|         sheet.actor.removeSubacteur(subActor.id); | ||||
|         RdDUtility.slideOnDelete(sheet, htmlToDelete); | ||||
|       } | ||||
|       onAction: onSuppression | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -182,6 +182,16 @@ export class RdDCalendrier extends Application { | ||||
|     return this.timestamp.formatDate(); | ||||
|   } | ||||
|  | ||||
|   dateReel() { | ||||
|     return new Date().toLocaleString("sv-SE", { | ||||
|       year: "numeric", | ||||
|       month: "2-digit", | ||||
|       day: "2-digit", | ||||
|       hour: "2-digit", | ||||
|       minute: "2-digit" | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   isAfterIndexDate(indexDate) { | ||||
|     // TODO: standardize | ||||
|     return indexDate < this.timestamp.indexDate; | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { ExperienceLog, XP_TOPIC } from "../actor/experience-log.js"; | ||||
| import { ChatUtility } from "../chat-utility.js"; | ||||
| import { Poetique } from "../poetique.js"; | ||||
| import { RdDDice } from "../rdd-dice.js"; | ||||
| @@ -53,9 +54,10 @@ export class EffetsRencontre { | ||||
|   static xp_sort_force = async (dialog, context) => {  | ||||
|     let competence = context.competence; | ||||
|     if (competence) { | ||||
|       const xpSort = Misc.toInt(competence.system.xp_sort) + context.rencontre.system.force; | ||||
|       await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': xpSort }]); | ||||
|       await this.updateExperienceLog("XP Sort", xpSort, `Rencontre d'un ${context.rencontre.name} en TMR`); | ||||
|       const fromXpSort = Number(competence.system.xp_sort); | ||||
|       const toXpSort = fromXpSort + context.rencontre.system.force; | ||||
|       await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'system.xp_sort': toXpSort }]); | ||||
|       await ExperienceLog.add(this, XP_TOPIC.XPSORT, fromXpSort, toXpSort, `${competence.name} - ${context.rencontre.name} en TMR`); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,12 +1,13 @@ | ||||
| { | ||||
|   "id": "foundryvtt-reve-de-dragon", | ||||
|   "title": "Rêve de Dragon", | ||||
|   "version": "10.7.13", | ||||
|   "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.13.zip", | ||||
|   "version": "10.7.16", | ||||
|   "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.7.16.zip", | ||||
|   "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json", | ||||
|   "compatibility": { | ||||
|     "minimum": "10", | ||||
|     "verified": "10" | ||||
|     "verified": "10", | ||||
|     "maximum": "10" | ||||
|   }, | ||||
|   "description": "Rêve de Dragon RPG for FoundryVTT", | ||||
|   "authors": [ | ||||
|   | ||||
| @@ -41,6 +41,9 @@ | ||||
|             {{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-creature.html"}} | ||||
|             {{>"systems/foundryvtt-reve-de-dragon/templates/actor/comp-possession.html"}} | ||||
|           </div> | ||||
|           <div> | ||||
|             {{>"systems/foundryvtt-reve-de-dragon/templates/actor/resonances.hbs"}} | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="form-group large-editor"> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| {{#if recettesAlchimiques.length}} | ||||
| <h3>Recettes Alchimiques</h3> | ||||
| <ul class="item-list alterne-list"> | ||||
|   {{#each recettesAlchimiques as |recette id|}} | ||||
|   {{#each (trier 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 flex-shrink"> | ||||
|       <a class="item-edit" title="Edit Item"><i class="fas fa-edit"></i></a> | ||||
|   | ||||
| @@ -61,7 +61,7 @@ | ||||
|               {{/unless}} | ||||
|             </label> | ||||
|           </li> | ||||
|           {{#each system.services as |service key|}} | ||||
|           {{#each (trier system.services) as |service key|}} | ||||
|           <li class="item flexrow list-item" data-key="{{key}}"> | ||||
|             <input {{@root.disabled}} type="text" name="services[{{key}}].name" value="{{service.name}}" data-dtype="String" /> | ||||
|             <input {{@root.disabled}} type="checkbox" name="services[{{key}}].system.moral" {{#if service.system.moral}}checked{{/if}} /> | ||||
|   | ||||
| @@ -25,14 +25,14 @@ | ||||
|     <span class="equipement-detail">Prix (sols)</span> | ||||
|     <span class="equipement-actions">Actions</span> | ||||
|   </li> | ||||
|   {{#each objets as |item id|}} | ||||
|   {{#each (trier inventaires) as |item id|}} | ||||
|     {{#unless item.estContenu}} | ||||
|       {{#if (ne item.type 'conteneur')}} | ||||
|         {{buildLigneInventaire item ../options}} | ||||
|       {{/if}} | ||||
|     {{/unless}} | ||||
|   {{/each}} | ||||
|   {{#each conteneurs as |conteneur id|}} | ||||
|   {{#each (trier conteneurs) as |conteneur id|}} | ||||
|     {{buildLigneInventaire conteneur ../options}} | ||||
|   {{/each}} | ||||
| </ul> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| {{#if meditations.length}} | ||||
| <h3>Méditations</h3> | ||||
| <ul class="item-list"> | ||||
|   {{#each meditations as |meditation key|}} | ||||
|   {{#each (trier meditations) as |meditation key|}} | ||||
|   <li class="item flexrow" data-item-id="{{meditation._id}}" data-attribute="{{key}}"> | ||||
|     <img class="sheet-competence-img" src="{{meditation.img}}" /> | ||||
|     <span class="meditation-label flex-grow"><a data-item-id="{{meditation._id}}">{{meditation.name}} - {{meditation.system.competence}}</a></span>  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| {{#if sortsReserve.length}} | ||||
| <h3>Sorts en Réserve</h3> | ||||
| <ul class="item-list alterne-list"> | ||||
|   {{#each sortsReserve as |sort key|}} | ||||
|   {{#each (trier sortsReserve) as |sort key|}} | ||||
|   <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}"> | ||||
|     <img class="sheet-competence-img" src="{{sort.img}}" /> | ||||
|     <span class="item-edit"><a>{{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}}</a></span>  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| {{#if sorts.length}} | ||||
| <h3>Sorts</h3> | ||||
| <ul class="item-list alterne-list"> | ||||
|   {{#each sorts as |sort key|}} | ||||
|   {{#each (trier sorts) as |sort key|}} | ||||
|   <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}"> | ||||
|     <img class="sheet-competence-img" src="{{sort.img}}" /> | ||||
|     <span class="item-edit flex-grow-2"> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| {{#if @root.options.isObserver}} | ||||
| <span class="item-name"><h4>Argent et Monnaies (fortune: {{calc.fortune.sols}} sols {{calc.fortune.deniers}} deniers)</h4></span> | ||||
| <ul class="item-list alterne-list"> | ||||
|   {{#each monnaie as |piece id|}} | ||||
|   {{#each monnaies as |piece id|}} | ||||
|   <li class="item flexrow list-item" data-item-id="{{piece._id}}"> | ||||
|     <img class="sheet-competence-img" src="{{piece.img}}" title="{{piece.name}}"/> | ||||
|     <span class="equipement-nom">{{piece.name}}</span> | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
|     <span class="equipement-detail">Enc.</span> | ||||
|     <span class="equipement-actions">Actions</span> | ||||
|   </li> | ||||
|   {{#each objets as |item id|}} | ||||
|   {{#each inventaires as |item id|}} | ||||
|     {{#unless item.estContenu}} | ||||
|     {{#if (ne item.type 'conteneur')}} | ||||
|       {{buildLigneInventaire item @root.options}} | ||||
|   | ||||
| @@ -1,18 +1,18 @@ | ||||
| <h3>Oeuvres diverses</h3><a class="chat-card-button creer-une-oeuvre">Créer une oeuvre</a> | ||||
| <ul class="item-list alterne-list"> | ||||
|   {{#each chants as |chant id|}} | ||||
|   {{#each (trier chants) as |chant id|}} | ||||
|   {{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=chant typeOeuvre="Chant" classOeuvre="chant-label"}} | ||||
|   {{/each}} | ||||
|   {{#each musiques as |musique id|}} | ||||
|   {{#each (trier musiques) as |musique id|}} | ||||
|   {{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=musique typeOeuvre="Musique" classOeuvre="musique-label"}} | ||||
|   {{/each}} | ||||
|   {{#each danses as |danse id|}} | ||||
|   {{#each (trier danses) as |danse id|}} | ||||
|   {{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=danse typeOeuvre="Danse" classOeuvre="danse-label"}} | ||||
|   {{/each}} | ||||
|   {{#each oeuvres as |oeuvre id|}} | ||||
|   {{#each (trier oeuvres) as |oeuvre id|}} | ||||
|   {{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=oeuvre typeOeuvre=oeuvre.system.competence classOeuvre="oeuvre-label"}} | ||||
|   {{/each}} | ||||
|   {{#each recettescuisine as |recette id|}} | ||||
|   {{#each (trier recettescuisine) as |recette id|}} | ||||
|   {{> "systems/foundryvtt-reve-de-dragon/templates/actor/oeuvre.html" oeuvre=recette typeOeuvre="Recette de cuisine" classOeuvre="recettecuisine-label"}} | ||||
|   {{/each}} | ||||
| </ul> | ||||
|   | ||||
							
								
								
									
										12
									
								
								templates/actor/resonances.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								templates/actor/resonances.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| <span class="item-name"><h4>Personnages accordés</h4></span> | ||||
| <ul class="item-list alterne-list"> | ||||
|   {{#each resonances as |actor|}} | ||||
|   <li class="item flexrow list-item" data-actor-id="{{actor.id}}"> | ||||
|     <img class="sheet-competence-img" src="{{actor.img}}" title="{{actor.name}}"/> | ||||
|     <span class="subacteur-label"><a>{{actor.name}}</a></span> | ||||
|     <div class="flex-shrink"> | ||||
|       <a class="resonance-delete" title="Supprimer"><i class="fas fa-trash"></i></a> | ||||
|   </div> | ||||
|   </li> | ||||
|   {{/each}} | ||||
| </ul> | ||||
| @@ -3,7 +3,7 @@ | ||||
|     <li class="item flexrow"> | ||||
|       <label class="derivee-label" for="system.compteurs.experience.value">Stress transformé</label> | ||||
|       {{#if options.vueDetaillee}} | ||||
|       <input type="number" name="system.compteurs.experience.value" value="{{system.compteurs.experience.value}}" data-dtype="number" size="3"/> | ||||
|       <input class="derivee-value" type="number" name="system.compteurs.experience.value" value="{{system.compteurs.experience.value}}" data-dtype="number" size="3"/> | ||||
|       {{else}} | ||||
|       <label name="system.compteurs.experience.value">{{system.compteurs.experience.value}}</label> | ||||
|       {{/if}} | ||||
|   | ||||
| @@ -1,14 +1,18 @@ | ||||
| <h3>Journal d'Experience</h3> | ||||
| <div class="form-group large-editor"> | ||||
|   <ul class="item-list alterne-list"> | ||||
|   {{#each system.experiencelog as |xp key|}} | ||||
|   {{#each system.experiencelog as |xplog key|}} | ||||
|     <li class="experiencelog flexrow list-item" data-key="{{key}}"> | ||||
|       <label class="flex-grow">{{xp.valeur}} {{xp.raison}}</label> | ||||
|       <label class="flex-shrink">{{xp.mode}}</label> | ||||
|       <label class="flex-shrink">{{xp.daterdd}}</label> | ||||
|       <label class="flex-shrink">{{xp.datereel}}</label> | ||||
|       <label class="flex-shrink">{{xplog.valeur}} {{experienceLog-topic xplog.mode}} </label> | ||||
|       {{#if (or xplog.from xplog.to)}} | ||||
|       <label class="flex-grow">{{xplog.raison}}: de {{xplog.from}} à {{xplog.to}}</label> | ||||
|       {{else}} | ||||
|       <label class="flex-grow">{{xplog.raison}}</label> | ||||
|       {{/if}} | ||||
|       <label class="flex-shrink">{{xplog.daterdd}}</label> | ||||
|       <label class="flex-shrink">{{xplog.datereel}}</label> | ||||
|       {{#if @root.options.isGM}} | ||||
|       <span> | ||||
|       <span class="flex-shrink"> | ||||
|         <a class="experiencelog-delete" title="Supprimer"> | ||||
|           <i class="fas fa-trash"></i> | ||||
|         </a> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user