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

Reviewed-on: #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

@ -133,7 +133,7 @@ export class RdDActorSheet extends ActorSheet {
async _onDropItem(event, dragData) { async _onDropItem(event, dragData) {
const destItemId = $(event.target)?.closest('.item').attr('data-item-id') const destItemId = $(event.target)?.closest('.item').attr('data-item-id')
const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur) const dropParams = RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur)
if (dropParams){ if (dropParams) {
const callSuper = await this.actor.processDropItem(dropParams) const callSuper = await this.actor.processDropItem(dropParams)
if (callSuper) { if (callSuper) {
await super._onDropItem(event, dragData) await super._onDropItem(event, dragData)
@ -164,31 +164,11 @@ export class RdDActorSheet extends ActorSheet {
const item = RdDSheetUtility.getItem(event, this.actor); const item = RdDSheetUtility.getItem(event, this.actor);
RdDSheetUtility.splitItem(item, this.actor); RdDSheetUtility.splitItem(item, this.actor);
}); });
html.find('.item-edit').click(async event => { html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true))
const item = RdDSheetUtility.getItem(event, this.actor) html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor)));
item.sheet.render(true) 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('.display-label a').click(async event => { html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor));
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('.subacteur-delete').click(async event => { html.find('.subacteur-delete').click(async event => {
const li = RdDSheetUtility.getEventElement(event); const li = RdDSheetUtility.getEventElement(event);
const actorId = li.data("actor-id"); const actorId = li.data("actor-id");

View File

@ -250,7 +250,7 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getReveActuel() { getReveActuel() {
switch(this.type) { switch (this.type) {
case 'personnage': case 'personnage':
return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value); return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value);
case 'creature': case 'creature':
@ -620,7 +620,7 @@ export class RdDActor extends Actor {
content: 'Remise à neuf de ' + this.name content: 'Remise à neuf de ' + this.name
}); });
const updates = { 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.isEntite([ENTITE_INCARNE, ENTITE_BLURETTE])) {
if (this.system.blessures) { if (this.system.blessures) {
@ -631,7 +631,7 @@ export class RdDActor extends Actor {
updates['system.sante.vie.value'] = this.system.sante.vie.max; updates['system.sante.vie.value'] = this.system.sante.vie.max;
updates['system.sante.fatigue.value'] = 0; updates['system.sante.fatigue.value'] = 0;
if (this.isPersonnage()) { 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); await this.update(updates);
@ -809,8 +809,7 @@ export class RdDActor extends Actor {
name: 'maitrise', name: 'maitrise',
label: 'Maîtriser le Rêve de Dragon', label: 'Maîtriser le Rêve de Dragon',
callbacks: [ callbacks: [
{ action: async r => { action: async r => this.resultCombatReveDeDragon(r) }
this.resultCombatReveDeDragon(r) }
] ]
} }
); );
@ -832,8 +831,9 @@ export class RdDActor extends Actor {
type: 'sortreserve', type: 'sortreserve',
name: sort.name, name: sort.name,
img: sort.img, 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}); }],
{ renderSheet: false });
this.currentTMR.updateTokens(); this.currentTMR.updateTokens();
} }
@ -923,7 +923,7 @@ export class RdDActor extends Actor {
return; return;
} }
const xpUtilise = Math.max(0, Math.min(stress, xpRequis)); 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 nouveauNiveau = niveau + gainNiveau;
const nouveauXp = gainNiveau > 0 ? Math.max(competence.system.xp - xpSuivant, 0) : (competence.system.xp + xpUtilise); const nouveauXp = gainNiveau > 0 ? Math.max(competence.system.xp - xpSuivant, 0) : (competence.system.xp + xpUtilise);
await competence.update({ await competence.update({
@ -1209,7 +1209,7 @@ export class RdDActor extends Actor {
const cible = this.getContenantOrParent(dest); const cible = this.getContenantOrParent(dest);
const [empilable, message] = item.isInventaireEmpilable(dest); const [empilable, message] = item.isInventaireEmpilable(dest);
if (empilable) { if (empilable) {
await this.regrouperEquipementsSimilaires(item, dest); await dest.empiler(item)
result = false; result = false;
} }
// changer de conteneur // changer de conteneur
@ -1309,11 +1309,6 @@ export class RdDActor extends Actor {
return itemMap; return itemMap;
} }
async regrouperEquipementsSimilaires(item, dest) {
await dest.quantiteIncDec(item.system.quantite);
await item.delete();
}
isSurenc() { isSurenc() {
return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false
} }
@ -1568,7 +1563,7 @@ export class RdDActor extends Actor {
async deleteTMRRencontreAtPosition() { async deleteTMRRencontreAtPosition() {
const demiReve = this.getDemiReve() const demiReve = this.getDemiReve()
let rencontreIds = this.items.filter(it => it.type == 'rencontre' && it.system.coord == demiReve).map(it => it.id); 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); await this.deleteEmbeddedDocuments('Item', rencontreIds);
} }
} }
@ -1576,7 +1571,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async addTMRRencontre(currentRencontre) { async addTMRRencontre(currentRencontre) {
const toCreate = currentRencontre.toObject(); const toCreate = currentRencontre.toObject();
console.log('actor.addTMRRencontre(', toCreate,')'); console.log('actor.addTMRRencontre(', toCreate, ')');
this.createEmbeddedDocuments('Item', [toCreate]); this.createEmbeddedDocuments('Item', [toCreate]);
} }
@ -1813,7 +1808,7 @@ export class RdDActor extends Actor {
const value = this.system.etat[name].value; const value = this.system.etat[name].value;
const max = this.system.etat[name].max; const max = this.system.etat[name].max;
const newValue = value + inc; const newValue = value + inc;
if (0 <= newValue && newValue <=max) { if (0 <= newValue && newValue <= max) {
await this.update({ [`system.etat.${name}.value`]: newValue }) await this.update({ [`system.etat.${name}.value`]: newValue })
} }
} }
@ -1949,25 +1944,33 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async actionItem(item, onActionItem = async () => { }) { async actionItem(item, onActionItem = async () => { }) {
if (!item.getActionPrincipale()) return; item.actionPrincipale(this, onActionItem);
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);
}
} }
async actionNourritureboisson(item, onActionItem) { async actionNourritureboisson(item, onActionItem) {
const dialog = await DialogConsommer.create(this, item, onActionItem); switch (item.isComestible()) {
dialog.render(true); 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) { async actionLire(item) {
@ -1976,11 +1979,18 @@ export class RdDActor extends Actor {
await this.rollTache(tache.id); await this.rollTache(tache.id);
} }
} }
async actionHerbe(item) {
if (item.isHerbeAPotion()) {
return this.dialogFabriquerPotion(item);
}
return;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async consommer(item, choix) { async consommer(item, choix) {
switch (item.type) { switch (item.type) {
case 'nourritureboisson': case 'nourritureboisson':
case 'herbe': case 'faune':
return await this.consommerNourritureboisson(item.id, choix); return await this.consommerNourritureboisson(item.id, choix);
case 'potion': case 'potion':
return await this.consommerPotion(item) return await this.consommerPotion(item)
@ -1988,7 +1998,7 @@ 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) { if (userId != undefined && userId != game.user.id) {
RdDActor.remoteActorCall({ RdDActor.remoteActorCall({
actorId: this.id, actorId: this.id,
@ -1999,7 +2009,7 @@ export class RdDActor extends Actor {
return; return;
} }
const item = this.getObjet(itemId) const item = this.getObjet(itemId)
if (item.type != 'nourritureboisson') { if (!item.isComestible()) {
return; return;
} }
if (choix.doses > item.system.quantite) { if (choix.doses > item.system.quantite) {
@ -2297,9 +2307,9 @@ export class RdDActor extends Actor {
if (xpData) { if (xpData) {
const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, xpData); const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.html`, xpData);
if (hideChatMessage) { if (hideChatMessage) {
ChatUtility.blindMessageToGM({ content: content}); ChatUtility.blindMessageToGM({ content: content });
} }
else{ else {
ChatMessage.create({ ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
content: content content: content
@ -2583,7 +2593,7 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollCompetence(idOrName, options = {tryTarget: true}) { async rollCompetence(idOrName, options = { tryTarget: true }) {
let rollData = { let rollData = {
carac: this.system.carac, carac: this.system.carac,
competence: this.getCompetence(idOrName) competence: this.getCompetence(idOrName)
@ -2705,14 +2715,15 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _rollArt(artData, selected, oeuvre, callBackResult = r => this._resultArt(r)) { async _rollArt(artData, selected, oeuvre, callBackResult = r => this._resultArt(r)) {
oeuvre.system.niveau = oeuvre.system.niveau ?? 0;
mergeObject(artData, mergeObject(artData,
{ {
oeuvre: oeuvre, oeuvre: oeuvre,
art: oeuvre.type, art: oeuvre.type,
competence: duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)), competence: duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)),
diffLibre: - (oeuvre.system.niveau ?? 0), diffLibre: - oeuvre.system.niveau,
diffConditions: 0, diffConditions: 0,
use: { libre: false, conditions: true }, use: { libre: false, conditions: true, surenc: false },
selectedCarac: duplicate(this.system.carac[selected]) selectedCarac: duplicate(this.system.carac[selected])
}, },
{ overwrite: false }); { overwrite: false });
@ -2721,8 +2732,6 @@ export class RdDActor extends Actor {
artData.forceCarac = {}; artData.forceCarac = {};
artData.forceCarac[selected] = duplicate(this.system.carac[selected]); artData.forceCarac[selected] = duplicate(this.system.carac[selected]);
} }
console.log("rollArt !!!", artData);
const dialog = await RdDRoll.create(this, artData, const dialog = await RdDRoll.create(this, artData,
{ html: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html` }, { html: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html` },
{ {
@ -2739,8 +2748,9 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _resultArt(artData) { async _resultArt(artData) {
const baseQualite = (artData.rolled.isSuccess ? artData.oeuvre.system.niveau : artData.competence.system.niveau); const niveau = artData.oeuvre.system.niveau ?? 0;
artData.qualiteFinale = Math.min(baseQualite, artData.oeuvre.system.niveau) + artData.rolled.ptQualite; 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`); await RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`);
} }
@ -2794,32 +2804,64 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async _resultRecetteCuisine(artData) { async _resultRecetteCuisine(cuisine) {
const baseQualite = (artData.rolled.isSuccess ? artData.oeuvre.system.niveau : artData.competence.system.niveau); const niveauRecette = cuisine.oeuvre.system.niveau ?? 0;
const sust = artData.oeuvre.system.sust * artData.proportions; const baseQualite = (cuisine.rolled.isSuccess ? niveauRecette : cuisine.competence.system.niveau);
artData.qualiteFinale = Math.min(baseQualite, artData.oeuvre.system.niveau) + artData.rolled.ptQualite; cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite;
artData.exotismeFinal = Math.min(Math.min(artData.qualiteFinale, artData.oeuvre.system.exotisme ?? 0), 0); cuisine.exotismeFinal = Math.min(Math.min(cuisine.qualiteFinale, cuisine.oeuvre.system.exotisme ?? 0), 0);
//console.log("OEUVRE", artData.art, artData) cuisine.sust = cuisine.oeuvre.system.sust * Math.min(cuisine.proportions, cuisine.proportionsMax ?? cuisine.proportions)
const platCuisine = { const platCuisine = {
name: artData.oeuvre.name, name: cuisine.oeuvre.name,
type: 'nourritureboisson', type: 'nourritureboisson',
img: 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp', img: 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp',
system: { system: {
"description": artData.oeuvre.system.description, "description": cuisine.oeuvre.system.description,
"sust": Math.min(sust, 1), "sust": 1,
"qualite": artData.qualiteFinale, "qualite": cuisine.qualiteFinale,
"exotisme": artData.exotismeFinal, "exotisme": cuisine.exotismeFinal,
"encombrement": 0.1, "encombrement": 0.1,
"quantite": Math.max(1, Math.floor(sust)), "quantite": Math.max(1, Math.floor(cuisine.sust)),
"cout": Math.max(artData.qualiteFinale) * 0.01 "cout": Math.max(cuisine.qualiteFinale) * 0.01
} }
}; }
if (artData.ajouterEquipement) { if (cuisine.ajouterEquipement) {
await this.createEmbeddedDocuments('Item', [platCuisine]); await this.createEmbeddedDocuments('Item', [platCuisine]);
ui.notifications.info(`${platCuisine.system.quantite} rations de ${platCuisine.name} ont été ajoutés à votre équipement`); ui.notifications.info(`${platCuisine.system.quantite} rations de ${platCuisine.name} ont été ajoutés à votre équipement`);
} }
artData.platCuisine = platCuisine; cuisine.platCuisine = platCuisine;
await RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`); 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]);
}
});
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -3171,7 +3213,7 @@ export class RdDActor extends Actor {
const caracList = Object.entries(carac); const caracList = Object.entries(carac);
let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' }); 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' }); entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' });
} }
return entry && entry.length > 0 ? carac[entry[0]] : undefined; return entry && entry.length > 0 ? carac[entry[0]] : undefined;
@ -3265,13 +3307,13 @@ export class RdDActor extends Actor {
title: 'Ne pas utiliser les automatisation de combat', title: 'Ne pas utiliser les automatisation de combat',
buttonLabel: "Pas d'automatisation", buttonLabel: "Pas d'automatisation",
onAction: async () => { onAction: async () => {
this.rollCompetence(arme.system.competence, {tryTarget: false}) this.rollCompetence(arme.system.competence, { tryTarget: false })
} }
}); });
return; return;
} }
Targets.selectOneToken(target => { 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}!!!!`); ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
return; return;
} }
@ -3880,7 +3922,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
addSubActeur(subActor) { 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") ui.notifications.warn("Vous ne pouvez pas attacher un acteur à lui même")
} }
else if (!subActor?.isOwner) { else if (!subActor?.isOwner) {
@ -4107,10 +4149,10 @@ export class RdDActor extends Actor {
} }
console.log("setEffect", statusId, status) console.log("setEffect", statusId, status)
const effect = this.getEffect(statusId); const effect = this.getEffect(statusId);
if (!status && effect){ if (!status && effect) {
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]); await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
} }
if (status && !effect ) { if (status && !effect) {
await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.status(statusId)]); await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.status(statusId)]);
} }
} }
@ -4136,7 +4178,6 @@ export class RdDActor extends Actor {
await this.checkCompetenceXP(item.name, item.system.xp); await this.checkCompetenceXP(item.name, item.system.xp);
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async onCreateItem(item, options, id) { async onCreateItem(item, options, id) {
switch (item.type) { switch (item.type) {
@ -4147,6 +4188,7 @@ export class RdDActor extends Actor {
await this.onCreateOwnedDraconique(item, options, id); await this.onCreateOwnedDraconique(item, options, id);
break; break;
} }
await item.onCreateDecoupeComestible(this);
} }
async onDeleteItem(item, options, id) { async onDeleteItem(item, options, id) {

View File

@ -2,13 +2,13 @@ import { Misc } from "./misc.js";
export class DialogConsommer extends Dialog { 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 consommerData = DialogConsommer.prepareData(actor, item);
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData); const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-item-consommer.html', consommerData);
return new DialogConsommer(actor, item, consommerData, html, onActionItem) 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 }; const options = { classes: ["dialogconsommer"], width: 350, height: 'fit-content', 'z-index': 99999 };
let conf = { let conf = {
title: consommerData.title, title: consommerData.title,
@ -18,7 +18,8 @@ export class DialogConsommer extends Dialog {
[consommerData.buttonName]: { [consommerData.buttonName]: {
label: consommerData.buttonName, callback: async it => { label: consommerData.buttonName, callback: async it => {
await this.onConsommer(it); await this.onConsommer(it);
await onActionItem();} await onActionItem();
}
} }
} }
}; };
@ -38,9 +39,8 @@ export class DialogConsommer extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
static prepareData(actor, item) { static prepareData(actor, item) {
item = duplicate(item);
let consommerData = { let consommerData = {
item: item, item: duplicate(item),
cuisine: actor.getCompetence('cuisine'), cuisine: actor.getCompetence('cuisine'),
choix: { choix: {
doses: 1, doses: 1,
@ -48,25 +48,47 @@ export class DialogConsommer extends Dialog {
} }
} }
switch (item.type) { switch (item.type) {
case 'herbe': case 'faune':
consommerData.title = 'Manger une portion crue: ';
consommerData.buttonName = "Manger";
break;
case 'nourritureboisson': 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"; consommerData.buttonName = item.system.boisson ? "Boire" : "Manger";
break; break;
case 'potion': case 'potion':
consommerData.title = `${item.name}: boire la potion`; consommerData.title = 'Boire la potion: ';
consommerData.buttonName = "Boire"; consommerData.buttonName = "Boire";
break; break;
} }
DialogConsommer.calculDoses(consommerData, consommerData.choix.doses) consommerData.title += item.name;
DialogConsommer.calculDoses(consommerData, item)
return consommerData; return consommerData;
} }
static calculDoses(consommer) { static calculDoses(consommer, item) {
const doses = consommer.choix.doses; 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.totalSust = Misc.keepDecimals(doses * (consommer.item.system.sust ?? 0), 2);
consommer.totalDesaltere = consommer.item.system.boisson consommer.totalDesaltere = consommer.item.system.boisson
? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2) ? Misc.keepDecimals(doses * (consommer.item.system.desaltere ?? 0), 2)
: 0; : 0;
break;
case 'potion':
consommer.totalSust = 0
consommer.totalDesaltere = 0
}
} }
@ -84,7 +106,7 @@ export class DialogConsommer extends Dialog {
selectDoses(event) { selectDoses(event) {
this.consommerData.choix.doses = Number(event.currentTarget.value); 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-sust").text(this.consommerData.totalSust);
$(".total-desaltere").text(this.consommerData.totalDesaltere); $(".total-desaltere").text(this.consommerData.totalDesaltere);
} }

View File

@ -281,4 +281,36 @@ export class RdDItemCompetence extends Item {
return duplicate(limitesArchetypes); 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) { if (this.actor) {
this.prepareConteneurData(formData); this.prepareConteneurData(formData);
} }
return formData;
} }
activateListeners(html) { activateListeners(html) {

View File

@ -26,21 +26,22 @@ export class RdDFauneItemSheet extends RdDItemSheet {
EnvironmentSheetHelper.activateListeners(this, html); EnvironmentSheetHelper.activateListeners(this, html);
html.find("a.linked-actor-delete").click(event => this.onDeleteLinkedActor()); 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) { async _onDropActor(event, dragData) {
console.log('faune:dropActor', event, dragData) console.log('faune:dropActor', event, dragData)
const actor = fromUuidSync(dragData.uuid); const linkedActor = fromUuidSync(dragData.uuid);
if (actor?.pack) { if (linkedActor?.pack) {
this.item.update({ this.item.update({
'system.actor.pack': actor.pack, 'system.actor.pack': linkedActor.pack,
'system.actor.id': actor._id, 'system.actor.id': linkedActor._id,
'system.actor.name': actor.name 'system.actor.name': linkedActor.name
}); });
} }
else { 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`) <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': '' '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", cssClass: this.isEditable ? "editable" : "locked",
isSoins: false, isSoins: false,
description: await TextEditor.enrichHTML(this.item.system.description, { async: true }), 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); 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.ondragstart = (event) => this._onDragStart(event);
this.form.ondrop = (event) => this._onDrop(event); this.form.ondrop = (event) => this._onDrop(event);
// Select competence categorie // Select competence categorie
html.find(".categorie").change(event => this._onSelectCategorie(event)); 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); this.dateUpdated = game.system.rdd.calendrier.getIndexFromDate(jour, mois);
}); });
html.find('.creer-tache-livre').click((event) => { html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item));
let actorId = event.currentTarget.attributes['data-actor-id'].value; html.find('.consommer-potion').click((event) => this._getEventActor(event).consommerPotion(this.item));
let actor = game.actors.get(actorId); html.find('.creer-potion-base').click((event) => this._getEventActor(event).dialogFabriquerPotion(this.item));
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('.alchimie-tache a').click((event) => { 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 recetteId = event.currentTarget.attributes['data-recette-id'].value;
let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value; let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value;
let tacheData = event.currentTarget.attributes['data-alchimie-data'].value; let tacheData = event.currentTarget.attributes['data-alchimie-data'].value;
let actor = game.actors.get(actorId);
if (actor) {
actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData); actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData);
} else { } else {
ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique."); ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique.");
} }
}); });
html.find('.item-split').click(async event => { html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => itemSheetDialog.render(true)));
const item = RdDSheetUtility.getItem(event, this.actor); html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true));
await RdDSheetUtility.splitItem(item, this.actor, async () => itemSheetDialog.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-edit').click(async event => { html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem());
const item = RdDSheetUtility.getItem(event, this.actor); html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => itemSheetDialog.render(true)));
item.sheet.render(true); }
});
html.find('.item-delete').click(async event => { _getEventActor(event) {
const li = RdDSheetUtility.getEventElement(event); let actorId = event.currentTarget.attributes['data-actor-id'].value;
const item = this.actor.getObjet(li.data("item-id")); let actor = game.actors.get(actorId);
RdDUtility.confirmerSuppressionItem(this, item, li); return actor;
});
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));
});
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@ -1,5 +1,6 @@
import { DialogItemVente } from "./dialog-item-vente.js"; import { DialogItemVente } from "./dialog-item-vente.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { RdDHerbes } from "./rdd-herbes.js"; import { RdDHerbes } from "./rdd-herbes.js";
import { RdDUtility } from "./rdd-utility.js"; import { RdDUtility } from "./rdd-utility.js";
@ -91,10 +92,16 @@ export class RdDItem extends Item {
return true; return true;
} }
static getUniteQuantite(type) { getUniteQuantite() {
switch (type) { switch (this.type) {
case "monnaie": return "(Pièces)" 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)" case "ingredient": return "(Pépins ou Brins)"
} }
return ''; return '';
@ -165,9 +172,25 @@ export class RdDItem extends Item {
return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0; return !this.isConteneur() || (this.system.contenu?.length ?? 0) == 0;
} }
isAlcool() { isNourritureBoisson() {
return this.type == 'nourritureboisson' && this.system.boisson && this.system.alcoolise; 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() { isHerbeAPotion() {
return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos');
} }
@ -193,13 +216,22 @@ export class RdDItem extends Item {
getEnc() { getEnc() {
switch (this.type) { switch (this.type) {
case 'herbe': case 'herbe':
return encBrin; return this.getEncHerbe();
case 'gemme': case 'gemme':
return encPepin * this.system.taille; return encPepin * this.system.taille;
} }
return Math.max(this.system.encombrement ?? 0, 0); 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() { valeurTotale() {
return this.getQuantite() * this.valeur() return this.getQuantite() * this.valeur()
} }
@ -231,18 +263,42 @@ export class RdDItem extends Item {
} }
getActionPrincipale(options = { warnIfNot: true }) { getActionPrincipale(options = { warnIfNot: true }) {
switch (this.type) {
case 'conteneur': return 'Ouvrir';
}
if (this.actor?.isPersonnage()) {
const warn = options.warnIfNot; const warn = options.warnIfNot;
if (this.isComestible() == 'brut') {
return 'Utiliser';
}
switch (this.type) { switch (this.type) {
case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn); case 'nourritureboisson': return this._actionOrWarnQuantiteZero(this.system.boisson ? 'Boire' : 'Manger', warn);
case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn); case 'potion': return this._actionOrWarnQuantiteZero('Boire', warn);
case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn); case 'livre': return this._actionOrWarnQuantiteZero('Lire', warn);
case 'conteneur': return 'Ouvrir';
case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined; case 'herbe': return this.isHerbeAPotion() ? this._actionOrWarnQuantiteZero('Décoction', warn) : undefined;
case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined; case 'queue': case 'ombre': return this.system.refoulement > 0 ? 'Refouler' : undefined;
} }
}
return 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) { _actionOrWarnQuantiteZero(actionName, warn) {
if ((this.system.quantite ?? 0) <= 0) { if ((this.system.quantite ?? 0) <= 0) {
if (warn) { if (warn) {
@ -260,6 +316,42 @@ export class RdDItem extends Item {
await this.quantiteIncDec(-nombre, options); 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 }) { async quantiteIncDec(nombre, options = { diminuerQuantite: true, supprimerSiZero: false }) {
const quantite = Number(this.system.quantite ?? -1); const quantite = Number(this.system.quantite ?? -1);
if (quantite >= 0) { if (quantite >= 0) {
@ -287,7 +379,6 @@ export class RdDItem extends Item {
if (!other || !this.isInventaire()) { if (!other || !this.isInventaire()) {
return [false, undefined]; return [false, undefined];
} }
if (this.system.quantite == undefined) { if (this.system.quantite == undefined) {
return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`]; 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}`]; return [false, `Impossible de regrouper ${this.name} avec ${other.name}`];
} }
else { else {
const differences = Object.entries(this.system) const excludedProperties = ['quantite', 'cout', 'encTotal'];
.filter(([key, value]) => !['quantite', 'cout', 'encTotal'].includes(key) && value != other.system[key]); 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) { if (differences.length > 0) {
let message = `Impossible de regrouper les ${this.type} ${this.name}: `; let message = `Impossible de regrouper les ${this.type} ${this.name}: `;
for (const [key, value] of differences) { 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 { RdDConfirm } from "./rdd-confirm.js";
import { RdDCalendrier } from "./rdd-calendrier.js"; import { RdDCalendrier } from "./rdd-calendrier.js";
import { Environnement } from "./environnement.js"; import { Environnement } from "./environnement.js";
import { RdDItemCompetence } from "./item-competence.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
// This table starts at 0 -> niveau -10 // This table starts at 0 -> niveau -10
@ -170,6 +171,7 @@ export class RdDUtility {
//Items //Items
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs', 'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs',
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs', 'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs',
'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-inventaire.html',
'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html',
'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html',
@ -279,6 +281,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/chat-signe-draconique-actor.html' '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('upperFirst', str => Misc.upperFirst(str ?? 'Null'));
Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null')); Handlebars.registerHelper('lowerFirst', str => Misc.lowerFirst(str ?? 'Null'));
Handlebars.registerHelper('upper', str => str?.toUpperCase() ?? '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('min', (...args) => Math.min(...args.slice(0, -1)));
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option)); Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));
Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name))); Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name)));
Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.system.isVisible) Handlebars.registerHelper('filtreTriCompetences', competences => RdDItemCompetence.triVisible(competences));
.sort((a, b) => { Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
if (a.name.startsWith("Survie") && b.name.startsWith("Survie")) { Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite());
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('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field)); Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field));
Handlebars.registerHelper('getFrequenceRarete', (rarete, field) => Environnement.getFrequenceRarete(rarete, field)); Handlebars.registerHelper('getFrequenceRarete', (rarete, field) => Environnement.getFrequenceRarete(rarete, field));
Handlebars.registerHelper('either', (a, b) => a ?? b);
return loadTemplates(templatePaths); 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) { static linkCompendium(pack, id, name) {
return `@Compendium[${pack}.${id}]{${name}}`; return `@Compendium[${pack}.${id}]{${name}}`;
} }
@ -1001,7 +976,7 @@ export class RdDUtility {
} }
static slideOnDelete(sheet, htmlToDelete) { 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: { encTotal: {
isVisible: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac) && RdDItemCompetence.isMalusEncombrementTotal(rollData.competence), 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', getLabel: (rollData, actor) => 'Encombrement total',
getValue: (rollData, actor) => -actor.getEncTotal() getValue: (rollData, actor) => -actor.getEncTotal()
}, },

View File

@ -1,8 +1,8 @@
{ {
"id": "foundryvtt-reve-de-dragon", "id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon", "title": "Rêve de Dragon",
"version": "10.3.5", "version": "10.3.6",
"download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.3.5.zip", "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", "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"compatibility": { "compatibility": {
"minimum": "10", "minimum": "10",

View File

@ -595,6 +595,10 @@
"environnement": { "environnement": {
"milieu": "", "milieu": "",
"environnement": [] "environnement": []
},
"comestible": {
"sust": 0,
"exotisme": 0
} }
}, },
"competence": { "competence": {
@ -699,13 +703,12 @@
"templates": [ "description", "inventaire" ] "templates": [ "description", "inventaire" ]
}, },
"nourritureboisson": { "nourritureboisson": {
"templates": [ "description", "inventaire" ], "templates": [ "description", "inventaire", "comestible"],
"cuisinier": "",
"boisson": false, "boisson": false,
"desaltere": 0, "desaltere": 0,
"alcoolise": false, "alcoolise": false,
"force": 0, "force": 0
"sust": 0,
"exotisme": 0
}, },
"herbe": { "herbe": {
"templates": [ "description", "inventaire", "environnement"], "templates": [ "description", "inventaire", "environnement"],
@ -714,17 +717,14 @@
"categorie": "" "categorie": ""
}, },
"ingredient": { "ingredient": {
"templates": [ "description", "inventaire", "environnement" ], "templates": [ "description", "inventaire", "environnement", "comestible"],
"niveau": 0, "niveau": 0,
"base": 0, "base": 0,
"sust": 0,
"exotisme": 0,
"categorie": "" "categorie": ""
}, },
"faune": { "faune": {
"templates": [ "description", "inventaire", "environnement"], "templates": [ "description", "inventaire", "environnement", "comestible"],
"sust": 0, "categorie": "",
"exotisme": 0,
"actor": { "actor": {
"id": "", "id": "",
"pack": "", "pack": "",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
{{#each sortsReserve as |sort key|}} {{#each sortsReserve as |sort key|}}
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}"> <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{sort.img}}" /> <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> <span>{{sort.system.coord}} - {{caseTmr-label sort.system.coord}}</span>
<div class="item-controls flex-shrink"> <div class="item-controls flex-shrink">
<a class="item-delete flex-shrink" title="Supprimer"><i class="fas fa-trash"></i></a> <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|}} {{#each sorts as |sort key|}}
<li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}"> <li class="item list-item flexrow" data-item-id="{{sort._id}}" data-attribute="{{key}}">
<img class="sheet-competence-img" src="{{sort.img}}" /> <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}} <a data-item-id="{{sort._id}}">{{sort.name}}
- {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}} - {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}}
</a> </a>

View File

@ -3,6 +3,7 @@
<img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" /> <img class="profile-img" src="{{img}}" data-edit="img" title="{{name}}" />
<div class="header-fields"> <div class="header-fields">
<h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1> <h1 class="charname"><input name="name" type="text" value="{{name}}" placeholder="Name" /></h1>
{{>'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html'}}
</div> </div>
</header> </header>
@ -28,11 +29,15 @@
<label>Créature correspondante</label> <label>Créature correspondante</label>
<div> <div>
{{#if system.actor.id}} {{#if system.actor.id}}
{{#if isGM}}
<label> <label>
{{>'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs' {{>'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs'
pack=system.actor.pack id=system.actor.id name=system.actor.name}} pack=system.actor.pack id=system.actor.id name=system.actor.name}}
</label> </label>
<a class="linked-actor-delete" title="Supprimer"><i class="fas fa-trash"></i></a> <a class="linked-actor-delete" title="Supprimer"><i class="fas fa-trash"></i></a>
{{else}}
<label>{{system.actor.name}}</label>
{{/if}}
{{else}} {{else}}
<label>Pas de fiche de créature</label> <label>Pas de fiche de créature</label>
{{/if}} {{/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> <span><a class="creer-potion-base chat-card-button" data-actor-id="{{actorId}}">Fabriquer une potion depuis cette plante</a></span>
</div> </div>
{{/if}} {{/if}}
{{>'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html'}}
</div> </div>
</header> </header>
@ -19,10 +20,6 @@
<section class="sheet-body"> <section class="sheet-body">
<div class="tab items" data-group="primary" data-tab="informations"> <div class="tab items" data-group="primary" data-tab="informations">
<div class="flexcol"> <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"> <div class="form-group">
<label>Catégorie</label> <label>Catégorie</label>
<select name="system.categorie" class="categorie" data-dtype="String"> <select name="system.categorie" class="categorie" data-dtype="String">
@ -31,6 +28,23 @@
{{/select}} {{/select}}
</select> </select>
</div> </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/item/partial-inventaire.html"}}
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.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}}/> {{#unless (isFieldInventaireModifiable type 'encombrement')}}disabled{{/unless}}/>
</div> </div>
<div class="form-group"> <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" <input class="attribute-value" type="text" name="system.quantite" value="{{system.quantite}}" data-dtype="Number"
{{#unless (isFieldInventaireModifiable type 'quantite')}}disabled{{/unless}}/> {{#unless (isFieldInventaireModifiable type 'quantite')}}disabled{{/unless}}/>
</div> </div>