From b20a6d729acf4d910c2b5e2bdc24d5b2c5cdc7cc Mon Sep 17 00:00:00 2001 From: sladecraven Date: Tue, 8 Dec 2020 21:40:41 +0100 Subject: [PATCH] #17 Gestion heure et calendrier --- module/actor.js | 6 +- module/rdd-calendrier-editeur.js | 59 ++++++ module/rdd-calendrier.js | 331 +++++++++++++++++++++++++++++-- module/rdd-main.js | 50 +++-- module/rdd-utility.js | 4 + 5 files changed, 415 insertions(+), 35 deletions(-) create mode 100644 module/rdd-calendrier-editeur.js diff --git a/module/actor.js b/module/actor.js index 751ab2bf..b1a05dae 100644 --- a/module/actor.js +++ b/module/actor.js @@ -912,9 +912,11 @@ export class RdDActor extends Actor { if (data.compteurs && data.compteurs.ethylisme) // Ajout de l'éthylisme state = state + data.compteurs.ethylisme.value; state = state; - surenc = -this.detectSurEncombrement(); data.compteurs.etat.value = state; - data.compteurs.surenc.value = surenc; + if ( data.compteurs && data.compteurs.surenc) { + surenc = -this.detectSurEncombrement(); + data.compteurs.surenc.value = surenc; + } } /* -------------------------------------------- */ diff --git a/module/rdd-calendrier-editeur.js b/module/rdd-calendrier-editeur.js new file mode 100644 index 00000000..14d504f1 --- /dev/null +++ b/module/rdd-calendrier-editeur.js @@ -0,0 +1,59 @@ +import { Misc } from "./misc.js"; + +/** + * Extend the base Dialog entity by defining a custom window to perform roll. + * @extends {Dialog} + */ +export class RdDCalendrierEditeur extends Dialog { + + /* -------------------------------------------- */ + constructor(html, calendrier, calendrierData) { + + let myButtons = { + saveButton: { label: "Enregistrer", callback: html => this.fillData() } + }; + + // Common conf + let dialogConf = { content: html, title: "Editeur de date/heure", buttons: myButtons, default: "saveButton" }; + let dialogOptions = { classes: ["rdddialog"], width: 400, height: 300, 'z-index': 99999 } + super(dialogConf, dialogOptions) + + this.calendrier = calendrier; + this.calendrierData = calendrierData; //duplicate(calendrierData); + } + + /* -------------------------------------------- */ + fillData( ) { + this.calendrierData.moisKey = $("#nomMois").val(); + this.calendrierData.heureKey = $("#nomHeure").val(); + this.calendrierData.jourMois = $("#jourMois").val(); + this.calendrierData.heuresRelative = $("#heuresRelative").val(); + this.calendrierData.minutesRelative = $("#minutesRelative").val(); + + console.log("UPDATE ", this.calendrierData); + this.calendrier.saveEditeur( this.calendrierData ) + } + + /* -------------------------------------------- */ + updateData( calendrierData ) { + this.calendrierData = duplicate(calendrierData); + } + + /* -------------------------------------------- */ + activateListeners(html) { + super.activateListeners(html); + + let calendrierData = this.calendrierData; + + $(function () { + console.log(calendrierData); + $("#nomMois").val(calendrierData.moisKey); + $("#nomHeure").val(calendrierData.heureKey); + $("#jourMois").val(calendrierData.jourMois); + $("#heuresRelative").val(calendrierData.heuresRelative); + $("#minutesRelative").val(calendrierData.minutesRelative); + }); + + } + +} diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js index 99891407..07a259f3 100644 --- a/module/rdd-calendrier.js +++ b/module/rdd-calendrier.js @@ -1,22 +1,321 @@ /* -------------------------------------------- */ -const heures = [ "Vaisseau", "Sirène", "Faucon", "Couronne", "Dragon", "Epées", "Lyre", "Serpent", "Poisson Acrobate", "Araignée", "Roseau", "Château Dormant" ] +import { RdDCalendrierEditeur } from "./rdd-calendrier-editeur.js"; + +/* -------------------------------------------- */ +const heuresList = [ "vaisseau", "sirene", "faucon", "couronne", "dragon", "epees", "lyre", "serpent", "poissonacrobate", "araignee", "roseau", "chateaudormant" ]; +const heuresDef = { "vaisseau": { label: "Vaisseau", lettreFont: 'v', saison: "printemps" }, + "sirene": { label: "Sirène", lettreFont: 'S', saison: "printemps"}, + "faucon": {label: "Faucon", lettreFont: 'f', saison: "printemps"}, + "couronne": {label: "Couronne", lettreFont: 'C', saison: "ete"}, + "dragon": {label: "Dragon", lettreFont: 'd', saison: "ete"}, + "epees": {label: "Epées", lettreFont: 'e', saison: "ete"}, + "lyre": {label: "Lyre", lettreFont: 'l', saison: "automne"}, + "serpent": {label: "Serpent", lettreFont: 's', saison: "automne"}, + "poissonacrobate": {label: "Poisson Acrobate", lettreFont: 'p', saison: "automne"}, + "araignee": {label: "Araignée", lettreFont: 'a', saison: "hiver"}, + "roseau": {label: "Roseau", lettreFont: 'r', saison: "hiver"}, + "chateaudormant": {label: "Château Dormant", lettreFont: 'c', saison: "hiver"} + }; +const saisonsDef = { "printemps": { label: "Printemps"}, + "ete": { label: "Eté"}, + "automne": { label: "Automne"}, + "hiver": { label: "Hiver"} + }; +const RDD_JOUR_PAR_MOIS = 28; /* -------------------------------------------- */ export class RdDCalendrier extends Application { - data = { - saisons: [], - }; - - static get defaultOptions() { - const options = super.defaultOptions; - options.template = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html"; - options.popOut = false; - options.resizable = false; - return options; - } - - /*getData() { - return templateData; - }*/ +/* -------------------------------------------- */ + async initCalendrier() { + // Calendrier + this.calendrier = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier")); + console.log("CALENDRIER", this.calendrier); + if ( this.calendrier == undefined || this.calendrier.moisRdD == undefined) { + this.calendrier.heureRdD = 0; // Index dans heuresList + this.calendrier.heuresRelative = 0; + this.calendrier.minutesRelative = 0; + this.calendrier.moisRdD = 0; // Index dans heuresList + this.calendrier.jour = 1; + if ( game.user.isGM) { // Uniquement si GM + game.settings.set("foundryvtt-reve-de-dragon", "calendrier", this.calendrier ); + } + } + // position + this.calendrierPos = duplicate(game.settings.get("foundryvtt-reve-de-dragon", "calendrier-pos")); + if ( this.calendrierPos == undefined || this.calendrierPos.top == undefined) { + this.calendrierPos.top = 200; + this.calendrierPos.left = 200; + if ( game.user.isGM) { // Uniquement si GM + game.settings.set("foundryvtt-reve-de-dragon", "calendrier-pos", this.calendrierPos ); + } + } + console.log(this.calendrier, this.calendrierPos); + } + +/* -------------------------------------------- */ + static get defaultOptions() { + const options = super.defaultOptions; + options.template = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html"; + options.popOut = false; + options.resizable = false; + return options; + } + + /* -------------------------------------------- */ + incrementTime(heure, minute = 0) { + this.calendrier.minutesRelative += minute; + if (this.calendrier.minutesRelative >= 60 ) { + this.calendrier.minutesRelative -= 60; + heure += 1; + } + this.calendrier.heuresRelative += heure; + if (this.calendrier.heuresRelative >= 2) { + this.calendrier.heuresRelative -= 2; + this.calendrier.heureRdD += 1; + } + if ( this.calendrier.heureRdD > 11 ) { + this.calendrier.heureRdD -= 11; + this.calendrier.jour += 1; + } + if ( this.calendrier.jour > RDD_JOUR_PAR_MOIS) { + this.calendrier.jour -= this.calendrier.jour; + if ( this.calendrier.jour <= 0) + this.calendrier.jour = 1; + this.calendrier.moisRdD += 1; + } + game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier) ); + // Notification aux joueurs + game.socket.emit("system.foundryvtt-reve-de-dragon", { + msg: "msg_sync_time", + data: duplicate(this.calendrier) + } ); + + //console.log(this.calendrier, heure, minute); + } + + /* -------------------------------------------- */ + syncPlayerTime( calendrier ) { + this.calendrier = duplicate(calendrier); // Local copy update + this.updateDisplay(); // Then update + } + + /* -------------------------------------------- */ + positionnerHeure( indexHeure ) { + if ( indexHeure <= this.calendrier.heureRdD ) + this.calendrier.jour +=1; + this.calendrier.heureRdD = indexHeure; + this.calendrier.minutesRelative = 0; + this.calendrier.heuresRelative = 0; + game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier) ); + } + + /* -------------------------------------------- */ + fillCalendrierData( data = {} ) { + let moisKey = heuresList[this.calendrier.moisRdD]; + let heureKey = heuresList[this.calendrier.heureRdD]; + //console.log(moisKey, heureKey); + data.heureKey = heureKey; + data.moisKey = moisKey; + data.nomMois = heuresDef[moisKey].label; // heures et mois nommés identiques + data.jourMois = this.calendrier.jour; + data.nomHeure = heuresDef[heureKey].label; + data.nomSaison = saisonsDef[heuresDef[moisKey].saison].label; + data.heuresRelative = this.calendrier.heuresRelative; + data.minutesRelative = this.calendrier.minutesRelative; + data.lettreFont = heuresDef[heureKey].lettreFont; + data.isGM = game.user.isGM; + return data; + } + + /* -------------------------------------------- */ + getData() { + let data = super.getData(); + + this.fillCalendrierData(data); + + this.setPos( this.calendrierPos ); + return data; + } + + /* -------------------------------------------- */ + setPos(pos) { + return new Promise(resolve => { + function check() { + let elmnt = document.getElementById("calendar-time-container"); + if (elmnt) { + elmnt.style.bottom = null; + let xPos = (pos.left) > window.innerWidth ? window.innerWidth-200 : pos.left; + let yPos = (pos.top) > window.innerHeight-20 ? window.innerHeight-100 : pos.top; + elmnt.style.top = (yPos) + "px"; + elmnt.style.left = (xPos) + "px"; + elmnt.style.position = 'fixed'; + elmnt.style.zIndex = 100; + resolve(); + } else { + setTimeout(check, 30); + } + } + check(); + }); + } + + /* -------------------------------------------- */ + updateDisplay() { + let data = this.fillCalendrierData( ); + // Rebuild data + document.getElementById("calendar--move-handle").innerHTML = `Jour ${data.jourMois} de ${data.nomMois} (${data.nomSaison})`; + document.getElementById("calendar-heure-texte").innerHTML = ` - ${data.nomHeure}`; + document.getElementById("calendar-time").innerHTML = `${data.heuresRelative}:${data.minutesRelative}`; + document.getElementById("calendar-icone-heure").innerHTML = data.lettreFont; + } + + /* -------------------------------------------- */ + saveEditeur( calendrierData ) { + this.calendrier.heuresRelative = Number(calendrierData.heuresRelative); + this.calendrier.minutesRelative = Number(calendrierData.minutesRelative); + this.calendrier.jour = Number(calendrierData.jourMois); + this.calendrier.moisRdD = heuresList.findIndex(mois => mois === calendrierData.moisKey); + this.calendrier.heureRdD = heuresList.findIndex(heure => heure === calendrierData.heureKey);; // Index dans heuresList + + game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier) ); + + this.updateDisplay(); + } + + /* -------------------------------------------- */ + async showCalendarEditor() { + let calendrierData = duplicate( this.fillCalendrierData( ) ); + if ( this.editeur == undefined ) { + calendrierData.jourMoisOptions = Array(28).fill().map((item, index) => 1 + index); + calendrierData.heuresOptions = [0, 1]; + calendrierData.minutesOptions = Array(60).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 ) + } + this.editeur.updateData( calendrierData ); + this.editeur.render(true); + } + + /* -------------------------------------------- */ + /** @override */ + activateListeners(html) { + super.activateListeners(html); + + this.updateDisplay(); + + html.find('#calendar-btn-1min').click(ev => { + ev.preventDefault(); + this.incrementTime(0, 1); + this.updateDisplay(); + }); + html.find('#calendar-btn-5min').click(ev => { + ev.preventDefault(); + this.incrementTime(0, 5); + this.updateDisplay(); + }); + html.find('#calendar-btn-10min').click(ev => { + ev.preventDefault(); + this.incrementTime(0, 10); + this.updateDisplay(); + }); + html.find('#calendar-btn-20min').click(ev => { + ev.preventDefault(); + this.incrementTime(0, 20); + this.updateDisplay(); + }); + html.find('#calendar-btn-30min').click(ev => { + ev.preventDefault(); + this.incrementTime(0, 30); + this.updateDisplay(); + }); + html.find('#calendar-btn-1heure').click(ev => { + ev.preventDefault(); + this.incrementTime(2, 0); + this.updateDisplay(); + }); + html.find('#calendar-btn-vaisseau').click(ev => { + ev.preventDefault(); + this.positionnerHeure(0); // 0 -> vaisseau + this.updateDisplay(); + }); + html.find('#calendar-btn-lyre').click(ev => { + ev.preventDefault(); + this.positionnerHeure(6); // 6 -> lyre + this.updateDisplay(); + }); + html.find('#calendar-btn-edit').click(ev => { + ev.preventDefault(); + this.showCalendarEditor(); + }); + + html.find('#calendar--move-handle').mousedown(ev => { + ev.preventDefault(); + ev = ev || window.event; + let isRightMB = false; + if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera + isRightMB = ev.which == 3; + } else if ("button" in ev) { // IE, Opera + isRightMB = ev.button == 2; + } + + if (!isRightMB) { + dragElement(document.getElementById("calendar-time-container")); + let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; + + function dragElement(elmnt) { + elmnt.onmousedown = dragMouseDown; + function dragMouseDown(e) { + e = e || window.event; + e.preventDefault(); + pos3 = e.clientX; + pos4 = e.clientY; + + document.onmouseup = closeDragElement; + document.onmousemove = elementDrag; + } + + function elementDrag(e) { + e = e || window.event; + e.preventDefault(); + // calculate the new cursor position: + pos1 = pos3 - e.clientX; + pos2 = pos4 - e.clientY; + pos3 = e.clientX; + pos4 = e.clientY; + // set the element's new position: + elmnt.style.bottom = null + elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; + elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; + elmnt.style.position = 'fixed'; + elmnt.style.zIndex = 100; + } + + function closeDragElement() { + // stop moving when mouse button is released: + elmnt.onmousedown = null; + document.onmouseup = null; + document.onmousemove = null; + let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth-200 : (elmnt.offsetLeft - pos1); + let yPos = (elmnt.offsetTop - pos2) > window.innerHeight-20 ? window.innerHeight-100 : (elmnt.offsetTop - pos2) + xPos = xPos < 0 ? 0 : xPos; + yPos = yPos < 0 ? 0 : yPos; + if(xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)){ + elmnt.style.top = (yPos) + "px"; + elmnt.style.left = (xPos) + "px"; + } + game.system.rdd.calendrier.calendrierPos.top = yPos; + game.system.rdd.calendrier.calendrierPos.left = xPos; + game.settings.set("foundryvtt-reve-de-dragon", "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos) ); + } + } + } else if(isRightMB){ + game.system.rdd.calendrier.calendrierPos.top = 200; + game.system.rdd.calendrier.calendrierPos.left = 200; + game.settings.set("foundryvtt-reve-de-dragon", "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos) ); + this.setPos(game.system.rdd.calendrier.calendrierPos); + } + }); + } + } \ No newline at end of file diff --git a/module/rdd-main.js b/module/rdd-main.js index 394afcfa..1996179e 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -105,6 +105,8 @@ Hooks.once("init", async function() { rollDataHandler: {}, TMRUtility: TMRUtility } + + /* -------------------------------------------- */ game.settings.register("foundryvtt-reve-de-dragon", "accorder-entite-cauchemar", { name: "Accorder le rêve aux entités", hint: "A quel moment les personnages doivent accorder leur rêve aux entités de cauchemar", @@ -119,13 +121,21 @@ Hooks.once("init", async function() { default: "avant-encaissement" }); - // Create specific settings - // game.settings.register("foundryvtt-reve-de-dragon", "configuration", { - // name: "configuration", - // scope: "world", - // config: false, - // type: Object - // }); + /* -------------------------------------------- */ + game.settings.register("foundryvtt-reve-de-dragon", "calendrier", { + name: "calendrier", + scope: "world", + config: false, + type: Object + }); + /* -------------------------------------------- */ + game.settings.register("foundryvtt-reve-de-dragon", "calendrier-pos", { + name: "calendrierPos", + scope: "world", + config: false, + type: Object + }); + /* -------------------------------------------- */ game.settings.register("foundryvtt-reve-de-dragon", "dice-so-nice", { name: "Montrer les dés pour toutes les jets", hint: "Utilise Dice So Nice pour tous les jets de dés possibles. Décocher pour limiter à la table de résolution", @@ -136,19 +146,19 @@ Hooks.once("init", async function() { }); //game.settings.get("","") to retrieve it and game.settings.set("","", ) - /** - * Set an initiative formula for the system - * @type {String} - */ + /* -------------------------------------------- */ + // Set an initiative formula for the system CONFIG.Combat.initiative = { formula: "1d20", decimals: 2 }; + /* -------------------------------------------- */ game.socket.on("system.foundryvtt-reve-de-dragon", data => { RdDUtility.performSocketMesssage( data ); }); + /* -------------------------------------------- */ // Define custom Entity classes CONFIG.Actor.entityClass = RdDActor; CONFIG.RDD = { @@ -159,6 +169,7 @@ Hooks.once("init", async function() { difficultesLibres : RdDUtility.getDifficultesLibres() } + /* -------------------------------------------- */ // Register sheet application classes Actors.unregisterSheet("core", ActorSheet); Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorSheet, { @@ -209,13 +220,18 @@ Hooks.once("renderApplication", () => { /* Foundry VTT Initialization */ /* -------------------------------------------- */ Hooks.once("ready", function() { - /* Affiche le calendrier */ - //let calendrier = new RdDCalendrier(); - //let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html"; - //let templateData = {}; - /* DISABLEDrenderTemplate(templatePath, templateData).then(html => { + + /* -------------------------------------------- */ + /* Affiche/Init le calendrier */ + let calendrier = new RdDCalendrier(); + calendrier.initCalendrier(); + let templatePath = "systems/foundryvtt-reve-de-dragon/templates/calendar-template.html"; + let templateData = {}; + renderTemplate(templatePath, templateData).then(html => { calendrier.render(true); - } ); */ + } ); + game.system.rdd.calendrier = calendrier; // Reference; + // Avertissement si joueur sans personnage if ( !game.user.isGM && game.user.character == undefined) { ui.notifications.info( "Attention ! Vous n'êtes connecté à aucun personnage !" ); diff --git a/module/rdd-utility.js b/module/rdd-utility.js index f8739ae5..fe0d2cf5 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -179,6 +179,8 @@ export class RdDUtility { 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-natation.html', // Calendrier 'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html', + 'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html', + 'systems/foundryvtt-reve-de-dragon/templates/heures-select-option.html', // Conteneur/item in Actor sheet 'systems/foundryvtt-reve-de-dragon/templates/actor-inventaire-conteneur.html', 'systems/foundryvtt-reve-de-dragon/templates/editor-notes-mj.html' @@ -714,6 +716,8 @@ export class RdDUtility { return RdDUtility._handleMsgDefense(sockmsg.data); case "msg_gm_chat_message": return ChatUtility.handleGMChatMessage(sockmsg.data); + case "msg_sync_time": + return game.system.rdd.calendrier.syncPlayerTime( sockmsg.data ); } }