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}}}
+