Gestion des monnaies de valeur 0

Ajout d'un message d'erreur quand on met la valeur d'une monnaie à 0.
Ajout d'une notification quand on détecte des monnaies de valeur 0

Pour les pièces en bois, les créer comme objets, si on ne veut pas de
messages d'avertissement.
This commit is contained in:
Vincent Vandemeulebrouck 2022-12-12 22:51:38 +01:00
parent 57d52c1966
commit bbde3b73fe
4 changed files with 100 additions and 64 deletions

View File

@ -3642,20 +3642,13 @@ export class RdDActor extends Actor {
return; return;
} }
/* -------------------------------------------- */
getFortune() {
return this.itemTypes['monnaie']
.map(m => Number(m.system.cout) * Number(m.system.quantite))
.reduce(Misc.sum(), 0);
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async payerSols(depense) { async payerSols(depense) {
depense = Number(depense); depense = Number(depense);
if (depense == 0) { if (depense == 0) {
return; return;
} }
let fortune = this.getFortune(); let fortune = Monnaie.getFortune(this);
console.log("payer", game.user.character, depense, fortune); console.log("payer", game.user.character, depense, fortune);
let msg = ""; let msg = "";
if (fortune >= depense) { if (fortune >= depense) {
@ -3674,7 +3667,7 @@ export class RdDActor extends Actor {
} }
async depenserSols(sols) { async depenserSols(sols) {
let reste = this.getFortune() - Number(sols); let reste = Monnaie.getFortune(this) - Number(sols);
if (reste >= 0) { if (reste >= 0) {
await Monnaie.optimiserFortune(this, reste); await Monnaie.optimiserFortune(this, reste);
} }
@ -3699,7 +3692,7 @@ export class RdDActor extends Actor {
} }
else { else {
const fromActor = game.actors.get(fromActorId) const fromActor = game.actors.get(fromActorId)
await Monnaie.optimiserFortune(this, sols + this.getFortune()); await Monnaie.optimiserFortune(this, sols + Monnaie.getFortune(this));
RdDAudio.PlayContextAudio("argent"); // Petit son RdDAudio.PlayContextAudio("argent"); // Petit son
ChatMessage.create({ ChatMessage.create({
@ -3732,50 +3725,31 @@ export class RdDActor extends Actor {
}); });
return; return;
} }
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
const vente = achat.vente;
const itemId = vente.item._id;
const isItemEmpilable = "quantite" in vente.item.system;
const cout = Number(achat.prixTotal ?? 0); const cout = Number(achat.prixTotal ?? 0);
const vente = achat.vente;
const acheteur = achat.acheteurId ? game.actors.get(achat.acheteurId) : undefined;
const vendeur = achat.vendeurId ? game.actors.get(achat.vendeurId) : undefined;
let itemVendu = vendeur?.getObjet(vente.item._id);
if (vendeur && (itemVendu?.getQuantite() ?? 0) < achat.quantiteTotal) {
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a plus assez de ${vente.item.name} !`);
return;
}
if (Monnaie.getFortune(acheteur) < Number(cout)) {
ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`);
return;
}
achat.quantiteTotal = (achat.choix.nombreLots ?? 1) * (vente.tailleLot); achat.quantiteTotal = (achat.choix.nombreLots ?? 1) * (vente.tailleLot);
if (acheteur) { if (vendeur) {
let resteAcheteur = await acheteur.depenserSols(cout); await vendeur.ajouterSols(cout);
if (resteAcheteur < 0) { await vendeur.decrementerQuantiteItem(itemVendu, achat.quantiteTotal,);
ChatUtility.notifyUser(achat.userId, 'warn', `Vous n'avez pas assez d'argent pour payer ${Math.ceil(cout / 100)} sols !`);
return;
}
}
const itemVendu = vendeur?.getObjet(itemId);
if (itemVendu) {
if (isItemEmpilable ? (itemVendu.system.quantite < achat.quantiteTotal) : (achat.choix.nombreLots != 1)) {
await acheteur?.ajouterSols(cout);
ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a plus assez de ${vente.item.name} !`);
return;
}
vendeur.ajouterSols(cout);
let resteQuantite = (itemVendu.system.quantite ?? 1) - achat.quantiteTotal;
if (resteQuantite == 0) {
vendeur.deleteEmbeddedDocuments("Item", [itemId])
}
else {
vendeur.updateEmbeddedDocuments("Item", [{ _id: itemId, 'system.quantite': resteQuantite }]);
}
} }
if (acheteur) { if (acheteur) {
const achatData = { await acheteur.depenserSols(cout);
type: vente.item.type, let createdItemId = await acheteur.creerQuantiteItem(vente.item, achat.quantiteTotal);
img: vente.item.img, await acheteur.consommerNourritureAchetee(achat, vente, createdItemId);
name: vente.item.name,
system: mergeObject(vente.item.system, { quantite: isItemEmpilable ? achat.quantiteTotal : undefined }),
}
let listeAchat = isItemEmpilable ? [achatData] : Array.from({ length: achat.quantiteTotal }, (_, i) => achatData)
let items = await acheteur.createEmbeddedDocuments("Item", listeAchat);
if (achat.choix.consommer && vente.item.type == 'nourritureboisson') {
achat.choix.doses = achat.choix.nombreLots;
await acheteur.consommerNourritureboisson(items[0].id, achat.choix, vente.actingUserId);
}
} }
if (cout > 0) { if (cout > 0) {
RdDAudio.PlayContextAudio("argent"); RdDAudio.PlayContextAudio("argent");
@ -3804,6 +3778,42 @@ export class RdDActor extends Actor {
} }
} }
async consommerNourritureAchetee(achat, vente, createdItemId) {
if (achat.choix.consommer && vente.item.type == 'nourritureboisson' && createdItemId != undefined) {
achat.choix.doses = achat.choix.nombreLots;
await this.consommerNourritureboisson(createdItemId, achat.choix, vente.actingUserId);
}
}
async decrementerQuantiteItem(item, quantite) {
let resteQuantite = (item.system.quantite ?? 1) - quantite;
if (resteQuantite <= 0) {
await this.deleteEmbeddedDocuments("Item", [item.id]);
if (resteQuantite < 0) {
ui.notifications.warn(`La quantité de ${item.name} était insuffisante, l'objet a donc été supprimé`)
}
}
else if (resteQuantite > 0) {
await this.updateEmbeddedDocuments("Item", [{ _id: item.id, 'system.quantite': resteQuantite }]);
}
}
async creerQuantiteItem(item, quantite) {
const items = await this.createEmbeddedDocuments("Item", RdDActor.$prepareListeAchat(item, quantite));
return items.length > 0 ? items[0].id : undefined;
}
static $prepareListeAchat(item, quantite) {
const isItemEmpilable = "quantite" in item.system;
const achatData = {
type: item.type,
img: item.img,
name: item.name,
system: mergeObject(item.system, { quantite: isItemEmpilable ? quantite : undefined }),
};
return isItemEmpilable ? [achatData] : Array.from({ length: quantite }, (_, i) => achatData);
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async effectuerTacheAlchimie(recetteId, tacheAlchimie, texteTache) { async effectuerTacheAlchimie(recetteId, tacheAlchimie, texteTache) {
let recetteData = this.getItemOfType(recetteId, 'recettealchimique'); let recetteData = this.getItemOfType(recetteId, 'recettealchimique');

View File

@ -23,6 +23,7 @@ const MONNAIE_OR = {
}; };
const MONNAIES_STANDARD = [MONNAIE_ETAIN, MONNAIE_BRONZE, MONNAIE_ARGENT, MONNAIE_OR]; const MONNAIES_STANDARD = [MONNAIE_ETAIN, MONNAIE_BRONZE, MONNAIE_ARGENT, MONNAIE_OR];
const VALEUR_DENIERS = sols => Math.max(Math.floor((sols ?? 0) * 100), 0);
export class Monnaie { export class Monnaie {
@ -40,15 +41,11 @@ export class Monnaie {
} }
static deValeur(monnaie, valeur) { static deValeur(monnaie, valeur) {
return Monnaie.valEntiere(valeur) == Monnaie.valEntiere(monnaie.system.cout) return VALEUR_DENIERS(valeur) == VALEUR_DENIERS(monnaie.system.cout)
}
static valEntiere(sols) {
return Math.max(Math.floor((sols??0)*100), 0);
} }
static triValeurEntiere() { static triValeurEntiere() {
return Misc.ascending(item => Monnaie.valEntiere(item.system.cout)) return Misc.ascending(item => VALEUR_DENIERS(item.system.cout))
} }
static async creerMonnaiesStandard(actor) { static async creerMonnaiesStandard(actor) {
@ -65,29 +62,49 @@ export class Monnaie {
return deniers; return deniers;
} }
static getFortune(actor) {
if (actor) {
Monnaie.validerMonnaies(actor);
return actor.itemTypes['monnaie']
.map(m => Number(m.system.cout) * Number(m.system.quantite))
.reduce(Misc.sum(), 0);
}
return 0;
}
static async optimiserFortune(actor, fortune) { static async optimiserFortune(actor, fortune) {
let resteEnDeniers = Math.round(fortune*100); let resteEnDeniers = Math.round(fortune * 100);
let monnaies = actor.itemTypes['monnaie']; let monnaies = actor.itemTypes['monnaie'];
let updates = []; let updates = [];
let parValeur = Misc.classifyFirst(monnaies, it => Monnaie.valEntiere(it.system.cout)); Monnaie.validerMonnaies(actor);
for (let valeurDeniers of [1000, 100, 10, 1]) {
let parValeur = Misc.classifyFirst(monnaies, it => VALEUR_DENIERS(it.system.cout));
for (let valeurDeniers of [1000, 100, 10, 1]) {
const itemPiece = parValeur[valeurDeniers]; const itemPiece = parValeur[valeurDeniers];
if (itemPiece) { if (itemPiece) {
const quantite = Math.floor(resteEnDeniers / valeurDeniers); const quantite = Math.floor(resteEnDeniers / valeurDeniers);
if (quantite != itemPiece.system.quantite) { if (quantite != itemPiece.system.quantite) {
updates.push({ _id: parValeur[valeurDeniers].id, 'system.quantite': quantite }); updates.push({ _id: parValeur[valeurDeniers].id, 'system.quantite': quantite });
} }
resteEnDeniers -= quantite*valeurDeniers; resteEnDeniers -= quantite * valeurDeniers;
} }
} }
console.log('Monnaie.optimiserFortune', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', resteEnDeniers); console.log('Monnaie.optimiserFortune', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', resteEnDeniers);
if (updates.length > 0) { if (updates.length > 0) {
await actor.updateEmbeddedDocuments('Item', updates); await actor.updateEmbeddedDocuments('Item', updates);
} }
if (resteEnDeniers > 0){ if (resteEnDeniers > 0) {
// créer le reste en deniers fortune en deniers // créer le reste en deniers fortune en deniers
await Monnaie.creerMonnaiesDeniers(actor, resteEnDeniers); await Monnaie.creerMonnaiesDeniers(actor, resteEnDeniers);
} }
} }
static validerMonnaies(actor) {
actor.itemTypes['monnaie'].filter(it => VALEUR_DENIERS(it.system.cout) == 0)
.map(it => `La monnaie ${it.name} de l'acteur ${actor.name} a une valeur de 0!`)
.forEach(message => {
ui.notifications.warn(message);
console.warn(message);
});
}
} }

View File

@ -159,8 +159,6 @@ export class RdDItemSheet extends ItemSheet {
super.activateListeners(html); super.activateListeners(html);
this.html = html; this.html = html;
let itemSheetDialog = this;
HtmlUtility._showControlWhen(this.html.find(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.item.isOwned); HtmlUtility._showControlWhen(this.html.find(".item-cout"), ReglesOptionelles.isUsing('afficher-prix-joueurs') || game.user.isGM || !this.item.isOwned);
HtmlUtility._showControlWhen(this.html.find(".item-magique"), this.item.isMagique()); HtmlUtility._showControlWhen(this.html.find(".item-magique"), this.item.isMagique());
@ -178,6 +176,14 @@ export class RdDItemSheet extends ItemSheet {
RdDUtility.checkThanatosXP(this.item.name); RdDUtility.checkThanatosXP(this.item.name);
} }
}); });
this.html.find(".item-cout input[name='system.cout']").change(event => {
if (this.item.isMonnaie()) {
const value = event.currentTarget.value;
if (Number(value) == 0) {
ui.notifications.error(`${this.actor?.name ?? 'Monnaie'}: La monnaie ${this.item.name} a maintenant une valeur de 0, et ne peut plus être utilisée pour payer!`)
}
}
})
this.html.find('.enchanteDate').change((event) => { this.html.find('.enchanteDate').change((event) => {
let jour = Number(this.html.find('[name="splitDate.day"]').val()); let jour = Number(this.html.find('[name="splitDate.day"]').val());
@ -201,12 +207,12 @@ export class RdDItemSheet extends ItemSheet {
} }
}); });
this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => itemSheetDialog.render(true))); this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, async () => this.render(true)));
this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true)); this.html.find('.item-edit').click(async event => RdDSheetUtility.getItem(event, this.actor)?.sheet.render(true));
this.html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor))); this.html.find('.item-delete').click(async event => RdDUtility.confirmerSuppressionItem(this, RdDSheetUtility.getItem(event, this.actor)));
this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente()); this.html.find('.item-vendre').click(async event => RdDSheetUtility.getItem(event, this.actor)?.proposerVente());
this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem()); this.html.find('.item-montrer').click(async event => RdDSheetUtility.getItem(event, this.actor)?.postItem());
this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => itemSheetDialog.render(true))); this.html.find('.item-action').click(async event => RdDSheetUtility.getItem(event, this.actor)?.actionPrincipale(this.actor, async () => this.render(true)));
} }
_getEventActor(event) { _getEventActor(event) {

View File

@ -149,6 +149,9 @@ export class RdDItem extends Item {
isConteneur() { isConteneur() {
return this.type == 'conteneur'; return this.type == 'conteneur';
} }
isMonnaie() {
return this.type == 'monnaie';
}
getItemGroup() { getItemGroup() {
if (this.isInventaire()) return "equipement"; if (this.isInventaire()) return "equipement";