import { ITEM_TYPES } from "../item.js"; import { TMRUtility } from "../tmr-utility.js"; import { PixiTMR } from "./pixi-tmr.js"; const registeredEffects = [ ] /** * Définition des informations d'une "draconique" (queue, ombre, tête, souffle) qui influence les TMR */ export class Draconique { static init() { } static isCaseTMR(item) { return item.type == ITEM_TYPES.casetmr; } static isQueueDragon(item) { return item.isQueueDragon(); } static isSouffleDragon(item) { return item.type == ITEM_TYPES.souffle; } static isTeteDragon(item) { return item.type == ITEM_TYPES.tete; } static isQueueSouffle(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item); } static register(draconique, code = undefined) { registeredEffects[code ?? draconique.code()] = draconique; if (draconique.img()) { PixiTMR.register(draconique.code(), draconique.img()) } return draconique; } static all() { return Object.values(registeredEffects); } static get(code) { return registeredEffects[code]; } tmrLabel(linkData) { return TMRUtility.getTMRLabel(linkData.system.coord); } /** * @param item un Item quelconque * @returns true si l'item correspond */ match(item) { return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item) || Draconique.isTeteDragon(item); } /** * @returns un message à afficher si la draconique doit être gérée manuellement. */ manualMessage() { return false; } /** * Méthode responsable de gérer une draconique (par exemple, ajouter des casetmr pour la fermeture des cités). * @param actor auquel la draconique est ajoutée */ async onActorCreateOwned(actor, item) { return false; } async onActorDeleteOwned(actor, item) { this.deleteCasesTmr(actor, item); return false; } async onActorDeleteCaseTmr(actor, casetmr) { return false; } /** * @return le code interne utilisé pour les casetmr correpondant */ code() { return undefined } /** * @param {*} linkData données associées au token pixi (une casetmr, un sort en réserve, une rencontre en attente) * @returns un tooltip à afficher au dessus du token */ tooltip(linkData) { return undefined } /** * @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é. */ img() { return undefined } /** * 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. */ token(pixiTMR, linkData, coordTMR, type = undefined) { const tooltip = this.tooltip(linkData); return this._createToken(pixiTMR, linkData, coordTMR, type, tooltip); } tokens(pixiTMR, linkData, coordTMR, type = undefined) { const tooltip = this.tooltip(linkData); return [this._createToken(pixiTMR, linkData, coordTMR, type, tooltip)]; } _createToken(pixiTMR, linkData, coordTMR, type, tooltip) { const token = { sprite: this.createSprite(pixiTMR), coordTMR: coordTMR, tooltip: tooltip }; token[type ?? this.code()] = linkData; return token; } /** * 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. */ createSprite(pixiTMR) { if (this.img()) { return pixiTMR.sprite(this.code()) } else { return pixiTMR.circle() } } /** * * @param {*} item un item à tester * @param {*} coord les coordonnées d'une case. Si undefined toute case du type correspondra, */ isCase(item, coord = undefined) { return Draconique.isCaseTMR(item) && item.system.specific == this.code() && (coord ? item.system.coord == coord : true); } find(list, coord = undefined) { return list.find(c => this.isCase(c, coord)); } async createCaseTmr(actor, label, tmr, sourceId = undefined) { const casetmrData = { name: label, type: 'casetmr', img: this.img(), system: { coord: tmr.coord, specific: this.code(), sourceid: sourceId } }; await actor.createEmbeddedDocuments('Item', [casetmrData]); } async deleteCasesTmr(actor, draconique) { let caseTmrs = actor.items.filter(it => this.isCaseForSource(it, draconique)); await actor.deleteEmbeddedDocuments('Item', caseTmrs.map(it => it.id)); } isCaseForSource(item, draconique) { return Draconique.isCaseTMR(item) && item.system.specific == this.code() && item.system.sourceid == draconique.id; } async onVisiteSupprimer(actor, tmr, onRemoveToken) { let existants = actor.items.filter(it => this.isCase(it, tmr.coord)); await actor.deleteEmbeddedDocuments('Item', existants.map(it => it.id)); for (let casetmr of existants) { onRemoveToken(tmr, casetmr); } } }