import { DialogItemVente } from "./dialog-item-vente.js"; import { Grammar } from "./grammar.js"; import { RdDHerbes } from "./rdd-herbes.js"; import { RdDUtility } from "./rdd-utility.js"; const typesObjetsEquipement = [ "arme", "armure", "conteneur", "gemme", "herbe", "ingredient", "livre", "monnaie", "munition", "nourritureboisson", "objet", "potion", ] const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"] const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve"] const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"] const typesObjetsEffet = ["possession", "poison", "maladie"] const typesObjetsCompetence = ["competence", "compcreature"] const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/ */ 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", sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", } /* -------------------------------------------- */ export class RdDItem extends Item { constructor(itemData, context) { if (!itemData.img) { itemData.img = defaultItemImg[itemData.type]; } super(itemData, context); } static getTypesObjetsEquipement() { return typesObjetsEquipement } static getTypesOeuvres() { return typesObjetsOeuvres } isCompetence() { return typesObjetsCompetence.includes(this.type) } isEquipement() { return typesObjetsEquipement.includes(this.type) } isOeuvre() { return typesObjetsOeuvres.includes(this.type) } isDraconique() { return typesObjetsDraconiques.includes(this.type) } isEffet() { return typesObjetsEffet.includes(this.type) } isConnaissance() { return typesObjetsConnaissance.includes(this.type) } isConteneur() { return this.type == 'conteneur'; } getItemGroup() { if (this.isEquipement()) return "equipement"; if (this.isOeuvre()) return "oeuvre"; if (this.isDraconique()) return "draconique"; if (this.isConnaissance()) return "connaissance"; if (this.isEffet()) return "effet"; if (this.isCompetence()) return "competence"; return "autres"; } isConteneurNonVide() { return this.isConteneur() && (this.system.contenu?.length ?? 0) > 0; } isConteneurVide() { return this.isConteneur() && (this.system.contenu?.length ?? 0) == 0; } isVideOuNonConteneur() { return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0; } isAlcool() { return this.type == 'nourritureboisson' && this.system.boisson && this.system.alcoolise; } isHerbeAPotion() { return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); } isPotion() { return this.type == 'potion'; } isCristalAlchimique() { return this.type == 'objet' && Grammar.toLowerCaseNoAccent(this.name) == 'cristal alchimique' && this.system.quantite > 0; } isMagique() { return this.system.magique } getQuantite() { return Math.round(this.isConteneur() ? 1 : (this.system.quantite ?? 0)) } getEncTotal() { return this.getEnc() * this.getQuantite(); } getEnc() { switch (this.type) { case 'herbe': return encBrin; case 'gemme': return encPepin * this.system.taille; } return Math.max(this.system.encombrement ?? 0, 0); } prixTotalDeniers() { return this.getQuantite() * this.valeurDeniers() } valeurDeniers() { return Math.max(Math.round(this.system.cout ? (this.system.cout * 100) : (this.system.valeur_deniers ?? 0)), 0) } prepareDerivedData() { super.prepareDerivedData(); if (this.isEquipement()) { this.system.encTotal = this.getEncTotal(); if (this.isPotion()) { this.prepareDataPotion() } this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false }); } } prepareDataPotion() { const categorie = Grammar.toLowerCaseNoAccent(this.system.categorie); this.system.magique = categorie.includes('enchante'); if (this.system.magique) { if (categorie.includes('soin') || categorie.includes('repos')) { // TODO: utiliser calculePointsRepos / calculePointsGuerison this.system.puissance = RdDHerbes.calculePuissancePotion(this); } } } getActionPrincipale(options = { warnIfNot: true }) { const warn = options.warnIfNot; switch (this.type) { case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn); case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn); case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn); case 'conteneur': return 'Ouvrir'; case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined; case 'queue': case 'ombre': return this.system.refoulement>0 ? 'Refouler' : undefined; } return undefined; } _actionOrWarnQuantiteZero(actionName, warn){ if ((this.system.quantite ?? 0) <= 0) { if (warn) { ui.notifications.warn(`Vous n'avez plus de ${this.name}.`); } return undefined; } else { return actionName; } } 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 quantite = Number(this.system.quantite ?? -1); if (quantite >= 0) { const reste = Math.max(quantite + Number(nombre), 0); if (reste == 0) { if (options.supprimerSiZero) { ui.notifications.notify(`${this.name} supprimé de votre équipement`); await this.delete(); } else { ui.notifications.notify(`Il ne vous reste plus de ${this.name}, vous pouvez le supprimer de votre équipement, ou trouver un moyen de vous en procurer.`); await this.update({ "system.quantite": 0 }); } } else { await this.update({ "system.quantite": reste }); } } } /* -------------------------------------------- */ // détermine si deux équipements sont similaires: de même type, et avec les même champs hormis la quantité messageEquipementDifferent(other) { if (!other || !this.isEquipement()) return undefined; let message = undefined; if (this.system.quantite == undefined) { message = `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`; } else if (this.type != other.type) { message = `Impossible de regrouper des ${this.type} avec des ${other.type}`; } else if (this.name != other.name) { message = `Impossible de regrouper ${this.name} avec ${other.name}`; } else { const differences = Object.entries(this.system) .filter(([key, value]) => !['quantite', 'cout'].includes(key) && value != other.system[key]); if (differences.length > 0) { message = `Impossible de regrouper les ${this.type} ${this.name}: `; for (const [key, value] of differences) { message += `
${key}: ${value} vs ${other.system[key]}`; } } } return message; } async proposerVente() { console.log(this); if (this.isConteneurNonVide()) { ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`); return; } await DialogItemVente.display(this, async (vente) => { vente["properties"] = this.getProprietes(); if (vente.isOwned) { if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) { ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`) return; } } vente.jsondata = JSON.stringify(vente.item); console.log(vente); let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente); ChatMessage.create(RdDUtility.chatDataSetup(html)); }); } /* -------------------------------------------- */ getProprietes() { return this[`_${this.type}ChatData`](); } /* -------------------------------------------- */ async postItem(modeOverride) { console.log(this); let chatData = duplicate(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 ? [`${name}: ${val}`] : []; } /* -------------------------------------------- */ _objetChatData() { const tplData = this.system 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 = this.system 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 = this.system let properties = [ `Compétence: ${tplData.competence}`, `Dommages: ${tplData.dommages}`, `Force minimum: ${tplData.force}`, `Resistance: ${tplData.resistance}`, `Encombrement: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _conteneurChatData() { const tplData = this.system let properties = [ `Capacité: ${tplData.capacite} Enc.`, `Encombrement: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _munitionChatData() { const tplData = this.system let properties = [ `Encombrement: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _armureChatData() { const tplData = this.system let properties = [ `Protection: ${tplData.protection}`, `Détérioration: ${tplData.deterioration}`, `Malus armure: ${tplData.malus}`, `Encombrement: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _competenceChatData() { const tplData = this.system let properties = [ `Catégorie: ${tplData.categorie}`, `Niveau: ${tplData.niveau}`, `Caractéristique par défaut: ${tplData.carac_defaut}`, `XP: ${tplData.xp}` ] return properties; } /* -------------------------------------------- */ _competencecreatureChatData() { const tplData = this.system let properties = [ `Catégorie: ${tplData.categorie}`, `Niveau: ${tplData.niveau}`, `Caractéristique: ${tplData.carac_value}`, `XP: ${tplData.xp}` ] return properties; } /* -------------------------------------------- */ _sortChatData() { const tplData = this.system let properties = [ `Draconic: ${tplData.draconic}`, `Difficulté: ${tplData.difficulte}`, `Case TMR: ${tplData.caseTMR}`, `Points de Rêve: ${tplData.ptreve}` ] return properties; } /* -------------------------------------------- */ _herbeChatData() { const tplData = this.system let properties = [ `Milieu: ${tplData.milieu}`, `Rareté: ${tplData.rarete}`, `Catégorie: ${tplData.categorie}`, ] return properties; } /* -------------------------------------------- */ _ingredientChatData() { const tplData = this.system let properties = [ `Milieu: ${tplData.milieu}`, `Rareté: ${tplData.rarete}`, `Catégorie: ${tplData.categorie}`, ] return properties; } /* -------------------------------------------- */ _tacheChatData() { const tplData = this.system let properties = [ `Caractéristique: ${tplData.carac}`, `Compétence: ${tplData.competence}`, `Périodicité: ${tplData.periodicite}`, `Fatigue: ${tplData.fatigue}`, `Difficulté: ${tplData.difficulte}` ].concat([ tplData.cacher_points_de_tache ? [] :`Points de Tâche: ${tplData.points_de_tache}` ]).concat([ `Points de Tâche atteints: ${tplData.points_de_tache_courant}`] ); return properties; } /* -------------------------------------------- */ _livreChatData() { const tplData = this.system let properties = [ `Compétence: ${tplData.competence}`, `Auteur: ${tplData.auteur}`, `Difficulté: ${tplData.difficulte}`, `Points de Tâche: ${tplData.points_de_tache}`, `Encombrement: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _potionChatData() { const tplData = this.system let properties = [ `Rareté: ${tplData.rarete}`, `Catégorie: ${tplData.categorie}`, `Encombrement: ${tplData.encombrement}`, ] return properties; } /* -------------------------------------------- */ _queueChatData() { const tplData = this.system let properties = [ `Refoulement: ${tplData.refoulement}` ] return properties; } /* -------------------------------------------- */ _ombreChatData() { const tplData = this.system let properties = [ `Refoulement: ${tplData.refoulement}` ] return properties; } /* -------------------------------------------- */ _souffleChatData() { const tplData = this.system let properties = []; return properties; } /* -------------------------------------------- */ _teteChatData() { const tplData = this.system let properties = []; return properties; } /* -------------------------------------------- */ _tarotChatData() { const tplData = this.system let properties = [ `Concept: ${tplData.concept}`, `Aspect: ${tplData.aspect}`, ] return properties; } /* -------------------------------------------- */ _nombreastralChatData() { const tplData = this.system let properties = [ `Valeur: ${tplData.value}`, `Jour: ${tplData.jourlabel}`, ] return properties; } /* -------------------------------------------- */ _monnaieChatData() { const tplData = this.system let properties = [ `Valeur en Deniers: ${tplData.valeur_deniers}`, `Encombrement: ${tplData.encombrement}` ] return properties; } /* -------------------------------------------- */ _meditationChatData() { const tplData = this.system let properties = [ `Thème: ${tplData.theme}`, `Compétence: ${tplData.competence}`, `Support: ${tplData.support}`, `Heure: ${tplData.heure}`, `Purification: ${tplData.purification}`, `Vêture: ${tplData.veture}`, `Comportement: ${tplData.comportement}`, `Case TMR: ${tplData.tmr}` ] return properties; } /* -------------------------------------------- */ _casetmrChatData() { const tplData = this.system let properties = [ `Coordonnée: ${tplData.coord}`, `Spécificité: ${tplData.specific}` ] return properties; } /* -------------------------------------------- */ _maladieChatData() { const tplData = this.system let properties if (tplData.identifie) { properties = [ `Malignité: ${tplData.malignite}`, `Périodicité: ${tplData.periodicite}`, `Dommages: ${tplData.dommages}` ] if (tplData.remedesconnus) { properties.push(`Remedes: ${tplData.remedes}`) } } else { properties = [ `Inconnue`] } return properties; } /* -------------------------------------------- */ _poisonChatData() { return this._maladieChatData(); } /* -------------------------------------------- */ _gemmeChatData() { const tplData = this.system let properties = [ `Pureté: ${tplData.purete}`, `Taille: ${tplData.taille}`, `Inertie: ${tplData.inertie}`, `Enchantabilité: ${tplData.enchantabilite}`, `Prix: ${tplData.cout}`, ] return properties; } }