diff --git a/module/actor.js b/module/actor.js
index 42ca2438..6e993730 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -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 Périple. Vous devez gérer manuellement le détail du Périple.
" + item.data.description);
}
- if (EffetsDraconiques.isDesorientation(item)) {
- messages.push("Vous souffrez du Souffle Désorientation. Vous devez gérer avec votre MJ les effets de ce souffle.
" + 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);
diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js
index 05bf2113..823e8679 100644
--- a/module/rdd-tmr-dialog.js
+++ b/module/rdd-tmr-dialog.js
@@ -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 Reserve en Sécurité ou Réserve Exensible, vous pouvez contrôler le déclenchement. Cliquez si vous souhaitez le déclencher :
";
for (let sortReserve of sortReserveList) {
- msg += "- " + sortReserve.sort.name + "
";
+ msg += "- " + sortReserve.sort.name + "
";
}
msg += "";
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;
}
/* -------------------------------------------- */
diff --git a/module/tmr-rencontres.js b/module/tmr-rencontres.js
index 2b6632ec..e22489c8 100644
--- a/module/tmr-rencontres.js
+++ b/module/tmr-rencontres.js
@@ -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();
diff --git a/module/tmr-utility.js b/module/tmr-utility.js
index 523008e7..0da70a62 100644
--- a/module/tmr-utility.js
+++ b/module/tmr-utility.js
@@ -90,7 +90,7 @@ const TMRMapping = {
A7: { type: "plaines", label: "Plaines de l’Arc" },
B7: { type: "marais", label: "Marais Bluants" },
C7: { type: "fleuve", label: "Fleuve de l'Oubli" },
- D7: { type: "plaines", label: "Plaines d’A!a" },
+ D7: { type: "plaines", label: "Plaines d’Affa" },
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);
}
/* -------------------------------------------- */
diff --git a/module/tmr/conquete.js b/module/tmr/conquete.js
new file mode 100644
index 00000000..fc3579b2
--- /dev/null
+++ b/module/tmr/conquete.js
@@ -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);
+ }
+ }
+}
diff --git a/module/tmr/desorientation.js b/module/tmr/desorientation.js
new file mode 100644
index 00000000..43fedf32
--- /dev/null
+++ b/module/tmr/desorientation.js
@@ -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);
+ }
+ }
+
+}
diff --git a/module/tmr/effets-draconiques.js b/module/tmr/effets-draconiques.js
index b9745acb..656b0491 100644
--- a/module/tmr/effets-draconiques.js
+++ b/module/tmr/effets-draconiques.js
@@ -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) {
diff --git a/module/tmr/fermeture-cites.js b/module/tmr/fermeture-cites.js
index 0357c8ad..29c0ef92 100644
--- a/module/tmr/fermeture-cites.js
+++ b/module/tmr/fermeture-cites.js
@@ -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);
+ }
+
}
diff --git a/module/tmr/present-cites.js b/module/tmr/present-cites.js
index 4cb0135e..84d13ba7 100644
--- a/module/tmr/present-cites.js
+++ b/module/tmr/present-cites.js
@@ -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: '',
+ label: "Fleur des rêves 2d6",
+ callback: () => this.creerObjet()
+ }
+ }
+ });
+ d.render(true);
+ }
+
}
diff --git a/system.json b/system.json
index e1b9dfe4..25b90434 100644
--- a/system.json
+++ b/system.json
@@ -6,7 +6,7 @@
"manifestPlusVersion": "1.0.0",
"minimumCoreVersion": "0.7.5",
"compatibleCoreVersion": "0.7.9",
- "templateVersion": 93,
+ "templateVersion": 94,
"author": "LeRatierBretonnien",
"authors": [
{
diff --git a/template.json b/template.json
index 7f976010..1fde5f9b 100644
--- a/template.json
+++ b/template.json
@@ -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": ""
diff --git a/templates/casetmr-specific-list.html b/templates/casetmr-specific-list.html
index d69feec5..ccedfd1f 100644
--- a/templates/casetmr-specific-list.html
+++ b/templates/casetmr-specific-list.html
@@ -7,5 +7,6 @@
+