foundryvtt-reve-de-dragon/module/item.js

478 lines
16 KiB
JavaScript

import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { RdDUtility } from "./rdd-utility.js";
const typesObjetsEquipement = ["objet", "arme", "armure", "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 class RdDItem extends Item {
static getTypeObjetsEquipement() {
return typesObjetsEquipement;
}
static getTypesOeuvres() {
return typesObjetsOeuvres;
}
isConteneur() {
return Misc.data(this).type == 'conteneur';
}
isAlcool() {
const itemData = Misc.data(this);
return itemData.type == 'nourritureboisson' && itemData.data.boisson && itemData.data.alcoolise;
}
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;
}
getEnc() {
const itemData = Misc.data(this);
switch (itemData.type) {
case 'herbe':
return encBrin;
}
return itemData.data.encombrement
}
prepareDerivedData() {
super.prepareDerivedData();
if (this.isEquipement(this)) {
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.isEnchante = categorie.includes('enchante');
if (tplData.isEnchante) {
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 ((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';
}
if (options.warnIfNot) {
ui.notifications.warn(`Impossible d'utilise 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;
for (const [key, value] of Object.entries(tplData)) {
if (['quantite', 'encTotal', 'prixTotal'].includes(key)) continue;
if (value != otherTplData[key]) return false;
}
return true;
}
/* -------------------------------------------- */
async postItem() {
console.log(this);
let chatData = duplicate(Misc.data(this));
const properties = this[`_${chatData.type}ChatData`]();
chatData["properties"] = properties
if (this.actor){
chatData.actor = {id: this.actor.id };
}
//Check if the posted item should have availability/pay buttons
chatData.hasPrice = "cout" in chatData.data;
chatData.data.cout_deniers = 0;
let dialogResult = [-1, -1]; // dialogResult[0] = quantité, dialogResult[1] = prix
if (chatData.hasPrice) {
chatData.data.cout_deniers = Math.floor(chatData.data.cout * 100);
dialogResult = await new Promise((resolve, reject) => {
new Dialog({
content:
`<p>Modifier la quantité?</p>
<div class="form-group">
<label> Quantité</label>
<input name="quantity" type="text" value="1"/>
</div>
<p>Modifier la prix?</p>
<div class="form-group">
<label> Prix en Sols</label>
<input name="price" type="text" value="${chatData.data.cout}"/>
</div>
`,
title: "Quantité & Prix",
buttons: {
post: {
label: "Soumettre",
callback: (dlg) => {
resolve([Number(dlg.find('[name="quantity"]').val()), Number(dlg.find('[name="price"]').val())])
}
},
}
}).render(true)
})
}
let quantiteEnvoi = Math.min(dialogResult[0], chatData.data.quantite);
const prixTotal = dialogResult[1];
if (quantiteEnvoi > 0) {
if (this.isOwned) {
if (chatData.data.quantite == 0) {
quantiteEnvoi = -1
}
else if (quantiteEnvoi > chatData.data.quantite) {
quantiteEnvoi = chatData.data.quantite;
ui.notifications.notify(`Impossible de poster plus que ce que vous avez. La quantité à été réduite à ${quantiteEnvoi}.`)
}
if (quantiteEnvoi > 0) {
this.diminuerQuantite(quantiteEnvoi);
}
}
}
if (chatData.hasPrice) {
if (quantiteEnvoi > 0)
chatData.postQuantity = Number(quantiteEnvoi);
if (prixTotal >= 0) {
chatData.postPrice = prixTotal;
chatData.data.cout_deniers = Math.floor(prixTotal * 100); // Mise à jour cout en deniers
}
chatData.finalPrice = Number(chatData.postPrice) * Number(chatData.postQuantity);
chatData.data.cout_deniers_total = chatData.data.cout_deniers * Number(chatData.postQuantity);
chatData.data.quantite = chatData.postQuantity;
console.log("POST : ", chatData.finalPrice, chatData.data.cout_deniers_total, chatData.postQuantity);
}
// Don't post any image for the item (which would leave a large gap) if the default image is used
if (chatData.img.includes("/blank.png"))
chatData.img = null;
// 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);
ChatMessage.create(chatOptions)
});
}
static propertyIfDefined(name, val, condition) {
return condition ? [`<b>${name}</b>: ${val}`] : [];
}
/* -------------------------------------------- */
_objetChatData() {
const tplData = Misc.templateData(this);
let properties = [
`<b>Encombrement</b>: ${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),
[`<b>Qualité</b>: ${tplData.qualité}`],
[`<b>Encombrement</b>: ${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}`,
`<b>Points de Tâche</b>: ${tplData.points_de_tache}`,
`<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;
}
}