Fix calcul de l'expérience
Ajout d'une commande pour calculer l'expérience pour augmenter
This commit is contained in:
		| @@ -41,7 +41,7 @@ export class RdDActorSheet extends ActorSheet { | ||||
|     data.itemsByType = RdDItem.buildItemsClassification(data.items); | ||||
|  | ||||
|     // Competence per category | ||||
|     let competenceXPTotal = 0; | ||||
|     data.data.competenceXPTotal = 0; | ||||
|     data.competenceByCategory = RdDItem.classify( | ||||
|       data.itemsByType.competence, | ||||
|       item => item.data.categorie, | ||||
| @@ -51,11 +51,10 @@ export class RdDActorSheet extends ActorSheet { | ||||
|         //this.actor.checkCompetenceXP(item.name); // Petite vérification experience | ||||
|         item.data.showCompetence = !data.data.showCompNiveauBase || (Number(item.data.niveau) != Number(RdDUtility.getLevelCategory(item.data.categorie))); | ||||
|         // Ignorer les compétences 'troncs' à ce stade | ||||
|         competenceXPTotal += RdDItemCompetence.isTronc(item.name) ? 0 : RdDItemCompetence.computeCompetenceXPCost(item); | ||||
|         data.data.competenceXPTotal += RdDItemCompetence.computeCompetenceXPCost(item); | ||||
|         return item; | ||||
|       }); | ||||
|     competenceXPTotal += RdDItemCompetence.computeCompetenceTroncXP(data.itemsByType.competence); | ||||
|     data.data.competenceXPTotal = competenceXPTotal; | ||||
|     data.data.competenceXPTotal -= RdDItemCompetence.computeEconomieCompetenceTroncXP(data.itemsByType.competence); | ||||
|  | ||||
|     // Compute current carac sum | ||||
|     let sum = 0; | ||||
|   | ||||
| @@ -3,6 +3,20 @@ const competenceTroncs = [["Esquive", "Dague", "Corps à corps"], | ||||
| ["Epée à 1 main", "Epée à 2 mains", "Hache à 1 main", "Hache à 2 mains", "Lance", "Masse à 1 main", "Masse à 2 mains"]]; | ||||
|  | ||||
| const competence_xp_par_niveau = [5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20, 30, 30, 40, 40, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100]; | ||||
| const competence_niveau_max = competence_xp_par_niveau.length - 10; | ||||
|  | ||||
| function _buildCumulXP() { | ||||
|   let cumulXP = { "-11": 0 }; | ||||
|   let cumul = 0; | ||||
|   for (let i = 0; i <= competence_xp_par_niveau.length; i++) { | ||||
|     let level = i - 10; | ||||
|     cumul += competence_xp_par_niveau[i]; | ||||
|     cumulXP[level] = cumul; | ||||
|   } | ||||
|   return cumulXP; | ||||
| } | ||||
|  | ||||
| const competence_xp_cumul = _buildCumulXP(); | ||||
|  | ||||
| export class RdDItemCompetence extends Item { | ||||
|  | ||||
| @@ -43,44 +57,25 @@ export class RdDItemCompetence extends Item { | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   static computeCompetenceXPCost(competence) { | ||||
|     let minLevel = competence.data.base; | ||||
|     if (minLevel == competence.data.niveau) return 0; | ||||
|     if (competence.data.niveau < -10) return 0; | ||||
|  | ||||
|     let xp = 0; | ||||
|     for (let i = minLevel + 1; i <= competence.data.niveau; i++) { | ||||
|       xp += competence_xp_par_niveau[i + 10]; | ||||
|       //console.log(i, i+10, competence_xp_par_niveau[i+10]); | ||||
|     } | ||||
|     if (competence.data.categorie == 'draconic') { | ||||
|       xp += competence.data.xp_sort; | ||||
|     } | ||||
|     let xp = RdDItemCompetence.getDeltaXp(competence.data.base, competence.data.niveau ?? competence.data.base); | ||||
|     xp += competence.data.xp ?? 0; | ||||
|     xp += competence.data.xp_sort ?? 0; | ||||
|     return xp; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static computeCompetenceTroncXP(competences) { | ||||
|     let xp = 0; | ||||
|   static computeEconomieCompetenceTroncXP(competences) { | ||||
|     let economie = 0; | ||||
|     for (let troncList of competenceTroncs) { | ||||
|       let minNiveau = 0; | ||||
|       for (let troncName of troncList) { | ||||
|         let comp = RdDItemCompetence.findCompetence(competences, troncName); | ||||
|         if (comp) { | ||||
|           minNiveau = Math.min(comp.data.niveau, minNiveau); | ||||
|         } | ||||
|       } | ||||
|       minNiveau = Math.max(minNiveau, 0); // Clamp à 0, pour le tronc commun | ||||
|       let minNiveauXP = competence_xp_par_niveau[minNiveau + 10]; | ||||
|       xp += minNiveauXP; | ||||
|       for (let troncName of troncList) { | ||||
|         let comp = RdDItemCompetence.findCompetence(competences, troncName); | ||||
|         if (comp) { | ||||
|           xp += competence_xp_par_niveau[comp.data.niveau + 10] - minNiveauXP; | ||||
|         } | ||||
|       } | ||||
|       let list = troncList.map(name => RdDItemCompetence.findCompetence(competences, name)) | ||||
|         .sort( (c1, c2) => c2.data.niveau - c1.data.niveau); // tri du plus haut au plus bas | ||||
|       list.splice(0,1); // ignorer la plus élevée | ||||
|       list.forEach(c => { | ||||
|         economie += RdDItemCompetence.getDeltaXp(c.data.base, Math.min(c.data.niveau, 0) ); | ||||
|       }); | ||||
|     } | ||||
|     return xp; | ||||
|     return economie; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static findCompetence(list, name) { | ||||
|     name = name.toLowerCase(); | ||||
| @@ -89,7 +84,24 @@ export class RdDItemCompetence extends Item { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static getCompetenceNextXp(niveau) { | ||||
|     return competence_xp_par_niveau[niveau + 10]; | ||||
|     return RdDItemCompetence.getCompetenceXp(niveau + 1); | ||||
|   } | ||||
|  | ||||
|   static getCompetenceXp(niveau) { | ||||
|     RdDItemCompetence._valideNiveau(niveau); | ||||
|     return niveau < -10 ? 0 : competence_xp_par_niveau[niveau + 10]; | ||||
|   } | ||||
|  | ||||
|   static getDeltaXp(from, to) { | ||||
|     RdDItemCompetence._valideNiveau(from); | ||||
|     RdDItemCompetence._valideNiveau(to); | ||||
|     return competence_xp_cumul[to] - competence_xp_cumul[from]; | ||||
|   } | ||||
|  | ||||
|   static _valideNiveau(niveau){ | ||||
|     if (niveau < -11 || niveau > competence_niveau_max) { | ||||
|       console.warn("Niveau en dehors des niveaux de compétences: [-11, " + competence_niveau_max + "]", niveau) | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| import { ChatUtility } from "./chat-utility.js"; | ||||
| import { DeDraconique } from "./de-draconique.js"; | ||||
| import { RdDItemCompetence } from "./item-competence.js"; | ||||
| import { Misc } from "./misc.js"; | ||||
| import { RdDDice } from "./rdd-dice.js"; | ||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||
| @@ -30,8 +31,21 @@ export class RdDCommands { | ||||
|  | ||||
|       rddCommands.registerCommand({ path: ["/tmra"], func: (content, msg, params) => TMRUtility.getTMRAleatoire(), descr: "Tire une case aléatoire des Terres médianes" }); | ||||
|       rddCommands.registerCommand({ | ||||
|         path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params), | ||||
|         descr: "Syntaxe: <strong>/tmrr case jet</strong><br>Détermine quelle est la rencontre dans la case pour le jet<br>Exemple: <strong>/tmrr forêt 50</strong>" | ||||
|         path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(msg, params), | ||||
|         descr: "Exemple: <strong>/tmrr forêt 47</strong><br>Détermine quelle est la rencontre dans une case 'forêt' pour un jet de dé de 47" | ||||
|       }); | ||||
|  | ||||
|       rddCommands.registerCommand({ | ||||
|         path: ["/xp", "comp"], func: (content, msg, params) => rddCommands.getCoutXpComp(msg, params), | ||||
|         descr: `Détermine le coût d'expérience pour augmenter une compétence. Exemples: | ||||
|         <br>/xp comp -6 1: pour passer de -6 à +1 | ||||
|         <br>/xp comp +4: pour atteindre le niveau 4 (depuis +3)` | ||||
|       }); | ||||
|  | ||||
|       rddCommands.registerCommand({ | ||||
|         path: ["/xp", "carac"], func: (content, msg, params) => rddCommands.getCoutXpCarac(msg, params), | ||||
|         descr: `Détermine le coût d'expérience pour augmenter une caractéristique. Exemples: | ||||
|         <br>/xp carac 15: coût pour atteindre 15 (depuis 14)` | ||||
|       }); | ||||
|  | ||||
|       rddCommands.registerCommand({ | ||||
| @@ -129,8 +143,9 @@ export class RdDCommands { | ||||
|       } | ||||
|     } | ||||
|     if (command && command.func) { | ||||
|       if (command.func(content, msg, params) === false) { | ||||
|         this._displayHelp(msg, `${path}: ${command.descr}`); | ||||
|       const result = command.func(content, msg, params); | ||||
|       if (result == false) { | ||||
|         RdDCommands._chatAnswer(msg, command.descr); | ||||
|       } | ||||
|       return true; | ||||
|     } | ||||
| @@ -142,8 +157,13 @@ export class RdDCommands { | ||||
|     let list = [] | ||||
|     this._buildSubTableHelp(list, table || this.commandsTable); | ||||
|     const messageAide = list.reduce((a, b) => a + '</li><li class="list-item">' + b); | ||||
|     RdDCommands._chatAnswer(msg, `Commandes disponibles<ul class="alterne-list"><li class="list-item">${messageAide}</li></ul>`); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static _chatAnswer(msg, content) { | ||||
|     msg.whisper = [game.user._id]; | ||||
|     msg.content = `Commandes disponibles<ul class="alterne-list"><li class="list-item">${messageAide}</li></ul>`; | ||||
|     msg.content = content; | ||||
|     ChatMessage.create(msg); | ||||
|   } | ||||
|  | ||||
| @@ -161,7 +181,7 @@ export class RdDCommands { | ||||
|     return list.sort(); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   getRencontreTMR(params) { | ||||
|     if (params.length == 2) { | ||||
|       return TMRUtility.getRencontre(params[0], params[1]) | ||||
| @@ -171,6 +191,7 @@ export class RdDCommands { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollRdd(msg, params) { | ||||
|     if (params.length == 0) { | ||||
|       RdDRollResolutionTable.open(); | ||||
| @@ -188,6 +209,7 @@ export class RdDCommands { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollRdDNumeric(msg, carac, diff, significative = false) { | ||||
|     let rollData = { | ||||
|       caracValue: carac, | ||||
| @@ -197,15 +219,38 @@ export class RdDCommands { | ||||
|       show: { title: "Table de résolution" } | ||||
|     }; | ||||
|     await RdDResolutionTable.rollData(rollData); | ||||
|     msg.content = await RdDResolutionTable.buildRollDataHtml(rollData); | ||||
|     ChatUtility.createChatWithRollMode(game.user.name, msg); | ||||
|     RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData)); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollDeDraconique(msg) { | ||||
|     let ddr = new DeDraconique().evaluate(); | ||||
|     await RdDDice.show(ddr, rollMode); | ||||
|     msg.content = `Lancer d'un Dé draconique: ${ddr.total}`; | ||||
|     ChatUtility.createChatWithRollMode(game.user.name, msg); | ||||
|     RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   getCoutXpComp(msg, params) { | ||||
|     if (params && (params.length == 1 || params.length == 2)) { | ||||
|       let to = params.length == 1 ? Number(params[0]) : Number(params[1]); | ||||
|       let from = params.length == 1 ? to - 1 : Number(params[0]); | ||||
|       RdDCommands._chatAnswer(msg, `Coût pour passer une compétence de ${from} à ${to}: ${RdDItemCompetence.getDeltaXp(from, to)}`); | ||||
|     } | ||||
|     else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   getCoutXpCarac(msg, params) { | ||||
|     if (params && params.length == 1) { | ||||
|       let to = Number(params[0]); | ||||
|       RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDUtility.getCaractXp(to)}`); | ||||
|     } | ||||
|     else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -405,8 +405,13 @@ export class RdDUtility { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static getCaracNextXp(value) { | ||||
|     const nextValue = Number(value) + 1; | ||||
|     // xp est le coût pour atteindre cette valeur, on regarde donc le coût de la valeur+1 | ||||
|     return tableCaracDerivee[Number(value)+1].xp; | ||||
|     return RdDUtility.getCaractXp(nextValue); | ||||
|   } | ||||
|  | ||||
|   static getCaractXp(targetValue) { | ||||
|     return tableCaracDerivee[targetValue].xp; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user