Nouvelles TMRs

This commit is contained in:
Vincent Vandemeulebrouck 2023-10-20 22:18:37 +02:00
parent f2a3e1db45
commit c1cecc76b3
10 changed files with 134 additions and 95 deletions

View File

@ -1,4 +1,7 @@
# v11.0 # v11.0
## v11.0.24 - les couleurs de Khrachtchoum
- nouvelle carte des TMRs
## v11.0.23 - la lumière de Khrachtchoum ## v11.0.23 - la lumière de Khrachtchoum
- ajustement automatique de la luminosité selon l'heure pour les scènes: - ajustement automatique de la luminosité selon l'heure pour les scènes:
- avec une vision des tokens (sinon: ce n'est pas une scène de carte pour tokens) - avec une vision des tokens (sinon: ce n'est pas une scène de carte pour tokens)

View File

@ -46,7 +46,7 @@ export class RdDTMRDialog extends Dialog {
const dialogOptions = { const dialogOptions = {
classes: ["tmrdialog"], classes: ["tmrdialog"],
width: 920, height: 980, width: 920, maxheight: 1024, height: 'fit-content',
'z-index': 40 'z-index': 40
} }
super(dialogConf, dialogOptions); super(dialogConf, dialogOptions);
@ -62,7 +62,6 @@ export class RdDTMRDialog extends Dialog {
this.allTokens = []; this.allTokens = [];
this.rencontreState = 'aucune'; this.rencontreState = 'aucune';
this.pixiApp = new PIXI.Application({ width: 720, height: 860 }); this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
this.pixiTMR = new PixiTMR(this, this.pixiApp); this.pixiTMR = new PixiTMR(this, this.pixiApp);
this.callbacksOnAnimate = []; this.callbacksOnAnimate = [];
@ -906,15 +905,12 @@ export class RdDTMRDialog extends Dialog {
if (this.viewOnly) { if (this.viewOnly) {
return; return;
} }
let clickOddq = RdDTMRDialog._computeEventOddq(event.nativeEvent); let clickOddq = TMRUtility.computeEventOddq(event);
await this._onClickTMRPos(clickOddq); // Vérifier l'état des compteurs reve/fatigue/vie
}
/* -------------------------------------------- */
async _onClickTMRPos(clickOddq) {
let currentOddq = TMRUtility.coordTMRToOddq(this._getActorCoord()); let currentOddq = TMRUtility.coordTMRToOddq(this._getActorCoord());
let targetCoord = TMRUtility.oddqToCoordTMR(clickOddq); let targetCoord = TMRUtility.oddqToCoordTMR(clickOddq);
let currentCoord = TMRUtility.oddqToCoordTMR(currentOddq); let currentCoord = TMRUtility.oddqToCoordTMR(currentOddq);
// Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter) // Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
let deplacementType = this._calculDeplacement(targetCoord, currentCoord, currentOddq, clickOddq); let deplacementType = this._calculDeplacement(targetCoord, currentCoord, currentOddq, clickOddq);
@ -946,7 +942,7 @@ export class RdDTMRDialog extends Dialog {
await this._messagerDemiReve(targetCoord); await this._messagerDemiReve(targetCoord);
break; break;
default: default:
ui.notifications.error("Vous ne pouvez pas vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre"); 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 :", this.rencontreState, this.currentRencontre); console.log("STATUS :", this.rencontreState, this.currentRencontre);
} }
@ -1049,19 +1045,6 @@ export class RdDTMRDialog extends Dialog {
await this.postRencontre(tmr); await this.postRencontre(tmr);
return tmr; return tmr;
} }
/* -------------------------------------------- */
static _computeEventOddq(origEvent) {
console.log("EVENT", origEvent)
let canvasRect = origEvent.target.getBoundingClientRect();
let x = origEvent.clientX - canvasRect.left;
let y = origEvent.clientY - canvasRect.top;
let col = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
y -= col % 2 == 0 ? tmrConstants.col1_y : tmrConstants.col2_y;
let row = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14]
return { col: col, row: row };
}
/* -------------------------------------------- */ /* -------------------------------------------- */
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */ /** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
_getCaseRectangleCoord(coord) { _getCaseRectangleCoord(coord) {

View File

@ -1,6 +1,7 @@
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { RdDDice } from "./rdd-dice.js"; import { RdDDice } from "./rdd-dice.js";
import { tmrConstants } from "./tmr-constants.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
const TMRMapping = { const TMRMapping = {
@ -275,10 +276,10 @@ export class TMRUtility {
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label; return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
} }
static findTMRLike(type, options = {inclusMauvaise:true}) { static findTMRLike(type, options = { inclusMauvaise: true }) {
const choix = [...Object.values(TMRType)] const choix = [...Object.values(TMRType)]
if (options.inclusMauvaise){ if (options.inclusMauvaise) {
choix.push({name: 'Mauvaise'}); choix.push({ name: 'Mauvaise' });
} }
const selection = Misc.findAllLike(type, choix).map(it => it.name); const selection = Misc.findAllLike(type, choix).map(it => it.name);
if (selection.length == 0) { if (selection.length == 0) {
@ -297,7 +298,7 @@ export class TMRUtility {
} }
static buildSelectionTypesTMR(typesTMR) { static buildSelectionTypesTMR(typesTMR) {
typesTMR = typesTMR?? []; typesTMR = typesTMR ?? [];
return Object.values(TMRType).map(value => Misc.upperFirst(value.name)) return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
.sort() .sort()
.map(name => { return { name: name, selected: typesTMR.includes(name) } }); .map(name => { return { name: name, selected: typesTMR.includes(name) } });
@ -375,6 +376,33 @@ export class TMRUtility {
return caseList; return caseList;
} }
// /* -------------------------------------------- */
static computeEventPosition(event) {
const canvasRect = event.nativeEvent.target.getBoundingClientRect();
return {
x: event.nativeEvent.clientX - canvasRect.left,
y: event.nativeEvent.clientY - canvasRect.top
};
}
/* -------------------------------------------- */
static computeEventOddq(event) {
var { x, y } = TMRUtility.computeEventPosition(event);
return TMRUtility.computeOddq(x, y);
}
static computeOddq(x, y) {
const col = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
const decallageColonne = col % 2 == 0 ? tmrConstants.col1_y : tmrConstants.col2_y;
const row = Math.floor((y - decallageColonne) / tmrConstants.cellh); // [From 0 -> 14]
return { col, row };
}
static computeEventCoord(event) {
const oddq = TMRUtility.computeEventOddq(event);
return TMRUtility.oddqToCoordTMR(oddq);
}
/* -------------------------------------------- */ /* -------------------------------------------- */
// https://www.redblobgames.com/grids/hexagons/#distances // https://www.redblobgames.com/grids/hexagons/#distances
// TMR Letter-row correspond to "odd-q" grid (letter => col, numeric => row ) // TMR Letter-row correspond to "odd-q" grid (letter => col, numeric => row )
@ -400,7 +428,7 @@ export class TMRUtility {
col >= 0 && col < 13 && col >= 0 && col < 13 &&
row >= 0 && row >= 0 &&
(row + col % 2 <= 14) (row + col % 2 <= 14)
); );
// if (x >= 0 && x < 13 && y >= 0 && y < 14) return true; // if (x >= 0 && x < 13 && y >= 0 && y < 14) return true;
// if (x >= 0 && x < 13 && x % 2 == 0 && y == 14) return true; // if (x >= 0 && x < 13 && x % 2 == 0 && y == 14) return true;
// return false; // return false;
@ -444,7 +472,7 @@ export class TMRUtility {
static axial_subtract(a, b) { static axial_subtract(a, b) {
return { return {
q: a.q- b.q, q: a.q - b.q,
r: a.r - b.r r: a.r - b.r
}; };
} }

View File

@ -4,7 +4,6 @@ import { PixiTMR } from "./pixi-tmr.js";
export class CarteTmr extends Draconique { export class CarteTmr extends Draconique {
constructor() { constructor() {
console.log("Sprite create 1!!!!")
super(); super();
} }
@ -14,9 +13,25 @@ export class CarteTmr extends Draconique {
async onActorCreateOwned(actor, item) { } async onActorCreateOwned(actor, item) { }
code() { return 'tmr' } code() { return 'tmr' }
img() { return 'systems/foundryvtt-reve-de-dragon/styles/img/ui/tmp_main_r1.webp' } img() { return 'systems/foundryvtt-reve-de-dragon/styles/img/ui/tmr.webp' }
createSprite(pixiTMR) { createSprite(pixiTMR) {
return pixiTMR.carteTmr(this.code());
const img = PixiTMR.getImgFromCode(this.code())
const sprite = new PIXI.Sprite(PIXI.utils.TextureCache[img]);
// Setup the position of the TMR
sprite.x = 0;
sprite.y = 0;
sprite.width = 722;
sprite.height = 860;
// Rotate around the center
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;
} }
} }

View File

@ -11,7 +11,7 @@ const registeredEffects = [
export class Draconique { export class Draconique {
static isCaseTMR(item) { return item.type == TYPES.casetmr; } static isCaseTMR(item) { return item.type == TYPES.casetmr; }
static isQueueDragon(item) { return item.isQueueDragon(); } static isQueueDragon(item) { return item.isQueueDragon(); }
static isSouffleDragon(item) {return item.type == TYPES.souffle; } static isSouffleDragon(item) { return item.type == TYPES.souffle; }
static isTeteDragon(item) { return item.type == TYPES.tete; } static isTeteDragon(item) { return item.type == TYPES.tete; }
static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); } static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); }
@ -78,25 +78,45 @@ export class Draconique {
/** /**
* @param {*} img l'url du fichier image à utiliser pour le token. Si indéfini (et si createSprite n'est pas surchargé), * @param {*} img l'url du fichier image à utiliser pour le token. Si indéfini (et si createSprite n'est pas surchargé),
* un disque est utilisé. * un disque est utilisé.
*/ */
img() { return undefined } img() { return undefined }
/** /**
* factory d'élément graphique PIXI correpsondant à l'objet draconique * factory d'élément graphique PIXI correspondant à l'objet 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 token = { const token = {
sprite: this.createSprite(pixiTMR), sprite: this.createSprite(pixiTMR),
coordTMR: coordTMR coordTMR: coordTMR
}; };
token[type ?? this.code()] = linkData; token[type ?? this.code()] = linkData;
console.log("SPRITE: ", token.sprite) this.linkData = linkData;
//PixiTMR.getImgFromCode() if (this.tooltip(linkData)) {
pixiTMR.addTooltip(token.sprite, this.tooltip(linkData)); pixiTMR.addTooltip(token.sprite, (e, s) => this.computeTooltip(e, s));
}
return token; return token;
} }
/**
* methode en charge de recalculer le tooltip lorsque la souris bouge
* @param {*} event evenement contenant les coordonnées
* @param {*} sprite sprite pour laquelle calculer le tooltip
*/
computeTooltip(event, sprite) {
if (sprite.isOver) {
const oddq = TMRUtility.computeEventOddq(event);
const coord = TMRUtility.oddqToCoordTMR(oddq);
const tmr = TMRUtility.getTMR(coord)
if (tmr){
const label = TMRUtility.getTMRLabel(coord);
const text = this.tooltip(this.linkData);
return text ? `${coord}: ${label}\n${text}` : `${coord}: ${label}`
}
}
return '';
}
/** /**
* factory d'élément graphique PIXI correpsondant à l'objet draconique * factory d'élément graphique PIXI correpsondant à l'objet 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.

View File

@ -1,6 +1,8 @@
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";
const tooltipStyle = new PIXI.TextStyle({ export const tooltipStyle = new PIXI.TextStyle({
fontFamily: 'CaslonAntique', fontFamily: 'CaslonAntique',
fontSize: 18, fontSize: 18,
fill: '#FFFFFF', fill: '#FFFFFF',
@ -20,7 +22,7 @@ export class PixiTMR {
this.callbacksOnAnimate = []; this.callbacksOnAnimate = [];
} }
async load( onLoad = (loader, resources) => {} ) { async load(onLoad = (loader, resources) => { }) {
// WIP - Deprecated since v7 : let loader = new PIXI.Loader(); // WIP - Deprecated since v7 : let loader = new PIXI.Loader();
for (const [name, img] of Object.entries(PixiTMR.textures)) { for (const [name, img] of Object.entries(PixiTMR.textures)) {
const texture = await PIXI.Assets.load(img); const texture = await PIXI.Assets.load(img);
@ -40,33 +42,10 @@ export class PixiTMR {
PixiTMR.textures[name] = img; PixiTMR.textures[name] = img;
} }
animate(animation = pixiApp=>{}) animate(animation = pixiApp => { }) {
{
this.callbacksOnAnimate.push(() => animation(this.pixiApp)); this.callbacksOnAnimate.push(() => animation(this.pixiApp));
} }
carteTmr(code) {
let img = PixiTMR.getImgFromCode(code)
const carteTmr = new PIXI.Sprite(PIXI.utils.TextureCache[img]);
console.log(code, carteTmr)
// Setup the position of the TMR
carteTmr.x = 0;
carteTmr.y = 0;
carteTmr.width = 720;
carteTmr.height = 860;
// Rotate around the center
carteTmr.anchor.set(0);
carteTmr.eventMode = 'dynamic'; // PIXI 7 : Not sure ..
// This one is deprecated ; carteTmr.interactive = true;
carteTmr.buttonMode = true;
carteTmr.tmrObject = this;
if (!this.tmrObject.viewOnly) {
carteTmr.on('pointerdown', event => this.onClickBackground(event));
}
this.pixiApp.stage.addChild(carteTmr);
return carteTmr;
}
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];
@ -81,7 +60,7 @@ export class PixiTMR {
if (options.color) { if (options.color) {
sprite.tint = options.color; sprite.tint = options.color;
} }
sprite.zIndex = options.zIndex ?? tmrTokenZIndex.casehumide+1; sprite.zIndex = options.zIndex ?? tmrTokenZIndex.casehumide + 1;
sprite.alpha = options.alpha ?? 0.75; sprite.alpha = options.alpha ?? 0.75;
sprite.decallage = options.decallage ?? tmrConstants.center; sprite.decallage = options.decallage ?? tmrConstants.center;
this.pixiApp.stage.addChild(sprite); this.pixiApp.stage.addChild(sprite);
@ -98,27 +77,37 @@ export class PixiTMR {
return sprite; return sprite;
} }
addTooltip(sprite, text) { addTooltip(sprite, computeTooltip) {
if (text) { sprite.tooltip = new PIXI.Text('', tooltipStyle);
sprite.tooltip = new PIXI.Text(text, tooltipStyle); sprite.tooltip.zIndex = tmrTokenZIndex.tooltip;
sprite.tooltip.zIndex = tmrTokenZIndex.tooltip; sprite.isOver = false;
sprite.isOver = false; sprite.eventMode = 'dynamic'; // PIXI 7 To be checked
// Deprecated : sprite.interactive = true; sprite
sprite.eventMode = 'dynamic'; // PIXI 7 To be checked .on('pointermove', event => this.onPointerMove(event, sprite, computeTooltip))
sprite.on('pointerdown', event => this.onClickBackground(event)) .on('pointerdown', event => this.onClickBackground(event))
.on('pointerover', () => this.onShowTooltip(sprite)) .on('pointerover', event => this.onShowTooltip(event, sprite))
.on('pointerout', () => this.onHideTooltip(sprite)); .on('pointerout', event => this.onHideTooltip(event, sprite));
}
onClickBackground(event) {
if (!this.viewOnly) {
this.tmrObject.onClickTMR(event)
} }
} }
onPointerMove(event, sprite, computeTooltip) {
if (sprite.isOver && sprite.tooltip) {
var { x, y } = TMRUtility.computeEventPosition(event);
const oddq = TMRUtility.computeOddq(x, y);
onClickBackground(event) { sprite.tooltip.x = x + (oddq.col > 8 ? - 3 * tmrConstants.full : tmrConstants.half)
this.tmrObject.onClickTMR(event) sprite.tooltip.y = y + (oddq.row > 10 ? - tmrConstants.half : tmrConstants.half)
sprite.tooltip.text = computeTooltip(event, sprite);
}
} }
onShowTooltip(sprite) { onShowTooltip(event, sprite) {
if (sprite.tooltip) { if (sprite.tooltip) {
if (!sprite.isOver) { if (!sprite.isOver) {
sprite.tooltip.x = sprite.x; sprite.tooltip.x = sprite.x;
sprite.tooltip.y = sprite.y; sprite.tooltip.y = sprite.y;
@ -128,7 +117,7 @@ export class PixiTMR {
} }
} }
onHideTooltip(sprite) { onHideTooltip(event, sprite) {
if (sprite.tooltip) { if (sprite.tooltip) {
if (sprite.isOver) { if (sprite.isOver) {
this.pixiApp.stage.removeChild(sprite.tooltip); this.pixiApp.stage.removeChild(sprite.tooltip);
@ -137,7 +126,7 @@ export class PixiTMR {
} }
} }
setPosition( sprite, oddq) { setPosition(sprite, oddq) {
let decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; let decallagePairImpair = (oddq.col % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x; let dx = (sprite.decallage == undefined) ? 0 : sprite.decallage.x;
let dy = (sprite.decallage == undefined) ? 0 : sprite.decallage.y; let dy = (sprite.decallage == undefined) ? 0 : sprite.decallage.y;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 KiB

BIN
styles/img/ui/tmr.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB

View File

@ -171,6 +171,9 @@ i:is(.fas, .far) {
width: fit-content; width: fit-content;
} }
.tmr-dialog table {
border: none;
}
.system-foundryvtt-reve-de-dragon .sheet-header div.tmr-buttons { .system-foundryvtt-reve-de-dragon .sheet-header div.tmr-buttons {
padding: 0; padding: 0;
margin: 0; margin: 0;

View File

@ -1,7 +1,5 @@
<form class="tmr-dialog"> <form class="tmr-dialog">
<h2 class="comptmrdialog" id="tmrDialogTitle"></h2> <table>
<table id="tmrsheet">
<tr id="tmrrow1"> <tr id="tmrrow1">
<td> <td>
{{#if (eq mode "visu")}} {{#if (eq mode "visu")}}