diff --git a/module/actor.js b/module/actor.js index dca482fb..83d366c8 100644 --- a/module/actor.js +++ b/module/actor.js @@ -18,7 +18,7 @@ import { RdDItemArme } from "./item-arme.js"; import { RdDAlchimie } from "./rdd-alchimie.js"; import { STATUSES, StatusEffects } from "./settings/status-effects.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; -import { RdDItemSigneDraconique } from "./item-signedraconique.js"; +import { RdDItemSigneDraconique } from "./item/item-signedraconique.js"; import { ReglesOptionelles } from "./settings/regles-optionelles.js"; import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; import { Draconique } from "./tmr/draconique.js"; @@ -30,10 +30,11 @@ import { RdDPossession } from "./rdd-possession.js"; import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { RdDConfirm } from "./rdd-confirm.js"; import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js"; -import { RdDRencontre } from "./item-rencontre.js"; +import { RdDRencontre } from "./item/item-rencontre.js"; import { Targets } from "./targets.js"; import { DialogRepos } from "./dialog-repos.js"; import { RdDBaseActor } from "./actor/base-actor.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; const POSSESSION_SANS_DRACONIC = { img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp', @@ -933,7 +934,7 @@ export class RdDActor extends RdDBaseActor { let expLog = duplicate(this.system.experiencelog); expLog.push({ mode: Misc.upperFirst(modeXP), valeur: valeurXP, raison: Misc.upperFirst(raisonXP), - daterdd: game.system.rdd.calendrier.getDateFromIndex(), + daterdd: game.system.rdd.calendrier.dateCourante(), datereel: `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}` }); await this.update({ [`system.experiencelog`]: expLog }); @@ -2727,10 +2728,10 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ getHeureNaissance() { - if (this.isCreatureEntite()) { - return 0; + if (this.isPersonnage()) { + return this.system.heure; } - return this.system.heure; + return 0; } /* -------------------------------------------- */ @@ -2818,10 +2819,16 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ async ajouteNombreAstral(callData) { + const indexDate = Number.parseInt(callData.date); // Ajout du nombre astral const item = { name: "Nombre Astral", type: "nombreastral", system: - { value: callData.nbAstral, istrue: callData.isvalid, jourindex: Number(callData.date), jourlabel: game.system.rdd.calendrier.getDateFromIndex(Number(callData.date)) } + { + value: callData.nbAstral, + istrue: callData.isvalid, + jourindex: indexDate, + jourlabel: RdDTimestamp.formatIndexDate(indexDate) + } }; await this.createEmbeddedDocuments("Item", [item]); // Affichage Dialog @@ -2830,7 +2837,7 @@ export class RdDActor extends RdDBaseActor { async supprimerAnciensNombresAstraux() { const toDelete = this.listItems('nombreastral') - .filter(it => it.system.jourindex < game.system.rdd.calendrier.getCurrentDayIndex()) + .filter(it => game.system.rdd.calendrier.isAfterIndexDate(it.system.jourindex)) .map(it => it._id); await this.deleteEmbeddedDocuments("Item", toDelete); } @@ -3694,6 +3701,7 @@ export class RdDActor extends RdDBaseActor { await this.onCreateOwnedDraconique(item, options, id); break; } + await item.onCreateItemTemporel(this); await item.onCreateDecoupeComestible(this); } diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js index 5740b70f..7acad67f 100644 --- a/module/actor/base-actor.js +++ b/module/actor/base-actor.js @@ -1,7 +1,6 @@ import { ChatUtility } from "../chat-utility.js"; import { SYSTEM_SOCKET_ID } from "../constants.js"; import { Monnaie } from "../item-monnaie.js"; -import { RdDItem } from "../item.js"; import { Misc } from "../misc.js"; import { RdDAudio } from "../rdd-audio.js"; import { RdDUtility } from "../rdd-utility.js"; diff --git a/module/dialog-chronologie.js b/module/dialog-chronologie.js index c86dd519..cd24e6de 100644 --- a/module/dialog-chronologie.js +++ b/module/dialog-chronologie.js @@ -25,7 +25,7 @@ export class DialogChronologie extends Dialog { journaux: game.journal.filter(it => it.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)), dateRdD: dateRdD, jourRdD: dateRdD.jour +1, - heureRdD: game.system.rdd.calendrier.getCurrentHeure(), + heureRdD: game.system.rdd.calendrier.heureCourante().key, dateReel: DialogChronologie.getCurrentDateTime() }; const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-chronologie.html", dialogData); diff --git a/module/dialog-create-signedraconique.js b/module/dialog-create-signedraconique.js index 86b98d45..fa012e9d 100644 --- a/module/dialog-create-signedraconique.js +++ b/module/dialog-create-signedraconique.js @@ -1,6 +1,6 @@ import { ChatUtility } from "./chat-utility.js"; import { HtmlUtility } from "./html-utility.js"; -import { RdDItemSigneDraconique } from "./item-signedraconique.js"; +import { RdDItemSigneDraconique } from "./item/item-signedraconique.js"; import { TMRUtility } from "./tmr-utility.js"; export class DialogCreateSigneDraconique extends Dialog { diff --git a/module/item-rencontre-sheet.js b/module/item-rencontre-sheet.js index 50a34834..c134300d 100644 --- a/module/item-rencontre-sheet.js +++ b/module/item-rencontre-sheet.js @@ -1,4 +1,4 @@ -import { RdDRencontre } from "./item-rencontre.js"; +import { RdDRencontre } from "./item/item-rencontre.js"; import { RdDItemSheet } from "./item-sheet.js"; export class RdDRencontreItemSheet extends RdDItemSheet { diff --git a/module/item-sheet.js b/module/item-sheet.js index b803de32..ca15056a 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -10,6 +10,7 @@ import { SYSTEM_RDD } from "./constants.js"; import { RdDSheetUtility } from "./rdd-sheet-utility.js"; import { SystemCompendiums } from "./settings/system-compendiums.js"; import { Misc } from "./misc.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; /** * Extend the basic ItemSheet for RdD specific items @@ -135,11 +136,7 @@ export class RdDItemSheet extends ItemSheet { RdDGemme.calculDataDerivees(this.item); } if (this.item.type == 'potion') { - if (this.dateUpdated) { - formData.system.prdate = this.dateUpdated; - this.dateUpdated = undefined; - } - await RdDHerbes.updatePotionData(formData); + await RdDHerbes.addPotionFormData(formData); } if (formData.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) { formData.isIngredientPotionBase = true; @@ -185,10 +182,12 @@ export class RdDItemSheet extends ItemSheet { } }) - this.html.find('.enchanteDate').change((event) => { - let jour = Number(this.html.find('[name="splitDate.day"]').val()); - let mois = this.html.find('[name="splitDate.month"]').val(); - this.dateUpdated = game.system.rdd.calendrier.getIndexFromDate(jour, mois); + this.html.find('.date-enchantement').change((event) => { + const jour = Number(this.html.find('input.date-enchantement[name="enchantement.jour"]').val()); + const mois = RdDTimestamp.definition(this.html.find('select.date-enchantement[name="enchantement.mois"]').val()); + const indexDate = game.system.rdd.calendrier.getIndexFromDate(jour, mois.heure); + this.item.update({'system.prdate': indexDate}); + console.warn(`Date d'enchantement modifiée ${jour}/${mois.heure}: ${indexDate}`) }); this.html.find('.creer-tache-livre').click((event) => this._getEventActor(event).creerTacheDepuisLivre(this.item)); diff --git a/module/item-signedraconique-sheet.js b/module/item-signedraconique-sheet.js index 119a446c..6052079a 100644 --- a/module/item-signedraconique-sheet.js +++ b/module/item-signedraconique-sheet.js @@ -1,5 +1,5 @@ import { RdDItemSheet } from "./item-sheet.js"; -import { RdDItemSigneDraconique } from "./item-signedraconique.js"; +import { RdDItemSigneDraconique } from "./item/item-signedraconique.js"; import { TMRUtility } from "./tmr-utility.js"; /** diff --git a/module/item.js b/module/item.js index 03edc4fa..594ad6b4 100644 --- a/module/item.js +++ b/module/item.js @@ -2,6 +2,7 @@ import { DialogItemVente } from "./dialog-item-vente.js"; import { Grammar } from "./grammar.js"; import { Misc } from "./misc.js"; import { RdDHerbes } from "./rdd-herbes.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; import { RdDUtility } from "./rdd-utility.js"; import { SystemCompendiums } from "./settings/system-compendiums.js"; @@ -30,6 +31,7 @@ const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraco const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"] const typesObjetsEffet = ["possession", "poison", "maladie"] const typesObjetsCompetence = ["competence", "competencecreature"] +const typesObjetsTemporels = ["poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"] const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/ @@ -152,24 +154,15 @@ export class RdDItem extends Item { isMonnaie() { return this.type == 'monnaie'; } isNourritureBoisson() { return this.type == 'nourritureboisson'; } isService() { return this.type == 'service'; } - isCompetence() { - return typesObjetsCompetence.includes(this.type) - } - isInventaire(mode = 'materiel') { - return RdDItem.getItemTypesInventaire(mode).includes(this.type); - } - isOeuvre() { - return typesObjetsOeuvres.includes(this.type) - } - isDraconique() { - return typesObjetsDraconiques.includes(this.type) - } - isEffet() { - return typesObjetsEffet.includes(this.type) - } - isConnaissance() { - return typesObjetsConnaissance.includes(this.type) - } + isCompetence() { return typesObjetsCompetence.includes(this.type) } + isTemporel() { return typesObjetsTemporels.includes(this.type) } + + isOeuvre() { return typesObjetsOeuvres.includes(this.type) } + isDraconique() { return typesObjetsDraconiques.includes(this.type) } + isEffet() { return typesObjetsEffet.includes(this.type) } + isConnaissance() { return typesObjetsConnaissance.includes(this.type) } + + isInventaire(mode = 'materiel') { return RdDItem.getItemTypesInventaire(mode).includes(this.type); } getItemGroup() { if (this.isInventaire()) return "equipement"; @@ -383,6 +376,40 @@ export class RdDItem extends Item { await item.delete(); } + async onCreateItemTemporel(actor) { + if (this.isTemporel()) { + const timestampDebut = game.system.rdd.calendrier.timestamp; + const timestampFin = await this.calculerFinPeriodeTemporel(timestampDebut); + await actor.updateEmbeddedDocuments('Item', [{ + _id: this.id, + 'system.temporel.debut': duplicate(timestampDebut), + 'system.temporel.fin': duplicate(timestampFin), + }]) + } + } + + async calculerFinPeriodeTemporel(timestampDebut) { + return timestampDebut; + } + + async prolongerPeriode() { + if (this.actor) { + const current = game.system.rdd.calendrier.timestamp; + const finPeriode = new RdDTimestamp(this.system.temporel.fin) + const periodeSuivante = (finPeriode.compare(current)>0 ? finPeriode : current); + const timestampFin = await this.calculerFinPeriodeTemporel(periodeSuivante); + + await this.actor.updateEmbeddedDocuments('Item', [{ + _id: this.id, + 'system.temporel.fin': duplicate(timestampFin), + }]) + } + } + + async onFinTemporel() { + await this.actor?.deleteEmbeddedDocuments('Item', [this.id]); + } + async quantiteIncDec(nombre, options = { supprimerSiZero: false }) { const quantite = Number(this.system.quantite ?? -1); if (quantite >= 0) { diff --git a/module/item-rencontre.js b/module/item/item-rencontre.js similarity index 93% rename from module/item-rencontre.js rename to module/item/item-rencontre.js index 519b5129..bcd0ac7b 100644 --- a/module/item-rencontre.js +++ b/module/item/item-rencontre.js @@ -1,4 +1,5 @@ -import { EffetsRencontre } from "./effets-rencontres.js"; +import { EffetsRencontre } from "../effets-rencontres.js"; +import { RdDItem } from "../item.js"; const tableEffets = [ { code: "messager", resultat: "succes", description: "Envoie un message à (force) cases", method: EffetsRencontre.messager }, @@ -36,7 +37,11 @@ const tableEffets = [ // { code: "epart-souffle", resultat: "echec", description: "Souffle de dragon sur échec particulier" }, ]; -export class RdDRencontre { +export class RdDRencontre extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp"; + } static getEffetsSucces() { return RdDRencontre.getEffets("succes"); } static getEffetsEchec() { return RdDRencontre.getEffets("echec"); } @@ -68,4 +73,8 @@ export class RdDRencontre { } } + async calculerFinPeriodeTemporel(debut) { + return await debut.nouvelleHeure().addHeures(12); + } + } diff --git a/module/item-service.js b/module/item/item-service.js similarity index 92% rename from module/item-service.js rename to module/item/item-service.js index 95e192b7..5c57f90c 100644 --- a/module/item-service.js +++ b/module/item/item-service.js @@ -1,4 +1,4 @@ -import { RdDItem } from "./item.js"; +import { RdDItem } from "../item.js"; export class RdDItemService extends RdDItem { diff --git a/module/item-signedraconique.js b/module/item/item-signedraconique.js similarity index 82% rename from module/item-signedraconique.js rename to module/item/item-signedraconique.js index 8bed1ed0..31eaf436 100644 --- a/module/item-signedraconique.js +++ b/module/item/item-signedraconique.js @@ -1,8 +1,9 @@ -import { defaultItemImg } from "./item.js"; -import { Misc } from "./misc.js"; -import { RdDDice } from "./rdd-dice.js"; -import { RdDRollTables } from "./rdd-rolltables.js"; -import { TMRType, TMRUtility } from "./tmr-utility.js"; +import { RdDItem, defaultItemImg } from "../item.js"; +import { Misc } from "../misc.js"; +import { RdDDice } from "../rdd-dice.js"; +import { RdDRollTables } from "../rdd-rolltables.js"; +import { RdDTimestamp } from "../rdd-timestamp.js"; +import { TMRType, TMRUtility } from "../tmr-utility.js"; const tableSignesIndicatifs = [ { rarete: "Très facile", difficulte: 0, xp: 6, nbCases: 14 }, @@ -15,7 +16,17 @@ const tableSignesIndicatifs = [ const DIFFICULTE_LECTURE_SIGNE_MANQUE = +11; -export class RdDItemSigneDraconique { +export class RdDItemSigneDraconique extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp"; + } + + + async calculerFinPeriodeTemporel(debut) { + // TODO + return RdDTimestamp.formulesDuree().find(it => it.code == "").calcul(debut, this.actor); + } static prepareSigneDraconiqueMeditation(meditation, rolled) { return { @@ -96,6 +107,6 @@ export class RdDItemSigneDraconique { static async randomSigneDescription() { return await RdDRollTables.drawTextFromRollTable("Signes draconiques", false); - } + } } \ No newline at end of file diff --git a/module/item/maladie.js b/module/item/maladie.js new file mode 100644 index 00000000..f6ace94c --- /dev/null +++ b/module/item/maladie.js @@ -0,0 +1,13 @@ +import { RdDItem } from "../item.js"; + +export class RdDItemMaladie extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/maladie.webp"; + } + + async calculerFinPeriodeTemporel(debut) { + return await debut.addPeriode(this.system.periode.nombre, this.system.periode.unite) ; + } + +} \ No newline at end of file diff --git a/module/item/ombre.js b/module/item/ombre.js new file mode 100644 index 00000000..c7d55ccd --- /dev/null +++ b/module/item/ombre.js @@ -0,0 +1,18 @@ +import { RdDItem } from "../item.js"; + +export class RdDItemOmbre extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp"; + } + + async calculerFinPeriodeTemporel(debut) { + return await debut.appliquerDuree(this.system.duree, this.parent); + } + + async onFinTemporel() { + // fin de période + await this.prolongerPeriode(); + } + +} \ No newline at end of file diff --git a/module/item/poison.js b/module/item/poison.js new file mode 100644 index 00000000..c6ef408e --- /dev/null +++ b/module/item/poison.js @@ -0,0 +1,17 @@ +import { RdDItem } from "../item.js"; + +export class RdDItemPoison extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/maladies_venins/venin.webp"; + } + + async calculerFinPeriodeTemporel(debut) { + return await debut.addPeriode(this.system.periode.nombre, this.system.periode.unite) ; + } + + async onFinTemporel() { + // fin de période + await this.prolongerPeriode(); + } +} \ No newline at end of file diff --git a/module/item/queue.js b/module/item/queue.js new file mode 100644 index 00000000..c21d1dbd --- /dev/null +++ b/module/item/queue.js @@ -0,0 +1,13 @@ +import { RdDItem } from "../item.js"; + +export class RdDItemQueue extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp"; + } + + async calculerFinPeriodeTemporel(debut) { + return await debut.appliquerDuree(this.system.duree, this.parent); + } + +} \ No newline at end of file diff --git a/module/item/souffle.js b/module/item/souffle.js new file mode 100644 index 00000000..a0ff90c9 --- /dev/null +++ b/module/item/souffle.js @@ -0,0 +1,13 @@ +import { RdDItem } from "../item.js"; + +export class RdDItemSouffle extends RdDItem { + + static get defaultIcon() { + return "systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp"; + } + + async calculerFinPeriodeTemporel(debut) { + return await debut.appliquerDuree(this.system.duree, this.parent); + } + +} \ No newline at end of file diff --git a/module/rdd-astrologie-editeur.js b/module/rdd-astrologie-editeur.js index b2dd6260..3dbf6cbe 100644 --- a/module/rdd-astrologie-editeur.js +++ b/module/rdd-astrologie-editeur.js @@ -15,7 +15,7 @@ // Common conf let dialogConf = { content: html, title: "Editeur d'Astrologie", buttons: myButtons, default: "saveButton" }; - let dialogOptions = { classes: ["rdd-roll-dialog"], width: 600, height: 300, 'z-index': 99999 } + let dialogOptions = { classes: ["rdd-roll-dialog"], width: 600, height: 'fit-content', 'z-index': 99999 } super(dialogConf, dialogOptions) this.calendrier = calendrier; diff --git a/module/rdd-calendrier-editeur.js b/module/rdd-calendrier-editeur.js index d097a1d3..e5fac221 100644 --- a/module/rdd-calendrier-editeur.js +++ b/module/rdd-calendrier-editeur.js @@ -1,4 +1,4 @@ -import { Misc } from "./misc.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; /** * Extend the base Dialog entity by defining a custom window to perform roll. @@ -12,7 +12,7 @@ export class RdDCalendrierEditeur extends Dialog { content: html, title: "Editeur de date/heure", buttons: { - save: { label: "Enregistrer", callback: html => this.fillData() } + save: { label: "Enregistrer", callback: html => this.saveCalendrier() } }, default: "save" }; @@ -26,22 +26,42 @@ export class RdDCalendrierEditeur extends Dialog { activateListeners(html) { super.activateListeners(html); this.html = html; - this.html.find("input[name='nomMois']").val(this.calendrierData.moisKey); + this.html.find("input[name='annee']").val(this.calendrierData.annee); + this.html.find("select[name='nomMois']").val(this.calendrierData.moisKey); + this.html.find("input[name='jourMois']").val(this.calendrierData.jourMois); this.html.find("select[name='nomHeure']").val(this.calendrierData.heureKey); - this.html.find("select[name='jourMois']").val(this.calendrierData.jourMois); - this.html.find("select[name='minutesRelative']").val(this.calendrierData.minutesRelative); - this.html.find("select[name='annee']").val(this.calendrierData.annee); + this.html.find("input[name='minutesRelative']").val(this.calendrierData.minutesRelative); + + this.html.find("input[name='jourMois']").change(event => { + const jour = Number.parseInt(this.html.find("input[name='jourMois']").val()); + if (jour < 1) { + this.html.find("input[name='jourMois']").val(1); + } + if (jour > 28) { + this.html.find("input[name='jourMois']").val(28); + } + }); + this.html.find("input[name='minutesRelative']").change(event => { + const minute = Number.parseInt(this.html.find("input[name='minutesRelative']").val()); + if (minute < 0) { + this.html.find("input[name='minutesRelative']").val(0); + } + if (minute > 119) { + this.html.find("input[name='minutesRelative']").val(119); + } + + }); } /* -------------------------------------------- */ - fillData() { - this.calendrierData.annee = this.html.find("input[name='annee']").val(); - this.calendrierData.moisKey = this.html.find("select[name='nomMois']").val(); - this.calendrierData.heureKey = this.html.find("select[name='nomHeure']").val(); - this.calendrierData.jourMois = this.html.find("select[name='jourMois']").val(); - this.calendrierData.minutesRelative = this.html.find("select[name='minutesRelative']").val(); + saveCalendrier() { + const annee = Number.parseInt(this.html.find("input[name='annee']").val()); + const mois = this.html.find("select[name='nomMois']").val(); + const jour = Number.parseInt(this.html.find("input[name='jourMois']").val()); + const heure = this.html.find("select[name='nomHeure']").val(); + const minute = Number.parseInt(this.html.find("input[name='minutesRelative']").val()); - this.calendrier.saveEditeur(this.calendrierData) + this.calendrier.setNewTimestamp(RdDTimestamp.timestamp(annee, mois, jour, heure, minute)) } /* -------------------------------------------- */ diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js index 2eda5830..5ec8cf76 100644 --- a/module/rdd-calendrier.js +++ b/module/rdd-calendrier.js @@ -1,32 +1,14 @@ -/* -------------------------------------------- */ import { RdDCalendrierEditeur } from "./rdd-calendrier-editeur.js"; import { RdDAstrologieEditeur } from "./rdd-astrologie-editeur.js"; -import { HtmlUtility } from "./html-utility.js"; import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDUtility } from "./rdd-utility.js"; -import { Grammar } from "./grammar.js"; import { RdDDice } from "./rdd-dice.js"; import { Misc } from "./misc.js"; import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { DialogChronologie } from "./dialog-chronologie.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; /* -------------------------------------------- */ -const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/' -const heuresList = ["vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant"]; -const heuresDef = { - "vaisseau": { key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "printemps", heure: 0, icon: 'hd01.svg' }, - "sirene": { key: "sirene", label: "Sirène", lettreFont: 'i', saison: "printemps", heure: 1, icon: 'hd02.svg' }, - "faucon": { key: "faucon", label: "Faucon", lettreFont: 'f', saison: "printemps", heure: 2, icon: 'hd03.svg' }, - "couronne": { key: "couronne", label: "Couronne", lettreFont: '', saison: "ete", heure: 3, icon: 'hd04.svg' }, - "dragon": { key: "dragon", label: "Dragon", lettreFont: 'd', saison: "ete", heure: 4, icon: 'hd05.svg' }, - "epees": { key: "epees", label: "Epées", lettreFont: 'e', saison: "ete", heure: 5, icon: 'hd06.svg' }, - "lyre": { key: "lyre", label: "Lyre", lettreFont: 'l', saison: "automne", heure: 6, icon: 'hd07.svg' }, - "serpent": { key: "serpent", label: "Serpent", lettreFont: 's', saison: "automne", heure: 7, icon: 'hd08.svg' }, - "poissonacrobate": { key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "automne", heure: 8, icon: 'hd09.svg' }, - "araignee": { key: "araignee", label: "Araignée", lettreFont: 'a', saison: "hiver", heure: 9, icon: 'hd10.svg' }, - "roseau": { key: "roseau", label: "Roseau", lettreFont: 'r', saison: "hiver", heure: 10, icon: 'hd11.svg' }, - "chateaudormant": { key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "hiver", heure: 11, icon: 'hd12.svg' } -}; const saisonsDef = { "printemps": { label: "Printemps" }, "ete": { label: "Eté" }, @@ -34,11 +16,10 @@ const saisonsDef = { "hiver": { label: "Hiver" } }; -const RDD_MOIS_PAR_AN = 12; -export const RDD_JOUR_PAR_MOIS = 28; +const RDD_JOUR_PAR_MOIS = 28; const RDD_HEURES_PAR_JOUR = 12; -const RDD_MINUTES_PAR_HEURES = 120; const MAX_NOMBRE_ASTRAL = 12; +const JOURS_DU_MOIS = Array(RDD_JOUR_PAR_MOIS).fill().map((item, index) => 1 + index); /* -------------------------------------------- */ export class RdDCalendrier extends Application { @@ -55,57 +36,6 @@ export class RdDCalendrier extends Application { return { top: 200, left: 200 }; } - static getDefSigne(chiffre) { - chiffre = chiffre % RDD_MOIS_PAR_AN; - return Object.values(heuresDef).find(h => h.heure == chiffre); - } - - static getSigneAs(key, value) { - const heure = (typeof value == 'string' || typeof value == 'number') && Number.isInteger(Number(value)) - ? Number(value) - : (typeof value == 'string') ? RdDCalendrier.getChiffreFromSigne(value) - : undefined - - if (heure != undefined && ['key', 'label', 'lettreFont', 'saison', 'heure', 'icon'].includes(key)) { - return RdDCalendrier.getDefSigne(heure)[key] - } - if (heure != undefined && ['webp'].includes(key)) { - return RdDCalendrier.getDefSigne(heure)['icon'].replace('svg', 'webp'); - } - console.error(`Appel à getSigneAs('${key}', ${value}) avec une clé/heure incorrects`); - return value; - - } - static getChiffreFromSigne(signe) { - return heuresList.indexOf(signe); - } - - static createCalendrierInitial() { - return { - heureRdD: 0, - minutesRelative: 0, - indexJour: 0, - annee: 0, - moisRdD: 0, - moisLabel: heuresDef["vaisseau"].label, - jour: 0 - } - } - - getCalendrier(index) { - index = index ?? this.getCurrentDayIndex(); - const mois = Math.floor(index / RDD_JOUR_PAR_MOIS) % RDD_MOIS_PAR_AN; - return { - heureRdD: 0, // Index dans heuresList / heuresDef[x].heure - minutesRelative: 0, - indexJour: index, - annee: Math.floor(index / (RDD_JOUR_PAR_MOIS * RDD_MOIS_PAR_AN)), - moisRdD: RdDCalendrier.getDefSigne(mois).heure, - moisLabel: RdDCalendrier.getDefSigne(mois).label, - jour: (index % RDD_JOUR_PAR_MOIS) // Le calendrier stocke le jour en 0-27, mais en 1-28 à l'affichage - } - } - constructor() { super(); // position @@ -114,19 +44,19 @@ export class RdDCalendrier extends Application { this.calendrierPos = RdDCalendrier.createCalendrierPos(); game.settings.set(SYSTEM_RDD, "calendrier-pos", this.calendrierPos); } - // Calendrier - this.calendrier = duplicate(game.settings.get(SYSTEM_RDD, "calendrier") ?? RdDCalendrier.createCalendrierInitial()); - this.calendrier.annee = this.calendrier.annee ?? Math.floor((this.calendrier.moisRdD ?? 0) / RDD_MOIS_PAR_AN); - this.calendrier.moisRdD = (this.calendrier.moisRdD ?? 0) % RDD_MOIS_PAR_AN; + this.timestamp = new RdDTimestamp({}); if (Misc.isUniqueConnectedGM()) { // Uniquement si GM - game.settings.set(SYSTEM_RDD, "calendrier", this.calendrier); - + RdDTimestamp.setWorldTime(this.timestamp); this.listeNombreAstral = this.getListeNombreAstral(); this.rebuildListeNombreAstral(HIDE_DICE); // Ensure always up-to-date } - console.log('RdDCalendrier.constructor()', this.calendrier, this.calendrierPos, this.listeNombreAstral); + console.log('RdDCalendrier.constructor()', this.timestamp, this.timestamp.toOldCalendrier(), this.calendrierPos, this.listeNombreAstral); + } + + getCalendrier() { + return this.timestamp.toOldCalendrier(); } /* -------------------------------------------- */ @@ -227,48 +157,49 @@ export class RdDCalendrier extends Application { } /* -------------------------------------------- */ - getDateFromIndex(index) { - const dateRdD = this.getCalendrier(index); - return (dateRdD.jour + 1) + ' ' + dateRdD.moisLabel; + dateCourante() { + return this.timestamp.formatDate(); + } + + isAfterIndexDate(indexDate) { + return indexDate < this.timestamp.indexDate; } /* -------------------------------------------- */ - getDayMonthFromIndex(index = undefined) { - const dateRdD = this.getCalendrier(index); - return { - day: dateRdD.jour + 1, - month: heuresList[dateRdD.moisRdD] - } - } + heureCourante() { return RdDTimestamp.definition(this.timestamp.heure); } /* -------------------------------------------- */ - getCurrentHeure() { - return heuresList[this.calendrier.heureRdD]; + getCurrentMinute() { return this.timestamp.indexMinute; } + + getTimestampFinChateauDormant(nbJours = 0) { + return this.timestamp.nouveauJour().addJour(nbJours); } - /* -------------------------------------------- */ - getCurrentDayIndex() { - return (((this.calendrier.annee ?? 0) * RDD_MOIS_PAR_AN + (this.calendrier.moisRdD ?? 0)) * RDD_JOUR_PAR_MOIS) + (this.calendrier.jour ?? 0); + getTimestampFinHeure(nbHeures = 0) { + return this.timestamp.nouvelleHeure().addHeures(nbHeures); } /* -------------------------------------------- */ getIndexFromDate(jour, mois) { - return (heuresDef[mois].heure * RDD_JOUR_PAR_MOIS) + jour - 1; + const addYear = mois < this.timestamp.mois || (mois == this.timestamp.mois && jour < this.timestamp.jour) + const time = RdDTimestamp.timestamp(this.timestamp.annee + (addYear ? 1 : 0), mois, jour); + return time.indexDate; } + /* -------------------------------------------- */ - getJoursSuivants(num) { + getJoursSuivants(count) { let jours = []; - let index = this.getCurrentDayIndex(); - for (let i = 0; i < num; i++) { - jours[i] = { label: this.getDateFromIndex(index + i), index: index + i }; + let indexDate = this.timestamp.indexDate; + for (let i = 0; i < count; i++, indexDate++) { + jours[i] = { label: RdDTimestamp.formatIndexDate(indexDate), index: indexDate }; } return jours; } /* -------------------------------------------- */ - async ajouterNombreAstral(index, showDice = SHOW_DICE) { + async ajouterNombreAstral(indexDate, showDice = SHOW_DICE) { const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showDice, rollMode: "selfroll" }); - const dateFuture = this.getDateFromIndex(index); + const dateFuture = RdDTimestamp.formatIndexDate(indexDate); if (showDice != HIDE_DICE) { ChatMessage.create({ whisper: ChatMessage.getWhisperRecipients("GM"), @@ -278,14 +209,13 @@ export class RdDCalendrier extends Application { return { nombreAstral: nombreAstral, valeursFausses: [], - index: index + index: indexDate } } /* -------------------------------------------- */ getCurrentNombreAstral() { - let indexDate = this.getCurrentDayIndex(); - return this.getNombreAstral(indexDate); + return this.getNombreAstral(this.timestamp.indexDate); } /* -------------------------------------------- */ @@ -309,10 +239,9 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async rebuildListeNombreAstral(showDice = HIDE_DICE) { if (Misc.isUniqueConnectedGM()) { - let jourCourant = this.getCurrentDayIndex(); let newList = []; for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) { - let dayIndex = jourCourant + i; + let dayIndex = this.timestamp.indexDate + i; let na = this.listeNombreAstral.find(n => n.index == dayIndex); if (na) { newList[i] = na; @@ -320,25 +249,31 @@ export class RdDCalendrier extends Application { newList[i] = await this.ajouterNombreAstral(dayIndex, showDice); } } - game.settings.set(SYSTEM_RDD, "liste-nombre-astral", newList); this.listeNombreAstral = newList; + game.settings.set(SYSTEM_RDD, "liste-nombre-astral", newList); } } /* -------------------------------------------- */ - async onCalendarButton(ev) { - ev.preventDefault(); - const calendarAvance = ev.currentTarget.attributes['data-calendar-avance']; - const calendarSet = ev.currentTarget.attributes['data-calendar-set']; - if (calendarAvance) { - await this.incrementTime(Number(calendarAvance.value)); + async setNewTimestamp(newTimestamp) { + this.checkMaladiePoison(this.timestamp, newTimestamp); + + this.checkMaladie("round"); + this.checkMaladie("minute"); + if (this.timestamp.heure != newTimestamp.heure || this.timestamp.indexDate != newTimestamp.indexDate) { + this.checkMaladie("heure"); } - else if (calendarSet) { - this.positionnerHeure(Number(calendarSet.value)); + if (this.timestamp.indexDate != newTimestamp.indexDate) { + this.checkMaladie("jour"); } + + RdDTimestamp.setWorldTime(newTimestamp); + this.timestamp = newTimestamp; + await this.rebuildListeNombreAstral(); this.updateDisplay(); } + /* -------------------------------------------- */ checkMaladie(periode) { for (let actor of game.actors) { @@ -357,77 +292,94 @@ export class RdDCalendrier extends Application { } } + checkMaladiePoison(oldTimestamp, newTimestamp) { + // TODO + const isInPeriod = maladie => { + //TODO: utiliser les timestamp + return false; + } + + game.actors.filter(it => it.type == 'personnage') + .forEach(actor => { + actor.items.filter(it => it.type == 'maladie' || (it.type == 'poison' && it.system.active)) + .filter(m => isInPeriod(m)) + .forEach(m => { + if (m.system.identifie) { + ChatMessage.create({ content: `${actor.name} souffre de ${m.name} (${m.type}): vérifiez que les effets ne se sont pas aggravés !` }); + } else { + ChatMessage.create({ content: `${actor.name} souffre d'un mal inconnu (${m.type}): vérifiez que les effets ne se sont pas aggravés !` }); + } + let itemMaladie = actor.getItem(m.id) + itemMaladie.postItemToChat('gmroll'); + }) + }); + } + + /* -------------------------------------------- */ + async onCalendarButton(ev) { + ev.preventDefault(); + const calendarAvance = ev.currentTarget.attributes['data-calendar-avance']; + const calendarSet = ev.currentTarget.attributes['data-calendar-set']; + if (calendarAvance) { + await this.incrementTime(Number(calendarAvance.value)); + } + else if (calendarSet) { + this.positionnerHeure(Number(calendarSet.value)); + } + this.updateDisplay(); + } + /* -------------------------------------------- */ async incrementTime(minutes = 0) { - this.calendrier.minutesRelative += minutes; - this.checkMaladie("round"); - this.checkMaladie("minute"); - if (this.calendrier.minutesRelative >= RDD_MINUTES_PAR_HEURES) { - this.calendrier.minutesRelative -= RDD_MINUTES_PAR_HEURES; - this.calendrier.heureRdD += 1; - this.checkMaladie("heure"); - } - if (this.calendrier.heureRdD >= RDD_HEURES_PAR_JOUR) { - this.calendrier.heureRdD -= RDD_HEURES_PAR_JOUR; - await this.incrementerJour(); - this.checkMaladie("heure"); - this.checkMaladie("jour"); - } - game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier)); - // Notification aux joueurs // TODO: replace with Hook on game settings update - game.socket.emit(SYSTEM_SOCKET_ID, { - msg: "msg_sync_time", - data: duplicate(this.calendrier) - }); + await this.setNewTimestamp(this.timestamp.addMinutes(minutes)); } /* -------------------------------------------- */ async incrementerJour() { - const index = this.getCurrentDayIndex() + 1; - this.calendrier = this.getCalendrier(index); - await this.rebuildListeNombreAstral(); + await this.setNewTimestamp(this.timestamp.nouveauJour()); } /* -------------------------------------------- */ - syncPlayerTime(calendrier) { - this.calendrier = duplicate(calendrier); // Local copy update + syncPlayerTime(timestamp) { + this.timestamp = new RdDTimestamp(timestamp); this.updateDisplay(); } /* -------------------------------------------- */ async positionnerHeure(indexHeure) { - if (indexHeure <= this.calendrier.heureRdD) { - await this.incrementerJour(); - } - this.calendrier.heureRdD = indexHeure; - this.calendrier.minutesRelative = 0; - game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier)); + await this.setNewTimestamp(new RdDTimestamp({ indexDate: this.timestamp.indexDate + (this.timestamp.heure < indexHeure ? 0 : 1) }).addHeures(indexHeure)) } /* -------------------------------------------- */ fillCalendrierData(formData = {}) { - const mois = RdDCalendrier.getDefSigne(this.calendrier.moisRdD); - const heure = RdDCalendrier.getDefSigne(this.calendrier.heureRdD); - console.log('fillCalendrierData', this.calendrier, mois, heure); + const mois = RdDTimestamp.definition(this.timestamp.mois); + const heure = RdDTimestamp.definition(this.timestamp.heure); + + formData.annee = this.timestamp.annee; + + formData.moisKey = mois.key; + formData.nomMois = mois.label; // heures et mois nommés identiques + formData.iconMois = mois.icon; + formData.nomSaison = saisonsDef[mois.saison].label; + + formData.jourMois = this.timestamp.jour + 1; formData.heureKey = heure.key; - formData.moisKey = mois.key; - formData.jourMois = this.calendrier.jour + 1; - formData.nomMois = mois.label; // heures et mois nommés identiques - formData.annee = this.calendrier.annee; - formData.iconMois = dossierIconesHeures + mois.icon; + formData.heureRdD = this.timestamp.heure; formData.nomHeure = heure.label; - formData.iconHeure = dossierIconesHeures + heure.icon; - formData.nomSaison = saisonsDef[mois.saison].label; - formData.heureRdD = this.calendrier.heureRdD; - formData.minutesRelative = this.calendrier.minutesRelative; + formData.iconHeure = heure.icon; + + formData.minutesRelative = this.timestamp.minute; + formData.isGM = game.user.isGM; + + console.log('fillCalendrierData', this.timestamp, mois, heure, formData); return formData; } /* -------------------------------------------- */ getLectureAstrologieDifficulte(dateIndex) { - let indexNow = this.getCurrentDayIndex(); + let indexNow = this.timestamp.indexDate; let diffDay = dateIndex - indexNow; return - Math.floor(diffDay / 2); } @@ -449,9 +401,9 @@ export class RdDCalendrier extends Application { request.rolled = rollData.rolled; request.isValid = request.rolled.isSuccess; request.nbAstral = this.getNombreAstral(request.date); - + if (request.rolled.isSuccess) { - if (request.rolled.isPart){ + if (request.rolled.isPart) { // Gestion expérience (si existante) request.competence = actor.getCompetence("astrologie") request.selectedCarac = actor.system.carac["vue"]; @@ -483,55 +435,32 @@ export class RdDCalendrier extends Application { game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral); } - /* -------------------------------------------- */ - findHeure(heure) { - heure = Grammar.toLowerCaseNoAccentNoSpace(heure); - let parHeureOuLabel = Object.values(heuresDef).filter(it => (it.heure + 1) == parseInt(heure) || Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure); - if (parHeureOuLabel.length == 1) { - return parHeureOuLabel[0]; - } - let parLabelPartiel = Object.values(heuresDef).filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure)); - if (parLabelPartiel.length > 0) { - parLabelPartiel.sort(Misc.ascending(h => h.label.length)); - return parLabelPartiel[0]; - } - return undefined; - } - /* -------------------------------------------- */ - getHeureNumber(hNum) { - let heure = Object.values(heuresDef).find(it => (it.heure) == hNum); - return heure + getHeureChance(heure) { + return heure + (this.getCurrentNombreAstral() ?? 1) - 1; } /* -------------------------------------------- */ getHeuresChanceMalchance(heureNaissance) { - let heuresChancesMalchances = []; - let defHeure = this.findHeure(heureNaissance); + let defHeure = RdDTimestamp.findHeure(heureNaissance); if (defHeure) { - let hn = defHeure.heure; - let chiffreAstral = this.getCurrentNombreAstral() ?? 0; - heuresChancesMalchances[0] = { value: "+4", heures: [this.getHeureNumber((hn + chiffreAstral) % RDD_HEURES_PAR_JOUR).label] }; - heuresChancesMalchances[1] = { - value: "+2", heures: [this.getHeureNumber((hn + chiffreAstral + 4) % RDD_HEURES_PAR_JOUR).label, - this.getHeureNumber((hn + chiffreAstral + 8) % RDD_HEURES_PAR_JOUR).label] - }; - heuresChancesMalchances[2] = { value: "-4", heures: [this.getHeureNumber((hn + chiffreAstral + 6) % RDD_HEURES_PAR_JOUR).label] }; - heuresChancesMalchances[3] = { - value: "-2", heures: [this.getHeureNumber((hn + chiffreAstral + 3) % RDD_HEURES_PAR_JOUR).label, - this.getHeureNumber((hn + chiffreAstral + 9) % RDD_HEURES_PAR_JOUR).label] - }; + const signe = h => h % RDD_HEURES_PAR_JOUR; + const chance = this.getHeureChance(defHeure.heure); + return [ + { ajustement: "+4", heures: [signe(chance)] }, + { ajustement: "+2", heures: [signe(chance + 4), signe(chance + 8)] }, + { ajustement: "-4", heures: [signe(chance + 6)] }, + { ajustement: "-2", heures: [signe(chance + 3), signe(chance + 9)] } + ]; } - return heuresChancesMalchances; + return []; } /* -------------------------------------------- */ getAjustementAstrologique(heureNaissance, name = undefined) { - let defHeure = this.findHeure(heureNaissance); + let defHeure = RdDTimestamp.findHeure(heureNaissance); if (defHeure) { - let hn = defHeure.heure; - let chiffreAstral = this.getCurrentNombreAstral() ?? 0; - let heureCourante = this.calendrier.heureRdD; - let ecartChance = (hn + chiffreAstral - heureCourante) % RDD_HEURES_PAR_JOUR; + const chance = this.getHeureChance(defHeure.heure); + const ecartChance = (chance - this.timestamp.heure) % RDD_HEURES_PAR_JOUR; switch (ecartChance) { case 0: return 4; case 4: case 8: return 2; @@ -551,9 +480,7 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ getData() { let formData = super.getData(); - this.fillCalendrierData(formData); - this.setPos(this.calendrierPos); return formData; } @@ -602,30 +529,20 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async saveEditeur(calendrierData) { - this.calendrier.minutesRelative = Number(calendrierData.minutesRelative); - this.calendrier.jour = Number(calendrierData.jourMois) - 1; - this.calendrier.moisRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.moisKey); - this.calendrier.annee = Number(calendrierData.annee); - this.calendrier.heureRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.heureKey); - game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier)); - - await this.rebuildListeNombreAstral(); - - game.socket.emit(SYSTEM_SOCKET_ID, { - msg: "msg_sync_time", - data: duplicate(this.calendrier) - }); - - this.updateDisplay(); + const newTimestamp = RdDTimestamp.timestamp( + Number.parseInt(calendrierData.annee), + RdDTimestamp.definition(calendrierData.moisKey).heure, + Number.parseInt(calendrierData.jourMois), + RdDTimestamp.definition(calendrierData.heureKey).heure, + Number.parseInt(calendrierData.minutesRelative) + ); + await this.setNewTimestamp(newTimestamp); } /* -------------------------------------------- */ async showCalendarEditor() { - let calendrierData = duplicate(this.fillCalendrierData()); + let calendrierData = this.fillCalendrierData(); if (this.editeur == undefined) { - calendrierData.jourMoisOptions = RdDCalendrier.buildJoursMois(); - calendrierData.heuresOptions = [0, 1]; - calendrierData.minutesOptions = Array(RDD_MINUTES_PAR_HEURES).fill().map((item, index) => 0 + index); let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html', calendrierData); this.editeur = new RdDCalendrierEditeur(html, this, calendrierData) } @@ -633,33 +550,30 @@ export class RdDCalendrier extends Application { this.editeur.render(true); } - static buildJoursMois() { - return Array(RDD_JOUR_PAR_MOIS).fill().map((item, index) => 1 + index); - } + static buildJoursMois() { return JOURS_DU_MOIS; } /* -------------------------------------------- */ async showAstrologieEditor() { - let calendrierData = duplicate(this.fillCalendrierData()); - let astrologieArray = []; + const calendrierData = duplicate(this.fillCalendrierData()); this.listeNombreAstral = this.listeNombreAstral || []; - for (let astralData of this.listeNombreAstral) { - astralData.humanDate = this.getDateFromIndex(astralData.index); - for (let vf of astralData.valeursFausses) { + + calendrierData.astrologieData = this.listeNombreAstral.map(astro => { + const timestamp = new RdDTimestamp({ indexDate: astro.index }); + astro.date = { mois: timestamp.mois, jour: timestamp.jour + 1 } + for (let vf of astro.valeursFausses) { let actor = game.actors.get(vf.actorId); vf.actorName = (actor) ? actor.name : "Inconnu"; } - astrologieArray.push(duplicate(astralData)); - } - let heuresParActeur = {}; - for (let actor of game.actors) { + return astro; + }); + + calendrierData.heuresParActeur = {}; + game.actors.filter(it => it.isPersonnage() && it.hasPlayerOwner).forEach(actor => { let heureNaissance = actor.getHeureNaissance(); if (heureNaissance) { - heuresParActeur[actor.name] = this.getHeuresChanceMalchance(heureNaissance); + calendrierData.heuresParActeur[actor.name] = this.getHeuresChanceMalchance(heureNaissance); } - } - //console.log("ASTRO", astrologieArray); - calendrierData.astrologieData = astrologieArray; - calendrierData.heuresParActeur = heuresParActeur; + }) let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-astrologie-template.html', calendrierData); let astrologieEditeur = new RdDAstrologieEditeur(html, this, calendrierData) astrologieEditeur.updateData(calendrierData); diff --git a/module/rdd-herbes.js b/module/rdd-herbes.js index 5210e03e..859cccea 100644 --- a/module/rdd-herbes.js +++ b/module/rdd-herbes.js @@ -1,7 +1,6 @@ -import { RdDUtility } from "./rdd-utility.js"; -import { RdDCalendrier } from "./rdd-calendrier.js"; import { Grammar } from "./grammar.js"; import { SystemCompendiums } from "./settings/system-compendiums.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; /* -------------------------------------------- */ export class RdDHerbes extends Item { @@ -29,7 +28,7 @@ export class RdDHerbes extends Item { } /* -------------------------------------------- */ - static async updatePotionData(formData) { + static async addPotionFormData(formData) { formData.isSoins = formData.system.categorie.includes('Soin'); formData.isRepos = formData.system.categorie.includes('Repos'); if (formData.isSoins) { @@ -40,9 +39,8 @@ export class RdDHerbes extends Item { } formData.herbesSoins = RdDHerbes.buildHerbesList(this.herbesSoins, 12); formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7); - formData.jourMoisOptions = RdDCalendrier.buildJoursMois(); - formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex(); - formData.splitDate = game.system.rdd.calendrier.getDayMonthFromIndex(formData.system.prdate); + formData.dateActuelle = game.system.rdd.calendrier.dateCourante(); + formData.enchantement = RdDTimestamp.splitIndexDate(formData.system.prdate); } /* -------------------------------------------- */ diff --git a/module/rdd-main.js b/module/rdd-main.js index 2b13a1d2..54684146 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -1,10 +1,6 @@ import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { RdDActor } from "./actor.js"; -import { RdDItemSheet } from "./item-sheet.js"; -import { RdDActorSheet } from "./actor-sheet.js"; -import { RdDActorCreatureSheet } from "./actor-creature-sheet.js"; -import { RdDActorVehiculeSheet } from "./actor-vehicule-sheet.js"; -import { RdDActorEntiteSheet } from "./actor-entite-sheet.js"; +import { RdDItem } from "./item.js"; import { RdDUtility } from "./rdd-utility.js"; import { TMRUtility } from "./tmr-utility.js"; import { RdDCalendrier } from "./rdd-calendrier.js"; @@ -19,26 +15,40 @@ import { ReglesOptionelles } from "./settings/regles-optionelles.js"; import { RdDHotbar } from "./rdd-hotbar-drop.js" import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; import { RdDHerbes } from "./rdd-herbes.js"; -import { RdDItem } from "./item.js"; import { RdDDice } from "./rdd-dice.js"; import { RdDPossession } from "./rdd-possession.js"; -import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js"; import { Misc } from "./misc.js"; import { Migrations } from './migrations.js'; import { DialogChronologie } from "./dialog-chronologie.js"; import { SystemCompendiums } from "./settings/system-compendiums.js"; -import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js"; -import { TMRRencontres } from "./tmr-rencontres.js"; -import { RdDHerbeItemSheet } from "./item-herbe-sheet.js"; import { Environnement } from "./environnement.js"; -import { RdDIngredientItemSheet } from "./item-ingredient-sheet.js"; -import { RdDFauneItemSheet } from "./item-faune-sheet.js"; -import { RdDConteneurItemSheet } from "./item-conteneur-sheet.js"; -import { RdDServiceItemSheet } from "./item-service-sheet.js"; -import { RdDItemService } from "./item-service.js"; +import { RdDItemService } from "./item/item-service.js"; import { RdDBaseActor } from "./actor/base-actor.js"; import { RdDCommerceSheet } from "./actor/commerce-sheet.js"; import { RdDCommerce } from "./actor/commerce.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; +import { RdDItemMaladie } from "./item/maladie.js"; +import { RdDItemPoison } from "./item/poison.js"; +import { RdDItemSigneDraconique } from "./item/item-signedraconique.js"; +import { RdDItemQueue } from "./item/queue.js"; +import { RdDItemOmbre } from "./item/ombre.js"; +import { RdDItemSouffle } from "./item/souffle.js"; +import { RdDRencontre } from "./item/item-rencontre.js"; + +import { RdDActorSheet } from "./actor-sheet.js"; +import { RdDActorCreatureSheet } from "./actor-creature-sheet.js"; +import { RdDActorVehiculeSheet } from "./actor-vehicule-sheet.js"; +import { RdDActorEntiteSheet } from "./actor-entite-sheet.js"; +import { RdDItemSheet } from "./item-sheet.js"; +import { RdDServiceItemSheet } from "./item-service-sheet.js"; +import { RdDHerbeItemSheet } from "./item-herbe-sheet.js"; +import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js"; +import { RdDIngredientItemSheet } from "./item-ingredient-sheet.js"; +import { RdDFauneItemSheet } from "./item-faune-sheet.js"; +import { RdDConteneurItemSheet } from "./item-conteneur-sheet.js"; +import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js"; + +import { TMRRencontres } from "./tmr-rencontres.js"; /** * RdD system @@ -57,7 +67,14 @@ export class SystemReveDeDragon { this.RdDUtility = RdDUtility; this.RdDHotbar = RdDHotbar; this.itemClasses = { - service: RdDItemService + service: RdDItemService, + maladie: RdDItemMaladie, + poison: RdDItemPoison, + queue: RdDItemQueue, + ombre: RdDItemOmbre, + souffle: RdDItemSouffle, + signedraconique: RdDItemSigneDraconique, + rencontre: RdDRencontre } this.actorClasses = { creature: RdDActor, @@ -145,6 +162,7 @@ export class SystemReveDeDragon { CONFIG.Combat.documentClass = RdDCombatManager; // préparation des différents modules + RdDTimestamp.init(); SystemCompendiums.init(); DialogChronologie.init(); ReglesOptionelles.init(); @@ -181,15 +199,6 @@ export class SystemReveDeDragon { default: "avant-encaissement" }); - /* -------------------------------------------- */ - game.settings.register(SYSTEM_RDD, "calendrier", { - name: "calendrier", - scope: "world", - config: false, - default: RdDCalendrier.createCalendrierInitial(), - type: Object - }); - /* -------------------------------------------- */ game.settings.register(SYSTEM_RDD, "liste-nombre-astral", { name: "liste-nombre-astral", diff --git a/module/rdd-timestamp.js b/module/rdd-timestamp.js new file mode 100644 index 00000000..619dfc55 --- /dev/null +++ b/module/rdd-timestamp.js @@ -0,0 +1,292 @@ +import { SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; +import { Grammar } from "./grammar.js"; +import { Misc } from "./misc.js"; +import { RdDDice } from "./rdd-dice.js"; + +const RDD_MOIS_PAR_AN = 12; +const RDD_JOURS_PAR_MOIS = 28; +const RDD_JOURS_PAR_AN = 336; //RDD_JOURS_PAR_MOIS * RDD_MOIS_PAR_AN; +const RDD_HEURES_PAR_JOUR = 12; +const RDD_MINUTES_PAR_HEURES = 120; +const RDD_MINUTES_PAR_JOUR = 1440; //RDD_HEURES_PAR_JOUR * RDD_MINUTES_PAR_HEURES; +const ROUNDS_PAR_MINUTE = 10; +const CALENDRIER = "calendrier"; + +const DEFINITION_HEURES = [ + { key: "vaisseau", label: "Vaisseau", lettreFont: 'v', saison: "printemps" }, + { key: "sirene", label: "Sirène", lettreFont: 'i', saison: "printemps" }, + { key: "faucon", label: "Faucon", lettreFont: 'f', saison: "printemps" }, + { key: "couronne", label: "Couronne", lettreFont: '', saison: "ete" }, + { key: "dragon", label: "Dragon", lettreFont: 'd', saison: "ete" }, + { key: "epees", label: "Epées", lettreFont: 'e', saison: "ete" }, + { key: "lyre", label: "Lyre", lettreFont: 'l', saison: "automne" }, + { key: "serpent", label: "Serpent", lettreFont: 's', saison: "automne" }, + { key: "poissonacrobate", label: "Poisson Acrobate", lettreFont: 'p', saison: "automne" }, + { key: "araignee", label: "Araignée", lettreFont: 'a', saison: "hiver" }, + { key: "roseau", label: "Roseau", lettreFont: 'r', saison: "hiver" }, + { key: "chateaudormant", label: "Château Dormant", lettreFont: 'c', saison: "hiver" }, +] + +const FORMULES_DUREE = [ + { code: "", label: "", calcul: async (t, actor) => t.addJours(100 * RDD_JOURS_PAR_AN) }, + { code: "jour", label: "1 jour", calcul: async (t, actor) => t.nouveauJour().addJours(1) }, + { code: "1d7jours", label: "1d7 jour", calcul: async (t, actor) => t.nouveauJour().addJours(await RdDDice.rollTotal('1d7', { showDice: SHOW_DICE })) }, + { code: "1ddr", label: "Un dé draconique jours", calcul: async (t, actor) => t.nouveauJour().addJours(await RdDDice.rollTotal('1dr+7', { showDice: SHOW_DICE })) }, + { code: "hn", label: "Fin de l'Heure de Naissance", calcul: async (t, actor) => t.finHeure(actor.getHeureNaissance()) }, + // { code: "1h", label: "Une heure", calcul: async (t, actor) => t.nouvelleHeure().addHeures(1) }, + // { code: "12h", label: "12 heures", calcul: async (t, actor) => t.nouvelleHeure().addHeures(12) }, + // { code: "chateaudormant", label: "Fin Chateau dormant", calcul: async (t, actor) => t.nouveauJour() }, + // { code: "special", label: "Spéciale", calcul: async (t, actor) => t.addJours(100 * RDD_JOURS_PAR_AN) }, +] + +export class RdDTimestamp { + + static iconeHeure(heure) { + return `systems/foundryvtt-reve-de-dragon/icons/heures/hd${heure < 9 ? '0' : ''}${heure + 1}.svg`; + } + + static init() { + game.settings.register(SYSTEM_RDD, CALENDRIER, { + name: CALENDRIER, + scope: "world", + config: false, + default: { indexJour: 0, heureRdD: 0, minutesRelative: 0 }, + type: Object + }); + + for (let i = 0; i < DEFINITION_HEURES.length; i++) { + DEFINITION_HEURES[i].heure = i; + DEFINITION_HEURES[i].icon = RdDTimestamp.iconeHeure(i); + DEFINITION_HEURES[i].webp = DEFINITION_HEURES[i].icon.replace(".svg", ".webp"); + } + // TODO: positionner les calculs de FORMULES_DUREE + } + + /** + * @param signe + * @returns L'entrée de DEFINITION_HEURES correspondant au signe + */ + static definition(signe) { + if (Number.isInteger(signe)) { + return DEFINITION_HEURES[signe % RDD_HEURES_PAR_JOUR]; + } + let definition = DEFINITION_HEURES.find(it => it.key == signe); + if (!definition) { + definition = Misc.findFirstLike(signe, DEFINITION_HEURES, { mapper: it => it.label, description: 'signe' }); + } + return definition + } + + static formulesDuree() { + return FORMULES_DUREE + } + + static imgSigneHeure(heure) { + return RdDTimestamp.imgSigne(RdDTimestamp.definition(heure)); + } + + static imgSigne(signe) { + return `` + } + + static findHeure(heure) { + heure = Grammar.toLowerCaseNoAccentNoSpace(heure); + let parHeureOuLabel = DEFINITION_HEURES.filter(it => (it.heure) == parseInt(heure) % RDD_HEURES_PAR_JOUR || Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure); + if (parHeureOuLabel.length == 1) { + return parHeureOuLabel[0]; + } + let parLabelPartiel = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure)); + if (parLabelPartiel.length > 0) { + parLabelPartiel.sort(Misc.ascending(h => h.label.length)); + return parLabelPartiel[0]; + } + return undefined; + } + + static signeHeure(key, value) { + const signe = RdDTimestamp.definition(value); + if (signe && ['key', 'webp', 'label', 'lettreFont', 'saison', 'heure', 'icon'].includes(key)) { + return signe[key]; + } + console.error(`Appel à getSigneAs('${key}', ${value}) avec une clé/heure incorrects`); + return value; + + } + + static getCalendrier(indexDate, indexMinute = 0) { + return new RdDTimestamp({ indexDate, indexMinute }).toOldCalendrier(); + } + + /** + * + * @param indexMinute: la version formattée de la date + */ + static formatIndexDate(indexDate) { + return new RdDTimestamp({ indexDate }).formatDate() + } + static splitIndexDate(indexDate) { + const timestamp = new RdDTimestamp({ indexDate }); + return { + jour: timestamp.jour + 1, + mois: RdDTimestamp.definition(timestamp.mois).key + } + } + + static getWorldTime() { + return game.settings.get(SYSTEM_RDD, CALENDRIER); + } + + static setWorldTime(timestamp) { + game.settings.set(SYSTEM_RDD, CALENDRIER, timestamp.toOldCalendrier()); + game.socket.emit(SYSTEM_SOCKET_ID, { + msg: "msg_sync_time", + data: duplicate(timestamp) + }); + + } + + /** construit un RdDTimestamp à partir de l'année/mois/jour/heure?/minute? */ + static timestamp(annee, mois, jour, heure = 0, minute = 0) { + mois = this.definition(mois)?.heure + heure = this.definition(heure)?.heure + return new RdDTimestamp({ + indexDate: (jour - 1) + (mois + annee * RDD_MOIS_PAR_AN) * RDD_JOURS_PAR_MOIS, + indexMinute: heure * RDD_MINUTES_PAR_HEURES + minute + }) + } + + /** + * Constructeur d'un timestamp. + * Selon les paramètres, l'objet construit se base su: + * - le timestamp + * - la date numérique + minute (dans la journée) + * @param indexDate: la date à utiliser pour ce timestamp + * @param indexMinute: la minute de la journée à utiliser pour ce timestamp + * + */ + constructor({ indexDate = undefined, indexMinute = undefined }) { + function fromSettings() { + const fromSettings = RdDTimestamp.getWorldTime(); + return { indexDate: fromSettings.indexJour, indexMinute: fromSettings.heureRdD * RDD_MINUTES_PAR_HEURES + fromSettings.minutesRelative }; + } + + const val = Number.isInteger(indexDate) ? { indexDate, indexMinute: indexMinute ?? 0 } : fromSettings(); + + this.indexDate = val.indexDate + this.indexMinute = val.indexMinute + } + + toCalendrier() { + return { + timestamp: this, + annee: this.annee, + mois: RdDTimestamp.definition(this.mois), + jour: this.jour, + heure: RdDTimestamp.definition(this.heure), + minute: this.minute + }; + } + + /** + * Convertit un timestamp en donnée utile à l'affichage d'un calendrier + */ + toOldCalendrier() { + const calendrier = { + indexJour: this.indexDate, + annee: this.annee, + moisRdD: this.mois, + jour: this.jour, + heureRdD: this.heure, + moisLabel: RdDTimestamp.definition(this.mois).label, + heureLabel: RdDTimestamp.definition(this.heure).label, + minutesRelative: this.minute, + }; + return calendrier + } + get annee() { return Math.floor(this.indexDate / RDD_JOURS_PAR_AN) } + get mois() { return Math.floor((this.indexDate % RDD_JOURS_PAR_AN) / RDD_JOURS_PAR_MOIS) } + get jour() { return (this.indexDate % RDD_JOURS_PAR_AN) % RDD_JOURS_PAR_MOIS } + get heure() { return Math.floor(this.indexMinute / RDD_MINUTES_PAR_HEURES) } + get minute() { return this.indexMinute % RDD_MINUTES_PAR_HEURES } + get round() { return ROUNDS_PAR_MINUTE * (this.indexMinute - Math.floor(this.indexMinute)) } + + formatDate() { + const jour = this.jour + 1; + const mois = RdDTimestamp.definition(this.mois).label; + const annee = this.annee ?? ''; + return `${jour} ${mois}` + (annee ? ' ' + annee : ''); + } + + nouveauJour() { return new RdDTimestamp({ indexDate: this.indexDate + 1, indexMinute: 0 }) } + + nouvelleHeure() { + return this.heure >= RDD_HEURES_PAR_JOUR ? this.nouveauJour() : new RdDTimestamp({ + indexDate: this.indexDate, + indexMinute: (this.heure + 1) * RDD_MINUTES_PAR_HEURES + }) + } + + addJours(jours) { + return jours == 0 ? this : new RdDTimestamp({ + indexDate: this.indexDate + jours, + indexMinute: this.indexMinute + }) + } + + addHeures(heures) { + if (heures == 0) { + return this + } + const heure = this.heure + heures; + return new RdDTimestamp({ + indexDate: this.indexDate + Math.floor(heure / RDD_HEURES_PAR_JOUR), + indexMinute: (this.indexMinute + (heure % RDD_HEURES_PAR_JOUR)) % (RDD_MINUTES_PAR_JOUR) + }) + } + + addMinutes(minutes) { + if (minutes == 0) { + return this; + } + const indexMinute = this.indexMinute + minutes; + const jours = Math.floor(indexMinute / RDD_MINUTES_PAR_JOUR) + return new RdDTimestamp({ + indexDate: this.indexDate + jours, + indexMinute: indexMinute - (jours * RDD_MINUTES_PAR_JOUR) + }) + } + + addPeriode(nombre, unite) { + switch (unite) { + case 'heures': return this.addHeures(nombre) + case 'minutes': return this.addMinutes(nombre) + case 'jours': return this.addJours(nombre) + case 'rounds': return this.addMinutes(nombre / 10) + } + return this; + } + + finHeure(heure) { + return this.nouvelleHeure().addHeures((12 + heure - this.heure) % 12); + } + + async appliquerDuree(duree, actor) { + const formule = FORMULES_DUREE.find(it => it.code == duree) ?? FORMULES_DUREE.find(it => it.code == ""); + return await formule.calcul(this, actor); + } + + compare(timestamp) { + let diff = (this.indexDate - timestamp.indexDate) ?? (this.indexMinute - timestamp.indexMinute); + return diff < 0 ? -1 : diff > 0 ? 1 : 0; + } + + difference(timestamp) { + const jours = this.indexDate - timestamp.indexDate; + const minutes = this.indexMinute - timestamp.indexMinute; + return { + jours: jours, + heures: Math.floor(minutes / RDD_MINUTES_PAR_HEURES), + minutes: minutes % RDD_MINUTES_PAR_HEURES + } + } +} \ No newline at end of file diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index 0e7ffb31..c6c9f5d9 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -15,8 +15,9 @@ import { HtmlUtility } from "./html-utility.js"; import { ReglesOptionelles } from "./settings/regles-optionelles.js"; import { RdDDice } from "./rdd-dice.js"; import { STATUSES } from "./settings/status-effects.js"; -import { RdDRencontre } from "./item-rencontre.js"; +import { RdDRencontre } from "./item/item-rencontre.js"; import { RdDCalendrier } from "./rdd-calendrier.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; /* -------------------------------------------- */ @@ -840,7 +841,7 @@ export class RdDTMRDialog extends Dialog { async processSortReserve(sortReserve) { await this.actor.deleteEmbeddedDocuments('Item', [sortReserve.id]); console.log("declencheSortEnReserve", sortReserve); - const heureCible = RdDCalendrier.getSigneAs('label', sortReserve.system.heurecible); + const heureCible = RdDTimestamp.definition(sortReserve.system.heurecible).label; this._tellToUserAndGM(`Vous avez déclenché ${sortReserve.system.echectotal ? "l'échec total!" : "le sort"} en réserve ${sortReserve.name} diff --git a/module/rdd-utility.js b/module/rdd-utility.js index d8cb280c..688aec63 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -12,11 +12,10 @@ import { Monnaie } from "./item-monnaie.js"; import { RdDPossession } from "./rdd-possession.js"; import { RdDNameGen } from "./rdd-namegen.js"; import { RdDConfirm } from "./rdd-confirm.js"; -import { RdDCalendrier } from "./rdd-calendrier.js"; import { Environnement } from "./environnement.js"; import { RdDItemCompetence } from "./item-competence.js"; import { RdDResolutionTable } from "./rdd-resolution-table.js"; -import { RdDCommerce } from "./actor/commerce.js"; +import { RdDTimestamp } from "./rdd-timestamp.js"; /* -------------------------------------------- */ // This table starts at 0 -> niveau -10 @@ -177,9 +176,11 @@ export class RdDUtility { 'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs', 'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs', 'systems/foundryvtt-reve-de-dragon/templates/item/boutons-comestible.html', + 'systems/foundryvtt-reve-de-dragon/templates/item/temporel.hbs', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html', 'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html', + 'systems/foundryvtt-reve-de-dragon/templates/item-queue-sheet.html', 'systems/foundryvtt-reve-de-dragon/templates/header-item.html', // partial enums 'systems/foundryvtt-reve-de-dragon/templates/enum-caracteristiques.html', @@ -200,6 +201,8 @@ export class RdDUtility { 'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-type.html', 'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html', // Partials + 'systems/foundryvtt-reve-de-dragon/templates/common/timestamp.hbs', + 'systems/foundryvtt-reve-de-dragon/templates/common/enum-duree.hbs', 'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs', 'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.html', 'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.html', @@ -279,7 +282,13 @@ export class RdDUtility { Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord)); Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type)); Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord)); - Handlebars.registerHelper('signeHeure', (key, heure) => RdDCalendrier.getSigneAs(key, heure)); + // TODO: upgrade + Handlebars.registerHelper('signeHeure', (key, heure) => RdDTimestamp.signeHeure(key, heure)); + Handlebars.registerHelper('timestamp-imgSigneHeure', (heure) => { return new Handlebars.SafeString(RdDTimestamp.imgSigneHeure(heure)) }); + Handlebars.registerHelper('timestamp-imgSigne', (heure) => { return new Handlebars.SafeString(RdDTimestamp.imgSigne(heure)) }); + Handlebars.registerHelper('timestamp-extract', timestamp => new RdDTimestamp(timestamp).toCalendrier()); + Handlebars.registerHelper('timestamp-formulesDuree', () => RdDTimestamp.formulesDuree()); + Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option)); Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name))); @@ -338,69 +347,6 @@ export class RdDUtility { return undefined; } - /* -------------------------------------------- */ - static filterItemsPerTypeForSheet(formData, itemTypes) { - - RdDUtility.filterEquipementParType(formData, itemTypes); - - formData.sorts = this.arrayOrEmpty(itemTypes['sort']); - formData.rencontres = this.arrayOrEmpty(itemTypes['rencontre']); - formData.casestmr = this.arrayOrEmpty(itemTypes['casetmr']); - formData.signesdraconiques = this.arrayOrEmpty(itemTypes['signedraconique']); - formData.queues = this.arrayOrEmpty(itemTypes['queue']); - formData.souffles = this.arrayOrEmpty(itemTypes['souffle']); - formData.ombres = this.arrayOrEmpty(itemTypes['ombre']); - formData.tetes = this.arrayOrEmpty(itemTypes['tete']); - formData.taches = this.arrayOrEmpty(itemTypes['tache']); - formData.meditations = this.arrayOrEmpty(itemTypes['meditation']); - formData.chants = this.arrayOrEmpty(itemTypes['chant']); - formData.danses = this.arrayOrEmpty(itemTypes['danse']); - formData.musiques = this.arrayOrEmpty(itemTypes['musique']); - formData.oeuvres = this.arrayOrEmpty(itemTypes['oeuvre']); - formData.jeux = this.arrayOrEmpty(itemTypes['jeu']); - - formData.services = this.arrayOrEmpty(itemTypes['service']); - formData.recettescuisine = this.arrayOrEmpty(itemTypes['recettecuisine']); - formData.recettesAlchimiques = this.arrayOrEmpty(itemTypes['recettealchimique']); - formData.maladies = this.arrayOrEmpty(itemTypes['maladie']); - formData.poisons = this.arrayOrEmpty(itemTypes['poison']); - formData.possessions = this.arrayOrEmpty(itemTypes['possession']); - formData.maladiesPoisons = formData.maladies.concat(formData.poisons); - formData.competences = (itemTypes['competence'] ?? []).concat(itemTypes['competencecreature'] ?? []); - formData.sortsReserve = this.arrayOrEmpty(itemTypes['sortreserve']); - } - - static filterEquipementParType(formData, itemTypes) { - formData.conteneurs = this.arrayOrEmpty(itemTypes['conteneur']); - - formData.materiel = this.arrayOrEmpty(itemTypes['objet']); - formData.armes = this.arrayOrEmpty(itemTypes['arme']); - formData.armures = this.arrayOrEmpty(itemTypes['armure']); - formData.munitions = this.arrayOrEmpty(itemTypes['munition']); - formData.livres = this.arrayOrEmpty(itemTypes['livre']); - formData.potions = this.arrayOrEmpty(itemTypes['potion']); - formData.ingredients = this.arrayOrEmpty(itemTypes['ingredient']); - formData.faunes = this.arrayOrEmpty(itemTypes['faune']); - formData.herbes = this.arrayOrEmpty(itemTypes['herbe']); - formData.monnaie = this.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere()); - formData.nourritureboissons = this.arrayOrEmpty(itemTypes['nourritureboisson']); - formData.gemmes = this.arrayOrEmpty(itemTypes['gemme']); - - formData.objets = formData.conteneurs - .concat(formData.materiel) - .concat(formData.armes) - .concat(formData.armures) - .concat(formData.munitions) - .concat(formData.livres) - .concat(formData.potions) - .concat(formData.ingredients) - .concat(formData.herbes) - .concat(formData.faunes) - .concat(formData.monnaie) - .concat(formData.nourritureboissons) - .concat(formData.gemmes); - } - /* -------------------------------------------- */ static buildArbreDeConteneurs(conteneurs, objets) { let objetVersConteneur = {}; @@ -474,7 +420,7 @@ export class RdDUtility { objet.niveau = profondeur; const display = afficherContenu ? 'item-display-show' : 'item-display-hide'; - let strContenu = `
Date | {{#each astrologieData as |nombreData key|}} -{{nombreData.humanDate}} | +{{nombreData.date.jour}}{{timestamp-imgSigneHeure nombreData.date.mois}} | {{/each}}
---|---|---|
Nombre astral | {{#each astrologieData as |nombreData key|}}
|
{{/each}}
Jour {{jourMois}} de {{nomMois}} ({{nomSaison}})
diff --git a/templates/common/enum-duree.hbs b/templates/common/enum-duree.hbs new file mode 100644 index 00000000..b0a91858 --- /dev/null +++ b/templates/common/enum-duree.hbs @@ -0,0 +1,3 @@ +{{#each (timestamp-formulesDuree) as |duree|}} + +{{/each}} \ No newline at end of file diff --git a/templates/common/timestamp.hbs b/templates/common/timestamp.hbs new file mode 100644 index 00000000..6f9a6b9f --- /dev/null +++ b/templates/common/timestamp.hbs @@ -0,0 +1,23 @@ +