diff --git a/icons/services/bacquet-eau.webp b/icons/services/bacquet-eau.webp new file mode 100644 index 00000000..a8546ed3 Binary files /dev/null and b/icons/services/bacquet-eau.webp differ diff --git a/icons/items/services.webp b/icons/services/commerce.webp similarity index 100% rename from icons/items/services.webp rename to icons/services/commerce.webp diff --git a/icons/services/compagnie.webp b/icons/services/compagnie.webp new file mode 100644 index 00000000..d6d89a95 Binary files /dev/null and b/icons/services/compagnie.webp differ diff --git a/icons/services/lit.webp b/icons/services/lit.webp new file mode 100644 index 00000000..9d3586d3 Binary files /dev/null and b/icons/services/lit.webp differ diff --git a/icons/services/paiement.webp b/icons/services/paiement.webp new file mode 100644 index 00000000..68d1f887 Binary files /dev/null and b/icons/services/paiement.webp differ diff --git a/lang/fr.json b/lang/fr.json index 36819273..8fa8f3fd 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -3,6 +3,7 @@ "TypePersonnage": "Personnage", "TypeCreature": "Créature", "TypeEntite": "Entité de cauchemar", + "TypeCommerce": "Commerce", "TypeVehicule": "Véhicule" }, "ITEM": { diff --git a/module/actor/commerce-sheet.js b/module/actor/commerce-sheet.js new file mode 100644 index 00000000..e1bbb08d --- /dev/null +++ b/module/actor/commerce-sheet.js @@ -0,0 +1,68 @@ +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"; + +/** + * 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 }); + }) + } + + 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.system.cout + }); + } +} diff --git a/module/actor/commerce.js b/module/actor/commerce.js new file mode 100644 index 00000000..bed83bee --- /dev/null +++ b/module/actor/commerce.js @@ -0,0 +1,48 @@ +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()) { + 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}); + } + +} \ No newline at end of file diff --git a/module/item.js b/module/item.js index 4deec4a1..f0b84c86 100644 --- a/module/item.js +++ b/module/item.js @@ -58,7 +58,7 @@ export const defaultItemImg = { poison: "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp", oeuvre: "systems/foundryvtt-reve-de-dragon/icons/competence_comedie.webp", nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp", - service: "systems/foundryvtt-reve-de-dragon/icons/items/services.webp", + service: "systems/foundryvtt-reve-de-dragon/icons/services/lit.webp", signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", diff --git a/module/rdd-main.js b/module/rdd-main.js index 13be7ddf..2b13a1d2 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -37,6 +37,8 @@ import { RdDConteneurItemSheet } from "./item-conteneur-sheet.js"; import { RdDServiceItemSheet } from "./item-service-sheet.js"; import { RdDItemService } from "./item-service.js"; import { RdDBaseActor } from "./actor/base-actor.js"; +import { RdDCommerceSheet } from "./actor/commerce-sheet.js"; +import { RdDCommerce } from "./actor/commerce.js"; /** * RdD system @@ -62,6 +64,7 @@ export class SystemReveDeDragon { entite: RdDActor, personnage: RdDActor, vehicule: RdDActor, + commerce: RdDCommerce, } } @@ -113,6 +116,7 @@ export class SystemReveDeDragon { /* -------------------------------------------- */ // Register sheet application classes 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, RdDActorCreatureSheet, { types: ["creature"], makeDefault: true }); Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }); diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 083bcb95..f8bb2c42 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -170,6 +170,8 @@ export class RdDUtility { '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-vehicules.html', + 'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.html', + 'systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire-item.html', //Items 'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs', 'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs', @@ -296,7 +298,7 @@ export class RdDUtility { Handlebars.registerHelper('apostrophe', (article, str) => Grammar.apostrophe(article, str)); Handlebars.registerHelper('un', str => Grammar.articleIndetermine(str)); Handlebars.registerHelper('accord', (genre, ...args) => Grammar.accord(genre, args)); - Handlebars.registerHelper('buildConteneur', (objet, tplItem) => { return new Handlebars.SafeString(RdDUtility.buildConteneur(objet, 1, tplItem)); }); + 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('caseTmr-label', coord => TMRUtility.getTMRLabel(coord)); Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord)); @@ -472,33 +474,34 @@ export class RdDUtility { /** Construit la structure récursive des conteneurs, avec imbrication potentielle * */ - static buildConteneur(objet, profondeur, tplItem) { + static buildConteneur(objet, profondeur, templateItem, options) { if (!profondeur) profondeur = 1; - if (!tplItem) tplItem = 'actor/inventaire-item.html' + if (!templateItem) templateItem = 'actor/inventaire-item.html' objet.niveau = profondeur; const isConteneur = objet.type == 'conteneur'; const isOuvert = isConteneur && this.getAfficheContenu(objet._id); const isVide = isConteneur && objet.system.contenu.length == 0; - const conteneur = Handlebars.partials[`systems/foundryvtt-reve-de-dragon/templates/${tplItem}`]({ + const conteneur = Handlebars.partials[`systems/foundryvtt-reve-de-dragon/templates/${templateItem}`]({ item: objet, vide: isVide, - ouvert: isOuvert + ouvert: isOuvert, + options: options }); - const contenu = isConteneur ? RdDUtility.buildContenu(objet, profondeur, isOuvert, tplItem) : ''; + const contenu = isConteneur ? RdDUtility.buildContenu(objet, profondeur, isOuvert, templateItem, options) : ''; return conteneur + contenu; } /* -------------------------------------------- */ - static buildContenu(objet, profondeur, afficherContenu, tplItem) { + static buildContenu(objet, profondeur, afficherContenu, templateItem, options) { if (!profondeur) profondeur = 1; - if (!tplItem) tplItem = 'actor/inventaire-item.html' + if (!templateItem) templateItem = 'actor/inventaire-item.html' objet.niveau = profondeur; const display = afficherContenu ? 'item-display-show' : 'item-display-hide'; let strContenu = `