import { DialogItemVente } from "./dialog-item-vente.js"; import { Grammar } from "./grammar.js"; import { Misc } from "./misc.js"; import { RdDUtility } from "./rdd-utility.js"; const typesObjetsEquipement = ["objet", "arme", "armure", "gemme", "conteneur", "herbe", "ingredient", "livre", "potion", "munition", "nourritureboisson", "monnaie"] const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"] const encBrin = 0.00005;// un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc export const defaultItemImg = { competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", compcreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp", arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp", armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp", conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp", sort: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", herbe: "systems/foundryvtt-reve-de-dragon/icons/botanique/Endorlotte.webp", ingredient: "systems/foundryvtt-reve-de-dragon/icons/objets/sable_poudre.webp", livre: "systems/foundryvtt-reve-de-dragon/icons/objets/livre.webp", potion: "systems/foundryvtt-reve-de-dragon/icons/objets/liqueur_de_bagdol.webp", queue: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp", ombre: "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp", souffle: "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp", tete: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp", meditation: "systems/foundryvtt-reve-de-dragon/icons/meditations_ecrits/meditation_alchimie.webp", recettealchimique: "systems/foundryvtt-reve-de-dragon/icons/competence_alchimie.webp", chant: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp", danse: "systems/foundryvtt-reve-de-dragon/icons/arts/danse_0.webp", jeu: "systems/foundryvtt-reve-de-dragon/icons/arts/jeux_petasse.webp", recettecuisine: "systems/foundryvtt-reve-de-dragon/icons/arts/recette_cuisine_1.webp", musique: "systems/foundryvtt-reve-de-dragon/icons/arts/chant_0.webp", maladie: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/maladie.webp", poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp", oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp", nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp", signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp" } /* -------------------------------------------- */ export class RdDItem extends Item { constructor(data, context) { if (!data.img) { data.img = defaultItemImg[data.type]; } super(data, context); } static getTypeObjetsEquipement() { return typesObjetsEquipement } static getTypesOeuvres() { return typesObjetsOeuvres } isCompetence() { return Misc.data(this).type == 'competence'; } isConteneur() { return Misc.data(this).type == 'conteneur'; } isConteneurNonVide() { return this.isConteneur() && (Misc.templateData(this).contenu?.length ?? 0) > 0; } isConteneurVide() { return this.isConteneur() && (Misc.templateData(this).contenu?.length ?? 0) == 0; } isVideOuNonConteneur() { return !this.isConteneur() || (Misc.templateData(this).contenu?.length ?? 0) == 0; } isAlcool() { const itemData = Misc.data(this); return itemData.type == 'nourritureboisson' && itemData.data.boisson && itemData.data.alcoolise; } isHerbeAPotion() { const itemData = Misc.data(this); return itemData.type == 'herbe' && (itemData.data.categorie == 'Soin' || itemData.data.categorie == 'Repos'); } isPotion() { return Misc.data(this).type == 'potion'; } isEquipement() { return RdDItem.getTypeObjetsEquipement().includes(Misc.data(this).type); } isCristalAlchimique() { const itemData = Misc.data(this); return itemData.type == 'objet' && Grammar.toLowerCaseNoAccent(itemData.name) == 'cristal alchimique' && itemData.data.quantite > 0; } isMagique() { return Misc.templateData(this).magique; } getEncTotal() { const itemData = Misc.data(this); return Number(itemData.data.encombrement ?? 0) * Number(itemData.data.quantite ?? 1); } getEnc() { const itemData = Misc.data(this); switch (itemData.type) { case 'herbe': return encBrin; } return itemData.data.encombrement ?? 0; } prepareDerivedData() { super.prepareDerivedData(); if (this.isEquipement()) { this._calculsEquipement(); if (this.isPotion()) { this.prepareDataPotion() } const itemData = Misc.data(this); itemData.data.actionPrincipale = this.getActionPrincipale({ warnIfNot: false }); } } prepareDataPotion() { const tplData = Misc.templateData(this); const categorie = Grammar.toLowerCaseNoAccent(tplData.categorie); tplData.magique = categorie.includes('enchante'); if (tplData.magique) { if (categorie.includes('soin') || categorie.includes('repos')) { tplData.puissance = tplData.herbebonus * tplData.pr; } } } _calculsEquipement() { const tplData = Misc.templateData(this); const quantite = this.isConteneur() ? 1 : (tplData.quantite ?? 0); const enc = this.getEnc(); if (enc != undefined) { tplData.encTotal = Math.max(enc, 0) * quantite; } if (tplData.cout != undefined) { tplData.prixTotal = Math.max(tplData.cout, 0) * quantite; } } getActionPrincipale(options = { warnIfNot: true }) { const itemData = Misc.data(this); if (!this.isConteneur() && (itemData.data.quantite ?? 0) <= 0) { if (options.warnIfNot) { ui.notifications.warn(`Vous n'avez plus de ${itemData.name}.`); } return undefined; } switch (itemData.type) { case 'nourritureboisson': return itemData.data.boisson ? 'Boire' : 'Manger'; case 'potion': return 'Boire'; case 'livre': return 'Lire'; case 'conteneur': return 'Ouvrir'; } if (this.isHerbeAPotion()) { return 'Décoction'; } if (options.warnIfNot) { ui.notifications.warn(`Impossible d'utiliser un ${itemData.name}, aucune action associée définie.`); } return undefined; } async diminuerQuantite(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) { if (options.diminuerQuantite == false) return; await this.quantiteIncDec(-nombre, options); } async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) { const itemData = Misc.data(this); const quantite = Number(itemData.data.quantite ?? -1); if (quantite >= 0) { const reste = Math.max(quantite + Number(nombre), 0); if (reste == 0) { if (options.supprimerSiZero) { ui.notifications.notify(`${itemData.name} supprimé de votre équipement`); await this.delete(); } else { ui.notifications.notify(`Il ne vous reste plus de ${itemData.name}, vous pouvez le supprimer de votre équipement, ou trouver un moyen de vous en procurer.`); await this.update({ "data.quantite": 0 }); } } else { await this.update({ "data.quantite": reste }); } } } /* -------------------------------------------- */ // détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité isEquipementSimilaire(other) { const itemData = Misc.data(this); const otherData = Misc.data(other); const tplData = Misc.templateData(this); const otherTplData = Misc.templateData(other); if (!this.isEquipement()) return false; if (itemData.type != otherData.type) return false; if (itemData.name != otherData.name) return false; if (tplData.quantite == undefined) return false; const differences = Object.entries(tplData).filter(([key, value]) => !['quantite', 'encTotal', 'prixTotal', 'cout'].includes(key)) .filter(([key, value]) => value != otherTplData[key]); if (differences.length > 0) { let message = `Impossible de regrouper les ${itemData.type} ${itemData.name}: `; for (const [key, value] of differences) { message += `<br>${key}: ${value} vs ${otherTplData[key]}`; } ui.notifications.info(message) return false; } return true; } async proposerVente() { console.log(this); if (this.isConteneurNonVide()) { ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le donner ou le vendre`); return; } const dialog = await DialogItemVente.create(this, (vente) => this._onProposerVente(vente)) dialog.render(true); } async _onProposerVente(venteData) { 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}`) return; } } venteData.jsondata = JSON.stringify(venteData.item); console.log(venteData); let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', venteData); ChatMessage.create(RdDUtility.chatDataSetup(html)); } /* -------------------------------------------- */ getProprietes() { return this[`_${Misc.data(this).type}ChatData`](); } /* -------------------------------------------- */ async postItem(modeOverride) { console.log(this); let chatData = duplicate(Misc.data(this)); const properties = this.getProprietes(); chatData["properties"] = properties if (this.actor) { chatData.actor = { id: this.actor.id }; } // JSON object for easy creation chatData.jsondata = JSON.stringify( { compendium: "postedItem", payload: chatData, }); renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-item.html', chatData).then(html => { let chatOptions = RdDUtility.chatDataSetup(html, modeOverride); ChatMessage.create(chatOptions) }); } static propertyIfDefined(name, val, condition = (it) => true) { return condition ? [`<b>${name}</b>: ${val}`] : []; } /* -------------------------------------------- */ _objetChatData() { const tplData = Misc.templateData(this); let properties = [].concat( RdDItem.propertyIfDefined('Résistance', tplData.resistance, tplData.resistance), RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite), RdDItem.propertyIfDefined('Encombrement', tplData.encombrement), ); return properties; } /* -------------------------------------------- */ _nourritureboissonChatData() { const tplData = Misc.templateData(this); let properties = [].concat( RdDItem.propertyIfDefined('Sustentation', tplData.sust, tplData.sust > 0), RdDItem.propertyIfDefined('Désaltère', tplData.desaltere, tplData.boisson), RdDItem.propertyIfDefined('Force alcool', tplData.force, tplData.boisson && tplData.alcoolise), RdDItem.propertyIfDefined('Exotisme', tplData.exotisme, tplData.exotisme < 0), RdDItem.propertyIfDefined('Qualité', tplData.qualite, tplData.qualite), RdDItem.propertyIfDefined('Encombrement', tplData.encombrement), ); return properties; } /* -------------------------------------------- */ _armeChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Compétence</b>: ${tplData.competence}`, `<b>Dommages</b>: ${tplData.dommages}`, `<b>Force minimum</b>: ${tplData.force}`, `<b>Resistance</b>: ${tplData.resistance}`, `<b>Encombrement</b>: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _conteneurChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Capacité</b>: ${tplData.capacite} Enc.`, `<b>Encombrement</b>: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _munitionChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Encombrement</b>: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _armureChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Protection</b>: ${tplData.protection}`, `<b>Détérioration</b>: ${tplData.deterioration}`, `<b>Malus armure</b>: ${tplData.malus}`, `<b>Encombrement</b>: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _competenceChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Catégorie</b>: ${tplData.categorie}`, `<b>Niveau</b>: ${tplData.niveau}`, `<b>Caractéristique par défaut</b>: ${tplData.carac_defaut}`, `<b>XP</b>: ${tplData.xp}` ] return properties; } /* -------------------------------------------- */ _competencecreatureChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Catégorie</b>: ${tplData.categorie}`, `<b>Niveau</b>: ${tplData.niveau}`, `<b>Caractéristique</b>: ${tplData.carac_value}`, `<b>XP</b>: ${tplData.xp}` ] return properties; } /* -------------------------------------------- */ _sortChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Draconic</b>: ${tplData.draconic}`, `<b>Difficulté</b>: ${tplData.difficulte}`, `<b>Case TMR</b>: ${tplData.caseTMR}`, `<b>Points de Rêve</b>: ${tplData.ptreve}` ] return properties; } /* -------------------------------------------- */ _herbeChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Milieu</b>: ${tplData.milieu}`, `<b>Rareté</b>: ${tplData.rarete}`, `<b>Catégorie</b>: ${tplData.categorie}`, ] return properties; } /* -------------------------------------------- */ _ingredientChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Milieu</b>: ${tplData.milieu}`, `<b>Rareté</b>: ${tplData.rarete}`, `<b>Catégorie</b>: ${tplData.categorie}`, ] return properties; } /* -------------------------------------------- */ _tacheChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Caractéristique</b>: ${tplData.carac}`, `<b>Compétence</b>: ${tplData.competence}`, `<b>Périodicité</b>: ${tplData.periodicite}`, `<b>Fatigue</b>: ${tplData.fatigue}`, `<b>Difficulté</b>: ${tplData.difficulte}` ].concat([ tplData.cacher_points_de_tache ? [] :`<b>Points de Tâche</b>: ${tplData.points_de_tache}` ]).concat([ `<b>Points de Tâche atteints</b>: ${tplData.points_de_tache_courant}`] ); return properties; } /* -------------------------------------------- */ _livreChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Compétence</b>: ${tplData.competence}`, `<b>Auteur</b>: ${tplData.auteur}`, `<b>Difficulté</b>: ${tplData.difficulte}`, `<b>Points de Tâche</b>: ${tplData.points_de_tache}`, `<b>Encombrement</b>: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _potionChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Rareté</b>: ${tplData.rarete}`, `<b>Catégorie</b>: ${tplData.categorie}`, `<b>Encombrement</b>: ${tplData.encombrement}`, ] return properties; } /* -------------------------------------------- */ _queueChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Refoulement</b>: ${tplData.refoulement}` ] return properties; } /* -------------------------------------------- */ _ombreChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Refoulement</b>: ${tplData.refoulement}` ] return properties; } /* -------------------------------------------- */ _souffleChatData() { const tplData = Misc.templateData(this); let properties = []; return properties; } /* -------------------------------------------- */ _teteChatData() { const tplData = Misc.templateData(this); let properties = []; return properties; } /* -------------------------------------------- */ _tarotChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Concept</b>: ${tplData.concept}`, `<b>Aspect</b>: ${tplData.aspect}`, ] return properties; } /* -------------------------------------------- */ _nombreastralChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Valeur</b>: ${tplData.value}`, `<b>Jour</b>: ${tplData.jourlabel}`, ] return properties; } /* -------------------------------------------- */ _monnaieChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Valeur en Deniers</b>: ${tplData.valeur_deniers}`, `<b>Encombrement</b>: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _meditationChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Thème</b>: ${tplData.theme}`, `<b>Compétence</b>: ${tplData.competence}`, `<b>Support</b>: ${tplData.support}`, `<b>Heure</b>: ${tplData.heure}`, `<b>Purification</b>: ${tplData.purification}`, `<b>Vêture</b>: ${tplData.veture}`, `<b>Comportement</b>: ${tplData.comportement}`, `<b>Case TMR</b>: ${tplData.tmr}` ] return properties; } /* -------------------------------------------- */ _casetmrChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Coordonnée</b>: ${tplData.coord}`, `<b>Spécificité</b>: ${tplData.specific}` ] return properties; } /* -------------------------------------------- */ _maladieChatData() { const tplData = Misc.templateData(this); let properties if (tplData.identifie) { properties = [ `<b>Malignité</b>: ${tplData.malignite}`, `<b>Périodicité</b>: ${tplData.periodicite}`, `<b>Dommages</b>: ${tplData.dommages}` ] if (tplData.remedesconnus) { properties.push(`<b>Remedes</b>: ${tplData.remedes}`) } } else { properties = [ `<b>Inconnue</b>`] } return properties; } /* -------------------------------------------- */ _poisonChatData() { return this._maladieChatData(); } /* -------------------------------------------- */ _gemmeChatData() { const tplData = Misc.templateData(this); let properties = [ `<b>Pureté</b>: ${tplData.purete}`, `<b>Taille</b>: ${tplData.taille}`, `<b>Inertie</b>: ${tplData.inertie}`, `<b>Enchantabilité</b>: ${tplData.enchantabilite}`, `<b>Prix</b>: ${tplData.cout}`, ] return properties; } }