Fixes nombreux sur tmr

- rencontre sur case humide ne causait pas de maîtrise
- détermination de la liste des tmrs par type à l'init (classify)
- tirages aléatoire par type de tmr dans les commandes
- amélioration de messages (nom de case)
- fix expérience case humide
- correction gestion des débordement
- montées très laborieuses multiples
- renommages et extraits méthodes
- distinction de pos (x, y) vs coord (A1)
This commit is contained in:
Vincent Vandemeulebrouck
2021-02-05 01:38:40 +01:00
parent d53077d862
commit 9fd7db2ccf
11 changed files with 282 additions and 246 deletions

View File

@ -200,7 +200,6 @@ export class RdDTMRDialog extends Dialog {
this.actor.deleteTMRRencontreAtPosition();
this.updatePreviousRencontres();
let rencontreData = {
actor: this.actor,
alias: this.actor.name,
@ -248,20 +247,22 @@ export class RdDTMRDialog extends Dialog {
rencontreData.nbRounds++;
this.nbFatigue += 1;
this._tentativeMaitrise(rencontreData);
setTimeout(() => this._deleteTmrMessages(rencontreData.actor, rencontreData.nbRounds), 500);
this._deleteTmrMessages(rencontreData.actor, rencontreData.nbRounds);
}, 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}">`);
setTimeout(() => {
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}">`);
}
}
}, 500);
}
/* -------------------------------------------- */
@ -275,38 +276,38 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async manageRencontre(coordTMR, cellDescr) {
async manageRencontre(tmr, postRencontre) {
if (this.viewOnly) {
return;
}
this.currentRencontre = undefined;
let rencontre = await this._jetDeRencontre(coordTMR, cellDescr);
let rencontre = await this._jetDeRencontre(tmr);
if (rencontre) { // Manages it
if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres
console.log("manageRencontre", rencontre);
this.currentRencontre = duplicate(rencontre);
let dialog = new RdDTMRRencontreDialog("", this, this.currentRencontre);
let dialog = new RdDTMRRencontreDialog("", this, this.currentRencontre, postRencontre);
dialog.render(true);
}
}
/* -------------------------------------------- */
async _jetDeRencontre(coordTMR, cellDescr) {
async _jetDeRencontre(tmr) {
if (TMRUtility.isForceRencontre()) {
return await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr);
return await TMRUtility.rencontreTMRRoll(tmr.coord, tmr);
}
let rencontre = this.rencontresExistantes.find(prev => prev.coord == coordTMR);
let rencontre = this.rencontresExistantes.find(prev => prev.coord == tmr.coord);
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);
return await TMRUtility.rencontreTMRRoll(tmr.coord, tmr, isMauvaise);
}
this._tellToUser(myRoll.total + ": Pas de rencontre en " + cellDescr.label + " (" + coordTMR + ")");
this._tellToUser(myRoll.total + ": Pas de rencontre en " + tmr.label + " (" + tmr.coord + ")");
}
/* -------------------------------------------- */
@ -330,13 +331,13 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async manageCaseSpeciale(cellDescr, coordTMR) {
async manageCaseSpeciale(tmr) {
for (let caseTMR of this.casesSpeciales) {
if (caseTMR.data.coord == coordTMR) { // Match !
if (caseTMR.data.coord == tmr.coord) { // Match !
if (caseTMR.data.specific == 'trounoir') {
let newTMR = TMRUtility.getTMRAleatoire();
let tmrPos = duplicate(this.actor.data.data.reve.tmrpos);
tmrPos.coord = newTMR;
tmrPos.coord = newTMR.coord;
await this.actor.update({ "data.reve.tmrpos": tmrPos });
ChatMessage.create({
content: "Vous êtes rentré sur un Trou Noir : ré-insertion aléatoire.",
@ -349,12 +350,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
isCaseMaitrisee(coordTMR) {
for (let caseTMR of this.casesSpeciales) {
if (caseTMR.data.coord == coordTMR && caseTMR.data.specific == 'maitrisee') {
return true;
}
}
return false;
return this.casesSpeciales.find(it => it.data.coord = coordTMR && it.data.specific == 'maitrisee');
}
/* -------------------------------------------- */
@ -364,19 +360,11 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async manageCaseHumide(cellDescr, coordTMR) {
async manageCaseHumide(tmr) {
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({
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)
});
return;
}
if (this.isCaseHumide(tmr)) {
// TODO: permettre de choisir la voie de draconic?
let draconic = this.actor.getBestDraconic();
@ -404,7 +392,7 @@ export class RdDTMRDialog extends Dialog {
explication += "Vous êtes entré sur une case humide, et vous avez <strong>réussi</strong> votre maîtrise !"
msg2MJ += game.user.name + " est rentré sur une case humides : Réussite !";
}
explication += "<br><strong>Test : Rêve actuel / " + draconic.name + " / " + cellDescr.type + "</strong>"
explication += "<br><strong>Test : Rêve actuel / " + draconic.name + " / " + tmr.type + "</strong>"
+ RdDResolutionTable.explain(rolled);
if (rolled.isETotal) {
@ -414,7 +402,7 @@ export class RdDTMRDialog extends Dialog {
}
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, selectedCarac: { label: 'reve' }, competence: draconic.name })
msg2MJ += "<br>Et a fait une réussite particulière";
}
@ -432,6 +420,21 @@ export class RdDTMRDialog extends Dialog {
humideDiag.render(true);
}
}
isCaseHumide(tmr) {
if (this.isCaseMaitrisee(tmr.coord)) {
ChatMessage.create({
content: tmr.label + ": 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)
});
return false;
}
if (this.actor.isCaseHumideAdditionelle(tmr)) {
return true;
}
return tmr.type == "lac" || tmr.type == "fleuve" || tmr.type == "marais";
}
/* -------------------------------------------- */
isReserveExtensible(coordTMR) {
for (let caseTMR of this.casesSpeciales) {
@ -537,60 +540,38 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async deplacerDemiReve(event) {
async onClickTMR(event) {
if (this.viewOnly) {
return;
}
let origEvent = event.data.originalEvent;
let myself = event.target.tmrObject;
let tmrObject = event.target.tmrObject;
let eventCoord = RdDTMRDialog._computeEventCoord(origEvent);
let cellx = eventCoord.cellx;
let celly = eventCoord.celly;
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 eventPos = RdDTMRDialog._computeEventPos(origEvent);
await tmrObject._onClickTMRPos(eventPos); // Vérifier l'état des compteurs reve/fatigue/vie
}
async _onClickTMRPos(eventPos) {
let currentPos = TMRUtility.convertToCellPos(this.actor.data.data.reve.tmrpos.coord);
console.log("deplacerDemiReve >>>>", currentPos, eventPos);
let targetCoordTMR = TMRUtility.convertToTMRCoord(eventPos);
let currentCoordTMR = TMRUtility.convertToTMRCoord(currentPos);
// 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 (this.rencontreState == 'aucune') { // Pas de recontre en post-processing, donc deplacement normal
if (!RdDTMRDialog._horsDePortee(currentPos, eventPos) || this.isTerreAttache(targetCoordTMR) || this.checkConnaissanceFleuve(currentCoordTMR, targetCoordTMR)) {
deplacementType = 'normal';
}
} else {
deplacementType = myself.processClickPostRencontre(coordTMR);
deplacementType = this.processClickPostRencontre(targetCoordTMR);
}
// Si le deplacement est valide
if (deplacementType == 'normal' || deplacementType == 'saut') {
if (myself.currentRencontre != 'normal')
myself.nettoyerRencontre();
let cellDescr = TMRUtility.getTMR(coordTMR);
await myself.manageCaseSpeciale(cellDescr, coordTMR); // Gestion cases spéciales type Trou noir, etc
console.log("deplacerDemiReve: TMR column is", coordTMR, cellx, celly, cellDescr, this);
let tmrPos = duplicate(myself.actor.data.data.reve.tmrpos);
tmrPos.coord = coordTMR;
await myself.actor.update({ "data.reve.tmrpos": tmrPos });
myself._updateDemiReve(myself);
myself.nbFatigue += 1;
myself.updateValuesDisplay();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_tmr_move", data: {
actorId: myself.actor.data._id,
tmrPos: tmrPos
}
});
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
await myself.manageRencontre(coordTMR, cellDescr);
}
await myself.manageCaseHumide(cellDescr, coordTMR);
await myself.declencheSortEnReserve(coordTMR);
await myself.actor.checkSoufflePeage(cellDescr);
await this._deplacerDemiReve(targetCoordTMR, deplacementType);
} else if (deplacementType == 'messager') { // Dans ce cas, ouverture du lancement de sort sur la case visée
/*
@ -598,29 +579,71 @@ 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);
myself.nettoyerRencontre();
await this._messagerDemiReve(targetCoordTMR);
} 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);
console.log("STATUS :", this.rencontreState, this.currentRencontre);
}
myself.checkQuitterTMR(); // Vérifier l'état des compteurs reve/fatigue/vie
this.checkQuitterTMR();
}
async _messagerDemiReve(targetCoordTMR) {
await this.actor.rollUnSort(targetCoordTMR);
this.nettoyerRencontre();
}
async _deplacerDemiReve(targetCoord, deplacementType) {
if (this.currentRencontre != 'normal') {
this.nettoyerRencontre();
}
let tmr = TMRUtility.getTMR(targetCoord);
await this.manageCaseSpeciale(tmr); // Gestion cases spéciales type Trou noir, etc
console.log("deplacerDemiReve: TMR is", tmr, this);
let tmrPos = duplicate(this.actor.data.data.reve.tmrpos);
tmrPos.coord = targetCoord;
await this.actor.update({ "data.reve.tmrpos": tmrPos });
this._updateDemiReve();
this.nbFatigue += 1;
this.updateValuesDisplay();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_tmr_move", data: {
actorId: this.actor.data._id,
tmrPos: tmrPos
}
});
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
await this.manageRencontre(tmr, () => this.postRencontre(tmr));
}
else{
await this.postRencontre(tmr);
}
}
async postRencontre(tmr) {
await this.manageCaseHumide(tmr);
await this.declencheSortEnReserve(tmr.coord);
await this.actor.checkSoufflePeage(tmr);
}
/* -------------------------------------------- */
async forceDemiRevePositionView(coordTMR) {
this._updateDemiReve(this);
this._updateDemiReve();
}
/* -------------------------------------------- */
async forceDemiRevePosition(coordTMR) {
await this.actor.updateCoordTMR(coordTMR);
this._updateDemiReve(this);
let cellDescr = TMRUtility.getTMR(coordTMR);
this.manageCaseHumide(cellDescr, coordTMR);
await this.declencheSortEnReserve(coordTMR);
this._updateDemiReve();
let tmr = TMRUtility.getTMR(coordTMR);
this.manageCaseHumide(tmr);
await this.declencheSortEnReserve(tmr.coord);
}
/* -------------------------------------------- */
@ -661,7 +684,7 @@ export class RdDTMRDialog extends Dialog {
mytmr.buttonMode = true;
mytmr.tmrObject = this;
if (!this.viewOnly) {
mytmr.on('pointerdown', this.deplacerDemiReve);
mytmr.on('pointerdown', this.onClickTMR);
}
this.pixiApp.stage.addChild(mytmr);
@ -676,42 +699,36 @@ export class RdDTMRDialog extends Dialog {
}
// Gestion du cout de montée en points de rêve
let reveCout = -1;
if (this.actor.checkTeteDeplacementAccelere()) {
reveCout = -1;
} else {
reveCout = (this.tmrdata.isRapide) ? -2 : -1;
}
let reveCout = (this.tmrdata.isRapide && !this.actor.checkTeteDeplacementAccelere()) ? -2 : -1;
reveCout -= this.actor.checkMonteeLaborieuse();
await this.actor.reveActuelIncDec(reveCout);
// Le reste...
this.updateValuesDisplay();
let coordTMR = this.actor.data.data.reve.tmrpos.coord;
let cellDescr = TMRUtility.getTMR(coordTMR);
await this.manageRencontre(coordTMR, cellDescr);
this.manageCaseHumide(cellDescr, coordTMR);
// Mise à jour du nb de cases de Fatigue
this.nbFatigue = this.actor.getTMRFatigue();
this.actor.displayTMRQueueSouffleInformation();
let tmr = TMRUtility.getTMR(this.actor.data.data.reve.tmrpos.coord);
await this.manageRencontre(tmr, () => {
this.postRencontre(tmr);
this.nbFatigue = this.actor.getTMRFatigue();
this.actor.displayTMRQueueSouffleInformation();
});
}
/* -------------------------------------------- */
static _computeEventCoord(origEvent) {
static _computeEventPos(origEvent) {
let canvasRect = origEvent.target.getBoundingClientRect();
let x = origEvent.clientX - canvasRect.left;
let y = origEvent.clientY - canvasRect.top;
let cellx = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
y -= (cellx % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let celly = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14]
return { cellx, celly };
return { x: cellx, y: celly };
}
/* -------------------------------------------- */
static _horsDePortee(pos, cellx, celly) {
return Math.abs(cellx - pos.x) > 1
|| Math.abs(celly - pos.y) > 1
|| (pos.y == 0 && celly > pos.y && cellx != pos.x && pos.x % 2 == 0)
|| (celly == 0 && celly < pos.y && cellx != pos.x && pos.x % 2 == 1);
static _horsDePortee(origin, target) {
return Math.abs(target.x - origin.x) > 1
|| Math.abs(target.y - origin.y) > 1
|| (origin.y == 0 && target.y > origin.y && target.x != origin.x && origin.x % 2 == 0)
|| (target.y == 0 && target.y < origin.y && target.x != origin.x && origin.x % 2 == 1);
}
/* -------------------------------------------- */
@ -811,14 +828,14 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
_updateDemiReve(myself) {
myself._setTokenPosition(myself.demiReve);
_updateDemiReve() {
this._setTokenPosition(this.demiReve);
}
/* -------------------------------------------- */
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
_getCaseRectangleCoord(coord) {
let coordXY = TMRUtility.convertToCellCoord(coord);
let coordXY = TMRUtility.convertToCellPos(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;
@ -827,7 +844,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
_setTokenPosition(token) {
let coordXY = TMRUtility.convertToCellCoord(token.coordTMR());
let coordXY = TMRUtility.convertToCellPos(token.coordTMR());
let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let dx = (token.sprite.decallage == undefined) ? 0 : token.sprite.decallage.x;
let dy = (token.sprite.decallage == undefined) ? 0 : token.sprite.decallage.y;