25d7a447a8
Ajout de méthode Misc.data pour accéder aux data des Actor/Item Dans le cas où on est sur un Actor/Item, retourne le document (noeud data) Dans les autres cas, retourne l'objet lkui même (donc, le document) Du coup, on devrait pouvoir facilement changer en 0.8.0
231 lines
8.2 KiB
JavaScript
231 lines
8.2 KiB
JavaScript
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;
|
|
/* -------------------------------------------- */
|
|
const limitesArchetypes = [
|
|
{ "niveau": 0, "nombreMax": 100, "nombre": 0 },
|
|
{ "niveau": 1, "nombreMax": 10, "nombre": 0 },
|
|
{ "niveau": 2, "nombreMax": 9, "nombre": 0 },
|
|
{ "niveau": 3, "nombreMax": 8, "nombre": 0 },
|
|
{ "niveau": 4, "nombreMax": 7, "nombre": 0 },
|
|
{ "niveau": 5, "nombreMax": 6, "nombre": 0 },
|
|
{ "niveau": 6, "nombreMax": 5, "nombre": 0 },
|
|
{ "niveau": 7, "nombreMax": 4, "nombre": 0 },
|
|
{ "niveau": 8, "nombreMax": 3, "nombre": 0 },
|
|
{ "niveau": 9, "nombreMax": 2, "nombre": 0 },
|
|
{ "niveau": 10, "nombreMax": 1, "nombre": 0 },
|
|
{ "niveau": 11, "nombreMax": 1, "nombre": 0 }
|
|
];
|
|
|
|
/* -------------------------------------------- */
|
|
const categorieCompetences = {
|
|
"generale": { level: "-4", label: "Générales" },
|
|
"particuliere": { level: "-8", label: "Particulières" },
|
|
"specialisee": { level: "-11", label: "Spécialisées" },
|
|
"connaissance": { level: "-11", label: "Connaissances" },
|
|
"draconic": { level: "-11", label: "Draconics" },
|
|
"melee": { level: "-6", label: "Mêlée" },
|
|
"tir": { level: "-8", label: "Tir" },
|
|
"lancer": { level: "-8", label: "Lancer" }
|
|
}
|
|
|
|
const compendiumCompetences = {
|
|
"personnage": "foundryvtt-reve-de-dragon.competences",
|
|
"creature": "foundryvtt-reve-de-dragon.competences-creatures",
|
|
"entite": "foundryvtt-reve-de-dragon.competences-entites"
|
|
};
|
|
|
|
|
|
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 {
|
|
|
|
static actorCompendium(actorType) {
|
|
return compendiumCompetences[actorType];
|
|
}
|
|
|
|
static getCategorieCompetences() {
|
|
return categorieCompetences;
|
|
}
|
|
static getNiveauBase(category) {
|
|
return categorieCompetences[category].level;
|
|
}
|
|
static getLabelCategorie(category) {
|
|
return categorieCompetences[category].label;
|
|
}
|
|
|
|
static getEsquive(competences) {
|
|
return { name: 'Esquive', niveau: RdDItemCompetence.findCompetence(competences, 'Esquive')?.data.niveau ?? -6 };
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static isCompetenceArme(competence) {
|
|
switch (competence.data.categorie) {
|
|
case 'melee':
|
|
return competence.name != '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) {
|
|
const factor = competence.name.includes('Thanatos') ? 2 : 1; // Thanatos compte double !
|
|
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 computeDeltaXP(from, to) {
|
|
RdDItemCompetence._valideNiveau(from);
|
|
RdDItemCompetence._valideNiveau(to);
|
|
return competence_xp_cumul[to] - competence_xp_cumul[from];
|
|
}
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
static computeCompetenceXPCost(competence) {
|
|
let xp = RdDItemCompetence.getDeltaXp(competence.data.base, competence.data.niveau ?? competence.data.base);
|
|
xp += competence.data.xp ?? 0;
|
|
if (competence.name.includes('Thanatos')) xp *= 2; /// Thanatos compte double !
|
|
xp += competence.data.xp_sort ?? 0;
|
|
return xp;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static computeEconomieCompetenceTroncXP(competences) {
|
|
let economie = 0;
|
|
for (let troncList of competenceTroncs) {
|
|
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 economie;
|
|
}
|
|
|
|
static levelUp(itemData) {
|
|
itemData.data.xpNext = RdDItemCompetence.getCompetenceNextXp(itemData.data.niveau);
|
|
itemData.data.isLevelUp = itemData.data.xp >= itemData.data.xpNext;
|
|
}
|
|
|
|
static isVisible(itemData) {
|
|
return Number(itemData.data.niveau) != RdDItemCompetence.getNiveauBase(itemData.data.categorie);
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static isNiveauBase(itemData) {
|
|
return Number(itemData.data.niveau) == RdDItemCompetence.getNiveauBase(itemData.data.categorie);
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static findCompetence(list, name) {
|
|
name = name.toLowerCase();
|
|
return list.find(it => it.name.toLowerCase() == name && (it.type == "competence" || it.type == "competencecreature"))
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
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 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 ${niveau} en dehors des niveaux de compétences: [-11, ${competence_niveau_max} ]`);
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static computeResumeArchetype(competences) {
|
|
const archetype = RdDItemCompetence.getLimitesArchetypes();
|
|
competences.forEach(it => {
|
|
let niveau = Math.max(0, it.data.niveau_archetype);
|
|
archetype[niveau] = archetype[niveau] ?? { "niveau": niveau, "nombreMax": 0, "nombre": 0 };
|
|
archetype[niveau].nombre = (archetype[niveau]?.nombre ?? 0) + 1;
|
|
});
|
|
return archetype;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static getLimitesArchetypes() {
|
|
return duplicate(limitesArchetypes);
|
|
}
|
|
|
|
} |