From 717bb6fc6e79a24e498083fb45981a5ca12a50f8 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 5 Dec 2022 16:23:12 +0100 Subject: [PATCH 1/5] Fix ouverture conteneur --- module/item-conteneur-sheet.js | 1 + 1 file changed, 1 insertion(+) diff --git a/module/item-conteneur-sheet.js b/module/item-conteneur-sheet.js index 6ab5205d..4cb398fb 100644 --- a/module/item-conteneur-sheet.js +++ b/module/item-conteneur-sheet.js @@ -11,6 +11,7 @@ export class RdDConteneurItemSheet extends RdDItemSheet { if (this.actor) { this.prepareConteneurData(formData); } + return formData; } activateListeners(html) { From 7efa7be1c076f07e2f6fcd7cc5d62055d6b7ee8d Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 5 Dec 2022 01:52:49 +0100 Subject: [PATCH 2/5] L'art ne s'encombre de rien MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ne pas appliquer le surencombrement (ou l'encombrement) aux oeuvres d'art: on considère que pour faire de l'art, on pose son sac. --- module/actor.js | 4 +--- module/rolldata-ajustements.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/module/actor.js b/module/actor.js index 1e7c51bc..c38d9124 100644 --- a/module/actor.js +++ b/module/actor.js @@ -2712,7 +2712,7 @@ export class RdDActor extends Actor { competence: duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)), diffLibre: - (oeuvre.system.niveau ?? 0), diffConditions: 0, - use: { libre: false, conditions: true }, + use: { libre: false, conditions: true, surenc: false }, selectedCarac: duplicate(this.system.carac[selected]) }, { overwrite: false }); @@ -2721,8 +2721,6 @@ export class RdDActor extends Actor { artData.forceCarac = {}; artData.forceCarac[selected] = duplicate(this.system.carac[selected]); } - console.log("rollArt !!!", artData); - const dialog = await RdDRoll.create(this, artData, { html: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html` }, { diff --git a/module/rolldata-ajustements.js b/module/rolldata-ajustements.js index 690705a2..2baaa58f 100644 --- a/module/rolldata-ajustements.js +++ b/module/rolldata-ajustements.js @@ -63,7 +63,7 @@ export const referenceAjustements = { }, encTotal: { isVisible: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence), - isUsed: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence) && rollData.use.encTotal, + isUsed: (rollData, actor) => !rollData.oeuvre && RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence) && rollData.use.encTotal, getLabel: (rollData, actor) => 'Encombrement total', getValue: (rollData, actor) => -actor.getEncTotal() }, From 7b58407634de75be99d901e409b5873b10f04808 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 5 Dec 2022 15:29:00 +0100 Subject: [PATCH 3/5] Cleanup --- module/actor-sheet.js | 27 +---- module/actor.js | 130 ++++++++++----------- module/dialog-item-consommer.js | 10 +- module/item-competence.js | 32 +++++ module/item-sheet.js | 60 +++------- module/item.js | 1 - module/rdd-utility.js | 45 ++----- templates/actor/dragon-queue.html | 2 +- templates/actor/dragon-souffles.html | 2 +- templates/actor/dragon-tetes.html | 2 +- templates/actor/hr-casestmr.html | 2 +- templates/actor/hr-rencontres.html | 2 +- templates/actor/hr-signes-draconiques.html | 2 +- templates/actor/hr-sorts-reserve.html | 2 +- templates/actor/hr-sorts.html | 2 +- 15 files changed, 142 insertions(+), 179 deletions(-) diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 8dc97a16..4003a99c 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -133,7 +133,7 @@ export class RdDActorSheet extends ActorSheet { async _onDropItem(event, dragData) { const destItemId = $(event.target)?.closest('.item').attr('data-item-id') const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur) - if (dropParams){ + if (dropParams) { const callSuper = await this.actor.processDropItem(dropParams) if (callSuper) { await super._onDropItem(event, dragData) @@ -164,31 +164,14 @@ export class RdDActorSheet extends ActorSheet { const item = RdDSheetUtility.getItem(event, this.actor); RdDSheetUtility.splitItem(item, this.actor); }); - html.find('.item-edit').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor) - item.sheet.render(true) - }) - html.find('.display-label a').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - item.sheet.render(true); - }); - html.find('.item-delete').click(async event => { - const li = RdDSheetUtility.getEventElement(event); - const item = this.actor.getObjet(li.data("item-id")); - RdDUtility.confirmerSuppressionItem(this, item, li); - }); - html.find('.item-vendre').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - item?.proposerVente(); - }); - html.find('.item-montrer').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - item?.postItem(); - }); html.find('.item-action').click(async event => { const item = RdDSheetUtility.getItem(event, this.actor) this.actor.actionItem(item); }); + html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)) + html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor))); + html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); + html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem()); html.find('.subacteur-delete').click(async event => { const li = RdDSheetUtility.getEventElement(event); const actorId = li.data("actor-id"); diff --git a/module/actor.js b/module/actor.js index c38d9124..f9c5c3bf 100644 --- a/module/actor.js +++ b/module/actor.js @@ -250,7 +250,7 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ getReveActuel() { - switch(this.type) { + switch (this.type) { case 'personnage': return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value); case 'creature': @@ -258,7 +258,7 @@ export class RdDActor extends Actor { return Misc.toInt(this.system.carac.reve?.value) case 'vehicule': default: - return 0; + return 0; } } @@ -400,8 +400,8 @@ export class RdDActor extends Actor { return duplicate(possessions[0]); } const draconics = [...this.getDraconicList().filter(it => it.system.niveau >= 0), - POSSESSION_SANS_DRACONIC] - .sort(Misc.descending(it => it.system.niveau)); + POSSESSION_SANS_DRACONIC] + .sort(Misc.descending(it => it.system.niveau)); return duplicate(draconics[0]); } @@ -620,18 +620,18 @@ export class RdDActor extends Actor { content: 'Remise à neuf de ' + this.name }); const updates = { - 'system.sante.endurance.value' : this.system.sante.endurance.max + 'system.sante.endurance.value': this.system.sante.endurance.max }; if (!this.isEntite([ENTITE_INCARNE, ENTITE_BLURETTE])) { if (this.system.blessures) { updates['system.blessures.legeres.liste'] = [PAS_DE_BLESSURE, PAS_DE_BLESSURE, PAS_DE_BLESSURE, PAS_DE_BLESSURE, PAS_DE_BLESSURE]; - updates['system.blessures.graves.liste'] = [PAS_DE_BLESSURE, PAS_DE_BLESSURE]; + updates['system.blessures.graves.liste'] = [PAS_DE_BLESSURE, PAS_DE_BLESSURE]; updates['system.blessures.critiques.liste'] = [PAS_DE_BLESSURE]; } updates['system.sante.vie.value'] = this.system.sante.vie.max; updates['system.sante.fatigue.value'] = 0; if (this.isPersonnage()) { - updates['system.compteurs.ethylisme'] = { value:1, nb_doses: 0, jet_moral: false}; + updates['system.compteurs.ethylisme'] = { value: 1, nb_doses: 0, jet_moral: false }; } } await this.update(updates); @@ -809,8 +809,7 @@ export class RdDActor extends Actor { name: 'maitrise', label: 'Maîtriser le Rêve de Dragon', callbacks: [ - { action: async r => - this.resultCombatReveDeDragon(r) } + { action: async r => this.resultCombatReveDeDragon(r) } ] } ); @@ -829,11 +828,12 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async sortMisEnReserve(sort, draconic, coord, ptreve) { await this.createEmbeddedDocuments("Item", [{ - type: 'sortreserve', - name: sort.name, - img: sort.img, - system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' } }], - { renderSheet: false}); + type: 'sortreserve', + name: sort.name, + img: sort.img, + system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' } + }], + { renderSheet: false }); this.currentTMR.updateTokens(); } @@ -923,7 +923,7 @@ export class RdDActor extends Actor { return; } const xpUtilise = Math.max(0, Math.min(stress, xpRequis)); - const gainNiveau = (xpUtilise >= xpRequis || xpRequis <=0) ? 1 : 0; + const gainNiveau = (xpUtilise >= xpRequis || xpRequis <= 0) ? 1 : 0; const nouveauNiveau = niveau + gainNiveau; const nouveauXp = gainNiveau > 0 ? Math.max(competence.system.xp - xpSuivant, 0) : (competence.system.xp + xpUtilise); await competence.update({ @@ -1028,7 +1028,7 @@ export class RdDActor extends Actor { }); await this.update({ [`system.experiencelog`]: expLog }); } - + async deleteExperienceLog(from, count) { if (from >= 0 && count > 0) { let expLog = duplicate(this.system.experiencelog); @@ -1144,7 +1144,7 @@ export class RdDActor extends Actor { onEnleverDeConteneur(); } } - + /* -------------------------------------------- */ /** Ajoute un item dans un conteneur, sur la base * de leurs ID */ @@ -1158,7 +1158,7 @@ export class RdDActor extends Actor { await this.updateEmbeddedDocuments('Item', [{ _id: conteneur.id, 'system.contenu': [...conteneur.system.contenu, item.id] - }]); + }]); onAjouterDansConteneur(item.id, conteneur.id); } } @@ -1374,8 +1374,8 @@ export class RdDActor extends Actor { async computeMalusArmure() { if (this.isPersonnage()) { const malusArmure = this.filterItems(it => it.type == 'armure' && it.system.equipe) - .map(it => it.system.malus ?? 0) - .reduce(Misc.sum(), 0); + .map(it => it.system.malus ?? 0) + .reduce(Misc.sum(), 0); // Mise à jour éventuelle du malus armure if (this.system.attributs?.malusarmure?.value != malusArmure) { await this.updateAttributeValue("malusarmure", malusArmure); @@ -1460,7 +1460,7 @@ export class RdDActor extends Actor { }); } } - + /* -------------------------------------------- */ async ajouterRefoulement(value = 1, refouler) { const refoulement = this.system.reve.refoulement.value + value; @@ -1568,7 +1568,7 @@ export class RdDActor extends Actor { async deleteTMRRencontreAtPosition() { const demiReve = this.getDemiReve() let rencontreIds = this.items.filter(it => it.type == 'rencontre' && it.system.coord == demiReve).map(it => it.id); - if (rencontreIds.length>0) { + if (rencontreIds.length > 0) { await this.deleteEmbeddedDocuments('Item', rencontreIds); } } @@ -1576,7 +1576,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async addTMRRencontre(currentRencontre) { const toCreate = currentRencontre.toObject(); - console.log('actor.addTMRRencontre(', toCreate,')'); + console.log('actor.addTMRRencontre(', toCreate, ')'); this.createEmbeddedDocuments('Item', [toCreate]); } @@ -1805,7 +1805,7 @@ export class RdDActor extends Actor { } return result; } - + async vehicleIncDec(name, inc) { if (!this.isVehicule() || !['resistance', 'structure'].includes(name)) { return @@ -1813,7 +1813,7 @@ export class RdDActor extends Actor { const value = this.system.etat[name].value; const max = this.system.etat[name].max; const newValue = value + inc; - if (0 <= newValue && newValue <=max) { + if (0 <= newValue && newValue <= max) { await this.update({ [`system.etat.${name}.value`]: newValue }) } } @@ -1965,9 +1965,9 @@ export class RdDActor extends Actor { } } - async actionNourritureboisson(item, onActionItem) { - const dialog = await DialogConsommer.create(this, item, onActionItem); - dialog.render(true); + + async mangerNourriture(item, onActionItem) { + return (await DialogConsommer.create(this, item, onActionItem)).render(true); } async actionLire(item) { @@ -1988,14 +1988,14 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false}, userId = undefined) { + async consommerNourritureboisson(itemId, choix = { doses: 1, seForcer: false, supprimerSiZero: false }, userId = undefined) { if (userId != undefined && userId != game.user.id) { RdDActor.remoteActorCall({ actorId: this.id, method: 'consommerNourritureboisson', args: [itemId, choix, userId] }, - userId) + userId) return; } const item = this.getObjet(itemId) @@ -2297,9 +2297,9 @@ export class RdDActor extends Actor { if (xpData) { const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, xpData); if (hideChatMessage) { - ChatUtility.blindMessageToGM({ content: content}); + ChatUtility.blindMessageToGM({ content: content }); } - else{ + else { ChatMessage.create({ whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), content: content @@ -2583,7 +2583,7 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async rollCompetence(idOrName, options = {tryTarget: true}) { + async rollCompetence(idOrName, options = { tryTarget: true }) { let rollData = { carac: this.system.carac, competence: this.getCompetence(idOrName) @@ -2591,14 +2591,14 @@ export class RdDActor extends Actor { if (rollData.competence.type == 'competencecreature') { if (rollData.competence.system.iscombat && options.tryTarget && Targets.hasTargets()) { Targets.selectOneToken(target => { - if (rollData.competence.system.ispossession) { - RdDPossession.onAttaquePossession(target, this, rollData.competence) - } - else { - const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence) - RdDCombat.rddCombatTarget(target, this).attaque(competence, arme) - } - }); + if (rollData.competence.system.ispossession) { + RdDPossession.onAttaquePossession(target, this, rollData.competence) + } + else { + const arme = RdDItemCompetenceCreature.armeNaturelle(rollData.competence) + RdDCombat.rddCombatTarget(target, this).attaque(competence, arme) + } + }); return; } // Transformer la competence de créature @@ -2705,12 +2705,13 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async _rollArt(artData, selected, oeuvre, callBackResult = r => this._resultArt(r)) { + oeuvre.system.niveau = oeuvre.system.niveau ?? 0; mergeObject(artData, { oeuvre: oeuvre, art: oeuvre.type, competence: duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)), - diffLibre: - (oeuvre.system.niveau ?? 0), + diffLibre: - oeuvre.system.niveau, diffConditions: 0, use: { libre: false, conditions: true, surenc: false }, selectedCarac: duplicate(this.system.carac[selected]) @@ -2803,13 +2804,13 @@ export class RdDActor extends Actor { type: 'nourritureboisson', img: 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp', system: { - "description": artData.oeuvre.system.description, - "sust": Math.min(sust, 1), - "qualite": artData.qualiteFinale, - "exotisme": artData.exotismeFinal, - "encombrement": 0.1, - "quantite": Math.max(1, Math.floor(sust)), - "cout": Math.max(artData.qualiteFinale) * 0.01 + description: cuisine.oeuvre.system.description, + sust: 1, + qualite: cuisine.qualiteFinale, + exotisme: cuisine.exotismeFinal, + encombrement: 0.1, + quantite: Math.max(1, Math.floor(cuisine.sust)), + cout: Math.max(cuisine.qualiteFinale, 0) * 0.01 } }; if (artData.ajouterEquipement) { @@ -3169,7 +3170,7 @@ export class RdDActor extends Actor { const caracList = Object.entries(carac); let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' }); - if (!entry || entry.length ==0) { + if (!entry || entry.length == 0) { entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' }); } return entry && entry.length > 0 ? carac[entry[0]] : undefined; @@ -3205,7 +3206,7 @@ export class RdDActor extends Actor { ui.notifications.warn("Vous êtes déja dans les TMR...."); return } - if (mode != 'visu' && this.getEffect(STATUSES.StatusDemiReve)) { + if (mode != 'visu' && this.getEffect(STATUSES.StatusDemiReve)) { ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement"); mode = "visu"; // bascule le mode en visu automatiquement } @@ -3263,18 +3264,18 @@ export class RdDActor extends Actor { title: 'Ne pas utiliser les automatisation de combat', buttonLabel: "Pas d'automatisation", onAction: async () => { - this.rollCompetence(arme.system.competence, {tryTarget: false}) + this.rollCompetence(arme.system.competence, { tryTarget: false }) } }); return; } Targets.selectOneToken(target => { - if (Targets.isTargetEntite(target)){ + if (Targets.isTargetEntite(target)) { ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`); return; } - - + + const competence = this.getCompetence(arme.system.competence) if (competence.system.ispossession) { return RdDPossession.onAttaquePossession(target, this, competence); @@ -3393,12 +3394,12 @@ export class RdDActor extends Actor { async validerEncaissement(rollData, show) { if (ReglesOptionelles.isUsing('validation-encaissement-gr') && !game.user.isGM) { - RdDActor.remoteActorCall({ - actorId: this.id, - method: 'validerEncaissement', - args: [rollData, show] - }); - return; + RdDActor.remoteActorCall({ + actorId: this.id, + method: 'validerEncaissement', + args: [rollData, show] + }); + return; } const armure = await this.computeArmure(rollData); if (ReglesOptionelles.isUsing('validation-encaissement-gr')) { @@ -3878,7 +3879,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ addSubActeur(subActor) { - if(subActor?.id == this.id){ + if (subActor?.id == this.id) { ui.notifications.warn("Vous ne pouvez pas attacher un acteur à lui même") } else if (!subActor?.isOwner) { @@ -4105,10 +4106,10 @@ export class RdDActor extends Actor { } console.log("setEffect", statusId, status) const effect = this.getEffect(statusId); - if (!status && effect){ + if (!status && effect) { await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]); } - if (status && !effect ) { + if (status && !effect) { await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.status(statusId)]); } } @@ -4134,7 +4135,6 @@ export class RdDActor extends Actor { await this.checkCompetenceXP(item.name, item.system.xp); } } - /* -------------------------------------------- */ async onCreateItem(item, options, id) { switch (item.type) { diff --git a/module/dialog-item-consommer.js b/module/dialog-item-consommer.js index 81ef25d9..d74a704c 100644 --- a/module/dialog-item-consommer.js +++ b/module/dialog-item-consommer.js @@ -2,13 +2,13 @@ import { Misc } from "./misc.js"; export class DialogConsommer extends Dialog { - static async create(actor, item, onActionItem = async ()=>{}) { + static async create(actor, item, onActionItem = async () => { }) { const consommerData = DialogConsommer.prepareData(actor, item); const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData); return new DialogConsommer(actor, item, consommerData, html, onActionItem) } - constructor(actor, item, consommerData, html, onActionItem = async ()=>{}) { + constructor(actor, item, consommerData, html, onActionItem = async () => { }) { const options = { classes: ["dialogconsommer"], width: 350, height: 'fit-content', 'z-index': 99999 }; let conf = { title: consommerData.title, @@ -18,7 +18,8 @@ export class DialogConsommer extends Dialog { [consommerData.buttonName]: { label: consommerData.buttonName, callback: async it => { await this.onConsommer(it); - await onActionItem();} + await onActionItem(); + } } } }; @@ -38,9 +39,8 @@ export class DialogConsommer extends Dialog { /* -------------------------------------------- */ static prepareData(actor, item) { - item = duplicate(item); let consommerData = { - item: item, + item: duplicate(item), cuisine: actor.getCompetence('cuisine'), choix: { doses: 1, diff --git a/module/item-competence.js b/module/item-competence.js index e5fbfab9..13b7de41 100644 --- a/module/item-competence.js +++ b/module/item-competence.js @@ -281,4 +281,36 @@ export class RdDItemCompetence extends Item { return duplicate(limitesArchetypes); } + static triVisible(competences) { + return competences.filter(it => it.system.isVisible) + .sort((a, b) => RdDItemCompetence.compare(a,b)) + } + + static $positionTri(comp) { + if (comp.name.startsWith("Survie")) { + if (comp.name.includes("Cité")) return 0; + if (comp.name.includes("Extérieur")) return 1; + return 2; + } + if (comp.system.categorie.startsWith("melee")) { + if (comp.name.includes("Corps")) return 0; + if (comp.name.includes("Dague")) return 1; + if (comp.name.includes("Esquive")) return 2; + return 3; + } + if (comp.system.categorie.startsWith("draconic")) { + if (comp.name.includes("Oniros")) return 0; + if (comp.name.includes("Hypnos")) return 1; + if (comp.name.includes("Narcos")) return 2; + if (comp.name.includes("Thanatos")) return 3; + return 4; + } + return 0; + } + + static compare(a,b) { + const diff = RdDItemCompetence.$positionTri(a) - RdDItemCompetence.$positionTri(b); + return diff ? diff : a.name.localeCompare(b.name); + } + } \ No newline at end of file diff --git a/module/item-sheet.js b/module/item-sheet.js index 2e6c91c2..b08d6a8d 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -166,7 +166,6 @@ export class RdDItemSheet extends ItemSheet { this.form.ondragstart = (event) => this._onDragStart(event); this.form.ondrop = (event) => this._onDrop(event); - // Select competence categorie html.find(".categorie").change(event => this._onSelectCategorie(event)); @@ -182,60 +181,37 @@ export class RdDItemSheet extends ItemSheet { this.dateUpdated = game.system.rdd.calendrier.getIndexFromDate(jour, mois); }); - html.find('.creer-tache-livre').click((event) => { - let actorId = event.currentTarget.attributes['data-actor-id'].value; - let actor = game.actors.get(actorId); - actor.creerTacheDepuisLivre(this.item); - }); - html.find('.consommer-potion').click((event) => { - let actorId = event.currentTarget.attributes['data-actor-id'].value; - let actor = game.actors.get(actorId); - actor.consommerPotion(this.item); - }); - html.find('.creer-potion-base').click((event) => { - let actorId = event.currentTarget.attributes['data-actor-id'].value; - let actor = game.actors.get(actorId); - actor.dialogFabriquerPotion(this.item); - }); + html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item)); + html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item)); + html.find('.creer-potion-base').click((event) => this._getEventActor(event).dialogFabriquerPotion(this.item)); html.find('.alchimie-tache a').click((event) => { - let actorId = event.currentTarget.attributes['data-actor-id'].value; - let recetteId = event.currentTarget.attributes['data-recette-id'].value; - let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value; - let tacheData = event.currentTarget.attributes['data-alchimie-data'].value; - let actor = game.actors.get(actorId); + let actor = this._getEventActor(event); if (actor) { + let recetteId = event.currentTarget.attributes['data-recette-id'].value; + let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value; + let tacheData = event.currentTarget.attributes['data-alchimie-data'].value; actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData); } else { ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique."); } }); - html.find('.item-split').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - await RdDSheetUtility.splitItem(item, this.actor, async () => itemSheetDialog.render(true)); - }); - html.find('.item-edit').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - item.sheet.render(true); - }); - html.find('.item-delete').click(async event => { - const li = RdDSheetUtility.getEventElement(event); - const item = this.actor.getObjet(li.data("item-id")); - RdDUtility.confirmerSuppressionItem(this, item, li); - }); - html.find('.item-vendre').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - item?.proposerVente(); - }); - html.find('.item-montrer').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - item?.postItem(); - }); html.find('.item-action').click(async event => { const item = RdDSheetUtility.getItem(event, this.actor); this.actor.actionItem(item, async () => itemSheetDialog.render(true)); }); + html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => itemSheetDialog.render(true))); + html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)); + html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor))); + html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); + html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem()); + } + + _getEventActor(event) { + let actorId = event.currentTarget.attributes['data-actor-id'].value; + let actor = game.actors.get(actorId); + return actor; } /* -------------------------------------------- */ diff --git a/module/item.js b/module/item.js index 6182bd0f..650540b9 100644 --- a/module/item.js +++ b/module/item.js @@ -287,7 +287,6 @@ export class RdDItem extends Item { if (!other || !this.isInventaire()) { return [false, undefined]; } - if (this.system.quantite == undefined) { return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`]; } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 0b7f21d3..8625e267 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -279,6 +279,7 @@ export class RdDUtility { 'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html' ]; + Handlebars.registerHelper('either', (a, b) => a ?? b); Handlebars.registerHelper('upperFirst', str => Misc.upperFirst(str ?? 'Null')); Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null')); Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? 'NULL'); @@ -296,46 +297,18 @@ export class RdDUtility { Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option)); Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name))); - Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.system.isVisible) - .sort((a, b) => { - if (a.name.startsWith("Survie") && b.name.startsWith("Survie")) { - if (a.name.includes("Cité")) return -1; - if (b.name.includes("Cité")) return 1; - if (a.name.includes("Extérieur")) return -1; - if (b.name.includes("Extérieur")) return 1; - return a.name.localeCompare(b.name); - } - if (a.system.categorie.startsWith("melee") && b.system.categorie.startsWith("melee")) { - if (a.name.includes("Corps")) return -1; - if (b.name.includes("Corps")) return 1; - if (a.name.includes("Dague")) return -1; - if (b.name.includes("Dague")) return 1; - if (a.name.includes("Esquive")) return -1; - if (b.name.includes("Esquive")) return 1; - return a.name.localeCompare(b.name); - } - if (a.name.startsWith("Voie") && b.name.startsWith("Voie")) { - if (a.name.includes("Oniros")) return -1; - if (b.name.includes("Oniros")) return 1; - if (a.name.includes("Hypnos")) return -1; - if (b.name.includes("Hypnos")) return 1; - if (a.name.includes("Narcos")) return -1; - if (b.name.includes("Narcos")) return 1; - if (a.name.includes("Thanatos")) return -1; - if (b.name.includes("Thanatos")) return 1; - return a.name.localeCompare(b.name); - } - return a.name.localeCompare(b.name); - }) - ); - Handlebars.registerHelper('linkCompendium', (pack, id, name)=> RdDUtility.linkCompendium(pack, id, name)); - Handlebars.registerHelper('uniteQuantite', (type) => RdDItem.getUniteQuantite(type)); + Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences)); + Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name)); + Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite()); Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field)); Handlebars.registerHelper('getFrequenceRarete', (rarete, field) => Environnement.getFrequenceRarete(rarete, field)); - Handlebars.registerHelper('either', (a, b) => a ?? b); return loadTemplates(templatePaths); } + static getItem(itemId, actorId = undefined) { + return actorId ? game.actors.get(actorId)?.getObjet(itemId) : game.items.get(itemId); + } + static linkCompendium(pack, id, name) { return `@Compendium[${pack}.${id}]{${name}}`; } @@ -1001,7 +974,7 @@ export class RdDUtility { } static slideOnDelete(sheet, htmlToDelete) { - return htmlToDelete.slideUp(200, () => sheet.render(false)); + return htmlToDelete?.slideUp(200, () => sheet.render(false)); } /* -------------------------------------------- */ diff --git a/templates/actor/dragon-queue.html b/templates/actor/dragon-queue.html index 057dc09e..889a752e 100644 --- a/templates/actor/dragon-queue.html +++ b/templates/actor/dragon-queue.html @@ -1,6 +1,6 @@
  • - + {{#if (eq queue.type 'ombre')}} {{/if}} diff --git a/templates/actor/dragon-souffles.html b/templates/actor/dragon-souffles.html index aa28abab..4671b429 100644 --- a/templates/actor/dragon-souffles.html +++ b/templates/actor/dragon-souffles.html @@ -4,7 +4,7 @@ {{#each souffles as |souffle key|}}
  • - {{souffle.name}} + {{souffle.name}}
    diff --git a/templates/actor/dragon-tetes.html b/templates/actor/dragon-tetes.html index fc65ed54..28785008 100644 --- a/templates/actor/dragon-tetes.html +++ b/templates/actor/dragon-tetes.html @@ -4,7 +4,7 @@ {{#each tetes as |tete key|}}
  • - {{tete.name}} + {{tete.name}}
    diff --git a/templates/actor/hr-casestmr.html b/templates/actor/hr-casestmr.html index 1c1f3fd8..0ec1decf 100644 --- a/templates/actor/hr-casestmr.html +++ b/templates/actor/hr-casestmr.html @@ -4,7 +4,7 @@ {{#each casestmr as |casetmr key|}}
  • - {{casetmr.name}} + {{casetmr.name}} {{casetmr.system.coord}} - {{caseTmr-label casetmr.system.coord}}
    diff --git a/templates/actor/hr-rencontres.html b/templates/actor/hr-rencontres.html index 7d9a2a7e..bdd432ff 100644 --- a/templates/actor/hr-rencontres.html +++ b/templates/actor/hr-rencontres.html @@ -4,7 +4,7 @@ {{#each rencontres as |rencontre key|}}
  • - + {{rencontre.name}} r{{rencontre.system.force}} ({{rencontre.system.coord}} - {{caseTmr-label rencontre.system.coord}}) {{#if rencontre.system.date}} diff --git a/templates/actor/hr-signes-draconiques.html b/templates/actor/hr-signes-draconiques.html index 1edb8f1c..4a45ad21 100644 --- a/templates/actor/hr-signes-draconiques.html +++ b/templates/actor/hr-signes-draconiques.html @@ -4,7 +4,7 @@ {{#each signesdraconiques as |signe key|}}
  • - {{signe.name}} + {{signe.name}} {{signe.system.difficulte}}
    diff --git a/templates/actor/hr-sorts-reserve.html b/templates/actor/hr-sorts-reserve.html index 3214bceb..8976e6ff 100644 --- a/templates/actor/hr-sorts-reserve.html +++ b/templates/actor/hr-sorts-reserve.html @@ -4,7 +4,7 @@ {{#each sortsReserve as |sort key|}}
  • - {{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}} + {{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}} {{sort.system.coord}} - {{caseTmr-label sort.system.coord}}
    diff --git a/templates/actor/hr-sorts.html b/templates/actor/hr-sorts.html index 09d92cff..80c20740 100644 --- a/templates/actor/hr-sorts.html +++ b/templates/actor/hr-sorts.html @@ -4,7 +4,7 @@ {{#each sorts as |sort key|}}
  • - + {{sort.name}} - {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}} From 5056c35038207a6f364cbffe027bf8c70a22f8c3 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 3 Dec 2022 22:32:32 +0100 Subject: [PATCH 4/5] Faune et flore comestibles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - permettre de cuisiner les ingrédients (faune & flore) - permettre de manger des ingrédients "crus" --- module/actor-sheet.js | 5 +- module/actor.js | 122 ++++++++++++++++-------- module/dialog-item-consommer.js | 40 ++++++-- module/item-faune-sheet.js | 27 ++++-- module/item-sheet.js | 8 +- module/item.js | 125 ++++++++++++++++++++++--- module/rdd-utility.js | 2 + template.json | 20 ++-- templates/item-faune-sheet.html | 7 +- templates/item-herbe-sheet.html | 24 ++++- templates/item/boutons-comestible.html | 8 ++ templates/item/partial-inventaire.html | 4 +- 12 files changed, 296 insertions(+), 96 deletions(-) create mode 100644 templates/item/boutons-comestible.html diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 4003a99c..7965a19d 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -164,14 +164,11 @@ export class RdDActorSheet extends ActorSheet { const item = RdDSheetUtility.getItem(event, this.actor); RdDSheetUtility.splitItem(item, this.actor); }); - html.find('.item-action').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor) - this.actor.actionItem(item); - }); html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)) html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor))); html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem()); + html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor)); html.find('.subacteur-delete').click(async event => { const li = RdDSheetUtility.getEventElement(event); const actorId = li.data("actor-id"); diff --git a/module/actor.js b/module/actor.js index f9c5c3bf..f8c6ea1c 100644 --- a/module/actor.js +++ b/module/actor.js @@ -1209,7 +1209,7 @@ export class RdDActor extends Actor { const cible = this.getContenantOrParent(dest); const [empilable, message] = item.isInventaireEmpilable(dest); if (empilable) { - await this.regrouperEquipementsSimilaires(item, dest); + await dest.empiler(item) result = false; } // changer de conteneur @@ -1309,11 +1309,6 @@ export class RdDActor extends Actor { return itemMap; } - async regrouperEquipementsSimilaires(item, dest) { - await dest.quantiteIncDec(item.system.quantite); - await item.delete(); - } - isSurenc() { return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false } @@ -1949,20 +1944,28 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async actionItem(item, onActionItem = async () => { }) { - if (!item.getActionPrincipale()) return; - switch (item.type) { - case 'nourritureboisson': return await this.actionNourritureboisson(item, onActionItem); - case 'potion': return await this.consommerPotion(item, onActionItem); - case 'livre': return await this.actionLire(item); - case 'conteneur': return await item.sheet.render(true); - case 'herbe': { - if (item.isHerbeAPotion()) { - return this.dialogFabriquerPotion(item); - } - return; + item.actionPrincipale(this, onActionItem); + } + + async actionNourritureboisson(item, onActionItem) { + switch (item.isComestible()) { + case 'brut': { + let d = new Dialog({ + title: "Nourriture brute", + content: `Que faire de votre ${item.name}`, + buttons: { + 'cuisiner': { icon: '', label: 'Cuisiner', callback: async () => await this.preparerNourriture(item) }, + 'manger': { icon: '', label: 'Manger cru', callback: async () => await this.mangerNourriture(item, onActionItem) } + } + }); + d.render(true); + return true; } - case 'queue': case 'ombre': return await this.actionRefoulement(item); + case 'pret': + await this.mangerNourriture(item, onActionItem); + return true; } + return false; } @@ -1976,11 +1979,18 @@ export class RdDActor extends Actor { await this.rollTache(tache.id); } } + async actionHerbe(item) { + if (item.isHerbeAPotion()) { + return this.dialogFabriquerPotion(item); + } + return; + } /* -------------------------------------------- */ async consommer(item, choix) { switch (item.type) { case 'nourritureboisson': + case 'herbe': case 'faune': return await this.consommerNourritureboisson(item.id, choix); case 'potion': return await this.consommerPotion(item) @@ -1999,7 +2009,7 @@ export class RdDActor extends Actor { return; } const item = this.getObjet(itemId) - if (item.type != 'nourritureboisson') { + if (!item.isComestible()) { return; } if (choix.doses > item.system.quantite) { @@ -2738,8 +2748,9 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async _resultArt(artData) { - const baseQualite = (artData.rolled.isSuccess ? artData.oeuvre.system.niveau : artData.competence.system.niveau); - artData.qualiteFinale = Math.min(baseQualite, artData.oeuvre.system.niveau) + artData.rolled.ptQualite; + const niveau = artData.oeuvre.system.niveau ?? 0; + const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau); + artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite; await RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`); } @@ -2793,32 +2804,64 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async _resultRecetteCuisine(artData) { - const baseQualite = (artData.rolled.isSuccess ? artData.oeuvre.system.niveau : artData.competence.system.niveau); - const sust = artData.oeuvre.system.sust * artData.proportions; - artData.qualiteFinale = Math.min(baseQualite, artData.oeuvre.system.niveau) + artData.rolled.ptQualite; - artData.exotismeFinal = Math.min(Math.min(artData.qualiteFinale, artData.oeuvre.system.exotisme ?? 0), 0); - //console.log("OEUVRE", artData.art, artData) + async _resultRecetteCuisine(cuisine) { + const niveauRecette = cuisine.oeuvre.system.niveau ?? 0; + const baseQualite = (cuisine.rolled.isSuccess ? niveauRecette : cuisine.competence.system.niveau); + cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite; + cuisine.exotismeFinal = Math.min(Math.min(cuisine.qualiteFinale, cuisine.oeuvre.system.exotisme ?? 0), 0); + cuisine.sust = cuisine.oeuvre.system.sust * Math.min(cuisine.proportions, cuisine.proportionsMax ?? cuisine.proportions) const platCuisine = { - name: artData.oeuvre.name, + name: cuisine.oeuvre.name, type: 'nourritureboisson', img: 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp', system: { - description: cuisine.oeuvre.system.description, - sust: 1, - qualite: cuisine.qualiteFinale, - exotisme: cuisine.exotismeFinal, - encombrement: 0.1, - quantite: Math.max(1, Math.floor(cuisine.sust)), - cout: Math.max(cuisine.qualiteFinale, 0) * 0.01 + "description": cuisine.oeuvre.system.description, + "sust": 1, + "qualite": cuisine.qualiteFinale, + "exotisme": cuisine.exotismeFinal, + "encombrement": 0.1, + "quantite": Math.max(1, Math.floor(cuisine.sust)), + "cout": Math.max(cuisine.qualiteFinale) * 0.01 } - }; - if (artData.ajouterEquipement) { + } + if (cuisine.ajouterEquipement) { await this.createEmbeddedDocuments('Item', [platCuisine]); ui.notifications.info(`${platCuisine.system.quantite} rations de ${platCuisine.name} ont été ajoutés à votre équipement`); } - artData.platCuisine = platCuisine; - await RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`); + cuisine.platCuisine = platCuisine; + await RdDResolutionTable.displayRollData(cuisine, this.name, `chat-resultat-${cuisine.art}.html`); + } + + async preparerNourriture(item) { + if (item.isComestible() == 'brut') { + const nourriture = { + name: 'Plat de ' + item.name, + type: 'recettecuisine', + img: item.img, + system: { + sust: 1, + exotisme: item.system.exotisme, + ingredients: item.name + } + }; + const artData = { + verbe: 'Préparer', + compName: 'cuisine', + proportions: 1, + proportionsMax: Math.min(50, item.system.sust), + ajouterEquipement: true + }; + await this._rollArt(artData, 'odoratgout', nourriture, async (cuisine) => { + await this._resultRecetteCuisine(cuisine); + const remaining = Math.max(item.system.quantite - cuisine.proportions, 0); + if (remaining > 0) { + await item.update({ 'system.quantite': remaining }) + } + else { + await this.deleteEmbeddedDocuments('Item', [item.id]); + } + }); + } } /* -------------------------------------------- */ @@ -4145,6 +4188,7 @@ export class RdDActor extends Actor { await this.onCreateOwnedDraconique(item, options, id); break; } + await item.onCreateDecoupeComestible(this); } async onDeleteItem(item, options, id) { diff --git a/module/dialog-item-consommer.js b/module/dialog-item-consommer.js index d74a704c..69642e7d 100644 --- a/module/dialog-item-consommer.js +++ b/module/dialog-item-consommer.js @@ -48,25 +48,47 @@ export class DialogConsommer extends Dialog { } } switch (item.type) { + case 'herbe': case 'faune': + consommerData.title = 'Manger une portion crue: '; + consommerData.buttonName = "Manger"; + break; case 'nourritureboisson': - consommerData.title = item.system.boisson ? `${item.name}: boire une dose` : `${item.name}: manger une portion`; + consommerData.title = item.system.boisson ? 'Boire une dose: ' : 'Manger une portion: '; consommerData.buttonName = item.system.boisson ? "Boire" : "Manger"; break; case 'potion': - consommerData.title = `${item.name}: boire la potion`; + consommerData.title = 'Boire la potion: '; consommerData.buttonName = "Boire"; break; } - DialogConsommer.calculDoses(consommerData, consommerData.choix.doses) + consommerData.title += item.name; + DialogConsommer.calculDoses(consommerData, item) return consommerData; } - static calculDoses(consommer) { + static calculDoses(consommer, item) { const doses = consommer.choix.doses; - consommer.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2); - consommer.totalDesaltere = consommer.item.system.boisson - ? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2) - : 0; + switch (item.type) { + case 'herbe': case 'faune': + consommer.totalSust = doses; + consommer.totalDesaltere = 0; + consommer.choix.sust = 1; + consommer.choix.quantite = 0; + consommer.choix.encombrement = Misc.keepDecimals(consommer.item.system.encombrement / item.system.sust, 2); + return; + case 'nourritureboisson': + consommer.choix.sust = consommer.item.system.sust; + consommer.choix.quantite = doses; + consommer.choix.encombrement = 0 + consommer.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2); + consommer.totalDesaltere = consommer.item.system.boisson + ? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2) + : 0; + break; + case 'potion': + consommer.totalSust = 0 + consommer.totalDesaltere = 0 + } } @@ -84,7 +106,7 @@ export class DialogConsommer extends Dialog { selectDoses(event) { this.consommerData.choix.doses = Number(event.currentTarget.value); - DialogConsommer.calculDoses(this.consommerData); + DialogConsommer.calculDoses(this.consommerData, this.item); $(".total-sust").text(this.consommerData.totalSust); $(".total-desaltere").text(this.consommerData.totalDesaltere); } diff --git a/module/item-faune-sheet.js b/module/item-faune-sheet.js index 274142b2..3b97d7ca 100644 --- a/module/item-faune-sheet.js +++ b/module/item-faune-sheet.js @@ -26,21 +26,22 @@ export class RdDFauneItemSheet extends RdDItemSheet { EnvironmentSheetHelper.activateListeners(this, html); html.find("a.linked-actor-delete").click(event => this.onDeleteLinkedActor()); - + html.find("a.preparer-nourriture").click(event => this.preparerNourriture(event)); + html.find("a.manger-nourriture").click(event => this.mangerNourriture(event)); } async _onDropActor(event, dragData) { console.log('faune:dropActor', event, dragData) - const actor = fromUuidSync(dragData.uuid); - if (actor?.pack) { + const linkedActor = fromUuidSync(dragData.uuid); + if (linkedActor?.pack) { this.item.update({ - 'system.actor.pack': actor.pack, - 'system.actor.id': actor._id, - 'system.actor.name': actor.name + 'system.actor.pack': linkedActor.pack, + 'system.actor.id': linkedActor._id, + 'system.actor.name': linkedActor.name }); } else { - ui.notifications.warn(`${actor.name} ne provient pas d'eun compendium. + ui.notifications.warn(`${linkedActor.name} ne provient pas d'un compendium.
    Choisissez une créature du compendium pour représenter un élément de faune générique`) } } @@ -51,4 +52,16 @@ export class RdDFauneItemSheet extends RdDItemSheet { 'system.actor.name': '' }); } + + async preparerNourriture(event) { + if (this.actor) { + await this.actor.preparerNourriture(this.item); + } + } + async mangerNourriture(event) { + if (this.actor) { + await this.actor.mangerNourriture(this.item); + } + } + } diff --git a/module/item-sheet.js b/module/item-sheet.js index b08d6a8d..baeb40e5 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -99,7 +99,8 @@ export class RdDItemSheet extends ItemSheet { cssClass: this.isEditable ? "editable" : "locked", isSoins: false, description: await TextEditor.enrichHTML(this.item.system.description, { async: true }), - descriptionmj: await TextEditor.enrichHTML(this.item.system.descriptionmj, { async: true }) + descriptionmj: await TextEditor.enrichHTML(this.item.system.descriptionmj, { async: true }), + isComestible: this.item.isComestible() } const competences = await SystemCompendiums.getCompetences(this.actor?.type); @@ -197,15 +198,12 @@ export class RdDItemSheet extends ItemSheet { } }); - html.find('.item-action').click(async event => { - const item = RdDSheetUtility.getItem(event, this.actor); - this.actor.actionItem(item, async () => itemSheetDialog.render(true)); - }); html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => itemSheetDialog.render(true))); html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)); html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor))); html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem()); + html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => itemSheetDialog.render(true))); } _getEventActor(event) { diff --git a/module/item.js b/module/item.js index 650540b9..4d888422 100644 --- a/module/item.js +++ b/module/item.js @@ -1,5 +1,6 @@ import { DialogItemVente } from "./dialog-item-vente.js"; import { Grammar } from "./grammar.js"; +import { Misc } from "./misc.js"; import { RdDHerbes } from "./rdd-herbes.js"; import { RdDUtility } from "./rdd-utility.js"; @@ -91,10 +92,16 @@ export class RdDItem extends Item { return true; } - static getUniteQuantite(type) { - switch (type) { + getUniteQuantite() { + switch (this.type) { case "monnaie": return "(Pièces)" - case "herbe": return "(Brins)" + case "herbe": + switch (this.system.categorie) { + case 'Alchimie': case 'Repos': case 'Soin': + return "(Brins)" + case 'Cuisine': return ''; + } + return ''; case "ingredient": return "(Pépins ou Brins)" } return ''; @@ -165,9 +172,25 @@ export class RdDItem extends Item { return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0; } - isAlcool() { - return this.type == 'nourritureboisson' && this.system.boisson && this.system.alcoolise; + isNourritureBoisson() { + return this.type == 'nourritureboisson'; } + + isComestible() { + switch (this.type) { + case 'nourritureboisson': return 'pret'; + case 'herbe': + return this.system.categorie == 'Cuisine' && this.system.sust > 0 ? 'brut' : ''; + case 'faune': + return this.system.sust > 0 ? 'brut' : ''; + } + return ''; + } + + isAlcool() { + return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; + } + isHerbeAPotion() { return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); } @@ -193,13 +216,22 @@ export class RdDItem extends Item { getEnc() { switch (this.type) { case 'herbe': - return encBrin; + return this.getEncHerbe(); case 'gemme': return encPepin * this.system.taille; } return Math.max(this.system.encombrement ?? 0, 0); } + getEncHerbe() { + switch (this.system.categorie) { + case 'Repos': case 'Soin': case 'Alchimie': + return encBrin; + } + return this.system.encombrement; + + } + valeurTotale() { return this.getQuantite() * this.valeur() } @@ -231,17 +263,41 @@ export class RdDItem extends Item { } getActionPrincipale(options = { warnIfNot: true }) { - const warn = options.warnIfNot; switch (this.type) { - case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn); - case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn); - case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn); case 'conteneur': return 'Ouvrir'; - case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined; - case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined; + } + if (this.actor?.isPersonnage()) { + const warn = options.warnIfNot; + if (this.isComestible() == 'brut') { + return 'Utiliser'; + } + switch (this.type) { + case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn); + case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn); + case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn); + case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined; + case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined; + } } return undefined; } + + /* -------------------------------------------- */ + async actionPrincipale(actor, onActionItem = async () => { }) { + if (!this.getActionPrincipale()) { + return; + } + if (await actor.actionNourritureboisson(this, onActionItem)) { + return; + } + switch (this.type) { + case 'potion': return await actor.consommerPotion(this, onActionItem); + case 'livre': return await actor.actionLire(this); + case 'conteneur': return await this.sheet.render(true); + case 'herbe': return await actor.actionHerbe(this); + case 'queue': case 'ombre': return await actor.actionRefoulement(this); + } + } _actionOrWarnQuantiteZero(actionName, warn) { if ((this.system.quantite ?? 0) <= 0) { @@ -260,6 +316,42 @@ export class RdDItem extends Item { await this.quantiteIncDec(-nombre, options); } + async onCreateDecoupeComestible(actor) { + if (actor && this.isComestible() == 'brut' && this.system.sust != 1) { + if (this.system.sust < 1) { + await actor.updateEmbeddedDocuments('Item', [{ + _id: this.id, + 'system.sust': 0 + }]) + } + else { + const sust = Math.floor(this.system.sust); + await actor.updateEmbeddedDocuments('Item', [{ + _id: this.id, + 'system.quantite': this.system.quantite * sust, + 'system.encombrement': Misc.keepDecimals(this.system.encombrement / sust, 2), + 'system.cout': Misc.keepDecimals(this.system.cout / sust, 2), + 'system.sust': 1 + }]) + } + } + } + + async empiler(item) { + if (this.isComestible() == 'brut') { + const sust = this.system.sust + item.system.sust; + const encombrement = this.system.encombrement + item.system.encombrement; + await this.update({ + "system.sust": sust, + "system.encombrement": encombrement + }); + } + else { + await this.quantiteIncDec(item.system.quantite); + } + await item.delete(); + } + async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) { const quantite = Number(this.system.quantite ?? -1); if (quantite >= 0) { @@ -297,8 +389,13 @@ export class RdDItem extends Item { return [false, `Impossible de regrouper ${this.name} avec ${other.name}`]; } else { - const differences = Object.entries(this.system) - .filter(([key, value]) => !['quantite', 'cout', 'encTotal'].includes(key) && value != other.system[key]); + const excludedProperties = ['quantite', 'cout', 'encTotal']; + if (this.isComestible()) { + excludedProperties.push('sust', 'encombrement'); + } + let differences = Object.entries(this.system) + .filter(([key, value]) => !excludedProperties.includes(key)) + .filter(([key, value]) => value != other.system[key]) if (differences.length > 0) { let message = `Impossible de regrouper les ${this.type} ${this.name}: `; for (const [key, value] of differences) { diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 8625e267..c86000df 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -14,6 +14,7 @@ import { RdDNameGen } from "./rdd-namegen.js"; import { RdDConfirm } from "./rdd-confirm.js"; import { RdDCalendrier } from "./rdd-calendrier.js"; import { Environnement } from "./environnement.js"; +import { RdDItemCompetence } from "./item-competence.js"; /* -------------------------------------------- */ // This table starts at 0 -> niveau -10 @@ -170,6 +171,7 @@ export class RdDUtility { //Items '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/item/boutons-comestible.html', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html', diff --git a/template.json b/template.json index c9950acf..a81410e4 100644 --- a/template.json +++ b/template.json @@ -595,6 +595,10 @@ "environnement": { "milieu": "", "environnement": [] + }, + "comestible": { + "sust": 0, + "exotisme": 0 } }, "competence": { @@ -699,13 +703,12 @@ "templates": [ "description", "inventaire" ] }, "nourritureboisson": { - "templates": [ "description", "inventaire" ], + "templates": [ "description", "inventaire", "comestible"], + "cuisinier": "", "boisson": false, "desaltere": 0, "alcoolise": false, - "force": 0, - "sust": 0, - "exotisme": 0 + "force": 0 }, "herbe": { "templates": [ "description", "inventaire", "environnement"], @@ -714,17 +717,14 @@ "categorie": "" }, "ingredient": { - "templates": [ "description", "inventaire", "environnement" ], + "templates": [ "description", "inventaire", "environnement", "comestible"], "niveau": 0, "base": 0, - "sust": 0, - "exotisme": 0, "categorie": "" }, "faune": { - "templates": [ "description", "inventaire", "environnement"], - "sust": 0, - "exotisme": 0, + "templates": [ "description", "inventaire", "environnement", "comestible"], + "categorie": "", "actor": { "id": "", "pack": "", diff --git a/templates/item-faune-sheet.html b/templates/item-faune-sheet.html index 145b7a0c..cde0c58c 100644 --- a/templates/item-faune-sheet.html +++ b/templates/item-faune-sheet.html @@ -3,6 +3,7 @@

    + {{>'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html'}}
    @@ -28,14 +29,18 @@
    {{#if system.actor.id}} + {{#if isGM}} {{else}} - + {{/if}} + {{else}} + + {{/if}}
    {{>"systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html"}} diff --git a/templates/item-herbe-sheet.html b/templates/item-herbe-sheet.html index 8221be6a..a1e6b6b3 100644 --- a/templates/item-herbe-sheet.html +++ b/templates/item-herbe-sheet.html @@ -8,6 +8,7 @@ Fabriquer une potion depuis cette plante {{/if}} + {{>'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html'}} @@ -19,10 +20,6 @@
    -
    - - -
    - + {{#if (eq isComestible 'brut')}} +
    + + +
    + {{#if (gt system.sust 0)}} +
    + + +
    + {{/if}} + {{else}} +
    + + +
    + {{/if}} + {{>"systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}
    diff --git a/templates/item/boutons-comestible.html b/templates/item/boutons-comestible.html new file mode 100644 index 00000000..1117c420 --- /dev/null +++ b/templates/item/boutons-comestible.html @@ -0,0 +1,8 @@ +{{#if (and isOwned isComestible)}} +
    + {{#if (eq isComestible 'brut')}} + Cuisiner + {{/if}} + Manger cru +
    +{{/if}} diff --git a/templates/item/partial-inventaire.html b/templates/item/partial-inventaire.html index 89c678ed..b05413fb 100644 --- a/templates/item/partial-inventaire.html +++ b/templates/item/partial-inventaire.html @@ -9,9 +9,9 @@ {{#unless (isFieldInventaireModifiable type 'encombrement')}}disabled{{/unless}}/>
    - + + {{#unless (isFieldInventaireModifiable type 'quantite')}}disabled{{/unless}}/>
    From 31b4d1cfcc605bb83dd7f5901a747ce2952eaa2c Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 5 Dec 2022 16:36:02 +0100 Subject: [PATCH 5/5] Version 10.3.6 --- system.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system.json b/system.json index 6f40a556..4a1f83d9 100644 --- a/system.json +++ b/system.json @@ -1,8 +1,8 @@ { "id": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", - "version": "10.3.5", - "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.3.5.zip", + "version": "10.3.6", + "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.3.6.zip", "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json", "compatibility": { "minimum": "10",