From c6ed8db2fca1a1a73ea1728f30873666e8b97b46 Mon Sep 17 00:00:00 2001 From: sladecraven Date: Fri, 20 Nov 2020 12:06:54 +0100 Subject: [PATCH] #27 Gestion des rencontres --- module/actor-sheet.js | 58 +++++++++++++---------- module/rdd-tmr-dialog.js | 95 ++++++++++++++++++++++++++++++++++---- module/tmr-utility.js | 50 +++++++++----------- system.json | 2 +- templates/actor-sheet.html | 39 ++++++++-------- 5 files changed, 165 insertions(+), 79 deletions(-) diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 7dc2531d..30072932 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -17,7 +17,8 @@ export class RdDActorSheet extends ActorSheet { width: 640, height: 720, tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac"}], - dragDrop: [{dragSelector: ".item-list .item", dropSelector: null}] + dragDrop: [{dragSelector: ".item-list .item", dropSelector: null}], + editCaracComp: false }); } @@ -104,16 +105,19 @@ export class RdDActorSheet extends ActorSheet { data.data.isGM = game.user.isGM; data.ajustementsConditions = CONFIG.RDD.ajustementsConditions; data.difficultesLibres = CONFIG.RDD.difficultesLibres; + + // Gestion du lock/unlock des zones éditables (carac+compétences) + data.data.editCaracComp = this.options.editCaracComp; + data.data.lockUnlockText = (this.options.editCaracComp) ? "Bloquer" : "Debloquer"; // low is normal, this the base used to compute the grid. data.data.fatigue = { malus: RdDUtility.calculMalusFatigue(data.data.sante.fatigue.value, data.data.sante.endurance.max), html: "" + RdDUtility.makeHTMLfatigueMatrix( data.data.sante.fatigue.value, data.data.sante.endurance.max ).html() + "
" } - - RdDUtility.filterItemsPerTypeForSheet(data ); - data.data.sortReserve = data.data.reve.reserve.list; + RdDUtility.filterItemsPerTypeForSheet(data ); + data.data.sortReserve = data.data.reve.reserve.list; RdDUtility.buildArbreDeConteneur( this, data ); return data; @@ -267,20 +271,32 @@ export class RdDActorSheet extends ActorSheet { item.sheet.render(true); }); - // On carac change - html.find('.carac-value').change((event) => { - let caracName = event.currentTarget.name.replace(".value", "").replace("data.carac.", ""); - //console.log("Value changed :", event, caracName); - this.actor.updateCarac( caracName, parseInt(event.target.value) ); - } ); - - // On competence change - html.find('.competence-value').change((event) => { - let compName = event.currentTarget.attributes.compname.value; - //console.log("Competence changed :", compName); - this.actor.updateCompetence( compName, parseInt(event.target.value) ); - } ); - + if (this.options.editCaracComp) { + // On carac change + html.find('.carac-value').change((event) => { + let caracName = event.currentTarget.name.replace(".value", "").replace("data.carac.", ""); + //console.log("Value changed :", event, caracName); + this.actor.updateCarac( caracName, parseInt(event.target.value) ); + } ); + // On competence change + html.find('.competence-value').change((event) => { + let compName = event.currentTarget.attributes.compname.value; + //console.log("Competence changed :", compName); + this.actor.updateCompetence( compName, parseInt(event.target.value) ); + } ); + // On competence xp change + html.find('.competence-xp').change((event) => { + let compName = event.currentTarget.attributes.compname.value; + this.actor.updateCompetenceXP( compName, parseInt(event.target.value) ); + } ); + } + + // Gestion du bouton lock/unlock + html.find('.lock-unlock-sheet a').click((event) => { + this.options.editCaracComp = !this.options.editCaracComp; + this.render(true); + }); + // On pts de reve change html.find('.pointsreve-value').change((event) => { let reveValue = event.currentTarget.value; @@ -295,12 +311,6 @@ export class RdDActorSheet extends ActorSheet { this.actor.setPointsDeSeuil(event.currentTarget.value); } ); - // On competence xp change - html.find('.competence-xp').change((event) => { - let compName = event.currentTarget.attributes.compname.value; - this.actor.updateCompetenceXP( compName, parseInt(event.target.value) ); - } ); - // On stress change html.find('.compteur-edit').change((event) => { let fieldName = event.currentTarget.attributes.name.value; diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index e3ee7e84..bfcd3f7f 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -46,6 +46,7 @@ export class RdDTMRDialog extends Dialog { this.rencontresExistantes = duplicate(this.actor.data.data.reve.rencontre.list); this.sortReserves = duplicate(this.actor.data.data.reve.reserve.list); this.allTokens = []; + this.rencontreState = "aucune"; this.pixiApp = new PIXI.Application({ width: 720, height: 860 }); } @@ -101,6 +102,44 @@ export class RdDTMRDialog extends Dialog { console.log("-> refouler", this.currentRencontre) this.updateValuesDisplay(); } + + /* -------------------------------------------- */ + colorierZone( locList) { + this.currentRencontre.graphics = []; // Keep track of rectangles to delete it + this.currentRencontre.locList = duplicate(locList); // And track of allowed location + for (let loc of locList) { + let rect = this._getCaseRectangleCoord( loc); + var rectDraw = new PIXI.Graphics(); + rectDraw.beginFill(0xFFFF00, 0.3); + // set the line style to have a width of 5 and set the color to red + rectDraw.lineStyle(5, 0xFF0000); + // draw a rectangle + rectDraw.drawRect(rect.x, rect.y, rect.w, rect.h); + this.pixiApp.stage.addChild(rectDraw); + this.currentRencontre.graphics.push(rectDraw); // garder les objets pour gestion post-click + } + } + + /* -------------------------------------------- */ + /** Gère les rencontres avec du post-processing graphique (passeur, messagers, tourbillons, ...) */ + rencontrePostProcess( rencontreData) { + if (!rencontreData) return; // Sanity check + this.rencontreState = rencontreData.state; // garder la trace de l'état en cours + if ( this.rencontreState == "passeur") { + console.log("Processing passeur"); + // Récupère la liste des cases à portées + let locList = TMRUtility.getTMRArea(this.actor.data.data.reve.tmrpos.coord, this.currentRencontre.force, tmrConstants ); + this.colorierZone( locList ); + } else if ( this.rencontreState == "messager") { + console.log("Processing messager"); + // Récupère la liste des cases à portées + let locList = TMRUtility.getTMRArea(this.actor.data.data.reve.tmrpos.coord, this.currentRencontre.force, tmrConstants ); + this.colorierZone( locList ); + } else { + this.currentRencontre = undefined; // Cleanup, not used anymore + } + } + /* -------------------------------------------- */ async maitriser(data) { this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary @@ -117,16 +156,22 @@ export class RdDTMRDialog extends Dialog { let message = "
Test : Rêve actuel / " + draconic.name + " / " + this.currentRencontre.name + "" + "
" + RdDResolutionTable.explain(rolled); + let rencontreData if (rolled.isEchec) { - message += await TMRUtility.processRencontreEchec(this.actor, this.currentRencontre, rolled, this); + rencontreData = await TMRUtility.processRencontreEchec(this.actor, this.currentRencontre, rolled, this); + message += rencontreData.message; this._tellToUser("Vous avez échoué à maîtriser un " + this.currentRencontre.name + " de force " + this.currentRencontre.force + "
Vous quittez brutalement les Terres Médianes !" + message); if (this.currentRencontre.data.quitterTMR) // Selon les rencontres, quitter TMR ou pas this.close(); } else { - message += await TMRUtility.processRencontreReussite(this.actor, this.currentRencontre, rolled); + rencontreData = await TMRUtility.processRencontreReussite(this.actor, this.currentRencontre, rolled); + message += rencontreData.message; this._tellToUser("Vous avez réussi à maîtriser un " + this.currentRencontre.name + " de force " + this.currentRencontre.force + message); } + + this.rencontrePostProcess( rencontreData ); + console.log("-> matriser", this.currentRencontre); this.updateValuesDisplay(); } @@ -154,7 +199,7 @@ export class RdDTMRDialog extends Dialog { rencontre = await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr); } } - //rencontre = await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr); To test + rencontre = await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr); if (rencontre) { // Manages it if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres @@ -276,6 +321,19 @@ export class RdDTMRDialog extends Dialog { } } + /* -------------------------------------------- */ + processClickPostRencontre( coord ) { + let deplacementType = "erreur"; + if (this.rencontreState == "passeur" || this.rencontreState == "messager") { + let isInArea = this.currentRencontre.locList.find(locCoord => locCoord == coord ); + if ( isInArea ) { // OK ! + deplacementType = "saut"; + + } + + } + } + /* -------------------------------------------- */ async deplacerDemiReve(event) { if (this.viewOnly) { @@ -288,12 +346,19 @@ export class RdDTMRDialog extends Dialog { let cellx = eventCoord.cellx; let celly = eventCoord.celly; console.log("deplacerDemiReve >>>>", cellx, celly); - let currentPos = TMRUtility.convertToCellCoord(myself.actor.data.data.reve.tmrpos.coord); - - if (RdDTMRDialog._horsDePortee(currentPos, cellx, celly)) { - ui.notifications.error("Vous ne pouvez vous déplacer que sur des cases adjacentes à votre position"); + + // Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter) + let deplacementType = "erreur"; + if ( this.rencontreState == "aucune") { // Pas de recontre en post-processing, donc deplacement normal + if ( !RdDTMRDialog._horsDePortee(currentPos, cellx, celly)) { + deplacementType = "normal"; + } } else { + deplacementType = this.processClickPostRencontre( currentPos ); + } + // Si le deplacement est valide + if ( deplacementType == "normal" || deplacementType == "saut") { let coordTMR = TMRUtility.convertToTMRCoord(cellx, celly); let cellDescr = TMRUtility.getTMRDescription(coordTMR); @@ -306,9 +371,13 @@ export class RdDTMRDialog extends Dialog { myself.nbFatigue += 1; myself.updateValuesDisplay(); - myself.manageRencontre(coordTMR, cellDescr); + if ( deplacementType == "normal") { // Pas de rencontres après un saut de type passeur/changeur/... + myself.manageRencontre(coordTMR, cellDescr); + } myself.manageCaseHumide(cellDescr); await myself.declencheSortEnReserve(coordTMR); + } else { + ui.notifications.error("Vous ne pouvez vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre"); } } @@ -448,6 +517,16 @@ export class RdDTMRDialog extends Dialog { myself._setTokenPosition(myself.demiReve); } + /* -------------------------------------------- */ + /** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */ + _getCaseRectangleCoord( coord ) { + let coordXY = TMRUtility.convertToCellCoord( coord ); + let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; + let x = tmrConstants.gridx + (coordXY.x * tmrConstants.cellw) - (tmrConstants.cellw /2); + let y = tmrConstants.gridy + (coordXY.y * tmrConstants.cellh) - (tmrConstants.cellh /2) + decallagePairImpair; + return {x: x, y: y, w: tmrConstants.cellw, h: tmrConstants.cellh} + } + /* -------------------------------------------- */ _setTokenPosition(token) { let coordXY = TMRUtility.convertToCellCoord(token.coordTMR()); diff --git a/module/tmr-utility.js b/module/tmr-utility.js index 5620bdb0..c859df14 100644 --- a/module/tmr-utility.js +++ b/module/tmr-utility.js @@ -240,23 +240,9 @@ const rencontresTable = [ lac: "98-00", marais: "98-00", gouffre: "98-00", necropole: "98-00", desolation: "98-00" } } ] -/* -------------------------------------------- */ -const tmrConstants = { - col1_y: 30, - col2_y: 55, - cellw: 55, - cellh: 55, - gridx: 28, - gridy: 28 -} - /* -------------------------------------------- */ export class TMRUtility { - static getTMRConstants() { - return tmrConstants; - } - /* -------------------------------------------- */ static convertToTMRCoord( x, y ) { @@ -290,9 +276,9 @@ export class TMRUtility { rencontre.coord = coordTMR; } // Forced - //rencontre = rencontresTable[4]; - //rencontre.force = 11; - //rencontre.coord = coordTMR; + rencontre = rencontresTable[0]; + rencontre.force = 1; + rencontre.coord = coordTMR; return rencontre; } @@ -379,13 +365,17 @@ export class TMRUtility { /* -------------------------------------------- */ static async processRencontreReussite( actor, rencontre, rolled ) { let msg = "
"; + let state = "aucune"; + console.log("processRencontreReussite", actor, rencontre); if (rencontre.name == "Messagers des Rêves") { msg += "Le Messager des Rêves vous permet de lancer votre sort à XX cases !"; + state = "messager"; } else if (rencontre.name == "Passeur des Rêves") { - msg += "Le Passeur des Rêves vous téléporte sur une case à XX !"; - + msg += "Le Passeur des Rêves vous permet de vous téléporter à " + rencontre.force + " cases !"; + state = "passeur"; + } else if (rencontre.name == "Fleur des Rêves") { await actor.updatePointsDeReve( rencontre.force ); msg += "La Fleur des rêves s'évanouit en vous fournissant " + rencontre.force + " Points de Rêve"; @@ -419,13 +409,14 @@ export class TMRUtility { msg += "Vous maîtrisez le Rêve de Dragon !" msg += actor.appliquerReveDeDragon(rolled, rencontre.force); } - return msg; + return { msg: msg, state: state }; } /* -------------------------------------------- */ static async processRencontreEchec( actor, rencontre, rolled, tmrDialog ) { let msg = "
"; - + let state = "aucune"; + if (rencontre.name == "Messagers des Rêves") { msg += "Le Messager des Rêves s'éloigne de vous !"; @@ -453,18 +444,21 @@ export class TMRUtility { } else if (rencontre.name == "Reflet d'ancien Rêve") { msg += "Votre Rêve est Brisé, vous quittez les Terres Médianes"; - + state = "reflet" + } else if (rencontre.name == "Tourbillon blanc") { msg += "Votre Rêve est Brisé, vous quittez les Terres Médianes"; - + state = "tourbillonblanc"; + } else if (rencontre.name == "Tourbillon noir") { msg += "Votre Rêve est Brisé, vous quittez les Terres Médianes"; + state = "tourbillonnoir"; } else if (rencontre.name == "Rêve de Dragon") { msg += "Le Rêve de Dragon tourne au cauchemar !" msg += actor.appliquerReveDeDragon(rolled, rencontre.force); } - return msg; + return { msg: msg, state: state }; } /* -------------------------------------------- */ @@ -502,7 +496,7 @@ export class TMRUtility { } /* -------------------------------------------- */ - static computeRealPictureCoordinates( coordXY ) { + static computeRealPictureCoordinates( coordXY, tmrConstants ) { let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; return { x: tmrConstants.gridx + (coordXY.x * tmrConstants.cellw), @@ -514,15 +508,15 @@ export class TMRUtility { /** Returns a list of case inside a given distance * */ - static getTMRArea( coord, distance ) { + static getTMRArea( coord, distance, tmrConstants ) { let pos = this.convertToCellCoord( coord ); - let posPic = this.computeRealPictureCoordinates( pos ); + let posPic = this.computeRealPictureCoordinates( pos, tmrConstants ); let caseList = []; for (let x=pos.x-distance; x<=pos.x+distance; x++ ) { // Loop thru lines for (let y=pos.y-distance; y<=pos.y+distance; y++ ) { // Loop thru lines //console.log("Parsing position", x, y); if ( this._checkTMRCoord(x, y) ) { // Coordinate is valie - let posPicNow = this.computeRealPictureCoordinates( {x: x, y: y} ); + let posPicNow = this.computeRealPictureCoordinates( {x: x, y: y}, tmrConstants ); let dist = Math.sqrt(Math.pow(posPicNow.x - posPic.x,2) + Math.pow(posPicNow.y - posPic.y, 2)) / tmrConstants.cellw; if ( dist < distance+0.5) { caseList.push( this.convertToTMRCoord(x, y) ); // Inside the area diff --git a/system.json b/system.json index b76de95f..db9cdc7d 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "name": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", "description": "Rêve de Dragon RPG for FoundryVTT", - "version": "0.9.63", + "version": "0.9.64", "minimumCoreVersion": "0.7.5", "compatibleCoreVersion": "0.7.6", "templateVersion": 47, diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 1c1f2269..9ff01c19 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -35,6 +35,9 @@ {{{data.fatigue.html}}} +
+ {{data.lockUnlockText}} +
@@ -75,8 +78,8 @@ {{#if carac.derivee}} {{else}} - - + + {{/if}} {{/each}} @@ -115,8 +118,8 @@
  • {{comp.name}} - - + +
    @@ -133,8 +136,8 @@
  • {{comp.name}} - - + +
    @@ -150,8 +153,8 @@
  • {{comp.name}} - - + +
    @@ -170,8 +173,8 @@
  • {{comp.name}} - - + +
    @@ -188,8 +191,8 @@
  • {{comp.name}} - - + +
    @@ -206,8 +209,8 @@
  • {{comp.name}} - - + +
    @@ -224,8 +227,8 @@
  • {{comp.name}} - - + +
    @@ -242,8 +245,8 @@
  • {{comp.name}} - - + +