Fix: tooltips sorts TMRs

This commit is contained in:
Vincent Vandemeulebrouck 2023-11-10 03:39:35 +01:00
parent ecb47addba
commit 1759e6d1c3
5 changed files with 141 additions and 115 deletions

View File

@ -1,4 +1,7 @@
# v11.0 # v11.0
## v11.1.3 - Werther de Zloth l'Onirique
- Fix: dans les TMRs, les tooltips affichent bien les informations de tous les effets sur la case
## v11.1.2 - Les vertèbres de Werther de Zloth ## v11.1.2 - Les vertèbres de Werther de Zloth
- Fix: les jets d'encaissement fonctionnent de nouveau normalement - Fix: les jets d'encaissement fonctionnent de nouveau normalement
- Macro "Mon personnage" permettant au joueur d'accéder à sa feuille de personnage depuis la barre de macros - Macro "Mon personnage" permettant au joueur d'accéder à sa feuille de personnage depuis la barre de macros

View File

@ -62,8 +62,8 @@ export class RdDTMRDialog extends Dialog {
this.loadCasesSpeciales(); this.loadCasesSpeciales();
this.allTokens = []; this.allTokens = [];
this.rencontreState = 'aucune'; this.rencontreState = 'aucune';
this.pixiApp = new PIXI.Application({ width: 720, height: 860 }); this.pixiTMR = new PixiTMR(this);
this.pixiTMR = new PixiTMR(this, this.pixiApp);
this.subdialog = undefined this.subdialog = undefined
this.callbacksOnAnimate = []; this.callbacksOnAnimate = [];
@ -128,7 +128,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
createPixiSprites() { createPixiSprites() {
EffetsDraconiques.carteTmr.createSprite(this.pixiTMR); this.pixiTMR.setup()
this.updateTokens(); this.updateTokens();
this.forceDemiRevePositionView(); this.forceDemiRevePositionView();
} }
@ -139,13 +139,9 @@ export class RdDTMRDialog extends Dialog {
this.demiReve = this._tokenDemiReve(); this.demiReve = this._tokenDemiReve();
this._trackToken(this.demiReve); this._trackToken(this.demiReve);
} }
let tokens = this._getTokensCasesTmr() this._getTokensCasesTmr().forEach(t => this._trackToken(t))
.concat(this._getTokensRencontres()) this._getTokensRencontres().forEach(t => this._trackToken(t))
.concat(this._getTokensSortsReserve()); this._getTokensSortsReserve().forEach(t => this._trackToken(t))
for (let t of tokens) {
this._trackToken(t);
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -204,6 +200,7 @@ export class RdDTMRDialog extends Dialog {
if (this.subdialog) { if (this.subdialog) {
return this.forceTMRContinueAction(); return this.forceTMRContinueAction();
} }
let oddq = TMRUtility.coordTMRToOddq(this._getActorCoord()); let oddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
if (move == 'top') oddq.row -= 1; if (move == 'top') oddq.row -= 1;
@ -230,7 +227,8 @@ export class RdDTMRDialog extends Dialog {
document.getElementsByClassName("tmr-row") document.getElementsByClassName("tmr-row")
.item(0) .item(0)
.insertCell(0).append(this.pixiApp.view); .insertCell(0)
.append(this.pixiTMR.view);
if (this.viewOnly) { if (this.viewOnly) {
this.html.find('.lancer-sort').remove(); this.html.find('.lancer-sort').remove();
@ -241,24 +239,17 @@ export class RdDTMRDialog extends Dialog {
HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue")); HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue"));
HtmlUtility.showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord())); HtmlUtility.showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
this.html.find('tr.tmr-row *').click((event) => { this.html.find('tr.tmr-row *').click(event => this.subdialog?.bringToTop());
this.subdialog?.bringToTop();
});
// Roll Sort // Roll Sort
this.html.find('.lancer-sort').click((event) => { this.html.find('.lancer-sort').click(event => this.actor.rollUnSort(this._getActorCoord()));
this.actor.rollUnSort(this._getActorCoord()); this.html.find('.lire-signe-draconique').click(event => this.actor.rollLireSigneDraconique(this._getActorCoord()));
}); this.html.find('#dir-top').click(event=> this.moveFromKey("top"));
this.html.find('.lire-signe-draconique').click((event) => { this.html.find('#dir-top-left').click(event=> this.moveFromKey("top-left"));
this.actor.rollLireSigneDraconique(this._getActorCoord()); this.html.find('#dir-top-right').click(event=> this.moveFromKey("top-right"));
}); this.html.find('#dir-bottom-left').click(event=> this.moveFromKey("bottom-left"));
this.html.find('#dir-bottom-right').click(event=> this.moveFromKey("bottom-right"));
this.html.find('#dir-top').click((event) => this.moveFromKey("top")); this.html.find('#dir-bottom').click(event=> this.moveFromKey("bottom"));
this.html.find('#dir-top-left').click((event) => this.moveFromKey("top-left"));
this.html.find('#dir-top-right').click((event) => this.moveFromKey("top-right"));
this.html.find('#dir-bottom-left').click((event) => this.moveFromKey("bottom-left"));
this.html.find('#dir-bottom-right').click((event) => this.moveFromKey("bottom-right"));
this.html.find('#dir-bottom').click((event) => this.moveFromKey("bottom"));
// Gestion du cout de montée en points de rêve // Gestion du cout de montée en points de rêve
let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse(); let reveCout = ((this.tmrdata.isRapide && !EffetsDraconiques.isDeplacementAccelere(this.actor)) ? -2 : -1) - this.actor.countMonteeLaborieuse();
@ -382,19 +373,8 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
$marquerCasesTMR(listCoordTMR) { $marquerCasesTMR(listCoordTMR) {
this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
for (let coordTMR of listCoordTMR) { this.currentRencontre.graphics = listCoordTMR.map(coordTMR => this.pixiTMR.addMarkTMR(coordTMR))
const rect = this._getCaseRectangleCoord(coordTMR);
const 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
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -907,15 +887,11 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
nettoyerRencontre() { nettoyerRencontre() {
if (!this.currentRencontre) return; // Sanity check // Suppression des dessins des zones possibles
if (this.currentRencontre.graphics) { this.currentRencontre?.graphics?.forEach(graphic => this.pixiTMR.removeGraphic(graphic))
for (let drawRect of this.currentRencontre.graphics) { // Nettoyage de la structureet de l'état
// Suppression des dessins des zones possibles this.currentRencontre = undefined;
this.pixiApp.stage.removeChild(drawRect); this.rencontreState = 'aucune';
}
}
this.currentRencontre = undefined; // Nettoyage de la structure
this.rencontreState = 'aucune'; // Et de l'état
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -1106,18 +1082,10 @@ export class RdDTMRDialog extends Dialog {
await this.postRencontre(tmr); await this.postRencontre(tmr);
return tmr; return tmr;
} }
/* -------------------------------------------- */
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
_getCaseRectangleCoord(coord) {
return this.pixiTMR.getCaseRectangle(TMRUtility.coordTMRToOddq(coord));
}
/* -------------------------------------------- */ /* -------------------------------------------- */
_removeTokens(filter) { _removeTokens(filter) {
const tokensToRemove = this.allTokens.filter(filter); this.allTokens.filter(filter).forEach(token => this.pixiTMR.removeToken(token))
for (let token of tokensToRemove) {
this.pixiApp.stage.removeChild(token.sprite);
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -1125,7 +1093,9 @@ export class RdDTMRDialog extends Dialog {
if (this.demiReve === token && this.isDemiReveCache()) { if (this.demiReve === token && this.isDemiReveCache()) {
return; return;
} }
this.pixiTMR.setPosition(token.sprite, TMRUtility.coordTMRToOddq(token.coordTMR())); this.pixiTMR.positionToken(token);
this.allTokens.push(token); if (!this.allTokens.includes(token)) {
this.allTokens.push(token);
}
} }
} }

View File

@ -1,3 +1,4 @@
import { TMRUtility } from "../tmr-utility.js";
import { Draconique } from "./draconique.js"; import { Draconique } from "./draconique.js";
import { PixiTMR } from "./pixi-tmr.js"; import { PixiTMR } from "./pixi-tmr.js";
@ -16,7 +17,6 @@ export class CarteTmr extends Draconique {
img() { return 'systems/foundryvtt-reve-de-dragon/styles/img/ui/tmr.webp' } img() { return 'systems/foundryvtt-reve-de-dragon/styles/img/ui/tmr.webp' }
createSprite(pixiTMR) { createSprite(pixiTMR) {
const img = PixiTMR.getImgFromCode(this.code()) const img = PixiTMR.getImgFromCode(this.code())
const sprite = new PIXI.Sprite(PIXI.utils.TextureCache[img]); const sprite = new PIXI.Sprite(PIXI.utils.TextureCache[img]);
// Setup the position of the TMR // Setup the position of the TMR
@ -28,10 +28,12 @@ export class CarteTmr extends Draconique {
sprite.anchor.set(0); sprite.anchor.set(0);
sprite.buttonMode = true; sprite.buttonMode = true;
sprite.tmrObject = pixiTMR; sprite.tmrObject = pixiTMR;
pixiTMR.addTooltip(sprite, (e,s) => this.computeTooltip(e,s));
pixiTMR.pixiApp.stage.addChild(sprite);
return sprite; return sprite;
} }
computeTooltip(coordTMR) {
const tmr = TMRUtility.getTMR(coordTMR)
return tmr? TMRUtility.getTMRLabel(coordTMR) : '';
}
} }

View File

@ -86,15 +86,13 @@ export class Draconique {
* @param {*} pixiTMR instance de PixiTMR qui gère les tooltips, les méthodes de création de sprite standard, les clicks. * @param {*} pixiTMR instance de PixiTMR qui gère les tooltips, les méthodes de création de sprite standard, les clicks.
*/ */
token(pixiTMR, linkData, coordTMR, type = undefined) { token(pixiTMR, linkData, coordTMR, type = undefined) {
const tooltip = this.tooltip(linkData);
const token = { const token = {
sprite: this.createSprite(pixiTMR), sprite: this.createSprite(pixiTMR),
coordTMR: coordTMR coordTMR: coordTMR,
tooltip: tooltip
}; };
token[type ?? this.code()] = linkData; token[type ?? this.code()] = linkData;
this.linkData = linkData;
if (this.tooltip(linkData)) {
pixiTMR.addTooltip(token.sprite, (e, s) => this.computeTooltip(e, s));
}
return token; return token;
} }

View File

@ -1,6 +1,8 @@
import { Misc } from "../misc.js";
import { RdDTMRDialog } from "../rdd-tmr-dialog.js"; import { RdDTMRDialog } from "../rdd-tmr-dialog.js";
import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js"; import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js";
import { TMRUtility } from "../tmr-utility.js"; import { TMRUtility } from "../tmr-utility.js";
import { EffetsDraconiques } from "./effets-draconiques.js";
export const tooltipStyle = new PIXI.TextStyle({ export const tooltipStyle = new PIXI.TextStyle({
fontFamily: 'CaslonAntique', fontFamily: 'CaslonAntique',
@ -15,11 +17,33 @@ export class PixiTMR {
static textures = [] static textures = []
constructor(tmrObject, pixiApp) { constructor(tmrDialog) {
this.tmrObject = tmrObject; this.tmrDialog = tmrDialog;
this.pixiApp = pixiApp ?? tmrObject.pixiApp;
this.pixiApp.stage.sortableChildren = true;
this.callbacksOnAnimate = []; this.callbacksOnAnimate = [];
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
this.pixiApp.eventMode = 'static';
this.pixiApp.stage.sortableChildren = true;
this.tooltip = new PIXI.Text('', tooltipStyle);
this.pixiApp.stage.addChild(this.tooltip);
}
get view() {
return this.pixiApp.view
}
setup() {
this.carteTMR = EffetsDraconiques.carteTmr.createSprite(this);
this.pixiApp.stage.addChild(this.carteTMR);
this.carteTMR.isOver = false;
this.carteTMR.eventMode = 'static';
this.carteTMR
.on('pointermove', event => this.onPointerMove(event))
.on('pointerdown', event => this.onClickBackground(event))
.on('pointerover', event => this.onShowTooltip(event))
.on('pointerout', event => this.onHideTooltip(event));
} }
async load(onLoad = (loader, resources) => { }) { async load(onLoad = (loader, resources) => { }) {
@ -46,6 +70,22 @@ export class PixiTMR {
this.callbacksOnAnimate.push(() => animation(this.pixiApp)); this.callbacksOnAnimate.push(() => animation(this.pixiApp));
} }
addMarkTMR(coordTMR) {
const rect = this.getCaseRectangle(TMRUtility.coordTMRToOddq(coordTMR))
const markTMR = new PIXI.Graphics();
markTMR.beginFill(0xffff00, 0.3);
// set the line style to have a width of 5 and set the color to red
markTMR.lineStyle(5, 0xff0000);
// draw a rectangle
markTMR.drawRect(rect.x, rect.y, rect.w, rect.h);
this.pixiApp.stage.addChild(markTMR);
return markTMR
}
removeGraphic(graphic) {
this.pixiApp.stage.removeChild(graphic);
}
sprite(code, options = {}) { sprite(code, options = {}) {
let img = PixiTMR.getImgFromCode(code) let img = PixiTMR.getImgFromCode(code)
const texture = PIXI.utils.TextureCache[img]; const texture = PIXI.utils.TextureCache[img];
@ -67,7 +107,7 @@ export class PixiTMR {
return sprite; return sprite;
} }
circle(name, options = {}) { circle(code, options = {}) {
let sprite = new PIXI.Graphics(); let sprite = new PIXI.Graphics();
sprite.beginFill(options.color, options.opacity); sprite.beginFill(options.color, options.opacity);
sprite.drawCircle(0, 0, (options.taille ?? 12) / 2); sprite.drawCircle(0, 0, (options.taille ?? 12) / 2);
@ -77,61 +117,74 @@ export class PixiTMR {
return sprite; return sprite;
} }
addTooltip(sprite, computeTooltip) {
sprite.tooltip = new PIXI.Text('', tooltipStyle);
sprite.tooltip.zIndex = tmrTokenZIndex.tooltip;
sprite.isOver = false;
sprite.eventMode = 'static';
sprite
.on('pointermove', event => this.onPointerMove(event, sprite, computeTooltip))
.on('pointerdown', event => this.onClickBackground(event))
.on('pointerover', event => this.onShowTooltip(event, sprite))
.on('pointerout', event => this.onHideTooltip(event, sprite));
}
onClickBackground(event) { onClickBackground(event) {
if (!this.viewOnly) { if (!this.viewOnly) {
this.tmrObject.onClickTMR(event) this.tmrDialog.onClickTMR(event)
} }
} }
onPointerMove(event, sprite, computeTooltip) { onPointerMove(event) {
if (sprite.isOver && sprite.tooltip) { if (this.carteTMR.isOver) {
var { x, y } = TMRUtility.computeEventPosition(event); this.setTooltipPosition(event);
const oddq = TMRUtility.computeOddq(x, y); this.tooltip.text = this.computeTooltip(event);
sprite.tooltip.x = x + (oddq.col > 8 ? - 3 * tmrConstants.full : tmrConstants.half)
sprite.tooltip.y = y + (oddq.row > 10 ? - tmrConstants.half : tmrConstants.half)
sprite.tooltip.text = computeTooltip(event, sprite);
} }
} }
onShowTooltip(event, sprite) { onShowTooltip(event) {
if (sprite.tooltip) { if (!this.carteTMR.isOver) {
if (!sprite.isOver) { this.setTooltipPosition(event);
sprite.tooltip.x = sprite.x; this.pixiApp.stage.addChild(this.tooltip);
sprite.tooltip.y = sprite.y; this.tooltip.text = this.computeTooltip(event);
this.pixiApp.stage.addChild(sprite.tooltip); }
} this.carteTMR.isOver = true;
sprite.isOver = true; }
onHideTooltip(event) {
if (this.carteTMR.isOver) {
this.pixiApp.stage.removeChild(this.tooltip);
}
this.carteTMR.isOver = false;
}
computeTooltip(event) {
const oddq = TMRUtility.computeEventOddq(event);
const coordTMR = TMRUtility.oddqToCoordTMR(oddq);
const tmr = TMRUtility.getTMR(coordTMR)
if (tmr) {
const labelTMR = TMRUtility.getTMRLabel(coordTMR);
const tokenTooltips = this.tmrDialog.allTokens
.filter(token => token.coordTMR() == coordTMR)
.map(token => token.tooltip);
const tmrTooltip = `${coordTMR}: ${labelTMR}`;
return [tmrTooltip, ...tokenTooltips].reduce(Misc.joining('\n'))
} }
} }
onHideTooltip(event, sprite) { setTooltipPosition(event) {
if (sprite.tooltip) { var { x, y } = TMRUtility.computeEventPosition(event);
if (sprite.isOver) { const oddq = TMRUtility.computeOddq(x, y);
this.pixiApp.stage.removeChild(sprite.tooltip);
} this.tooltip.x = x + (oddq.col > 8 ? -3 * tmrConstants.full : tmrConstants.half);
sprite.isOver = false; this.tooltip.y = y + (oddq.row > 10 ? -tmrConstants.half : tmrConstants.half);
}
positionToken(token) {
if (token.sprite) {
const sprite = token.sprite;
const oddq = TMRUtility.coordTMRToOddq(token.coordTMR());
const decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
const dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x;
const dy = (sprite.decallage == undefined) ? 0 : sprite.decallage.y;
sprite.x = tmrConstants.gridx + (oddq.col * tmrConstants.cellw) + dx;
sprite.y = tmrConstants.gridy + (oddq.row * tmrConstants.cellh) + dy + decallagePairImpair;
} }
} }
setPosition(sprite, oddq) { removeToken(token) {
let decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; if (token.sprite) {
let dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x; this.pixiApp.stage.removeChild(token.sprite)
let dy = (sprite.decallage == undefined) ? 0 : sprite.decallage.y; }
sprite.x = tmrConstants.gridx + (oddq.col * tmrConstants.cellw) + dx;
sprite.y = tmrConstants.gridy + (oddq.row * tmrConstants.cellh) + dy + decallagePairImpair;
} }
getCaseRectangle(oddq) { getCaseRectangle(oddq) {