Merge pull request 'Ragoût de Klampin' (#588) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10

Reviewed-on: public/foundryvtt-reve-de-dragon#588
This commit is contained in:
uberwald 2022-12-05 16:50:33 +01:00
commit f027e3318b
24 changed files with 436 additions and 274 deletions

View File

@ -164,31 +164,11 @@ 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('.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");

View File

@ -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) }
]
}
);
@ -832,7 +831,8 @@ export class RdDActor extends Actor {
type: 'sortreserve',
name: sort.name,
img: sort.img,
system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' } }],
system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' }
}],
{ renderSheet: false });
this.currentTMR.updateTokens();
}
@ -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,25 +1944,33 @@ 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;
}
case 'queue': case 'ombre': return await this.actionRefoulement(item);
}
item.actionPrincipale(this, onActionItem);
}
async actionNourritureboisson(item, onActionItem) {
const dialog = await DialogConsommer.create(this, item, onActionItem);
dialog.render(true);
switch (item.isComestible()) {
case 'brut': {
let d = new Dialog({
title: "Nourriture brute",
content: `Que faire de votre ${item.name}`,
buttons: {
'cuisiner': { icon: '<i class="fas fa-check"></i>', label: 'Cuisiner', callback: async () => await this.preparerNourriture(item) },
'manger': { icon: '<i class="fas fa-check"></i>', label: 'Manger cru', callback: async () => await this.mangerNourriture(item, onActionItem) }
}
});
d.render(true);
return true;
}
case 'pret':
await this.mangerNourriture(item, onActionItem);
return true;
}
return false;
}
async mangerNourriture(item, onActionItem) {
return (await DialogConsommer.create(this, item, onActionItem)).render(true);
}
async actionLire(item) {
@ -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) {
@ -2705,14 +2715,15 @@ 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 },
use: { libre: false, conditions: true, surenc: false },
selectedCarac: duplicate(this.system.carac[selected])
},
{ overwrite: false });
@ -2721,8 +2732,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` },
{
@ -2739,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`);
}
@ -2794,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": artData.oeuvre.system.description,
"sust": Math.min(sust, 1),
"qualite": artData.qualiteFinale,
"exotisme": artData.exotismeFinal,
"description": cuisine.oeuvre.system.description,
"sust": 1,
"qualite": cuisine.qualiteFinale,
"exotisme": cuisine.exotismeFinal,
"encombrement": 0.1,
"quantite": Math.max(1, Math.floor(sust)),
"cout": Math.max(artData.qualiteFinale) * 0.01
"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]);
}
});
}
}
/* -------------------------------------------- */
@ -4136,7 +4178,6 @@ export class RdDActor extends Actor {
await this.checkCompetenceXP(item.name, item.system.xp);
}
}
/* -------------------------------------------- */
async onCreateItem(item, options, id) {
switch (item.type) {
@ -4147,6 +4188,7 @@ export class RdDActor extends Actor {
await this.onCreateOwnedDraconique(item, options, id);
break;
}
await item.onCreateDecoupeComestible(this);
}
async onDeleteItem(item, options, id) {

View File

@ -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,
@ -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;
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);
}

View File

@ -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);
}
}

View File

@ -11,6 +11,7 @@ export class RdDConteneurItemSheet extends RdDItemSheet {
if (this.actor) {
this.prepareConteneurData(formData);
}
return formData;
}
activateListeners(html) {

View File

@ -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.
<br>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);
}
}
}

View File

@ -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);
@ -166,7 +167,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 +182,34 @@ 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 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;
let actor = game.actors.get(actorId);
if (actor) {
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());
html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => itemSheetDialog.render(true)));
}
_getEventActor(event) {
let actorId = event.currentTarget.attributes['data-actor-id'].value;
let actor = game.actors.get(actorId);
return actor;
}
/* -------------------------------------------- */

View File

@ -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,18 +263,42 @@ export class RdDItem extends Item {
}
getActionPrincipale(options = { warnIfNot: true }) {
switch (this.type) {
case 'conteneur': return 'Ouvrir';
}
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 '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;
}
}
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) {
if (warn) {
@ -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) {
@ -287,7 +379,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`];
}
@ -298,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) {

View File

@ -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',
@ -279,6 +281,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 +299,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('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
Handlebars.registerHelper('uniteQuantite', (type) => RdDItem.getUniteQuantite(type));
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 +976,7 @@ export class RdDUtility {
}
static slideOnDelete(sheet, htmlToDelete) {
return htmlToDelete.slideUp(200, () => sheet.render(false));
return htmlToDelete?.slideUp(200, () => sheet.render(false));
}
/* -------------------------------------------- */

View File

@ -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()
},

View File

@ -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",

View File

@ -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": "",

View File

@ -1,6 +1,6 @@
<li class="item flexrow" data-attribute={{key}} data-item-id="{{queue._id}}">
<img class="sheet-competence-img" src="{{queue.img}}" />
<span class="display-label flex-grow">
<span class="item-edit flex-grow">
{{#if (eq queue.type 'ombre')}}
<img class="sheet-competence-img" src="systems/foundryvtt-reve-de-dragon/icons/competence_thanatos.webp" />
{{/if}}

View File

@ -4,7 +4,7 @@
{{#each souffles as |souffle key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{souffle._id}}">
<img class="sheet-competence-img" src="{{souffle.img}}" />
<span class="display-label flex-grow"><a>{{souffle.name}}</a></span>
<span class="item-edit flex-grow"><a>{{souffle.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>

View File

@ -4,7 +4,7 @@
{{#each tetes as |tete key|}}
<li class="item flexrow" data-attribute={{key}} data-item-id="{{tete._id}}">
<img class="sheet-competence-img" src="{{tete.img}}" />
<span class="display-label flex-grow"><a>{{tete.name}}</a></span>
<span class="item-edit flex-grow"><a>{{tete.name}}</a></span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>

View File

@ -4,7 +4,7 @@
{{#each casestmr as |casetmr key|}}
<li class="item list-item flexrow" data-item-id="{{casetmr.id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{casetmr.img}}" />
<span class="display-label"><a>{{casetmr.name}}</a></span>
<span class="item-edit"><a>{{casetmr.name}}</a></span>
<span>{{casetmr.system.coord}} - {{caseTmr-label casetmr.system.coord}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>

View File

@ -4,7 +4,7 @@
{{#each rencontres as |rencontre key|}}
<li class="item flexrow" data-item-id="{{rencontre._id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{rencontre.img}}" />
<span class="display-label flex-grow"><a>
<span class="item-edit flex-grow"><a>
{{rencontre.name}} r{{rencontre.system.force}} ({{rencontre.system.coord}} - {{caseTmr-label rencontre.system.coord}})
</a></span>
{{#if rencontre.system.date}}

View File

@ -4,7 +4,7 @@
{{#each signesdraconiques as |signe key|}}
<li class="item list-item flexrow" data-item-id="{{signe._id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{signe.img}}" />
<span class="display-label flex-grow"><a>{{signe.name}}</a></span>
<span class="item-edit flex-grow"><a>{{signe.name}}</a></span>
<span class="flex-shrink">{{signe.system.difficulte}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete" title="Supprimer"><i class="fas fa-trash"></i></a>

View File

@ -4,7 +4,7 @@
{{#each sortsReserve as |sort key|}}
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{sort.img}}" />
<span class="display-label"><a>{{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}}</a></span>
<span class="item-edit"><a>{{#if sort.system.echectotal}}Echec total: {{/if}}{{sort.name}} r{{sort.system.ptreve}}</a></span>
<span>{{sort.system.coord}} - {{caseTmr-label sort.system.coord}}</span>
<div class="item-controls flex-shrink">
<a class="item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a>

View File

@ -4,7 +4,7 @@
{{#each sorts as |sort key|}}
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{sort.img}}" />
<span class="display-label flex-grow-2">
<span class="item-edit flex-grow-2">
<a data-item-id="{{sort._id}}">{{sort.name}}
- {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}}
</a>

View File

@ -3,6 +3,7 @@
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<div class="header-fields">
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
{{>'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html'}}
</div>
</header>
@ -28,11 +29,15 @@
<label>Créature correspondante</label>
<div>
{{#if system.actor.id}}
{{#if isGM}}
<label>
{{>'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs'
pack=system.actor.pack id=system.actor.id name=system.actor.name}}
</label>
<a class="linked-actor-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
{{else}}
<label>{{system.actor.name}}</label>
{{/if}}
{{else}}
<label>Pas de fiche de créature</label>
{{/if}}

View File

@ -8,6 +8,7 @@
<span><a class="creer-potion-base chat-card-button" data-actor-id="{{actorId}}">Fabriquer une potion depuis cette plante</a></span>
</div>
{{/if}}
{{>'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html'}}
</div>
</header>
@ -19,10 +20,6 @@
<section class="sheet-body">
<div class="tab items" data-group="primary" data-tab="informations">
<div class="flexcol">
<div class="form-group">
<label>Niveau (si applicable)</label>
<input class="attribute-value" type="text" name="system.niveau" value="{{system.niveau}}" data-dtype="Number" />
</div>
<div class="form-group">
<label>Catégorie</label>
<select name="system.categorie" class="categorie" data-dtype="String">
@ -31,6 +28,23 @@
{{/select}}
</select>
</div>
{{#if (eq isComestible 'brut')}}
<div class="form-group">
<label for="system.sust">Sustentation</label>
<input class="attribute-value" type="number" name="system.sust" value="{{system.sust}}" data-dtype="Number" min="0"/>
</div>
{{#if (gt system.sust 0)}}
<div class="form-group">
<label for="system.exotisme">Exotisme</label>
<input class="attribute-value" type="number" name="system.exotisme" value="{{system.exotisme}}" data-dtype="Number" min="-10" max="0"/>
</div>
{{/if}}
{{else}}
<div class="form-group">
<label>Niveau (si applicable)</label>
<input class="attribute-value" type="text" name="system.niveau" value="{{system.niveau}}" data-dtype="Number" />
</div>
{{/if}}
{{>"systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}}

View File

@ -0,0 +1,8 @@
{{#if (and isOwned isComestible)}}
<div class="form-group">
{{#if (eq isComestible 'brut')}}
<span><a class="preparer-nourriture chat-card-button" data-actor-id="{{actorId}}">Cuisiner</a></span>
{{/if}}
<span><a class="manger-nourriture chat-card-button" data-actor-id="{{actorId}}">Manger cru</a></span>
</div>
{{/if}}

View File

@ -9,7 +9,7 @@
{{#unless (isFieldInventaireModifiable type 'encombrement')}}disabled{{/unless}}/>
</div>
<div class="form-group">
<label for="system.quantite">Quantité {{uniteQuantite type}}</label>
<label for="system.quantite">Quantité {{uniteQuantite id actorId}}</label>
<input class="attribute-value" type="text" name="system.quantite" value="{{system.quantite}}" data-dtype="Number"
{{#unless (isFieldInventaireModifiable type 'quantite')}}disabled{{/unless}}/>
</div>