Nettoyage de data

* séparation de options, calc, ...
* extraction de méthodes pour clarifier ce qui est fait dans getData
* fix de la feuille: utiliser data.data
* fix d'Actor:  update({ data.data
This commit is contained in:
Vincent Vandemeulebrouck
2021-03-05 03:42:45 +01:00
parent 2cb7647fc4
commit 3ae461bb71
110 changed files with 600 additions and 433 deletions

View File

@@ -7,6 +7,8 @@
import { HtmlUtility } from "./html-utility.js";
import { RdDUtility } from "./rdd-utility.js";
import { RdDActorSheet } from "./actor-sheet.js";
import { Misc } from "./misc.js";
import { RdDCarac } from "./rdd-carac.js";
/* -------------------------------------------- */
export class RdDActorCreatureSheet extends RdDActorSheet {
@@ -26,40 +28,29 @@ export class RdDActorCreatureSheet extends RdDActorSheet {
/* -------------------------------------------- */
getData() {
let data = super.getData();
console.log("Creature : ", data);
let sheetData = super.getData();
console.log("Creature : ", sheetData);
data.itemsByType = {};
for (const item of data.items) {
let list = data.itemsByType[item.type];
if (!list) {
list = [];
data.itemsByType[item.type] = list;
sheetData.itemsByType = Misc.classify(sheetData.items, item => item.type);
sheetData.calc = {
caracTotal: RdDCarac.computeTotal(sheetData.data.data.carac),
blessures: {
resume: sheetData.actor.computeResumeBlessure(sheetData.data.data.blessures)
}
list.push(item);
}
// Compute current carac sum
let sum = 0;
Object.values(data.data.carac).forEach(carac => { if (!carac.derivee) { sum += parseInt(carac.value) } });
data.data.caracSum = sum;
sheetData.data.carac.taille.isTaille = true; // To avoid button link;
data.data.carac.taille.isTaille = true; // To avoid button link;
data.data.blessures.resume = this.actor.computeResumeBlessure(data.data.blessures);
data.data.isGM = game.user.isGM;
data.data.competencecreature = data.itemsByType["competencecreature"];
sheetData.data.competencecreature = sheetData.itemsByType["competencecreature"];
this.actor.computeEncombrementTotalEtMalusArmure();
RdDUtility.filterItemsPerTypeForSheet(data);
RdDUtility.buildArbreDeConteneur(this, data);
data.data.encTotal = this.actor.encTotal;
data.data.isGM = game.user.isGM;
RdDUtility.filterItemsPerTypeForSheet(sheetData);
RdDUtility.buildArbreDeConteneur(this, sheetData);
console.log("Creature : ", this.objetVersConteneur, data);
console.log("Creature : ", this.objetVersConteneur, sheetData);
return data;
return sheetData;
}
/* -------------------------------------------- */

View File

@@ -20,33 +20,17 @@ export class RdDActorEntiteSheet extends ActorSheet {
});
}
/* -------------------------------------------- */
_checkNull(items) {
if (items && items.length) {
return items;
}
return [];
}
/* -------------------------------------------- */
getData() {
let data = super.getData();
let sheetData = super.getData();
data.itemsByType = {};
for (const item of data.items) {
let list = data.itemsByType[item.type];
if (!list) {
list = [];
data.itemsByType[item.type] = list;
}
list.push(item);
}
data.data.carac.taille.isTaille = true; // To avoid button link;
data.data.competencecreature = data.itemsByType["competencecreature"];
data.data.isGM = game.user.isGM;
sheetData.data.competencecreature = sheetData.itemsByType["competencecreature"];
return data;
data.options = {
isGM: game.user.isGM
};
return sheetData;
}
/* -------------------------------------------- */

View File

@@ -10,6 +10,7 @@ import { RdDItemCompetence } from "./item-competence.js";
import { RdDBonus } from "./rdd-bonus.js";
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
import { RdDCarac } from "./rdd-carac.js";
/* -------------------------------------------- */
export class RdDActorSheet extends ActorSheet {
@@ -31,122 +32,92 @@ export class RdDActorSheet extends ActorSheet {
}
/* -------------------------------------------- */
getData() {
let data = super.getData();
if ( data.actor.type == 'creature' || data.actor.type == 'humanoide') return data; // Shortcut
async getData() {
// Partie commune
let sheetData = await super.getData();
data.data.editCaracComp = this.options.editCaracComp;
data.data.showCompNiveauBase = this.options.showCompNiveauBase;
data.data.montrerArchetype = this.options.montrerArchetype;
sheetData.options = this.options;
sheetData.itemsByType = Misc.classify(sheetData.items, item => item.type);
sheetData.options.isGM = game.user.isGM;
data.itemsByType = Misc.classify(data.items);
const carac = sheetData.data.data.carac;
// la taille est la taille: on ne peut pas l'utiliser pour un jet
carac.taille.isTaille = true;
// Competence per category
data.data.comptageArchetype = RdDUtility.getLimitesArchetypes();
data.data.competenceXPTotal = 0;
data.competenceByCategory = Misc.classify(
data.itemsByType.competence,
item => item.data.categorie,
item => {
let archetypeKey = (item.data.niveau_archetype < 0) ? 0 : item.data.niveau_archetype;
if (data.data.comptageArchetype[archetypeKey] == undefined) {
data.data.comptageArchetype[archetypeKey] = { "niveau": archetypeKey, "nombreMax": 0, "nombre": 0};
}
data.data.comptageArchetype[archetypeKey].nombre = (data.data.comptageArchetype[archetypeKey]?.nombre??0) + 1; //Comptage archetype
item.data.xpNext = RdDItemCompetence.getCompetenceNextXp(item.data.niveau);
item.data.isLevelUp = item.data.xp >= item.data.xpNext; // Flag de niveau à MAJ
//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
data.data.competenceXPTotal += RdDItemCompetence.computeCompetenceXPCost(item);
return item;
});
data.data.competenceXPTotal -= RdDItemCompetence.computeEconomieCompetenceTroncXP(data.itemsByType.competence);
if (sheetData.actor.type == 'creature') return sheetData; // Shortcut
// Compute current carac sum
let sum = 0;
let caracList = data.data.data.carac;
for (let caracName in caracList) {
let currentCarac = caracList[caracName];
if (!currentCarac.derivee) {
sum += parseInt(currentCarac.value);
}
currentCarac.xpNext = RdDUtility.getCaracNextXp(currentCarac.value);
currentCarac.isLevelUp = (currentCarac.xp >= currentCarac.xpNext);
}
sum += (data.data.beaute >= 0) ? (data.data.beaute - 10) : 0;
data.data.caracSum = sum;
/* -- partie spécifique aux personnages -- */
// Force empty arme, at least for Esquive
if (data.itemsByType.arme == undefined) data.itemsByType.arme = [];
for (const arme of data.itemsByType.arme) {
arme.data.niveau = 0; // Per default, TODO to be fixed
for (const melee of data.competenceByCategory.melee) {
if (melee.name == arme.data.competence)
arme.data.niveau = melee.data.niveau
}
for (const tir of data.competenceByCategory.tir) {
if (tir.name == arme.data.competence)
arme.data.niveau = tir.data.niveau
}
for (const lancer of data.competenceByCategory.lancer) {
if (lancer.name == arme.data.competence)
arme.data.niveau = lancer.data.niveau
}
const competences = sheetData.itemsByType.competence;
// toujours avoir une liste d'armes (pour mettre esquive et corps à corps)
sheetData.itemsByType.arme = sheetData.itemsByType.arme ?? [];
sheetData.competenceByCategory = Misc.classify(competences, comp => comp.data.categorie);
sheetData.calc = {
comptageArchetype: RdDItemCompetence.computeResumeArchetype(competences),
competenceXPTotal: RdDItemCompetence.computeTotalXP(competences),
caracTotal: RdDCarac.computeTotal(carac),
// Mise à jour de l'encombrement total et du prix de l'équipement
encTotal: await sheetData.actor.computeEncombrementTotalEtMalusArmure(),
prixTotalEquipement: await sheetData.actor.computePrixTotalEquipement(),
surprise: RdDBonus.find(sheetData.actor.getSurprise(false)).descr,
surEncombrementMessage: (sheetData.data.data.compteurs.surenc.value < 0) ? "Sur-Encombrement!" : "",
fatigue: {
malus: RdDUtility.calculMalusFatigue(sheetData.data.data.sante.fatigue.value, sheetData.data.data.sante.endurance.max),
html: "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(sheetData.data.data.sante.fatigue.value, sheetData.data.data.sante.endurance.max).html() + "</table>"
},
resumeBlessures: sheetData.actor.computeResumeBlessure(sheetData.data.data.blessures),
};
competences.forEach(it => it.visible = this.isCompetenceAffichable(it));
RdDItemCompetence.setLevelUp(competences);
RdDCarac.setLevelUp(carac);
sheetData.armes = sheetData.itemsByType.arme;
RdDItemArme.computeNiveauArmes(sheetData.armes, competences);
RdDItemArme.ajoutCorpsACorps(sheetData.armes, competences, carac);
sheetData.esquive = RdDItemCompetence.getEsquive(competences);
sheetData.armes = RdDCombatManager.finalizeArmeList(sheetData.armes, competences, carac);
sheetData.data.data.compteurs.chance.isChance = true;
RdDUtility.filterItemsPerTypeForSheet(sheetData);
sheetData.tmr = {
sortsReserve: sheetData.data.data.reve.reserve.list,
rencontres: sheetData.data.data.reve.rencontre.list,
caseSpeciales: sheetData.itemsByType.casetmr
}
// To avoid armour and so on...
data.data.combat = duplicate(RdDUtility.checkNull(data.itemsByType['arme']));
data.data.combat = RdDCombatManager.finalizeArmeList(data.data.combat, data.itemsByType.competence, data.data.carac);
RdDUtility.buildArbreDeConteneur(this, sheetData);
data.esquive = { name: "Esquive", niveau: data.competenceByCategory?.melee.find(it => it.name == 'Esquive')?.data.niveau ?? -6};
let corpsACorps = data.competenceByCategory?.melee.find(it => it.name == 'Corps à corps');
if (corpsACorps) {
let cc_init = RdDCombatManager.calculInitiative(corpsACorps.data.niveau, data.data.carac['melee'].value);
data.data.combat.push(RdDItemArme.mainsNues({ niveau: corpsACorps.data.niveau, initiative: cc_init }));
}
this.armesList = duplicate(data.data.combat);
caracList.isTaille = true; // To avoid button link;
let compteursList = data.data.data.compteurs
compteursList.chance.isChance = true;
data.data.data.blessures.resume = this.actor.computeResumeBlessure(data.data.data.blessures);
// Mise à jour de l'encombrement total et du prix de l'équipement
this.actor.computeEncombrementTotalEtMalusArmure();
this.actor.computePrixTotalEquipement();
// Common data
data.data.competenceByCategory = data.competenceByCategory;
data.data.encTotal = this.actor.encTotal;
data.data.prixTotalEquipement = this.actor.prixTotalEquipement;
data.data.surprise = RdDBonus.find(this.actor.getSurprise(false)).descr;
data.data.isGM = game.user.isGM;
data.ajustementsConditions = CONFIG.RDD.ajustementsConditions;
data.difficultesLibres = CONFIG.RDD.difficultesLibres;
// low is normal, this the base used to compute the grid.
data.data.fatigue = {
malus: RdDUtility.calculMalusFatigue(data.data.data.sante.fatigue.value, data.data.data.sante.endurance.max),
html: "<table class='table-fatigue'>" + RdDUtility.makeHTMLfatigueMatrix(data.data.data.sante.fatigue.value, data.data.data.sante.endurance.max).html() + "</table>"
sheetData.subacteurs = {
vehiculesList: sheetData.actor.buildVehiculesList(),
montures: sheetData.actor.buildMonturesList(),
suivants: sheetData.actor.buildSuivantsList()
}
RdDUtility.filterItemsPerTypeForSheet(data);
data.data.sortReserve = data.data.data.reve.reserve.list;
data.data.rencontres = duplicate(data.data.data.reve.rencontre.list);
data.data.caseSpeciales = data.itemsByType['casetmr'];
RdDUtility.buildArbreDeConteneur(this, data);
data.data.surEncombrementMessage = (data.data.data.compteurs.surenc.value < 0) ? "Sur-Encombrement!" : "";
data.data.vehiculesList = this.actor.buildVehiculesList();
data.data.monturesList = this.actor.buildMonturesList();
data.data.suivantsList = this.actor.buildSuivantsList();
return data;
// conserver la liste des armes
this.armesList = sheetData.armes;
return sheetData;
}
computeNiveauArme(armes, competences) {
for (const arme of armes) {
const compArme = competences.find(it => it.name == arme.data.competence);
arme.data.niveau = compArme?.data.niveau ?? -8;
}
}
isCompetenceAffichable(competence) {
return !this.options.showCompNiveauBase || !RdDItemCompetence.isNiveauBase(competence);
}
/* -------------------------------------------- */
async _onDrop(event) {
let toSuper = await RdDUtility.processItemDropEvent(this, event);
if ( toSuper) {
if (toSuper) {
super._onDrop(event);
}
}
@@ -215,12 +186,12 @@ export class RdDActorSheet extends ActorSheet {
html.find('.item-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
RdDUtility.confirmerSuppression(this, li);
});
});
html.find('.subacteur-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
RdDUtility.confirmerSuppressionSubacteur(this, li);
});
html.find('#encaisser-direct').click(ev => {
this.actor.encaisser();
});
@@ -337,12 +308,12 @@ export class RdDActorSheet extends ActorSheet {
html.find('.subacteur-label a').click((event) => {
const li = $(event.currentTarget).parents(".item");
let actorId = li.data('actor-id');
let actor = game.actors.get( actorId) ;
if ( actor ) {
let actor = game.actors.get(actorId);
if (actor) {
actor.sheet.render(true);
}
});
// Points de reve actuel
html.find('.ptreve-actuel a').click((event) => {
this.actor.rollCarac('reve-actuel');

View File

@@ -24,30 +24,26 @@ export class RdDActorVehiculeSheet extends ActorSheet {
});
}
/* -------------------------------------------- */
_checkNull(items) {
if (items && items.length) {
return items;
}
return [];
}
/* -------------------------------------------- */
getData() {
let data = super.getData();
let sheetData = super.getData();
sheetData.options = {
isGM: game.user.isGM
};
data.itemsByType = Misc.classify(data.items);
sheetData.itemsByType = Misc.classify(sheetData.items);
RdDUtility.filterItemsPerTypeForSheet(data);
RdDUtility.buildArbreDeConteneur(this, data);
RdDUtility.filterItemsPerTypeForSheet(sheetData);
RdDUtility.buildArbreDeConteneur(this, sheetData);
this.actor.computeEncombrementTotalEtMalusArmure();
data.data.isGM = game.user.isGM;
data.data.surEncombrementMessage = (this.encTotal > data.capacite_encombrement) ? "Sur-Encombrement!" : "";
sheetData.calc = {
surEncombrementMessage: (this.encTotal > sheetData.capacite_encombrement) ? "Sur-Encombrement!" : ""
}
console.log("DATA", data);
console.log("DATA", sheetData);
return data;
return sheetData;
}
/* -------------------------------------------- */

View File

@@ -328,7 +328,7 @@ export class RdDActor extends Actor {
);
if (index >=0 ) {
reserve.list.splice(index,1);
await this.update({ "data.reve.reserve": reserve });
await this.update({ "data.data.reve.reserve": reserve });
}
}
@@ -358,7 +358,7 @@ export class RdDActor extends Actor {
await this._recupererBlessures(message, "legere", blessures.legeres.liste.filter(b => b.active), []);
await this._recupererBlessures(message, "grave", blessures.graves.liste.filter(b => b.active), blessures.legeres.liste);
await this._recupererBlessures(message, "critique", blessures.critiques.liste.filter(b => b.active), blessures.graves.liste);
await this.update({ "data.blessures": blessures });
await this.update({ "data.data.blessures": blessures });
await this._recupererVie(message);
await this.jetDeMoral('neutre');
@@ -475,7 +475,7 @@ export class RdDActor extends Actor {
this._supprimerBlessure(blessure);
}
}
await this.update({ "data.blessures": blessures });
await this.update({ "data.data.blessures": blessures });
}
if (this.isPersonnage()) {
await this.setEthylisme(1);
@@ -486,7 +486,7 @@ export class RdDActor extends Actor {
if (this.data.data.sante.fatigue) {
let fatigue = duplicate(this.data.data.sante.fatigue)
fatigue.value = 0;
await this.update({ "data.sante.fatigue": fatigue });
await this.update({ "data.data.sante.fatigue": fatigue });
}
}
ChatMessage.create(message);
@@ -522,7 +522,7 @@ export class RdDActor extends Actor {
message.content += `Vous dégrisez un peu (${RdDUtility.getNomEthylisme(ethylisme.value)}). `;
}
}
await this.update({ "data.compteurs.ethylisme": ethylisme });
await this.update({ "data.data.compteurs.ethylisme": ethylisme });
}
/* -------------------------------------------- */
@@ -544,7 +544,7 @@ export class RdDActor extends Actor {
}
fatigue.value = Math.max(fatigueMin, this._calculRecuperationSegment(fatigue.value));
console.log("recupererFatigue", fatigue)
await this.update({ "data.sante.fatigue": fatigue });
await this.update({ "data.data.sante.fatigue": fatigue });
if (fatigue.value == 0) {
message.content += "Vous êtes complêtement reposé. ";
}
@@ -686,7 +686,7 @@ export class RdDActor extends Actor {
async sortMisEnReserve(rollData, sort) {
let reserve = duplicate(this.data.data.reve.reserve);
reserve.list.push({ coord: rollData.tmr.coord, sort: sort, draconic: duplicate(rollData.competence) });
await this.update({ "data.reve.reserve": reserve });
await this.update({ "data.data.reve.reserve": reserve });
this.currentTMR.updateTokens();
}
@@ -802,14 +802,14 @@ export class RdDActor extends Actor {
//console.log("Update", fieldName, fieldValue);
let compteurs = duplicate(this.data.data.compteurs);
compteurs[fieldName].value = fieldValue;
await this.update({ "data.compteurs": compteurs });
await this.update({ "data.data.compteurs": compteurs });
}
/* -------------------------------------------- */
async updateProtectionValue(fieldName, fieldValue) {
let attributs = duplicate(this.data.data.attributs);
attributs[fieldName].value = fieldValue;
await this.update({ "data.attributs": attributs });
await this.update({ "data.data.attributs": attributs });
}
/* -------------------------------------------- */
@@ -1018,8 +1018,9 @@ export class RdDActor extends Actor {
// Mise à jour éventuelle du malus armure
if (this.data.data.attributs && this.data.data.attributs.malusarmure && newMalusArmure != malusArmureData.value) {
malusArmureData.value = newMalusArmure;
await this.update({ "data.attributs.malusarmure": malusArmureData });
await this.update({ "data.data.attributs.malusarmure": malusArmureData });
}
return this.encTotal;
}
/* -------------------------------------------- */
@@ -1037,6 +1038,7 @@ export class RdDActor extends Actor {
}
// Mise à jour valeur totale de l'équipement
this.prixTotalEquipement = prixTotalEquipement;
return this.prixTotalEquipement;
}
/* -------------------------------------------- */
@@ -1104,7 +1106,7 @@ export class RdDActor extends Actor {
ret = "souffle";
}
await this.update({ "data.reve.refoulement": refoulement });
await this.update({ "data.data.reve.refoulement": refoulement });
return ret;
}
@@ -1129,7 +1131,7 @@ export class RdDActor extends Actor {
queue = await RdDRollTables.getOmbre();
let myReve = duplicate(this.data.data.reve.reve);
myReve.thanatosused = false;
await this.update({ "data.reve.reve": myReve } );
await this.update({ "data.data.reve.reve": myReve } );
}
else {
queue = await RdDRollTables.getQueue();
@@ -1181,7 +1183,7 @@ export class RdDActor extends Actor {
if (newTable.length != len) {
rencontres.list = newTable;
//console.log("Result: ", rencontres);
await this.update({ "data.reve.rencontre": rencontres });
await this.update({ "data.data.reve.rencontre": rencontres });
}
}
@@ -1197,7 +1199,7 @@ export class RdDActor extends Actor {
}
if (!already) {
rencontres.list.push(currentRencontre);
await this.update({ "data.reve.rencontre": rencontres });
await this.update({ "data.data.reve.rencontre": rencontres });
}
}
@@ -1209,19 +1211,19 @@ export class RdDActor extends Actor {
if ( i != rencontreKey)
newList.push( list[i]);
}
await this.update({ "data.reve.rencontre.list": newList });
await this.update({ "data.data.reve.rencontre.list": newList });
}
/* -------------------------------------------- */
async updateCoordTMR(coord) {
await this.update({ "data.reve.tmrpos.coord": coord });
await this.update({ "data.data.reve.tmrpos.coord": coord });
}
/* -------------------------------------------- */
async reveActuelIncDec(value) {
let reve = duplicate(this.data.data.reve.reve);
reve.value = Math.max(reve.value + value, 0);
await this.update({ "data.reve.reve": reve });
await this.update({ "data.data.reve.reve": reve });
}
/* -------------------------------------------- */
@@ -1235,16 +1237,16 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async setPointsDeSeuil(value) {
let seuil = duplicate(this.data.data.reve.seuil);
seuil.value = value;
await this.update({ "data.reve.seuil": seuil });
// let seuil = duplicate(this.data.data.reve.seuil);
// seuil.value = value;
await this.update({ "data.data.reve.seuil.value": value });
}
/* -------------------------------------------- */
async setPointsDeChance(value) {
let chance = duplicate(this.data.data.compteurs.chance);
chance.value = value;
await this.update({ "data.compteurs.chance": chance });
await this.update({ "data.data.compteurs.chance": chance });
}
/* -------------------------------------------- */
@@ -1285,7 +1287,7 @@ export class RdDActor extends Actor {
let sonneData = duplicate(this.data.data.sante.sonne);
sonneData.value = sonne;
sonneData.round = round;
await this.update({ "data.sante.sonne": sonneData });
await this.update({ "data.data.sante.sonne": sonneData });
}
/* -------------------------------------------- */
@@ -1307,7 +1309,7 @@ export class RdDActor extends Actor {
}
if (roll.total == 1) {
let xp = Misc.toInt(this.data.data.carac.constitution.xp) + 1;
this.update({ "data.carac.constitution.xp": xp }); // +1 XP !
this.update({ "data.data.carac.constitution.xp": xp }); // +1 XP !
ChatMessage.create( { content: `${this.name} a obenu 1 sur son Jet d'Endurance et a gagné 1 point d'Expérience en Constitution. Ce point d'XP a été ajouté automatiquement).`});
}
if (result.sonne) {
@@ -1340,7 +1342,7 @@ export class RdDActor extends Actor {
msgText += `et gagne 1 Point d'Experience en Constitution`;
let constit = duplicate(this.data.data.carac.constitution)
constit.xp += 1;
await this.update({ "data.carac.constitution": constit });
await this.update({ "data.data.carac.constitution": constit });
}
} else {
msgText += `${this.name} a échoué son Jet d'Endurance et devient Sonné`;
@@ -1424,7 +1426,7 @@ export class RdDActor extends Actor {
if (sante.fatigue && fatigue > 0) {
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this._computeFatigueMin());
}
await this.update({ "data.sante": sante });
await this.update({ "data.data.sante": sante });
if (this.isDead()) {
await this.addStatusEffectById('dead');
}
@@ -1537,7 +1539,7 @@ export class RdDActor extends Actor {
if (degre == 1) {
ethylisme.jet_moral = false;
}
await this.update({ "data.compteurs.ethylisme": ethylisme });
await this.update({ "data.data.compteurs.ethylisme": ethylisme });
}
/* -------------------------------------------- */
@@ -1649,7 +1651,7 @@ export class RdDActor extends Actor {
compteurs.experience.value += stressRollData.xp;
compteurs.dissolution.value = dissolution - perteDissolution;
compteurs.exaltation.value = 0;
await this.update({ "data.compteurs": compteurs });
await this.update({ "data.data.compteurs": compteurs });
}
/* -------------------------------------------- */
@@ -1969,7 +1971,7 @@ export class RdDActor extends Actor {
}
myReve.value = Math.max(myReve.value - rollData.depenseReve, 0);
await this.update({ "data.reve.reve": myReve });
await this.update({ "data.data.reve.reve": myReve });
if (closeTMR) {
this.currentTMR.close(); // Close TMR !
@@ -2311,7 +2313,7 @@ export class RdDActor extends Actor {
if (limit) {
chance.value = Math.min(chance.value, this.getChance())
}
await this.update({ "data.compteurs.chance": chance });
await this.update({ "data.data.compteurs.chance": chance });
}
/* -------------------------------------------- */
@@ -2320,7 +2322,7 @@ export class RdDActor extends Actor {
ChatMessage.create({ content: `<span class="rdd-roll-part">${this.name} a fait appel à la Destinée !</span>` });
let destinee = duplicate(this.data.data.compteurs.destinee);
destinee.value = destinee.value - 1;
await this.update({ "data.compteurs.destinee": destinee });
await this.update({ "data.data.compteurs.destinee": destinee });
onSuccess();
}
else {
@@ -2373,7 +2375,7 @@ export class RdDActor extends Actor {
let selectedCarac = RdDActor._findCaracByName(carac, caracName);
if (!selectedCarac.derivee) {
selectedCarac.xp = Misc.toInt(selectedCarac.xp) + xpCarac;
await this.update({ "data.carac": carac });
await this.update({ "data.data.carac": carac });
} else {
ChatMessage.create({
content: `Vous avez ${xpCarac} à répartir pour la caractéristique dérivée ${caracName}. Vous devez le faire manuellement.`,
@@ -2751,7 +2753,7 @@ export class RdDActor extends Actor {
}
encaissement.endurance = Math.max(encaissement.endurance, -endActuelle);
this.update({ "data.blessures": blessures });
this.update({ "data.data.blessures": blessures });
}
/* -------------------------------------------- */
@@ -2857,7 +2859,7 @@ export class RdDActor extends Actor {
return;
}
resonnance.actors.push(attaquant._id);
await this.update({ "data.sante.resonnance": resonnance });
await this.update({ "data.data.sante.resonnance": resonnance });
return;
}
/* -------------------------------------------- */
@@ -3151,7 +3153,7 @@ export class RdDActor extends Actor {
this.deleteStatusEffectById(statusEffect.id, options);
const effet = duplicate(statusEffect);
effet["flags.core.statusId"] = effet.id;
await this.createEmbeddedDocuments('ActiveEffect', effet, options);
await this.createEmbeddedDocuments('ActiveEffect', [effet], options);
this.applyActiveEffects();
}

View File

@@ -1,4 +1,5 @@
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
import { RdDCombatManager } from "./rdd-combat.js"
const nomCategorieParade = {
"sans-armes": "Sans arme / armes naturelles",
@@ -167,4 +168,24 @@ export class RdDItemArme extends Item {
}
return mainsNues
}
}
static ajoutCorpsACorps(armes, competences, carac) {
let corpsACorps = competences.find(it => it.name == 'Corps à corps');
if (corpsACorps) {
let cc_init = RdDCombatManager.calculInitiative(corpsACorps.data.niveau, carac['melee'].value);
armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.data.niveau, initiative: cc_init }));
}
}
static computeNiveauArmes(armes, competences) {
for (const arme of armes) {
arme.data.niveau = RdDItemArme.computeNiveauArme(arme, competences);
}
}
static computeNiveauArme(arme, competences) {
const compName = arme.data.competence;
const compArme = competences.find(it => it.name == compName);
return compArme?.data.niveau ?? -8;
}
}

View File

@@ -1,3 +1,4 @@
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"]];
@@ -55,33 +56,70 @@ export class RdDItemCompetence extends Item {
}
return false;
}
/* -------------------------------------------- */
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 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 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 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, Math.min(it.data.niveau, 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(item => item.name.toLowerCase() == name && (item.type == "competence" || item.type == "competencecreature"))
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 };
}
/* -------------------------------------------- */
@@ -96,14 +134,14 @@ export class RdDItemCompetence extends Item {
}
/* -------------------------------------------- */
static getDeltaXp(from, to) {
static computeDeltaXP(from, to) {
RdDItemCompetence._valideNiveau(from);
RdDItemCompetence._valideNiveau(to);
return competence_xp_cumul[to] - competence_xp_cumul[from];
}
/* -------------------------------------------- */
static _valideNiveau(niveau){
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)
}

View File

@@ -47,27 +47,27 @@ export class RdDItemSheet extends ItemSheet {
/* -------------------------------------------- */
async getData() {
let data = super.getData();
let sheetData = super.getData();
data.categorieCompetences = RdDUtility.getCategorieCompetences();
if ( data.item.type == 'tache' || data.item.type == 'livre' || data.item.type == 'meditation' || data.item.type == 'oeuvre') {
data.caracList = duplicate(game.system.model.Actor.personnage.carac);
data.competences = await RdDUtility.loadCompendiumNames( 'foundryvtt-reve-de-dragon.competences' );
sheetData.categorieCompetences = RdDUtility.getCategorieCompetences();
if ( sheetData.item.type == 'tache' || sheetData.item.type == 'livre' || sheetData.item.type == 'meditation' || sheetData.item.type == 'oeuvre') {
sheetData.caracList = duplicate(game.system.model.Actor.personnage.carac);
sheetData.competences = await RdDUtility.loadCompendiumNames( 'foundryvtt-reve-de-dragon.competences' );
}
if (data.item.type == 'arme') {
data.competences = await RdDUtility.loadCompendium( 'foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it));
if (sheetData.item.type == 'arme') {
sheetData.competences = await RdDUtility.loadCompendium( 'foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it));
}
if ( data.item.type == 'recettealchimique' ) {
RdDAlchimie.processManipulation(data.item, this.actor && this.actor.id );
if ( sheetData.item.type == 'recettealchimique' ) {
RdDAlchimie.processManipulation(sheetData.item, this.actor && this.actor.id );
}
if ( this.actor ) {
data.isOwned = true;
data.actorId = this.actor.id;
sheetData.isOwned = true;
sheetData.actorId = this.actor.id;
}
data.bonusCaseList = RdDItemSort.getBonusCaseList(data, true);
data.isGM = game.user.isGM; // Pour verrouiller certaines éditions
sheetData.bonusCaseList = RdDItemSort.getBonusCaseList(sheetData, true);
sheetData.isGM = game.user.isGM; // Pour verrouiller certaines éditions
return data;
return sheetData;
}
/* -------------------------------------------- */
@@ -112,7 +112,7 @@ export class RdDItemSheet extends ItemSheet {
async _onClickSelectCategorie(event) {
event.preventDefault();
let level = RdDUtility.getLevelCategory(event.currentTarget.value);
let level = RdDUtility.getCategorieNiveauBase(event.currentTarget.value);
this.object.data.data.base = level;
$("#base").val( level );
}

View File

@@ -1,4 +1,5 @@
import { Grammar } from "./grammar.js";
import { RdDUtility } from "./rdd-utility.js";
export class RdDCarac {
@@ -20,6 +21,21 @@ export class RdDCarac {
RdDCarac.isChance(selectedCarac) ||
(RdDCarac.isReve(selectedCarac) && !competence);
}
static computeTotal(carac, beaute=undefined) {
const total = Object.values(carac).filter(c => !c.derivee)
.map(it => parseInt(it.value))
.reduce((a, b) => a + b, 0);
const beauteSuperieur10 = Math.max((beaute ?? 10) - 10, 0);
return total + beauteSuperieur10;
}
static setLevelUp(carac) {
Object.values(carac).forEach(it => {
it.xpNext = RdDUtility.getCaracNextXp(it.value);
it.isLevelUp = (it.xp >= it.xpNext);
});
}
/**
* Lappel à la chance nest possible que pour recommencer les jets dactions physiques :

View File

@@ -257,7 +257,7 @@ export class RdDCommands {
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)}`);
RdDCommands._chatAnswer(msg, `Coût pour passer une compétence de ${from} à ${to}: ${RdDItemCompetence.computeDeltaXP(from, to)}`);
}
else {
return false;

View File

@@ -12,14 +12,14 @@ import { Grammar } from "./grammar.js";
/* -------------------------------------------- */
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" }
"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" }
}
/* -------------------------------------------- */
@@ -267,10 +267,7 @@ export class RdDUtility {
/* -------------------------------------------- */
static checkNull(items) {
if (items && items.length) {
return items;
}
return [];
return items ?? [];
}
/* -------------------------------------------- */
@@ -296,32 +293,39 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static filterItemsPerTypeForSheet(data) {
data.data.materiel = this.checkNull(data.itemsByType['objet']);
data.data.conteneurs = this.checkNull(data.itemsByType['conteneur']);
data.data.armes = this.checkNull(data.itemsByType['arme']);
data.data.armures = this.checkNull(data.itemsByType['armure']);
data.data.livres = this.checkNull(data.itemsByType['livre']);
data.data.potions = this.checkNull(data.itemsByType['potion']);
data.data.ingredients = this.checkNull(data.itemsByType['ingredient']);
data.data.munitions = this.checkNull(data.itemsByType['munition']);
data.data.herbes = this.checkNull(data.itemsByType['herbe']);
data.data.sorts = this.checkNull(data.itemsByType['sort']);
data.data.queues = this.checkNull(data.itemsByType['queue']);
data.data.souffles = this.checkNull(data.itemsByType['souffle']);
data.data.ombres = this.checkNull(data.itemsByType['ombre']);
data.data.tetes = this.checkNull(data.itemsByType['tete']);
data.data.taches = this.checkNull(data.itemsByType['tache']);
data.data.monnaie = this.checkNull(data.itemsByType['monnaie']);
data.data.meditations = this.checkNull(data.itemsByType['meditation']);
data.data.chants = this.checkNull(data.itemsByType['chant']);
data.data.danses = this.checkNull(data.itemsByType['danse']);
data.data.musiques = this.checkNull(data.itemsByType['musique']);
data.data.oeuvres = this.checkNull(data.itemsByType['oeuvre']);
data.data.jeux = this.checkNull(data.itemsByType['jeu']);
data.data.recettescuisine = this.checkNull(data.itemsByType['recettecuisine']);
data.data.recettesAlchimiques = this.checkNull(data.itemsByType['recettealchimique']);
data.data.objets = data.data.conteneurs.concat(data.data.materiel).concat(data.data.armes).concat(data.data.armures).concat(data.data.munitions).concat(data.data.livres).concat(data.data.potions).concat(data.data.herbes).concat(data.data.ingredients);
static filterItemsPerTypeForSheet(sheetData) {
sheetData.data.materiel = this.checkNull(sheetData.itemsByType['objet']);
sheetData.data.conteneurs = this.checkNull(sheetData.itemsByType['conteneur']);
sheetData.data.armes = this.checkNull(sheetData.itemsByType['arme']);
sheetData.data.armures = this.checkNull(sheetData.itemsByType['armure']);
sheetData.data.livres = this.checkNull(sheetData.itemsByType['livre']);
sheetData.data.potions = this.checkNull(sheetData.itemsByType['potion']);
sheetData.data.ingredients = this.checkNull(sheetData.itemsByType['ingredient']);
sheetData.data.munitions = this.checkNull(sheetData.itemsByType['munition']);
sheetData.data.herbes = this.checkNull(sheetData.itemsByType['herbe']);
sheetData.data.sorts = this.checkNull(sheetData.itemsByType['sort']);
sheetData.data.queues = this.checkNull(sheetData.itemsByType['queue']);
sheetData.data.souffles = this.checkNull(sheetData.itemsByType['souffle']);
sheetData.data.ombres = this.checkNull(sheetData.itemsByType['ombre']);
sheetData.data.tetes = this.checkNull(sheetData.itemsByType['tete']);
sheetData.data.taches = this.checkNull(sheetData.itemsByType['tache']);
sheetData.data.monnaie = this.checkNull(sheetData.itemsByType['monnaie']);
sheetData.data.meditations = this.checkNull(sheetData.itemsByType['meditation']);
sheetData.data.chants = this.checkNull(sheetData.itemsByType['chant']);
sheetData.data.danses = this.checkNull(sheetData.itemsByType['danse']);
sheetData.data.musiques = this.checkNull(sheetData.itemsByType['musique']);
sheetData.data.oeuvres = this.checkNull(sheetData.itemsByType['oeuvre']);
sheetData.data.jeux = this.checkNull(sheetData.itemsByType['jeu']);
sheetData.data.recettescuisine = this.checkNull(sheetData.itemsByType['recettecuisine']);
sheetData.data.recettesAlchimiques = this.checkNull(sheetData.itemsByType['recettealchimique']);
sheetData.data.objets = sheetData.data.conteneurs.concat(sheetData.data.materiel)
.concat(sheetData.data.armes)
.concat(sheetData.data.armures)
.concat(sheetData.data.munitions)
.concat(sheetData.data.livres)
.concat(sheetData.data.potions)
.concat(sheetData.data.herbes)
.concat(sheetData.data.ingredients);
}
/* -------------------------------------------- */
@@ -352,16 +356,16 @@ export class RdDUtility {
}
/* -------------------------------------------- */
static buildArbreDeConteneur(actorSheet, data) {
static buildArbreDeConteneur(actorSheet, sheetData) {
actorSheet.objetVersConteneur = {}; // Table de hash locale pour recupération rapide du conteneur parent (si existant)
// Attribution des objets aux conteneurs
for (let conteneur of data.data.conteneurs) {
for (let conteneur of sheetData.data.conteneurs) {
conteneur.subItems = [];
if (!conteneur.data.encTotal) conteneur.data.encTotal = 0;
//conteneur.data.encTotal = ; Deja calculé
if (conteneur.data.contenu) {
for (let id of conteneur.data.contenu) {
let objet = data.data.objets.find(objet => (id == objet._id));
let objet = sheetData.data.objets.find(objet => (id == objet._id));
if (objet) {
if (!objet.data.encombrement) objet.data.encombrement = 0; // Auto-fix
objet.estContenu = true; // Permet de filtrer ce qifui est porté dans le template
@@ -373,8 +377,8 @@ export class RdDUtility {
}
}
// Construit la liste des conteneurs de niveau 1 (c'est à dire non contenu eux-même dans un conteneur)
let newConteneurs = data.data.conteneurs.filter(function (conteneur, index, arr) { return !conteneur.estContenu });
data.data.conteneurs = newConteneurs;
let newConteneurs = sheetData.data.conteneurs.filter(function (conteneur, index, arr) { return !conteneur.estContenu });
sheetData.data.conteneurs = newConteneurs;
//console.log(newConteneurs);
}
@@ -406,10 +410,10 @@ export class RdDUtility {
static getCategorieCompetences() {
return categorieCompetences;
}
static getLevelCategory(category) {
static getCategorieNiveauBase(category) {
return categorieCompetences[category].level;
}
static getLabelCategory(category) {
static getCategorieLabel(category) {
return categorieCompetences[category].label;
}
static getCaracArray() {
@@ -609,7 +613,7 @@ export class RdDUtility {
let compendiumItems = await RdDUtility.loadCompendiumNames(compendium);
const pack = game.packs.get(compendium);
let list = [];
for (let compendiumItem of compendiumItems) {
for (let compendiumItem of compendiumItems) {
await pack.getDocument(compendiumItem._id).then(it => {
const item = it.data;
if (filter(item)) {