diff --git a/lang/fr.json b/lang/fr.json index ee3e67cb..3201992b 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -41,7 +41,8 @@ "TypeOmbre": "Ombre de Thanatos", "TypeSouffle": "Souffle de Dragon", "TypeTete": "Tête de Dragon", - "TypePossession": "Possession" + "TypePossession": "Possession", + "TypeSortreserve": "Sort en réserve" }, "EFFECT": { "StatusStunned": "Sonné", diff --git a/module/actor-sheet.js b/module/actor-sheet.js index b823162a..ba5c6099 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -15,7 +15,7 @@ import { DialogSplitItem } from "./dialog-split-item.js"; import { ReglesOptionelles } from "./regles-optionelles.js"; import { DialogRepos } from "./dialog-repos.js"; import { RdDSheetUtility } from "./rdd-sheet-utility.js"; -import { TMRUtility } from "./tmr-utility.js"; +import { STATUSES } from "./status-effects.js"; /* -------------------------------------------- */ export class RdDActorSheet extends ActorSheet { @@ -100,8 +100,7 @@ export class RdDActorSheet extends ActorSheet { formData.difficultesLibres = CONFIG.RDD.difficultesLibres; formData.hautreve = { - isDemiReve: this.actor.getEffectByLabel("Demi-rêve"), - sortsReserve: formData.system.reve.reserve.list, + isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve), rencontres: duplicate(formData.system.reve.rencontre.list), casesTmr: formData.itemsByType.casetmr, cacheTMR: this.actor.isTMRCache() @@ -184,19 +183,6 @@ export class RdDActorSheet extends ActorSheet { const item = this.actor.getObjet(li.data("item-id")); RdDUtility.confirmerSuppressionItem(this, item, li); }); - html.find('.sort-reserve-delete').click(async event => { - const li = RdDSheetUtility.getEventElement(event); - const index = li.data('index'); - const sortReserve = this.actor.system.reve.reserve.list[index]; - RdDUtility.confirmerSuppression(this, li, { - supprimer: `le sort en réserve ${sortReserve.sort.name} en ${TMRUtility.getTMR(sortReserve.coord).label}`, - deleteLabel: "Supprimer le sort en réserve", - onDelete: () => { - console.log("Delete : ", sortReserve.name); - this.actor.deleteSortReserveKey(index); - } - }); - }); html.find('.item-vendre').click(async event => { const item = RdDSheetUtility.getItem(event, this.actor); item?.proposerVente(); @@ -375,11 +361,15 @@ export class RdDActorSheet extends ActorSheet { await DialogRepos.create(this.actor); }); html.find('.delete-active-effect').click(async event => { - let id = $(event.currentTarget).parents(".active-effect").data('id'); - this.actor.enleverActiveEffectById(id); + if (game.user.isGM) { + let effect = $(event.currentTarget).parents(".active-effect").data('effect'); + this.actor.removeEffect(effect); + } }); html.find('.enlever-tous-effets').click(async event => { - this.actor.enleverTousLesEffets(); + if (game.user.isGM) { + this.actor.enleverTousLesEffets(); + } }); html.find('.conteneur-name a').click(async event => { RdDUtility.toggleAfficheContenu(RdDSheetUtility.getItemId(event)); diff --git a/module/actor.js b/module/actor.js index ee9307a8..33a3055a 100644 --- a/module/actor.js +++ b/module/actor.js @@ -17,7 +17,7 @@ import { RdDAudio } from "./rdd-audio.js"; import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemArme } from "./item-arme.js"; import { RdDAlchimie } from "./rdd-alchimie.js"; -import { StatusEffects } from "./status-effects.js"; +import { STATUSES, StatusEffects } from "./status-effects.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { RdDItemSigneDraconique } from "./item-signedraconique.js"; import { ReglesOptionelles } from "./regles-optionelles.js"; @@ -52,8 +52,6 @@ const POSSESSION_SANS_DRACONIC = { export class RdDActor extends Actor { /* -------------------------------------------- */ static init() { - Hooks.on("deleteActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onDeleteActiveEffect(effect, options)); - Hooks.on("preUpdateItem", (item, change, options, id) => RdDActor.getParentActor(item)?.onPreUpdateItem(item, change, options, id)); Hooks.on("createItem", (item, options, id) => RdDActor.getParentActor(item)?.onCreateItem(item, options, id)); Hooks.on("deleteItem", (item, options, id) => RdDActor.getParentActor(item)?.onDeleteItem(item, options, id)); @@ -418,31 +416,9 @@ export class RdDActor extends Actor { } } - /* -------------------------------------------- */ - async deleteSortReserve(sortReserve) { - let reserve = duplicate(this.system.reve.reserve); - let tmr = TMRUtility.getTMR(sortReserve.coord); - let index = reserve.list.findIndex(tmr.type == 'fleuve' - ? sort => (TMRUtility.getTMR(sort.coord).type == 'fleuve' && sort.sort.name == sortReserve.sort.name) - : sort => (sort.coord == sortReserve.coord && sort.sort.name == sortReserve.sort.name) - ); - if (index >= 0) { - reserve.list.splice(index, 1); - await this.update({ "system.reve.reserve": reserve }); - } - } - - async deleteSortReserveKey(index) { - let reserve = duplicate(this.system.reve.reserve); - if (index >= 0) { - reserve.list.splice(index, 1); - await this.update({ "system.reve.reserve": reserve }, { renderSheet: false }); - } - } - /* -------------------------------------------- */ getSurprise(isCombat = undefined) { - let niveauSurprise = this.getActiveEffects() + let niveauSurprise = this.getEffects() .map(effect => StatusEffects.valeurSurprise(effect, isCombat)) .reduce(Misc.sum(), 0); if (niveauSurprise > 1) { @@ -856,10 +832,13 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async sortMisEnReserve(rollData, sort) { - let reserve = duplicate(this.system.reve.reserve.list); - reserve.push({ coord: rollData.tmr.coord, sort: sort, draconic: duplicate(rollData.competence) }); - await this.update({ "system.reve.reserve.list": reserve }); + async sortMisEnReserve(sort, draconic, coord, ptreve) { + await this.createEmbeddedDocuments("Item", [{ + type: 'sortreserve', + name: sort.name, + img: sort.img, + system: { sortid: sort.id, draconic: (draconic ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' } }], + { renderSheet: false}); this.currentTMR.updateTokens(); } @@ -1140,11 +1119,11 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async deleteAllConteneur(itemId) { + async deleteAllConteneur(itemId, options) { let list = []; list.push({ id: itemId, conteneurId: undefined }); // Init list this.buildSubConteneurObjetList(itemId, list); - await this.deleteEmbeddedDocuments('Item', list.map(it => it.id)); + await this.deleteEmbeddedDocuments('Item', list.map(it => it.id), options); } /* -------------------------------------------- */ @@ -1606,12 +1585,12 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ getSonne() { - return this.getEffectByLabel("EFFECT.StatusStunned"); + return this.getEffect(STATUSES.StatusStunned); } /* -------------------------------------------- */ async finDeRound(options = { terminer: false }) { - for (let effect of this.getActiveEffects()) { + for (let effect of this.getEffects()) { if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) { if (effect.system.origin) { await effect.update({ 'disabled': true }); @@ -1640,7 +1619,7 @@ export class RdDActor extends Actor { ui.notifications.info("Le personnage est hors combat, il ne reste donc pas sonné"); return; } - await this.setStatusEffect("EFFECT.StatusStunned", sonne); + await this.setEffect(STATUSES.StatusStunned, sonne); } /* -------------------------------------------- */ @@ -1793,7 +1772,7 @@ export class RdDActor extends Actor { } await this.update({ "system.sante": sante }) if (this.isDead()) { - await this.setStatusEffect("EFFECT.StatusComma", true); + await this.setEffect(STATUSES.StatusComma, true); } return result; } @@ -2453,7 +2432,7 @@ export class RdDActor extends Actor { RdDItemSort.incrementBonusCase(this, selectedSort, rollData.tmr.coord); if (rollData.isSortReserve) { - await this.sortMisEnReserve(rollData, selectedSort); + await this.sortMisEnReserve(selectedSort, rollData.competence, rollData.tmr.coord, Number(selectedSort.system.ptreve_reel)); } } else { @@ -2465,6 +2444,7 @@ export class RdDActor extends Actor { if (rolled.isETotal) { // Echec total ! rollData.depenseReve = Math.min(reveActuel, Math.floor(rollData.depenseReve * 1.5)) // TODO: mise en réserve d'un échec total... + // await dialog mse en réserve, pour traitement échec total } else { rollData.depenseReve = 0 } @@ -3176,8 +3156,7 @@ export class RdDActor extends Actor { ui.notifications.warn("Vous êtes déja dans les TMR...."); return } - let demiReve = this.getActiveEffects(it => it.label == "Demi-rêve"); - if (mode != 'visu' && demiReve.length > 0) { + if (mode != 'visu' && this.getEffect(STATUSES.StatusDemiReve)) { ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement"); mode = "visu"; // bascule le mode en visu automatiquement } @@ -3192,7 +3171,7 @@ export class RdDActor extends Actor { }); return; } - await this.setStatusEffect("EFFECT.StatusDemiReve", true); + await this.setEffect(STATUSES.StatusDemiReve, true); } const fatigue = this.system.sante.fatigue.value; @@ -3482,7 +3461,7 @@ export class RdDActor extends Actor { count--; } else { // TODO: status effect dead - this.setStatusEffect("EFFECT.StatusComma", true); + this.setEffect(STATUSES.StatusComma, true); ChatMessage.create({ content: ` ${this.name} vient de succomber à une seconde blessure critique ! Que les Dragons gardent son Archétype en paix !` @@ -4117,61 +4096,44 @@ export class RdDActor extends Actor { async onUpdateActor(update, options, actorId) { const updatedEndurance = update?.system?.sante?.endurance if (updatedEndurance && options.diff) { - await this.setStatusEffect("EFFECT.StatusUnconscious", updatedEndurance.value == 0) + await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0) } } /* -------------------------------------------- */ - async onDeleteActiveEffect(effect, options) { - switch (effect.label) { - case 'EFFECT.StatusStunned': - return; - } + getEffects() { + return this.getEmbeddedCollection("ActiveEffect"); } /* -------------------------------------------- */ - getActiveEffects(matching = it => true) { - return Array.from(this.getEmbeddedCollection("ActiveEffect").values()).filter(it => matching(it)); + getEffect(statusId) { + return this.getEmbeddedCollection("ActiveEffect").find(it => it.flags?.core?.statusId == statusId); } /* -------------------------------------------- */ - getEffectByLabel(label) { - return this.getActiveEffects().find(it => it.system?.label == label); - } - - /* -------------------------------------------- */ - getEffectById(id) { - return this.getActiveEffects().find(it => it.id == id); - } - - /* -------------------------------------------- */ - async setStatusEffect(label, status, updates = {}) { + async setEffect(statusId, status) { if (this.isEntite() || this.type == 'vehicule') { return; } - console.log("setStatusEffect", label, status, updates) - const existing = this.getEffectByLabel(label); - if (existing) { - existing.delete(); - } - if (status) { - const statusEffect = mergeObject(duplicate(StatusEffects.status(label)), updates); - await this.createEmbeddedDocuments("ActiveEffect", [statusEffect]); + console.log("setEffect", statusId, status) + await this.removeEffect(statusId); + const effect = StatusEffects.status(statusId); + if (effect) { + await this.createEmbeddedDocuments("ActiveEffect", [effect]); } } - enleverActiveEffectById(id) { - if (game.user.isGM) { - const existing = this.getEffectById(id); - if (existing) { - existing.delete(); - } + async removeEffect(statusId) { + const effect = this.getEffect(statusId); + if (effect) { + await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]); } } + /* -------------------------------------------- */ enleverTousLesEffets() { if (game.user.isGM) { - this.deleteEmbeddedDocuments('ActiveEffect', this.getActiveEffects().map(it => it.id)); + this.deleteEmbeddedDocuments('ActiveEffect', this.getEffects().map(it => it.id)); } } diff --git a/module/constants.js b/module/constants.js index 675749ed..2861889b 100644 --- a/module/constants.js +++ b/module/constants.js @@ -1,5 +1,6 @@ export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon'; export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon'; +export const LOG_HEAD = 'RdD | '; export const HIDE_DICE = 'hide'; export const SHOW_DICE = 'show'; diff --git a/module/item-sheet.js b/module/item-sheet.js index 933b4642..ee2abc4a 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -84,32 +84,36 @@ export class RdDItemSheet extends ItemSheet { } formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences() - if (formData.type == 'tache' || formData.type == 'livre' || formData.type == 'meditation' || formData.type == 'oeuvre') { + if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') { formData.caracList = duplicate(game.system.model.Actor.personnage.carac) formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve) formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences') } - if (formData.type == 'arme') { + if (this.item.type == 'arme') { formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it)); console.log(formData.competences) } - if (formData.type == 'recettealchimique') { + if (this.item.type == 'recettealchimique') { RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id); } - if (formData.type == 'gemme') { + if (this.item.type == 'gemme') { formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); RdDGemme.calculDataDerivees(this.item); } - if (formData.type == 'potion') { + if (this.item.type == 'potion') { if (this.dateUpdated) { formData.system.prdate = this.dateUpdated; this.dateUpdated = undefined; } RdDHerbes.updatePotionData(formData); } - if (formData.isOwned && formData.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) { + if (formData.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) { formData.isIngredientPotionBase = true; } + if (this.item.type == 'sortreserve') { + const sortId = this.item.system.sortid; + formData.sort = formData.isOwned ? this.item.actor.items.get(sortId) : game.items.get(sortId); + } formData.bonusCaseList = RdDItemSort.getBonusCaseList(formData, true); return formData; diff --git a/module/item.js b/module/item.js index 7f9003d8..3e8a8cd9 100644 --- a/module/item.js +++ b/module/item.js @@ -36,7 +36,8 @@ export const defaultItemImg = { nourritureboisson: "systems/foundryvtt-reve-de-dragon/icons/objets/provision_crue.webp", signedraconique: "systems/foundryvtt-reve-de-dragon/icons/tmr/signe_draconique.webp", gemme: "systems/foundryvtt-reve-de-dragon/icons/gemmes/almaze.webp", - possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp" + possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", + sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", } /* -------------------------------------------- */ diff --git a/module/migrations.js b/module/migrations.js new file mode 100644 index 00000000..9bd75d62 --- /dev/null +++ b/module/migrations.js @@ -0,0 +1,103 @@ +import { LOG_HEAD, SYSTEM_RDD } from "./constants.js"; + +class Migration { + get code() { return "sample"; } + get version() { return "0.0.0"; } + async migrate() { } +} + +class _10_0_16_MigrationSortsReserve extends Migration { + get code() { return "creation-item-sort-reserve"; } + get version() { return "10.0.16"; } + + async migrate() { + await game.actors + .filter((actor) => actor.type == "personnage") + .filter((actor) => actor.system.reve?.reserve?.list?.length ?? 0 > 0) + .forEach(async (actor) => { + const sortsReserve = actor.system.reve.reserve.list.map(this.conversionSortReserve); + console.log(LOG_HEAD + "Migration des sorts ", sortsReserve); + await actor.createEmbeddedDocuments("Item", sortsReserve, { + renderSheet: false, + }); + await actor.update({'system.reve.reserve.list':[]}) + }); + } + + conversionSortReserve(it) { + return { + type: 'sortreserve', + name: it.sort.name, + img: it.sort.img, + system: { + // ATTENTION, utilisation de data / _id possibles, encore présents pour les anciens sorts en réserve + sortid: it.sort._id, + draconic: it.sort.draconic, + ptreve: (it.sort.system ?? it.sort.data).ptreve_reel, + coord: it.coord, + heurecible: 'Vaisseau', + }, + }; + } +} + +export class Migrations { + static getMigrations() { + return [ + new _10_0_16_MigrationSortsReserve() + ]; + } + + constructor() { + game.settings.register(SYSTEM_RDD, "systemMigrationVersion", { + name: "System Migration Version", + scope: "world", + config: false, + type: String, + default: "0.0.0", + }); + } + + migrate() { + const currentVersion = game.settings.get( + SYSTEM_RDD, + "systemMigrationVersion" + ); + if (isNewerVersion(game.system.version, currentVersion)) { + const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion)); + // if (true) { + // const migrations = Migrations.getMigrations(); + if (migrations.length > 0) { + migrations.sort((a, b) => + isNewerVersion(a.version, b.version) + ? 1 + : isNewerVersion(b.version, a.version) + ? -1 + : 0 + ); + migrations.forEach(async (m) => { + ui.notifications.info( + `Executing migration ${m.code}: version ${currentVersion} is lower than ${m.version}` + ); + await m.migrate(); + }); + ui.notifications.info( + `Migrations done, version will change to ${game.system.version}` + ); + } else { + console.log( + LOG_HEAD + + `No migration needeed, version will change to ${game.system.version}` + ); + } + + game.settings.set( + SYSTEM_RDD, + "systemMigrationVersion", + game.system.version + ); + } else { + console.log(LOG_HEAD + `No system version changed`); + } + } +} diff --git a/module/rdd-combat.js b/module/rdd-combat.js index fee00988..30456d43 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -10,6 +10,7 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDRoll } from "./rdd-roll.js"; import { RdDRollTables } from "./rdd-rolltables.js"; import { ReglesOptionelles } from "./regles-optionelles.js"; +import { STATUSES } from "./status-effects.js"; /* -------------------------------------------- */ const premierRoundInit = [ @@ -1185,7 +1186,7 @@ export class RdDCombat { defenderRoll.show.recul = 'encaisse'; } else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) { defenderRoll.show.recul = 'chute'; - await this.defender.setStatusEffect("EFFECT.StatusProne", true); + await this.defender.setEffect(STATUSES.StatusProne, true); } else { defenderRoll.show.recul = 'recul'; diff --git a/module/rdd-main.js b/module/rdd-main.js index a01bc08c..cfb87b59 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -35,6 +35,7 @@ import { RdDDice } from "./rdd-dice.js"; import { RdDPossession } from "./rdd-possession.js"; import { RdDSigneDraconiqueItemSheet } from "./item-signedraconique-sheet.js"; import { Misc } from "./misc.js"; +import { Migrations } from './migrations.js'; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -183,7 +184,7 @@ Hooks.once("init", async function () { Items.registerSheet(SYSTEM_RDD, RdDItemSheet, { types: ["arme", "armure", "objet", "arme", "armure", "conteneur", "competence", "sort", "herbe", "ingredient", "livre", "potion", "munition", "rencontresTMR", "queue", "ombre", "souffle", "tete", "competencecreature", "tarot", "monnaie", "nombreastral", "tache", "meditation", "casetmr", "recettealchimique", "gemme", - "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession"], makeDefault: true + "musique", "chant", "danse", "jeu", "recettecuisine", "maladie", "poison", "oeuvre", "nourritureboisson", "possession", "sortreserve"], makeDefault: true }); CONFIG.Combat.documentClass = RdDCombatManager; @@ -245,6 +246,9 @@ function registerUsageCount( registerKey ) { /* -------------------------------------------- */ Hooks.once("ready", async function () { await migrationPngWebp_1_5_34() + if (Misc.isUniqueConnectedGM()) { + new Migrations().migrate(); + } StatusEffects.onReady(); RdDHerbes.initializeHerbes(); diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index fce54383..7ff6d0c3 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -1,4 +1,3 @@ -import { SYSTEM_SOCKET_ID } from "./constants.js"; import { RollDataAjustements } from "./rolldata-ajustements.js"; import { RdDUtility } from "./rdd-utility.js"; import { TMRUtility } from "./tmr-utility.js"; @@ -16,6 +15,7 @@ import { Misc } from "./misc.js"; import { HtmlUtility } from "./html-utility.js"; import { ReglesOptionelles } from "./regles-optionelles.js"; import { RdDDice } from "./rdd-dice.js"; +import { STATUSES } from "./status-effects.js"; /* -------------------------------------------- */ export class RdDTMRDialog extends Dialog { @@ -55,7 +55,6 @@ export class RdDTMRDialog extends Dialog { this.fatigueParCase = this.viewOnly || !ReglesOptionelles.isUsing("appliquer-fatigue") ? 0 : this.actor.getTMRFatigue(); this.cumulFatigue = 0; this.loadRencontres(); - this.loadSortsReserve(); this.loadCasesSpeciales(); this.allTokens = []; this.rencontreState = 'aucune'; @@ -81,9 +80,16 @@ export class RdDTMRDialog extends Dialog { this.casesSpeciales = this.actor.items.filter(item => Draconique.isCaseTMR(item)); } - /* -------------------------------------------- */ - loadSortsReserve() { - this.sortsReserves = this.actor.system.reve.reserve.list; + get sortsReserve() { + return this.actor.itemTypes['sortreserve']; + } + + getSortsReserve(coord) { + return this.actor.itemTypes['sortreserve'].filter(// Reserve sur une case fleuve ou normale + TMRUtility.getTMR(coord).type == 'fleuve' + ? it => TMRUtility.getTMR(it.system.coord).type == 'fleuve' + : it => it.system.coord == coord + ); } /* -------------------------------------------- */ @@ -97,10 +103,10 @@ export class RdDTMRDialog extends Dialog { this.updateTokens(); this.forceDemiRevePositionView(); } - + /* -------------------------------------------- */ _createTokens() { - if (!this.isDemiReveCache()){ + if (!this.isDemiReveCache()) { this.demiReve = this._tokenDemiReve(); this._trackToken(this.demiReve); } @@ -117,7 +123,6 @@ export class RdDTMRDialog extends Dialog { updateTokens() { this._removeTokens(t => true); this.loadRencontres(); - this.loadSortsReserve(); this.loadCasesSpeciales(); this._createTokens(); } @@ -136,7 +141,7 @@ export class RdDTMRDialog extends Dialog { return this.rencontresExistantes.map(it => this._tokenRencontre(it)); } _getTokensSortsReserve() { - return this.sortsReserves.map(it => this._tokenSortEnReserve(it)); + return this.actor.itemTypes['sortreserve'].map(it => this._tokenSortEnReserve(it)); } /* -------------------------------------------- */ @@ -148,8 +153,8 @@ export class RdDTMRDialog extends Dialog { const draconique = Draconique.get(caseData.system.specific); return draconique?.token(this.pixiTMR, caseData, () => caseData.system.coord); } - _tokenSortEnReserve(sortEnReserve) { - return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortEnReserve.sort, () => sortEnReserve.coord); + _tokenSortEnReserve(sortReserve) { + return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortReserve, () => sortReserve.system.coord); } _tokenDemiReve() { @@ -254,9 +259,9 @@ export class RdDTMRDialog extends Dialog { let tmrpos = document.getElementById("tmr-pos"); if (this.isDemiReveCache()) { - tmrpos.innerHTML = '?? (' + TMRUtility.getTMRType(coord) + ')'; + tmrpos.innerHTML = `?? ( ${ TMRUtility.getTMRType(coord)})`; } else { - tmrpos.innerHTML = coord + " (" + TMRUtility.getTMRLabel(coord) + ")"; + tmrpos.innerHTML = `${coord} ( ${TMRUtility.getTMRLabel(coord)})`; } let etat = document.getElementById("tmr-etatgeneral-value"); @@ -272,15 +277,16 @@ export class RdDTMRDialog extends Dialog { } /* -------------------------------------------- */ - close() { - if ( this.actor.tmrApp ) { + async close() { + if (this.actor.tmrApp) { this.actor.tmrApp = undefined; // Cleanup reference - if ( !this.viewOnly ) { - this.actor.setStatusEffect("EFFECT.StatusDemiReve", false); + if (!this.viewOnly) { + await this.actor.setEffect(STATUSES.StatusDemiReve, false) this._tellToGM(this.actor.name + " a quitté les terres médianes"); } - this.actor.santeIncDec("fatigue", this.cumulFatigue).then(super.close()); // moving 1 cell costs 1 fatigue + await this.actor.santeIncDec("fatigue", this.cumulFatigue) } + await super.close(); // moving 1 cell costs 1 fatigue } /* -------------------------------------------- */ @@ -316,11 +322,11 @@ export class RdDTMRDialog extends Dialog { 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) { - let rect = this._getCaseRectangleCoord(coordTMR); - var rectDraw = new PIXI.Graphics(); - rectDraw.beginFill(0xFFFF00, 0.3); + 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); + rectDraw.lineStyle(5, 0xff0000); // draw a rectangle rectDraw.drawRect(rect.x, rect.y, rect.w, rect.h); this.pixiApp.stage.addChild(rectDraw); @@ -336,19 +342,13 @@ export class RdDTMRDialog extends Dialog { /* -------------------------------------------- */ async choisirCasePortee(coord, portee) { - if (this.actor.isTMRCache()) - { - return; - } // Récupère la liste des cases à portées - let locList = TMRUtility.getTMRPortee(coord, portee); - this.colorierZoneRencontre(locList); + this.colorierZoneRencontre(TMRUtility.getTMRPortee(coord, portee)); } /* -------------------------------------------- */ async choisirCaseType(type) { - const locList = TMRUtility.filterTMR(it => it.type == type).map(it => it.coord); - this.colorierZoneRencontre(locList); + this.colorierZoneRencontre(TMRUtility.filterTMR(it => it.type == type).map(it => it.coord)); } /* -------------------------------------------- */ @@ -573,6 +573,9 @@ export class RdDTMRDialog extends Dialog { /* -------------------------------------------- */ async manageTmrInnaccessible(tmr) { + if (!tmr) { + return await this.actor.reinsertionAleatoire('Sortie de carte'); + } const caseTmrInnaccessible = this.casesSpeciales.find(c => EffetsDraconiques.isInnaccessible(c, tmr.coord)); if (caseTmrInnaccessible) { return await this.actor.reinsertionAleatoire(caseTmrInnaccessible.name); @@ -774,9 +777,8 @@ export class RdDTMRDialog extends Dialog { /* -------------------------------------------- */ async declencheSortEnReserve(coord) { - - let sortsEnCoord = TMRUtility.getSortsReserve(this.sortsReserves, coord); - if (sortsEnCoord.length > 0) { + let sorts = this.getSortsReserve(coord); + if (sorts.length > 0) { if (EffetsDraconiques.isSortReserveImpossible(this.actor)) { ui.notifications.error("Une queue ou un souffle vous empèche de déclencher de sort!"); return; @@ -784,8 +786,8 @@ export class RdDTMRDialog extends Dialog { if (!EffetsDraconiques.isUrgenceDraconique(this.actor) && (EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coord))) { let msg = "Vous êtes sur une case avec un Sort en Réserve. Grâce à votre Tête Reserve en Sécurité ou Réserve Exensible, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher :