Les auberges sont des commerces #600
BIN
icons/services/bacquet-eau.webp
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
icons/services/biere.webp
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
icons/services/brandevin.webp
Normal file
After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
BIN
icons/services/compagnie.webp
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
icons/services/lit.webp
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
icons/services/paiement.webp
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
icons/services/repas.webp
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
icons/services/verre.webp
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
icons/services/vin.webp
Normal file
After Width: | Height: | Size: 5.5 KiB |
@ -3,6 +3,7 @@
|
|||||||
"TypePersonnage": "Personnage",
|
"TypePersonnage": "Personnage",
|
||||||
"TypeCreature": "Créature",
|
"TypeCreature": "Créature",
|
||||||
"TypeEntite": "Entité de cauchemar",
|
"TypeEntite": "Entité de cauchemar",
|
||||||
|
"TypeCommerce": "Commerce",
|
||||||
"TypeVehicule": "Véhicule"
|
"TypeVehicule": "Véhicule"
|
||||||
},
|
},
|
||||||
"ITEM": {
|
"ITEM": {
|
||||||
@ -27,7 +28,7 @@
|
|||||||
"TypeArmure": "Armure",
|
"TypeArmure": "Armure",
|
||||||
"TypeConteneur": "Conteneur",
|
"TypeConteneur": "Conteneur",
|
||||||
"TypeNourritureboisson": "Nourriture & boisson",
|
"TypeNourritureboisson": "Nourriture & boisson",
|
||||||
"TypeService": "Services/Boutique",
|
"TypeService": "Service",
|
||||||
"TypeChant": "Chant",
|
"TypeChant": "Chant",
|
||||||
"TypeDanse": "Danse",
|
"TypeDanse": "Danse",
|
||||||
"TypeMusique": "Musique",
|
"TypeMusique": "Musique",
|
||||||
|
@ -10,7 +10,6 @@ import { DialogSplitItem } from "./dialog-split-item.js";
|
|||||||
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
import { ReglesOptionelles } from "./settings/regles-optionelles.js";
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
import { Monnaie } from "./item-monnaie.js";
|
|
||||||
import { MAINS_DIRECTRICES } from "./actor.js";
|
import { MAINS_DIRECTRICES } from "./actor.js";
|
||||||
import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js";
|
import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js";
|
||||||
import { RdDItem } from "./item.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)),
|
effects: this.actor.effects.map(e => foundry.utils.deepClone(e)),
|
||||||
limited: this.actor.limited,
|
limited: this.actor.limited,
|
||||||
owner: this.actor.isOwner,
|
owner: this.actor.isOwner,
|
||||||
description: await TextEditor.enrichHTML(this.object.system.description, { async: true }),
|
biographie: await TextEditor.enrichHTML(this.actor.system.biographie, { async: true }),
|
||||||
biographie: await TextEditor.enrichHTML(this.object.system.biographie, { async: true }),
|
notes: await TextEditor.enrichHTML(this.actor.system.notes, { async: true }),
|
||||||
notes: await TextEditor.enrichHTML(this.object.system.notes, { async: true }),
|
|
||||||
notesmj: await TextEditor.enrichHTML(this.object.system.notesmj, { async: true }),
|
|
||||||
});
|
});
|
||||||
mergeObject(formData.calc, {
|
mergeObject(formData.calc, {
|
||||||
surenc: this.actor.computeMalusSurEncombrement(),
|
surenc: this.actor.computeMalusSurEncombrement(),
|
||||||
|
453
module/actor.js
@ -13,7 +13,6 @@ import { RdDItemSort } from "./item-sort.js";
|
|||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDEncaisser } from "./rdd-roll-encaisser.js";
|
import { RdDEncaisser } from "./rdd-roll-encaisser.js";
|
||||||
import { RdDCombat } from "./rdd-combat.js";
|
import { RdDCombat } from "./rdd-combat.js";
|
||||||
import { RdDAudio } from "./rdd-audio.js";
|
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { RdDItemArme } from "./item-arme.js";
|
import { RdDItemArme } from "./item-arme.js";
|
||||||
import { RdDAlchimie } from "./rdd-alchimie.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 { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||||
import { Draconique } from "./tmr/draconique.js";
|
import { Draconique } from "./tmr/draconique.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
import { Monnaie } from "./item-monnaie.js";
|
|
||||||
import { DialogConsommer } from "./dialog-item-consommer.js";
|
import { DialogConsommer } from "./dialog-item-consommer.js";
|
||||||
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
|
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
|
||||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||||
import { RdDItem } from "./item.js";
|
|
||||||
import { RdDPossession } from "./rdd-possession.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 { RdDConfirm } from "./rdd-confirm.js";
|
||||||
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
||||||
import { RdDRencontre } from "./item-rencontre.js";
|
import { RdDRencontre } from "./item-rencontre.js";
|
||||||
@ -77,12 +74,12 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_prepareCreatureData(actorData) {
|
_prepareCreatureData(actorData) {
|
||||||
this.computeEncombrementTotalEtMalusArmure();
|
this.computeEncTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_prepareVehiculeData(actorData) {
|
_prepareVehiculeData(actorData) {
|
||||||
this.computeEncombrementTotalEtMalusArmure();
|
this.computeEncTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -94,7 +91,8 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
RdDCarac.computeCarac(actorData.system)
|
RdDCarac.computeCarac(actorData.system)
|
||||||
this.computeIsHautRevant();
|
this.computeIsHautRevant();
|
||||||
await this.cleanupConteneurs();
|
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) {
|
getTache(id) {
|
||||||
return this.findItemLike(id, 'tache');
|
return this.findItemLike(id, 'tache');
|
||||||
}
|
}
|
||||||
@ -993,237 +987,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
await this.update({ [`system.attributs.${fieldName}.value`]: fieldValue });
|
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: `<p>Etes vous certain de vouloir vider tous les conteneurs ?</p>`,
|
|
||||||
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}<br>${item.name} a été déplacé dans: ${cible.name}`
|
|
||||||
: `${message}<br>${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() {
|
isSurenc() {
|
||||||
return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false
|
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);
|
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() {
|
async computeMalusArmure() {
|
||||||
if (this.isPersonnage()) {
|
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) {
|
computeResumeBlessure(blessures = undefined) {
|
||||||
blessures = blessures ?? this.system.blessures;
|
blessures = blessures ?? this.system.blessures;
|
||||||
@ -1332,7 +1077,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recompute(){
|
recompute() {
|
||||||
this.computeEtatGeneral();
|
this.computeEtatGeneral();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3282,7 +3027,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
if (item && ['arme', 'armure'].includes(item.type)) {
|
if (item && ['arme', 'armure'].includes(item.type)) {
|
||||||
const isEquipe = !item.system.equipe;
|
const isEquipe = !item.system.equipe;
|
||||||
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]);
|
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]);
|
||||||
this.computeEncombrementTotalEtMalusArmure(); // Mise à jour encombrement
|
this.computeEncTotal(); // Mise à jour encombrement
|
||||||
if (isEquipe)
|
if (isEquipe)
|
||||||
this.verifierForceMin(item);
|
this.verifierForceMin(item);
|
||||||
}
|
}
|
||||||
@ -3575,190 +3320,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
return;
|
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é <strong>${depense} Sols</strong>, 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 <strong>${sols} Sols</strong> ${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) {
|
async effectuerTacheAlchimie(recetteId, tacheAlchimie, texteTache) {
|
||||||
let recetteData = this.findItemLike(recetteId, 'recettealchimique');
|
let recetteData = this.findItemLike(recetteId, 'recettealchimique');
|
||||||
|
@ -40,6 +40,7 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
isLimited: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED,
|
isLimited: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED,
|
||||||
isObserver: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER,
|
isObserver: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER,
|
||||||
isOwner: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
|
isOwner: userRightLevel >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
|
||||||
|
owner: this.actor.isOwner,
|
||||||
});
|
});
|
||||||
|
|
||||||
let formData = {
|
let formData = {
|
||||||
@ -49,13 +50,15 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
img: this.actor.img,
|
img: this.actor.img,
|
||||||
name: this.actor.name,
|
name: this.actor.name,
|
||||||
system: foundry.utils.deepClone(this.actor.system),
|
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,
|
options: options,
|
||||||
}
|
}
|
||||||
this.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
|
this.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
|
||||||
formData.calc = {
|
formData.calc = {
|
||||||
fortune: this.toSolsDeniers(this.actor.getFortune()),
|
fortune: this.toSolsDeniers(this.actor.getFortune()),
|
||||||
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
|
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
|
||||||
encTotal: await this.actor.computeEncombrementTotalEtMalusArmure(),
|
encTotal: await this.actor.computeEncTotal(),
|
||||||
}
|
}
|
||||||
|
|
||||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.objets);
|
||||||
@ -74,7 +77,6 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
filterItemsPerTypeForSheet(formData, itemTypes) {
|
filterItemsPerTypeForSheet(formData, itemTypes) {
|
||||||
formData.services = Misc.arrayOrEmpty(itemTypes['service']);
|
|
||||||
formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']);
|
formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']);
|
||||||
formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']);
|
formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']);
|
||||||
formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']);
|
formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']);
|
||||||
@ -100,9 +102,8 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
formData.oeuvres = Misc.arrayOrEmpty(itemTypes['oeuvre']);
|
formData.oeuvres = Misc.arrayOrEmpty(itemTypes['oeuvre']);
|
||||||
formData.jeux = Misc.arrayOrEmpty(itemTypes['jeu']);
|
formData.jeux = Misc.arrayOrEmpty(itemTypes['jeu']);
|
||||||
|
|
||||||
|
formData.services = Misc.arrayOrEmpty(itemTypes['service']);
|
||||||
formData.conteneurs = Misc.arrayOrEmpty(itemTypes['conteneur']);
|
formData.conteneurs = Misc.arrayOrEmpty(itemTypes['conteneur']);
|
||||||
|
|
||||||
formData.materiel = Misc.arrayOrEmpty(itemTypes['objet']);
|
formData.materiel = Misc.arrayOrEmpty(itemTypes['objet']);
|
||||||
formData.armes = Misc.arrayOrEmpty(itemTypes['arme']);
|
formData.armes = Misc.arrayOrEmpty(itemTypes['arme']);
|
||||||
formData.armures = Misc.arrayOrEmpty(itemTypes['armure']);
|
formData.armures = Misc.arrayOrEmpty(itemTypes['armure']);
|
||||||
@ -114,22 +115,12 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']);
|
formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']);
|
||||||
formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']);
|
formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']);
|
||||||
formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']);
|
formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']);
|
||||||
|
|
||||||
formData.monnaie = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere());
|
formData.monnaie = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere());
|
||||||
|
|
||||||
formData.objets = formData.conteneurs
|
formData.objets = RdDItem.getItemTypesInventaire('all')
|
||||||
.concat(formData.materiel)
|
.map(t => Misc.arrayOrEmpty(itemTypes[t]))
|
||||||
.concat(formData.armes)
|
.reduce((a, b) => a.concat(b), [])
|
||||||
.concat(formData.armures)
|
.sort(Misc.ascending(it => it.name));
|
||||||
.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */ /** @override */
|
/* -------------------------------------------- */ /** @override */
|
||||||
@ -138,22 +129,22 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
this.html = html;
|
this.html = html;
|
||||||
|
|
||||||
this.html.find('.conteneur-name a').click(async event => {
|
this.html.find('.conteneur-name a').click(async event => {
|
||||||
RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event));
|
RdDUtility.toggleAfficheContenu(this.getItemId(event));
|
||||||
this.render(true);
|
this.render(true);
|
||||||
});
|
});
|
||||||
this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true))
|
this.html.find('.item-edit').click(async event => this.getItem(event)?.sheet.render(true))
|
||||||
this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItemToChat());
|
this.html.find('.item-montrer').click(async event => this.getItem(event)?.postItemToChat());
|
||||||
this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat());
|
this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat());
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
// Everything below here is only needed if the sheet is editable
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
this.html.find('.item-split').click(async event => {
|
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);
|
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-delete').click(async event => RdDUtility.confirmActorItemDelete(this, this.getItem(event)));
|
||||||
this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
|
this.html.find('.item-vendre').click(async event => this.vendre(this.getItem(event)));
|
||||||
|
|
||||||
this.html.find('.creer-un-objet').click(async event => {
|
this.html.find('.creer-un-objet').click(async event => {
|
||||||
this.selectObjetTypeToCreate();
|
this.selectObjetTypeToCreate();
|
||||||
@ -162,14 +153,20 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
this.actor.nettoyerConteneurs();
|
this.actor.nettoyerConteneurs();
|
||||||
});
|
});
|
||||||
this.html.find('.monnaie-plus').click(async event => {
|
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.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() {
|
_getHeaderButtons() {
|
||||||
@ -185,7 +182,7 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _onDropItem(event, dragData) {
|
async _onDropItem(event, dragData) {
|
||||||
const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id')
|
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) {
|
if (dropParams) {
|
||||||
const callSuper = await this.actor.processDropItem(dropParams)
|
const callSuper = await this.actor.processDropItem(dropParams)
|
||||||
if (callSuper) {
|
if (callSuper) {
|
||||||
@ -194,10 +191,9 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async selectObjetTypeToCreate() {
|
async selectObjetTypeToCreate() {
|
||||||
let typeObjets = RdDItem.getItemTypesInventaire();
|
let typeObjets = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type)));
|
||||||
let content = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
let content = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
||||||
for (let typeName of typeObjets) {
|
for (let typeName of typeObjets) {
|
||||||
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
||||||
@ -217,6 +213,10 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
d.render(true);
|
d.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTypesInventaire() {
|
||||||
|
return RdDItem.getItemTypesInventaire();
|
||||||
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
setPosition(options = {}) {
|
setPosition(options = {}) {
|
||||||
const position = super.setPosition(options);
|
const position = super.setPosition(options);
|
||||||
@ -253,4 +253,8 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vendre(item) {
|
||||||
|
item?.proposerVente(this.actor.getQuantiteDisponible(item));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
||||||
import { Monnaie } from "../item-monnaie.js";
|
import { Monnaie } from "../item-monnaie.js";
|
||||||
|
import { RdDItem } from "../item.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDAudio } from "../rdd-audio.js";
|
||||||
import { RdDUtility } from "../rdd-utility.js";
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
||||||
|
|
||||||
@ -73,14 +76,14 @@ export class RdDBaseActor extends Actor {
|
|||||||
if (actorData.items) {
|
if (actorData.items) {
|
||||||
return await super.create(actorData, options);
|
return await super.create(actorData, options);
|
||||||
}
|
}
|
||||||
|
actorData.items = [];
|
||||||
if (actorData.type == "personnage") {
|
if (actorData.type == "personnage") {
|
||||||
const competences = await SystemCompendiums.getCompetences(actorData.type);
|
const competences = await SystemCompendiums.getCompetences(actorData.type);
|
||||||
actorData.items = competences.map(i => i.toObject())
|
actorData.items = actorData.items.concat(competences.map(i => i.toObject()))
|
||||||
.concat(Monnaie.monnaiesStandard());
|
.concat(Monnaie.monnaiesStandard());
|
||||||
}
|
}
|
||||||
else {
|
else if (actorData.type == "commerce") {
|
||||||
actorData.items = [];
|
actorData.items = actorData.items.concat(Monnaie.monnaiesStandard());
|
||||||
}
|
}
|
||||||
return super.create(actorData, options);
|
return super.create(actorData, options);
|
||||||
}
|
}
|
||||||
@ -120,9 +123,11 @@ export class RdDBaseActor extends Actor {
|
|||||||
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
?? Misc.findFirstLike(idOrName, this.listItems(type), { description: Misc.typeName('Item', type) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMonnaie(id) { return this.findItemLike(id, 'monnaie'); }
|
||||||
|
|
||||||
recompute() { }
|
recompute() { }
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onPreUpdateItem(item, change, options, id) { }
|
async onPreUpdateItem(item, change, options, id) { }
|
||||||
|
|
||||||
@ -132,11 +137,220 @@ export class RdDBaseActor extends Actor {
|
|||||||
|
|
||||||
async onUpdateActor(update, options, actorId) { }
|
async onUpdateActor(update, options, actorId) { }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
getFortune() {
|
getFortune() {
|
||||||
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
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 }]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
computePrixTotalEquipement() {
|
||||||
|
return this.items.filter(it => it.isInventaire())
|
||||||
|
.filter(it => !it.isMonnaie())
|
||||||
|
.map(it => it.valeurTotale())
|
||||||
|
.reduce(Misc.sum(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
async payerSols(depense) {
|
||||||
|
depense = Number(depense);
|
||||||
|
if (depense == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let fortune = this.getFortune();
|
||||||
|
console.log("payer", game.user.character, depense, fortune);
|
||||||
|
let msg = "";
|
||||||
|
if (fortune >= depense) {
|
||||||
|
await Monnaie.optimiserFortune(this, fortune - depense);
|
||||||
|
msg = `Vous avez payé <strong>${depense} Sols</strong>, 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 = this.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 <strong>${sols} Sols</strong> ${fromActor ? " de " + fromActor.name : ''}, qui ont été ajoutés à votre argent.`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
getQuantiteDisponible(item) {
|
||||||
|
return item?.getQuantite();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
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 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);
|
||||||
|
if (!this.verifierQuantite(vendeur, itemVendu, quantite)) {
|
||||||
|
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a pas assez de ${itemVendu.name} !`);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (acheteur && !acheteur.verifierFortune(cout)) {
|
||||||
|
ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.decrementerVente(vendeur, itemVendu, quantite, cout);
|
||||||
|
if (acheteur) {
|
||||||
|
await acheteur.depenserSols(cout);
|
||||||
|
const 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 (achat.chatMessageIdVente) {
|
||||||
|
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(vendeur, itemVendu, quantite, cout) {
|
||||||
|
if (vendeur) {
|
||||||
|
await vendeur.ajouterSols(cout);
|
||||||
|
await vendeur.decrementerQuantiteItem(itemVendu, quantite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierFortune(cout) {
|
||||||
|
return this.getFortune() >= cout;
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierQuantite(vendeur, item, quantiteTotal) {
|
||||||
|
const disponible = vendeur?.getQuantiteDisponible(item);
|
||||||
|
return disponible == undefined || 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, options = { supprimerSiZero: true }) {
|
||||||
|
let resteQuantite = (item.system.quantite ?? 1) - quantite;
|
||||||
|
if (resteQuantite <= 0) {
|
||||||
|
if (options.supprimerSiZero) {
|
||||||
|
await this.deleteEmbeddedDocuments("Item", [item.id]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await this.updateEmbeddedDocuments("Item", [{ _id: item.id, 'system.quantite': 0 }]);
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
if (this.canReceive(item)) {
|
||||||
|
const isItemEmpilable = "quantite" in item.system;
|
||||||
|
const baseItem = {
|
||||||
|
type: item.type,
|
||||||
|
img: item.img,
|
||||||
|
name: item.name,
|
||||||
|
system: mergeObject(item.system, { quantite: isItemEmpilable ? quantite : undefined })
|
||||||
|
};
|
||||||
|
const newItems = isItemEmpilable ? [baseItem] : Array.from({ length: quantite }, (_, i) => baseItem);
|
||||||
|
const items = await this.createEmbeddedDocuments("Item", newItems);
|
||||||
|
return items.length > 0 ? items[0].id : undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async computeEncTotal() {
|
||||||
|
if (!this.pack) {
|
||||||
|
this.encTotal = this.items.map(it => it.getEncTotal()).reduce(Misc.sum(), 0);
|
||||||
|
return this.encTotal;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
async createItem(type, name = undefined) {
|
async createItem(type, name = undefined) {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
name = 'Nouveau ' + Misc.typeName('Item', type);
|
name = 'Nouveau ' + Misc.typeName('Item', type);
|
||||||
@ -148,6 +362,237 @@ export class RdDBaseActor extends Actor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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('all') && 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}<br>${item.name} a été déplacé dans: ${cible.name}`
|
||||||
|
: `${message}<br>${item.name} a été sorti du conteneur`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.computeEncTotal();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
_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...*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** 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: `<p>Etes vous certain de vouloir vider tous les conteneurs ?</p>`,
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async postActorToChat(modeOverride) {
|
async postActorToChat(modeOverride) {
|
||||||
let chatData = {
|
let chatData = {
|
||||||
|
74
module/actor/commerce-sheet.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { DialogItemAchat } from "../dialog-item-achat.js";
|
||||||
|
import { RdDItem } from "../item.js";
|
||||||
|
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
||||||
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
|
import { RdDBaseActorSheet } from "./base-actor-sheet.js";
|
||||||
|
import { RdDCommerce } from "./commerce.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
|
* @extends {ActorSheet}
|
||||||
|
*/
|
||||||
|
export class RdDCommerceSheet extends RdDBaseActorSheet {
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static get defaultOptions() {
|
||||||
|
return mergeObject(super.defaultOptions, {
|
||||||
|
classes: ["rdd", "sheet", "actor"],
|
||||||
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-actor-sheet.html",
|
||||||
|
width: 600,
|
||||||
|
height: 720,
|
||||||
|
tabs: [],
|
||||||
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
this.html.find('a.item-acheter').click(async event => await this.vente(this.getItem(event)));
|
||||||
|
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
this.html.find('a.item-quantite-moins').click(async event => await this.getItem(event)?.quantiteIncDec(-1, { supprimerSiZero: false}));
|
||||||
|
this.html.find('a.item-quantite-plus').click(async event => await this.getItem(event)?.quantiteIncDec(1));
|
||||||
|
this.html.find('input.item-quantite').change(async event => {
|
||||||
|
const newQuantite = Math.max(0, Number.parseInt(this.html.find(event.currentTarget).val()));
|
||||||
|
await this.getItem(event)?.update({ "system.quantite": newQuantite });
|
||||||
|
})
|
||||||
|
this.html.find('input.item-cout').change(async event => {
|
||||||
|
const newCout = Math.max(0, Number(this.html.find(event.currentTarget).val()));
|
||||||
|
await this.getItem(event)?.update({ "system.cout": newCout });
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getTypesInventaire() {
|
||||||
|
return RdDItem.getItemTypesInventaire('all');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async vente(item) {
|
||||||
|
const acheteur = RdDUtility.getSelectedActor();
|
||||||
|
if (!acheteur) {
|
||||||
|
ui.notifications.warn(`Pas d'acheteur sélectionné`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const disponible = this.actor.getQuantiteDisponible(item)
|
||||||
|
if (disponible == 0) {
|
||||||
|
ui.notifications.warn(`${this.name} n'a plus de ${item.name} en vente`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await DialogItemAchat.onAcheter({
|
||||||
|
item,
|
||||||
|
vendeur: this.actor,
|
||||||
|
acheteur,
|
||||||
|
quantiteIllimite: disponible == undefined,
|
||||||
|
nbLots: disponible ?? 1,
|
||||||
|
tailleLot: 1,
|
||||||
|
prixLot: item.calculerPrixCommercant()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
53
module/actor/commerce.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDBaseActor } from "./base-actor.js";
|
||||||
|
|
||||||
|
export class RdDCommerce extends RdDBaseActor {
|
||||||
|
|
||||||
|
static get defaultIcon() {
|
||||||
|
return "systems/foundryvtt-reve-de-dragon/icons/services/commerce.webp";
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareData() {
|
||||||
|
super.prepareData();
|
||||||
|
}
|
||||||
|
prepareDerivedData() {
|
||||||
|
super.prepareDerivedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
canReceive(item) {
|
||||||
|
if (item.isInventaire('all')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.canReceive(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
getQuantiteDisponible(item) {
|
||||||
|
return this.system.illimite ? undefined : item.getQuantite();
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierFortune(cout) {
|
||||||
|
return this.system.illimite || super.verifierFortune(cout);
|
||||||
|
}
|
||||||
|
async depenserSols(cout) {
|
||||||
|
if (this.system.illimite) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await super.depenserSols(cout)
|
||||||
|
}
|
||||||
|
|
||||||
|
async consommerNourritureAchetee(achat, vente, createdItemId) {
|
||||||
|
// ne pas consommer pour un commerce
|
||||||
|
}
|
||||||
|
|
||||||
|
async decrementerQuantiteItem(itemVendu, quantite) {
|
||||||
|
if (this.system.illimite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await super.decrementerQuantiteItem(itemVendu, quantite, {supprimerSiZero: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
calculerPrix(item) {
|
||||||
|
const pourcentage = this.system.pourcentage ?? 100;
|
||||||
|
return Misc.keepDecimals(Math.ceil(item.system.cout * pourcentage)/100, 2);
|
||||||
|
}
|
||||||
|
}
|
@ -30,15 +30,13 @@ export class DialogItemAchat extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static async onAcheter({ item, vendeur, acheteur, service, serviceSubItem, tailleLot, prixLot, nbLots, quantiteIllimite, chatMessageIdVente }) {
|
static async onAcheter({ item, vendeur, acheteur, tailleLot, prixLot, nbLots, quantiteIllimite, chatMessageIdVente }) {
|
||||||
const venteData = {
|
const venteData = {
|
||||||
item,
|
item,
|
||||||
actingUserId: game.user.id,
|
actingUserId: game.user.id,
|
||||||
vendeurId: vendeur?.id,
|
vendeurId: vendeur?.id,
|
||||||
vendeur,
|
vendeur,
|
||||||
acheteur,
|
acheteur,
|
||||||
serviceSubItem: serviceSubItem,
|
|
||||||
service,
|
|
||||||
tailleLot,
|
tailleLot,
|
||||||
quantiteIllimite,
|
quantiteIllimite,
|
||||||
quantiteNbLots: nbLots,
|
quantiteNbLots: nbLots,
|
||||||
@ -77,7 +75,7 @@ export class DialogItemAchat extends Dialog {
|
|||||||
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
|
buttons[actionAchat] = { label: actionAchat, callback: it => { this.onAchat(); } };
|
||||||
buttons["decliner"] = { label: "Décliner", callback: it => { } };
|
buttons["decliner"] = { label: "Décliner", callback: it => { } };
|
||||||
const acheteur = venteData.acheteur?.name ?? 'Un acheteur';
|
const acheteur = venteData.acheteur?.name ?? 'Un acheteur';
|
||||||
const vendeur = (venteData.service ?? venteData.vendeur)?.name ?? 'Un vendeur';
|
const vendeur = venteData.vendeur?.name ?? 'Un vendeur';
|
||||||
let conf = {
|
let conf = {
|
||||||
title: `${acheteur} - ${actionAchat} à ${vendeur}`,
|
title: `${acheteur} - ${actionAchat} à ${vendeur}`,
|
||||||
content: html,
|
content: html,
|
||||||
@ -93,7 +91,6 @@ export class DialogItemAchat extends Dialog {
|
|||||||
await this.html.find(".nombreLots").change();
|
await this.html.find(".nombreLots").change();
|
||||||
(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
|
(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
|
||||||
userId: game.user.id,
|
userId: game.user.id,
|
||||||
serviceId: this.venteData.service?.id,
|
|
||||||
vendeurId: this.venteData.vendeur?.id,
|
vendeurId: this.venteData.vendeur?.id,
|
||||||
acheteurId: this.venteData.acheteur?.id,
|
acheteurId: this.venteData.acheteur?.id,
|
||||||
prixTotal: this.venteData.prixTotal,
|
prixTotal: this.venteData.prixTotal,
|
||||||
|
@ -2,23 +2,21 @@ import { HtmlUtility } from "./html-utility.js";
|
|||||||
|
|
||||||
export class DialogItemVente extends Dialog {
|
export class DialogItemVente extends Dialog {
|
||||||
|
|
||||||
static async display({ item, callback, service = undefined, quantiteMax = undefined }) {
|
static async display({ item, callback, quantiteMax = undefined }) {
|
||||||
const quantite = quantiteMax ?? item.getQuantite();
|
const quantite = quantiteMax ?? item.getQuantite() ?? 1;
|
||||||
const isOwned = item.isOwned;
|
const isOwned = item.isOwned;
|
||||||
// const isOwned = item.isOwned || service?.actor;
|
|
||||||
const venteData = {
|
const venteData = {
|
||||||
item: item,
|
item: item,
|
||||||
alias: item.actor?.name ?? service?.name ?? game.user.name,
|
alias: item.actor?.name ?? game.user.name,
|
||||||
serviceId: service?.id,
|
vendeurId: item.actor?.id ,
|
||||||
vendeurId: item.actor?.id ?? service?.actor?.id,
|
prixOrigine: item.calculerPrixCommercant(),
|
||||||
prixOrigine: item.system.cout,
|
prixUnitaire: item.calculerPrixCommercant(),
|
||||||
prixUnitaire: item.system.cout,
|
prixLot: item.calculerPrixCommercant(),
|
||||||
prixLot: item.system.cout,
|
|
||||||
tailleLot: 1,
|
tailleLot: 1,
|
||||||
quantiteNbLots: quantite,
|
quantiteNbLots: quantite,
|
||||||
quantiteMaxLots: quantite,
|
quantiteMaxLots: quantite,
|
||||||
quantiteMax: quantite,
|
quantiteMax: quantite,
|
||||||
quantiteIllimite: (service && service.system && service.system.illimite) ? service.system.illimite : !isOwned,
|
quantiteIllimite: !isOwned || quantiteMax == undefined,
|
||||||
isOwned: isOwned,
|
isOwned: isOwned,
|
||||||
};
|
};
|
||||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
|
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
|
||||||
|
@ -51,7 +51,7 @@ export class RdDConteneurItemSheet extends RdDItemSheet {
|
|||||||
|
|
||||||
async _onDropItem(event, dragData) {
|
async _onDropItem(event, dragData) {
|
||||||
if (this.actor) {
|
if (this.actor) {
|
||||||
const dropParams = RdDSheetUtility.prepareItemDropParameters(this.item.id, this.actor, dragData, this.objetVersConteneur);
|
const dropParams = await RdDSheetUtility.prepareItemDropParameters(this.item.id, this.actor, dragData, this.objetVersConteneur);
|
||||||
await this.actor.processDropItem(dropParams);
|
await this.actor.processDropItem(dropParams);
|
||||||
await this.render(true);
|
await this.render(true);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
import { RdDItemSheet } from "./item-sheet.js";
|
import { RdDItemSheet } from "./item-sheet.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
|
||||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
|
||||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
|
||||||
import { RdDItem } from "./item.js";
|
|
||||||
import { RdDItemService } from "./item-service.js";
|
|
||||||
|
|
||||||
export class RdDServiceItemSheet extends RdDItemSheet {
|
export class RdDServiceItemSheet extends RdDItemSheet {
|
||||||
|
|
||||||
@ -18,64 +12,5 @@ export class RdDServiceItemSheet extends RdDItemSheet {
|
|||||||
|
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
|
||||||
this.html.find('a.rdd-world-content-link').click(async event => {
|
|
||||||
const itemRef = this.getItemRef(event);
|
|
||||||
game.items.get(itemRef.id)?.sheet.render(true)
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('a.sub-item-acheter').click(async event => {
|
|
||||||
const subItem = this.item.findRefItem(this.getItemRef(event));
|
|
||||||
await this.item.acheter(RdDUtility.getSelectedActor(), subItem);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!this.options.editable) return;
|
|
||||||
|
|
||||||
this.html.find('a.sub-item-vendre').click(async event => {
|
|
||||||
const subItem = this.item.findRefItem(this.getItemRef(event));
|
|
||||||
await this.item.vendre(subItem);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('a.sub-item-delete').click(async event => {
|
|
||||||
await this.item.removeRefItem(this.getItemRef(event));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('a.sub-item-quantite-moins').click(async event => await this.item.increaseRefItemQuantite(this.getItemRef(event), -1))
|
|
||||||
this.html.find('a.sub-item-quantite-plus').click(async event => await this.item.increaseRefItemQuantite(this.getItemRef(event), 1))
|
|
||||||
this.html.find('input.sub-item-quantite').change(async event => {
|
|
||||||
const newQuantite = Math.max(0, Number.parseInt(this.html.find(event.currentTarget).val()));
|
|
||||||
await this.item.updateRefItem(this.getItemRef(event), it => it.system.quantite = newQuantite);
|
|
||||||
})
|
|
||||||
this.html.find('input.sub-item-cout').change(async event => {
|
|
||||||
const newCout = Math.max(0, Number(this.html.find(event.currentTarget).val()));
|
|
||||||
await this.item.updateRefItem(this.getItemRef(event), it => it.system.cout = newCout);
|
|
||||||
})
|
|
||||||
this.html.find('a.sub-item-info-add').click(__ =>
|
|
||||||
ui.notifications.info(`Utiliser le glisser-déposer pour ajouter des objets depuis un compendium ou les objets du monde`)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async _onDropItem(event, dragData) {
|
|
||||||
let linkedItem = fromUuidSync(dragData.uuid);
|
|
||||||
const existing = this.item.system.items.find(it => it.pack == linkedItem.pack && it.id == linkedItem.id && it.type == linkedItem.type);
|
|
||||||
if (existing) {
|
|
||||||
ui.notifications.warn(`${this.item.name} contient déjà un ${existing.name}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (linkedItem.pack) {
|
|
||||||
linkedItem = await SystemCompendiums.loadDocument(linkedItem);
|
|
||||||
}
|
|
||||||
if (linkedItem.isInventaire()) {
|
|
||||||
await this.item.addRefItem(RdDItemService.createSubItem(linkedItem));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui.notifications.warn(`${this.item.name} ne peut pas proposer à la vente de ${Misc.typeName('Item', linkedItem.type)}: ${linkedItem.name}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getItemRef(event) {
|
|
||||||
const itemRow = this.html.find(event.currentTarget)?.parents('.item.service-item');
|
|
||||||
return { id: itemRow?.data("item-id"), pack: itemRow?.data("pack") ?? undefined }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,141 +1,17 @@
|
|||||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
|
|
||||||
export class RdDItemService extends RdDItem {
|
export class RdDItemService extends RdDItem {
|
||||||
|
|
||||||
static get defaultIcon() {
|
static get defaultIcon() {
|
||||||
return "systems/foundryvtt-reve-de-dragon/icons/items/services.webp";
|
return "systems/foundryvtt-reve-de-dragon/icons/services/lit.webp";
|
||||||
}
|
|
||||||
|
|
||||||
/** @override*/
|
|
||||||
getUserLevel(user) {
|
|
||||||
const level = super.getUserLevel(user);
|
|
||||||
if (level == CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) {
|
|
||||||
// si quelqu'un a accès au lien d'un service, il peut le voir
|
|
||||||
return CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED;
|
|
||||||
}
|
|
||||||
return level;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isService() { return true; }
|
isService() { return true; }
|
||||||
getChatItemTemplate() { return 'systems/foundryvtt-reve-de-dragon/templates/post-item-service.html'; }
|
getProprietes() {
|
||||||
getProprietes() { return []; }
|
return [
|
||||||
|
RdDItem.propertyIfDefined('Qualité', this.system.qualite, this.system.qualite != 0),
|
||||||
getServiceItem(itemRef) {
|
RdDItem.propertyIfDefined('Moral', 'Situation heureuse', this.system.moral),
|
||||||
if (itemRef && this.isService()) {
|
RdDItem.propertyIfDefined('Coût', `${this.calculerPrixCommercant()} sols`),
|
||||||
return this.system.items.find(it => it.id == itemRef.id && it.pack == itemRef.pack);
|
];
|
||||||
}
|
}
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
getQuantiteDisponible(itemRef, max) {
|
|
||||||
if (this.system.illimite) {
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
const subItem = this.getServiceItem(itemRef);
|
|
||||||
return subItem?.system.quantite ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
async venteRefItem(ref, quantite, cout) {
|
|
||||||
if (this.actor) {
|
|
||||||
await this.actor.ajouterSols(cout);
|
|
||||||
}
|
|
||||||
await this.increaseRefItemQuantite(ref, -quantite);
|
|
||||||
}
|
|
||||||
|
|
||||||
async vendre(subItem) {
|
|
||||||
const item = await RdDItem.getCorrespondingItem(subItem);
|
|
||||||
const quantiteMax = this.system.illimite ? undefined : subItem.system.quantite;
|
|
||||||
await item.proposerVente({ service: this, quantiteMax });
|
|
||||||
}
|
|
||||||
|
|
||||||
async acheter(acheteur, subItem) {
|
|
||||||
if (!acheteur) {
|
|
||||||
ui.notifications.warn(`Pas d'acheteur sélectionné`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const nbLots = this.system.illimite ? 1 : subItem.system.quantite;
|
|
||||||
if (nbLots <= 0) {
|
|
||||||
ui.notifications.warn(`${this.name} n'a plus de ${subItem.name} en vente`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await DialogItemAchat.onAcheter({
|
|
||||||
item: await RdDItem.getCorrespondingItem(subItem),
|
|
||||||
acheteur,
|
|
||||||
serviceSubItem: subItem,
|
|
||||||
service: this,
|
|
||||||
quantiteIllimite: this.system.illimite,
|
|
||||||
nbLots,
|
|
||||||
tailleLot: 1,
|
|
||||||
prixLot: subItem.system.cout
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static createSubItem(linkedItem) {
|
|
||||||
return {
|
|
||||||
id: linkedItem.id,
|
|
||||||
pack: linkedItem.pack,
|
|
||||||
name: linkedItem.name,
|
|
||||||
img: linkedItem.img,
|
|
||||||
system: {
|
|
||||||
quantite: 1,
|
|
||||||
cout: linkedItem.system.cout ?? 0
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static matchRefItem({ id, pack }) {
|
|
||||||
return it => it.id == id && (pack ? (it.pack == pack) : (!it.pack));
|
|
||||||
}
|
|
||||||
|
|
||||||
findRefItem(ref) {
|
|
||||||
return this.system.items.find(RdDItemService.matchRefItem(ref));
|
|
||||||
}
|
|
||||||
|
|
||||||
async increaseRefItemQuantite(ref, quantite) {
|
|
||||||
await this.updateRefItem(ref,
|
|
||||||
it => it.system.quantite = Math.max(0, it.system.quantite + quantite)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateRefItem(ref, update = it => { }) {
|
|
||||||
await this.updateRefItems(RdDItemService.matchRefItem(ref), update);
|
|
||||||
}
|
|
||||||
|
|
||||||
async addRefItem(newItem) {
|
|
||||||
if (!newItem.id) {
|
|
||||||
ui.notifications.warn(`${newItem?.name ?? '??'} n'a pas d'identifiant`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.system.items.find(RdDItemService.matchRefItem(newItem))) {
|
|
||||||
ui.notifications.warn(`${newItem?.name ?? newItem.id} est déjà présent ici`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.setRefItems([...this.system.items, newItem]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async removeRefItem(ref) {
|
|
||||||
await this.removeRefItems(RdDItemService.matchRefItem(ref));
|
|
||||||
}
|
|
||||||
|
|
||||||
async removeRefItems(matcher = it => false) {
|
|
||||||
await this.setRefItems(this.system.items.filter(it => !matcher(it)));
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateRefItems(matcher = it => false, update = it => { }) {
|
|
||||||
const updatedList = this.system.items.map(it => {
|
|
||||||
if (matcher(it)) {
|
|
||||||
update(it);
|
|
||||||
}
|
|
||||||
return it;
|
|
||||||
});
|
|
||||||
await this.setRefItems(updatedList);
|
|
||||||
}
|
|
||||||
|
|
||||||
async setRefItems(newItems) {
|
|
||||||
await this.update({ 'system.items': newItems.sort(Misc.ascending(it => it.type + ':' + it.name)) });
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -60,7 +60,7 @@ export class RdDItemSheet extends ItemSheet {
|
|||||||
buttons.unshift({
|
buttons.unshift({
|
||||||
class: "vendre",
|
class: "vendre",
|
||||||
icon: "fas fa-comments-dollar",
|
icon: "fas fa-comments-dollar",
|
||||||
onclick: ev => this.item.proposerVente({service: this, quantiteMax: 1})
|
onclick: ev => this.item.proposerVente(1)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
buttons.unshift({
|
buttons.unshift({
|
||||||
|
@ -5,14 +5,14 @@ import { RdDHerbes } from "./rdd-herbes.js";
|
|||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
|
|
||||||
const typesObjetsInventaire = [
|
const typesInventaireMateriel = [
|
||||||
"arme",
|
"arme",
|
||||||
"armure",
|
"armure",
|
||||||
"conteneur",
|
"conteneur",
|
||||||
|
"faune",
|
||||||
"gemme",
|
"gemme",
|
||||||
"herbe",
|
"herbe",
|
||||||
"ingredient",
|
"ingredient",
|
||||||
"faune",
|
|
||||||
"livre",
|
"livre",
|
||||||
"monnaie",
|
"monnaie",
|
||||||
"munition",
|
"munition",
|
||||||
@ -20,6 +20,11 @@ const typesObjetsInventaire = [
|
|||||||
"objet",
|
"objet",
|
||||||
"potion",
|
"potion",
|
||||||
]
|
]
|
||||||
|
const typesInventaire = {
|
||||||
|
materiel: typesInventaireMateriel,
|
||||||
|
all: ['service'].concat(typesInventaireMateriel),
|
||||||
|
}
|
||||||
|
|
||||||
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
|
const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "danse", "jeu"]
|
||||||
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
|
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve", "rencontre"]
|
||||||
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
|
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
|
||||||
@ -58,7 +63,7 @@ export const defaultItemImg = {
|
|||||||
poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp",
|
poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp",
|
||||||
oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp",
|
oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp",
|
||||||
nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
|
nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp",
|
||||||
service: "systems/foundryvtt-reve-de-dragon/icons/items/services.webp",
|
service: "systems/foundryvtt-reve-de-dragon/icons/services/lit.webp",
|
||||||
signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp",
|
signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp",
|
||||||
gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
|
gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp",
|
||||||
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
|
||||||
@ -97,8 +102,8 @@ export class RdDItem extends Item {
|
|||||||
return game.items.get(itemRef.id ?? itemRef._id);
|
return game.items.get(itemRef.id ?? itemRef._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getItemTypesInventaire() {
|
static getItemTypesInventaire(mode = 'materiel') {
|
||||||
return typesObjetsInventaire
|
return typesInventaire[mode ?? 'materiel']
|
||||||
}
|
}
|
||||||
|
|
||||||
static getTypesOeuvres() {
|
static getTypesOeuvres() {
|
||||||
@ -150,8 +155,8 @@ export class RdDItem extends Item {
|
|||||||
isCompetence() {
|
isCompetence() {
|
||||||
return typesObjetsCompetence.includes(this.type)
|
return typesObjetsCompetence.includes(this.type)
|
||||||
}
|
}
|
||||||
isInventaire() {
|
isInventaire(mode = 'materiel') {
|
||||||
return typesObjetsInventaire.includes(this.type);
|
return RdDItem.getItemTypesInventaire(mode).includes(this.type);
|
||||||
}
|
}
|
||||||
isOeuvre() {
|
isOeuvre() {
|
||||||
return typesObjetsOeuvres.includes(this.type)
|
return typesObjetsOeuvres.includes(this.type)
|
||||||
@ -166,7 +171,6 @@ export class RdDItem extends Item {
|
|||||||
return typesObjetsConnaissance.includes(this.type)
|
return typesObjetsConnaissance.includes(this.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getItemGroup() {
|
getItemGroup() {
|
||||||
if (this.isInventaire()) return "equipement";
|
if (this.isInventaire()) return "equipement";
|
||||||
if (this.isOeuvre()) return "oeuvre";
|
if (this.isOeuvre()) return "oeuvre";
|
||||||
@ -253,6 +257,14 @@ export class RdDItem extends Item {
|
|||||||
return this.system.cout ?? 0
|
return this.system.cout ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculerPrixCommercant() {
|
||||||
|
if (this.parent?.type == 'commerce') {
|
||||||
|
// appliquer le pourcentage
|
||||||
|
return this.parent.calculerPrix(this);
|
||||||
|
}
|
||||||
|
return this.system.cout;
|
||||||
|
}
|
||||||
|
|
||||||
prepareDerivedData() {
|
prepareDerivedData() {
|
||||||
super.prepareDerivedData();
|
super.prepareDerivedData();
|
||||||
if (this.isInventaire()) {
|
if (this.isInventaire()) {
|
||||||
@ -365,7 +377,7 @@ export class RdDItem extends Item {
|
|||||||
await item.delete();
|
await item.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
|
async quantiteIncDec(nombre, options = { supprimerSiZero: false }) {
|
||||||
const quantite = Number(this.system.quantite ?? -1);
|
const quantite = Number(this.system.quantite ?? -1);
|
||||||
if (quantite >= 0) {
|
if (quantite >= 0) {
|
||||||
const reste = Math.max(quantite + Number(nombre), 0);
|
const reste = Math.max(quantite + Number(nombre), 0);
|
||||||
@ -402,7 +414,7 @@ export class RdDItem extends Item {
|
|||||||
return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
|
return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const excludedProperties = ['quantite', 'cout', 'encTotal'];
|
const excludedProperties = ['quantite', 'cout', 'encTotal', 'environnement'];
|
||||||
if (this.isComestible()) {
|
if (this.isComestible()) {
|
||||||
excludedProperties.push('sust', 'encombrement');
|
excludedProperties.push('sust', 'encombrement');
|
||||||
}
|
}
|
||||||
@ -420,7 +432,7 @@ export class RdDItem extends Item {
|
|||||||
return [true, undefined];
|
return [true, undefined];
|
||||||
}
|
}
|
||||||
|
|
||||||
async proposerVente({ service = undefined, quantiteMax = undefined }) {
|
async proposerVente(quantiteMax = undefined) {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
if (this.isConteneurNonVide()) {
|
if (this.isConteneurNonVide()) {
|
||||||
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
|
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
|
||||||
@ -428,7 +440,6 @@ export class RdDItem extends Item {
|
|||||||
}
|
}
|
||||||
await DialogItemVente.display({
|
await DialogItemVente.display({
|
||||||
item: this,
|
item: this,
|
||||||
service: service,
|
|
||||||
quantiteMax,
|
quantiteMax,
|
||||||
callback: async (vente) => {
|
callback: async (vente) => {
|
||||||
vente["properties"] = this.getProprietes();
|
vente["properties"] = this.getProprietes();
|
||||||
@ -464,7 +475,7 @@ export class RdDItem extends Item {
|
|||||||
img: this.img,
|
img: this.img,
|
||||||
pack: this.pack,
|
pack: this.pack,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
actor : this.actor ? { id: this.actor.id } : undefined,
|
actor: this.actor ? { id: this.actor.id } : undefined,
|
||||||
system: { description: this.system.description },
|
system: { description: this.system.description },
|
||||||
properties: this.getProprietes(),
|
properties: this.getProprietes(),
|
||||||
}
|
}
|
||||||
@ -475,9 +486,6 @@ export class RdDItem extends Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getChatItemTemplate() {
|
getChatItemTemplate() {
|
||||||
switch (this.type) {
|
|
||||||
case 'service': return 'systems/foundryvtt-reve-de-dragon/templates/post-item-service.html';
|
|
||||||
}
|
|
||||||
return 'systems/foundryvtt-reve-de-dragon/templates/post-item.html';
|
return 'systems/foundryvtt-reve-de-dragon/templates/post-item.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||||
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
|
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
|
||||||
import { Environnement } from "./environnement.js";
|
import { Environnement } from "./environnement.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
|
import { Monnaie } from "./item-monnaie.js";
|
||||||
|
import { RdDItem } from "./item.js";
|
||||||
|
|
||||||
class Migration {
|
class Migration {
|
||||||
get code() { return "sample"; }
|
get code() { return "sample"; }
|
||||||
@ -325,6 +328,46 @@ class _10_3_17_Monnaies extends Migration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _10_4_6_ServicesEnCommerces extends Migration {
|
||||||
|
|
||||||
|
get code() { return "migration-service-acteurs"; }
|
||||||
|
get version() { return "10.4.6"; }
|
||||||
|
|
||||||
|
async migrate() {
|
||||||
|
const servicesToMigrate = game.items.filter(it => it.type == 'service');
|
||||||
|
servicesToMigrate.forEach(async service => {
|
||||||
|
const commerce = await this.convertServiceToCommerce(service);
|
||||||
|
await RdDBaseActor.create(commerce, { renderSheet: false });
|
||||||
|
await service.delete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async convertServiceToCommerce(service) {
|
||||||
|
return {
|
||||||
|
name: service.name, img: service.img, type: 'commerce',
|
||||||
|
system: {
|
||||||
|
description: service.system.description,
|
||||||
|
notesmj: service.system.descriptionmj,
|
||||||
|
illimite: service.system.illimite
|
||||||
|
},
|
||||||
|
items: await this.transformInventaireCommerce(service)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async transformInventaireCommerce(service) {
|
||||||
|
const serviceItems = (service.system.items ?? []);
|
||||||
|
const commerceItems = await Promise.all(serviceItems.map(async (it) => { return await this.transformToItemBoutique(it); }));
|
||||||
|
return commerceItems.concat(Monnaie.monnaiesStandard());
|
||||||
|
}
|
||||||
|
|
||||||
|
async transformToItemBoutique(serviceRefItem) {
|
||||||
|
const item = await RdDItem.getCorrespondingItem(serviceRefItem);
|
||||||
|
const itemToCreate = {
|
||||||
|
name: item.name, img: item.img, type: item.type,
|
||||||
|
system: mergeObject({ cout: serviceRefItem.system.cout, quantite: serviceRefItem.system.quantite }, item.system, { overwrite: false })
|
||||||
|
};
|
||||||
|
return itemToCreate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Migrations {
|
export class Migrations {
|
||||||
static getMigrations() {
|
static getMigrations() {
|
||||||
@ -338,7 +381,8 @@ export class Migrations {
|
|||||||
new _10_2_10_DesirLancinant_IdeeFixe(),
|
new _10_2_10_DesirLancinant_IdeeFixe(),
|
||||||
new _10_3_0_Inventaire(),
|
new _10_3_0_Inventaire(),
|
||||||
new _10_3_0_FrequenceEnvironnement(),
|
new _10_3_0_FrequenceEnvironnement(),
|
||||||
new _10_3_17_Monnaies()
|
new _10_3_17_Monnaies(),
|
||||||
|
new _10_4_6_ServicesEnCommerces(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,13 +402,7 @@ export class Migrations {
|
|||||||
//if (true) { /* comment previous and uncomment here to test before upgrade */
|
//if (true) { /* comment previous and uncomment here to test before upgrade */
|
||||||
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
|
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
|
||||||
if (migrations.length > 0) {
|
if (migrations.length > 0) {
|
||||||
migrations.sort((a, b) =>
|
migrations.sort((a, b) => this.compareVersions(a, b));
|
||||||
isNewerVersion(a.version, b.version)
|
|
||||||
? 1
|
|
||||||
: isNewerVersion(b.version, a.version)
|
|
||||||
? -1
|
|
||||||
: 0
|
|
||||||
);
|
|
||||||
migrations.forEach(async (m) => {
|
migrations.forEach(async (m) => {
|
||||||
ui.notifications.info(
|
ui.notifications.info(
|
||||||
`Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}`
|
`Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}`
|
||||||
@ -390,4 +428,8 @@ export class Migrations {
|
|||||||
console.log(LOG_HEAD + `No system version changed`);
|
console.log(LOG_HEAD + `No system version changed`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compareVersions(a, b) {
|
||||||
|
return isNewerVersion(a.version, b.version) ? 1 : isNewerVersion(b.version, a.version) ? -1 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ import { RdDConteneurItemSheet } from "./item-conteneur-sheet.js";
|
|||||||
import { RdDServiceItemSheet } from "./item-service-sheet.js";
|
import { RdDServiceItemSheet } from "./item-service-sheet.js";
|
||||||
import { RdDItemService } from "./item-service.js";
|
import { RdDItemService } from "./item-service.js";
|
||||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||||
|
import { RdDCommerceSheet } from "./actor/commerce-sheet.js";
|
||||||
|
import { RdDCommerce } from "./actor/commerce.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RdD system
|
* RdD system
|
||||||
@ -62,6 +64,7 @@ export class SystemReveDeDragon {
|
|||||||
entite: RdDActor,
|
entite: RdDActor,
|
||||||
personnage: RdDActor,
|
personnage: RdDActor,
|
||||||
vehicule: RdDActor,
|
vehicule: RdDActor,
|
||||||
|
commerce: RdDCommerce,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,80 +80,7 @@ export class SystemReveDeDragon {
|
|||||||
RdDUtility.preloadHandlebarsTemplates();
|
RdDUtility.preloadHandlebarsTemplates();
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
game.settings.register(SYSTEM_RDD, "accorder-entite-cauchemar", {
|
this.initSystemSettings();
|
||||||
name: "Accorder le rêve aux entités",
|
|
||||||
hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar",
|
|
||||||
scope: "world",
|
|
||||||
config: true,
|
|
||||||
type: String,
|
|
||||||
choices: { // If choices are defined, the resulting setting will be a select menu
|
|
||||||
"avant-attaque": "Avant l'attaque",
|
|
||||||
"avant-defense": "Avant la défense",
|
|
||||||
"avant-encaissement": "Avant l'encaissement",
|
|
||||||
},
|
|
||||||
default: "avant-encaissement"
|
|
||||||
});
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
game.settings.register(SYSTEM_RDD, "calendrier", {
|
|
||||||
name: "calendrier",
|
|
||||||
scope: "world",
|
|
||||||
config: false,
|
|
||||||
default: RdDCalendrier.createCalendrierInitial(),
|
|
||||||
type: Object
|
|
||||||
});
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
game.settings.register(SYSTEM_RDD, "liste-nombre-astral", {
|
|
||||||
name: "liste-nombre-astral",
|
|
||||||
scope: "world",
|
|
||||||
config: false,
|
|
||||||
default: [],
|
|
||||||
type: Object
|
|
||||||
});
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
game.settings.register(SYSTEM_RDD, "calendrier-pos", {
|
|
||||||
name: "calendrierPos",
|
|
||||||
scope: "client",
|
|
||||||
config: false,
|
|
||||||
default: RdDCalendrier.createCalendrierPos(),
|
|
||||||
type: Object
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
|
|
||||||
name: "Supprimer les dialogues de combat",
|
|
||||||
hint: "Si désactivée, tous les dialogues de combat sont conservés dans la conversation",
|
|
||||||
scope: "world",
|
|
||||||
config: true,
|
|
||||||
default: true,
|
|
||||||
type: Boolean
|
|
||||||
});
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
game.settings.register(SYSTEM_RDD, "activer-sons-audio", {
|
|
||||||
name: "Activer les bruitages intégrés",
|
|
||||||
hint: "Si activé, certaines actions en jeu déclenchent un son d'ambiance",
|
|
||||||
scope: "world",
|
|
||||||
config: true,
|
|
||||||
default: true,
|
|
||||||
type: Boolean
|
|
||||||
});
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
game.settings.register(SYSTEM_RDD, "appliquer-famine-soif", {
|
|
||||||
name: "Notifier de la famine et la soif pour",
|
|
||||||
hint: "Indique si les cas de famine et de soif seront indiqués durant Château Dormant",
|
|
||||||
scope: "world",
|
|
||||||
config: true,
|
|
||||||
type: String,
|
|
||||||
choices: {
|
|
||||||
"aucun": "ni la famine, ni la soif",
|
|
||||||
"famine": "seulement la famine",
|
|
||||||
"famine-soif": "la famine et la soif",
|
|
||||||
},
|
|
||||||
default: "aucun"
|
|
||||||
});
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Set an initiative formula for the system
|
// Set an initiative formula for the system
|
||||||
@ -174,7 +104,7 @@ export class SystemReveDeDragon {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Define custom Entity classes
|
// Define custom Entity classes
|
||||||
CONFIG.Actor.documentClass = RdDActor;
|
CONFIG.Actor.documentClass = RdDBaseActor;
|
||||||
CONFIG.Item.documentClass = RdDItem;
|
CONFIG.Item.documentClass = RdDItem;
|
||||||
CONFIG.RDD = {
|
CONFIG.RDD = {
|
||||||
resolutionTable: RdDResolutionTable.resolutionTable,
|
resolutionTable: RdDResolutionTable.resolutionTable,
|
||||||
@ -186,6 +116,7 @@ export class SystemReveDeDragon {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Register sheet application classes
|
// Register sheet application classes
|
||||||
Actors.unregisterSheet("core", ActorSheet);
|
Actors.unregisterSheet("core", ActorSheet);
|
||||||
|
Actors.registerSheet(SYSTEM_RDD, RdDCommerceSheet, { types: ["commerce"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorSheet, { types: ["personnage"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorCreatureSheet, { types: ["creature"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorCreatureSheet, { types: ["creature"], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
|
||||||
@ -235,6 +166,84 @@ export class SystemReveDeDragon {
|
|||||||
Hooks.once('ready', () => this.onReady());
|
Hooks.once('ready', () => this.onReady());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initSystemSettings() {
|
||||||
|
game.settings.register(SYSTEM_RDD, "accorder-entite-cauchemar", {
|
||||||
|
name: "Accorder le rêve aux entités",
|
||||||
|
hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar",
|
||||||
|
scope: "world",
|
||||||
|
config: true,
|
||||||
|
type: String,
|
||||||
|
choices: {
|
||||||
|
"avant-attaque": "Avant l'attaque",
|
||||||
|
"avant-defense": "Avant la défense",
|
||||||
|
"avant-encaissement": "Avant l'encaissement",
|
||||||
|
},
|
||||||
|
default: "avant-encaissement"
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
game.settings.register(SYSTEM_RDD, "calendrier", {
|
||||||
|
name: "calendrier",
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
default: RdDCalendrier.createCalendrierInitial(),
|
||||||
|
type: Object
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
game.settings.register(SYSTEM_RDD, "liste-nombre-astral", {
|
||||||
|
name: "liste-nombre-astral",
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
default: [],
|
||||||
|
type: Object
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
game.settings.register(SYSTEM_RDD, "calendrier-pos", {
|
||||||
|
name: "calendrierPos",
|
||||||
|
scope: "client",
|
||||||
|
config: false,
|
||||||
|
default: RdDCalendrier.createCalendrierPos(),
|
||||||
|
type: Object
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
game.settings.register(SYSTEM_RDD, "supprimer-dialogues-combat-chat", {
|
||||||
|
name: "Supprimer les dialogues de combat",
|
||||||
|
hint: "Si désactivée, tous les dialogues de combat sont conservés dans la conversation",
|
||||||
|
scope: "world",
|
||||||
|
config: true,
|
||||||
|
default: true,
|
||||||
|
type: Boolean
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
game.settings.register(SYSTEM_RDD, "activer-sons-audio", {
|
||||||
|
name: "Activer les bruitages intégrés",
|
||||||
|
hint: "Si activé, certaines actions en jeu déclenchent un son d'ambiance",
|
||||||
|
scope: "world",
|
||||||
|
config: true,
|
||||||
|
default: true,
|
||||||
|
type: Boolean
|
||||||
|
});
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
game.settings.register(SYSTEM_RDD, "appliquer-famine-soif", {
|
||||||
|
name: "Notifier de la famine et la soif pour",
|
||||||
|
hint: "Indique si les cas de famine et de soif seront indiqués durant Château Dormant",
|
||||||
|
scope: "world",
|
||||||
|
config: true,
|
||||||
|
type: String,
|
||||||
|
choices: {
|
||||||
|
"aucun": "ni la famine, ni la soif",
|
||||||
|
"famine": "seulement la famine",
|
||||||
|
"famine-soif": "la famine et la soif",
|
||||||
|
},
|
||||||
|
default: "aucun"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async onReady() {
|
async onReady() {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { RdDActor } from "./actor.js";
|
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDDice } from "./rdd-dice.js";
|
import { RdDDice } from "./rdd-dice.js";
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ export class RdDNameGen {
|
|||||||
|
|
||||||
static async onCreerActeur(event) {
|
static async onCreerActeur(event) {
|
||||||
const button = event.currentTarget;
|
const button = event.currentTarget;
|
||||||
await RdDActor.create({
|
await RdDBaseActor.create({
|
||||||
name: button.attributes['data-nom'].value,
|
name: button.attributes['data-nom'].value,
|
||||||
type: button.attributes['data-type'].value
|
type: button.attributes['data-type'].value
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { DialogSplitItem } from "./dialog-split-item.js";
|
import { DialogSplitItem } from "./dialog-split-item.js";
|
||||||
|
import { RdDItem } from "./item.js";
|
||||||
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
|
|
||||||
export class RdDSheetUtility {
|
export class RdDSheetUtility {
|
||||||
|
|
||||||
@ -19,8 +21,11 @@ export class RdDSheetUtility {
|
|||||||
return $(event.currentTarget)?.parents(".item");
|
return $(event.currentTarget)?.parents(".item");
|
||||||
}
|
}
|
||||||
|
|
||||||
static prepareItemDropParameters(destItemId, actor, dragData, objetVersConteneur) {
|
static async prepareItemDropParameters(destItemId, actor, dragData, objetVersConteneur) {
|
||||||
const item = fromUuidSync(dragData.uuid)
|
let item = fromUuidSync(dragData.uuid);
|
||||||
|
if (item.pack && !item.system){
|
||||||
|
item = await RdDItem.getCorrespondingItem(item);
|
||||||
|
}
|
||||||
if (actor.canReceive(item)) {
|
if (actor.canReceive(item)) {
|
||||||
return {
|
return {
|
||||||
destId: destItemId,
|
destId: destItemId,
|
||||||
|
@ -16,6 +16,7 @@ import { RdDCalendrier } from "./rdd-calendrier.js";
|
|||||||
import { Environnement } from "./environnement.js";
|
import { Environnement } from "./environnement.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
|
import { RdDCommerce } from "./actor/commerce.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// This table starts at 0 -> niveau -10
|
// This table starts at 0 -> niveau -10
|
||||||
@ -170,6 +171,8 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-animaux.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.html',
|
||||||
//Items
|
//Items
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs',
|
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs',
|
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs',
|
||||||
@ -178,32 +181,6 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html',
|
'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
|
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-arme-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-armure-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-objet-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-conteneur-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-sort-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-herbe-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-ingredient-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-faune-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-livre-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-tache-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-potion-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-rencontre-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-souffle-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-tarot-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-tete-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-ombre-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-monnaie-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-meditation-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-nourritureboisson-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-signedraconique-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-possession-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-extraitpoetique-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/item-service-sheet.html',
|
|
||||||
// partial enums
|
// partial enums
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
|
'systems/foundryvtt-reve-de-dragon/templates/enum-base-competence.html',
|
||||||
@ -296,8 +273,9 @@ export class RdDUtility {
|
|||||||
Handlebars.registerHelper('apostrophe', (article, str) => Grammar.apostrophe(article, str));
|
Handlebars.registerHelper('apostrophe', (article, str) => Grammar.apostrophe(article, str));
|
||||||
Handlebars.registerHelper('un', str => Grammar.articleIndetermine(str));
|
Handlebars.registerHelper('un', str => Grammar.articleIndetermine(str));
|
||||||
Handlebars.registerHelper('accord', (genre, ...args) => Grammar.accord(genre, args));
|
Handlebars.registerHelper('accord', (genre, ...args) => Grammar.accord(genre, args));
|
||||||
Handlebars.registerHelper('buildConteneur', (objet) => { return new Handlebars.SafeString(RdDUtility.buildConteneur(objet)); });
|
Handlebars.registerHelper('buildConteneur', (objet, templateItem, options) => { return new Handlebars.SafeString(RdDUtility.buildConteneur(objet, 1, templateItem, options)); });
|
||||||
Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); });
|
Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); });
|
||||||
|
Handlebars.registerHelper('calculerPrixCommercant', item => item.calculerPrixCommercant());
|
||||||
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
|
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
|
||||||
Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
|
Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord));
|
||||||
Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type));
|
Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type));
|
||||||
@ -472,29 +450,34 @@ export class RdDUtility {
|
|||||||
/** Construit la structure récursive des conteneurs, avec imbrication potentielle
|
/** Construit la structure récursive des conteneurs, avec imbrication potentielle
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static buildConteneur(objet, profondeur) {
|
static buildConteneur(objet, profondeur, templateItem, options) {
|
||||||
if (!profondeur) profondeur = 1;
|
if (!profondeur) profondeur = 1;
|
||||||
|
if (!templateItem) templateItem = 'actor/inventaire-item.html'
|
||||||
objet.niveau = profondeur;
|
objet.niveau = profondeur;
|
||||||
|
|
||||||
const isConteneur = objet.type == 'conteneur';
|
const isConteneur = objet.type == 'conteneur';
|
||||||
const isOuvert = isConteneur && this.getAfficheContenu(objet._id);
|
const isOuvert = isConteneur && this.getAfficheContenu(objet._id);
|
||||||
const isVide = isConteneur && objet.system.contenu.length == 0;
|
const isVide = isConteneur && objet.system.contenu.length == 0;
|
||||||
const conteneur = Handlebars.partials['systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-item.html']({
|
const conteneur = Handlebars.partials[`systems/foundryvtt-reve-de-dragon/templates/${templateItem}`]({
|
||||||
item: objet,
|
item: objet,
|
||||||
vide: isVide,
|
vide: isVide,
|
||||||
ouvert: isOuvert
|
ouvert: isOuvert,
|
||||||
|
options: options
|
||||||
});
|
});
|
||||||
const contenu = isConteneur ? RdDUtility.buildContenu(objet, profondeur, isOuvert) : '';
|
const contenu = isConteneur ? RdDUtility.buildContenu(objet, profondeur, isOuvert, templateItem, options) : '';
|
||||||
return conteneur + contenu;
|
return conteneur + contenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static buildContenu(objet, profondeur, afficherContenu) {
|
static buildContenu(objet, profondeur, afficherContenu, templateItem, options) {
|
||||||
if (!profondeur) profondeur = 1;
|
if (!profondeur) profondeur = 1;
|
||||||
|
if (!templateItem) templateItem = 'actor/inventaire-item.html'
|
||||||
objet.niveau = profondeur;
|
objet.niveau = profondeur;
|
||||||
|
|
||||||
const display = afficherContenu ? 'item-display-show' : 'item-display-hide';
|
const display = afficherContenu ? 'item-display-show' : 'item-display-hide';
|
||||||
let strContenu = `<ul class='item-list alterne-list ${display} list-item-margin${Math.min(profondeur,6)}'>`;
|
let strContenu = `<ul class='item-list alterne-list ${display} list-item-margin${Math.min(profondeur,6)}'>`;
|
||||||
for (let subItem of objet.subItems) {
|
for (let subItem of objet.subItems) {
|
||||||
strContenu += this.buildConteneur(subItem, profondeur + 1);
|
strContenu += this.buildConteneur(subItem, profondeur + 1, templateItem, options);
|
||||||
}
|
}
|
||||||
return strContenu + "</ul>";
|
return strContenu + "</ul>";
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"id": "foundryvtt-reve-de-dragon",
|
"id": "foundryvtt-reve-de-dragon",
|
||||||
"title": "Rêve de Dragon",
|
"title": "Rêve de Dragon",
|
||||||
"version": "10.4.5",
|
"version": "10.4.6",
|
||||||
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.4.5.zip",
|
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.4.6.zip",
|
||||||
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
|
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "10",
|
"minimum": "10",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"Actor": {
|
"Actor": {
|
||||||
"types": ["personnage", "creature", "entite", "vehicule"],
|
"types": ["personnage", "creature", "entite", "commerce", "vehicule"],
|
||||||
"templates": {
|
"templates": {
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Description ...",
|
"description": "Description ...",
|
||||||
@ -554,6 +554,11 @@
|
|||||||
},
|
},
|
||||||
"vehicule": {
|
"vehicule": {
|
||||||
"templates": [ "vehicule", "description" ]
|
"templates": [ "vehicule", "description" ]
|
||||||
|
},
|
||||||
|
"commerce":{
|
||||||
|
"templates": [ "description" ],
|
||||||
|
"pourcentage": 100,
|
||||||
|
"illimite": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Item": {
|
"Item": {
|
||||||
@ -579,7 +584,7 @@
|
|||||||
"encombrement": 0,
|
"encombrement": 0,
|
||||||
"quantite": 1,
|
"quantite": 1,
|
||||||
"qualite": 0,
|
"qualite": 0,
|
||||||
"cout": 0
|
"cout": 0.0
|
||||||
},
|
},
|
||||||
"environnement": {
|
"environnement": {
|
||||||
"milieu": "",
|
"milieu": "",
|
||||||
@ -743,10 +748,8 @@
|
|||||||
"prdate": 0
|
"prdate": 0
|
||||||
},
|
},
|
||||||
"service": {
|
"service": {
|
||||||
"templates": [ "description"],
|
"templates": [ "description", "inventaire" ],
|
||||||
"illimite": false,
|
"moral": false
|
||||||
"items": [],
|
|
||||||
"services": []
|
|
||||||
},
|
},
|
||||||
"musique": {
|
"musique": {
|
||||||
"templates": [ "description" ],
|
"templates": [ "description" ],
|
||||||
|
@ -189,7 +189,7 @@
|
|||||||
<article class="flexcol">
|
<article class="flexcol">
|
||||||
<h3>Biographie : </h3>
|
<h3>Biographie : </h3>
|
||||||
<div class="form-group large-editor">
|
<div class="form-group large-editor">
|
||||||
{{editor biographie target="system.biographie" button=true owner=owner editable=true engine="prosemirror"}}
|
{{editor biographie target="system.biographie" button=true owner=options.owner editable=true engine="prosemirror"}}
|
||||||
</div>
|
</div>
|
||||||
<h3>Notes : </h3>
|
<h3>Notes : </h3>
|
||||||
<div class="form-group large-editor">
|
<div class="form-group large-editor">
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="caracteristique flexrow list-item">
|
<li class="caracteristique flexrow list-item">
|
||||||
<label class="derivee-label">{{system.compteurs.exaltation.label}}</label>
|
<label class="derivee-label">{{system.compteurs.exaltation.label}}</label>
|
||||||
<input class="derivee-value" type="text" name="{{system.compteurs.exaltation.value}}" value="{{system.compteurs.exaltation.value}}" data-dtype="number"/>
|
<input class="derivee-value" type="text" name="system.compteurs.exaltation.value" value="{{system.compteurs.exaltation.value}}" data-dtype="number"/>
|
||||||
<label class="derivee-label">{{system.compteurs.dissolution.label}}</label>
|
<label class="derivee-label">{{system.compteurs.dissolution.label}}</label>
|
||||||
<input class="derivee-value" type="text" name="{{system.compteurs.dissolution.value}}" value="{{system.compteurs.dissolution.value}}" data-dtype="number"/>
|
<input class="derivee-value" type="text" name="system.compteurs.dissolution.value" value="{{system.compteurs.dissolution.value}}" data-dtype="number"/>
|
||||||
</li>
|
</li>
|
||||||
<li class="caracteristique flexrow list-item">
|
<li class="caracteristique flexrow list-item">
|
||||||
<label class="derivee-label chance-actuelle"><a>Chance actuelle</a></label>
|
<label class="derivee-label chance-actuelle"><a>Chance actuelle</a></label>
|
||||||
|
79
templates/actor/commerce-actor-sheet.html
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
|
||||||
|
{{!-- Sheet Header --}}
|
||||||
|
<header class="sheet-header">
|
||||||
|
<div class="header-fields">
|
||||||
|
<div class="flexrow">
|
||||||
|
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||||
|
<div class="flexcol">
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
|
||||||
|
{{#if @root.options.isObserver}}
|
||||||
|
<div class="form-group">
|
||||||
|
<input {{@root.disabled}} class="attribute-value" type="checkbox" name="system.illimite" {{#if system.illimite}}checked{{/if}}/>
|
||||||
|
<label for="system.illimite">Quantité illimitée en vente</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<span>
|
||||||
|
<label for="system.pourcentage">Appliquer un pourcentage sur les prix</label>
|
||||||
|
<input {{@root.disabled}} class="attribute-value" type="number" data-dtype="Number"
|
||||||
|
name="system.pourcentage" value="{{system.pourcentage}}"
|
||||||
|
min="20" max="500" step="5"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
<div class="flexcol form-group medium-editor">
|
||||||
|
{{editor description target="system.description" button=true owner=options.owner editable=options.isOwner engine="prosemirror"}}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.html"}}
|
||||||
|
{{#unless system.illimite}}
|
||||||
|
{{#if @root.options.isObserver}}
|
||||||
|
<hr>
|
||||||
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html"}}
|
||||||
|
{{/if}}
|
||||||
|
{{/unless}}
|
||||||
|
{{!--
|
||||||
|
<br>
|
||||||
|
<div class="flexcol">
|
||||||
|
<ul class="item-list alterne-list">
|
||||||
|
<li class="item flexrow list-item">
|
||||||
|
<label class="flex-grow">Service</label>
|
||||||
|
<label>Moral</label>
|
||||||
|
<label>Qualité</label>
|
||||||
|
<label>Prix (sols)</label>
|
||||||
|
<label>
|
||||||
|
{{#unless disabled}}
|
||||||
|
<a class="service-add"><i class="fas fa-plus-circle"></i></a>
|
||||||
|
{{/unless}}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
{{#each system.services as |service key|}}
|
||||||
|
<li class="item flexrow list-item" data-key="{{key}}">
|
||||||
|
<input {{@root.disabled}} type="text" name="services[{{key}}].name" value="{{service.name}}" data-dtype="String" />
|
||||||
|
<input {{@root.disabled}} type="checkbox" name="services[{{key}}].system.moral" {{#if service.system.moral}}checked{{/if}} />
|
||||||
|
<input {{@root.disabled}} type="number" name="services[{{key}}].system.qualite" value="{{service.system.qualite}}" data-dtype="Number" min="-10" max="10"/>
|
||||||
|
<input {{@root.disabled}} type="number" class="input-prix" name="services[{{key}}].system.cout" value="{{numberFormat service.system.cout decimals=2 sign=false}}" data-dtype="Number" min="0" />
|
||||||
|
<div class="item-controls">
|
||||||
|
<a class="service-acheter" title="Acheter"><i class="fa-sharp fa-solid fa-coins"></i></a>
|
||||||
|
{{#unless @root.disabled}}
|
||||||
|
<a class="service-vendre" title="Proposer"><i class="fas fa-comments-dollar"></i></a>
|
||||||
|
<a class="service-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
--}}
|
||||||
|
<br>
|
||||||
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html"}}
|
||||||
|
<br>
|
||||||
|
</section>
|
||||||
|
</form>
|
64
templates/actor/commerce-inventaire-item.html
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
{{#if (ne item.type 'monnaie')}}
|
||||||
|
<li class="item flexrow list-item" data-item-id="{{item._id}}" draggable="true">
|
||||||
|
<span class="equipement-nom {{#if (eq item.type 'conteneur')}}conteneur-name{{/if}} ">
|
||||||
|
<a{{#if (and (ne item.type 'conteneur') options.isObserver)}} class="item-edit"{{/if}} >
|
||||||
|
{{#if (eq item.type 'conteneur')}}
|
||||||
|
<i class="{{~#if vide}}far fa-square
|
||||||
|
{{else if ouvert}}far fa-minus-square
|
||||||
|
{{else}}far fa-plus-square
|
||||||
|
{{/if~}}"></i>
|
||||||
|
{{/if}}
|
||||||
|
<img class="sheet-competence-img" src="{{item.img}}" title="{{item.name}}"/>
|
||||||
|
<span>{{item.name}}</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{{log 'item-inventaire' this}}
|
||||||
|
{{#unless item.parent.system.illimite}}
|
||||||
|
<span class="equipement-detail flexrow">
|
||||||
|
{{#unless (or (eq item.type 'service') (and (eq item.type 'conteneur') (not vide)))}}
|
||||||
|
{{#if options.isOwner}}
|
||||||
|
<a class="item-quantite-moins"><i class="fas fa-minus-square"></i></a>
|
||||||
|
{{/if}}
|
||||||
|
<input {{#unless options.isOwner}}disabled{{/unless}} type="number" data-dtype="Number"
|
||||||
|
class="item-quantite" name="items[{{key}}].system.quantite"
|
||||||
|
value="{{item.system.quantite}}" />
|
||||||
|
{{#if options.isOwner}}
|
||||||
|
<a class="item-quantite-plus"><i class="fas fa-plus-square"></i></a>
|
||||||
|
{{/if}}
|
||||||
|
{{/unless}}
|
||||||
|
</span>
|
||||||
|
{{/unless}}
|
||||||
|
<span class="equipement-detail">
|
||||||
|
{{#unless (and (eq item.type 'conteneur') (not vide))}}
|
||||||
|
<input {{#unless options.isOwner}}disabled{{/unless}} type="number" data-dtype="Number"
|
||||||
|
class="input-prix number-x3 item-cout" name="items[{{key}}].system.cout"
|
||||||
|
{{#if options.isObserver}}
|
||||||
|
value="{{numberFormat item.system.cout decimals=2 sign=false}}"
|
||||||
|
{{else}}
|
||||||
|
value="{{numberFormat (calculerPrixCommercant item) decimals=2 sign=false}}"
|
||||||
|
{{/if}} />
|
||||||
|
{{/unless}}
|
||||||
|
</span>
|
||||||
|
<span class="equipement-actions item-controls">
|
||||||
|
{{#if options.isOwner}}
|
||||||
|
{{#if (and (eq item.type 'conteneur') (not vide))}}
|
||||||
|
<a class="item-edit" title="Editer"><i class="fas fa-edit"></i></a>
|
||||||
|
{{else}}
|
||||||
|
<a class="item-edit" title="Editer"><i class="fas fa-edit"></i></a>
|
||||||
|
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
||||||
|
{{#if (or item.parent.system.illimite (ne item.system.quantite 0))}}
|
||||||
|
<a class="item-vendre" title="Vendre"><i class="fas fa-comments-dollar"></i></a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (gt item.system.quantite 0)}}
|
||||||
|
<a class="item-acheter" title="Acheter"><i class="fa-regular fa-coins"></i></a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
{{#if (or item.parent.system.illimite (gt item.system.quantite 0))}}
|
||||||
|
<a class="item-acheter" title="Acheter"><i class="fa-regular fa-coins"></i></a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
<a class="item-montrer" title="Montrer"><i class="fas fa-comment"></i></a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
36
templates/actor/commerce-inventaire.html
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<h4>Boutique</h4>
|
||||||
|
<span class="item-name">
|
||||||
|
{{#if options.isGM}}
|
||||||
|
<a class="chat-card-button creer-un-objet">Nouvel objet</a>
|
||||||
|
<a class="chat-card-button nettoyer-conteneurs">Tout vider</a>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#unless system.illimite}}
|
||||||
|
{{#if calc.surEncombrementMessage}}<b>{{calc.surEncombrementMessage}}</b> ‐{{/if}}
|
||||||
|
Encombrement: {{numberFormat calc.encTotal decimals=2}}
|
||||||
|
{{#if (regle-optionnelle 'afficher-prix-joueurs')}}
|
||||||
|
‐ Valeur: {{numberFormat calc.prixTotalEquipement decimals=2}} Sols
|
||||||
|
{{/if}}
|
||||||
|
{{/unless}}
|
||||||
|
</span>
|
||||||
|
<ul class="item-list alterne-list">
|
||||||
|
<li class="competence-header flexrow">
|
||||||
|
<span class="equipement-nom">Nom</span>
|
||||||
|
{{#unless system.illimite}}
|
||||||
|
<span class="equipement-detail">Quantité</span>
|
||||||
|
{{/unless}}
|
||||||
|
<span class="equipement-detail">Prix (sols)</span>
|
||||||
|
<span class="equipement-actions">Actions</span>
|
||||||
|
</li>
|
||||||
|
{{#each objets as |item id|}}
|
||||||
|
{{#unless item.estContenu}}
|
||||||
|
{{#if (ne item.type 'conteneur')}}
|
||||||
|
{{> "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.html"
|
||||||
|
item=item vide=true ouvert=true options=../options}}
|
||||||
|
{{/if}}
|
||||||
|
{{/unless}}
|
||||||
|
{{/each}}
|
||||||
|
{{#each conteneurs as |conteneur id|}}
|
||||||
|
{{buildConteneur conteneur 'actor/commerce-inventaire-item.html' ../options}}
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
@ -20,11 +20,11 @@
|
|||||||
{{#each objets as |item id|}}
|
{{#each objets as |item id|}}
|
||||||
{{#unless item.estContenu}}
|
{{#unless item.estContenu}}
|
||||||
{{#if (ne item.type 'conteneur')}}
|
{{#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}}
|
{{/if}}
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#each conteneurs as |conteneur id|}}
|
{{#each conteneurs as |conteneur id|}}
|
||||||
{{buildConteneur this}}
|
{{buildConteneur this 'actor/inventaire-item.html' @root.options}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (ne prixLot 0)}}
|
{{#if (ne prixLot 0)}}
|
||||||
<span><strong>Prix {{#if (gt tailleLot 1)}}du lot {{else}}unitaire{{/if}}:
|
<span><strong>Prix {{#if (gt tailleLot 1)}}du lot {{else}}unitaire{{/if}}:
|
||||||
<span class="prixLot">{{prixLot}}</span> Sols</strong></span><br>
|
<span class="prixLot">{{numberFormat prixLot decimals=2 sign=false}}</span> Sols</strong></span><br>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</p>
|
</p>
|
||||||
{{#if (or (gt quantiteNbLots 0) quantiteIllimite)}}
|
{{#if (or (gt quantiteNbLots 0) quantiteIllimite)}}
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="flexrow flex-center">
|
<div class="flexrow flex-center">
|
||||||
<div>
|
<div>
|
||||||
{{#if service}}
|
{{#if vendeur}}
|
||||||
<img class="chat-icon" src="{{service.img}}" title="{{service.name}}" alt="{{service.name}}" />
|
|
||||||
{{else if vendeur}}
|
|
||||||
<img class="chat-icon" src="{{vendeur.img}}" title="{{vendeur.name}}" alt="{{vendeur.name}}" />
|
<img class="chat-icon" src="{{vendeur.img}}" title="{{vendeur.name}}" alt="{{vendeur.name}}" />
|
||||||
{{else}}
|
{{else}}
|
||||||
<img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon_echoppe.webp" title="Un commerçant" alt="Vendeur MJ" />
|
<img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/styles/img/ui/icon_echoppe.webp" title="Un commerçant" alt="Vendeur MJ" />
|
||||||
@ -85,12 +83,12 @@
|
|||||||
{{#if isVente}}
|
{{#if isVente}}
|
||||||
<div class="flexrow flex-group-left">
|
<div class="flexrow flex-group-left">
|
||||||
<label>Prix {{#if (gt tailleLot 1)}}du lot{{else}}unitaire{{/if}}</label>
|
<label>Prix {{#if (gt tailleLot 1)}}du lot{{else}}unitaire{{/if}}</label>
|
||||||
<label>{{prixLot}} Sols</label>
|
<label>{{numberFormat prixLot decimals=2 sign=false}} Sols</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flexrow flex-group-left">
|
<div class="flexrow flex-group-left">
|
||||||
<label>Prix total</label>
|
<label>Prix total</label>
|
||||||
<span>
|
<span>
|
||||||
<span class="prixTotal">{{prixTotal}}</span>
|
<span class="prixTotal">{{numberFormat prixTotal decimals=2 sign=false}}</span>
|
||||||
Sols
|
Sols
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,13 +26,13 @@
|
|||||||
max="{{quantiteMax}}" value="{{tailleLot}}" data-dtype="Number" />
|
max="{{quantiteMax}}" value="{{tailleLot}}" data-dtype="Number" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flexrow flex-group-left">
|
<div class="flexrow flex-group-left">
|
||||||
<label>Valeur unitaire</label>
|
<label>Prix unitaire</label>
|
||||||
<label>{{prixOrigine}} Sols</label>
|
<label>{{numberFormat prixOrigine decimals=2 sign=false}} Sols</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flexrow flex-group-left">
|
<div class="flexrow flex-group-left">
|
||||||
<label for="prixLot">Prix du lot</label>
|
<label for="prixLot">Prix du lot</label>
|
||||||
<span class="flexrow">
|
<span class="flexrow">
|
||||||
<input name="prixLot" class="prixLot flex-shrink" type="number" value="{{prixLot}}"
|
<input name="prixLot" class="prixLot flex-shrink" type="number" value="{{numberFormat prixLot decimals=2 sign=false}}"
|
||||||
data-dtype="Number" />
|
data-dtype="Number" />
|
||||||
<label>Sols</label>
|
<label>Sols</label>
|
||||||
</span>
|
</span>
|
||||||
|
@ -2,102 +2,23 @@
|
|||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/header-item.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/header-item.html"}}
|
||||||
|
|
||||||
<section class="sheet-body">
|
<section class="sheet-body">
|
||||||
<div class="flexcol form-group small-editor">
|
|
||||||
{{editor description target="system.description" button=true owner=owner editable=(or isGM isOwner) engine="prosemirror"}}
|
|
||||||
</div>
|
|
||||||
{{!--
|
|
||||||
<div class="flexcol">
|
|
||||||
<ul class="item-list alterne-list">
|
|
||||||
<li class="item flexrow list-item">
|
|
||||||
<label class="flex-grow">Service</label>
|
|
||||||
<label>Moral</label>
|
|
||||||
<label>Qualité</label>
|
|
||||||
<label>Prix (sols)</label>
|
|
||||||
<label>
|
|
||||||
{{#unless disabled}}
|
|
||||||
<a class="service-add"><i class="fas fa-plus-circle"></i></a>
|
|
||||||
{{/unless}}
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
{{#each system.services as |service key|}}
|
|
||||||
<li class="item flexrow list-item" data-key="{{key}}">
|
|
||||||
<input {{@root.disabled}} type="text" name="services[{{key}}].name" value="{{service.name}}" data-dtype="String" />
|
|
||||||
<input {{@root.disabled}} type="checkbox" name="services[{{key}}].system.moral" {{#if service.system.moral}}checked{{/if}} />
|
|
||||||
<input {{@root.disabled}} type="number" name="services[{{key}}].system.qualite" value="{{service.system.qualite}}" data-dtype="Number" min="-10" max="10"/>
|
|
||||||
<input {{@root.disabled}} type="number" class="input-prix" name="services[{{key}}].system.cout" value="{{numberFormat service.system.cout decimals=2 sign=false}}" data-dtype="Number" min="0" />
|
|
||||||
<div class="item-controls">
|
|
||||||
<a class="service-acheter" title="Acheter"><i class="fa-sharp fa-solid fa-coins"></i></a>
|
|
||||||
{{#unless @root.disabled}}
|
|
||||||
<a class="service-vendre" title="Proposer"><i class="fas fa-comments-dollar"></i></a>
|
|
||||||
<a class="service-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
|
||||||
{{/unless}}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
--}}
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input {{@root.disabled}} class="attribute-value" type="checkbox" name="system.illimite" {{#if system.illimite}}checked{{/if}}/>
|
<span for="system.moral">Jet de moral en situation heureuse</span>
|
||||||
<span for="system.illimite">Quantité en vente illimitée</span>
|
<input {{@root.disabled}} class="attribute-value" type="checkbox" name="system.moral" {{#if system.moral}}checked{{/if}}/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flexcol">
|
|
||||||
<ul class="item-list alterne-list">
|
<div class="form-group">
|
||||||
<li class="item flexrow list-item">
|
<label for="system.qualite">Qualité</label>
|
||||||
<label class="flex-grow">A vendre</label>
|
<input class="attribute-value number-x3" type="number" name="system.qualite" value="{{system.qualite}}" data-dtype="Number"
|
||||||
{{#unless system.illimite}}
|
{{#unless (isFieldInventaireModifiable type 'qualite')}}disabled{{/unless}}/>
|
||||||
<label>Quantite</label>
|
|
||||||
{{/unless}}
|
|
||||||
<label>Prix (sols)</label>
|
|
||||||
<div class="item-controls">
|
|
||||||
{{#unless disabled}}
|
|
||||||
<a class="sub-item-info-add" title="Utiliser le drag&drop pour ajouter un objet dans la liste">
|
|
||||||
<i class="fa-solid fa-circle-info"></i>
|
|
||||||
</a>
|
|
||||||
{{/unless}}
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
{{#each system.items as |item key|}}
|
<div class="form-group item-cout">
|
||||||
<li class="item flexrow list-item service-item" data-item-id="{{item.id}}" data-pack="{{item.pack}}" data-key="{{key}}">
|
<label for="system.cout">Prix (sols)</label>
|
||||||
<label class="flex-grow">
|
<input class="input-prix attribute-value number-x3" type="number" name="system.cout" value="{{numberFormat system.cout decimals=2 sign=false}}" data-dtype="Number"
|
||||||
{{#if item.img}}<img class="sheet-competence-img" src="{{item.img}}" title="{{item.name}}"/>{{/if}}
|
{{#unless (isFieldInventaireModifiable type 'cout')}}disabled{{/unless}}/>
|
||||||
{{> 'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs'
|
|
||||||
pack=item.pack id=item.id name=item.name}}
|
|
||||||
</label>
|
|
||||||
{{#unless @root.system.illimite}}
|
|
||||||
<span class="flexrow">
|
|
||||||
{{#unless @root.disabled}}
|
|
||||||
<a class="sub-item-quantite-moins"><i class="fas fa-minus-square"></i></a>
|
|
||||||
{{/unless}}
|
|
||||||
<input {{@root.disabled}} type="number" class="sub-item-quantite" name="items[{{key}}].system.quantite" value="{{item.system.quantite}}" data-dtype="Number" />
|
|
||||||
{{#unless @root.disabled}}
|
|
||||||
<a class="sub-item-quantite-plus"><i class="fas fa-plus-square"></i></a>
|
|
||||||
{{/unless}}
|
|
||||||
</span>
|
|
||||||
{{/unless}}
|
|
||||||
<span class="flexrow">
|
|
||||||
<input {{@root.disabled}} type="number" class="input-prix number-x3 sub-item-cout" name="items[{{key}}].system.cout" value="{{numberFormat item.system.cout decimals=2 sign=false}}" data-dtype="Number" />
|
|
||||||
</span>
|
|
||||||
<div class="item-controls">
|
|
||||||
<a class="sub-item-acheter" title="Acheter"><i class="fa-regular fa-coins"></i></a>
|
|
||||||
{{#unless @root.disabled}}
|
|
||||||
<a class="sub-item-vendre" title="Vendre"><i class="fas fa-comments-dollar"></i></a>
|
|
||||||
<a class="sub-item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
|
|
||||||
{{/unless}}
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
{{/each}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{{#if isGM}}
|
|
||||||
<br>
|
|
||||||
<div class="flexcol">
|
|
||||||
<span><label>Description (MJ seulement): </label></span>
|
|
||||||
<div class="form-group medium-editor">
|
|
||||||
{{editor descriptionmj target="system.descriptionmj" button=true owner=owner editable=true engine="prosemirror"}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</section>
|
</section>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
<form autocomplete="off" onsubmit="event.preventDefault();">
|
<form autocomplete="off" onsubmit="event.preventDefault();">
|
||||||
{{log 'systemCompendiums'systemCompendiums}}
|
|
||||||
{{log 'availableCompendiums' availableCompendiums}}
|
|
||||||
<ul>
|
<ul>
|
||||||
{{#each systemCompendiums as |definition key|}}
|
{{#each systemCompendiums as |definition key|}}
|
||||||
<li class="flexrow">
|
<li class="flexrow">
|
||||||
|