diff --git a/module/actor.js b/module/actor.js
index 0defc7d9..8709a331 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -57,10 +57,10 @@ export class RdDActor extends Actor {
}
static remoteActorCall(data) {
- if (Misc.isElectedUser()){
+ if (Misc.isElectedUser()) {
RdDActor.onRemoteActorCall(data);
}
- else{
+ else {
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_remote_actor_call", data: data });
}
}
@@ -833,14 +833,14 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
- async updateCompetenceXP(compName, compValue) {
+ async updateCompetenceXP(compName, newXp) {
let comp = this.getCompetence(compName);
if (comp) {
- compValue = compValue ?? 0;
- this.checkCompetenceXP(compName, compValue);
- const update = { _id: comp.id, 'data.xp': compValue };
+ newXp = newXp ?? 0;
+ this.checkCompetenceXP(compName, newXp);
+ const update = { _id: comp.id, 'data.xp': newXp };
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- this.updateExperienceLog("XP Compétence", compValue, "XP attribués en " + compName);
+ this.updateExperienceLog("XP Compétence", newXp, "XP attribués en " + compName);
} else {
console.log("Competence not found", compName);
}
@@ -873,20 +873,22 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
- async updateExperienceLog( modeXP, valeurXP, raisonXP = 'Inconnue') {
+ async updateExperienceLog(modeXP, valeurXP, raisonXP = 'Inconnue') {
let d = new Date();
- console.log( modeXP, valeurXP, raisonXP);
- let expLog = duplicate( (Misc.templateData(this)).experiencelog );
- expLog.push( { mode: Misc.upperFirst(modeXP), valeur: valeurXP, raison: Misc.upperFirst(raisonXP),
- daterdd : game.system.rdd.calendrier.getDateFromIndex(), datereel: `${d.getDate()}/${d.getMonth()+1}/${d.getFullYear()}` } );
- await this.update({ [`data.experiencelog`]: expLog } );
+ console.log(modeXP, valeurXP, raisonXP);
+ let expLog = duplicate((Misc.templateData(this)).experiencelog);
+ expLog.push({
+ mode: Misc.upperFirst(modeXP), valeur: valeurXP, raison: Misc.upperFirst(raisonXP),
+ daterdd: game.system.rdd.calendrier.getDateFromIndex(), datereel: `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}`
+ });
+ await this.update({ [`data.experiencelog`]: expLog });
console.log("Add XP log", expLog);
}
/* -------------------------------------------- */
async updateCompteurValue(fieldName, fieldValue, raison = 'Inconnue') {
await this.update({ [`data.compteurs.${fieldName}.value`]: fieldValue });
- if ( fieldName == 'stress') {
+ if (fieldName == 'stress') {
await this.updateExperienceLog('stress', fieldValue, raison);
}
}
@@ -894,12 +896,12 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async addCompteurValue(fieldName, fieldValue, raison = 'Inconnue') {
let oldValue = (Misc.templateData(this)).compteurs[fieldName].value;
- await this.update({ [`data.compteurs.${fieldName}.value`]: Number(oldValue) + Number(fieldValue) } );
- if ( fieldName == 'stress') {
- await this.updateExperienceLog('stress', fieldValue, raison );
+ await this.update({ [`data.compteurs.${fieldName}.value`]: Number(oldValue) + Number(fieldValue) });
+ if (fieldName == 'stress') {
+ await this.updateExperienceLog('stress', fieldValue, raison);
}
}
-
+
/* -------------------------------------------- */
async updateAttributeValue(fieldName, fieldValue) {
await this.update({ [`data.attributs.${fieldName}.value`]: fieldValue });
@@ -1938,8 +1940,8 @@ export class RdDActor extends Actor {
compteurs.dissolution.value = dissolution - perteDissolution;
compteurs.exaltation.value = 0;
await this.update({ "data.compteurs": compteurs });
-
- this.updateExperienceLog( 'XP', stressRollData.xp, "Transformation du stress");
+
+ this.updateExperienceLog('XP', stressRollData.xp, "Transformation du stress");
}
/* -------------------------------------------- */
@@ -1974,7 +1976,7 @@ export class RdDActor extends Actor {
createCallbackExperience() {
return {
condition: r => r.rolled.isPart && r.finalLevel < 0 && game.settings.get("core", "rollMode") != 'selfroll',
- action: r => this._appliquerAjoutExperience(r, game.settings.get("core", "rollMode") != 'blindroll')
+ action: r => this.appliquerAjoutExperience(r, game.settings.get("core", "rollMode") != 'blindroll')
};
}
@@ -1987,29 +1989,33 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
- async checkCaracXP(caracName) {
- let carac = Misc.templateData(this).carac[caracName];
+ async checkCaracXP(caracName, display = true) {
+ let carac = RdDActor._findCaracByName(Misc.templateData(this).carac, caracName);
if (carac && carac.xp > 0) {
- let xpNeeded = RdDCarac.getCaracNextXp(carac.value + 1);
+ const niveauSuivant = Number(carac.value) + 1;
+ let xpNeeded = RdDCarac.getCaracNextXp(niveauSuivant);
if (carac.xp >= xpNeeded) {
carac = duplicate(carac);
- carac.value = Number(carac.value) + 1;
+ carac.value = niveauSuivant;
- let xpData = {
+ let checkXp = {
alias: this.name,
carac: caracName,
- value: carac.value,
+ value: niveauSuivant,
xp: carac.xp
}
- ChatUtility.createChatMessage(this.name, "default", {
- content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html`, xpData)
- });
+ if (display){
+ ChatUtility.createChatMessage(this.name, "default", {
+ content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-carac-xp.html`, checkXp)
+ });
+ }
+ return checkXp;
}
}
}
/* -------------------------------------------- */
- async checkCompetenceXP(compName, newXP = undefined) {
+ async checkCompetenceXP(compName, newXP, display = true) {
let compData = Misc.data(this.getCompetence(compName));
if (compData && newXP && newXP == compData.data.xp) { // Si édition, mais sans changement XP
return;
@@ -2021,8 +2027,7 @@ export class RdDActor extends Actor {
let newCompData = duplicate(compData);
newCompData.data.niveau += 1;
newCompData.data.xp = newXP;
-
- let xpData = {
+ let checkXp = {
alias: this.name,
competence: newCompData.name,
niveau: newCompData.data.niveau,
@@ -2030,33 +2035,30 @@ export class RdDActor extends Actor {
archetype: newCompData.data.niveau_archetype,
archetypeWarning: newCompData.data.niveau > compData.data.niveau_archetype
}
- ChatUtility.createChatMessage(this.name, "default", {
- content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html`, xpData)
- });
+ if (display) {
+ ChatUtility.createChatMessage(this.name, "default", {
+ content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-competence-xp.html`, checkXp)
+ });
+ }
+ return checkXp;
}
}
}
/* -------------------------------------------- */
- async _appliquerAjoutExperience(rollData, display = true) {
+ async appliquerAjoutExperience(rollData, display) {
if (!this.isPersonnage()) return;
- let xpResult = this.appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence);
- if (display && xpResult.result) {
- let xpmsg = "
Points d'expérience gagnés ! Carac: " + xpResult.xpCarac + ", Comp: " + xpResult.xpCompetence;
+ let xpData = await this._appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence);
+ if (!xpData) {
+ return;
+ }
+ if (display) {
let message = {
- whisher: ChatMessage.getWhisperRecipients(["GM", this.name]),
- content: "" + rollData.selectedCarac.label + "" + xpmsg,
+ whisher: ChatUtility.getWhisperRecipientsAndGMs(this.name),
+ content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, xpData)
}
ChatMessage.create(message);
}
- if (xpResult && xpResult.xpComp > 0 && rollData.competence) {
- this.checkCompetenceXP(rollData.competence.name);
- this.updateExperienceLog("XP", xpResult.xpComp,"XP en compétence "+rollData.competence.name);
- }
- if (xpResult && xpResult.xpCarac > 0 && rollData.selectedCarac) {
- this.checkCaracXP(rollData.selectedCarac.name);
- this.updateExperienceLog("XP", xpResult.xpCarac,"XP en carac "+rollData.selectedCarac.name);
- }
}
/* -------------------------------------------- */
@@ -2780,47 +2782,64 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
- async appliquerExperience(rolled, caracName, competence = undefined) {
+ async _appliquerExperience(rolled, caracName, competence) {
if (!this.isPersonnage()) return;
- if (rolled.isPart && rolled.finalLevel < 0) {
- // Cas de désir lancinant, pas d'expérience sur particulière
- if (this.checkDesirLancinant()) {
- ChatMessage.create({
- content: `Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi`,
- whisper: ChatMessage.getWhisperRecipients(game.user.name)
- });
- return { result: false, xpcarac: 0, xpCompetence: 0 };
- }
-
- if (caracName == 'Vie') caracName = 'constitution';
- if (caracName == 'derobee') caracName = 'agilite';
- if (caracName == 'reve-actuel') caracName = 'reve';
- let xp = Math.abs(rolled.finalLevel);
- let xpCarac = Math.floor(xp / 2); // impair: arrondi inférieur en carac
- let xpComp = 0;
- if (competence) {
- xpComp = xp - xpCarac;
- let update = { _id: competence.id, 'data.xp': Misc.toInt(competence.data.xp) + xpComp };
- await this.updateEmbeddedDocuments('Item', [update]);
- } else {
- xpCarac = Math.max(xpCarac, 1);
- }
- if (xpCarac > 0) {
- let carac = duplicate(Misc.templateData(this).carac);
- let selectedCarac = RdDActor._findCaracByName(carac, caracName);
- if (!selectedCarac.derivee) {
- selectedCarac.xp = Misc.toInt(selectedCarac.xp) + xpCarac;
- await this.update({ "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.`,
- whisper: ChatMessage.getWhisperRecipients(game.user.name)
- });
- }
- }
- return { result: true, xpCarac: xpCarac, xpCompetence: xpComp }; //XP
+ // Pas d'XP
+ if (!rolled.isPart || rolled.finalLevel >= 0) {
+ return undefined;
+ }
+ if (this.checkDesirLancinant()) {
+ // Cas de désir lancinant, pas d'expérience sur particulière
+ ChatMessage.create({
+ content: `Vous souffrez au moins d'un Désir Lancinant, vous ne pouvez pas gagner d'expérience sur une Particulière tant que le désir n'est pas assouvi`,
+ whisper: ChatMessage.getWhisperRecipients(game.user.name)
+ });
+ return undefined;
+ }
+ if (caracName == 'Vie') caracName = 'constitution';
+ if (caracName == 'derobee') caracName = 'agilite';
+ if (caracName == 'reve-actuel') caracName = 'reve';
+
+ let xp = Math.abs(rolled.finalLevel);
+ // impair: arrondi inférieur en carac
+ let xpCarac = competence ? Math.floor(xp / 2) : Math.max(Math.floor(xp / 2), 1);
+
+ let xpData = {
+ alias: this.name,
+ caracName: caracName, xpCarac: xpCarac,
+ competence: competence, xpCompetence: competence ? xp - xpCarac : 0
+ };
+
+ await this._xpCompetence(xpData);
+ await this._xpCarac(xpData);
+ return xpData;
+ }
+
+ /* -------------------------------------------- */
+ async _xpCompetence(xpData) {
+ if (xpData.competence) {
+ const newXp = Misc.toInt(xpData.competence.data.xp) + xpData.xpCompetence;
+ let update = { _id: xpData.competence._id, 'data.xp': newXp };
+ await this.updateEmbeddedDocuments('Item', [update]);
+ xpData.checkComp = await this.checkCompetenceXP(xpData.competence.name, undefined, false);
+ this.updateExperienceLog("XP", xpData.xp, "XP en compétence " + xpData.competence.name);
+ }
+ }
+
+ /* -------------------------------------------- */
+ async _xpCarac(xpData) {
+ if (xpData.xpCarac > 0) {
+ let carac = duplicate(Misc.templateData(this).carac);
+ let selectedCarac = RdDActor._findCaracByName(carac, xpData.caracName);
+ if (!selectedCarac.derivee) {
+ selectedCarac.xp = Misc.toInt(selectedCarac.xp) + xpData.xpCarac;
+ await this.update({ "data.carac": carac });
+ xpData.checkCarac = await this.checkCaracXP(selectedCarac.label, false);
+ this.updateExperienceLog("XP", xpData.xpCarac, "XP en carac " + xpData.caracName);
+ } else {
+ xpData.caracRepartitionManuelle = true;
+ }
}
- return { result: false, xpCarac: 0, xpCompetence: 0 }; // Pas d'XP
}
/* -------------------------------------------- */
@@ -2828,7 +2847,7 @@ export class RdDActor extends Actor {
// Gestion expérience (si existante)
data.competence = Misc.data(this.getCompetence("astrologie"));
data.selectedCarac = Misc.templateData(this).carac["vue"];
- this._appliquerAjoutExperience(data);
+ this.appliquerAjoutExperience(data, false);
// Ajout du nombre astral
const item = {
@@ -2855,14 +2874,14 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
getCaracByName(caracName) {
- switch (caracName) {
- case 'reve-actuel': case 'Rêve actuel':
+ switch (Grammar.toLowerCaseNoAccent(caracName)) {
+ case 'reve-actuel': case 'reve actuel':
return {
label: 'Rêve actuel',
value: this.getReveActuel(),
type: "number"
};
- case 'chance-actuelle': case 'Chance actuelle':
+ case 'chance-actuelle': case 'chance-actuelle':
return {
label: 'Chance actuelle',
value: this.getChanceActuel(),
@@ -2891,11 +2910,6 @@ export class RdDActor extends Actor {
if (keys.length > 0) {
return carac[keys[0]];
}
- // for (const [key, value] of Object.entries(carac)) {
- // if (key.includes(name) || Grammar.toLowerCaseNoAccent(value.label).includes('name')) {
- // return carac[key];
- // }
- // }
return undefined; // Per default
}
@@ -2925,12 +2939,12 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async displayTMR(mode = "normal") {
- let demiReve = this.listeEffets( it => it.label == "Demi-rêve");
- if ( mode != 'visu' && demiReve.length > 0 ) {
+ let demiReve = this.listeEffets(it => it.label == "Demi-rêve");
+ if (mode != 'visu' && demiReve.length > 0) {
ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement");
mode = "visu"; // bascule le mode en visu automatiquement
}
-
+
let isRapide = mode == "rapide";
if (mode != "visu") {
let minReveValue = (isRapide && !EffetsDraconiques.isDeplacementAccelere(this) ? 3 : 2) + this.countMonteeLaborieuse();
@@ -3280,7 +3294,7 @@ export class RdDActor extends Actor {
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.html');
if (rolled.isPart) {
- await this._appliquerAjoutExperience(rollData, true);
+ await this.appliquerAjoutExperience(rollData, true);
}
return rolled.isSuccess;
}
@@ -3908,10 +3922,10 @@ export class RdDActor extends Actor {
const ids = Array.from(this.effects?.values())
.filter(it => StatusEffects.statusId(it.data) == StatusEffects.statusId(effect))
.map(it => it.id);
- //console.log("Delete effect 1: ", this.effects, ids);
- if (ids.length > 0) {
- await this.deleteEmbeddedDocuments('ActiveEffect', ids);
- }
+ //console.log("Delete effect 1: ", this.effects, ids);
+ if (ids.length > 0) {
+ await this.deleteEmbeddedDocuments('ActiveEffect', ids);
+ }
}
/* -------------------------------------------- */
@@ -3928,7 +3942,7 @@ export class RdDActor extends Actor {
//effet.flags.core.statusId = effet.id;
let effectArray = await this.createEmbeddedDocuments('ActiveEffect', [effet]);
if (effectArray[0]) {
- await effectArray[0].setFlag( 'core', 'statusId', effet.id);
+ await effectArray[0].setFlag('core', 'statusId', effet.id);
}
}
diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js
index 34d20e6e..deb5c9dd 100644
--- a/module/rdd-tmr-dialog.js
+++ b/module/rdd-tmr-dialog.js
@@ -386,6 +386,7 @@ export class RdDTMRDialog extends Dialog {
rencontre: this.currentRencontre,
nbRounds: 1,
canClose: false,
+ selectedCarac: {label: "reve-actuel"},
tmr: TMRUtility.getTMR(this._getActorCoord())
}
@@ -393,7 +394,7 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
- async _tentativeMaitrise(rencData, presentCite) {
+ async _tentativeMaitrise(rencData) {
console.log("-> matriser", rencData);
rencData.reve = this.actor.getReveActuel();
diff --git a/module/tmr-rencontres.js b/module/tmr-rencontres.js
index eea11c27..85c12887 100644
--- a/module/tmr-rencontres.js
+++ b/module/tmr-rencontres.js
@@ -473,7 +473,7 @@ export class TMRRencontres {
/* -------------------------------------------- */
static async onPostSuccessReveDeDragon(tmrDialog, tmrData) {
if (tmrData.rolled.isPart) {
- await tmrData.actor.appliquerExperience(tmrData.rolled, 'reve', tmrData.competence);
+ await tmrData.actor.appliquerAjoutExperience(tmrData, true);
}
await tmrData.actor.resultCombatReveDeDragon(tmrData);
}
diff --git a/templates/chat-actor-gain-xp.html b/templates/chat-actor-gain-xp.html
new file mode 100644
index 00000000..ec447eba
--- /dev/null
+++ b/templates/chat-actor-gain-xp.html
@@ -0,0 +1,26 @@
+