diff --git a/icons/services/bacquet-eau.webp b/icons/services/bacquet-eau.webp new file mode 100644 index 00000000..a8546ed3 Binary files /dev/null and b/icons/services/bacquet-eau.webp differ diff --git a/icons/services/biere.webp b/icons/services/biere.webp new file mode 100644 index 00000000..cd1d443c Binary files /dev/null and b/icons/services/biere.webp differ diff --git a/icons/services/brandevin.webp b/icons/services/brandevin.webp new file mode 100644 index 00000000..dfc2ee44 Binary files /dev/null and b/icons/services/brandevin.webp differ diff --git a/icons/items/services.webp b/icons/services/commerce.webp similarity index 100% rename from icons/items/services.webp rename to icons/services/commerce.webp diff --git a/icons/services/compagnie.webp b/icons/services/compagnie.webp new file mode 100644 index 00000000..d6d89a95 Binary files /dev/null and b/icons/services/compagnie.webp differ diff --git a/icons/services/lit.webp b/icons/services/lit.webp new file mode 100644 index 00000000..9d3586d3 Binary files /dev/null and b/icons/services/lit.webp differ diff --git a/icons/services/paiement.webp b/icons/services/paiement.webp new file mode 100644 index 00000000..68d1f887 Binary files /dev/null and b/icons/services/paiement.webp differ diff --git a/icons/services/repas.webp b/icons/services/repas.webp new file mode 100644 index 00000000..d51e25a3 Binary files /dev/null and b/icons/services/repas.webp differ diff --git a/icons/services/verre.webp b/icons/services/verre.webp new file mode 100644 index 00000000..f05bf758 Binary files /dev/null and b/icons/services/verre.webp differ diff --git a/icons/services/vin.webp b/icons/services/vin.webp new file mode 100644 index 00000000..1e2d1ce8 Binary files /dev/null and b/icons/services/vin.webp differ diff --git a/lang/fr.json b/lang/fr.json index 36819273..f857f204 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -3,6 +3,7 @@ "TypePersonnage": "Personnage", "TypeCreature": "Créature", "TypeEntite": "Entité de cauchemar", + "TypeCommerce": "Commerce", "TypeVehicule": "Véhicule" }, "ITEM": { @@ -27,7 +28,7 @@ "TypeArmure": "Armure", "TypeConteneur": "Conteneur", "TypeNourritureboisson": "Nourriture & boisson", - "TypeService": "Services/Boutique", + "TypeService": "Service", "TypeChant": "Chant", "TypeDanse": "Danse", "TypeMusique": "Musique", diff --git a/module/actor-sheet.js b/module/actor-sheet.js index b735fda4..803ad71c 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -10,7 +10,6 @@ import { DialogSplitItem } from "./dialog-split-item.js"; import { ReglesOptionelles } from "./settings/regles-optionelles.js"; import { RdDSheetUtility } from "./rdd-sheet-utility.js"; import { STATUSES } from "./settings/status-effects.js"; -import { Monnaie } from "./item-monnaie.js"; import { MAINS_DIRECTRICES } from "./actor.js"; import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js"; import { RdDItem } from "./item.js"; @@ -46,10 +45,8 @@ export class RdDActorSheet extends RdDBaseActorSheet { effects: this.actor.effects.map(e => foundry.utils.deepClone(e)), limited: this.actor.limited, owner: this.actor.isOwner, - description: await TextEditor.enrichHTML(this.object.system.description, { async: true }), - biographie: await TextEditor.enrichHTML(this.object.system.biographie, { async: true }), - notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }), - notesmj: await TextEditor.enrichHTML(this.object.system.notesmj, { async: true }), + biographie: await TextEditor.enrichHTML(this.actor.system.biographie, { async: true }), + notes: await TextEditor.enrichHTML(this.actor.system.notes, { async: true }), }); mergeObject(formData.calc, { surenc: this.actor.computeMalusSurEncombrement(), diff --git a/module/actor.js b/module/actor.js index f532d894..dca482fb 100644 --- a/module/actor.js +++ b/module/actor.js @@ -13,7 +13,6 @@ import { RdDItemSort } from "./item-sort.js"; import { Grammar } from "./grammar.js"; import { RdDEncaisser } from "./rdd-roll-encaisser.js"; import { RdDCombat } from "./rdd-combat.js"; -import { RdDAudio } from "./rdd-audio.js"; import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemArme } from "./item-arme.js"; import { RdDAlchimie } from "./rdd-alchimie.js"; @@ -24,13 +23,11 @@ import { ReglesOptionelles } from "./settings/regles-optionelles.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"; import { DialogConsommer } from "./dialog-item-consommer.js"; import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js"; import { RollDataAjustements } from "./rolldata-ajustements.js"; -import { RdDItem } from "./item.js"; import { RdDPossession } from "./rdd-possession.js"; -import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; +import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { RdDConfirm } from "./rdd-confirm.js"; import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js"; import { RdDRencontre } from "./item-rencontre.js"; @@ -77,12 +74,12 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ _prepareCreatureData(actorData) { - this.computeEncombrementTotalEtMalusArmure(); + this.computeEncTotal(); } /* -------------------------------------------- */ _prepareVehiculeData(actorData) { - this.computeEncombrementTotalEtMalusArmure(); + this.computeEncTotal(); } /* -------------------------------------------- */ @@ -94,7 +91,8 @@ export class RdDActor extends RdDBaseActor { RdDCarac.computeCarac(actorData.system) this.computeIsHautRevant(); await this.cleanupConteneurs(); - await this.computeEncombrementTotalEtMalusArmure(); + await this.computeEncTotal(); + await this.computeMalusArmure(); } /* -------------------------------------------- */ @@ -234,10 +232,6 @@ export class RdDActor extends RdDBaseActor { } /* -------------------------------------------- */ - getMonnaie(id) { - return this.findItemLike(id, 'monnaie'); - } - getTache(id) { return this.findItemLike(id, 'tache'); } @@ -993,237 +987,7 @@ export class RdDActor extends RdDBaseActor { await this.update({ [`system.attributs.${fieldName}.value`]: fieldValue }); } - /* -------------------------------------------- */ - _isConteneurContenu(item, conteneur) { - if (item?.isConteneur()) { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant - for (let id of item.system.contenu) { - let subObjet = this.getItem(id); - if (subObjet?.id == conteneur.id) { - return true; // Loop detected ! - } - if (subObjet?.isConteneur()) { - return this._isConteneurContenu(subObjet, conteneur); - } - } - } - return false; - } - /* -------------------------------------------- */ - getRecursiveEnc(objet) { - if (!objet) { - return 0; - } - const tplData = objet.system; - if (objet.type != 'conteneur') { - return Number(tplData.encombrement) * Number(tplData.quantite); - } - const encContenus = tplData.contenu.map(idContenu => this.getRecursiveEnc(this.getItem(idContenu))); - return encContenus.reduce(Misc.sum(), 0) - + Number(tplData.encombrement) /* TODO? Number(tplData.quantite) -- on pourrait avoir plusieurs conteneurs...*/ - } - - /* -------------------------------------------- */ - buildSubConteneurObjetList(conteneurId, deleteList) { - let conteneur = this.getItem(conteneurId); - if (conteneur?.type == 'conteneur') { // Si c'est un conteneur - for (let subId of conteneur.system.contenu) { - let subObj = this.getItem(subId); - if (subObj) { - if (subObj.type == 'conteneur') { - this.buildSubConteneurObjetList(subId, deleteList); - } - deleteList.push({ id: subId, conteneurId: conteneurId }); - } - } - } - } - - /* -------------------------------------------- */ - async deleteAllConteneur(itemId, options) { - let list = []; - list.push({ id: itemId, conteneurId: undefined }); // Init list - this.buildSubConteneurObjetList(itemId, list); - await this.deleteEmbeddedDocuments('Item', list.map(it => it.id), options); - } - - /* -------------------------------------------- */ - /** Supprime un item d'un conteneur, sur la base - * de leurs ID */ - async enleverDeConteneur(item, conteneur, onEnleverDeConteneur) { - if (conteneur?.isConteneur()) { - item.estContenu = false; - await this.updateEmbeddedDocuments('Item', [{ - _id: conteneur.id, - 'system.contenu': conteneur.system.contenu.filter(id => id != item.id) - }]); - onEnleverDeConteneur(); - } - } - - /* -------------------------------------------- */ - /** Ajoute un item dans un conteneur, sur la base - * de leurs ID */ - async ajouterDansConteneur(item, conteneur, onAjouterDansConteneur) { - if (!conteneur) { - // TODO: afficher - item.estContenu = false; - } - else if (conteneur.isConteneur()) { - item.estContenu = true; - await this.updateEmbeddedDocuments('Item', [{ - _id: conteneur.id, - 'system.contenu': [...conteneur.system.contenu, item.id] - }]); - onAjouterDansConteneur(item.id, conteneur.id); - } - } - - /* -------------------------------------------- */ - /** Fonction de remise à plat de l'équipement (ie vide les champs 'contenu') */ - async nettoyerConteneurs() { - RdDConfirm.confirmer({ - settingConfirmer: "confirmation-vider", - content: `

Etes vous certain de vouloir vider tous les conteneurs ?

`, - title: 'Vider les conteneurs', - buttonLabel: 'Vider', - onAction: async () => { - const corrections = []; - for (let item of this.items) { - if (item.estContenu) { - item.estContenu = undefined; - } - if (item.type == 'conteneur' && item.system.contenu.length > 0) { - corrections.push({ _id: item.id, 'system.contenu': [] }); - } - } - if (corrections.length > 0) { - await this.updateEmbeddedDocuments('Item', corrections); - } - } - }); - } - - async processDropItem(params) { - const targetActorId = this.id; - const sourceActorId = params.sourceActorId; - const itemId = params.itemId; - const destId = params.destId; - const srcId = params.srcId; - if (sourceActorId && sourceActorId != targetActorId) { - console.log("Moving objects", sourceActorId, targetActorId, itemId); - this.moveItemsBetweenActors(itemId, sourceActorId); - return false; - } - let result = true; - const item = this.getItem(itemId); - if (item?.isInventaire() && sourceActorId == targetActorId) { - // rangement - if (srcId != destId && itemId != destId) { // déplacement de l'objet - const src = this.getItem(srcId); - const dest = this.getItem(destId); - const cible = this.getContenantOrParent(dest); - const [empilable, message] = item.isInventaireEmpilable(dest); - if (empilable) { - await dest.empiler(item) - result = false; - } - // changer de conteneur - else if (!cible || this.conteneurPeutContenir(cible, item)) { - await this.enleverDeConteneur(item, src, params.onEnleverConteneur); - await this.ajouterDansConteneur(item, cible, params.onAjouterDansConteneur); - if (message && !dest.isConteneur()) { - ui.notifications.info(cible - ? `${message}
${item.name} a été déplacé dans: ${cible.name}` - : `${message}
${item.name} a été sorti du conteneur`); - } - } - } - } - await this.computeEncombrementTotalEtMalusArmure(); - return result; - } - - getContenantOrParent(dest) { - if (!dest || dest.isConteneur()) { - return dest; - } - return this.getContenant(dest); - } - - getContenant(item) { - return this.itemTypes['conteneur'].find(it => it.system.contenu.includes(item.id)); - } - - /* -------------------------------------------- */ - conteneurPeutContenir(dest, item) { - if (!dest) { - return true; - } - if (!dest.isConteneur()) { - return false; - } - const destData = dest - if (this._isConteneurContenu(item, dest)) { - ui.notifications.warn(`Impossible de déplacer un conteneur parent (${item.name}) dans un de ses contenus ${destData.name} !`); - return false; // Loop detected ! - } - - // Calculer le total actuel des contenus - let encContenu = this.getRecursiveEnc(dest) - Number(destData.system.encombrement); - let newEnc = this.getRecursiveEnc(item); // Calculer le total actuel du nouvel objet - - // Teste si le conteneur de destination a suffisament de capacité pour recevoir le nouvel objet - if (Number(destData.system.capacite) < encContenu + newEnc) { - ui.notifications.warn( - `Le conteneur ${dest.name} a une capacité de ${destData.system.capacite}, et contient déjà ${encContenu}. - Impossible d'y ranger: ${item.name} d'encombrement ${newEnc}!`); - return false; - } - return true; - - } - - /* -------------------------------------------- */ - async moveItemsBetweenActors(itemId, sourceActorId) { - let itemsList = [] - let sourceActor = game.actors.get(sourceActorId); - itemsList.push({ id: itemId, conteneurId: undefined }); // Init list - sourceActor.buildSubConteneurObjetList(itemId, itemsList); // Get itemId list - - const itemsDataToCreate = itemsList.map(it => sourceActor.getItem(it.id)) - .map(it => duplicate(it)) - .map(it => { it.system.contenu = []; return it; }); - let newItems = await this.createEmbeddedDocuments('Item', itemsDataToCreate); - - let itemMap = this._buildMapOldNewId(itemsList, newItems); - - 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 - let newConteneurId = itemMap[item.conteneurId]; // Get conteneur - let newConteneur = this.getItem(newConteneurId); - - let newItemId = itemMap[item.id]; // Get newItem - - console.log('New conteneur filling!', newConteneur, newItemId, item); - let contenu = duplicate(newConteneur.system.contenu); - contenu.push(newItemId); - await this.updateEmbeddedDocuments('Item', [{ _id: newConteneurId, 'system.contenu': contenu }]); - } - } - for (let item of itemsList) { - await sourceActor.deleteEmbeddedDocuments('Item', [item.id]); - } - } - - _buildMapOldNewId(itemsList, newItems) { - let itemMap = {}; - for (let i = 0; i < itemsList.length; i++) { - itemMap[itemsList[i].id] = newItems[i].id; // Pour garder le lien ancien / nouveau - } - return itemMap; - } isSurenc() { return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false @@ -1268,16 +1032,6 @@ export class RdDActor extends RdDBaseActor { return this.listItems(type).find(it => Grammar.toLowerCaseNoAccent(it.name) == name); } - /* -------------------------------------------- */ - async computeEncombrementTotalEtMalusArmure() { - if (!this.pack) { - await this.computeMalusArmure(); - this.encTotal = this.items.map(it => it.getEncTotal()).reduce(Misc.sum(), 0); - return this.encTotal; - } - return 0; - } - /* -------------------------------------------- */ async computeMalusArmure() { if (this.isPersonnage()) { @@ -1291,15 +1045,6 @@ export class RdDActor extends RdDBaseActor { } } - /* -------------------------------------------- */ - computePrixTotalEquipement() { - const valeur = this.items.filter(it => it.isInventaire()) - .filter(it => !it.isMonnaie()) - .map(it => it.valeurTotale()) - .reduce(Misc.sum(), 0); - return valeur; - } - /* -------------------------------------------- */ computeResumeBlessure(blessures = undefined) { blessures = blessures ?? this.system.blessures; @@ -1332,7 +1077,7 @@ export class RdDActor extends RdDBaseActor { } } - recompute(){ + recompute() { this.computeEtatGeneral(); } @@ -3282,7 +3027,7 @@ export class RdDActor extends RdDBaseActor { if (item && ['arme', 'armure'].includes(item.type)) { const isEquipe = !item.system.equipe; await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]); - this.computeEncombrementTotalEtMalusArmure(); // Mise à jour encombrement + this.computeEncTotal(); // Mise à jour encombrement if (isEquipe) this.verifierForceMin(item); } @@ -3575,190 +3320,6 @@ export class RdDActor extends RdDBaseActor { return; } - /* -------------------------------------------- */ - async payerSols(depense) { - depense = Number(depense); - if (depense == 0) { - return; - } - let fortune = super.getFortune(); - console.log("payer", game.user.character, depense, fortune); - let msg = ""; - if (fortune >= depense) { - await Monnaie.optimiserFortune(this, fortune - depense); - msg = `Vous avez payé ${depense} Sols, qui ont été soustraits de votre argent.`; - RdDAudio.PlayContextAudio("argent"); // Petit son - } else { - msg = "Vous n'avez pas assez d'argent pour payer cette somme !"; - } - - let message = { - whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: msg - }; - ChatMessage.create(message); - } - - async depenserSols(sols) { - let reste = super.getFortune() - Number(sols); - if (reste >= 0) { - await Monnaie.optimiserFortune(this, reste); - } - return reste; - } - - async ajouterSols(sols, fromActorId = undefined) { - sols = Number(sols); - if (sols == 0) { - return; - } - if (sols < 0) { - ui.notifications.error(`Impossible d'ajouter un gain de ${sols} <0`); - return; - } - if (fromActorId && !game.user.isGM) { - RdDBaseActor.remoteActorCall({ - userId: Misc.connectedGMOrUser(), - actorId: this.id, - method: 'ajouterSols', args: [sols, fromActorId] - }); - } - else { - const fromActor = game.actors.get(fromActorId) - await Monnaie.optimiserFortune(this, sols + this.getFortune()); - - RdDAudio.PlayContextAudio("argent"); // Petit son - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: `Vous avez reçu ${sols} Sols ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.` - }); - } - } - - /* -------------------------------------------- */ - async monnaieIncDec(id, value) { - let monnaie = this.getMonnaie(id); - if (monnaie) { - const quantite = Math.max(0, monnaie.system.quantite + value); - await this.updateEmbeddedDocuments('Item', [{ _id: monnaie.id, 'system.quantite': quantite }]); - } - } - - /* -------------------------------------------- */ - async achatVente(achat) { - if (achat.vendeurId == achat.acheteurId) { - ui.notifications.info("Inutile de se vendre à soi-même"); - return; - } - if (!Misc.isUniqueConnectedGM()) { - RdDBaseActor.remoteActorCall({ - actorId: achat.vendeurId ?? achat.acheteurId, - method: 'achatVente', - args: [achat] - }); - return; - } - - const cout = Number(achat.prixTotal ?? 0); - const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined; - const service = achat.serviceId ? (vendeur?.getItem(achat.serviceId) ?? game.items.get(achat.serviceId)) : undefined; - const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined; - const vente = achat.vente; - const quantite = (achat.choix.nombreLots ?? 1) * (vente.tailleLot); - const itemVendu = vendeur?.getItem(vente.item._id) ?? (await RdDItem.getCorrespondingItem(vente.item)); - if (!this.verifierQuantite(service, vente.serviceSubItem, vendeur, itemVendu, quantite)) { - ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`); - return - } - - if ((acheteur?.getFortune() ?? 0) < Number(cout)) { - ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`); - return; - } - await this.decrementerVente(service, vendeur, itemVendu, quantite, cout); - if (acheteur) { - await acheteur.depenserSols(cout); - let createdItemId = await acheteur.creerQuantiteItem(vente.item, quantite); - await acheteur.consommerNourritureAchetee(achat, vente, createdItemId); - } - if (cout > 0) { - RdDAudio.PlayContextAudio("argent"); - } - const chatAchatItem = duplicate(vente); - chatAchatItem.quantiteTotal = quantite; - ChatMessage.create({ - user: achat.userId, - speaker: { alias: (acheteur ?? vendeur).name }, - whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-achat-item.html', chatAchatItem) - }); - - if (!vente.quantiteIllimite) { - if (vente.quantiteNbLots <= achat.choix.nombreLots) { - ChatUtility.removeChatMessageId(achat.chatMessageIdVente); - } - else if (!service) { - vente["properties"] = itemVendu.getProprietes(); - vente.quantiteNbLots -= achat.choix.nombreLots; - vente.jsondata = JSON.stringify(vente.item); - const messageVente = game.messages.get(achat.chatMessageIdVente); - messageVente.update({ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente) }); - messageVente.render(true); - } - } - } - - async decrementerVente(service, vendeur, itemVendu, quantite, cout) { - if (service) { - await service.venteRefItem(itemVendu, quantite, cout) - } - else if (vendeur) { - await vendeur.ajouterSols(cout); - await vendeur.decrementerQuantiteItem(itemVendu, quantite); - } - } - - verifierQuantite(service, serviceSubItem, vendeur, item, quantiteTotal) { - const disponible = service ? service.getQuantiteDisponible(serviceSubItem, quantiteTotal) : (vendeur ? (item?.getQuantite() ?? 0) : quantiteTotal); - return disponible >= quantiteTotal; - } - - async consommerNourritureAchetee(achat, vente, createdItemId) { - if (achat.choix.consommer && vente.item.type == 'nourritureboisson' && createdItemId != undefined) { - achat.choix.doses = achat.choix.nombreLots; - await this.consommerNourritureboisson(createdItemId, achat.choix, vente.actingUserId); - } - } - - async decrementerQuantiteItem(item, quantite) { - let resteQuantite = (item.system.quantite ?? 1) - quantite; - if (resteQuantite <= 0) { - await this.deleteEmbeddedDocuments("Item", [item.id]); - if (resteQuantite < 0) { - ui.notifications.warn(`La quantité de ${item.name} était insuffisante, l'objet a donc été supprimé`) - } - } - else if (resteQuantite > 0) { - await this.updateEmbeddedDocuments("Item", [{ _id: item.id, 'system.quantite': resteQuantite }]); - } - } - - async creerQuantiteItem(item, quantite) { - const items = await this.createEmbeddedDocuments("Item", RdDActor.$prepareListeAchat(item, quantite)); - return items.length > 0 ? items[0].id : undefined; - } - - static $prepareListeAchat(item, quantite) { - const isItemEmpilable = "quantite" in item.system; - const achatData = { - type: item.type, - img: item.img, - name: item.name, - system: mergeObject(item.system, { quantite: isItemEmpilable ? quantite : undefined }), - }; - return isItemEmpilable ? [achatData] : Array.from({ length: quantite }, (_, i) => achatData); - } - /* -------------------------------------------- */ async effectuerTacheAlchimie(recetteId, tacheAlchimie, texteTache) { let recetteData = this.findItemLike(recetteId, 'recettealchimique'); diff --git a/module/actor/base-actor-sheet.js b/module/actor/base-actor-sheet.js index 98cd8650..6cfc9e7e 100644 --- a/module/actor/base-actor-sheet.js +++ b/module/actor/base-actor-sheet.js @@ -40,6 +40,7 @@ export class RdDBaseActorSheet extends ActorSheet { isLimited: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED, isObserver: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER, isOwner: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER, + owner: this.actor.isOwner, }); let formData = { @@ -49,13 +50,15 @@ export class RdDBaseActorSheet extends ActorSheet { img: this.actor.img, name: this.actor.name, system: foundry.utils.deepClone(this.actor.system), + description: await TextEditor.enrichHTML(this.actor.system.description, { async: true }), + notesmj: await TextEditor.enrichHTML(this.actor.system.notesmj, { async: true }), options: options, } this.filterItemsPerTypeForSheet(formData, this.actor.itemTypes); formData.calc = { fortune: this.toSolsDeniers(this.actor.getFortune()), prixTotalEquipement: this.actor.computePrixTotalEquipement(), - encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(), + encTotal: await this.actor.computeEncTotal(), } this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets); @@ -74,7 +77,6 @@ export class RdDBaseActorSheet extends ActorSheet { /* -------------------------------------------- */ filterItemsPerTypeForSheet(formData, itemTypes) { - formData.services = Misc.arrayOrEmpty(itemTypes['service']); formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']); formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']); formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']); @@ -100,9 +102,8 @@ export class RdDBaseActorSheet extends ActorSheet { formData.oeuvres = Misc.arrayOrEmpty(itemTypes['oeuvre']); formData.jeux = Misc.arrayOrEmpty(itemTypes['jeu']); - + formData.services = Misc.arrayOrEmpty(itemTypes['service']); formData.conteneurs = Misc.arrayOrEmpty(itemTypes['conteneur']); - formData.materiel = Misc.arrayOrEmpty(itemTypes['objet']); formData.armes = Misc.arrayOrEmpty(itemTypes['arme']); formData.armures = Misc.arrayOrEmpty(itemTypes['armure']); @@ -114,22 +115,12 @@ export class RdDBaseActorSheet extends ActorSheet { formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']); formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']); formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']); - formData.monnaie = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere()); - formData.objets = formData.conteneurs - .concat(formData.materiel) - .concat(formData.armes) - .concat(formData.armures) - .concat(formData.munitions) - .concat(formData.livres) - .concat(formData.potions) - .concat(formData.ingredients) - .concat(formData.herbes) - .concat(formData.faunes) - .concat(formData.monnaie) - .concat(formData.nourritureboissons) - .concat(formData.gemmes); + formData.objets = RdDItem.getItemTypesInventaire('all') + .map(t => Misc.arrayOrEmpty(itemTypes[t])) + .reduce((a, b) => a.concat(b), []) + .sort(Misc.ascending(it => it.name)); } /* -------------------------------------------- */ /** @override */ @@ -138,22 +129,22 @@ export class RdDBaseActorSheet extends ActorSheet { this.html = html; this.html.find('.conteneur-name a').click(async event => { - RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event)); + RdDUtility.toggleAfficheContenu(this.getItemId(event)); this.render(true); }); - this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)) - this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat()); + this.html.find('.item-edit').click(async event => this.getItem(event)?.sheet.render(true)) + this.html.find('.item-montrer').click(async event => this.getItem(event)?.postItemToChat()); this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat()); // Everything below here is only needed if the sheet is editable if (!this.options.editable) return; this.html.find('.item-split').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); + const item = this.getItem(event); RdDSheetUtility.splitItem(item, this.actor); }); - this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, RdDSheetUtility.getItem(event, this.actor))); - this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); + this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, this.getItem(event))); + this.html.find('.item-vendre').click(async event => this.vendre(this.getItem(event))); this.html.find('.creer-un-objet').click(async event => { this.selectObjetTypeToCreate(); @@ -162,15 +153,21 @@ export class RdDBaseActorSheet extends ActorSheet { this.actor.nettoyerConteneurs(); }); this.html.find('.monnaie-plus').click(async event => { - this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), 1); + this.actor.monnaieIncDec(this.getItemId(event), 1); }); this.html.find('.monnaie-moins').click(async event => { - this.actor.monnaieIncDec(RdDSheetUtility.getItemId(event), -1); + this.actor.monnaieIncDec(this.getItemId(event), -1); }); - } - + getItemId(event) { + return RdDSheetUtility.getItemId(event); + } + + getItem(event) { + return RdDSheetUtility.getItem(event, this.actor); + } + /* -------------------------------------------- */ _getHeaderButtons() { let buttons = super._getHeaderButtons(); @@ -185,7 +182,7 @@ export class RdDBaseActorSheet extends ActorSheet { /* -------------------------------------------- */ async _onDropItem(event, dragData) { const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id') - const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur) + const dropParams = await RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur) if (dropParams) { const callSuper = await this.actor.processDropItem(dropParams) if (callSuper) { @@ -194,10 +191,9 @@ export class RdDBaseActorSheet extends ActorSheet { } } - /* -------------------------------------------- */ async selectObjetTypeToCreate() { - let typeObjets = RdDItem.getItemTypesInventaire(); + let typeObjets = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type))); let content = `Selectionnez le type d'équipement + - +
  • diff --git a/templates/actor/commerce-actor-sheet.html b/templates/actor/commerce-actor-sheet.html new file mode 100644 index 00000000..4792bbe7 --- /dev/null +++ b/templates/actor/commerce-actor-sheet.html @@ -0,0 +1,79 @@ +
    + + {{!-- Sheet Header --}} +
    +
    +
    + +
    +

    + {{#if @root.options.isObserver}} +
    + + +
    +
    + + + + +
    + {{/if}} +
    +
    +
    +
    + + {{!-- Sheet Body --}} +
    +
    + {{editor description target="system.description" button=true owner=options.owner editable=options.isOwner engine="prosemirror"}} +
    +
    + {{> "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.html"}} + {{#unless system.illimite}} + {{#if @root.options.isObserver}} +
    + {{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html"}} + {{/if}} + {{/unless}} + {{!-- +
    +
    +
      +
    • + + + + + +
    • + {{#each system.services as |service key|}} +
    • + + + + +
      + + {{#unless @root.disabled}} + + + {{/unless}} +
      +
    • + {{/each}} +
    +
    + --}} +
    + {{> "systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html"}} +
    +
    +
    \ No newline at end of file diff --git a/templates/actor/commerce-inventaire-item.html b/templates/actor/commerce-inventaire-item.html new file mode 100644 index 00000000..313b4ef4 --- /dev/null +++ b/templates/actor/commerce-inventaire-item.html @@ -0,0 +1,64 @@ +{{#if (ne item.type 'monnaie')}} +
  • + + + {{#if (eq item.type 'conteneur')}} + + {{/if}} + + {{item.name}} + + + {{log 'item-inventaire' this}} + {{#unless item.parent.system.illimite}} + + {{#unless (or (eq item.type 'service') (and (eq item.type 'conteneur') (not vide)))}} + {{#if options.isOwner}} + + {{/if}} + + {{#if options.isOwner}} + + {{/if}} + {{/unless}} + + {{/unless}} + + {{#unless (and (eq item.type 'conteneur') (not vide))}} + + {{/unless}} + + + {{#if options.isOwner}} + {{#if (and (eq item.type 'conteneur') (not vide))}} + + {{else}} + + + {{#if (or item.parent.system.illimite (ne item.system.quantite 0))}} + + {{/if}} + {{#if (gt item.system.quantite 0)}} + + {{/if}} + {{/if}} + {{else}} + {{#if (or item.parent.system.illimite (gt item.system.quantite 0))}} + + {{/if}} + {{/if}} + + +
  • +{{/if}} diff --git a/templates/actor/commerce-inventaire.html b/templates/actor/commerce-inventaire.html new file mode 100644 index 00000000..934560f8 --- /dev/null +++ b/templates/actor/commerce-inventaire.html @@ -0,0 +1,36 @@ +

    Boutique

    + + {{#if options.isGM}} + Nouvel objet + Tout vider + {{/if}} + + {{#unless system.illimite}} + {{#if calc.surEncombrementMessage}}{{calc.surEncombrementMessage}} ‐{{/if}} + Encombrement: {{numberFormat calc.encTotal decimals=2}} + {{#if (regle-optionnelle 'afficher-prix-joueurs')}} + ‐ Valeur: {{numberFormat calc.prixTotalEquipement decimals=2}} Sols + {{/if}} + {{/unless}} + + diff --git a/templates/actor/inventaire.html b/templates/actor/inventaire.html index 1456e8fe..c080c069 100644 --- a/templates/actor/inventaire.html +++ b/templates/actor/inventaire.html @@ -20,11 +20,11 @@ {{#each objets as |item id|}} {{#unless item.estContenu}} {{#if (ne item.type 'conteneur')}} - {{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html" item=item vide=true ouvert=true }} + {{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html" item=item vide=true ouvert=true options=@root.options}} {{/if}} {{/unless}} {{/each}} {{#each conteneurs as |conteneur id|}} - {{buildConteneur this}} + {{buildConteneur this 'actor/inventaire-item.html' @root.options}} {{/each}} diff --git a/templates/chat-vente-item.html b/templates/chat-vente-item.html index 4bfb7e23..ad5afd1d 100644 --- a/templates/chat-vente-item.html +++ b/templates/chat-vente-item.html @@ -19,7 +19,7 @@ {{/if}} {{#if (ne prixLot 0)}} Prix {{#if (gt tailleLot 1)}}du lot {{else}}unitaire{{/if}}: - {{prixLot}} Sols
    + {{numberFormat prixLot decimals=2 sign=false}} Sols
    {{/if}}

    {{#if (or (gt quantiteNbLots 0) quantiteIllimite)}} diff --git a/templates/dialog-item-achat.html b/templates/dialog-item-achat.html index 6bdff205..f6ecffb2 100644 --- a/templates/dialog-item-achat.html +++ b/templates/dialog-item-achat.html @@ -2,9 +2,7 @@
    - {{#if service}} - {{service.name}} - {{else if vendeur}} + {{#if vendeur}} {{vendeur.name}} {{else}} Vendeur MJ @@ -85,12 +83,12 @@ {{#if isVente}}
    - +
    - {{prixTotal}} + {{numberFormat prixTotal decimals=2 sign=false}} Sols
    diff --git a/templates/dialog-item-vente.html b/templates/dialog-item-vente.html index 4a0f1051..52d78e42 100644 --- a/templates/dialog-item-vente.html +++ b/templates/dialog-item-vente.html @@ -26,13 +26,13 @@ max="{{quantiteMax}}" value="{{tailleLot}}" data-dtype="Number" />
    - - + +
    - diff --git a/templates/item-service-sheet.html b/templates/item-service-sheet.html index 534fdd76..bcb7de4f 100644 --- a/templates/item-service-sheet.html +++ b/templates/item-service-sheet.html @@ -2,102 +2,23 @@ {{>"systems/foundryvtt-reve-de-dragon/templates/header-item.html"}}
    -
    - {{editor description target="system.description" button=true owner=owner editable=(or isGM isOwner) engine="prosemirror"}} -
    - {{!-- -
    -
      -
    • - - - - - -
    • - {{#each system.services as |service key|}} -
    • - - - - -
      - - {{#unless @root.disabled}} - - - {{/unless}} -
      -
    • - {{/each}} -
    -
    -
    - --}}
    - - Quantité en vente illimitée + Jet de moral en situation heureuse +
    -
    -
      -
    • - - {{#unless system.illimite}} - - {{/unless}} - -
      - {{#unless disabled}} - - - - {{/unless}} -
      -
    • - {{#each system.items as |item key|}} -
    • - - {{#unless @root.system.illimite}} - - {{#unless @root.disabled}} - - {{/unless}} - - {{#unless @root.disabled}} - - {{/unless}} - - {{/unless}} - - - -
      - - {{#unless @root.disabled}} - - - {{/unless}} -
      -
    • - {{/each}} -
    + +
    + +
    - {{#if isGM}} -
    -
    - -
    - {{editor descriptionmj target="system.descriptionmj" button=true owner=owner editable=true engine="prosemirror"}} -
    + +
    + +
    - {{/if}} + + {{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}
    diff --git a/templates/settings/system-compendiums.html b/templates/settings/system-compendiums.html index 089c6fb5..74e85cd3 100644 --- a/templates/settings/system-compendiums.html +++ b/templates/settings/system-compendiums.html @@ -1,6 +1,4 @@
    - {{log 'systemCompendiums'systemCompendiums}} - {{log 'availableCompendiums' availableCompendiums}}
      {{#each systemCompendiums as |definition key|}}