Vincent Vandemeulebrouck
40987149cc
Le contexte des constructeurs est partagé entre Actor et Items, il faut donc enlever l'indicateur qui sert au choix de la bonne classe dérivée, sans quoi certains objets/acteurs peuvent être créés en utilisant le type de base, ce qui empêche d'ouvrir certains items d'acteurs après avoir redémarré le monde Par exemple, après ajout d'une blessure et redémarrage, il était impossible de réouvrir la feuille du personnage blessé.
909 lines
31 KiB
JavaScript
909 lines
31 KiB
JavaScript
import { DialogItemVente } from "./achat-vente/dialog-item-vente.js";
|
|
import { Grammar } from "./grammar.js";
|
|
import { Misc } from "./misc.js";
|
|
import { RdDHerbes } from "./rdd-herbes.js";
|
|
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
|
import { RdDUtility } from "./rdd-utility.js";
|
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
|
import { RdDRaretes } from "./item/raretes.js";
|
|
import { RdDItemCompetence } from "./item-competence.js";
|
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
|
|
|
export const TYPES = {
|
|
competence: 'competence',
|
|
competencecreature: 'competencecreature',
|
|
empoignade: 'empoignade',
|
|
possession: 'possession',
|
|
blessure: 'blessure',
|
|
maladie: 'maladie',
|
|
poison: 'poison',
|
|
arme: 'arme',
|
|
armure: 'armure',
|
|
conteneur: 'conteneur',
|
|
objet: 'objet',
|
|
monnaie: 'monnaie',
|
|
gemme: 'gemme',
|
|
munition: 'munition',
|
|
nourritureboisson: 'nourritureboisson',
|
|
herbe: 'herbe',
|
|
plante: 'plante',
|
|
ingredient: 'ingredient',
|
|
faune: 'faune',
|
|
livre: 'livre',
|
|
potion: 'potion',
|
|
service: 'service',
|
|
musique: 'musique',
|
|
danse: 'danse',
|
|
chant: 'chant',
|
|
jeu: 'jeu',
|
|
recettecuisine: 'recettecuisine',
|
|
oeuvre: 'oeuvre',
|
|
recettealchimique: 'recettealchimique',
|
|
tache: 'tache',
|
|
sort: 'sort',
|
|
sortreserve: 'sortreserve',
|
|
rencontre: 'rencontre',
|
|
queue: 'queue',
|
|
ombre: 'ombre',
|
|
souffle: 'souffle',
|
|
tete: 'tete',
|
|
casetmr: 'casetmr',
|
|
meditation: 'meditation',
|
|
signedraconique: 'signedraconique',
|
|
tarot: 'tarot',
|
|
nombreastral: 'nombreastral',
|
|
extraitpoetique: 'extraitpoetique',
|
|
}
|
|
|
|
const typesInventaireMateriel = [
|
|
TYPES.arme,
|
|
TYPES.armure,
|
|
TYPES.conteneur,
|
|
TYPES.faune,
|
|
TYPES.gemme,
|
|
TYPES.herbe,
|
|
TYPES.plante,
|
|
TYPES.ingredient,
|
|
TYPES.livre,
|
|
TYPES.monnaie,
|
|
TYPES.munition,
|
|
TYPES.nourritureboisson,
|
|
TYPES.objet,
|
|
TYPES.potion,
|
|
]
|
|
const typesInventaire = {
|
|
materiel: typesInventaireMateriel,
|
|
all: ['service'].concat(typesInventaireMateriel),
|
|
}
|
|
|
|
const typesObjetsOeuvres = [TYPES.oeuvre, TYPES.recettecuisine, TYPES.musique, TYPES.chant, TYPES.danse, TYPES.jeu]
|
|
const typesObjetsDraconiques = [TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.tete, TYPES.signedraconique, TYPES.sortreserve, TYPES.rencontre]
|
|
const typesObjetsConnaissance = [TYPES.meditation, TYPES.recettealchimique, TYPES.sort]
|
|
const typesObjetsEffet = [TYPES.possession, TYPES.poison, TYPES.maladie, TYPES.blessure]
|
|
const typesObjetsCompetence = [TYPES.competence, TYPES.competencecreature]
|
|
const typesObjetsTemporels = [TYPES.blessure, TYPES.poison, TYPES.maladie, TYPES.queue, TYPES.ombre, TYPES.souffle, TYPES.signedraconique, TYPES.rencontre]
|
|
const typesObjetsEquipable = [TYPES.arme, TYPES.armure, TYPES.objet];
|
|
const typesEnvironnement = typesInventaireMateriel;
|
|
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",
|
|
competencecreature: "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",
|
|
faune: "systems/foundryvtt-reve-de-dragon/icons/faune/rongeur.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",
|
|
rencontre: "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.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",
|
|
service: "systems/foundryvtt-reve-de-dragon/icons/services/lit.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",
|
|
extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp",
|
|
tarot: "systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp",
|
|
empoignade: "systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp"
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
export class RdDItem extends Item {
|
|
|
|
static get defaultIcon() {
|
|
return undefined;
|
|
}
|
|
|
|
static getDefaultImg(itemType) {
|
|
return game.system.rdd.itemClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
|
|
}
|
|
|
|
static isFieldInventaireModifiable(type, field) {
|
|
switch (field) {
|
|
case 'quantite':
|
|
if ([TYPES.conteneur].includes(type)) {
|
|
return false;
|
|
}
|
|
break;
|
|
case 'cout':
|
|
if ([TYPES.monnaie].includes(type)) {
|
|
return game.user.isGM;
|
|
}
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static async getCorrespondingItem(itemRef) {
|
|
if (itemRef.pack) {
|
|
return await SystemCompendiums.loadDocument(itemRef)
|
|
}
|
|
return game.items.get(itemRef.id ?? itemRef._id);
|
|
}
|
|
|
|
static getItemTypesInventaire(mode = 'materiel') {
|
|
return typesInventaire[mode ?? 'materiel']
|
|
}
|
|
static getItemTypesDraconiques() {
|
|
return typesObjetsDraconiques;
|
|
}
|
|
static getItemTypesEnvironnement() {
|
|
return typesEnvironnement;
|
|
}
|
|
|
|
static getTypesOeuvres() {
|
|
return typesObjetsOeuvres
|
|
}
|
|
|
|
constructor(docData, context = {}) {
|
|
if (!context.rdd?.ready) {
|
|
foundry.utils.mergeObject(context, { rdd: { ready: true } });
|
|
const ItemConstructor = game.system.rdd.itemClasses[docData.type];
|
|
if (ItemConstructor) {
|
|
if (!docData.img) {
|
|
docData.img = ItemConstructor.defaultIcon;
|
|
}
|
|
return new ItemConstructor(docData, context);
|
|
}
|
|
}
|
|
if (!docData.img) {
|
|
docData.img = RdDItem.getDefaultImg(docData.type);
|
|
}
|
|
context.rdd = undefined
|
|
super(docData, context);
|
|
}
|
|
|
|
getUniteQuantite() {
|
|
switch (this.type) {
|
|
case TYPES.monnaie: return "(Pièces)"
|
|
case TYPES.herbe:
|
|
switch (this.system.categorie) {
|
|
case 'Alchimie': case 'Repos': case 'Soin':
|
|
return "(Brins)"
|
|
case 'Cuisine': return '';
|
|
}
|
|
return '';
|
|
case TYPES.ingredient: return "(Pépins ou Brins)"
|
|
}
|
|
return '';
|
|
}
|
|
|
|
isEquipable() {
|
|
return typesObjetsEquipable.includes(this.type)
|
|
}
|
|
|
|
isCompetencePersonnage() { return this.type == TYPES.competence }
|
|
isCompetenceCreature() { return this.type == TYPES.competencecreature }
|
|
isConteneur() { return this.type == TYPES.conteneur; }
|
|
isMonnaie() { return this.type == TYPES.monnaie; }
|
|
isPotion() { return this.type == TYPES.potion; }
|
|
isNourritureBoisson() { return this.type == TYPES.nourritureboisson; }
|
|
isService() { return this.type == TYPES.service; }
|
|
|
|
isCompetence() { return typesObjetsCompetence.includes(this.type) }
|
|
isEsquive() {
|
|
return (this.isCompetence()
|
|
&& this.system.categorie == 'melee'
|
|
&& Grammar.includesLowerCaseNoAccent(this.name, 'Esquive'));
|
|
}
|
|
|
|
isCorpsACorps() {
|
|
return this.isCompetence()
|
|
&& this.system.categorie == 'melee'
|
|
&& Grammar.includesLowerCaseNoAccent(this.name, 'Corps à Corps')
|
|
}
|
|
|
|
isCompetenceArme() {
|
|
return this.isCompetence() && ['melee', 'tir', 'lancer'].includes(this.system.categorie)
|
|
}
|
|
|
|
isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" }
|
|
isTemporel() { return typesObjetsTemporels.includes(this.type) }
|
|
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
|
|
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
|
|
isQueueDragon() { return [TYPES.queue, TYPES.ombre].includes(this.type) }
|
|
isEffet() { return typesObjetsEffet.includes(this.type) }
|
|
isConnaissance() { return typesObjetsConnaissance.includes(this.type) }
|
|
|
|
isInventaire(mode = 'materiel') { return RdDItem.getItemTypesInventaire(mode).includes(this.type); }
|
|
isBoisson() { return this.isNourritureBoisson() && this.system.boisson; }
|
|
isAlcool() { return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; }
|
|
isHerbeAPotion() { return this.type == TYPES.herbe && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
|
|
isBlessure() { return this.type == TYPES.blessure }
|
|
|
|
isPresentDansMilieux(milieux) {
|
|
return this.getEnvironnements(milieux).length > 0
|
|
}
|
|
getCategories() {
|
|
switch (this.type) {
|
|
case TYPES.competence: return RdDItemCompetence.getCategories()
|
|
case TYPES.competencecreature: return RdDItemCompetenceCreature.getCategories()
|
|
}
|
|
return {}
|
|
}
|
|
|
|
getEnvironnements(milieux = undefined) {
|
|
const environnements = this.isInventaire() ? this.system.environnement : undefined;
|
|
if (milieux == undefined || !environnements) {
|
|
return environnements ?? [];
|
|
}
|
|
return environnements.filter(env => milieux.includes(env.milieu))
|
|
}
|
|
|
|
getMilieux() {
|
|
return this.getEnvironnements().map(env => env.milieu);
|
|
}
|
|
|
|
getRaretes(milieux = undefined) {
|
|
if (this.isInventaire()) {
|
|
const raretes = this.getEnvironnements(milieux).map(env => RdDRaretes.byCode(env.rarete));
|
|
if (milieux == undefined && raretes.length == 0) {
|
|
return [RdDRaretes.rareteFrequente()];
|
|
}
|
|
return raretes;
|
|
}
|
|
return [RdDRaretes.rareteEgale()];
|
|
}
|
|
|
|
getFrequence(milieux = undefined) {
|
|
const frequences = this.getEnvironnements(milieux).map(it => it.frequence);
|
|
return frequences.length == 0 ? 0 : Math.max(...frequences);
|
|
}
|
|
|
|
getItemGroup() {
|
|
if (this.isInventaire()) 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; }
|
|
|
|
isFinPeriode(oldTimestamp, newTimestamp) {
|
|
if (!this.isTemporel()) {
|
|
return false;
|
|
}
|
|
const finPeriode = new RdDTimestamp(this.system.temporel.fin);
|
|
return oldTimestamp.compare(finPeriode) < 0 && finPeriode.compare(newTimestamp) <= 0
|
|
}
|
|
|
|
async onCreateItemTemporel(actor) {
|
|
if (this.isTemporel()) {
|
|
const timestampDebut = game.system.rdd.calendrier.timestamp;
|
|
const timestampFin = await this.calculerFinPeriodeTemporel(timestampDebut);
|
|
await actor.updateEmbeddedDocuments('Item', [{
|
|
_id: this.id,
|
|
'system.temporel.debut': foundry.utils.duplicate(timestampDebut),
|
|
'system.temporel.fin': foundry.utils.duplicate(timestampFin),
|
|
}])
|
|
}
|
|
}
|
|
|
|
async calculerFinPeriodeTemporel(timestampDebut) {
|
|
return timestampDebut;
|
|
}
|
|
|
|
async onFinPeriodeTemporel(oldTimestamp, newTimestamp) {
|
|
if (this.isTemporel() && this.actor) {
|
|
await this.onFinPeriode(oldTimestamp, newTimestamp);
|
|
}
|
|
}
|
|
|
|
async onFinPeriode(oldTimestamp, newTimestamp) {
|
|
console.log(`${this.actor.name}: l'objet ${this.name} a expiré et été supprimé`);
|
|
await this.actor?.deleteEmbeddedDocuments('Item', [this.id]);
|
|
}
|
|
|
|
getUtilisation() {
|
|
switch (this.type) {
|
|
case TYPES.potion:
|
|
switch (this.system.categorie) {
|
|
case 'Alchimie': case 'AlchimieEnchante': case 'AlchimieAutre': return 'alchimie'
|
|
case 'Cuisine': return 'cuisine'
|
|
case 'Remede': case 'Repos': case 'ReposEnchante': case 'Soin': case 'SoinEnchante': return 'soins'
|
|
}
|
|
return '';
|
|
case TYPES.nourritureboisson: return 'cuisine';
|
|
case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
|
|
switch (this.system.categorie) {
|
|
case 'Cuisine': return 'cuisine';
|
|
case 'Toxique': case 'Poison': return 'poison';
|
|
case 'Alchimie': return 'alchimie'
|
|
case 'Soin': case 'Repos': return 'soins'
|
|
}
|
|
return this.system.sust > 0 ? 'cuisine' : '';
|
|
}
|
|
return '';
|
|
}
|
|
|
|
getUtilisationCuisine() {
|
|
if (this.getUtilisation() == 'cuisine') {
|
|
switch (this.type) {
|
|
case TYPES.nourritureboisson:
|
|
return 'pret';
|
|
case TYPES.herbe: case TYPES.faune: case TYPES.ingredient: case TYPES.plante:
|
|
return 'brut';
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
isCristalAlchimique() {
|
|
return this.type == TYPES.objet && Grammar.includesLowerCaseNoAccent(this.name, 'cristal alchimique') && this.system.quantite > 0;
|
|
}
|
|
|
|
isMagique() {
|
|
return this.system.magique
|
|
}
|
|
|
|
isItemCommerce() {
|
|
return this.parent?.type == 'commerce';
|
|
}
|
|
|
|
isNomLike(texte) {
|
|
return Grammar.includesLowerCaseNoAccent(this.name, texte)
|
|
}
|
|
isNomTypeLike(texte) {
|
|
return this.isNomLike(texte) || Grammar.includesLowerCaseNoAccent(Misc.typeName(this.type, 'Item'), texte)
|
|
}
|
|
|
|
getQuantite() {
|
|
return this.isService() ? undefined : Math.round(this.system.quantite ?? 0)
|
|
}
|
|
|
|
getEncTotal() {
|
|
return (this.getQuantite() ?? 0) * this.getEnc();
|
|
}
|
|
|
|
getEnc() {
|
|
switch (this.type) {
|
|
case TYPES.service:
|
|
return 0;
|
|
case TYPES.herbe:
|
|
return this.getEncHerbe();
|
|
case TYPES.gemme:
|
|
return encPepin * this.system.taille;
|
|
}
|
|
return Math.max(this.system.encombrement ?? 0, 0);
|
|
}
|
|
|
|
getEncContenu() {
|
|
return this.getContenu()
|
|
.map(it => it.getRecursiveEnc())
|
|
.reduce(Misc.sum(), 0);
|
|
}
|
|
|
|
getRecursiveEnc() {
|
|
return this.getEncTotal() + this.getEncContenu()
|
|
}
|
|
|
|
getEncHerbe() {
|
|
switch (this.system.categorie) {
|
|
case 'Repos': case 'Soin': case 'Alchimie':
|
|
return encBrin;
|
|
}
|
|
return this.system.encombrement;
|
|
|
|
}
|
|
|
|
getContenu() {
|
|
if (this.isConteneur()) {
|
|
return this.system.contenu.map(idContenu => this.actor.getItem(idContenu));
|
|
}
|
|
return []
|
|
}
|
|
|
|
isConteneurContenu(conteneur) {
|
|
return this.getContenu()
|
|
.find(it => it.id == conteneur.id || it.isConteneurContenu(conteneur))
|
|
}
|
|
|
|
valeurTotale() {
|
|
return (this.isService() ? 1 : this.getQuantite()) * this.valeur()
|
|
}
|
|
|
|
valeur() {
|
|
return this.system.cout ?? 0
|
|
}
|
|
|
|
calculerPrixCommercant() {
|
|
if (this.isItemCommerce()) {
|
|
// appliquer le pourcentage
|
|
return this.parent.calculerPrix(this);
|
|
}
|
|
return this.system.cout;
|
|
}
|
|
|
|
prepareDerivedData() {
|
|
super.prepareDerivedData();
|
|
if (this.isInventaire()) {
|
|
this.system.encTotal = this.getEncTotal();
|
|
if (this.isPotion()) {
|
|
this.prepareDataPotion()
|
|
}
|
|
this.system.actionPrincipale = this.getActionPrincipale({ warnIfNot: false });
|
|
}
|
|
this.equipable = this.isEquipable();
|
|
}
|
|
|
|
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 calculPointsRepos / calculPointsGuerison
|
|
this.system.puissance = RdDHerbes.calculPuissancePotion(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
getActionPrincipale(options = { warnIfNot: true }) {
|
|
switch (this.type) {
|
|
case TYPES.conteneur: return 'Ouvrir';
|
|
}
|
|
if (this.actor?.isPersonnage()) {
|
|
const warn = options.warnIfNot;
|
|
if (this.getUtilisationCuisine() == 'brut') {
|
|
return 'Cuisiner';
|
|
}
|
|
switch (this.type) {
|
|
case TYPES.nourritureboisson: return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
|
|
case TYPES.potion: return this._actionOrWarnQuantiteZero('Consommer', warn);
|
|
case TYPES.livre: return this._actionOrWarnQuantiteZero('Lire', warn);
|
|
case TYPES.herbe: return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
|
|
case TYPES.queue: case TYPES.ombre: return this.system.refoulement > 0 ? 'Refouler' : undefined;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async actionPrincipale(actor, onActionItem = async () => { }) {
|
|
if (!this.getActionPrincipale()) { return }
|
|
await actor?.actionPrincipale(this, onActionItem);
|
|
}
|
|
|
|
_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 onCreateDecoupeComestible(actor) {
|
|
if (actor && this.getUtilisationCuisine() == 'brut' && this.system.sust != 1) {
|
|
if (this.system.sust < 1) {
|
|
await actor.updateEmbeddedDocuments('Item', [{
|
|
_id: this.id,
|
|
'system.sust': 0
|
|
}])
|
|
}
|
|
else {
|
|
const sust = Math.floor(this.system.sust);
|
|
await actor.updateEmbeddedDocuments('Item', [{
|
|
_id: this.id,
|
|
'system.quantite': this.system.quantite * sust,
|
|
'system.encombrement': Misc.keepDecimals(this.system.encombrement / sust, 2),
|
|
'system.cout': Math.max(0, Misc.keepDecimals(this.system.cout / sust, 2)),
|
|
'system.sust': 1
|
|
}])
|
|
}
|
|
}
|
|
}
|
|
|
|
async empiler(item) {
|
|
if (this.getUtilisationCuisine() == 'brut') {
|
|
const sust = this.system.sust + item.system.sust;
|
|
const encombrement = this.system.encombrement + item.system.encombrement;
|
|
await this.update({
|
|
"system.sust": sust,
|
|
"system.encombrement": encombrement
|
|
});
|
|
}
|
|
else {
|
|
await this.quantiteIncDec(item.system.quantite);
|
|
}
|
|
await item.delete();
|
|
}
|
|
|
|
async quantiteIncDec(nombre, options = { 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é
|
|
isInventaireEmpilable(other) {
|
|
if (!other || !this.isInventaire()) {
|
|
return [false, undefined];
|
|
}
|
|
if (this.system.quantite == undefined) {
|
|
return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`];
|
|
}
|
|
else if (this.type != other.type) {
|
|
return [false, `Impossible de regrouper des ${this.type} avec des ${other.type}`];
|
|
}
|
|
else if (this.name != other.name) {
|
|
return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
|
|
}
|
|
else {
|
|
const excludedProperties = ['quantite', 'cout', 'encTotal', 'environnement', 'contenu'];
|
|
if (this.getUtilisationCuisine()) {
|
|
excludedProperties.push('sust', 'encombrement');
|
|
}
|
|
let differences = Object.entries(this.system)
|
|
.filter(([key, value]) => !excludedProperties.includes(key))
|
|
.filter(([key, value]) => value != other.system[key])
|
|
if (differences.length > 0) {
|
|
let message = `Impossible de regrouper les ${this.type} ${this.name}: `;
|
|
for (const [key, value] of differences) {
|
|
message += `<br>${key}: ${value} vs ${other.system[key]}`;
|
|
}
|
|
return [false, message];
|
|
}
|
|
}
|
|
return [true, undefined];
|
|
}
|
|
|
|
async proposerVente(quantiteMax = undefined) {
|
|
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({ item: this, quantiteMax })
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
getProprietes() {
|
|
if (this[`_${this.type}ChatData`]) {
|
|
return this[`_${this.type}ChatData`]().filter(it => it != undefined);
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async postItemToChat(modeOverride) {
|
|
console.log(this);
|
|
let chatData = {
|
|
doctype: 'Item',
|
|
id: this.id,
|
|
type: this.type,
|
|
img: this.img,
|
|
pack: this.pack,
|
|
name: this.name,
|
|
actor: this.actor ? { id: this.actor.id } : undefined,
|
|
system: { description: this.system.description },
|
|
properties: this.getProprietes(),
|
|
}
|
|
renderTemplate(this.getChatItemTemplate(), chatData).then(html => {
|
|
let chatOptions = RdDUtility.chatDataSetup(html, modeOverride);
|
|
ChatMessage.create(chatOptions)
|
|
});
|
|
}
|
|
|
|
getChatItemTemplate() {
|
|
return 'systems/foundryvtt-reve-de-dragon/templates/post-item.html';
|
|
}
|
|
|
|
static propertyIfDefined(name, val, condition = true) {
|
|
return condition ? `<b>${name}</b>: ${val}` : undefined;
|
|
}
|
|
|
|
_inventaireTemplateChatData() {
|
|
return [
|
|
RdDItem.propertyIfDefined('Qualité', this.system.qualite, this.system.qualite != 0),
|
|
RdDItem.propertyIfDefined('Encombrement', this.system.encombrement)
|
|
// cout et quantité masqués
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_objetChatData() {
|
|
return this._inventaireTemplateChatData()
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
_nourritureboissonChatData() {
|
|
return [
|
|
RdDItem.propertyIfDefined('Sustentation', this.system.sust, this.system.sust > 0),
|
|
RdDItem.propertyIfDefined('Désaltère', this.system.desaltere, this.system.boisson),
|
|
RdDItem.propertyIfDefined('Force alcool', this.system.force, this.system.boisson && this.system.alcoolise),
|
|
RdDItem.propertyIfDefined('Exotisme', this.system.exotisme, this.system.exotisme < 0),
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_armeChatData() {
|
|
return [
|
|
`<b>Compétence</b>: ${this.system.competence}`,
|
|
`<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == 'non-mortel' ? '(Non mortel)' : ''}`,
|
|
`<b>Force minimum</b>: ${this.system.force}`,
|
|
`<b>Resistance</b>: ${this.system.resistance}`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_conteneurChatData() {
|
|
return [
|
|
`<b>Capacité</b>: ${this.system.capacite} Enc.`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_munitionChatData() {
|
|
return this._inventaireTemplateChatData()
|
|
}
|
|
/* -------------------------------------------- */
|
|
_armureChatData() {
|
|
return [
|
|
`<b>Protection</b>: ${this.system.protection}`,
|
|
`<b>Détérioration</b>: ${this.system.deterioration}`,
|
|
`<b>Malus armure</b>: ${this.system.malus}`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_competenceChatData() {
|
|
return [
|
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
|
`<b>Niveau</b>: ${this.system.niveau}`,
|
|
`<b>Caractéristique par défaut</b>: ${this.system.carac_defaut}`,
|
|
`<b>XP</b>: ${this.system.xp}`
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_competencecreatureChatData() {
|
|
return [
|
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
|
`<b>Niveau</b>: ${this.system.niveau}`,
|
|
`<b>Caractéristique</b>: ${this.system.carac_value}`,
|
|
`<b>XP</b>: ${this.system.xp}`
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_sortChatData() {
|
|
return [
|
|
`<b>Draconic</b>: ${this.system.draconic}`,
|
|
`<b>Difficulté</b>: ${this.system.difficulte}`,
|
|
`<b>Case TMR</b>: ${this.system.caseTMR}`,
|
|
`<b>Points de Rêve</b>: ${this.system.ptreve}`
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_herbeChatData() {
|
|
return [
|
|
`<b>Milieu</b>: ${this.system.milieu}`,
|
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_ingredientChatData() {
|
|
return [
|
|
`<b>Milieu</b>: ${this.system.milieu}`,
|
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_fauneChatData() {
|
|
return [
|
|
`<b>Sustentation</b>: ${this.system.sust}`,
|
|
`<b>Milieu</b>: ${this.system.milieu}`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_tacheChatData() {
|
|
return [
|
|
`<b>Caractéristique</b>: ${this.system.carac}`,
|
|
`<b>Compétence</b>: ${this.system.competence}`,
|
|
`<b>Périodicité</b>: ${this.system.periodicite}`,
|
|
`<b>Fatigue</b>: ${this.system.fatigue}`,
|
|
`<b>Difficulté</b>: ${this.system.difficulte}`,
|
|
RdDItem.propertyIfDefined('Points de Tâche', this.system.points_de_tache, !this.system.cacher_points_de_tache),
|
|
`<b>Points de Tâche atteints</b>: ${this.system.points_de_tache_courant}`]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_livreChatData() {
|
|
return [
|
|
`<b>Compétence</b>: ${this.system.competence}`,
|
|
`<b>Auteur</b>: ${this.system.auteur}`,
|
|
`<b>Difficulté</b>: ${this.system.difficulte}`,
|
|
RdDItem.propertyIfDefined('Points de Tâche', this.system.points_de_tache, !this.system.cacher_points_de_tache),
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_potionChatData() {
|
|
return [
|
|
`<b>Rareté</b>: ${this.system.rarete}`,
|
|
`<b>Catégorie</b>: ${this.system.categorie}`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_queueChatData() {
|
|
function label(categorie) {
|
|
switch (categorie) {
|
|
case 'ideefixe': return 'Idée fixe';
|
|
case 'lancinant': return 'Désir lancinant';
|
|
}
|
|
return ''
|
|
}
|
|
return [
|
|
`<b>Refoulement</b>: ${this.system.refoulement}`,
|
|
`<b>Catégorie</b>: ${label(this.system.categorie)}`,
|
|
`<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_ombreChatData() {
|
|
return this._queueChatData()
|
|
}
|
|
/* -------------------------------------------- */
|
|
_souffleChatData() {
|
|
return [
|
|
`<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
|
|
];
|
|
}
|
|
/* -------------------------------------------- */
|
|
_teteChatData() {
|
|
return [
|
|
`<b>Affecte</b>: ${this.system.hautrevant ? 'les haut-rêvants' : 'tout le monde'}`,
|
|
];
|
|
}
|
|
/* -------------------------------------------- */
|
|
_tarotChatData() {
|
|
return [
|
|
RdDItem.propertyIfDefined('Carte', RdDUtility.linkCompendium(this.pack, this.id, this.name), this.pack),
|
|
`<b>Concept</b>: ${this.system.concept}`,
|
|
`<b>Aspect</b>: ${this.system.aspect}`,
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_nombreastralChatData() {
|
|
return [
|
|
`<b>Valeur</b>: ${this.system.value}`,
|
|
`<b>Jour</b>: ${this.system.jourlabel}`,
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_monnaieChatData() {
|
|
return this._inventaireTemplateChatData()
|
|
}
|
|
/* -------------------------------------------- */
|
|
_meditationChatData() {
|
|
return [
|
|
`<b>Thème</b>: ${this.system.theme}`,
|
|
`<b>Compétence</b>: ${this.system.competence}`,
|
|
`<b>Support</b>: ${this.system.support}`,
|
|
`<b>Heure</b>: ${this.system.heure}`,
|
|
`<b>Purification</b>: ${this.system.purification}`,
|
|
`<b>Vêture</b>: ${this.system.veture}`,
|
|
`<b>Comportement</b>: ${this.system.comportement}`,
|
|
`<b>Case TMR</b>: ${this.system.tmr}`
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_rencontreChatData() {
|
|
if (this.system.coord) {
|
|
return [
|
|
`<b>Force</b>: ${this.system.force}`,
|
|
`<b>Coordonnées</b>: ${this.system.coord}`,
|
|
]
|
|
}
|
|
return [
|
|
`<b>Force</b>: ${this.system.formule}`,
|
|
`<b>Refoulement</b>: ${this.system.refoulement}`,
|
|
RdDItem.propertyIfDefined('<b>Présent de cités</b>', '', this.system.presentCite),
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_casetmrChatData() {
|
|
return [
|
|
`<b>Coordonnée</b>: ${this.system.coord}`,
|
|
`<b>Spécificité</b>: ${this.system.specific}`
|
|
]
|
|
}
|
|
/* -------------------------------------------- */
|
|
_maladieChatData() {
|
|
if (!this.system.identifie) {
|
|
return [`<b>Inconnue</b>`]
|
|
}
|
|
return [
|
|
`<b>Malignité</b>: ${this.system.malignite}`,
|
|
`<b>Périodicité</b>: ${this.system.periodicite}`,
|
|
`<b>Dommages</b>: ${this.system.dommages}`,
|
|
RdDItem.propertyIfDefined('<b>Remedes</b>', this.system.remedes, this.system.remedesconnus),
|
|
]
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
_poisonChatData() {
|
|
return this._maladieChatData();
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
_gemmeChatData() {
|
|
return [
|
|
`<b>Pureté</b>: ${this.system.purete}`,
|
|
`<b>Taille</b>: ${this.system.taille}`,
|
|
`<b>Inertie</b>: ${this.system.inertie}`,
|
|
`<b>Enchantabilité</b>: ${this.system.enchantabilite}`,
|
|
...this._inventaireTemplateChatData()
|
|
]
|
|
}
|
|
}
|