Amélioration rencontre TMR

- mise en forme des messages
- Ajout de messages poétiques
- regroupement par rencontre de la gestion et des messages
- séparation table de proba/type de rencontre
- quelques fixes lors de tests (mes régressions?)
- lors d'un déplacement avec un tourbillon, on n'a pas à vaincre les
cases humides
- pas de rencontre après un déplacement par une rencontre
This commit is contained in:
Vincent Vandemeulebrouck
2021-01-29 15:13:59 +01:00
parent df996695e4
commit 66dff68daf
10 changed files with 865 additions and 517 deletions

View File

@ -2,21 +2,14 @@
* Extend the base Dialog entity by defining a custom window to perform spell.
* @extends {Dialog}
*/
import { RollDataAjustements } from "./rolldata-ajustements.js";
import { RdDUtility } from "./rdd-utility.js";
import { TMRUtility } from "./tmr-utility.js";
import { RdDRollTables } from "./rdd-rolltables.js";
import { tmrConstants } from "./tmr-utility.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js";
/* -------------------------------------------- */
const tmrConstants = {
col1_y: 30,
col2_y: 55,
cellw: 55,
cellh: 55,
gridx: 28,
gridy: 28
}
import { TMRRencontres } from "./tmr-rencontres.js";
import { ChatUtility } from "./chat-utility.js";
/* -------------------------------------------- */
export class RdDTMRDialog extends Dialog {
@ -46,22 +39,22 @@ export class RdDTMRDialog extends Dialog {
this.nbFatigue = this.viewOnly ? 0 : 1; // 1 premier point de fatigue du à la montée
this.rencontresExistantes = duplicate(this.actor.data.data.reve.rencontre.list);
this.sortReserves = duplicate(this.actor.data.data.reve.reserve.list);
this.casesSpeciales = this.actor.data.items.filter( item => item.type == 'casetmr');
this.casesSpeciales = this.actor.data.items.filter(item => item.type == 'casetmr');
this.allTokens = [];
this.rencontreState = 'aucune';
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
if (!this.viewOnly){
if (!this.viewOnly) {
this.actor.setStatusDemiReve(true);
this._tellToGM(this.actor.name + " monte dans les terres médianes (" + mode + ")");
}
}
/* -------------------------------------------- */
close() {
this.actor.santeIncDec("fatigue", this.nbFatigue).then(super.close()); // moving 1 cell costs 1 fatigue
this.actor.tmrApp = undefined; // Cleanup reference
this.actor.setStatusDemiReve(false);
if (! this.viewOnly) {
if (!this.viewOnly) {
this._tellToGM(this.actor.name + " a quitté les terres médianes");
}
}
@ -78,14 +71,14 @@ export class RdDTMRDialog extends Dialog {
displaySpecificCase() {
for (let caseTMR of this.casesSpeciales) {
console.log("SPEC CASE ", caseTMR);
if ( caseTMR.data.specific == 'trounoir') {
this._trackToken(this._tokenTrouNoir( caseTMR.data.coord ));
} else if ( caseTMR.data.specific == 'attache') {
this._trackToken(this._tokenTerreAttache( caseTMR.data.coord ));
} else if ( caseTMR.data.specific == 'debordement') {
this._trackToken(this._tokenDebordement( caseTMR.data.coord ));
} else if ( caseTMR.data.specific == 'maitrisee') {
this._trackToken(this._tokenMaitrisee( caseTMR.data.coord ));
if (caseTMR.data.specific == 'trounoir') {
this._trackToken(this._tokenTrouNoir(caseTMR.data.coord));
} else if (caseTMR.data.specific == 'attache') {
this._trackToken(this._tokenTerreAttache(caseTMR.data.coord));
} else if (caseTMR.data.specific == 'debordement') {
this._trackToken(this._tokenDebordement(caseTMR.data.coord));
} else if (caseTMR.data.specific == 'maitrisee') {
this._trackToken(this._tokenMaitrisee(caseTMR.data.coord));
}
}
}
@ -120,10 +113,10 @@ export class RdDTMRDialog extends Dialog {
this.close();
}
/* -------------------------------------------- */
async refouler(data) {
this._tellToGM(this.actor.name + " a refoulé : " + this.currentRencontre.name );
async refouler() {
this._tellToGM(this.actor.name + " a refoulé : " + this.currentRencontre.name);
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
let result = await this.actor.ajouterRefoulement( this.currentRencontre.data.refoulement );
await this.actor.ajouterRefoulement(this.currentRencontre.refoulement ?? 1);
this.updatePreviousRencontres();
console.log("-> refouler", this.currentRencontre)
this.updateValuesDisplay();
@ -131,11 +124,20 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
colorierZoneRencontre( locList) {
async ignorerRencontre() {
this._tellToGM(this.actor.name + " a ignoré : " + this.currentRencontre.name);
await this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
this.updatePreviousRencontres();
this.updateValuesDisplay();
this.nettoyerRencontre();
}
/* -------------------------------------------- */
colorierZoneRencontre(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);
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
@ -148,132 +150,118 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async gererTourbillon( value ) {
this.nbFatigue += 1;
await this.actor.reveActuelIncDec( -value );
if ( !this.currentRencontre.tourbillonDirection ) {
this.currentRencontre.tourbillonDirection = TMRUtility.getDirectionPattern();
}
let tmrPos = this.actor.data.data.reve.tmrpos;
tmrPos.coord = TMRUtility.deplaceTMRSelonPattern( tmrPos.coord, this.currentRencontre.tourbillonDirection, value );
await this.actor.update({ "data.reve.tmrpos": tmrPos });
console.log("NEWPOS", tmrPos);
// garder la trace de l'état en cours
setStateRencontre(state) {
this.rencontreState = state;
}
/* -------------------------------------------- */
async gererTourbillonRouge( ) {
this.nbFatigue += 1;
await this.actor.reveActuelIncDec( -2 ); // -2 pts de Reve a chaque itération
if ( !this.currentRencontre.tourbillonDirection ) {
this.currentRencontre.tourbillonDirection = TMRUtility.getDirectionPattern();
}
let tmrPos = this.actor.data.data.reve.tmrpos;
tmrPos.coord = TMRUtility.deplaceTMRSelonPattern( tmrPos.coord, this.currentRencontre.tourbillonDirection, 4 ); // Depl. 4 cases.
await this.actor.update({ "data.reve.tmrpos": tmrPos });
await this.actor.santeIncDec( "vie", -1); // Et -1 PV
console.log("TOURBILLON ROUGE", tmrPos);
async choisirCasePortee(coord, portee) {
// Récupère la liste des cases à portées
let locList = TMRUtility.getTMRPortee(coord, portee);
this.colorierZoneRencontre(locList);
}
/* -------------------------------------------- */
/** Gère les rencontres avec du post-processing graphique (passeur, messagers, tourbillons, ...) */
async rencontrePostProcess( rencontreData) {
if (!rencontreData) return; // Sanity check
this.rencontreState = rencontreData.state; // garder la trace de l'état en cours
let locList
if ( this.rencontreState == 'passeur' || this.rencontreState == 'messager' ) {
// Récupère la liste des cases à portées
locList = TMRUtility.getTMRArea(this.actor.data.data.reve.tmrpos.coord, this.currentRencontre.force, tmrConstants );
} else if ( this.rencontreState == 'passeurfou' ) { // Cas spécial du passeur fou
let sortReserve = this.actor.data.data.reve.reserve[0];
let tmrPos
if ( sortReserve ) {
tmrPos = sortReserve.coord; // Passeur fou positionne sur la case d'un ort en réserve (TODO : Choisir le plus loin)
} else {
let direction = TMRUtility.getDirectionPattern(); // Déplacement aléatoire de la force du Passeur Fou
tmrPos = TMRUtility.deplaceTMRSelonPattern(this.actor.data.data.reve.tmrpos.coord, direction, this.currentRencontre.force );
}
await this.actor.update({ "data.reve.tmrpos": tmrPos });
} else if ( this.rencontreState == 'changeur' ) {
// Liste des cases de même type
locList = TMRUtility.getLocationTypeList( this.actor.data.data.reve.tmrpos.coord );
} else if ( this.rencontreState == 'reflet' ) {
this.nbFatigue += 1;
} else if ( this.rencontreState == 'tourbillonblanc' ) {
await this.gererTourbillon(1);
} else if ( this.rencontreState == 'tourbillonnoir' ) {
await this.gererTourbillon(2);
} else if ( this.rencontreState == 'tourbillonrouge' ) {
await this.gererTourbillonRouge();
} else {
this.currentRencontre = undefined; // Cleanup, not used anymore
}
if ( locList )
this.colorierZoneRencontre( locList );
async choisirCaseType(type) {
const locList = TMRUtility.getListCoordTMR(type);
this.colorierZoneRencontre(locList);
}
/* -------------------------------------------- */
checkQuitterTMR() {
if ( this.actor.data.data.reve.reve.value == 0) {
this._tellToGM("Vos Points de Rêve sont à 0 : vous quittez les Terres médianes !");
if (this.actor.isDead()) {
this._tellToGM("Vous êtes mort : vous quittez les Terres médianes !");
this.close();
return true;
}
if ( this.nbFatigue == this.actor.data.data.sante.fatigue.max ) {
const resteAvantInconscience = this.actor.getFatigueMax() - this.actor.getFatigueActuelle() - this.nbFatigue;
if (resteAvantInconscience <= 0) {
this._tellToGM("Vous vous écroulez de fatigue : vous quittez les Terres médianes !");
this.close();
this.quitterLesTMRInconscient();
return true;
}
if ( this.actor.data.data.sante.vie.value == 0 ) {
this._tellToGM("Vous n'avez plus de Points de Vie : vous quittez les Terres médianes !");
this.close();
if (this.actor.getReveActuel() == 0) {
this._tellToGM("Vos Points de Rêve sont à 0 : vous quittez les Terres médianes !");
this.quitterLesTMRInconscient();
return true;
}
return false;
}
async quitterLesTMRInconscient() {
if (this.currentRencontre?.isPersistant) {
await this.refouler();
}
this.close();
}
/* -------------------------------------------- */
async maitriser(data) {
this.actor.deleteTMRRencontreAtPosition(); // Remove the stored rencontre if necessary
async maitriser() {
this.actor.deleteTMRRencontreAtPosition();
this.updatePreviousRencontres();
const draconic = this.actor.getBestDraconic();
const carac = this.actor.getReveActuel();
const etatGeneral = this.actor.getEtatGeneral();
const difficulte = draconic.data.niveau - this.currentRencontre.force + etatGeneral;
console.log("Maitriser", carac, draconic.data.niveau, this.currentRencontre.force, etatGeneral);
let rolled = await RdDResolutionTable.roll(carac, difficulte);
let message = "<br><strong>Test : Rêve actuel / " + draconic.name + " / " + this.currentRencontre.name + "</strong>" + "<br>"
+ RdDResolutionTable.explain(rolled);
let rencontreData
if (rolled.isEchec) {
rencontreData = await TMRUtility.processRencontreEchec(this.actor, this.currentRencontre, rolled, this);
message += rencontreData.message;
this._tellToGM("Vous avez <strong>échoué</strong> à maîtriser un " + this.currentRencontre.name + " de force " + this.currentRencontre.force + message);
if (this.currentRencontre.data.quitterTMR) { // Selon les rencontres, quitter TMR ou pas
this.close();
}
} else {
rencontreData = await TMRUtility.processRencontreReussite(this.actor, this.currentRencontre, rolled);
message += rencontreData.message;
this._tellToGM("Vous avez <strong>réussi</strong> à maîtriser un " + this.currentRencontre.name + " de force " + this.currentRencontre.force + message);
let rencontreData = {
actor: this.actor,
alias: this.actor.name,
reveDepart: this.actor.getReveActuel(),
competence: this.actor.getBestDraconic(),
rencontre: this.currentRencontre,
nbRounds: 1,
tmr: TMRUtility.getTMR(this.actor.data.data.reve.tmrpos.coord)
}
await this.rencontrePostProcess( rencontreData );
await this._tentativeMaitrise(rencontreData);
}
async _tentativeMaitrise(rencontreData) {
console.log("-> matriser", rencontreData);
rencontreData.reve = this.actor.getReveActuel();
rencontreData.etat = this.actor.getEtatGeneral();
RollDataAjustements.calcul(rencontreData, this.actor);
rencontreData.rolled = await RdDResolutionTable.roll(rencontreData.reve, RollDataAjustements.sum(rencontreData.ajustements));
let postProcess = await TMRRencontres.gererRencontre(this, rencontreData);
ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencontreData)
});
if (postProcess) {
/** Gère les rencontres avec du post-processing (passeur, messagers, tourbillons, ...) */
await postProcess(this, rencontreData);
}
else {
this.currentRencontre = undefined;
}
console.log("-> matriser", this.currentRencontre);
this.updateValuesDisplay();
this.checkQuitterTMR();
if ( this.rencontreState == 'reflet' || this.rencontreState == 'tourbillonblanc' || this.rencontreState == 'tourbillonnoir' )
this.maitriser();
if (this.checkQuitterTMR()) {
return;
}
else if (rencontreData.rolled.isEchec && rencontreData.rencontre.isPersistant) {
setTimeout(() => {
rencontreData.nbRounds++;
this.nbFatigue += 1;
this._tentativeMaitrise(rencontreData);
setTimeout(() => this._deleteTmrMessages(rencontreData.actor, rencontreData.nbRounds), 500);
}, 2000);
}
}
_deleteTmrMessages(actor, nbRounds = -1) {
if (nbRounds < 0) {
ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}"`);
}
else {
for (let i = 1; i < nbRounds; i++) {
ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}" data-rencontre-round="${i}">`);
}
}
}
/* -------------------------------------------- */
@ -285,7 +273,7 @@ export class RdDTMRDialog extends Dialog {
_tellToGM(message) {
ChatMessage.create({ content: message, user: game.user._id, whisper: ChatMessage.getWhisperRecipients("GM") });
}
/* -------------------------------------------- */
async manageRencontre(coordTMR, cellDescr) {
if (this.viewOnly) {
@ -293,7 +281,7 @@ export class RdDTMRDialog extends Dialog {
}
this.currentRencontre = undefined;
let rencontre = await this._jetDeRencontre(coordTMR, cellDescr);
if (rencontre) { // Manages it
if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres
console.log("manageRencontre", rencontre);
@ -306,21 +294,19 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async _jetDeRencontre(coordTMR, cellDescr) {
let rencontre = this.rencontresExistantes.find(prev => prev.coord == coordTMR);
if (rencontre == undefined) {
let myRoll = new Roll("1d7").roll();
if (myRoll.total == 7) {
let isSpecial = this.actor.isRencontreSpeciale();
rencontre = await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr, isSpecial );
} else {
this._tellToUser(myRoll.total + ": Pas de rencontre en " + cellDescr.label + " (" + coordTMR + ")");
}
}
if (TMRUtility.isForceRencontre()) {
return await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr);
}
return rencontre;
let rencontre = this.rencontresExistantes.find(prev => prev.coord == coordTMR);
if (rencontre) {
return rencontre;
}
let myRoll = new Roll("1d7").evaluate();
if (myRoll.total == 7) {
let isMauvaise = this.actor.isRencontreSpeciale();
return await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr, isMauvaise);
}
this._tellToUser(myRoll.total + ": Pas de rencontre en " + cellDescr.label + " (" + coordTMR + ")");
}
/* -------------------------------------------- */
@ -329,7 +315,7 @@ export class RdDTMRDialog extends Dialog {
ptsreve.innerHTML = this.actor.data.data.reve.reve.value;
let tmrpos = document.getElementById("tmr-pos");
let tmr = TMRUtility.getTMRDescription(this.actor.data.data.reve.tmrpos.coord);
let tmr = TMRUtility.getTMR(this.actor.data.data.reve.tmrpos.coord);
tmrpos.innerHTML = this.actor.data.data.reve.tmrpos.coord + " (" + tmr.label + ")";
let etat = document.getElementById("tmr-etatgeneral-value");
@ -344,26 +330,27 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async manageCaseSpeciale( cellDescr, coordTMR ) {
for( let caseTMR of this.casesSpeciales) {
async manageCaseSpeciale(cellDescr, coordTMR) {
for (let caseTMR of this.casesSpeciales) {
if (caseTMR.data.coord == coordTMR) { // Match !
if (caseTMR.data.specific == 'trounoir') {
let newTMR = TMRUtility.getTMRAleatoire();
let tmrPos = duplicate(this.actor.data.data.reve.tmrpos);
tmrPos.coord = newTMR;
await this.actor.update( { "data.reve.tmrpos": tmrPos } );
ChatMessage.create( {
tmrPos.coord = newTMR;
await this.actor.update({ "data.reve.tmrpos": tmrPos });
ChatMessage.create({
content: "Vous êtes rentré sur un Trou Noir : ré-insertion aléatoire.",
whisper: ChatMessage.getWhisperRecipients(game.user.name) } );
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
}
}
}
}
/* -------------------------------------------- */
isCaseMaitrisee( coordTMR) {
for( let caseTMR of this.casesSpeciales) {
if (caseTMR.data.coord == coordTMR && caseTMR.data.specific == 'maitrisee') {
isCaseMaitrisee(coordTMR) {
for (let caseTMR of this.casesSpeciales) {
if (caseTMR.data.coord == coordTMR && caseTMR.data.specific == 'maitrisee') {
return true;
}
}
@ -378,15 +365,16 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async manageCaseHumide(cellDescr, coordTMR) {
if (this.viewOnly) {
if (this.viewOnly || this.currentRencontre) {
return;
}
let isHumide = this.actor.checkIsAdditionnalHumide(cellDescr, coordTMR);
if (cellDescr.type == "lac" || cellDescr.type == "fleuve" || cellDescr.type == "marais" || isHumide) {
if ( this.isCaseMaitrisee( coordTMR ) ) {
ChatMessage.create( {
if (this.isCaseMaitrisee(coordTMR)) {
ChatMessage.create({
content: "Cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>",
whisper: ChatMessage.getWhisperRecipients(game.user.name) } );
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
return;
}
// TODO: permettre de choisir la voie de draconic?
@ -396,11 +384,11 @@ export class RdDTMRDialog extends Dialog {
const etatGeneral = this.actor.getEtatGeneral();
let difficulte = draconic.data.niveau - 7;
let rolled = await RdDResolutionTable.roll(carac, difficulte);
// Gestion du souffle Double Résistance du Fleuve
if ( this.actor.isDoubleResistanceFleuve() ) {
if (this.actor.isDoubleResistanceFleuve()) {
let rolled2 = await RdDResolutionTable.roll(carac, difficulte);
if (rolled2.isEchec)
if (rolled2.isEchec)
rolled = rolled;
}
console.log("manageCaseHumide >>", rolled);
@ -420,18 +408,18 @@ export class RdDTMRDialog extends Dialog {
+ RdDResolutionTable.explain(rolled);
if (rolled.isETotal) {
let souffle = await this.actor.ajouterSouffle({chat: false});
let souffle = await this.actor.ajouterSouffle({ chat: false });
explication += "<br>Vous avez fait un Echec Total. Vous subissez un Souffle de Dragon : " + souffle.name;
msg2MJ += "<br>Et a reçu un Souffle de Dragon : " + souffle.name;
}
if (rolled.isPart) {
explication += "<br>Vous avez fait une Réussite Particulière";
this.actor._appliquerAjoutExperience({ rolled: rolled, seletedCarac: { label: 'reve'}, competence: draconic.name })
this.actor._appliquerAjoutExperience({ rolled: rolled, seletedCarac: { label: 'reve' }, competence: draconic.name })
msg2MJ += "<br>Et a fait une réussite particulière";
}
// Notification au MJ
ChatMessage.create( { content: msg2MJ, whisper: ChatMessage.getWhisperRecipients("GM") } );
ChatMessage.create({ content: msg2MJ, whisper: ChatMessage.getWhisperRecipients("GM") });
// Et au joueur (ca pourrait être un message de tchat d'ailleurs)
let humideDiag = new Dialog({
title: "Case humide",
@ -445,9 +433,9 @@ export class RdDTMRDialog extends Dialog {
}
}
/* -------------------------------------------- */
isReserveExtensible( coordTMR) {
for( let caseTMR of this.casesSpeciales) {
if (caseTMR.data.specific == 'reserve_extensible' && caseTMR.data.coord == coordTMR )
isReserveExtensible(coordTMR) {
for (let caseTMR of this.casesSpeciales) {
if (caseTMR.data.specific == 'reserve_extensible' && caseTMR.data.coord == coordTMR)
return true;
}
return false;
@ -458,55 +446,57 @@ export class RdDTMRDialog extends Dialog {
if (this.viewOnly) {
return;
}
let sortReserveList = TMRUtility.getSortReserveList( this.sortReserves, coordTMR );
if (sortReserveList.length > 0 ) {
if ( this.actor.isReserveEnSecurite() || this.isReserveExtensible(coordTMR) ) {
let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>";
let sortReserveList = TMRUtility.getSortReserveList(this.sortReserves, coordTMR);
if (sortReserveList.length > 0) {
if (this.actor.isReserveEnSecurite() || this.isReserveExtensible(coordTMR)) {
let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>";
for (let sortReserve of sortReserveList) {
msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='"+this.actor._id+"' data-tmr-coord='"+coordTMR+"' data-sort-id='"+sortReserve.sort._id+"'>"+sortReserve.sort.name+"</a></li>";
msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='" + this.actor._id + "' data-tmr-coord='" + coordTMR + "' data-sort-id='" + sortReserve.sort._id + "'>" + sortReserve.sort.name + "</a></li>";
}
msg += "</ol>";
ChatMessage.create( {
ChatMessage.create({
content: msg,
whisper: ChatMessage.getWhisperRecipients(game.user.name) } );
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
} else {
await this.processSortReserve( sortReserveList[0] );
await this.processSortReserve(sortReserveList[0]);
}
}
}
/* -------------------------------------------- */
lancerSortEnReserve( coordTMR, sortId ) {
let sortReserveList = TMRUtility.getSortReserveList( this.sortReserves, coordTMR );
let sortReserve = sortReserveList.find( sortReserve => sortReserve.sort._id == sortId);
lancerSortEnReserve(coordTMR, sortId) {
let sortReserveList = TMRUtility.getSortReserveList(this.sortReserves, coordTMR);
let sortReserve = sortReserveList.find(sortReserve => sortReserve.sort._id == sortId);
//console.log("SORT RESA", sortReserveList, coordTMR, sortId, sortReserve);
if ( sortReserve) {
this.processSortReserve( sortReserve );
if (sortReserve) {
this.processSortReserve(sortReserve);
} else {
ChatMessage.create( {
ChatMessage.create({
content: "Une erreur est survenue : impossible de récupérer le sort en réserve demandé.",
whisper: ChatMessage.getWhisperRecipients(game.user.name) } );
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
}
}
/* -------------------------------------------- */
async processSortReserve( sortReserve ) {
async processSortReserve(sortReserve) {
await this.actor.deleteSortReserve(sortReserve);
this.updateSortReserve();
console.log("declencheSortEnReserve", sortReserve)
const declenchementSort = "Vous avez déclenché le sort <strong>" + sortReserve.sort.name
+ "</strong> en réserve en " + sortReserve.coord + " (" + TMRUtility.getTMRDescription(sortReserve.coord).label
+ "</strong> en réserve en " + sortReserve.coord + " (" + TMRUtility.getTMR(sortReserve.coord).label
+ ") avec " + sortReserve.sort.data.ptreve_reel + " points de Rêve";
this._tellToGM(declenchementSort);
this.close();
}
/* -------------------------------------------- */
nettoyerRencontre( ) {
if ( !this.currentRencontre) return; // Sanity check
if ( this.currentRencontre.graphics) {
nettoyerRencontre() {
if (!this.currentRencontre) return; // Sanity check
if (this.currentRencontre.graphics) {
for (let drawRect of this.currentRencontre.graphics) { // Suppression des dessins des zones possibles
this.pixiApp.stage.removeChild( drawRect );
this.pixiApp.stage.removeChild(drawRect);
}
}
this.currentRencontre = undefined; // Nettoyage de la structure
@ -514,21 +504,20 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
processClickPostRencontre( coord ) {
let deplacementType = "erreur";
processClickPostRencontre(coord) {
if (this.rencontreState == 'passeur' || this.rencontreState == 'messager' || this.rencontreState == 'changeur') {
console.log("Searching", this.currentRencontre.locList, coord);
let isInArea = this.currentRencontre.locList.find(locCoord => locCoord == coord );
if ( isInArea ) { // OK !
deplacementType = (this.rencontreState == 'messager') ? 'messager' : 'saut';
}
}
return deplacementType;
let isInArea = this.currentRencontre.locList.find(locCoord => locCoord == coord);
if (isInArea) { // OK !
return (this.rencontreState == 'messager') ? 'messager' : 'saut';
}
}
return "erreur";
}
/* -------------------------------------------- */
isTerreAttache( coordTMR ) {
for( let caseTMR of this.casesSpeciales) {
isTerreAttache(coordTMR) {
for (let caseTMR of this.casesSpeciales) {
if (caseTMR.data.specific == 'attache' && caseTMR.data.coord == coordTMR) { // Match !
return true;
}
@ -537,10 +526,10 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
checkConnaissanceFleuve( currentTMR, nextTMR ) {
if ( this.actor.isConnaissanceFleuve() ) {
checkConnaissanceFleuve(currentTMR, nextTMR) {
if (this.actor.isConnaissanceFleuve()) {
//console.log(currentTMR, nextTMR );
if ( TMRUtility.getTMRDescription(currentTMR).type == 'fleuve' && TMRUtility.getTMRDescription(nextTMR).type == 'fleuve') {
if (TMRUtility.getTMR(currentTMR).type == 'fleuve' && TMRUtility.getTMR(nextTMR).type == 'fleuve') {
return true;
}
}
@ -562,22 +551,22 @@ export class RdDTMRDialog extends Dialog {
console.log("deplacerDemiReve >>>>", cellx, celly);
let currentPos = TMRUtility.convertToCellCoord(myself.actor.data.data.reve.tmrpos.coord);
let coordTMR = TMRUtility.convertToTMRCoord(cellx, celly);
let currentTMR = TMRUtility.convertToTMRCoord( currentPos.x, currentPos.y);
let currentTMR = TMRUtility.convertToTMRCoord(currentPos.x, currentPos.y);
// Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
let deplacementType = 'erreur';
if ( myself.rencontreState == 'aucune') { // Pas de recontre en post-processing, donc deplacement normal
if ( !RdDTMRDialog._horsDePortee(currentPos, cellx, celly) || myself.isTerreAttache(coordTMR) || myself.checkConnaissanceFleuve(currentTMR,coordTMR ) ) {
if (myself.rencontreState == 'aucune') { // Pas de recontre en post-processing, donc deplacement normal
if (!RdDTMRDialog._horsDePortee(currentPos, cellx, celly) || myself.isTerreAttache(coordTMR) || myself.checkConnaissanceFleuve(currentTMR, coordTMR)) {
deplacementType = 'normal';
}
} else {
deplacementType = myself.processClickPostRencontre( coordTMR );
deplacementType = myself.processClickPostRencontre(coordTMR);
}
// Si le deplacement est valide
if ( deplacementType == 'normal' || deplacementType == 'saut') {
if ( myself.currentRencontre != 'normal' )
if (deplacementType == 'normal' || deplacementType == 'saut') {
if (myself.currentRencontre != 'normal')
myself.nettoyerRencontre();
let cellDescr = TMRUtility.getTMRDescription(coordTMR);
let cellDescr = TMRUtility.getTMR(coordTMR);
await myself.manageCaseSpeciale(cellDescr, coordTMR); // Gestion cases spéciales type Trou noir, etc
@ -591,12 +580,12 @@ export class RdDTMRDialog extends Dialog {
myself.updateValuesDisplay();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_tmr_move", data: {
actorId: myself.actor.data._id,
actorId: myself.actor.data._id,
tmrPos: tmrPos
}
});
if ( deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
await myself.manageRencontre(coordTMR, cellDescr);
}
await myself.manageCaseHumide(cellDescr, coordTMR);
@ -609,9 +598,9 @@ export class RdDTMRDialog extends Dialog {
Si la case est le demi-rêve, ne pas lancer de sort.
Si un lancement de sort est en cours, trouver un moyen de réafficher cette fenêtre si on essaie de lancer un sort (ou bloquer le lancer de sort)
*/
await myself.actor.rollUnSort( coordTMR );
await myself.actor.rollUnSort(coordTMR);
myself.nettoyerRencontre();
} 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");
console.log("STATUS :", myself.rencontreState, myself.currentRencontre);
@ -621,16 +610,15 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async forceDemiRevePositionView( coordTMR ) {
async forceDemiRevePositionView(coordTMR) {
this._updateDemiReve(this);
}
/* -------------------------------------------- */
async forceDemiRevePosition( coordTMR ) {
async forceDemiRevePosition(coordTMR) {
await this.actor.updateCoordTMR(coordTMR);
this._updateDemiReve(this);
let cellDescr = TMRUtility.getTMRDescription(coordTMR);
await this.manageRencontre(coordTMR, cellDescr);
let cellDescr = TMRUtility.getTMR(coordTMR);
this.manageCaseHumide(cellDescr, coordTMR);
await this.declencheSortEnReserve(coordTMR);
}
@ -689,17 +677,17 @@ export class RdDTMRDialog extends Dialog {
// Gestion du cout de montée en points de rêve
let reveCout = -1;
if ( this.actor.checkTeteDeplacementAccelere() ) {
if (this.actor.checkTeteDeplacementAccelere()) {
reveCout = -1;
} else {
reveCout = (this.tmrdata.isRapide) ? -2 : -1;
}
reveCout -= this.actor.checkMonteeLaborieuse();
await this.actor.reveActuelIncDec( reveCout );
await this.actor.reveActuelIncDec(reveCout);
// Le reste...
this.updateValuesDisplay();
let coordTMR = this.actor.data.data.reve.tmrpos.coord;
let cellDescr = TMRUtility.getTMRDescription(coordTMR);
let cellDescr = TMRUtility.getTMR(coordTMR);
await this.manageRencontre(coordTMR, cellDescr);
this.manageCaseHumide(cellDescr, coordTMR);
// Mise à jour du nb de cases de Fatigue
@ -740,7 +728,7 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
_tokenTrouNoir( coord ) {
_tokenTrouNoir(coord) {
let sprite = new PIXI.Graphics();
sprite.beginFill(0x050505, 0.8);
sprite.drawCircle(0, 0, (tmrConstants.cellw / 2) - 2);
@ -753,7 +741,7 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
_tokenDebordement( coord ) {
_tokenDebordement(coord) {
let sprite = new PIXI.Graphics();
sprite.beginFill(0x0101FE, 0.3);
sprite.drawCircle(0, 0, (tmrConstants.cellw / 2) - 2);
@ -790,7 +778,7 @@ export class RdDTMRDialog extends Dialog {
}
return { sprite: sprite, coordTMR: () => coord }
}
/* -------------------------------------------- */
_tokenSortEnReserve(sort) {
let sprite = new PIXI.Graphics();
@ -829,12 +817,12 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
_getCaseRectangleCoord( coord ) {
let coordXY = TMRUtility.convertToCellCoord( coord );
_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}
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 }
}
/* -------------------------------------------- */