Gestion queues/souffles

- débordement
- conquête
This commit is contained in:
Vincent Vandemeulebrouck 2021-02-12 01:44:27 +01:00
parent 42bd63c999
commit 5328d2b690
12 changed files with 312 additions and 115 deletions

View File

@ -1121,6 +1121,24 @@ export class RdDActor extends Actor {
return queue;
}
/* -------------------------------------------- */
async reinsertionAleatoire(raison) {
ChatMessage.create({
content: `${raison} : ré-insertion aléatoire.`,
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name)
});
const innaccessible = this.buildTMRInnaccessible();
let tmr = TMRUtility.getTMRAleatoire(tmr => !innaccessible.includes(tmr.coord) );
this.updateCoordTMR(tmr.coord);
return tmr;
}
buildTMRInnaccessible() {
const tmrInnaccessibles = this.data.items.filter(it => Draconique.isCaseTMR(it) &&
EffetsDraconiques.isInnaccessible(it));
return tmrInnaccessibles.map(it => it.data.coord);
}
/* -------------------------------------------- */
displayTMRQueueSouffleInformation() {
let messages = [];
@ -1137,9 +1155,6 @@ export class RdDActor extends Actor {
if (EffetsDraconiques.isPeriple(item)) {
messages.push("Vous souffrez du Souffle <strong>Périple</strong>. Vous devez gérer manuellement le détail du Périple.<br>" + item.data.description);
}
if (EffetsDraconiques.isDesorientation(item)) {
messages.push("Vous souffrez du Souffle <strong>Désorientation</strong>. Vous devez gérer avec votre MJ les effets de ce souffle.<br>" + item.data.description);
}
}
if (messages.length > 0) {
@ -1796,6 +1811,10 @@ export class RdDActor extends Actor {
ui.notifications.info("Aucun sort disponible pour cette case !");
return;
}
if (EffetsDraconiques.isConquete(this)) {
ui.notifications.error("Vous ne pouvez pas lancer de sort sous l'effet d'une conquête!");
return;
}
if (this.currentTMR) this.currentTMR.minimize(); // Hide
let draconicList = this.filterDraconicList(sortList);

View File

@ -10,6 +10,7 @@ import { Poetique } from "./poetique.js";
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
import { PixiTMR } from "./tmr/pixi-tmr.js";
import { Draconique } from "./tmr/draconique.js";
import { Grammar } from "./grammar.js";
/* -------------------------------------------- */
export class RdDTMRDialog extends Dialog {
@ -50,7 +51,7 @@ export class RdDTMRDialog extends Dialog {
this.cumulFatigue = 0;
this.loadRencontres();
this.loadSortsReserve();
this.casesSpeciales = this.actor.data.items.filter(item => Draconique.isCaseTMR(item));
this.loadCasesSpeciales();
this.allTokens = [];
this.rencontreState = 'aucune';
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
@ -66,6 +67,10 @@ export class RdDTMRDialog extends Dialog {
this.pixiTMR.load((loader, resources) => this.createPixiSprites());
}
loadCasesSpeciales() {
this.casesSpeciales = this.actor.data.items.filter(item => Draconique.isCaseTMR(item));
}
loadSortsReserve() {
this.sortsReserves = duplicate(this.actor.data.data.reve.reserve.list);
}
@ -99,6 +104,7 @@ export class RdDTMRDialog extends Dialog {
this._removeTokens(t => true);
this.loadRencontres();
this.loadSortsReserve();
this.loadCasesSpeciales();
this._createTokens();
}
@ -396,10 +402,13 @@ export class RdDTMRDialog extends Dialog {
if (rencontre) {
return rencontre;
}
// TODO: dialog pour remplacer la rencontre par un présent
//if (this.casesSpeciales.find(c => EffetsDraconiques.isPresentCite(c, tmr.coord))) {
if (this.casesSpeciales.find(c => EffetsDraconiques.isPresentCite(c, tmr.coord))) {
// TODO: dialog pour remplacer la rencontre par un présent
}
let myRoll = new Roll("1d7").evaluate().total;
if (TMRUtility.isForceRencontre() || myRoll == 7) {
return await this.rencontreTMRRoll(tmr, this.actor.isRencontreSpeciale());
@ -415,30 +424,22 @@ export class RdDTMRDialog extends Dialog {
? await TMRRencontres.getMauvaiseRencontre()
: await TMRRencontres.getRencontreAleatoire(tmr.type));
rencontre.coord = tmr.coord;
rencontre.date = game.system.rdd.calendrier.getDateFromIndex();
rencontre.date = game.system.rdd.calendrier.getDateFromIndex();
rencontre.heure = game.system.rdd.calendrier.getCurrentHeure();
return rencontre;
}
/* -------------------------------------------- */
async manageCaseSpeciale(tmr) {
if (this.casesSpeciales.find(c => EffetsDraconiques.isCaseTrouNoir(c, tmr.coord))) {
let newTMR = TMRUtility.getTMRAleatoire();
let tmrPos = duplicate(this.actor.data.data.reve.tmrpos);
tmrPos.coord = newTMR.coord;
await this.actor.update({ "data.reve.tmrpos": tmrPos });
ChatMessage.create({
content: "Vous êtes rentré sur un Trou Noir : ré-insertion aléatoire.",
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
async manageTmrInnaccessible(tmr) {
const caseTmrInnaccessible = this.casesSpeciales.find(c => EffetsDraconiques.isInnaccessible(c, tmr.coord));
if (caseTmrInnaccessible) {
return await this.actor.reinsertionAleatoire(caseTmrInnaccessible.name);
}
return tmr;
}
/* -------------------------------------------- */
async manageCaseHumide(tmr) {
if (this.viewOnly || this.currentRencontre) {
return;
}
if (this.isCaseHumide(tmr)) {
let rollData = {
actor: this.actor,
@ -517,26 +518,52 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */
async conquerirCiteFermee(tmr) {
if (this.viewOnly || this.currentRencontre) {
return;
}
const citeFermee = this.isCiteFermee(tmr.coord);
if (citeFermee) {
let rollData = {
actor: this.actor,
competence: duplicate(this.actor.getBestDraconic()),
tmr: tmr,
canClose: false,
diffLibre: -9,
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.actor.getReveActuel() } },
maitrise: { verbe: 'conquérir', action: 'Conquérir la cité' }
}
rollData.competence.data.defaut_carac = 'reve-actuel';
await this._maitriserTMR(rollData, r => this._resultatConqueteCiteFermee(r));
if (EffetsDraconiques.fermetureCites.find(this.casesSpeciales, tmr.coord)) {
await this._conquerir(tmr, {
difficulte: -9,
action: 'Conquérir la cité',
onConqueteReussie: r => EffetsDraconiques.fermetureCites.onConquete(r.actor, tmr.coord),
onConqueteEchec: r => this.close(),
canClose: false
});
}
}
async _resultatConqueteCiteFermee(rollData) {
removeToken(tmr, casetmr) {
this._removeTokens(t => t.coordTMR() == tmr.coord && t.caseSpeciale?._id == casetmr._id);
this.updateTokens()
}
/* -------------------------------------------- */
async conquerirTMR(tmr) {
if (EffetsDraconiques.conquete.find(this.casesSpeciales, tmr.coord)) {
await this._conquerir(tmr, {
difficulte: -7,
action: 'Conquérir',
onConqueteReussie: r => EffetsDraconiques.conquete.onConquete(r.actor, tmr.coord, (casetmr) => this.removeToken(tmr, casetmr)),
onConqueteEchec: r => {},
canClose: false
});
}
}
/* -------------------------------------------- */
async _conquerir(tmr, options) {
let rollData = {
actor: this.actor,
competence: duplicate(this.actor.getBestDraconic()),
tmr: tmr,
canClose: options.canClose ?? false,
diffLibre: options.difficulte ?? -7,
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.actor.getReveActuel() } },
maitrise: { verbe: 'conquérir', action: options.action }
};
rollData.competence.data.defaut_carac = 'reve-actuel';
await this._maitriserTMR(rollData, r => this._onResultatConquerir(r, options));
}
async _onResultatConquerir(rollData, options) {
if (rollData.rolled.isETotal) {
rollData.souffle = await this.actor.ajouterSouffle({ chat: false });
}
@ -548,12 +575,11 @@ export class RdDTMRDialog extends Dialog {
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-maitrise-tmr.html`, rollData)
});
if (rollData.rolled.isEchec) {
this.close();
options.onConqueteEchec(rollData, options.effetDraconique);
}
else {
const citeFermee = this.actor.data.items.find(it => EffetsDraconiques.isCiteFermee(it, rollData.tmr.coord));
this.actor.deleteOwnedItem(citeFermee._id);
this._removeTokens(t => t.coordTMR() == citeFermee.data.coord && t.caseSpeciale?._id == citeFermee._id);
await options.onConqueteReussie(rollData, options.effetDraconique);
this.updateTokens();
}
}
@ -578,17 +604,18 @@ export class RdDTMRDialog extends Dialog {
}
/* -------------------------------------------- */
async declencheSortEnReserve(coordTMR) {
if (this.viewOnly) {
return;
}
let sortReserveList = TMRUtility.getSortReserveList(this.sortsReserves, coordTMR);
async declencheSortEnReserve(coord) {
let sortReserveList = TMRUtility.getSortReserveList(this.sortsReserves, coord);
if (sortReserveList.length > 0) {
if (EffetsDraconiques.isReserveEnSecurite(this.actor) || this.isReserveExtensible(coordTMR)) {
if (EffetsDraconiques.isConquete(this.actor)) {
ui.notifications.error("Vous ne pouvez pas déclencher de sort sous l'effet d'une conquête!");
return;
}
if (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 <strong>Reserve en Sécurité</strong> ou <strong>Réserve Exensible</strong>, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher : <ul>";
for (let sortReserve of sortReserveList) {
msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='" + this.actor._id + "' data-tmr-coord='" + coordTMR + "' data-sort-id='" + sortReserve.sort._id + "'>" + sortReserve.sort.name + "</a></li>";
msg += "<li><a class='chat-card-button' id='sort-reserve' data-actor-id='" + this.actor._id + "' data-tmr-coord='" + coord + "' data-sort-id='" + sortReserve.sort._id + "'>" + sortReserve.sort.name + "</a></li>";
}
msg += "</ol>";
ChatMessage.create({
@ -640,40 +667,28 @@ export class RdDTMRDialog extends Dialog {
this.rencontreState = 'aucune'; // Et de l'état
}
/* -------------------------------------------- */
processClickPostRencontre(coord) {
if (this.rencontreState == 'passeur' || this.rencontreState == 'messager' || this.rencontreState == 'changeur') {
console.log("Searching", this.currentRencontre.locList, coord);
let isInArea = this.currentRencontre.locList.find(locCoord => locCoord == coord);
if (isInArea) { // OK !
return (this.rencontreState == 'messager') ? 'messager' : 'saut';
}
}
return "erreur";
}
/* -------------------------------------------- */
isCaseInondee(coord) {
return this.casesSpeciales.find(c => EffetsDraconiques.isCaseInondee(c, coord));
return EffetsDraconiques.debordement.find(this.casesSpeciales, coord);
}
isCiteFermee(coord) {
return this.casesSpeciales.find(c => EffetsDraconiques.isCiteFermee(c, coord));
return EffetsDraconiques.fermetureCites.find(this.casesSpeciales, coord);
}
/* -------------------------------------------- */
isTerreAttache(coord) {
return this.casesSpeciales.find(c => EffetsDraconiques.isTerreAttache(c, coord));
return EffetsDraconiques.terreAttache.find(this.casesSpeciales, coord);
}
/* -------------------------------------------- */
isCaseMaitrisee(coord) {
return this.casesSpeciales.find(c => EffetsDraconiques.isCaseMaitrisee(c, coord));
return EffetsDraconiques.queteEaux.find(this.casesSpeciales, coord);
}
/* -------------------------------------------- */
isReserveExtensible(coord) {
return this.casesSpeciales.find(c => EffetsDraconiques.isReserveExtensible(c, coord));
return EffetsDraconiques.reserveExtensible.find(this.casesSpeciales, coord);
}
/* -------------------------------------------- */
@ -719,8 +734,29 @@ export class RdDTMRDialog extends Dialog {
this.checkQuitterTMR();
}
async _messagerDemiReve(targetCoordTMR) {
await this.actor.rollUnSort(targetCoordTMR);
/* -------------------------------------------- */
_calculDeplacement(targetCoord, currentCoord, currentPos, eventPos) {
let isInArea = this.rencontreState == 'aucune'
? this.isTerreAttache(targetCoord) || this.isConnaissanceFleuve(currentCoord, targetCoord) || !RdDTMRDialog._horsDePortee(currentPos, eventPos)
: this.currentRencontre?.locList.find(coord => coord == targetCoord) ?? false
if (isInArea) {
switch (this.rencontreState) {
case 'aucune': return 'normal';
case 'messager': return 'messager';
case 'passeur': case 'changeur': return 'saut';
}
}
return 'erreur'
}
/* -------------------------------------------- */
async _messagerDemiReve(targetCoord) {
/*
TODO: si la case a un sort en réserve, lancer ce sort.
Si la case est le demi-rêve, ne pas lancer de sort.
Si un lancement de sort est en cours, trouver un moyen de réafficher cette fenêtre si on essaie de lancer un sort (ou bloquer le lancer de sort)
*/
await this.actor.rollUnSort(targetCoord);
this.nettoyerRencontre();
}
@ -729,14 +765,12 @@ export class RdDTMRDialog extends Dialog {
this.nettoyerRencontre();
}
let tmr = TMRUtility.getTMR(targetCoord);
console.log("deplacerDemiReve", tmr, this);
// Gestion cases spéciales type Trou noir, etc
tmr = await this.manageTmrInnaccessible(tmr);
await this.manageCaseSpeciale(tmr); // Gestion cases spéciales type Trou noir, etc
console.log("deplacerDemiReve: TMR is", tmr, this);
let tmrPos = duplicate(this.actor.data.data.reve.tmrpos);
tmrPos.coord = targetCoord;
await this.actor.update({ "data.reve.tmrpos": tmrPos });
this.actor.updateCoordTMR(tmr.coord);
await this.actor.updateCoordTMR(tmr.coord);
this._updateDemiReve();
this.cumulFatigue += this.fatigueParCase;
@ -757,25 +791,31 @@ export class RdDTMRDialog extends Dialog {
}
async postRencontre(tmr) {
await this.manageCaseHumide(tmr);
await this.conquerirCiteFermee(tmr);
await this.declencheSortEnReserve(tmr.coord);
await this.actor.checkSoufflePeage(tmr);
if (!(this.viewOnly || this.currentRencontre)) {
await this.manageCaseHumide(tmr);
await this.conquerirCiteFermee(tmr);
await this.conquerirTMR(tmr);
await this.declencheSortEnReserve(tmr.coord);
await this.actor.checkSoufflePeage(tmr);
}
}
/* -------------------------------------------- */
async forceDemiRevePositionView(coordTMR) {
async forceDemiRevePositionView() {
this._updateDemiReve();
}
/* -------------------------------------------- */
async forceDemiRevePosition(coordTMR) {
await this.actor.updateCoordTMR(coordTMR);
async forceDemiRevePosition(coord) {
await this.actor.updateCoordTMR(coord);
this._updateDemiReve();
let tmr = TMRUtility.getTMR(coordTMR);
await this.manageCaseHumide(tmr);
await this.conquerirCiteFermee(tmr);
await this.declencheSortEnReserve(tmr.coord);
let tmr = TMRUtility.getTMR(coord);
if (!(this.viewOnly || this.currentRencontre)) {
await this.manageCaseHumide(tmr);
await this.conquerirCiteFermee(tmr);
await this.declencheSortEnReserve(tmr.coord);
}
return tmr;
}
/* -------------------------------------------- */

View File

@ -272,6 +272,12 @@ const rencontresStandard = [
{ code: "rdd", name: "Rêve de Dragon", type: "rdd", genre: "m", force: "1ddr + 7", refoulement: 2, quitterTMR: true }
];
const presentsCite = [
{ code: "messager2d6", name: "Messager des Rêves", type: "messager", genre: "m", force: "2d6", ignorer: true },
{ code: "passeur2d6", name: "Passeur des Rêves", type: "passeur", genre: "m", force: "2d6", ignorer: true },
{ code: "fleur2d6", name: "Fleur des Rêves", type: "fleur", genre: "f", force: "2d6", ignorer: true }
]
const tableRencontres = {
cite: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
sanctuaire: [{ code: 'messager', range: [1, 25] }, { code: 'passeur', range: [26, 50] }, { code: 'fleur', range: [51, 65] }, { code: 'mangeur', range: [66, 70] }, { code: 'changeur', range: [71, 80] }, { code: 'briseur', range: [81, 85] }, { code: 'reflet', range: [86, 90] }, { code: 'tbblanc', range: [91, 94] }, { code: 'tbnoir', range: [95, 97] }, { code: 'rdd', range: [98, 100] }],
@ -466,7 +472,7 @@ export class TMRRencontres {
static async _toubillonner(tmrDialog, actor, cases) {
let coord = actor.data.data.reve.tmrpos.coord;
for (let i = 0; i < cases; i++) {
coord = TMRUtility.deplaceTMRAleatoire(coord);
coord = TMRUtility.deplaceTMRAleatoire(actor, coord).coord;
}
await tmrDialog.forceDemiRevePosition(coord)
}
@ -477,7 +483,7 @@ export class TMRRencontres {
}
await data.actor.resultCombatReveDeDragon(data);
}
static async onPostEchecReveDeDragon(tmrDialog, data) {
await data.actor.resultCombatReveDeDragon(data);
tmrDialog.close();

View File

@ -90,7 +90,7 @@ const TMRMapping = {
A7: { type: "plaines", label: "Plaines de lArc" },
B7: { type: "marais", label: "Marais Bluants" },
C7: { type: "fleuve", label: "Fleuve de l'Oubli" },
D7: { type: "plaines", label: "Plaines dA!a" },
D7: { type: "plaines", label: "Plaines dAffa" },
E7: { type: "foret", label: "Forêt de Glusks" },
F7: { type: "fleuve", label: "Fleuve de l'Oubli" },
G7: { type: "cite", label: "Cité de Terwa" },
@ -377,7 +377,7 @@ export class TMRUtility {
if (this._checkTMRCoord(currentPos.x, currentPos.y)) { // Sortie de carte ! Ré-insertion aléatoire
coord = TMRUtility.getTMR(TMRUtility.convertToTMRCoord(currentPos));
} else {
coord = this.getTMRAleatoire().coord;
coord = await actor.reinsertionAleatoire('Sortie de carte');
}
console.log("Nouvelle case iteration !!!", i, coord);
}
@ -418,18 +418,15 @@ export class TMRUtility {
}
/* -------------------------------------------- */
static getSortReserveList(reserveList, coordTMR) {
static getSortReserveList(reserveList, coord) {
// TODO : Gérer les têtes spéciales réserve!
let sortReserveList
let tmrDescr = this.getTMR(coordTMR);
let tmrDescr = this.getTMR(coord);
//console.log("Sort réserve : ", tmrDescr);
if (tmrDescr.type == 'fleuve') { // Gestion de la reserve en Fleuve
sortReserveList = reserveList.filter(it => TMRUtility.getTMR(it.coord).type == 'fleuve');
} else { // Reserve sur un case "normale"
sortReserveList = reserveList.filter(it => it.coord == coordTMR);
return reserveList.filter(it => TMRUtility.getTMR(it.coord).type == 'fleuve');
}
//console.log("Sort réserve : ", tmrDescr, sortReserve, reserveList);
return sortReserveList;
// Reserve sur un case "normale"
return reserveList.filter(it => it.coord == coord);
}
/* -------------------------------------------- */

41
module/tmr/conquete.js Normal file
View File

@ -0,0 +1,41 @@
import { Misc } from "../misc.js";
import { tmrColors, tmrConstants, TMRUtility } from "../tmr-utility.js";
import { Draconique } from "./draconique.js";
export class Conquete extends Draconique {
constructor() {
super();
}
type() { return 'queue' }
match(item) { return Draconique.isQueueDragon(item) && item.name.toLowerCase() == 'conquête'; }
manualMessage() { return false }
async onActorCreateOwned(actor, item) { await this._creerConquete(actor, item); }
code() { return 'conquete' }
tooltip(linkData) { return `La ${this.tmrLabel(linkData)} doit être conquise` }
img() { return 'icons/svg/combat.svg' }
_createSprite(pixiTMR) {
return pixiTMR.sprite(this.code(),
{
color: tmrColors.queues, taille: tmrConstants.full, decallage: { x: 2, y: 0 }
});
}
async _creerConquete(actor, queue) {
let existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord);
let possibles = TMRUtility.filterTMR(tmr => !TMRUtility.isCaseHumide(tmr) && !existants.includes(tmr.coord));
let conquete = Misc.rollOneOf(possibles);
await this.createCaseTmr(actor, 'Conquête: ' + conquete.label, conquete, queue._id);
}
async onConquete(actor, coord) {
let existants = actor.data.items.filter(it => this.isCase(it, coord));
for (let casetmr of existants) {
await actor.deleteOwnedItem(casetmr._id);
await actor.deleteOwnedItem(casetmr.data.sourceid);
}
}
}

View File

@ -0,0 +1,58 @@
import { Misc } from "../misc.js";
import { RollDataAjustements } from "../rolldata-ajustements.js";
import { tmrColors, tmrConstants, TMRType, TMRUtility } from "../tmr-utility.js";
import { Debordement } from "./debordement.js";
import { Draconique } from "./draconique.js";
export class Desorientation extends Draconique {
constructor() {
super();
}
type() { return 'souffle' }
match(item) { return Draconique.isSouffleDragon(item) && item.name.toLowerCase().includes('désorientation'); }
manualMessage() { return false }
async onActorCreateOwned(actor, souffle) {
const type = Misc.rollOneOf(this._typesPossibles(actor));
console.log("désorientation", type);
souffle.name += ": " + TMRType[type].name;
await this._creerCasesTmr(actor, type, souffle);
}
_typesPossibles(actor) {
const dejaDesorientes = Misc.distinct(actor.data.items.filter(it => this.isCase(it)).map(it => it.type));
return Object.keys(TMRType).filter(it => !dejaDesorientes.includes(it));
}
async onActorDeleteOwned(actor, souffle) {
await this._supprimerCasesTmr(actor, souffle);
}
code() { return 'desorientation' }
tooltip(linkData) { return `Désorientation, cette case n'existe plus !` }
img() { return 'icons/svg/explosion.svg' }
_createSprite(pixiTMR) {
return pixiTMR.sprite(this.code(),
{
color: tmrColors.trounoir, alpha: 1, taille: tmrConstants.full, decallage: { x: 2, y: 2 },
});
}
async _creerCasesTmr(actor, type, souffle) {
const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord);
let tmrs = TMRUtility.filterTMR(it => it.type == type && !existants.includes(it.coord));
for (let tmr of tmrs) {
await this.createCaseTmr(actor, 'Désorientation: ' + tmr.label, tmr, souffle._id);
}
}
async _supprimerCasesTmr(actor, souffle) {
let caseTmrs = actor.data.items.filter(it => it.data.sourceId == souffle._id);
for (let casetmr of caseTmrs) {
await actor.deleteOwnedItem(casetmr._id);
}
}
}

View File

@ -11,6 +11,8 @@ import { CarteTmr } from "./carte-tmr.js";
import { PontImpraticable } from "./pont-impraticable.js";
import { Draconique } from "./draconique.js";
import { PresentCites } from "./present-cites.js";
import { Desorientation } from "./desorientation.js";
import { Conquete } from "./conquete.js";
@ -27,6 +29,8 @@ export class EffetsDraconiques {
static terreAttache = new TerreAttache();
static trouNoir = new TrouNoir();
static pontImpraticable = new PontImpraticable();
static desorientation = new Desorientation();
static conquete = new Conquete();
static init() {
Draconique.register(EffetsDraconiques.carteTmr);
@ -41,6 +45,8 @@ export class EffetsDraconiques {
Draconique.register(EffetsDraconiques.trouNoir);
Draconique.register(EffetsDraconiques.pontImpraticable);
Draconique.register(EffetsDraconiques.presentCites);
Draconique.register(EffetsDraconiques.desorientation);
Draconique.register(EffetsDraconiques.conquete);
}
/* -------------------------------------------- */
@ -48,19 +54,23 @@ export class EffetsDraconiques {
return EffetsDraconiques.debordement.isCase(caseTMR, coord) ||
EffetsDraconiques.pontImpraticable.isCase(caseTMR, coord);
}
static isInnaccessible(caseTMR, coord) {
return EffetsDraconiques.trouNoir.isCase(caseTMR, coord) ||
EffetsDraconiques.desorientation.isCase(caseTMR, coord);
}
static isCaseTrouNoir(caseTMR, coord) {
return EffetsDraconiques.trouNoir.isCase(caseTMR, coord);
}
static isReserveExtensible(caseTMR, coord) {
return EffetsDraconiques.reserveExtensible.isCase(caseTMR, coord);
}
static isTerreAttache(caseTMR, coord) {
return EffetsDraconiques.terreAttache.isCase(caseTMR, coord);
}
static isCiteFermee(caseTMR, coord) {
return EffetsDraconiques.fermetureCites.isCase(caseTMR, coord);
}
@ -77,8 +87,8 @@ export class EffetsDraconiques {
return EffetsDraconiques.isMatching(element, it => Draconique.isQueueSouffle(it) && it.name.toLowerCase().includes('montée laborieuse'));
}
static isFermetureCite(element) {
/* -------------------------------------------- */
static isFermetureCite(element) {
return EffetsDraconiques.isMatching(element, it => EffetsDraconiques.fermetureCites.match(it));
}
@ -100,14 +110,12 @@ export class EffetsDraconiques {
}
static isDesorientation(element) {
// TODO
return EffetsDraconiques.isMatching(element, it => Draconique.isSouffleDragon(it) && it.name.toLowerCase() == 'désorientation');
return EffetsDraconiques.isMatching(element, it => EffetsDraconiques.desorientation.match(it)); // TODO
}
/* -------------------------------------------- */
static isConquete(element) {
// TODO
return EffetsDraconiques.isMatching(element, it => Draconique.isQueueDragon(it) && it.name.toLowerCase() == 'conquête');
return EffetsDraconiques.isMatching(element, it => EffetsDraconiques.conquete.match(it));
}
static isPelerinage(element) {

View File

@ -30,4 +30,10 @@ export class FermetureCites extends Draconique {
await this.createCaseTmr(actor, 'Fermeture: ' + tmr.label, tmr);
}
}
async onConquete(actor, coord) {
const citeFermee = actor.data.items.find(it => this.isCase(it, coord));
await this.actor.deleteOwnedItem(citeFermee._id);
}
}

View File

@ -39,4 +39,19 @@ export class PresentCites extends Draconique {
}
}
}
async choisirUnPresent(casetmr) {
let d = new Dialog({
title: "Présent des cités",
content: `La ${casetmr.data.coord} vous offre un présent`,
buttons: {
fleur: {
icon: '<i class="fas fa-check"></i>',
label: "Fleur des rêves 2d6",
callback: () => this.creerObjet()
}
}
});
d.render(true);
}
}

View File

@ -6,7 +6,7 @@
"manifestPlusVersion": "1.0.0",
"minimumCoreVersion": "0.7.5",
"compatibleCoreVersion": "0.7.9",
"templateVersion": 93,
"templateVersion": 94,
"author": "LeRatierBretonnien",
"authors": [
{

View File

@ -718,14 +718,20 @@
},
"queue": {
"description": "",
"refoulement": 0
},
"refoulement": 0,
"duree": "",
"restant" : 0
},
"ombre": {
"description": "",
"refoulement": 2
"refoulement": 2,
"duree": "",
"restant" : 0
},
"souffle": {
"description": ""
"description": "",
"duree": "",
"restant" : 0
},
"tete": {
"description": ""

View File

@ -7,5 +7,6 @@
<option value="pont-impraticable">Pont impraticable</option>
<option value="desorientation">Désoriantation</option>
<option value="periple">Periple</option>
<option value="conquete">Conquête</option>
<option value="pelerinage">Pèlerinage</option>
<option value="present-cites">Présents des cités</option>