import { Misc } from "./misc.js"; import { LOG_HEAD } from "./constants.js"; const MONNAIE_ETAIN = { name: "Denier (étain)", type: 'monnaie', img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_etain_poisson.webp", system: { quantite: 0, cout: 0.01, encombrement: 0.001, description: "" } }; const MONNAIE_BRONZE = { name: "Sou (bronze)", type: 'monnaie', img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_bronze_epees.webp", system: { quantite: 0, cout: 0.10, encombrement: 0.002, description: "" } }; const MONNAIE_ARGENT = { name: "Sol (argent)", type: 'monnaie', img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_argent_sol.webp", system: { quantite: 0, cout: 1, encombrement: 0.003, description: "" } }; const MONNAIE_OR = { name: "Dragon (or)", type: 'monnaie', img: "systems/foundryvtt-reve-de-dragon/icons/objets/piece_or_sol.webp", system: { quantite: 0, cout: 10, encombrement: 0.004, description: "" } }; 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 { static monnaiesStandard() { return MONNAIES_STANDARD; } static monnaiesManquantes(actor) { const disponibles = actor.itemTypes['monnaie']; const manquantes = MONNAIES_STANDARD.filter(standard => !disponibles.find(disponible => Monnaie.deValeur(disponible, standard.system?.cout))); if (manquantes.length > 0) { console.error(`${LOG_HEAD} monnaiesManquantes pour ${actor.name}`, manquantes, ' avec monnaies', disponibles, MONNAIES_STANDARD); } return manquantes; } static deValeur(monnaie, valeur) { return VALEUR_DENIERS(valeur) == VALEUR_DENIERS(monnaie.system.cout) } static triValeurEntiere() { return Misc.ascending(item => VALEUR_DENIERS(item.system.cout)) } 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 toSolsDeniers(fortune) { return { sols: Math.floor(fortune), deniers: Math.round(100 * (fortune - Math.floor(fortune))) }; } static getFortune(monnaies) { return (monnaies??[]) .map(m => Number(m.system.cout) * Number(m.system.quantite)) .reduce(Misc.sum(), 0); } static async optimiserFortune(actor, fortune) { let resteEnDeniers = Math.round(fortune * 100); let monnaies = actor.itemTypes['monnaie']; let updates = []; Monnaie.validerMonnaies(monnaies, actor); let parValeur = Misc.classifyFirst(monnaies, it => VALEUR_DENIERS(it.system.cout)); for (let valeurDeniers of [1000, 100, 10, 1]) { const itemPiece = parValeur[valeurDeniers]; if (itemPiece) { const quantite = Math.floor(resteEnDeniers / valeurDeniers); if (quantite != itemPiece.system.quantite) { updates.push({ _id: parValeur[valeurDeniers].id, 'system.quantite': quantite }); } resteEnDeniers -= quantite * valeurDeniers; } } console.log('Monnaie.optimiserFortune', actor.name, 'total', fortune, 'parValeur', parValeur, 'updates', updates, 'reste', resteEnDeniers); if (updates.length > 0) { await actor.updateEmbeddedDocuments('Item', updates); } if (resteEnDeniers > 0) { // créer le reste en deniers fortune en deniers await Monnaie.creerMonnaiesDeniers(actor, resteEnDeniers); } } static validerMonnaies(monnaies, actor = undefined) { monnaies.filter(it => VALEUR_DENIERS(it.system.cout) == 0) .map(it => `La monnaie ${it.name} de l'acteur ${actor?.name ?? 'sélectionné'} a une valeur de 0!`) .forEach(message => { ui.notifications.warn(message); console.warn(message); }); } }