Merge pull request 'Monnaies et armes à distance' (#563) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: public/foundryvtt-reve-de-dragon#563
This commit is contained in:
commit
690dd1f0a2
@ -116,17 +116,13 @@ export class RdDActor extends Actor {
|
|||||||
const isPersonnage = actorData.type == "personnage";
|
const isPersonnage = actorData.type == "personnage";
|
||||||
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
|
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
|
||||||
if (actorData.items) {
|
if (actorData.items) {
|
||||||
let actor = await super.create(actorData, options);
|
return await super.create(actorData, options);
|
||||||
if (isPersonnage) {
|
|
||||||
await actor.checkMonnaiePresence();
|
|
||||||
}
|
|
||||||
return actor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPersonnage) {
|
if (isPersonnage) {
|
||||||
const competences = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(actorData.type));
|
const competences = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(actorData.type));
|
||||||
actorData.items = competences.map(i => i.toObject());
|
actorData.items = competences.map(i => i.toObject());
|
||||||
actorData.items = actorData.items.concat(Monnaie.monnaiesData());
|
actorData.items = actorData.items.concat(Monnaie.monnaiesStandard());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
actorData.items = [];
|
actorData.items = [];
|
||||||
@ -143,9 +139,9 @@ export class RdDActor extends Actor {
|
|||||||
|
|
||||||
// Make separate methods for each Actor type (character, npc, etc.) to keep
|
// Make separate methods for each Actor type (character, npc, etc.) to keep
|
||||||
// things organized.
|
// things organized.
|
||||||
if (this.type === 'personnage') this._prepareCharacterData(this)
|
if (this.isPersonnage()) this._prepareCharacterData(this)
|
||||||
if (this.type === 'creature') this._prepareCreatureData(this)
|
if (this.isCreature()) this._prepareCreatureData(this)
|
||||||
if (this.type === 'vehicule') this._prepareVehiculeData(this)
|
if (this.isVehicule()) this._prepareVehiculeData(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -180,8 +176,6 @@ export class RdDActor extends Actor {
|
|||||||
await this.cleanupConteneurs();
|
await this.cleanupConteneurs();
|
||||||
await this.computeEncombrementTotalEtMalusArmure();
|
await this.computeEncombrementTotalEtMalusArmure();
|
||||||
this.computeEtatGeneral();
|
this.computeEtatGeneral();
|
||||||
// Sanity check
|
|
||||||
await this.checkMonnaiePresence();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -194,15 +188,6 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async checkMonnaiePresence() { // Ajout opportuniste si les pièces n'existent pas.
|
|
||||||
if (!this.items) return; // Sanity check during import
|
|
||||||
let manquantes = Monnaie.monnaiesManquantes(this);
|
|
||||||
if (manquantes.length > 0) {
|
|
||||||
await this.createEmbeddedDocuments('Item', manquantes, { renderSheet: false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
isCreature() {
|
isCreature() {
|
||||||
return this.type == 'creature' || this.type == 'entite';
|
return this.type == 'creature' || this.type == 'entite';
|
||||||
@ -211,6 +196,9 @@ export class RdDActor extends Actor {
|
|||||||
isPersonnage() {
|
isPersonnage() {
|
||||||
return this.type == 'personnage';
|
return this.type == 'personnage';
|
||||||
}
|
}
|
||||||
|
isVehicule() {
|
||||||
|
return this.type == 'vehicule';
|
||||||
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
isHautRevant() {
|
isHautRevant() {
|
||||||
return this.isPersonnage() && this.system.attributs.hautrevant.value != ""
|
return this.isPersonnage() && this.system.attributs.hautrevant.value != ""
|
||||||
@ -3610,33 +3598,11 @@ export class RdDActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getFortune() {
|
getFortune() {
|
||||||
let monnaies = this.itemTypes['monnaie'];
|
return this.itemTypes['monnaie']
|
||||||
if (monnaies.length < 4) {
|
.map(m => Number(m.system.valeur_deniers) * Number(m.system.quantite))
|
||||||
ui.notifications.error("Problème de monnaies manquantes, impossible de payer correctement!")
|
|
||||||
throw "Problème de monnaies manquantes, impossible de payer correctement!";
|
|
||||||
}
|
|
||||||
return monnaies.map(m => Number(m.system.valeur_deniers) * Number(m.system.quantite))
|
|
||||||
.reduce(Misc.sum(), 0);
|
.reduce(Misc.sum(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async optimizeArgent(fortuneTotale) {
|
|
||||||
let monnaies = this.itemTypes['monnaie'];
|
|
||||||
let parValeur = Misc.classifyFirst(monnaies, it => it.system.valeur_deniers);
|
|
||||||
let nouvelleFortune = {
|
|
||||||
1000: Math.floor(fortuneTotale / 1000), // or
|
|
||||||
100: Math.floor(fortuneTotale / 100) % 10, // argent
|
|
||||||
10: Math.floor(fortuneTotale / 10) % 10, // bronze
|
|
||||||
1: fortuneTotale % 10 // étain
|
|
||||||
}
|
|
||||||
console.log('RdDActor.optimizeArgent', fortuneTotale, 'nouvelleFortune', nouvelleFortune, 'monnaie_par_valeur', parValeur);
|
|
||||||
let updates = [];
|
|
||||||
for (const [valeur, nombre] of Object.entries(nouvelleFortune)) {
|
|
||||||
updates.push({ _id: parValeur[valeur].id, 'system.quantite': nombre });
|
|
||||||
}
|
|
||||||
await this.updateEmbeddedDocuments('Item', updates);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async depenserDeniers(depense, dataObj = undefined, quantite = 1, toActorId) {
|
async depenserDeniers(depense, dataObj = undefined, quantite = 1, toActorId) {
|
||||||
depense = Number(depense);
|
depense = Number(depense);
|
||||||
@ -3653,10 +3619,9 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (fortune >= depense) {
|
if (fortune >= depense) {
|
||||||
fortune -= depense;
|
|
||||||
const toActor = game.actors.get(toActorId)
|
const toActor = game.actors.get(toActorId)
|
||||||
await toActor?.ajouterDeniers(depense, this.id);
|
await toActor?.ajouterDeniers(depense, this.id);
|
||||||
await this.optimizeArgent(fortune);
|
await Monnaie.optimiser(this, fortune - depense);
|
||||||
msg = `Vous avez payé <strong>${depense} Deniers</strong>${toActor ? " à " + toActor.name : ''}, qui ont été soustraits de votre argent.`;
|
msg = `Vous avez payé <strong>${depense} Deniers</strong>${toActor ? " à " + toActor.name : ''}, qui ont été soustraits de votre argent.`;
|
||||||
RdDAudio.PlayContextAudio("argent"); // Petit son
|
RdDAudio.PlayContextAudio("argent"); // Petit son
|
||||||
|
|
||||||
@ -3679,18 +3644,19 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async depenser(depense) {
|
async depenser(depense) {
|
||||||
depense = Number(depense);
|
let reste = this.getFortune() - Number.parseInt(depense);
|
||||||
let fortune = this.getFortune();
|
|
||||||
let reste = fortune - depense;
|
|
||||||
if (reste >= 0) {
|
if (reste >= 0) {
|
||||||
fortune -= depense;
|
await Monnaie.optimiser(this, reste);
|
||||||
await this.optimizeArgent(fortune);
|
|
||||||
}
|
}
|
||||||
return reste;
|
return reste;
|
||||||
}
|
}
|
||||||
|
|
||||||
async ajouterDeniers(gain, fromActorId = undefined) {
|
async ajouterDeniers(gain, fromActorId = undefined) {
|
||||||
gain = Number.parseInt(gain);
|
gain = Number.parseInt(gain);
|
||||||
|
if (gain < 0) {
|
||||||
|
ui.notifications.error(`Impossible d'ajouter un gain de ${gain} <0`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (gain == 0) {
|
if (gain == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3703,9 +3669,7 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const fromActor = game.actors.get(fromActorId)
|
const fromActor = game.actors.get(fromActorId)
|
||||||
let fortune = this.getFortune();
|
await Monnaie.optimiser(this, gain + this.getFortune());
|
||||||
fortune += gain;
|
|
||||||
await this.optimizeArgent(fortune);
|
|
||||||
|
|
||||||
RdDAudio.PlayContextAudio("argent"); // Petit son
|
RdDAudio.PlayContextAudio("argent"); // Petit son
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
@ -3744,8 +3708,8 @@ export class RdDActor extends Actor {
|
|||||||
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
|
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
|
||||||
const messageVente = game.messages.get(achat.chatMessageIdVente);
|
const messageVente = game.messages.get(achat.chatMessageIdVente);
|
||||||
const html = await messageVente.getHTML();
|
const html = await messageVente.getHTML();
|
||||||
const buttonAcheter = html.find(".button-acheter")[0];
|
const button = html.find(".button-acheter")[0];
|
||||||
const vente = DialogItemAchat.prepareVenteData(buttonAcheter, achat.vendeurId, vendeur, acheteur);
|
const vente = DialogItemAchat.venteData(button);
|
||||||
const itemId = vente.item._id;
|
const itemId = vente.item._id;
|
||||||
const isItemEmpilable = "quantite" in vente.item.system;
|
const isItemEmpilable = "quantite" in vente.item.system;
|
||||||
|
|
||||||
@ -4146,7 +4110,7 @@ export class RdDActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async setEffect(statusId, status) {
|
async setEffect(statusId, status) {
|
||||||
if (this.isEntite() || this.type == 'vehicule') {
|
if (this.isEntite() || this.isVehicule()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("setEffect", statusId, status)
|
console.log("setEffect", statusId, status)
|
||||||
|
@ -1,34 +1,52 @@
|
|||||||
|
|
||||||
|
import { Monnaie } from "./item-monnaie.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
export class DialogItemAchat extends Dialog {
|
export class DialogItemAchat extends Dialog {
|
||||||
|
|
||||||
static async onButtonAcheter(event) {
|
static venteData(button) {
|
||||||
const buttonAcheter = event.currentTarget;
|
const vendeurId = button.attributes['data-vendeurId']?.value;
|
||||||
if (!buttonAcheter.attributes['data-jsondata']?.value) {
|
|
||||||
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const chatMessageIdVente = RdDUtility.findChatMessageId(buttonAcheter);
|
|
||||||
|
|
||||||
const vendeurId = buttonAcheter.attributes['data-vendeurId']?.value;
|
|
||||||
const vendeur = vendeurId ? game.actors.get(vendeurId) : undefined;
|
const vendeur = vendeurId ? game.actors.get(vendeurId) : undefined;
|
||||||
const acheteur = RdDUtility.getSelectedActor();
|
const acheteur = RdDUtility.getSelectedActor();
|
||||||
|
const json = button.attributes['data-jsondata']?.value;
|
||||||
if (!acheteur && !vendeur) {
|
if (!acheteur && !vendeur) {
|
||||||
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
|
ui.notifications.info("Pas d'acheteur ni de vendeur, aucun changement");
|
||||||
return;
|
return undefined;
|
||||||
|
}
|
||||||
|
if (!json) {
|
||||||
|
ui.notifications.warn("Impossible d'acheter: informations sur l'objet manquantes")
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let venteData = DialogItemAchat.prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur);
|
const prixLot = Monnaie.arrondiDeniers(button.attributes['data-prixLot']?.value ?? 0);
|
||||||
|
return {
|
||||||
|
item: json ? JSON.parse(json) : undefined,
|
||||||
|
vendeurId: vendeurId,
|
||||||
|
vendeur: vendeur,
|
||||||
|
acheteur: acheteur,
|
||||||
|
tailleLot: parseInt(button.attributes['data-tailleLot']?.value ?? 1),
|
||||||
|
quantiteIllimite: button.attributes['data-quantiteIllimite']?.value == 'true',
|
||||||
|
quantiteNbLots: parseInt(button.attributes['data-quantiteNbLots']?.value),
|
||||||
|
choix: {
|
||||||
|
nombreLots: 1,
|
||||||
|
seForcer: false,
|
||||||
|
supprimerSiZero: true
|
||||||
|
},
|
||||||
|
prixLot: prixLot,
|
||||||
|
prixTotal: prixLot,
|
||||||
|
isVente: prixLot > 0,
|
||||||
|
chatMessageIdVente: RdDUtility.findChatMessageId(button)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static async onAcheter(venteData) {
|
||||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
|
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-achat.html`, venteData);
|
||||||
const dialog = new DialogItemAchat(html, vendeur, acheteur, venteData, chatMessageIdVente);
|
const dialog = new DialogItemAchat(html, venteData);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(html, vendeur, acheteur, venteData, chatMessageIdVente) {
|
constructor(html, venteData) {
|
||||||
const isConsommable = venteData.item.type == 'nourritureboisson';
|
const isConsommable = venteData.item.type == 'nourritureboisson' && venteData.acheteur?.isPersonnage();
|
||||||
let options = { classes: ["dialogachat"], width: 400, height: isConsommable ? 450 : 350, 'z-index': 99999 };
|
let options = { classes: ["dialogachat"], width: 400, height: isConsommable ? 450 : 350, 'z-index': 99999 };
|
||||||
|
|
||||||
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
|
const actionAchat = venteData.prixLot > 0 ? "Acheter" : "Prendre";
|
||||||
@ -47,42 +65,17 @@ export class DialogItemAchat extends Dialog {
|
|||||||
|
|
||||||
super(conf, options);
|
super(conf, options);
|
||||||
|
|
||||||
this.vendeur = vendeur;
|
|
||||||
this.acheteur = acheteur;
|
|
||||||
this.chatMessageIdVente = chatMessageIdVente;
|
|
||||||
this.venteData = venteData;
|
this.venteData = venteData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static prepareVenteData(buttonAcheter, vendeurId, vendeur, acheteur) {
|
|
||||||
const jsondata = buttonAcheter.attributes['data-jsondata']?.value;
|
|
||||||
const prixLot = parseInt(buttonAcheter.attributes['data-prixLot']?.value ?? 0);
|
|
||||||
return {
|
|
||||||
item: JSON.parse(jsondata),
|
|
||||||
vendeurId: vendeurId,
|
|
||||||
vendeur: vendeur,
|
|
||||||
acheteur: acheteur,
|
|
||||||
tailleLot: parseInt(buttonAcheter.attributes['data-tailleLot']?.value ?? 1),
|
|
||||||
quantiteIllimite: buttonAcheter.attributes['data-quantiteIllimite']?.value == 'true',
|
|
||||||
quantiteNbLots: parseInt(buttonAcheter.attributes['data-quantiteNbLots']?.value),
|
|
||||||
choix: {
|
|
||||||
nombreLots: 1,
|
|
||||||
seForcer: false,
|
|
||||||
supprimerSiZero: true
|
|
||||||
},
|
|
||||||
prixLot: prixLot,
|
|
||||||
prixTotal: prixLot,
|
|
||||||
isVente: prixLot > 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async onAchat() {
|
async onAchat() {
|
||||||
await $(".nombreLots").change();
|
await $(".nombreLots").change();
|
||||||
(this.vendeur ?? this.acheteur).achatVente({
|
(this.venteData.vendeur ?? this.venteData.acheteur).achatVente({
|
||||||
userId: game.user.id,
|
userId: game.user.id,
|
||||||
vendeurId: this.vendeur?.id,
|
vendeurId: this.venteData.vendeur?.id,
|
||||||
acheteurId: this.acheteur?.id,
|
acheteurId: this.venteData.acheteur?.id,
|
||||||
prixTotal: this.venteData.prixTotal,
|
prixTotal: this.venteData.prixTotal,
|
||||||
chatMessageIdVente: this.chatMessageIdVente,
|
chatMessageIdVente: this.venteData.chatMessageIdVente,
|
||||||
choix: this.venteData.choix
|
choix: this.venteData.choix
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { Misc } from "./misc.js";
|
|||||||
|
|
||||||
export class DialogItemVente extends Dialog {
|
export class DialogItemVente extends Dialog {
|
||||||
|
|
||||||
static async create(item, callback) {
|
static async display(item, callback) {
|
||||||
const quantite = item.isConteneur() ? 1 : item.system.quantite;
|
const quantite = item.isConteneur() ? 1 : item.system.quantite;
|
||||||
const venteData = {
|
const venteData = {
|
||||||
item: item,
|
item: item,
|
||||||
@ -20,7 +20,7 @@ export class DialogItemVente extends Dialog {
|
|||||||
isOwned: item.isOwned,
|
isOwned: item.isOwned,
|
||||||
};
|
};
|
||||||
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
|
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-item-vente.html`, venteData);
|
||||||
return new DialogItemVente(venteData, html, callback);
|
return new DialogItemVente(venteData, html, callback).render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(venteData, html, callback) {
|
constructor(venteData, html, callback) {
|
||||||
|
@ -1,44 +1,32 @@
|
|||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
|
import { LOG_HEAD } from "./constants.js";
|
||||||
|
|
||||||
const MONNAIES_STANDARD = [
|
const MONNAIE_ETAIN = {
|
||||||
{
|
name: "Etain (1 denier)", type: 'monnaie',
|
||||||
name: "Etain (1 denier)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp",
|
system: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 1, encombrement: 0.001, description: "" }
|
};
|
||||||
},
|
const MONNAIE_BRONZE = {
|
||||||
{
|
name: "Bronze (10 deniers)", type: 'monnaie',
|
||||||
name: "Bronze (10 deniers)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp",
|
system: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 10, encombrement: 0.002, description: "" }
|
};
|
||||||
},
|
const MONNAIE_ARGENT = {
|
||||||
{
|
name: "Argent (1 sol)", type: 'monnaie',
|
||||||
name: "Argent (1 sol)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp",
|
system: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 100, encombrement: 0.003, description: "" }
|
};
|
||||||
},
|
const MONNAIE_OR = {
|
||||||
{
|
name: "Or (10 sols)", type: 'monnaie',
|
||||||
name: "Or (10 sols)", type: 'monnaie',
|
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
|
||||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp",
|
system: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
|
||||||
system: { quantite: 0, valeur_deniers: 1000, encombrement: 0.004, description: "" }
|
};
|
||||||
}
|
|
||||||
]
|
const MONNAIES_STANDARD = [MONNAIE_ETAIN, MONNAIE_BRONZE, MONNAIE_ARGENT, MONNAIE_OR];
|
||||||
const VALEURS_STANDARDS = MONNAIES_STANDARD.map(it =>it.system.valeur_deniers);
|
|
||||||
|
|
||||||
export class Monnaie {
|
export class Monnaie {
|
||||||
|
|
||||||
static isSystemMonnaie(item, items) {
|
static monnaiesStandard() {
|
||||||
if (item.type == 'monnaie') {
|
|
||||||
const valeur = item.system.valeur_deniers;
|
|
||||||
if (VALEURS_STANDARDS.includes(valeur)) {
|
|
||||||
const monnaiesDeValeur = items.filter(it => it.type == 'monnaie' && it.system.valeur_deniers == valeur)
|
|
||||||
return monnaiesDeValeur.length<=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static monnaiesData() {
|
|
||||||
return MONNAIES_STANDARD;
|
return MONNAIES_STANDARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +44,47 @@ export class Monnaie {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static arrondiDeniers(sols) {
|
static arrondiDeniers(sols) {
|
||||||
return sols.toFixed(2);
|
return Number(sols).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static triValeurDenier() {
|
static triValeurDenier() {
|
||||||
return Misc.ascending(item => item.system.valeur_deniers)
|
return Misc.ascending(item => item.system.valeur_deniers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async creerMonnaiesStandard(actor) {
|
||||||
|
await actor.createEmbeddedDocuments('Item', MONNAIES_STANDARD, { renderSheet: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
static async creerMonnaiesDeniers(actor, fortune) {
|
||||||
|
await actor.createEmbeddedDocuments('Item', [Monnaie.creerDeniers(fortune)], { renderSheet: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
static creerDeniers(fortune) {
|
||||||
|
const deniers = duplicate(MONNAIE_ETAIN);
|
||||||
|
deniers.system.quantite = fortune;
|
||||||
|
return deniers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async optimiser(actor, fortune) {
|
||||||
|
let reste = fortune;
|
||||||
|
let monnaies = actor.itemTypes['monnaie'];
|
||||||
|
let updates = [];
|
||||||
|
let parValeur = Misc.classifyFirst(monnaies, it => it.system.valeur_deniers);
|
||||||
|
for (let valeur of [1000, 100, 10, 1]) {
|
||||||
|
if (parValeur[valeur]) {
|
||||||
|
const piecesDeCetteValeur = Math.floor(reste / valeur);
|
||||||
|
updates.push({ _id: parValeur[valeur].id, 'system.quantite': piecesDeCetteValeur });
|
||||||
|
reste -= piecesDeCetteValeur*valeur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('Monnaie.optimiser', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', reste);
|
||||||
|
if (updates.length > 0) {
|
||||||
|
await actor.updateEmbeddedDocuments('Item', updates);
|
||||||
|
}
|
||||||
|
if (reste>0){
|
||||||
|
// créer le reste en deniers fortune en deniers
|
||||||
|
await Monnaie.creerMonnaiesDeniers(actor, reste);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -268,26 +268,23 @@ export class RdDItem extends Item {
|
|||||||
async proposerVente() {
|
async proposerVente() {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
if (this.isConteneurNonVide()) {
|
if (this.isConteneurNonVide()) {
|
||||||
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le donner ou le vendre`);
|
ui.notifications.warn(`Votre ${this.name} n'est pas vide, pas possible de le proposer`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dialog = await DialogItemVente.create(this, (vente) => this._onProposerVente(vente))
|
await DialogItemVente.display(this, async (vente) => {
|
||||||
dialog.render(true);
|
vente["properties"] = this.getProprietes();
|
||||||
}
|
if (vente.isOwned) {
|
||||||
|
if (vente.quantiteNbLots * vente.tailleLot > vente.quantiteMax) {
|
||||||
async _onProposerVente(venteData) {
|
ui.notifications.warn(`Vous avez ${vente.quantiteMax} ${vente.item.name}, ce n'est pas suffisant pour vendre ${vente.quantiteNbLots} de ${vente.tailleLot}`)
|
||||||
venteData["properties"] = this.getProprietes();
|
return;
|
||||||
if (venteData.isOwned) {
|
}
|
||||||
if (venteData.quantiteNbLots * venteData.tailleLot > venteData.quantiteMax) {
|
|
||||||
ui.notifications.warn(`Vous avez ${venteData.quantiteMax} ${venteData.item.name}, ce n'est pas suffisant pour vendre ${venteData.quantiteNbLots} de ${venteData.tailleLot}`)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
vente.jsondata = JSON.stringify(vente.item);
|
||||||
venteData.jsondata = JSON.stringify(venteData.item);
|
|
||||||
|
console.log(vente);
|
||||||
console.log(venteData);
|
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', vente);
|
||||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-vente-item.html', venteData);
|
ChatMessage.create(RdDUtility.chatDataSetup(html));
|
||||||
ChatMessage.create(RdDUtility.chatDataSetup(html));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -105,17 +105,6 @@ export class Misc {
|
|||||||
return params.reduce((a, b) => a + separator + b);
|
return params.reduce((a, b) => a + separator + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static getEntityTypeLabel(entity) {
|
|
||||||
const documentName = entity?.documentName
|
|
||||||
const type = entity?.type
|
|
||||||
if (documentName === 'Actor' || documentName === 'Item') {
|
|
||||||
const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
|
|
||||||
return game.i18n.has(label) ? game.i18n.localize(label) : t;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static connectedGMOrUser(ownerId = undefined) {
|
static connectedGMOrUser(ownerId = undefined) {
|
||||||
if (ownerId && game.user.id == ownerId) {
|
if (ownerId && game.user.id == ownerId) {
|
||||||
return ownerId;
|
return ownerId;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDItemArme } from "./item-arme.js";
|
import { RdDItemArme } from "./item-arme.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
@ -688,27 +688,75 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
verifierDistance( rollData ) {
|
async proposerAjustementTirLancer( rollData ) {
|
||||||
if ( rollData.competence.system.categorie == "tir" ||
|
if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) {
|
||||||
rollData.competence.system.categorie == "lancer" ) {
|
if (this.defender.isEntite([ENTITE_BLURETTE])){
|
||||||
const defenderToken = canvas.tokens.get(this.defenderTokenId)
|
ChatMessage.create( {
|
||||||
let dist = canvas.grid.measureDistances([{ ray: new Ray(_token.center, defenderToken.center) }], { gridSpaces: false })
|
content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
|
||||||
dist = Number(dist).toPrecision(5)
|
whisper: ChatMessage.getWhisperRecipients("GM")})
|
||||||
//let ray = new Ray( {x: _token.x, y: _token.y}, {x: defenderToken.x, y:defenderToken.y} )
|
}
|
||||||
let msgPortee = "portée est courte (0)"
|
else {
|
||||||
if (dist > rollData.arme.system.portee_courte && dist <= rollData.arme.system.portee_moyenne) {
|
const defenderToken = canvas.tokens.get(this.defenderTokenId);
|
||||||
msgPortee = "portée est moyenne (-3)"
|
const dist = this.distance(_token, defenderToken)
|
||||||
} else if (dist > rollData.arme.system.portee_moyenne && dist <= rollData.arme.system.portee_extreme) {
|
const portee = this._ajustementPortee(dist, rollData.arme)
|
||||||
msgPortee = "portée est extrême (-5)"
|
const taille = this._ajustementTaille(this.defender)
|
||||||
} else if ( dist > rollData.arme.system.portee_extreme) {
|
const activite = this._ajustementMouvement(this.defender)
|
||||||
msgPortee = "cible est inateignable"
|
const total = [portee, taille, activite].map(it=>it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0)
|
||||||
|
ChatMessage.create({
|
||||||
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html', {
|
||||||
|
rollData: rollData,
|
||||||
|
attacker: _token,
|
||||||
|
defender: defenderToken,
|
||||||
|
distance: dist,
|
||||||
|
portee: portee,
|
||||||
|
taille: taille,
|
||||||
|
activite: activite,
|
||||||
|
total: total
|
||||||
|
}),
|
||||||
|
whisper: ChatMessage.getWhisperRecipients("GM")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ChatMessage.create( { content: `<strong>Indication MJ</strong> : La cible est à une distance indicative de : ${dist} mètres. Pour l'arme ${rollData.arme.name}, la ${msgPortee}.`, whisper: ChatMessage.getWhisperRecipients("GM") } )
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
distance(t, defenderToken) {
|
||||||
|
return Number(canvas.grid.measureDistances([{ ray: new Ray(t.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ajustementPortee(dist, arme) {
|
||||||
|
if (dist <= arme.system.portee_courte) return {msg:"courte", diff:0};
|
||||||
|
if (dist <= arme.system.portee_moyenne) return {msg: "moyenne" , diff: -3};
|
||||||
|
if (dist <= arme.system.portee_extreme) return {msg: "extrême", diff:-5};
|
||||||
|
return {msg: "inatteignable", diff: -10};
|
||||||
|
}
|
||||||
|
|
||||||
|
_ajustementTaille(actor) {
|
||||||
|
if (actor.isVehicule()) return {msg: "véhicule", diff: 0}
|
||||||
|
const taille = actor.getCaracByName('TAILLE')?.value ?? 1;
|
||||||
|
if (taille <= 1) return {msg: "souris", diff: -8};
|
||||||
|
if (taille <= 3) return {msg: "chat", diff: -4};
|
||||||
|
if (taille <= 5) return {msg: "chien", diff: -2};
|
||||||
|
if (taille <= 15) return {msg: "humanoïde", diff: 0};
|
||||||
|
if (taille <= 20) return {msg: "ogre", diff: 2};
|
||||||
|
return {msg: "gigantesque", diff: 4};
|
||||||
|
}
|
||||||
|
_ajustementMouvement(defender) {
|
||||||
|
if (defender.getSurprise(true)) return {msg: "immobile (surprise)", diff: 0};
|
||||||
|
if (game.combat?.combatants.find(it => it.actorId == defender.id)) return {msg: "en mouvement (combat)", diff: -4};
|
||||||
|
return {msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3};
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async attaque(competence, arme) {
|
async attaque(competence, arme) {
|
||||||
|
// const nonIncarnee = this.defender.isEntite([ENTITE_NONINCARNE])
|
||||||
|
// const blurette = this.defender.isEntite([ENTITE_BLURETTE])
|
||||||
|
// if (nonIncarnee || blurette) {
|
||||||
|
// ChatMessage.create( {
|
||||||
|
// content: `<strong>La cible est ${nonIncarnee ? 'non incarnée' : 'une blurette'}.
|
||||||
|
// Il est impossible de l'atteindre.`,
|
||||||
|
// whisper: ChatMessage.getWhisperRecipients("GM")})
|
||||||
|
// }
|
||||||
|
|
||||||
if (!await this.accorderEntite('avant-attaque')) {
|
if (!await this.accorderEntite('avant-attaque')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -729,7 +777,7 @@ export class RdDCombat {
|
|||||||
if (arme) {
|
if (arme) {
|
||||||
this.attacker.verifierForceMin(arme);
|
this.attacker.verifierForceMin(arme);
|
||||||
}
|
}
|
||||||
this.verifierDistance(rollData)
|
await this.proposerAjustementTirLancer(rollData)
|
||||||
|
|
||||||
const dialog = await RdDRoll.create(this.attacker, rollData,
|
const dialog = await RdDRoll.create(this.attacker, rollData,
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { SYSTEM_RDD } from "./constants.js";
|
import { SYSTEM_RDD } from "./constants.js";
|
||||||
import { Misc } from "./misc.js";
|
|
||||||
|
|
||||||
export class RddCompendiumOrganiser {
|
export class RddCompendiumOrganiser {
|
||||||
static init() {
|
static init() {
|
||||||
@ -17,7 +16,7 @@ export class RddCompendiumOrganiser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async setEntityTypeName(pack, element) {
|
static async setEntityTypeName(pack, element) {
|
||||||
const label = Misc.getEntityTypeLabel(await pack.getDocument(element.dataset.documentId));
|
const label = RddCompendiumOrganiser.getEntityTypeLabel(await pack.getDocument(element.dataset.documentId));
|
||||||
RddCompendiumOrganiser.insertEntityType(element, label);
|
RddCompendiumOrganiser.insertEntityType(element, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,4 +26,16 @@ export class RddCompendiumOrganiser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static getEntityTypeLabel(entity) {
|
||||||
|
const documentName = entity?.documentName
|
||||||
|
const type = entity?.type
|
||||||
|
if (documentName === 'Actor' || documentName === 'Item') {
|
||||||
|
const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
|
||||||
|
return game.i18n.has(label) ? game.i18n.localize(label) : t;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -150,11 +150,14 @@ Hooks.once("init", async function () {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
game.socket.on(SYSTEM_SOCKET_ID, sockmsg => {
|
game.socket.on(SYSTEM_SOCKET_ID, sockmsg => {
|
||||||
console.log(">>>>> MSG RECV", sockmsg);
|
console.log(">>>>> MSG RECV", sockmsg);
|
||||||
|
try {
|
||||||
RdDUtility.onSocketMessage(sockmsg);
|
RdDUtility.onSocketMessage(sockmsg);
|
||||||
RdDCombat.onSocketMessage(sockmsg);
|
RdDCombat.onSocketMessage(sockmsg);
|
||||||
ChatUtility.onSocketMessage(sockmsg);
|
ChatUtility.onSocketMessage(sockmsg);
|
||||||
RdDActor.onSocketMessage(sockmsg);
|
RdDActor.onSocketMessage(sockmsg);
|
||||||
|
} catch(e) {
|
||||||
|
console.error('game.socket.on(SYSTEM_SOCKET_ID) Exception: ', sockmsg,' => ', e)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -112,7 +112,6 @@ export class RdDUtility {
|
|||||||
static async preloadHandlebarsTemplates() {
|
static async preloadHandlebarsTemplates() {
|
||||||
const templatePaths = [
|
const templatePaths = [
|
||||||
//Character Sheets
|
//Character Sheets
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-creation-sheet.html',
|
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/actor-entite-sheet.html',
|
||||||
@ -242,6 +241,7 @@ export class RdDUtility {
|
|||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-description.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.html',
|
||||||
|
'systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html',
|
||||||
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html',
|
'systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html',
|
||||||
@ -750,7 +750,12 @@ export class RdDUtility {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// gestion bouton tchat Acheter
|
// gestion bouton tchat Acheter
|
||||||
html.on("click", '.button-acheter', event => DialogItemAchat.onButtonAcheter(event));
|
html.on("click", '.button-acheter', event => {
|
||||||
|
const venteData = DialogItemAchat.venteData(event.currentTarget);
|
||||||
|
if (venteData) {
|
||||||
|
DialogItemAchat.onAcheter(venteData);
|
||||||
|
}
|
||||||
|
});
|
||||||
html.on("click", '.button-creer-acteur', event => RdDNameGen.onCreerActeur(event));
|
html.on("click", '.button-creer-acteur', event => RdDNameGen.onCreerActeur(event));
|
||||||
|
|
||||||
// Gestion du bouton payer
|
// Gestion du bouton payer
|
||||||
@ -888,11 +893,6 @@ export class RdDUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async confirmerSuppressionItem(sheet, item, htmlToDelete) {
|
static async confirmerSuppressionItem(sheet, item, htmlToDelete) {
|
||||||
const itemId = item.id;
|
const itemId = item.id;
|
||||||
if (Monnaie.isSystemMonnaie(item, sheet.actor.items)) {
|
|
||||||
ui.notifications.warn("Suppression des monnaies de base impossible");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const confirmationSuppression = {
|
const confirmationSuppression = {
|
||||||
settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(),
|
settingConfirmer: "confirmation-supprimer-" + item.getItemGroup(),
|
||||||
content: `<p>Etes vous certain de vouloir supprimer: ${item.name}?</p>`,
|
content: `<p>Etes vous certain de vouloir supprimer: ${item.name}?</p>`,
|
||||||
|
9
templates/chat-info-distance.html
Normal file
9
templates/chat-info-distance.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<img class="chat-icon" src="{{rollData.arme.img}}" alt="{{rollData.arme.name}}" />
|
||||||
|
<strong>Ajustement de tir/lancer</strong> proposé de <strong>{{total}}</strong>
|
||||||
|
<ul>
|
||||||
|
<li>{{defender.name}} est à une distance indicative de {{distance}} mètres.</li>
|
||||||
|
{{log defender}}
|
||||||
|
<li>Portée {{portee.msg}} pour l'arme {{rollData.arme.name}} : {{portee.diff}}</li>
|
||||||
|
<li>De taille {{taille.msg}}: {{taille.diff}}</li>
|
||||||
|
<li>Mouvement {{activite.msg}}: {{activite.diff}}</li>
|
||||||
|
</ul>
|
@ -45,38 +45,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if (eq item.type 'nourritureboisson')}}
|
{{#if (and (eq item.type 'nourritureboisson') (eq acheteur.type 'personnage'))}}
|
||||||
<p>
|
<p>Si vous souhaitez {{#if item.system.boisson}}boire{{else}}manger{{/if}}:</p>
|
||||||
Si vous souhaitez {{#if item.system.boisson}}boire{{else}}manger{{/if}}:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{{#if item.system.sust}}
|
{{#if item.system.sust}}
|
||||||
<p>Cette {{#if item.system.boisson}}boisson{{else}}nourriture{{/if}} vous apportera <span
|
<p>Cette {{#if item.system.boisson}}boisson{{else}}nourriture{{/if}} vous apportera
|
||||||
class="total-sust">{{totalSust}}</span> de sustantation.</p>
|
<span class="total-sust">{{totalSust}}</span>
|
||||||
{{/if}}
|
de sustantation.</p>
|
||||||
{{#if item.system.boisson}}
|
{{/if}}
|
||||||
<p>{{#if item.system.alcoolise}}
|
{{#if item.system.boisson}}
|
||||||
C'est une boisson alcoolisée de force {{item.system.force}}, vous effectuerez un jet d'éthylisme.
|
<p>
|
||||||
{{/if}}
|
{{#if item.system.alcoolise}}
|
||||||
Cette boisson vous apportera <span class="total-desaltere">{{totalDesaltere}}</span> unités d'eau.
|
C'est une boisson alcoolisée de force {{item.system.force}}, vous effectuerez un jet d'éthylisme.
|
||||||
</p>
|
{{/if}}
|
||||||
{{/if}}
|
Cette boisson vous apportera <span class="total-desaltere">{{totalDesaltere}}</span> unités d'eau.
|
||||||
{{#if (gt item.system.qualite 0)}}
|
</p>
|
||||||
{{#if (gt item.system.qualite cuisine.system.niveau)}}
|
{{/if}}
|
||||||
<p>La qualité du plat est telle qu'un jet de Goût/Cuisine à {{numberFormat item.system.qualite decimals=0 sign=true}}
|
{{#if (gt item.system.qualite 0)}}
|
||||||
vous permettra un jet de moral heureux.</p>
|
{{#if (gt item.system.qualite cuisine.system.niveau)}}
|
||||||
{{/if}}
|
<p>La qualité du plat est telle qu'un jet de Goût/Cuisine à {{numberFormat item.system.qualite decimals=0 sign=true}}
|
||||||
{{/if}}
|
vous permettra un jet de moral heureux.</p>
|
||||||
|
{{/if}}
|
||||||
{{#if (or (lt item.system.qualite 0) (lt item.system.exotisme 0))}}
|
{{/if}}
|
||||||
<p>
|
|
||||||
Pour surmonter {{#if (lt item.system.qualite 0)}}le mauvais goût{{else}}l'exotisme{{/if}}, vous devez effectuer un jet de Volonté/Cuisine à {{numberFormat (min item.system.exotisme item.system.qualite) decimals=0 sign=true}}.
|
{{#if (or (lt item.system.qualite 0) (lt item.system.exotisme 0))}}
|
||||||
<br/>
|
<p>
|
||||||
<input class="attribute-value se-forcer" type="checkbox" name="se-forcer" {{#if choix.seForcer}}checked{{/if}}>
|
Pour surmonter {{#if (lt item.system.qualite 0)}}le mauvais goût{{else}}l'exotisme{{/if}}, vous devez effectuer un jet de Volonté/Cuisine à {{numberFormat (min item.system.exotisme item.system.qualite) decimals=0 sign=true}}.
|
||||||
<label for="se-forcer">En cas d'échec, voulez-vous vous forcer à manger (et subir un jet de moral en situation malheureuse)?</label>
|
<br/>
|
||||||
</input>
|
<input class="attribute-value se-forcer" type="checkbox" name="se-forcer" {{#if choix.seForcer}}checked{{/if}}>
|
||||||
</p>
|
<label for="se-forcer">En cas d'échec, voulez-vous vous forcer à manger (et subir un jet de moral en situation malheureuse)?</label>
|
||||||
{{/if}}
|
</input>
|
||||||
|
</p>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isVente}}
|
{{#if isVente}}
|
||||||
|
Loading…
Reference in New Issue
Block a user