diff --git a/dev-notes.md b/dev-notes.md
new file mode 100644
index 00000000..6dd99c00
--- /dev/null
+++ b/dev-notes.md
@@ -0,0 +1,48 @@
+# Actor notes
+
+> The Actor#getData default implementation gives you the following for use in sheet rendering:
+
+```
+ actor -> the Actor instance
+ data -> a cloned copy of Actor#data
+ items -> a cloned copy of Actor#data#items
+ effects -> a cloned copy of Actor#data#effects
+```
+
+> if all you need is a safe copy of `Actor#data`, you'll be much better off by simply defining your own function and avoiding all the wasted work that the parent class does which will slow down your sheet
+```js
+getData(options) {
+ return {
+ data: foundry.utils.deepClone(this.object.data)
+ }
+}
+```
+
+who knows, maybe you don't even need to copy your actor data, skip the copy and it's even faster:
+```js
+getData(options) {
+ return {
+ data: this.object.data
+ }
+}
+```
+
+
+Atropos19/02/2021
+There are two recommended ways to create owned items in 0.8.0:
+```js
+await Item.create(itemData, {parent: actor});
+await actor.createEmbeddedDocuments("Item", itemDataArray);
+```
+
+
+You can update an embedded item in one of two ways:
+```js
+//Method 1:
+
+const item = actor.items.get(itemId);
+item.update(data);
+
+//Method 2:
+actor.updateEmbeddedDocuments("Item", [{_id: itemId, ...}]);
+```
\ No newline at end of file
diff --git a/module/actor-creature-sheet.js b/module/actor-creature-sheet.js
index b9a820d7..3b164097 100644
--- a/module/actor-creature-sheet.js
+++ b/module/actor-creature-sheet.js
@@ -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;
}
/* -------------------------------------------- */
@@ -100,7 +91,7 @@ export class RdDActorCreatureSheet extends RdDActorSheet {
/* -------------------------------------------- */
/** @override */
- _updateObject(event, formData) {
+ async _updateObject(event, formData) {
// Update the Actor
return this.object.update(formData);
}
diff --git a/module/actor-entite-sheet.js b/module/actor-entite-sheet.js
index 8e9f3c93..7f909e5a 100644
--- a/module/actor-entite-sheet.js
+++ b/module/actor-entite-sheet.js
@@ -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;
}
/* -------------------------------------------- */
@@ -135,7 +119,7 @@ export class RdDActorEntiteSheet extends ActorSheet {
/* -------------------------------------------- */
/** @override */
- _updateObject(event, formData) {
+ async _updateObject(event, formData) {
// Update the Actor
return this.object.update(formData);
}
diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index 15b7f27c..a1963dd7 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -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: "
" + RdDUtility.makeHTMLfatigueMatrix(sheetData.data.data.sante.fatigue.value, sheetData.data.data.sante.endurance.max).html() + "
"
+ },
+ 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: "" + RdDUtility.makeHTMLfatigueMatrix(data.data.data.sante.fatigue.value, data.data.data.sante.endurance.max).html() + "
"
+ 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');
@@ -580,7 +551,7 @@ export class RdDActorSheet extends ActorSheet {
/* -------------------------------------------- */
/** @override */
- _updateObject(event, formData) {
+ async _updateObject(event, formData) {
// Update the Actor
return this.object.update(formData);
}
diff --git a/module/actor-vehicule-sheet.js b/module/actor-vehicule-sheet.js
index a2dd0cb3..0e6a366a 100644
--- a/module/actor-vehicule-sheet.js
+++ b/module/actor-vehicule-sheet.js
@@ -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;
}
/* -------------------------------------------- */
@@ -102,7 +98,7 @@ export class RdDActorVehiculeSheet extends ActorSheet {
/* -------------------------------------------- */
/** @override */
- _updateObject(event, formData) {
+ async _updateObject(event, formData) {
// Update the Actor
return this.object.update(formData);
}
diff --git a/module/actor.js b/module/actor.js
index b6c9ed62..68e8db57 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -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: `${this.name} a fait appel à la Destinée !` });
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();
}
diff --git a/module/item-arme.js b/module/item-arme.js
index 68e3cafb..00e6fe8b 100644
--- a/module/item-arme.js
+++ b/module/item-arme.js
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/module/item-competence.js b/module/item-competence.js
index deca47f1..40d32513 100644
--- a/module/item-competence.js
+++ b/module/item-competence.js
@@ -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)
}
diff --git a/module/item-sheet.js b/module/item-sheet.js
index 093ce575..a5275f94 100644
--- a/module/item-sheet.js
+++ b/module/item-sheet.js
@@ -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 );
}
@@ -127,7 +127,7 @@ export class RdDItemSheet extends ItemSheet {
/* -------------------------------------------- */
/** @override */
- _updateObject(event, formData) {
+ async _updateObject(event, formData) {
// Données de bonus de cases ?
formData = RdDItemSort.buildBonusCaseStringFromFormData( formData );
//console.log("HERE", this, formData, this.object.data );
diff --git a/module/rdd-carac.js b/module/rdd-carac.js
index 337212b2..c8472f46 100644
--- a/module/rdd-carac.js
+++ b/module/rdd-carac.js
@@ -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);
+ });
+ }
/**
* L’appel à la chance n’est possible que pour recommencer les jets d’actions physiques :
diff --git a/module/rdd-commands.js b/module/rdd-commands.js
index a10392ff..8a091058 100644
--- a/module/rdd-commands.js
+++ b/module/rdd-commands.js
@@ -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;
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index 1cf0e2c9..fcce0eac 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -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)) {
diff --git a/packs/rappel-des-regles.db b/packs/rappel-des-regles.db
index 65ea77b0..5ca0c0b9 100644
--- a/packs/rappel-des-regles.db
+++ b/packs/rappel-des-regles.db
@@ -5,3 +5,4 @@
{"_id":"K42KNuBHizMppV5F","name":"Tourbillon rouge","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{},"content":"Le Tourbillon rouge est un tourbillon vampire. Il fonctionne comme les Tourbillons blancs et noirs, sauf que chaque round tant qu’il n’est pas maîtrisé fait dériver le demi-rêve de 4 cases, draine 2 points de rêve et 1 point de vie.
\nOn peut se dérober normalement devant ces rencontres ou les refouler. Toutefois, leur refoulement coûte 2 points au lieu d’un, sauf le Tourbillon rouge qui en coûte 3.
"}
{"_id":"ZmMoOtUdgjMd4cNs","name":"Conflit de sens","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{},"content":"Chaque fois que le spectateur d’une illusion visuelle est en proie à un conflit de sens, c’est-à-dire quand il y a contradiction ou impossibilité entre ce que lui indiquent ses autres sens et sa vue, l’illusion suscite une brume limbaire. C’est une sorte de flou ectoplasmique de couleur gris vert (comme les Limbes) qui restitue la logique à défaut de restituer la réalité. La brume limbaire a la taille et la forme approximative de la chose réelle.
\nSoit par exemple une porte rendue invisible. Puisqu’elle \"n’existe pas\", on devrait voir soit la continuation du mur, soit ce qu’il y a de l’autre côté. Or ni l’un ni l’autre ne sont du ressort de l’illusion qui, au pied de la lettre, n’est que porte invisible, et non pas invention d’autre chose. Si un spectateur prend conscience de cette anomalie, il voit un rectangle de flou gris-vert se dessiner à la place de la porte, c’est-à-dire ni le mur, ni ce qu’il y a de l’autre côté, ni non plus la porte elle-même. La porte reste donc bien invisible, puisqu’on ne la voit pas, mais pas sa présence. De la même façon, un humanoïde invisible le reste totalement tant qu’il ne commet aucune action ayant pour conséquence un conflit d’interprétation chez un spectateur, auquel cas ce dernier voit apparaître un \"fantôme\" gris-vert justifiant l’action qui vient de se produire. Noter ici aussi que si la présence de l’humanoïde cesse d’être \"invisible\", ce dernier le demeure au sens où son fantôme n’est qu’une silhouette totalement anonyme.
\nLa brume limbaire n’apparaît que pour le spectateur ayant un conflit de sens. Ceux qui ne sont pas victimes d’un tel conflit continuent à voir l’illusion telle qu’elle est. En combat, un attaquant invisible ne suscite une brume limbaire que pour la créature qu’il vient d’attaquer ainsi que pour un témoin ponctuel de l’attaque.
\nCe sont les invisibilités qui sont à même de susciter le plus de conflits de sens, mais c’est également possible pour les deux autres illusions visuelles.
\nDès que les sens cessent d’être en conflit, la brume limbaire s’estompe et l’on retourne à une illusion réelle et totale, invisibilité ou autre.
\nLa brume limbaire n’est suscitée qu’en cas de conflit de sens, pas d’intellect. Un raisonnement ne peut susciter une brume limbaire, uniquement un conflit avec l’un ou l’autre des quatre autres sens, ouïe, toucher, odorat, goût.
\nMoins une illusion sollicite de sens, moins elle a de chances de créer un conflit, et plus elle est donc fiable, voire indétectable. Une illusion qui ne s’adresse qu’à la vue (changement de couleur, changement des lettres d’un texte) marche toujours à 100 %.
\nLes autres illusions, auditives, gustatives et olfactives, ne génèrent jamais de brume limbaire quand bien même elles sont inexplicables.
\nUne cible donnée ne peut recevoir à la fois qu’une seule illusion visuelle, une seule illusion auditive, une seule illusion olfactive et une seule illusion gustative, soit un maximum de quatre illusions sensorielles différentes.
"}
{"_id":"erO7AICiN1LtRyFg","name":"Magie impossible","permission":{"default":0,"jOzRscDxoXZWpGS6":3},"flags":{},"content":"Tout cas de magie impossible résulte immédiatement en une déchirure du rêve ayant le haut-rêvant pour centre.
\nElle peut être violette (déchirure de départ) ou jaune (déchirure d’arrivée). C’est au gardien des rêves de le décider ou de le tirer au sort.
\nSes dimensions peuvent faire jusqu’à 100 m de diamètre, à décider ou tirer par le gardien des rêves.
\nElle peut ne durer que quelques instants avant de se dissoudre, ou durer indéfiniment, toujours à la décision du gardien des rêves.
\nDe même, c’est à lui de décider du rêve d’arrivée si c’est une déchirure de départ, ou des créatures qui peuvent en surgir si c’est une déchirure d’arrivée. En cas de déchirure de départ (violette), elle emporte immédiatement tout ce qui ne fait pas partie du paysage : objets et créatures.
\nSeules les constituantes du paysage, végétation, rochers, constructions, demeurent. Noter que si une construction demeure, tous les objets qu’elle contient, meubles et autres, disparaissent.
"}
+{"_id":"7uGrUHGdPu0EmIu2","name":"Documentation MJ/Joueurs","content":"Préambule
\nCe système pour Foundry est une implémentation de Rêve de Dragon, un jeu de Denis Gerfaud, publié dans sa troisième édition par \"Le Scriptarium\". Rêve de Dragon est une marque déposée par \"Scriptarium\". Tous les droits leur en reviennent naturellement.
\nMerci à Scriptarium (Jidus et Roland Barthelémy) pour l'autorisation d'utilisation des silhouettes de créatures et les Terres Médianes du Rêve.
\nCrédits :
\n\n- Développement : LeRatierBretonnien & VincentVk
\n- Compendiums, tests et relectures : Grendel, VincentVk, Fred, Mickael Nome et Fab
\n- Icones/tokens : Grendel, VincentVk
\n- Graphisme et styles : Mandar, VincentVk
\n
\nPour nous contacter : https://discord.gg/pPSDNJk , channel #reve-de-dragon
\nCréer un Personnage
\nTout se fait manuellement à l'heure actuelle, il convient donc procéder comme suit :
\n\n
débloquer: pour permettre la saisie rapide des caractéristiques et compétences \n- Renseignez les caractéristiques dans l'onglet concerné.
\n- Renseignez les niveaux de compétences nécessaires
\n- Ouvrez le compendium de l'équipement et faites glisser/déplacer sur l'équipement que vous souhaitez
\n- Si votre personnage est haut-rêvant, ouvrez le compendium des sorts et faites glisser/déplacer pour attribuer les sorts.
\n- Si votre personnage a des têtes, queues, souffles de dragons, ouvrez le compendium correspondant et faites glisser/déplacer.
\n- se familiariser avec les différents compteurs, modifier le seuil de rêve (onglet Haut Rêve)
\n
\nChaque élément apparaît dans son onglet propre.
\nPour réaliser un jet, il suffit de cliquer sur le nom d'une caractéristique, sur une compétence ou sur un objet. Ce clic ouvre la boite de dialogue des jets, qui permet de paramétrer les différentes options (difficulté, compétence/carac, etc). Le lancer affiche les résultats dans le tchat, avec le résultat, la qualité de la réussite, les points d'expérience éventuels et les points de taches.
\nL'état général du personnage est automatiquement pris en compte.
\nPartie haute
\nLes principaux compteurs (vie, endurance, fatigue et rêve, sonné) sont visibles dans la partie haute. Un clic sur le rêve à cet endroit permet de faire un jet de points actuels de rêve (par exemple, un jet de résistance).
\nPlusieurs boutons sont disponibles:
\n\n
Encaisser des dommages \n
Remise à neuf (Uniquement pour le MJ) pour enlever toutes les blessures/états du personnage. \n
Dormir une heure (récupération de rêve, fatigue, endurance) \n
Chateau Dormant pour la dernière heure de la nuit (récupération des blessures, stress, ...) \n
Montée dans les Terres Médianes \n
Montée rapide \n
Regarder ses terres médianes (sans monter) \n
\nCombat
\nPour l'initiative et les attaques, des options sont disponibles sur le token (menu contextuel).
\nUne fois l'initiative réglée, l'attaquant sélectionne sa cible, puis utilise l'option d'attaque avec cette arme souhaitée (il peut aussi utiliser l'arme dans la feuille de persionnage). La fenêtre de jet de résolution est alors ouverte pour choisir sa difficulté libre, et différents ajustements liés aux conditions et tactiques.
\nSi l'attaque réussit, le défenseur recevra un message dans le tchat avec ses actions de défense -ou d'encaissement- disponibles, selon ses compétences : Encaisser, Esquiver, Parer, ...
\nUn click sur ces actions génère le jet de riposte et produit les résultats. En cas d'échec, le défenseur aura de nouveau un message lui demandant d'encaisser, pour lui donner l'opportunité de faire appel à la chance ou à la destinée.
\nSi décidément ce nb'est pas son jour, il peut cliquer sur le lien pour encaisser, les blessures et l'état général sont automatiquement mis à jour.
\nHaut Rêve
\nLes sorts peuvent être ajoutés depuis le compendium correspondant (par voie de Draconic). La description des sorts est disponible en cliquant sur le sort.
\nPour monter dans les Terres Médianes, il suffit de cliquer sur l'un des boutons \"Monter dans les Terres Médianes!\" sur la feuille de personnage.
\nLa fiche des TMR apparait alors, vous permettant de vous déplacer. Le point de rêve de montée, la fatigue, les rencontres, les cases humides sont automatiquement gérés. Lorsque vous êtes sur la bonne case, il vous suffit de cliquer sur 'Lancer le sort', qui ouvre la boite de dialogue du lancement.
\nDivers
\nCertains raccourcis de commandes sont disponibles directement dans le tchat:
\n\n/table [table]
: effectue un tirage sur la table correspondante (queues, ombres, tete, tetehr, souffle, tarot) \n/table rdd
: ouvre la table de résolution \n/tmra
: Tire une case aléatoire des TMR \n/tmrr [type de case] [1-100]
: détermine la rencontre correspondant au jet de dés pour le type de case \n
\nCe qui n'est pas implémenté/en cours
\n\n- Rendre plus jolie les feuilles de perso
\n- Rendre plus jolis les messages du système de jeu
\n- Les combats d'empoignade (et certaines spécificités du pugilat)
\n- Des messages pour le MJ sur certaines actions des joueurs, pour le prévenir (TMR notamment)
\n- Les retours que vous nous ferez ;-)
\n
\n![\"\"](\"systems/foundryvtt-reve-de-dragon/icons/humanoides/nitouche.svg\")
","img":null,"folder":"","sort":0,"permission":{"default":0,"Q4cUvqxCxMoTJXDL":3},"flags":{}}
diff --git a/templates/actor-creature-sheet.html b/templates/actor-creature-sheet.html
index 1901d9eb..ebd54730 100644
--- a/templates/actor-creature-sheet.html
+++ b/templates/actor-creature-sheet.html
@@ -1,3 +1,4 @@
+{{log "handlebar" this}}