2023-11-10 03:39:35 +01:00
|
|
|
import { Misc } from "../misc.js";
|
2023-11-15 22:14:00 +01:00
|
|
|
import { TMRConstants, tmrTokenZIndex } from "../tmr-constants.js";
|
2023-10-20 22:18:37 +02:00
|
|
|
import { TMRUtility } from "../tmr-utility.js";
|
2023-11-10 03:39:35 +01:00
|
|
|
import { EffetsDraconiques } from "./effets-draconiques.js";
|
2021-02-11 02:48:27 +01:00
|
|
|
|
|
|
|
export class PixiTMR {
|
|
|
|
static textures = []
|
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
static getImgFromCode(code) {
|
|
|
|
return PixiTMR.textures[code]
|
|
|
|
}
|
2023-11-10 03:39:35 +01:00
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
static register(name, img) {
|
|
|
|
PixiTMR.textures[name] = img;
|
|
|
|
}
|
2024-03-10 00:47:50 +01:00
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
static async init() {
|
|
|
|
await Promise.all(
|
|
|
|
Object.values(PixiTMR.textures)
|
2024-03-10 00:47:50 +01:00
|
|
|
.filter(img => img != undefined && !PIXI.utils.TextureCache[img])
|
|
|
|
.map(async img => PIXI.Sprite.from(await PIXI.Assets.load(img))))
|
2023-11-15 22:14:00 +01:00
|
|
|
}
|
2023-11-10 03:39:35 +01:00
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
constructor(tmrDialog, displaySize) {
|
|
|
|
this.tmrDialog = tmrDialog;
|
|
|
|
this.callbacksOnAnimate = [];
|
|
|
|
this.sizes = new TMRConstants({ size: displaySize })
|
2023-11-23 00:54:54 +01:00
|
|
|
console.info(`Creation d'Application PIXI pour les TMR de ${tmrDialog.actor.name}`)
|
2023-11-15 22:14:00 +01:00
|
|
|
this.pixiApp = new PIXI.Application(PixiTMR.computeTMRSize(this.sizes));
|
2023-11-10 03:39:35 +01:00
|
|
|
this.pixiApp.eventMode = 'static';
|
|
|
|
this.pixiApp.stage.sortableChildren = true;
|
2023-11-15 22:14:00 +01:00
|
|
|
|
|
|
|
this.tooltipStyle = new PIXI.TextStyle({
|
|
|
|
fontFamily: 'CaslonAntique',
|
|
|
|
fontSize: 16,
|
|
|
|
fill: '#FFFFFF',
|
|
|
|
stroke: '#000000',
|
|
|
|
strokeThickness: 4
|
|
|
|
});
|
|
|
|
|
|
|
|
this.tooltip = new PIXI.Text('', this.tooltipStyle);
|
2023-11-11 00:52:57 +01:00
|
|
|
this.tooltip.zIndex = 1000
|
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
this.pixiApp.stage.addChild(this.tooltip);
|
2023-11-15 22:14:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
close() {
|
2023-11-23 00:54:54 +01:00
|
|
|
console.info(`Destruction d'Application PIXI pour les TMR de ${this.tmrDialog.actor.name}`)
|
|
|
|
this.pixiApp.destroy();
|
|
|
|
this.pixiApp = undefined
|
2023-11-15 22:14:00 +01:00
|
|
|
}
|
|
|
|
static computeTMRSize(sizeConstants) {
|
|
|
|
return { width: sizeConstants.cellw * 13 + sizeConstants.marginx, height: sizeConstants.cellh / 2 + sizeConstants.cellh * 15 + sizeConstants.marginy }
|
|
|
|
}
|
2023-11-10 03:39:35 +01:00
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
resizeTMR(displaySize) {
|
|
|
|
this.sizes = new TMRConstants({ size: displaySize })
|
|
|
|
const appSize = PixiTMR.computeTMRSize(this.sizes)
|
|
|
|
this.pixiApp.renderer.resize(appSize.width, appSize.height)
|
2023-12-09 23:20:09 +01:00
|
|
|
this.tooltipStyle.fontSize = Math.max(this.sizes.size / 3, 16)
|
2023-11-10 03:39:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
async loadAnimations() {
|
2023-05-29 08:38:22 +02:00
|
|
|
for (let onAnimate of this.callbacksOnAnimate) {
|
|
|
|
onAnimate();
|
2023-05-25 20:40:59 +02:00
|
|
|
}
|
2023-11-15 22:14:00 +01:00
|
|
|
this.pixiApp.ticker.start();
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
|
2023-10-20 22:18:37 +02:00
|
|
|
animate(animation = pixiApp => { }) {
|
2021-02-11 02:48:27 +01:00
|
|
|
this.callbacksOnAnimate.push(() => animation(this.pixiApp));
|
|
|
|
}
|
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2021-02-11 02:48:27 +01:00
|
|
|
sprite(code, options = {}) {
|
2023-05-29 08:38:22 +02:00
|
|
|
let img = PixiTMR.getImgFromCode(code)
|
2024-03-10 00:47:50 +01:00
|
|
|
let texture = PIXI.utils.TextureCache[img]
|
2021-02-11 02:48:27 +01:00
|
|
|
if (!texture) {
|
2024-03-10 00:47:50 +01:00
|
|
|
// TODO: charger la texture
|
2023-05-29 08:38:22 +02:00
|
|
|
console.error("Texture manquante", code, PIXI.utils.TextureCache)
|
2021-02-11 02:48:27 +01:00
|
|
|
return;
|
2023-10-20 22:18:37 +02:00
|
|
|
}
|
2021-02-11 02:48:27 +01:00
|
|
|
let sprite = new PIXI.Sprite(texture);
|
2023-11-15 22:14:00 +01:00
|
|
|
sprite.taille = options.taille ?? (() => this.sizes.half)
|
|
|
|
|
|
|
|
sprite.width = sprite.taille()
|
|
|
|
sprite.height = sprite.taille()
|
|
|
|
sprite.anchor.set(0.5)
|
|
|
|
if (options.tint) {
|
|
|
|
sprite.tint = options.tint
|
2021-02-12 12:50:17 +01:00
|
|
|
}
|
2023-11-15 22:14:00 +01:00
|
|
|
sprite.zIndex = options.zIndex ?? tmrTokenZIndex.casehumide + 1
|
|
|
|
sprite.alpha = options.alpha ?? 1
|
|
|
|
sprite.decallage = options.decallage ?? this.sizes.center
|
|
|
|
this.pixiApp.stage.addChild(sprite)
|
|
|
|
return sprite
|
2023-10-20 22:18:37 +02:00
|
|
|
}
|
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
circle(code, options = {}) {
|
2023-11-15 22:14:00 +01:00
|
|
|
let sprite = new PIXI.Graphics()
|
|
|
|
sprite.taille = options.taille ?? (() => this.sizes.half)
|
|
|
|
sprite.decallage = options.decallage ?? this.sizes.topLeft
|
|
|
|
sprite.beginFill(options.tint, options.opacity)
|
|
|
|
sprite.drawCircle(0, 0, sprite.taille())
|
|
|
|
sprite.endFill()
|
|
|
|
this.pixiApp.stage.addChild(sprite)
|
|
|
|
return sprite
|
|
|
|
}
|
|
|
|
|
|
|
|
square(code, options = {}) {
|
2021-02-11 02:48:27 +01:00
|
|
|
let sprite = new PIXI.Graphics();
|
2023-11-15 22:14:00 +01:00
|
|
|
sprite.taille = options.taille ?? (() => this.sizes.half)
|
|
|
|
sprite.decallage = options.decallage ?? this.sizes.topLeft
|
|
|
|
sprite.beginFill(options.tint, options.opacity)
|
|
|
|
const size = sprite.taille();
|
|
|
|
sprite.drawRect(0, 0, size, size)
|
|
|
|
sprite.endFill()
|
|
|
|
this.pixiApp.stage.addChild(sprite)
|
|
|
|
return sprite
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
onClickBackground(event) {
|
2023-10-20 22:18:37 +02:00
|
|
|
if (!this.viewOnly) {
|
2023-11-10 03:39:35 +01:00
|
|
|
this.tmrDialog.onClickTMR(event)
|
2023-10-20 22:18:37 +02:00
|
|
|
}
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
onPointerMove(event) {
|
|
|
|
if (this.carteTMR.isOver) {
|
|
|
|
this.setTooltipPosition(event);
|
|
|
|
this.tooltip.text = this.computeTooltip(event);
|
|
|
|
}
|
|
|
|
}
|
2023-11-15 22:14:00 +01:00
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
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;
|
|
|
|
}
|
2021-02-11 02:48:27 +01:00
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
onHideTooltip(event) {
|
|
|
|
if (this.carteTMR.isOver) {
|
|
|
|
this.pixiApp.stage.removeChild(this.tooltip);
|
2023-10-20 22:18:37 +02:00
|
|
|
}
|
2023-11-10 03:39:35 +01:00
|
|
|
this.carteTMR.isOver = false;
|
2023-10-20 22:18:37 +02:00
|
|
|
}
|
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
computeTooltip(event) {
|
2023-11-15 22:14:00 +01:00
|
|
|
const oddq = this.sizes.computeEventOddq(event);
|
2023-11-10 03:39:35 +01:00
|
|
|
const coordTMR = TMRUtility.oddqToCoordTMR(oddq);
|
|
|
|
const tmr = TMRUtility.getTMR(coordTMR)
|
|
|
|
if (tmr) {
|
2023-11-15 22:14:00 +01:00
|
|
|
const tmrTooltip = `${coordTMR}: ${TMRUtility.getTMRLabel(coordTMR)}`;
|
2023-11-10 03:39:35 +01:00
|
|
|
const tokenTooltips = this.tmrDialog.allTokens
|
|
|
|
.filter(token => token.coordTMR() == coordTMR)
|
|
|
|
.map(token => token.tooltip);
|
|
|
|
return [tmrTooltip, ...tokenTooltips].reduce(Misc.joining('\n'))
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
computeEventOddq(event) {
|
|
|
|
return this.sizes.computeEventOddq(event)
|
|
|
|
}
|
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
setTooltipPosition(event) {
|
2023-11-15 22:14:00 +01:00
|
|
|
const oddq = this.sizes.computeEventOddq(event);
|
2023-11-10 03:39:35 +01:00
|
|
|
|
2023-12-09 23:20:09 +01:00
|
|
|
this.tooltip.x = oddq.x + (oddq.col > 7 ? -2.5 * this.sizes.full : this.sizes.quarter);
|
2023-11-15 22:14:00 +01:00
|
|
|
this.tooltip.y = oddq.y + (oddq.row > 10 ? -this.sizes.size : 0);
|
2023-11-10 03:39:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
positionToken(token) {
|
|
|
|
if (token.sprite) {
|
|
|
|
const sprite = token.sprite;
|
|
|
|
const oddq = TMRUtility.coordTMRToOddq(token.coordTMR());
|
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
const decallagePairImpair = (oddq.col % 2 == 0) ? this.sizes.col1_y : this.sizes.col2_y;
|
|
|
|
const dx = sprite.decallage?.x ?? 0
|
|
|
|
const dy = sprite.decallage?.y ?? 0
|
|
|
|
sprite.x = this.sizes.gridx + (oddq.col * this.sizes.cellw) + dx;
|
|
|
|
sprite.y = this.sizes.gridy + (oddq.row * this.sizes.cellh) + dy + decallagePairImpair;
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-10 03:39:35 +01:00
|
|
|
removeToken(token) {
|
|
|
|
if (token.sprite) {
|
|
|
|
this.pixiApp.stage.removeChild(token.sprite)
|
|
|
|
}
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
|
2021-12-12 17:36:22 +01:00
|
|
|
getCaseRectangle(oddq) {
|
2023-11-15 22:14:00 +01:00
|
|
|
const decallagePairImpair = (oddq.col % 2 == 0) ? this.sizes.col1_y : this.sizes.col2_y;
|
|
|
|
const x = this.sizes.gridx + (oddq.col * this.sizes.cellw) - (this.sizes.cellw / 2);
|
|
|
|
const y = this.sizes.gridy + (oddq.row * this.sizes.cellh) - (this.sizes.cellh / 2) + decallagePairImpair;
|
|
|
|
return { x, y, w: this.sizes.cellw, h: this.sizes.cellh };
|
2021-02-11 02:48:27 +01:00
|
|
|
}
|
|
|
|
}
|