foundryvtt-reve-de-dragon/module/item-competence.js
2021-03-09 02:02:34 +01:00

159 lines
5.6 KiB
JavaScript

import { RdDUtility } from "./rdd-utility.js";
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 compendiumCompetences = {
"personnage": "foundryvtt-reve-de-dragon.competences",
"creature": "foundryvtt-reve-de-dragon.competences-creatures",
"entite": "foundryvtt-reve-de-dragon.competences-entites"
};
const competence_xp_cumul = _buildCumulXP();
export class RdDItemCompetence extends Item {
static compendium(actorType) {
return compendiumCompetences[actorType] ?? '';
}
/* -------------------------------------------- */
static isCompetenceArme(competence) {
switch (competence.data.categorie) {
case 'melee':
return competence.name.toLowerCase() != 'esquive';
case 'tir':
case 'lancer':
return true;
}
return false;
}
/* -------------------------------------------- */
static isArmeUneMain(competence) {
return competence?.name.toLowerCase().includes("1 main");
}
static isArme2Main(competence) {
return competence?.name.toLowerCase().includes("2 main");
}
/* -------------------------------------------- */
static isMalusEncombrementTotal(competence) {
return competence?.name.toLowerCase().match(/(natation|acrobatie)/);
}
/* -------------------------------------------- */
static isTronc(compName) {
for (let troncList of competenceTroncs) {
for (let troncName of troncList) {
if (troncName == compName)
return troncList;
}
}
return false;
}
/* -------------------------------------------- */
static computeTotalXP(competences) {
const total = competences.map(c => RdDItemCompetence.computeXP(c))
.reduce((a, b) => a + b, 0);
const economieTronc = RdDItemCompetence.computeEconomieXPTronc(competences);
return total - economieTronc;
}
/* -------------------------------------------- */
static computeXP(competence) {
// Thanatos compte double !
const factor = competence.name.includes('Thanatos') ? 2 : 1
const xpNiveau = RdDItemCompetence.computeDeltaXP(competence.data.base, competence.data.niveau ?? competence.data.base);
const xp = competence.data.xp ?? 0;
const xpSort = competence.data.xp_sort ?? 0;
return factor * (xpNiveau + xp) + xpSort;
}
/* -------------------------------------------- */
static computeEconomieXPTronc(competences) {
return competenceTroncs.map(
list => list.map(name => RdDItemCompetence.findCompetence(competences, name))
// calcul du coût xp jusqu'au niveau 0 maximum
.map(it => RdDItemCompetence.computeDeltaXP(it?.data.base ?? -11, Math.min(it?.data.niveau ?? -11, 0)))
.sort((a, b) => b - a) // tri descendant
.splice(0, 1) // ignorer le coût xp le plus élevé
.reduce((a, b) => a + b, 0)
).reduce((a, b) => a + b, 0);
}
static setLevelUp(competences) {
competences.forEach(it => {
it.data.xpNext = RdDItemCompetence.getCompetenceNextXp(it.data.niveau);
it.data.isLevelUp = it.data.xp >= it.data.xpNext;
});
}
static computeResumeArchetype(competences) {
const archetype = RdDUtility.getLimitesArchetypes();
competences.forEach(item => {
let niveau = (item.data.niveau_archetype < 0) ? 0 : item.data.niveau_archetype;
archetype[niveau] = archetype[niveau] ?? { "niveau": niveau, "nombreMax": 0, "nombre": 0 };
archetype[niveau].nombre = (archetype[niveau]?.nombre ?? 0) + 1;
});
return archetype;
}
static isVisible(competence) {
return Number(competence.data.niveau) != RdDUtility.getCategorieNiveauBase(competence.data.categorie);
}
static isNiveauBase(competence) {
return Number(competence.data.niveau) == RdDUtility.getCategorieNiveauBase(competence.data.categorie);
}
/* -------------------------------------------- */
static findCompetence(list, name) {
name = name.toLowerCase();
return list.find(it => it.name.toLowerCase() == name && (it.type == "competence" || it.type == "competencecreature"))
}
static getEsquive(competences) {
return { name: "Esquive", niveau: RdDItemCompetence.findCompetence(competences, 'Esquive')?.data.niveau ?? -6 };
}
/* -------------------------------------------- */
static getCompetenceNextXp(niveau) {
return RdDItemCompetence.getCompetenceXp(niveau + 1);
}
/* -------------------------------------------- */
static getCompetenceXp(niveau) {
RdDItemCompetence._valideNiveau(niveau);
return niveau < -10 ? 0 : competence_xp_par_niveau[niveau + 10];
}
/* -------------------------------------------- */
static computeDeltaXP(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)
}
}
}