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 = `"; } diff --git a/template.json b/template.json index 63f2374d..15f2ff4e 100644 --- a/template.json +++ b/template.json @@ -1,6 +1,6 @@ { "Actor": { - "types": ["personnage", "creature", "entite", "vehicule"], + "types": ["personnage", "creature", "entite", "commerce", "vehicule"], "templates": { "description": { "description": "Description ...", @@ -554,6 +554,10 @@ }, "vehicule": { "templates": [ "vehicule", "description" ] + }, + "commerce":{ + "templates": [ "description" ], + "illimite": false } }, "Item": { diff --git a/templates/actor/commerce-actor-sheet.html b/templates/actor/commerce-actor-sheet.html new file mode 100644 index 00000000..1f80cfbd --- /dev/null +++ b/templates/actor/commerce-actor-sheet.html @@ -0,0 +1,71 @@ +
+ + {{!-- Sheet Header --}} +
+
+
+ +
+

+ {{#if @root.options.isObserver}} +
+ + Quantité illimitée en vente +
+ {{/if}} +
+
+
+
+ + {{!-- Sheet Body --}} +
+
+ {{editor description target="system.description" button=true owner=options.owner editable=options.isOwner engine="prosemirror"}} +
+
+ {{> "systems/foundryvtt-reve-de-dragon/templates/actor/commerce-inventaire.html"}} + {{#unless system.illimite}} + {{#if @root.options.isObserver}} +
+ {{> "systems/foundryvtt-reve-de-dragon/templates/actor/inventaire-monnaie.html"}} + {{/if}} + {{/unless}} + {{!-- +
+
+
    +
  • + + + + + +
  • + {{#each system.services as |service key|}} +
  • + + + + +
    + + {{#unless @root.disabled}} + + + {{/unless}} +
    +
  • + {{/each}} +
+
+ --}} +
+ {{> "systems/foundryvtt-reve-de-dragon/templates/actor/editor-notes-mj.html"}} +
+
+
\ No newline at end of file diff --git a/templates/actor/commerce-inventaire-item.html b/templates/actor/commerce-inventaire-item.html new file mode 100644 index 00000000..81b25fee --- /dev/null +++ b/templates/actor/commerce-inventaire-item.html @@ -0,0 +1,49 @@ +{{#if (ne item.type 'monnaie')}} +
  • + + + {{#if (eq item.type 'conteneur')}} + + {{/if}} + + {{item.name}} + + + {{#unless @root.system.illimite}} + + {{#unless (and (eq item.type 'conteneur') (not vide))}} + {{#if @root.options.isOwner}} + + {{/if}} + + {{#if @root.options.isOwner}} + + {{/if}} + {{/unless}} + + {{/unless}} + + {{#unless (and (eq item.type 'conteneur') (not vide))}} + + {{/unless}} + + + {{#unless (and (eq item.type 'conteneur') (not vide))}} + {{#if @root.options.isOwner}} + + + {{#if (or @root.system.illimite (ne item.system.quantite 0))}} + + {{/if}} + {{/if}} + + {{#if (gt item.system.quantite 0)}} + + {{/if}} + {{/unless}} + +
  • +{{/if}} diff --git a/templates/actor/commerce-inventaire.html b/templates/actor/commerce-inventaire.html new file mode 100644 index 00000000..0cff801e --- /dev/null +++ b/templates/actor/commerce-inventaire.html @@ -0,0 +1,35 @@ +

    Boutique

    + + {{#if options.isGM}} + Nouvel objet + Tout vider + {{/if}} + + {{#unless @root.system.illimite}} + {{#if calc.surEncombrementMessage}}{{calc.surEncombrementMessage}} ‐{{/if}} + Encombrement: {{numberFormat calc.encTotal decimals=2}} + {{#if (regle-optionnelle 'afficher-prix-joueurs')}} + ‐ Valeur: {{numberFormat calc.prixTotalEquipement decimals=2}} Sols + {{/if}} + {{/unless}} + + diff --git a/templates/actor/inventaire.html b/templates/actor/inventaire.html index 1456e8fe..c080c069 100644 --- a/templates/actor/inventaire.html +++ b/templates/actor/inventaire.html @@ -20,11 +20,11 @@ {{#each objets as |item id|}} {{#unless item.estContenu}} {{#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}} {{/unless}} {{/each}} {{#each conteneurs as |conteneur id|}} - {{buildConteneur this}} + {{buildConteneur this 'actor/inventaire-item.html' @root.options}} {{/each}} diff --git a/templates/item-service-sheet.html b/templates/item-service-sheet.html index 534fdd76..8e8f0ee0 100644 --- a/templates/item-service-sheet.html +++ b/templates/item-service-sheet.html @@ -5,39 +5,6 @@
    {{editor description target="system.description" button=true owner=owner editable=(or isGM isOwner) engine="prosemirror"}}
    - {{!-- -
    - -
    -
    - --}}
    Quantité en vente illimitée