diff --git a/module/actor-sheet.js b/module/actor-sheet.js index fd9fb336..ed649231 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -220,7 +220,7 @@ export class RdDActorSheet extends ActorSheet { RdDUtility.selectObjetType( this ); }); html.find('.creer-une-oeuvre').click(async event => { - this.selectTypeOeuvre(); + RdDUtility.selectTypeOeuvre(this); }); html.find('#nettoyer-conteneurs').click(async event => { this.actor.nettoyerConteneurs(); diff --git a/module/actor.js b/module/actor.js index 194106a9..5c921663 100644 --- a/module/actor.js +++ b/module/actor.js @@ -31,6 +31,7 @@ import { DialogConsommer } from "./dialog-item-consommer.js"; import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js"; import { RollDataAjustements } from "./rolldata-ajustements.js"; import { DialogItemAchat } from "./dialog-item-achat.js"; +import { RdDItem } from "./item.js"; /* -------------------------------------------- */ @@ -381,7 +382,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async verifierPotionsEnchantees() { - let potionsEnchantees = this.filterItemsData(it => it.type == 'potion' && it.data.magique); + let potionsEnchantees = this.filterItemsData(it => it.type == 'potion' && it.data.categorie.toLowerCase().includes('enchant') ); for (let potion of potionsEnchantees) { if (!potion.prpermanent) { console.log(potion); @@ -810,7 +811,8 @@ export class RdDActor extends Actor { if (caracName == 'Taille') { return; } - await this.update({ [`data.carac.${caracName}.xp`]: caracXP ?? 0 }); + // if ( isNaN(caracXP) || typeof(caracXP) != 'number') caracXP = 0; + //await this.update({ [`data.carac.${caracName}.xp`]: caracXP }); this.checkCaracXP(caracName); } @@ -896,7 +898,7 @@ export class RdDActor extends Actor { async updateCompetenceXP(compName, newXp) { let comp = this.getCompetence(compName); if (comp) { - newXp = newXp ?? 0; + if ( isNaN(newXp) || typeof(newXp) != 'number') newXp = 0; this.checkCompetenceXP(compName, newXp); const update = { _id: comp.id, 'data.xp': newXp }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity @@ -911,7 +913,7 @@ export class RdDActor extends Actor { async updateCompetenceXPSort(compName, compValue) { let comp = this.getCompetence(compName); if (comp) { - compValue = compValue ?? 0; + if ( isNaN(compValue) || typeof(compValue) != 'number') compValue = 0; const update = { _id: comp.id, 'data.xp_sort': compValue }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity this.updateExperienceLog("XP Sort", compValue, "XP modifié en sort de " + compName); @@ -1139,12 +1141,17 @@ export class RdDActor extends Actor { sourceActor.buildSubConteneurObjetList(itemId, itemsList); // Get itemId list let itemMap = {}; - for (let item of itemsList) { - let srcItem = sourceActor.data.items.find(subItem => subItem._id == item.id); - let newItem = await this.createEmbeddedDocuments('Item', [duplicate(srcItem)]); + const itemsDataToCreate = itemsList.map(it => sourceActor.getObjet(it.id)) + .map(it => duplicate(Misc.data(it))) + .map(it => { it.data.contenu = []; return it; }); + let newItems = await this.createEmbeddedDocuments('Item', itemsDataToCreate); + for (let i = 0; i < itemsList.length; i++) { + const srcItem = itemsList[i]; + const newItem = newItems[i]; console.log('New object', newItem, srcItem); - itemMap[srcItem._id] = newItem._id; // Pour garder le lien ancien / nouveau + itemMap[srcItem.id] = newItem._id; // Pour garder le lien ancien / nouveau } + for (let item of itemsList) { // Second boucle pour traiter la remise en conteneurs // gestion conteneur/contenu if (item.conteneurId) { // l'Objet était dans un conteneur @@ -2775,6 +2782,7 @@ export class RdDActor extends Actor { rollData.xpSort = RdDItemSigneDraconique.getXpSortSigneDraconique(rollData.rolled.code, rollData.signe); if (rollData.xpSort > 0) { await this.updateEmbeddedDocuments("Item", [{ _id: compData._id, 'data.xp_sort': Misc.toInt(compData.data.xp_sort) + rollData.xpSort }]); + await this.updateExperienceLog("XP Sort", rollData.xpSort, "Signe draconique en " + rollData.competence.name); } await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]); RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html'); @@ -3488,13 +3496,17 @@ export class RdDActor extends Actor { } async ajouterDeniers(gain, fromActorId = undefined) { + gain = Number.parseInt(gain); + if (gain == 0){ + return; + } if (fromActorId && !game.user.isGM) { RdDActor.remoteActorCall({ userId: Misc.connectedGMOrUser(), actorId: this.id, method: 'ajouterDeniers', args: [gain, fromActorId] }); } else { const fromActor = game.actors.get(fromActorId) let fortune = this.getFortune(); - fortune += Number(gain); + fortune += gain; await this.optimizeArgent(fortune); RdDAudio.PlayContextAudio("argent"); // Petit son @@ -3545,8 +3557,9 @@ export class RdDActor extends Actor { return; } } - if (vendeur) { - let itemVenduData = Misc.data(vendeur.getObjet(itemId)); + const itemVendu = vendeur?.getObjet(itemId); + if (itemVendu) { + let itemVenduData = Misc.data(itemVendu); if ("quantite" in itemVenduData.data ? itemVenduData.data.quantite < achat.quantiteTotal : achat.nombreLots != 1) { await acheteur?.ajouterDeniers(coutDeniers); ui.notifications.warn(`Le vendeur n'a plus assez de ${vente.item.name} !`); @@ -3582,10 +3595,12 @@ export class RdDActor extends Actor { if (!vente.quantiteIllimite) { if (vente.quantiteNbLots <= achat.nombreLots) { - ChatUtility.removeChatMessageId(chatMessageIdVente); + ChatUtility.removeChatMessageId(achat.chatMessageIdVente); } else { + vente["properties"] = new RdDItem(vente.item).getProprietes(); vente.quantiteNbLots -= achat.nombreLots; + vente.jsondata = JSON.stringify(vente.item); messageVente.update({ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente) }); messageVente.render(true); } diff --git a/module/item.js b/module/item.js index 26b0fb7e..870f0328 100644 --- a/module/item.js +++ b/module/item.js @@ -215,7 +215,7 @@ export class RdDItem extends Item { } async _onProposerVente(venteData) { - venteData["properties"] = this[`_${venteData.item.type}ChatData`](); + venteData["properties"] = this.getProprietes(); if (venteData.isOwned) { if (venteData.quantiteNbLots * venteData.tailleLot > venteData.quantiteMax) { ui.notifications.warn(`Vous avez ${venteData.quantiteMax} ${venteData.item.name}, ce n'est pas suffisant pour vendre ${venteData.quantiteNbLots} de ${venteData.tailleLot}`) @@ -229,11 +229,15 @@ export class RdDItem extends Item { ChatMessage.create(RdDUtility.chatDataSetup(html)); } + getProprietes() { + return this[`_${Misc.data(this).type}ChatData`](); + } + /* -------------------------------------------- */ async postItem() { console.log(this); let chatData = duplicate(Misc.data(this)); - const properties = this[`_${chatData.type}ChatData`](); + const properties = this.getProprietes(); chatData["properties"] = properties if (this.actor) { chatData.actor = { id: this.actor.id }; diff --git a/module/rdd-astrologie-editeur.js b/module/rdd-astrologie-editeur.js index 75913483..65ea242d 100644 --- a/module/rdd-astrologie-editeur.js +++ b/module/rdd-astrologie-editeur.js @@ -25,7 +25,7 @@ /* -------------------------------------------- */ async resetNombreAstraux() { game.system.rdd.calendrier.resetNombreAstral(); - await game.system.rdd.calendrier.rebuildListeNombreAstral(); + await game.system.rdd.calendrier.rebuildListeNombreAstral( 'reset' ); game.system.rdd.calendrier.showAstrologieEditor(); } diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js index 52c6f7ca..aba59b4e 100644 --- a/module/rdd-calendrier.js +++ b/module/rdd-calendrier.js @@ -37,13 +37,18 @@ const MAX_NOMBRE_ASTRAL = 12; /* -------------------------------------------- */ export class RdDCalendrier extends Application { - getCalendrier(index) { - let month = Math.floor(index / 28) % 12; + static createCalendrierPos() { + return { top: 200, left: 200 }; + } + + static getCalendrier(index) { let calendrier = { heureRdD: 0, // Index dans heuresList minutesRelative: 0, - moisRdD: month, - jour: (index - (month * 28)) + 1 + indexJour: index, + annee: Math.floor(index / (28 * 12)), + moisRdD: Math.floor(index / 28) % 12, + jour: (index % 28) // Le calendrier stocke le jour en 0-27, mais en 1-28 à l'affichage } return calendrier; } @@ -52,9 +57,12 @@ export class RdDCalendrier extends Application { async initCalendrier() { // Calendrier this.calendrier = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier")); + this.calendrier.annee = this.calendrier.annee ?? (this.calendrier.moisRdD == 12 ? 1 : 0); + this.calendrier.moisRdD = (this.calendrier.moisRdD ?? 0) % 12; + //console.log("CALENDRIER", this.calendrier); if (this.calendrier == undefined || this.calendrier.moisRdD == undefined) { - this.calendrier = this.getCalendrier(0); + this.calendrier = RdDCalendrier.getCalendrier(0); if (game.user.isGM) { // Uniquement si GM game.settings.set("foundryvtt-reve-de-dragon", "calendrier", this.calendrier); } @@ -62,9 +70,7 @@ export class RdDCalendrier extends Application { // position this.calendrierPos = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier-pos")); if (this.calendrierPos == undefined || this.calendrierPos.top == undefined) { - this.calendrierPos = {}; - this.calendrierPos.top = 200; - this.calendrierPos.left = 200; + this.calendrierPos = RdDCalendrier.createCalendrierPos(); if (game.user.isGM) { // Uniquement si GM game.settings.set("foundryvtt-reve-de-dragon", "calendrier-pos", this.calendrierPos); } @@ -94,19 +100,16 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ getDateFromIndex(index) { - index = index ?? this.getCurrentDayIndex(); - let month = Math.floor(index / 28); - let day = (index - (month * 28)) + 1; - return day + " " + heuresList[month]; + const date = RdDCalendrier.getCalendrier(index ?? this.getCurrentDayIndex()); + return (date.jour+1) + ' ' + heuresDef[heuresList[date.moisRdD]].label; } /* -------------------------------------------- */ getNumericDateFromIndex(index = undefined) { - if (!index) index = this.getCurrentDayIndex(); - let month = Math.floor(index / 28) + const dateRdD = RdDCalendrier.getCalendrier(index ?? this.getCurrentDayIndex()); return { - month: heuresList[month], - day: (index - (month * 28)) + 1 + day: dateRdD.jour + 1, + month: heuresList[dateRdD.moisRdD] } } @@ -117,7 +120,7 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ getCurrentDayIndex() { - return (this.calendrier.moisRdD * 28) + this.calendrier.jour; + return (((this.calendrier.annee ?? 0) * 12 + (this.calendrier.moisRdD ?? 0)) * 28) + (this.calendrier.jour ?? 0); } /* -------------------------------------------- */ @@ -136,8 +139,8 @@ export class RdDCalendrier extends Application { } /* -------------------------------------------- */ - async ajouterNombreAstral(index) { - const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: true, rollMode: "selfroll" }); + async ajouterNombreAstral(index, showdice = true) { + const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showdice, rollMode: "selfroll" }); const dateFuture = this.getDateFromIndex(index); ChatMessage.create({ whisper: ChatMessage.getWhisperRecipients("GM"), @@ -172,39 +175,34 @@ export class RdDCalendrier extends Application { if ( this.listeNombreAstral == undefined ) { this.listeNombreAstral = this._loadListNombreAstral(); } - let liste = this.listeNombreAstral; - if ( game.user.isGM ) { - if ( typeof(liste) != 'Array' || liste.length == 0 ) { - this.rebuildListeNombreAstral(); - liste = this.listeNombreAstral; - } - } + + let liste = this.listeNombreAstral || []; let astralData = liste.find((nombreAstral, i) => nombreAstral.index == indexDate); + return astralData?.nombreAstral; } /* -------------------------------------------- */ - async rebuildListeNombreAstral() { + async rebuildListeNombreAstral( raison = 'incjour') { if (game.user.isGM) { let jourCourant = this.getCurrentDayIndex(); - let jourFin = jourCourant + 12; let newList = []; - for (const na of this.listeNombreAstral) { - let index = na?.index; - if (index && index >= jourCourant && index < jourFin) { - newList[index - jourCourant] = na; - } - } for (let i = 0; i < 12; i++) { - if (newList[i] == undefined) { - newList[i] = await this.ajouterNombreAstral(jourCourant + i); + let dayIndex = jourCourant + i; + let na = this.listeNombreAstral.find( n => n.index == dayIndex); + if ( na ) { + newList[i] = duplicate(na); + } else { + newList[i] = await this.ajouterNombreAstral(dayIndex, raison == 'incjour' ); } } - this.listeNombreAstral = newList; + console.log("SAVE list", newList, jourCourant); game.settings.set("foundryvtt-reve-de-dragon", "liste-nombre-astral", this.listeNombreAstral); + this.listeNombreAstral = newList; } } + /* -------------------------------------------- */ async onCalendarButton(ev) { ev.preventDefault(); @@ -240,14 +238,8 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ incrementerJour() { - this.calendrier.jour += 1; - if (this.calendrier.jour >= RDD_JOUR_PAR_MOIS) { - this.calendrier.jour -= RDD_JOUR_PAR_MOIS; - if (this.calendrier.jour <= 0) - this.calendrier.jour = 0; - this.calendrier.moisRdD += 1; - // Reconstruire les nombres astraux - } + const index = this.getCurrentDayIndex() + 1; + this.calendrier = RdDCalendrier.getCalendrier(index); this.rebuildListeNombreAstral(); } @@ -260,7 +252,7 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async positionnerHeure(indexHeure) { if (indexHeure <= this.calendrier.heureRdD) { - await this.incrementerJour(); + this.incrementerJour(); } this.calendrier.heureRdD = indexHeure; this.calendrier.minutesRelative = 0; @@ -306,7 +298,8 @@ export class RdDCalendrier extends Application { let rollData = { caracValue: request.carac_vue, finalLevel: niveau, - showDice: false + showDice: false, + rollMode: "blindroll" }; await RdDResolutionTable.rollData(rollData); let nbAstral = this.getNombreAstral(request.date); @@ -334,8 +327,8 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ findHeure(heure) { - heure = Grammar.toLowerCaseNoAccent(heure); - let parHeureOuLabel = Object.values(heuresDef).filter(it => (it.heure+1) == heure || Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure); + heure = Grammar.toLowerCaseNoAccentNoSpace(heure); + let parHeureOuLabel = Object.values(heuresDef).filter(it => (it.heure + 1) == heure || Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure); if (parHeureOuLabel.length == 1) { return parHeureOuLabel[0]; } @@ -432,7 +425,7 @@ export class RdDCalendrier extends Application { this.calendrier.heureRdD = heuresList.findIndex(heure => heure === calendrierData.heureKey);; // Index dans heuresList game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier)); - await this.rebuildListeNombreAstral(); + await this.rebuildListeNombreAstral( 'reset' ); game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_sync_time", diff --git a/module/rdd-combat.js b/module/rdd-combat.js index cacc3dd1..3f67425d 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -911,7 +911,7 @@ export class RdDCombat { console.log("RdDCombat._onEchecTotal >>>", rollData); const arme = rollData.arme; - const avecArme = arme?.data.categorie_parade != 'sans-armes'; + const avecArme = arme && arme.data.categorie_parade != 'sans-armes'; const action = (rollData.attackerRoll ? (arme ? "la parade" : "l'esquive") : "l'attaque"); ChatUtility.createChatWithRollMode(this.defender.name, { content: `Maladresse à ${action}! ` + await RdDRollTables.getMaladresse({ arme: avecArme }) diff --git a/module/rdd-dice.js b/module/rdd-dice.js index 0b77bf57..ec3afc10 100644 --- a/module/rdd-dice.js +++ b/module/rdd-dice.js @@ -134,9 +134,7 @@ export class RdDDice { static async roll(formula, options = { showDice: false, rollMode: undefined }) { const roll = new Roll(formula); await roll.evaluate({ async: true }); - if (options.showDice) { - roll.showDice = options.showDice; - } + roll.showDice = options.showDice; await RdDDice.show(roll, options.rollMode ?? game.settings.get("core", "rollMode")); return roll; } diff --git a/module/rdd-main.js b/module/rdd-main.js index 0afcccbd..9cc02aa1 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -72,6 +72,7 @@ Hooks.once("init", async function () { name: "calendrier", scope: "world", config: false, + default: RdDCalendrier.getCalendrier(0), type: Object }); @@ -80,14 +81,16 @@ Hooks.once("init", async function () { name: "liste-nombre-astral", scope: "world", config: false, + default: [], type: Object }); /* -------------------------------------------- */ game.settings.register("foundryvtt-reve-de-dragon", "calendrier-pos", { name: "calendrierPos", - scope: "world", + scope: "client", config: false, + default: RdDCalendrier.createCalendrierPos(), type: Object }); diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js index 3367b6a2..2649d1fc 100644 --- a/module/rdd-resolution-table.js +++ b/module/rdd-resolution-table.js @@ -102,22 +102,23 @@ export class RdDResolutionTable { /* -------------------------------------------- */ static async rollData(rollData) { - rollData.rolled = await this.roll(rollData.caracValue, rollData.finalLevel, rollData.bonus, rollData.diviseurSignificative, rollData.showDice); + rollData.rolled = await this.roll(rollData.caracValue, rollData.finalLevel, rollData); return rollData; } /* -------------------------------------------- */ - static async roll(caracValue, finalLevel, bonus = undefined, diviseur = undefined, showDice = true) { + static async roll(caracValue, finalLevel, rollData = {}){ let chances = this.computeChances(caracValue, finalLevel); - this._updateChancesWithBonus(chances, bonus); - this._updateChancesFactor(chances, diviseur); - chances.showDice = showDice; + this._updateChancesWithBonus(chances, rollData.bonus); + this._updateChancesFactor(chances, rollData.diviseurSignificative); + chances.showDice = rollData.showDice; + chances.rollMode = rollData.rollMode; - let rolled = await this.rollChances(chances, diviseur); + let rolled = await this.rollChances(chances, rollData.diviseurSignificative); rolled.caracValue = caracValue; rolled.finalLevel = finalLevel; - rolled.bonus = bonus; - rolled.factorHtml = Misc.getFractionHtml(diviseur); + rolled.bonus = rollData.bonus; + rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative); rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll ); rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel; return rolled; @@ -163,7 +164,7 @@ export class RdDResolutionTable { /* -------------------------------------------- */ static async rollChances(chances, diviseur) { - chances.roll = await RdDDice.rollTotal("1d100", {showDice:chances.showDice}); + chances.roll = await RdDDice.rollTotal("1d100", chances); mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true }); return chances; } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index f41c37ad..1335b4af 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -285,7 +285,29 @@ export class RdDUtility { }); d.render(true); } - + + /* -------------------------------------------- */ + static async selectTypeOeuvre( actorSheet) { + let typeObjets = RdDItem.getTypesOeuvres(); + let options = `Selectionnez le type d'oeuvre'; + let d = new Dialog({ + title: "Créer un équipement", + content: options, + buttons: { + one: { + icon: '', + label: "Créer l'objet", + callback: () => this.creerObjet(actorSheet) + } + } + }); + d.render(true); + } + /* -------------------------------------------- */ static buildListOptions(min, max) { let options = "" @@ -866,6 +888,10 @@ export class RdDUtility { /*-------------------------------------------- */ static distribuerStress(stressValue, raison = 'Inconnu', nomJoueur = undefined) { if (game.user.isGM) { + if (stressValue == undefined){ + ui.notifications.warn("Pas de valeuir de stress à distribuer!"); + return; + } if (nomJoueur == undefined) { for (let actor of game.actors) { if (actor.hasPlayerOwner) { diff --git a/system.json b/system.json index c2e1b1ff..7811de3c 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "name": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", "description": "Rêve de Dragon RPG for FoundryVTT", - "version": "1.4.26", + "version": "1.4.33", "manifestPlusVersion": "1.0.0", "minimumCoreVersion": "0.8.0", "compatibleCoreVersion": "0.8.99", @@ -24,6 +24,9 @@ { "name": "Mandar" }, + { + "name": "Marafal" + }, { "name": "Fred" }, diff --git a/templates/chat-vente-item.html b/templates/chat-vente-item.html index 04ef2f24..c4774436 100644 --- a/templates/chat-vente-item.html +++ b/templates/chat-vente-item.html @@ -17,7 +17,7 @@ {{#if (gt tailleLot 1)}} Lots de: {{tailleLot}}
{{/if}} - {{#if prixLot}} + {{#if (ne prixLot 0)}} Prix {{#if (gt tailleLot 1)}}du lot {{else}}unitaire{{/if}}: {{prixLot}} Sols
{{/if}} @@ -31,6 +31,6 @@ data-quantiteNbLots="{{quantiteNbLots}}" data-quantiteIllimite="{{#if quantiteIllimite}}true{{else}}false{{/if}}" data-prixLot="{{prixLot}}"> - {{#if prixLot}}Acheter{{else}}Prendre{{/if}} + {{#if (eq prixLot 0)}}Prendre{{else}}Acheter{{/if}}