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

@ -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;
}
/* -------------------------------------------- */