diff --git a/module/actor.js b/module/actor.js
index ee1e39af..68bf750e 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -26,6 +26,7 @@ import { Poetique } from "./poetique.js";
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
import { Draconique } from "./tmr/draconique.js";
import { RdDCarac } from "./rdd-carac.js";
+import { Monnaie } from "./item-monnaie.js";
/* -------------------------------------------- */
@@ -56,36 +57,25 @@ export class RdDActor extends Actor {
*/
static async create(data, options) {
-
// Case of compendium global import
if (data instanceof Array) {
return super.create(data, options);
}
+
+ const isPersonnage = data.type == "personnage";
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
if (data.items) {
let actor = super.create(data, options);
- if (data.type == "personnage") {
+ if (isPersonnage) {
await actor.checkMonnaiePresence(data.items);
}
return actor;
}
- let compendiumName;
- if (data.type == "personnage") {
- compendiumName = "foundryvtt-reve-de-dragon.competences";
- } else if (data.type == "creature") {
- compendiumName = "foundryvtt-reve-de-dragon.competences-creatures";
- } else if (data.type == "entite") {
- compendiumName = "foundryvtt-reve-de-dragon.competences-entites";
+ data.items = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(data.type));
+ if (isPersonnage) {
+ data.items = data.items.concat(Monnaie.monnaiesData());
}
- if (compendiumName) {
- data.items = await RdDUtility.loadCompendium(compendiumName);
- }
- // Ajout monnaie
- if (data.type == "personnage" && data.items) {
- await RdDActor.ajouterMonnaie(data.items);
- }
-
return super.create(data, options);
}
@@ -151,41 +141,10 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async checkMonnaiePresence(items) { // Ajout opportuniste si les pièces n'existent pas.
if (!items) return; // Sanity check during import
- let piece = items.find(item => item.type == 'monnaie' && Number(item.data.valeur_deniers) == 1);
- let newMonnaie = [];
- if (!piece) {
- newMonnaie.push(RdDUtility.createMonnaie("Etain (1 denier)", 1, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp"));
+ let manquantes = Monnaie.monnaiesManquantes(items);
+ if (manquantes.length > 0) {
+ await this.createOwnedItem(manquantes);
}
- piece = items.find(item => item.type == 'monnaie' && Number(item.data.valeur_deniers) == 10);
- if (!piece) {
- newMonnaie.push(RdDUtility.createMonnaie("Bronze (10 deniers)", 10, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp"));
- }
- piece = items.find(item => item.type == 'monnaie' && Number(item.data.valeur_deniers) == 100);
- if (!piece) {
- newMonnaie.push(RdDUtility.createMonnaie("Argent (1 sol)", 100, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp"));
- }
- piece = items.find(item => item.type == 'monnaie' && Number(item.data.valeur_deniers) == 1000);
- if (!piece) {
- newMonnaie.push(RdDUtility.createMonnaie("Or (10 sols)", 1000, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp"));
- }
- if (newMonnaie.length > 0) {
- await this.createOwnedItem(newMonnaie);
- }
- }
-
- /* -------------------------------------------- */
- static async ajouterMonnaie(items) { // Creation auto à la création du personnage
- let etain = RdDUtility.createMonnaie("Etain (1 denier)", 1, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp");
- items.push(etain);
-
- let bronze = RdDUtility.createMonnaie("Bronze (10 deniers)", 10, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp");
- items.push(bronze);
-
- let argent = RdDUtility.createMonnaie("Argent (1 sol)", 100, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp");
- items.push(argent);
-
- let or = RdDUtility.createMonnaie("Or (10 sols)", 1000, "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp");
- items.push(or);
}
/* -------------------------------------------- */
@@ -307,7 +266,7 @@ export class RdDActor extends Actor {
getBestDraconic() {
const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau);
if (list.length == 0) {
- return { name: "none", data: { niveau: -11 } };
+ return { name: "Aucun", data: { niveau: -11 } };
}
return duplicate(list[0]);
}
@@ -350,27 +309,30 @@ export class RdDActor extends Actor {
};
const blessures = duplicate(this.data.data.blessures);
- console.log("dormirChateauDormant", blessures)
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._recupererVie(message);
await this.jetDeMoral('neutre');
-
- // On ne récupère un point de chance que si aucun appel à la chance dans la journée
- let utilisationChance = duplicate(this.getFlag('foundryvtt-reve-de-dragon', 'utilisationChance') ?? false);
- if (!utilisationChance) {
- await this.chanceActuelleIncDec(1);
- }
- await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance'); // Nouveau jour, suppression du flag
-
- this.transformerStress();
+ await this._recupereChance();
+ await this.transformerStress();
await this.retourSeuilDeReve(message);
message.content = `A la fin Chateau Dormant, ${message.content}
Un nouveau jour se lève`;
ChatMessage.create(message);
}
+ async _recupereChance() {
+ // On ne récupère un point de chance que si aucun appel à la chance dans la journée
+ if (this.getFlag('foundryvtt-reve-de-dragon', 'utilisationChance')) {
+ // Nouveau jour, suppression du flag
+ await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance');
+ }
+ else {
+ await this.chanceActuelleIncDec(1);
+ }
+ }
+
/* -------------------------------------------- */
async _recupererBlessures(message, type, liste, moindres) {
let count = 0;
@@ -480,9 +442,7 @@ export class RdDActor extends Actor {
await this.santeIncDec("vie", this.data.data.sante.vie.max - this.data.data.sante.vie.value);
await this.santeIncDec("endurance", this.data.data.sante.endurance.max - this.data.data.sante.endurance.value);
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.sante.fatigue.value": 0 });
}
}
ChatMessage.create(message);
@@ -532,16 +492,16 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async recupererFatigue(message) {
- let fatigue = duplicate(this.data.data.sante.fatigue)
+ let fatigue = this.data.data.sante.fatigue.value;
const fatigueMin = this._computeFatigueMin();
- if (fatigue.value <= fatigueMin) {
+ if (fatigue <= fatigueMin) {
message.content += "Vous êtes déjà reposé. ";
return;
}
- fatigue.value = Math.max(fatigueMin, this._calculRecuperationSegment(fatigue.value));
+ fatigue = Math.max(fatigueMin, this._calculRecuperationSegment(fatigue));
console.log("recupererFatigue", fatigue)
- await this.update({ "data.sante.fatigue": fatigue });
- if (fatigue.value == 0) {
+ await this.update({ "data.sante.fatigue.value": fatigue });
+ if (fatigue == 0) {
message.content += "Vous êtes complêtement reposé. ";
}
}
@@ -680,9 +640,9 @@ 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 });
+ let reserve = duplicate(this.data.data.reve.reserve.list);
+ reserve.push({ coord: rollData.tmr.coord, sort: sort, draconic: duplicate(rollData.competence) });
+ await this.update({ "data.reve.reserve.list": reserve });
this.currentTMR.updateTokens();
}
@@ -752,7 +712,7 @@ export class RdDActor extends Actor {
});
}
const update = { _id: comp._id, 'data.niveau': nouveauNiveau };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
+ await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
} else {
console.log("Competence not found", compName);
}
@@ -765,7 +725,7 @@ export class RdDActor extends Actor {
compValue = compValue ?? 0;
this.checkCompetenceXP(compName, compValue);
const update = { _id: comp._id, 'data.xp': compValue };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
+ await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
} else {
console.log("Competence not found", compName);
}
@@ -778,7 +738,7 @@ export class RdDActor extends Actor {
if (comp) {
compValue = compValue ?? 0;
const update = { _id: comp._id, 'data.xp_sort': compValue };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
+ await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
} else {
console.log("Competence not found", compName);
}
@@ -790,7 +750,7 @@ export class RdDActor extends Actor {
if (comp) {
compValue = compValue ?? 0;
const update = { _id: comp._id, 'data.niveau_archetype': compValue };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
+ await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity
} else {
console.log("Competence not found", compName);
}
@@ -798,7 +758,6 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async updateCompteurValue(fieldName, fieldValue) {
- //console.log("Update", fieldName, fieldValue);
let compteurs = duplicate(this.data.data.compteurs);
compteurs[fieldName].value = fieldValue;
await this.update({ "data.compteurs": compteurs });
@@ -992,8 +951,6 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async computeEncombrementTotalEtMalusArmure() {
let encTotal = 0;
-
- let malusArmureData = (this.data.data.attributs && this.data.data.attributs.malusarmure) ? duplicate(this.data.data.attributs.malusarmure) : {};
let newMalusArmure = 0;
for (const item of this.data.items) {
if (item.type == 'armure' && item.data.equipe) { // Armure équipée, intégration du malus armure total
@@ -1014,10 +971,10 @@ export class RdDActor extends Actor {
// Mise à jour valeur totale et états
this.encTotal = encTotal;
this.detectSurEncombrement();
+
// 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 });
+ if (this.data.data.attributs?.malusarmure && newMalusArmure != this.data.data.attributs.malusarmure.value) {
+ await this.update({ "data.attributs.malusarmure.value ": newMalusArmure });
}
return this.encTotal;
}
@@ -1049,12 +1006,12 @@ export class RdDActor extends Actor {
let resume = "Blessures:";
if (nbCritiques > 0 || nbGraves > 0 || nbLegeres > 0) {
if (nbLegeres > 0) {
- resume += " " + nbLegeres + " légères";
+ resume += " " + nbLegeres + " légère" + (nbLegeres > 1 ? "s" : "");
}
if (nbGraves > 0) {
if (nbLegeres > 0)
resume += ",";
- resume += " " + nbGraves + " graves";
+ resume += " " + nbGraves + " grave" + (nbGraves > 1 ? "s" : "");
}
if (nbCritiques > 0) {
if (nbGraves > 0 || nbLegeres > 0)
@@ -1063,7 +1020,7 @@ export class RdDActor extends Actor {
}
}
else {
- resume += " aucune";
+ resume = "Aucune blessure";
}
return resume;
}
@@ -1093,20 +1050,14 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async ajouterRefoulement(value = 1) {
- let ret = "none";
-
- let refoulement = duplicate(this.data.data.reve.refoulement);
- refoulement.value = refoulement.value + value;
-
+ let refoulement = this.data.data.reve.refoulement.value + value;
let total = new Roll("1d20").roll().total;
- if (total <= refoulement.value) {
- refoulement.value = 0;
- this.ajouterSouffle({ chat: true });
- ret = "souffle";
+ if (total <= refoulement) {
+ refoulement = 0;
+ await this.ajouterSouffle({ chat: true });
}
-
- await this.update({ "data.reve.refoulement": refoulement });
- return ret;
+ await this.update({ "data.reve.refoulement.value": refoulement });
+ return refoulement == 0 ? "souffle" : "none";
}
/* -------------------------------------------- */
@@ -1119,7 +1070,6 @@ export class RdDActor extends Actor {
content: this.name + " subit un Souffle de Dragon : " + souffle.name
});
}
- // TODO: fermeture cité
return souffle;
}
@@ -1128,9 +1078,7 @@ export class RdDActor extends Actor {
let queue;
if (this.data.data.reve.reve.thanatosused) {
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.reve.reve.thanatosused": false });
}
else {
queue = await RdDRollTables.getQueue();
@@ -1165,40 +1113,25 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
getTMRRencontres() {
- return this.data.data.reve.rencontre;
+ return this.data.data.reve.rencontre.list;
}
/* -------------------------------------------- */
async deleteTMRRencontreAtPosition() {
- let rencontres = duplicate(this.getTMRRencontres());
- let len = rencontres.list.length;
- let i = 0;
- //console.log("List", rencontres, len);
- let newTable = [];
- for (i = 0; i < len; i++) {
- if (rencontres.list[i].coord != this.getDemiReve())
- newTable.push(rencontres.list[i]);
- }
- if (newTable.length != len) {
- rencontres.list = newTable;
- //console.log("Result: ", rencontres);
- await this.update({ "data.reve.rencontre": rencontres });
+ let rencontres = this.getTMRRencontres();
+ let newRencontres = rencontres.filter(it => it.coord != this.getDemiReve());
+ if (newRencontres.length != rencontres.length) {
+ await this.update({ "data.reve.rencontre.list": newRencontres });
}
}
/* -------------------------------------------- */
async addTMRRencontre(currentRencontre) {
- let rencontres = duplicate(this.getTMRRencontres());
- let len = rencontres.list.length;
- let i = 0;
- let already = false;
- for (i = 0; i < len; i++) {
- if (rencontres.list[i].coord == this.getDemiReve())
- already = true;
- }
- if (!already) {
- rencontres.list.push(currentRencontre);
- await this.update({ "data.reve.rencontre": rencontres });
+ let rencontres = this.getTMRRencontres();
+ let newRencontres = rencontres.filter(it => it.coord != this.getDemiReve());
+ if (newRencontres.length == rencontres.length) {
+ newRencontres.push(currentRencontre);
+ await this.update({ "data.reve.rencontre": newRencontres });
}
}
@@ -1220,9 +1153,8 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
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 });
+ let reve = Math.max(this.data.data.reve.reve.value + value, 0);
+ await this.update({ "data.reve.reve.value": reve });
}
/* -------------------------------------------- */
@@ -1235,17 +1167,13 @@ 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 });
+ async setPointsDeSeuil(seuil) {
+ await this.update({ "data.reve.seuil.value": seuil });
}
/* -------------------------------------------- */
- async setPointsDeChance(value) {
- let chance = duplicate(this.data.data.compteurs.chance);
- chance.value = value;
- await this.update({ "data.compteurs.chance": chance });
+ async setPointsDeChance(chance) {
+ await this.update({ "data.compteurs.chance.value": chance });
}
/* -------------------------------------------- */
@@ -1299,7 +1227,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async testSiSonne(sante, endurance) {
- const roll = new Roll("1d20").roll();
+ const roll = new Roll("1d20").evaluate();
roll.showDice = true;
RdDDice.show(roll);
let result = {
@@ -1307,18 +1235,20 @@ export class RdDActor extends Actor {
sonne: roll.total > endurance || roll.total == 20 // 20 is always a failure
}
if (roll.total == 1) {
- let xp = Misc.toInt(this.data.data.carac.constitution.xp) + 1;
- this.update({ "data.carac.constitution.xp": xp }); // +1 XP !
+ await this.ajoutXpConstitution(1); // +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) {
-
await this.setSonne();
sante.sonne.value = true;
}
return result;
}
+ async ajoutXpConstitution(xp) {
+ await this.update({ "data.carac.constitution.xp": Misc.toInt(this.data.data.carac.constitution.xp) + xp });
+ }
+
/* -------------------------------------------- */
countBlessures(blessuresListe) {
return blessuresListe.filter(b => b.active).length
@@ -1338,14 +1268,12 @@ export class RdDActor extends Actor {
if (myRoll.total == 1 || (myRoll.total != 20 && myRoll.total <= this.data.data.sante.endurance.value)) {
msgText += `${this.name} a réussi son Jet d'Endurance !`;
if (myRoll.total == 1) {
+ await this.ajoutXpConstitution();
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 });
}
} else {
- msgText += `${this.name} a échoué son Jet d'Endurance et devient Sonné`;
await this.setSonne();
+ msgText += `${this.name} a échoué son Jet d'Endurance et devient Sonné`;
}
const message = {
content: msgText,
@@ -1454,29 +1382,25 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
- async manageBlessureFromSheet(bType, index, active) {
- let bList = duplicate(this.data.data.blessures);
- let blessure = bList[bType + "s"].liste[index];
+ async manageBlessureFromSheet(gravite, index) {
+ let listBlessures = duplicate(this.data.data.blessures);
+ let blessure = listBlessures[gravite + "s"].liste[index];
blessure.active = !blessure.active;
if (!blessure.active) {
- blessure.premiers_soins = 0;
- blessure.soins_complets = 0;
- blessure.jours = 0;
- blessure.loc = "";
+ this._supprimerBlessure(blessure);
}
- //console.log("Blessure update", bType, index, blessure, bList );
- await this.update({ 'data.blessures': bList });
+ await this.update({ 'data.blessures': listBlessures });
}
/* -------------------------------------------- */
- async setDataBlessureFromSheet(bType, index, psoins, pcomplets, jours, loc) {
- let bList = duplicate(this.data.data.blessures);
- let blessure = bList[bType + "s"].liste[index];
+ async setDataBlessureFromSheet(gravite, index, psoins, pcomplets, jours, loc) {
+ let listBlessures = duplicate(this.data.data.blessures);
+ let blessure = listBlessures[gravite + "s"].liste[index];
blessure.premiers_soins = psoins;
blessure.soins_complets = pcomplets;
blessure.jours = jours;
blessure.loc = loc;
- await this.update({ 'data.blessures': bList });
+ await this.update({ 'data.blessures': listBlessures });
}
/* -------------------------------------------- */
@@ -1499,24 +1423,21 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async moralIncDec(ajustementMoral) {
- let compteurs = duplicate(this.data.data.compteurs);
- compteurs.moral.value = Misc.toInt(compteurs.moral.value);;
if (ajustementMoral != 0) {
- compteurs.moral.value += ajustementMoral;
- if (compteurs.moral.value > 3) {
- // exaltation
- compteurs.moral.value--;
- compteurs.exaltation.value = Misc.toInt(compteurs.exaltation.value) + 1;
+ let moral = Misc.toInt(this.data.data.compteurs.moral.value) + ajustementMoral
+ if (moral > 3) { // exaltation
+ const exaltation = Misc.toInt(this.data.data.compteurs.exaltation.value) + moral - 3;
+ await this.update({ 'data.compteurs.exaltation.value': exaltation });
}
- if (compteurs.moral.value < -3) {
- // dissolution
- compteurs.moral.value++;
- compteurs.dissolution.value = Misc.toInt(compteurs.dissolution.value) + 1;
+ if (moral < -3) { // dissolution
+ const dissolution = Misc.toInt(this.data.data.compteurs.dissolution.value) + 3 - moral;
+ await this.update({ 'data.compteurs.dissolution.value': dissolution });
}
- await this.update({ 'data.compteurs': compteurs });
+ moral = Math.max(-3, Math.min(moral, 3));
+ await this.update({ 'data.compteurs.moral.value': moral });
}
- return compteurs.moral.value;
+ return this.data.data.compteurs.moral.value;
}
/* -------------------------------------------- */
@@ -1576,11 +1497,14 @@ export class RdDActor extends Actor {
const ajustementEthylique = ethylisme.value;
// Qui a bu boira (p 164)
let rollVolonte = await RdDResolutionTable.roll(this.data.data.carac.volonte.value, Math.min(ajustementEthylique, 0) + this.data.data.compteurs.moral.value);
- msgText += `Vous avez échoué à votre jet d'éthylisme, vous êtes maintenant ${RdDUtility.getNomEthylisme(ajustementEthylique)} (${ajustementEthylique}).`
- msgText += "
" + RdDResolutionTable.explain(rollVolonte) + "
";
- msgText += "Qui a bu boira : " + (rollVolonte.isSuccess
+ const quiABuBoira = (rollVolonte.isSuccess
? "vous êtes libre de continuer à boire ou pas."
: "vous avez une envie irrépréssible de reprendre un verre.");
+
+ msgText += `Vous avez échoué à votre jet d'éthylisme, vous êtes
+ maintenant ${RdDUtility.getNomEthylisme(ajustementEthylique)} (${ajustementEthylique}).
+
${RdDResolutionTable.explain(rollVolonte)}
+
Qui a bu boira : ${quiABuBoira}`;
}
ChatMessage.create({
@@ -1774,7 +1698,7 @@ export class RdDActor extends Actor {
if (!rollData.useMoral) return;
if (rollData.rolled.isEchec ||
(rollData.ajustements.diviseurSignificative && (rollData.rolled.roll * rollData.ajustements.diviseurSignificative > rollData.score))) {
- rollData.perteMoralEchec = rollData.moral<=-3? 'dissolution' : 'perte';
+ rollData.perteMoralEchec = rollData.moral <= -3 ? 'dissolution' : 'perte';
rollData.moral = await this.moralIncDec(-1); /* L'appel au moral a échoué. Le personnage perd un point de moral */
}
}
@@ -2863,42 +2787,29 @@ export class RdDActor extends Actor {
return;
}
/* -------------------------------------------- */
- async optimizeArgent(sumDenier) {
- let sols = Math.floor(sumDenier / 100);
- let deniers = sumDenier - (sols * 100);
- let nbOr = Math.floor(sols / 10);
- let nbArgent = sols - (nbOr * 10);
- let nbBronze = Math.floor(deniers / 10);
- let nbEtain = deniers - (nbBronze * 10);
+ async optimizeArgent(sumDenier, monnaies) {
- // console.log("ARGENT", nbOr, nbArgent, nbBronze, nbEtain);
- let piece = this.data.items.find(item => item.type == 'monnaie' && item.data.valeur_deniers == 1000);
- if (piece) {
- let update = { _id: piece._id, 'data.quantite': nbOr };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update);
+ let parValeur = Misc.classifyFirst(monnaies, it => it.data.valeur_deniers);
+ let fortune = {
+ 1000: Math.floor(sumDenier / 1000), // or
+ 100: Math.floor(sumDenier / 100) % 10, // argent
+ 10: Math.floor(sumDenier / 10) % 10, // bronze
+ 1: sumDenier % 10 // étain
}
-
- piece = this.data.items.find(item => item.type == 'monnaie' && item.data.valeur_deniers == 100);
- if (piece) {
- let update = { _id: piece._id, 'data.quantite': nbArgent };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update);
- }
-
- piece = this.data.items.find(item => item.type == 'monnaie' && item.data.valeur_deniers == 10);
- if (piece) {
- let update = { _id: piece._id, 'data.quantite': nbBronze };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update);
- }
-
- piece = this.data.items.find(item => item.type == 'monnaie' && item.data.valeur_deniers == 1);
- if (piece) {
- let update = { _id: piece._id, 'data.quantite': nbEtain };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update);
+ for (const [valeur, nombre] of Object.entries(fortune)) {
+ let piece = parValeur[valeur];
+ await this.updateEmbeddedEntity("OwnedItem", { _id: piece._id, 'data.quantite': nombre });
}
}
/* -------------------------------------------- */
async payerDenier(sumDenier, dataObj = undefined, quantite = 1) {
+ let monnaies = Monnaie.filtrerMonnaies(this.data.items);
+ if (monnaies.length < 4) {
+ ui.notifications.warn("Problème de monnaies manquantes, impossible de payer correctement!")
+ return;
+ }
+
sumDenier = Number(sumDenier);
let denierDisponible = 0;
@@ -2912,19 +2823,18 @@ export class RdDActor extends Actor {
let isPayed = false;
if (denierDisponible >= sumDenier) {
denierDisponible -= sumDenier;
- this.optimizeArgent(denierDisponible);
+ this.optimizeArgent(denierDisponible, monnaies);
msg = `Vous avez payé ${sumDenier} Deniers, qui ont été soustraits de votre argent.`;
RdDAudio.PlayContextAudio("argent"); // Petit son
isPayed = true;
+ if (dataObj) {
+ dataObj.payload.data.cout = sumDenier / 100; // Mise à jour du prix en sols , avec le prix acheté
+ dataObj.payload.data.quantite = quantite;
+ await this.createOwnedItem(dataObj.payload);
+ msg += `
Et l'objet ${dataObj.payload.name} a été ajouté à votre inventaire.`;
+ }
} else {
- msg = "Vous n'avez pas assez d'argent pour paye cette somme !";
- }
-
- if (dataObj && isPayed) {
- dataObj.payload.data.cout = sumDenier / 100; // Mise à jour du prix en sols , avec le prix acheté
- dataObj.payload.data.quantite = quantite;
- await this.createOwnedItem(dataObj.payload);
- msg += `
Et l'objet ${dataObj.payload.name} a été ajouté à votre inventaire.`;
+ msg = "Vous n'avez pas assez d'argent pour payer cette somme !";
}
let message = {
@@ -2938,10 +2848,8 @@ export class RdDActor extends Actor {
async monnaieIncDec(id, value) {
let monnaie = this.data.items.find(item => item.type == 'monnaie' && item._id == id);
if (monnaie) {
- monnaie.data.quantite += value;
- if (monnaie.data.quantite < 0) monnaie.data.quantite = 0; // Sanity check
- const update = { _id: monnaie._id, 'data.quantite': monnaie.data.quantite };
- const updated = await this.updateEmbeddedEntity("OwnedItem", update);
+ const quantite = Math.max(0, monnaie.data.quantite + value);
+ await this.updateEmbeddedEntity("OwnedItem", { _id: monnaie._id, 'data.quantite': quantite });
}
}
diff --git a/module/item-competence.js b/module/item-competence.js
index c7be84c7..98a422f6 100644
--- a/module/item-competence.js
+++ b/module/item-competence.js
@@ -31,6 +31,13 @@ const categorieCompetences = {
"lancer": { level: "-8", label: "Lancer" }
}
+const compendiumCompetences = {
+ "personnage": "foundryvtt-reve-de-dragon.competences",
+ "creature": "foundryvtt-reve-de-dragon.competences-creatures",
+ "entite": "foundryvtt-reve-de-dragon.competences-entites"
+};
+
+
function _buildCumulXP() {
let cumulXP = { "-11": 0 };
let cumul = 0;
@@ -46,6 +53,10 @@ const competence_xp_cumul = _buildCumulXP();
export class RdDItemCompetence extends Item {
+ static actorCompendium(actorType) {
+ return compendiumCompetences[actorType];
+ }
+
static getCategorieCompetences() {
return categorieCompetences;
}
diff --git a/module/item-monnaie.js b/module/item-monnaie.js
new file mode 100644
index 00000000..b0a76110
--- /dev/null
+++ b/module/item-monnaie.js
@@ -0,0 +1,40 @@
+
+const monnaiesData = [
+ {
+ _id: randomID(16), name: "Etain (1 denier)", type: 'monnaie',
+ img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
+ data: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
+ },
+ {
+ _id: randomID(16), name: "Bronze (10 deniers)", type: 'monnaie',
+ img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
+ data: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
+ },
+ {
+ _id: randomID(16), name: "Argent (1 sol)", type: 'monnaie',
+ img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
+ data: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
+ },
+ {
+ _id: randomID(16), name: "Or (10 sols)", type: 'monnaie',
+ img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
+ data: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
+ }
+]
+
+export class Monnaie {
+
+ static monnaiesData() {
+ return monnaiesData;
+ }
+
+ static filtrerMonnaies(items) {
+ return items.filter(it => it.type == 'monnaie');
+ }
+
+ static monnaiesManquantes(items) {
+ const valeurs = Monnaie.filtrerMonnaies(items)
+ .map(it => it.data.valeur_deniers)
+ return duplicate(monnaiesData.filter(monnaie => !valeurs.find(v => v != monnaie.data.valeur_deniers)));
+ }
+}
diff --git a/module/misc.js b/module/misc.js
index f1220c35..8f972c7b 100644
--- a/module/misc.js
+++ b/module/misc.js
@@ -47,6 +47,17 @@ export class Misc {
return itemsBy;
}
+ static classifyFirst(items, classifier) {
+ let itemsBy = {};
+ for (const item of items) {
+ const classification = classifier(item);
+ if (!itemsBy[classification]) {
+ itemsBy[classification] = item;
+ }
+ }
+ return itemsBy;
+ }
+
static classifyInto(itemsBy, items, classifier = it => it.type, transform = it => it) {
for (const item of items) {
const classification = classifier(item);
diff --git a/module/poetique.txt b/module/poetique.txt
new file mode 100644
index 00000000..35c1a630
--- /dev/null
+++ b/module/poetique.txt
@@ -0,0 +1,44 @@
+Le courant du Fleuve
+Te domine et te Porte
+Avant que tu te moeuves
+Combat le, ou il t'emporte
+
+
+
+A vous qui faites ripaille
+sourds aux damnés de la faim
+à vous qui livrez
+une inégale bataille
+à ceux qui vous tendent la main
+
+Ils sont tout près ! - Tenons fermée
+
Cette salle, où nous les narguons.
+
Quel bruit dehors ! Hideuse armée
+
De vampires et de dragons !
+
La poutre du toit descellée
+
Ploie ainsi qu'une herbe mouillée,
+
Et la vieille porte rouillée
+
Tremble, à déraciner ses gonds !`),
+
+https://www.poetica.fr/poeme-1423/guy-de-maupassant-le-sommeil-du-mandarin/
+
+
+
+
+Le monde est un rêve de Dragons. Nous
+ne savons pas qui sont les Dragons ni à quoi
+ils ressemblent, en dépit de l’antique iconographie qui les dépeint comme de gigantesques créatures ailées capables de cracher
+feu et flammes.
+
+
+
+Car parmi les humains, autre nom lui est donné,
+Nom sinistre parmi tous, nom funèbre, c'est la mort!
+Un ami disparu... Thanatos est passé...
+
+
+Messieurs, ne crachez pas de jurons ni d'ordure
+Au visage fardé de cette pauvre impure
+Que déesse Famine a par un soir d'hiver,
+Contrainte à relever ses jupons en plein air.
+
diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js
index be658177..15f69467 100644
--- a/module/rdd-calendrier.js
+++ b/module/rdd-calendrier.js
@@ -147,6 +147,7 @@ export class RdDCalendrier extends Application {
}
}
}
+ this.listeNombreAstral = newList;
game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral);
}
/* -------------------------------------------- */
diff --git a/module/rdd-carac.js b/module/rdd-carac.js
index 516b4f9f..6dbe169c 100644
--- a/module/rdd-carac.js
+++ b/module/rdd-carac.js
@@ -1,5 +1,4 @@
import { Grammar } from "./grammar.js";
-import { RdDUtility } from "./rdd-utility.js";
const tableCaracDerivee = {
// xp: coût pour passer du niveau inférieur à ce niveau
diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js
index cbc1aafe..b1fe330a 100644
--- a/module/rdd-tmr-dialog.js
+++ b/module/rdd-tmr-dialog.js
@@ -72,11 +72,11 @@ export class RdDTMRDialog extends Dialog {
}
loadSortsReserve() {
- this.sortsReserves = duplicate(this.actor.data.data.reve.reserve.list);
+ this.sortsReserves = this.actor.data.data.reve.reserve.list;
}
loadRencontres() {
- this.rencontresExistantes = duplicate(this.actor.getTMRRencontres()).list;
+ this.rencontresExistantes = this.actor.getTMRRencontres();
}
/* -------------------------------------------- */
@@ -389,6 +389,11 @@ export class RdDTMRDialog extends Dialog {
ChatMessage.create({ content: message, user: game.user._id, whisper: ChatMessage.getWhisperRecipients("GM") });
}
+ /* -------------------------------------------- */
+ _tellToUserAndGM(message) {
+ ChatMessage.create({ content: message, user: game.user._id, whisper: [game.user._id].concat(ChatMessage.getWhisperRecipients("GM")) });
+ }
+
/* -------------------------------------------- */
async manageRencontre(tmr, postRencontre) {
if (this.viewOnly) {
@@ -669,8 +674,8 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async declencheSortEnReserve(coord) {
- let sortReserveList = TMRUtility.getSortReserveList(this.sortsReserves, coord);
- if (sortReserveList.length > 0) {
+ let sortsEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord);
+ if (sortsEnCoord.length > 0) {
if (EffetsDraconiques.isSortReserveImpossible(this.actor)) {
ui.notifications.error("Une queue ou un souffle vous empèche de déclencher de sort!");
return;
@@ -678,7 +683,7 @@ export class RdDTMRDialog extends Dialog {
if (!EffetsDraconiques.isUrgenceDraconique(this.actor) &&
(EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coord))) {
let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête Reserve en Sécurité ou Réserve Exensible, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher :