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.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
- 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

View File

@ -62,8 +62,8 @@ export class RdDTMRDialog extends Dialog {
this.loadCasesSpeciales();
this.allTokens = [];
this.rencontreState = 'aucune';
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
this.pixiTMR = new PixiTMR(this, this.pixiApp);
this.pixiTMR = new PixiTMR(this);
this.subdialog = undefined
this.callbacksOnAnimate = [];
@ -128,7 +128,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
createPixiSprites() {
EffetsDraconiques.carteTmr.createSprite(this.pixiTMR);
this.pixiTMR.setup()
this.updateTokens();
this.forceDemiRevePositionView();
}
@ -139,13 +139,9 @@ export class RdDTMRDialog extends Dialog {
this.demiReve = this._tokenDemiReve();
this._trackToken(this.demiReve);
}
let tokens = this._getTokensCasesTmr()
.concat(this._getTokensRencontres())
.concat(this._getTokensSortsReserve());
for (let t of tokens) {
this._trackToken(t);
}
this._getTokensCasesTmr().forEach(t => this._trackToken(t))
this._getTokensRencontres().forEach(t => this._trackToken(t))
this._getTokensSortsReserve().forEach(t => this._trackToken(t))
}
/* -------------------------------------------- */
@ -204,6 +200,7 @@ export class RdDTMRDialog extends Dialog {
if (this.subdialog) {
return this.forceTMRContinueAction();
}
let oddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
if (move == 'top') oddq.row -= 1;
@ -230,7 +227,8 @@ export class RdDTMRDialog extends Dialog {
document.getElementsByClassName("tmr-row")
.item(0)
.insertCell(0).append(this.pixiApp.view);
.insertCell(0)
.append(this.pixiTMR.view);
if (this.viewOnly) {
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(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getActorCoord()));
this.html.find('tr.tmr-row *').click((event) => {
this.subdialog?.bringToTop();
});
this.html.find('tr.tmr-row *').click(event => this.subdialog?.bringToTop());
// Roll Sort
this.html.find('.lancer-sort').click((event) => {
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('#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"));
this.html.find('.lancer-sort').click(event => 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('#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
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) {
this.currentRencontre.graphics = []; // Keep track of rectangles to delete it
this.currentRencontre.locList = duplicate(listCoordTMR); // And track of allowed location
for (let coordTMR of listCoordTMR) {
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
}
this.currentRencontre.graphics = listCoordTMR.map(coordTMR => this.pixiTMR.addMarkTMR(coordTMR))
}
/* -------------------------------------------- */
@ -907,15 +887,11 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
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.currentRencontre = undefined; // Nettoyage de la structure
this.rencontreState = 'aucune'; // Et de l'état
// Suppression des dessins des zones possibles
this.currentRencontre?.graphics?.forEach(graphic => this.pixiTMR.removeGraphic(graphic))
// Nettoyage de la structureet de l'état
this.currentRencontre = undefined;
this.rencontreState = 'aucune';
}
/* -------------------------------------------- */
@ -1106,18 +1082,10 @@ export class RdDTMRDialog extends Dialog {
await this.postRencontre(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) {
const tokensToRemove = this.allTokens.filter(filter);
for (let token of tokensToRemove) {
this.pixiApp.stage.removeChild(token.sprite);
}
this.allTokens.filter(filter).forEach(token => this.pixiTMR.removeToken(token))
}
/* -------------------------------------------- */
@ -1125,7 +1093,9 @@ export class RdDTMRDialog extends Dialog {
if (this.demiReve === token && this.isDemiReveCache()) {
return;
}
this.pixiTMR.setPosition(token.sprite, TMRUtility.coordTMRToOddq(token.coordTMR()));
this.allTokens.push(token);
this.pixiTMR.positionToken(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 { 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' }
createSprite(pixiTMR) {
const img = PixiTMR.getImgFromCode(this.code())
const sprite = new PIXI.Sprite(PIXI.utils.TextureCache[img]);
// Setup the position of the TMR
@ -28,10 +28,12 @@ export class CarteTmr extends Draconique {
sprite.anchor.set(0);
sprite.buttonMode = true;
sprite.tmrObject = pixiTMR;
pixiTMR.addTooltip(sprite, (e,s) => this.computeTooltip(e,s));
pixiTMR.pixiApp.stage.addChild(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.
*/
token(pixiTMR, linkData, coordTMR, type = undefined) {
const tooltip = this.tooltip(linkData);
const token = {
sprite: this.createSprite(pixiTMR),
coordTMR: coordTMR
coordTMR: coordTMR,
tooltip: tooltip
};
token[type ?? this.code()] = linkData;
this.linkData = linkData;
if (this.tooltip(linkData)) {
pixiTMR.addTooltip(token.sprite, (e, s) => this.computeTooltip(e, s));
}
return token;
}

View File

@ -1,6 +1,8 @@
import { Misc } from "../misc.js";
import { RdDTMRDialog } from "../rdd-tmr-dialog.js";
import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js";
import { TMRUtility } from "../tmr-utility.js";
import { EffetsDraconiques } from "./effets-draconiques.js";
export const tooltipStyle = new PIXI.TextStyle({
fontFamily: 'CaslonAntique',
@ -15,11 +17,33 @@ export class PixiTMR {
static textures = []
constructor(tmrObject, pixiApp) {
this.tmrObject = tmrObject;
this.pixiApp = pixiApp ?? tmrObject.pixiApp;
this.pixiApp.stage.sortableChildren = true;
constructor(tmrDialog) {
this.tmrDialog = tmrDialog;
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) => { }) {
@ -46,6 +70,22 @@ export class PixiTMR {
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 = {}) {
let img = PixiTMR.getImgFromCode(code)
const texture = PIXI.utils.TextureCache[img];
@ -67,7 +107,7 @@ export class PixiTMR {
return sprite;
}
circle(name, options = {}) {
circle(code, options = {}) {
let sprite = new PIXI.Graphics();
sprite.beginFill(options.color, options.opacity);
sprite.drawCircle(0, 0, (options.taille ?? 12) / 2);
@ -77,63 +117,76 @@ export class PixiTMR {
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) {
if (!this.viewOnly) {
this.tmrObject.onClickTMR(event)
this.tmrDialog.onClickTMR(event)
}
}
onPointerMove(event, sprite, computeTooltip) {
if (sprite.isOver && sprite.tooltip) {
var { x, y } = TMRUtility.computeEventPosition(event);
const oddq = TMRUtility.computeOddq(x, y);
onPointerMove(event) {
if (this.carteTMR.isOver) {
this.setTooltipPosition(event);
this.tooltip.text = this.computeTooltip(event);
}
}
onShowTooltip(event) {
if (!this.carteTMR.isOver) {
this.setTooltipPosition(event);
this.pixiApp.stage.addChild(this.tooltip);
this.tooltip.text = this.computeTooltip(event);
}
this.carteTMR.isOver = true;
}
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);
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'))
}
}
onShowTooltip(event, sprite) {
if (sprite.tooltip) {
if (!sprite.isOver) {
sprite.tooltip.x = sprite.x;
sprite.tooltip.y = sprite.y;
this.pixiApp.stage.addChild(sprite.tooltip);
}
sprite.isOver = true;
setTooltipPosition(event) {
var { x, y } = TMRUtility.computeEventPosition(event);
const oddq = TMRUtility.computeOddq(x, y);
this.tooltip.x = x + (oddq.col > 8 ? -3 * tmrConstants.full : tmrConstants.half);
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;
}
}
onHideTooltip(event, sprite) {
if (sprite.tooltip) {
if (sprite.isOver) {
this.pixiApp.stage.removeChild(sprite.tooltip);
}
sprite.isOver = false;
removeToken(token) {
if (token.sprite) {
this.pixiApp.stage.removeChild(token.sprite)
}
}
setPosition(sprite, oddq) {
let decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x;
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) {
let decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let x = tmrConstants.gridx + (oddq.col * tmrConstants.cellw) - (tmrConstants.cellw / 2);