Merge branch 'travail-cases-humides' into 'v1.3'

Fixes nombreux sur tmr autour des cases humides

See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!144
This commit is contained in:
Leratier Bretonnien 2021-02-05 22:10:50 +00:00
commit 48688fc453
15 changed files with 351 additions and 256 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

60
icons/creatures/mule.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -9,6 +9,7 @@ import { RdDItem } from "./item.js";
import { RdDItemArme } from "./item-arme.js"; import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemCompetence } from "./item-competence.js";
import { RdDBonus } from "./rdd-bonus.js"; import { RdDBonus } from "./rdd-bonus.js";
import { Misc } from "./misc.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDActorSheet extends ActorSheet { export class RdDActorSheet extends ActorSheet {
@ -38,11 +39,11 @@ export class RdDActorSheet extends ActorSheet {
data.data.showCompNiveauBase = this.options.showCompNiveauBase; data.data.showCompNiveauBase = this.options.showCompNiveauBase;
data.data.montrerArchetype = this.options.montrerArchetype; data.data.montrerArchetype = this.options.montrerArchetype;
data.itemsByType = RdDItem.buildItemsClassification(data.items); data.itemsByType = Misc.classify(data.items);
// Competence per category // Competence per category
data.data.competenceXPTotal = 0; data.data.competenceXPTotal = 0;
data.competenceByCategory = RdDItem.classify( data.competenceByCategory = Misc.classify(
data.itemsByType.competence, data.itemsByType.competence,
item => item.data.categorie, item => item.data.categorie,
item => { item => {

View File

@ -6,6 +6,7 @@
import { RdDUtility } from "./rdd-utility.js"; import { RdDUtility } from "./rdd-utility.js";
import { HtmlUtility } from "./html-utility.js"; import { HtmlUtility } from "./html-utility.js";
import { RdDItem } from "./item.js"; import { RdDItem } from "./item.js";
import { Misc } from "./misc.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDActorVehiculeSheet extends ActorSheet { export class RdDActorVehiculeSheet extends ActorSheet {
@ -36,7 +37,7 @@ export class RdDActorVehiculeSheet extends ActorSheet {
getData() { getData() {
let data = super.getData(); let data = super.getData();
data.itemsByType = RdDItem.buildItemsClassification(data.items); data.itemsByType = Misc.classify(data.items);
RdDUtility.filterItemsPerTypeForSheet(data); RdDUtility.filterItemsPerTypeForSheet(data);
RdDUtility.buildArbreDeConteneur(this, data); RdDUtility.buildArbreDeConteneur(this, data);

View File

@ -1,5 +1,5 @@
import { RdDUtility } from "./rdd-utility.js"; import { RdDUtility } from "./rdd-utility.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRType, TMRUtility } from "./tmr-utility.js";
import { RdDRollDialogEthylisme } from "./rdd-roll-ethylisme.js"; import { RdDRollDialogEthylisme } from "./rdd-roll-ethylisme.js";
import { RdDRoll } from "./rdd-roll.js"; import { RdDRoll } from "./rdd-roll.js";
import { RdDTMRDialog } from "./rdd-tmr-dialog.js"; import { RdDTMRDialog } from "./rdd-tmr-dialog.js";
@ -21,6 +21,7 @@ import { RdDAlchimie } from "./rdd-alchimie.js";
import { StatusEffects } from "./status-effects.js"; import { StatusEffects } from "./status-effects.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { ReglesOptionelles } from "./regles-optionelles.js"; import { ReglesOptionelles } from "./regles-optionelles.js";
import { RdDItem } from "./item.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -1837,22 +1838,25 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
checkIsAdditionnalHumide(cellDescr, coordTMR) { isCaseHumideAdditionelle(tmr) {
let pontHumide = this.data.items.find(item => item.type == 'souffle' && item.name.toLowerCase().includes(' des ponts')); if (tmr.type == 'pont' && this.data.items.find(it => RdDItem.isSoufflePontImpraticable(it))) {
if (pontHumide && cellDescr.type == 'pont') {
ChatMessage.create({ ChatMessage.create({
content: "Vous êtes sous le coup d'une Impraticabilité des Ponts : ils doivent être maîtrisés comme des cases humides.", content: tmr.label +": Vous êtes sous le coup d'une Impraticabilité des Ponts : ce pont doit être maîtrisé comme une case humide.",
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(game.user.name)
}); });
return true; return true;
} }
// Débordement ? // Débordement ?
let debordementList = this.data.items.filter(item => item.type == 'casetmr' && item.data.specific == 'debordement'); let isTmrInondee = this.data.items.filter(it => RdDItem.isCaseTMR(it))
for (let caseTMR of debordementList) { .filter(it => it.data.coord == tmr.coord)
if (caseTMR.data.coord == coordTMR) .find(it => RdDItem.isCaseInnondee(it));
if (isTmrInondee) {
ChatMessage.create({
content: tmr.label +": cette case est inondée, elle doit être maîtrisée comme une case humide.",
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
return true; return true;
} }
return false; return false;
} }
@ -2398,14 +2402,14 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
checkMonteeLaborieuse() { // Return +1 si la queue Montée Laborieuse est présente, 0 sinon checkMonteeLaborieuse() { // Return +1 par queue/ombre/souffle Montée Laborieuse présente
let monteLaborieuse = this.data.items.find(item => (item.type == 'queue' || item.type == 'souffle') && item.name.toLowerCase().includes('montée laborieuse')); let countMonteLaborieuse = this.data.items.filter(item => (item.type == 'queue' || item.type == 'ombre' || item.type == 'souffle') && item.name.toLowerCase().includes('montée laborieuse')).length;
if (monteLaborieuse) { if (countMonteLaborieuse) {
ChatMessage.create({ ChatMessage.create({
content: "Vous êtes sous le coup d'une Montée Laborieuse : vos montées en TMR coûtent 1 Point de Rêve de plus.", content: `Vous êtes sous le coup d'une Montée Laborieuse : vos montées en TMR coûtent ${countMonteLaborieuse} Point de Rêve de plus.`,
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(game.user.name)
}); });
return 1; return countMonteLaborieuse;
} }
return 0; return 0;
} }
@ -2414,7 +2418,7 @@ export class RdDActor extends Actor {
refreshTMRView( tmrData ) { refreshTMRView( tmrData ) {
console.log("REFRESH !!!!"); console.log("REFRESH !!!!");
if ( this.currentTMR ) { if ( this.currentTMR ) {
this.currentTMR.forceDemiRevePositionView(tmrData.tmrPos); this.currentTMR.forceDemiRevePositionView();
} }
} }

View File

@ -29,7 +29,7 @@ export class RdDItemCompetenceCreature extends Item {
}); });
return arme; return arme;
} }
console.error("RdDItem.toArme(", item, ") : impossible de transformer l'Item en arme"); console.error("RdDItemCompetenceCreature.toArme(", item, ") : impossible de transformer l'Item en arme");
return undefined; return undefined;
} }

View File

@ -1,28 +1,18 @@
import { Misc } from "./misc.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
export class RdDItem { export class RdDItem {
/* -------------------------------------------- */ static isSoufflePontImpraticable(item) {
static buildItemsClassification(items) { return item.type == 'souffle' && item.name.toLowerCase().includes(' des ponts');
return RdDItem.classify(items, it => it.type)
} }
static classify(items, classifier = it => it.type, transform = it => it) { static isCaseInnondee(item) {
let itemsBy = {}; return RdDItem.isCaseTMR(item) && item.data.specific == 'debordement';
RdDItem.classifyInto(itemsBy, items, classifier, transform);
return itemsBy;
} }
static classifyInto(itemsBy, items, classifier = it => it.type, transform = it => it) {
for (const item of items) {
const classification = classifier(item);
let list = itemsBy[classification];
if (!list) {
list = [];
itemsBy[classification] = list;
}
list.push(transform(item));
}
}
static isCaseTMR(item) {
return item.type == 'casetmr';
}
} }

View File

@ -1,5 +1,4 @@
/** /**
* This class is intended as a placeholder for utility methods unrelated * This class is intended as a placeholder for utility methods unrelated
* to actual classes of the game system or of FoundryVTT * to actual classes of the game system or of FoundryVTT
@ -41,4 +40,23 @@ export class Misc {
default: return '1/' + diviseur; default: return '1/' + diviseur;
} }
} }
static classify(items, classifier = it => it.type, transform = it => it) {
let itemsBy = {};
Misc.classifyInto(itemsBy, items, classifier, transform);
return itemsBy;
}
static classifyInto(itemsBy, items, classifier = it => it.type, transform = it => it) {
for (const item of items) {
const classification = classifier(item);
let list = itemsBy[classification];
if (!list) {
list = [];
itemsBy[classification] = list;
}
list.push(transform(item));
}
}
} }

View File

@ -1,6 +1,5 @@
/* -------------------------------------------- */ /* -------------------------------------------- */
import { ChatUtility } from "./chat-utility.js";
import { DeDraconique } from "./de-draconique.js"; import { DeDraconique } from "./de-draconique.js";
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemCompetence } from "./item-competence.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
@ -10,7 +9,7 @@ import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
import { RdDRollTables } from "./rdd-rolltables.js"; import { RdDRollTables } from "./rdd-rolltables.js";
import { RdDUtility } from "./rdd-utility.js"; import { RdDUtility } from "./rdd-utility.js";
import { TMRRencontres } from "./tmr-rencontres.js"; import { TMRRencontres } from "./tmr-rencontres.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRType, TMRUtility } from "./tmr-utility.js";
const rddRollNumeric = /(\d+)\s*([\+\-]?\d+)?\s*(s)?/; const rddRollNumeric = /(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
@ -28,15 +27,17 @@ export class RdDCommands {
rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(), descr: "Tire une Tête de Dragon" }); rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(), descr: "Tire une Tête de Dragon" });
rddCommands.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle(), descr: " Tire un Souffle de Dragon" }); rddCommands.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle(), descr: " Tire un Souffle de Dragon" });
rddCommands.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot(), descr: "Tire une carte du Tarot Draconique" }); rddCommands.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot(), descr: "Tire une carte du Tarot Draconique" });
rddCommands.registerCommand({ path: ["/table", "tmr"], func: (content, msg, params) => TMRUtility.getTMRAleatoire(), descr: "Tire une case aléatoire des Terres médianes" });
rddCommands.registerCommand({ path: ["/tmra"], func: (content, msg, params) => TMRUtility.getTMRAleatoire(), descr: "Tire une case aléatoire des Terres médianes" }); rddCommands.registerCommand({
path: ["/tmra"], func: (content, msg, params) => rddCommands.getTMRAleatoire(msg, params),
descr: `Tire une case aléatoire des Terres médianes
<br><strong>/tmra forêt</strong> détermine une 'forêt' aléatoire
<br><strong>/tmra</strong> détermine une case aléatoire dans toutes les TMR` });
rddCommands.registerCommand({ rddCommands.registerCommand({
path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params), path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params),
descr: ` descr: `Détermine une rencontre dans un type de case
Exemple: <strong>/tmrr foret</strong> lance un d100 et détermine la rencontre correspondante en 'forêt' <br><strong>/tmrr foret</strong> lance un d100 et détermine la rencontre correspondante en 'forêt'
Exemple: <strong>/tmrr forêt 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47 <br><strong>/tmrr forêt 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47`
`
}); });
rddCommands.registerCommand({ rddCommands.registerCommand({
@ -59,8 +60,7 @@ export class RdDCommands {
<br><strong>/rdd 10 3</strong> effectue un jet 10 à +3 <br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
<br><strong>/rdd 10 +2</strong> effectue un jet 10 à +2 <br><strong>/rdd 10 +2</strong> effectue un jet 10 à +2
<br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2 <br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
<br><strong>/rdd 15 0 s</strong> effectue un jet 15 à 0, avec significative requise <br><strong>/rdd 15 0 s</strong> effectue un jet 15 à 0, avec significative requise`
`
}); });
rddCommands.registerCommand({ path: ["/ddr"], func: (content, msg, params) => rddCommands.rollDeDraconique(msg), descr: "Lance un Dé Draconique" }); rddCommands.registerCommand({ path: ["/ddr"], func: (content, msg, params) => rddCommands.rollDeDraconique(msg), descr: "Lance un Dé Draconique" });
@ -68,14 +68,12 @@ export class RdDCommands {
path: ["/payer"], func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1]), path: ["/payer"], func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1]),
descr: `Permet de payer un montant. Exemples: descr: `Permet de payer un montant. Exemples:
<br><strong>/payer 5s 10d</strong> permet d'envoyer un message pour payer 5 sols et 10 deniers <br><strong>/payer 5s 10d</strong> permet d'envoyer un message pour payer 5 sols et 10 deniers
<br><strong>/payer 10d</strong> permet d'envoyer un message pour payer 10 deniers <br><strong>/payer 10d</strong> permet d'envoyer un message pour payer 10 deniers`
`
}); });
rddCommands.registerCommand({ rddCommands.registerCommand({
path: ["/astro"], func: (content, msg, params) => RdDUtility.afficherHeuresChanceMalchance(params[0]), path: ["/astro"], func: (content, msg, params) => RdDUtility.afficherHeuresChanceMalchance(params[0]),
descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples: descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples:
<br><strong>/astro Lyre</strong> <br><strong>/astro Lyre</strong>`
`
}); });
game.system.rdd.commands = rddCommands; game.system.rdd.commands = rddCommands;
} }
@ -234,6 +232,18 @@ export class RdDCommands {
RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`); RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`);
} }
getTMRAleatoire(msg, params) {
if (params.length < 2) {
let type = params[0];
const tmr = TMRUtility.getTMRAleatoire(type);
RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`);
}
else {
return false;
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getCoutXpComp(msg, params) { getCoutXpComp(msg, params) {
if (params && (params.length == 1 || params.length == 2)) { if (params && (params.length == 1 || params.length == 2)) {

View File

@ -35,12 +35,12 @@ export class RdDRollTables {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getSouffle(toChat = true) { static async getSouffle(toChat = false) {
return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat); return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getQueue(toChat = true) { static async getQueue(toChat = false) {
let queue = await RdDRollTables.drawItemFromRollTable("Queues de dragon", toChat); let queue = await RdDRollTables.drawItemFromRollTable("Queues de dragon", toChat);
if (queue.name.toLowerCase().includes('lancinant') ) { if (queue.name.toLowerCase().includes('lancinant') ) {
queue = await RdDRollTables.drawItemFromRollTable("Désirs lancinants", toChat); queue = await RdDRollTables.drawItemFromRollTable("Désirs lancinants", toChat);
@ -52,17 +52,17 @@ export class RdDRollTables {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTete(toChat = true) { static async getTete(toChat = false) {
return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour haut-rêvants", toChat); return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour haut-rêvants", toChat);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTeteHR(toChat = true) { static async getTeteHR(toChat = false) {
return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour tous personnages", toChat); return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour tous personnages", toChat);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getOmbre(toChat = true) { static async getOmbre(toChat = false) {
return await RdDRollTables.drawItemFromRollTable("Ombre de Thanatos", toChat); return await RdDRollTables.drawItemFromRollTable("Ombre de Thanatos", toChat);
} }

View File

@ -200,7 +200,6 @@ export class RdDTMRDialog extends Dialog {
this.actor.deleteTMRRencontreAtPosition(); this.actor.deleteTMRRencontreAtPosition();
this.updatePreviousRencontres(); this.updatePreviousRencontres();
let rencontreData = { let rencontreData = {
actor: this.actor, actor: this.actor,
alias: this.actor.name, alias: this.actor.name,
@ -248,12 +247,13 @@ export class RdDTMRDialog extends Dialog {
rencontreData.nbRounds++; rencontreData.nbRounds++;
this.nbFatigue += 1; this.nbFatigue += 1;
this._tentativeMaitrise(rencontreData); this._tentativeMaitrise(rencontreData);
setTimeout(() => this._deleteTmrMessages(rencontreData.actor, rencontreData.nbRounds), 500); this._deleteTmrMessages(rencontreData.actor, rencontreData.nbRounds);
}, 2000); }, 2000);
} }
} }
_deleteTmrMessages(actor, nbRounds = -1) { _deleteTmrMessages(actor, nbRounds = -1) {
setTimeout(() => {
if (nbRounds < 0) { if (nbRounds < 0) {
ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}"`); ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}"`);
} }
@ -262,6 +262,7 @@ export class RdDTMRDialog extends Dialog {
ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}" data-rencontre-round="${i}">`); ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}" data-rencontre-round="${i}">`);
} }
} }
}, 500);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -275,38 +276,38 @@ export class RdDTMRDialog extends Dialog {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async manageRencontre(coordTMR, cellDescr) { async manageRencontre(tmr, postRencontre) {
if (this.viewOnly) { if (this.viewOnly) {
return; return;
} }
this.currentRencontre = undefined; this.currentRencontre = undefined;
let rencontre = await this._jetDeRencontre(coordTMR, cellDescr); let rencontre = await this._jetDeRencontre(tmr);
if (rencontre) { // Manages it if (rencontre) { // Manages it
if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres if (rencontre.rencontre) rencontre = rencontre.rencontre; // Manage stored rencontres
console.log("manageRencontre", rencontre); console.log("manageRencontre", rencontre);
this.currentRencontre = duplicate(rencontre); this.currentRencontre = duplicate(rencontre);
let dialog = new RdDTMRRencontreDialog("", this, this.currentRencontre); let dialog = new RdDTMRRencontreDialog("", this, this.currentRencontre, postRencontre);
dialog.render(true); dialog.render(true);
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async _jetDeRencontre(coordTMR, cellDescr) { async _jetDeRencontre(tmr) {
if (TMRUtility.isForceRencontre()) { if (TMRUtility.isForceRencontre()) {
return await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr); return await TMRUtility.rencontreTMRRoll(tmr.coord, tmr);
} }
let rencontre = this.rencontresExistantes.find(prev => prev.coord == coordTMR); let rencontre = this.rencontresExistantes.find(prev => prev.coord == tmr.coord);
if (rencontre) { if (rencontre) {
return rencontre; return rencontre;
} }
let myRoll = new Roll("1d7").evaluate(); let myRoll = new Roll("1d7").evaluate();
if (myRoll.total == 7) { if (myRoll.total == 7) {
let isMauvaise = this.actor.isRencontreSpeciale(); let isMauvaise = this.actor.isRencontreSpeciale();
return await TMRUtility.rencontreTMRRoll(coordTMR, cellDescr, isMauvaise); return await TMRUtility.rencontreTMRRoll(tmr.coord, tmr, isMauvaise);
} }
this._tellToUser(myRoll.total + ": Pas de rencontre en " + cellDescr.label + " (" + coordTMR + ")"); this._tellToUser(myRoll.total + ": Pas de rencontre en " + tmr.label + " (" + tmr.coord + ")");
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -330,13 +331,13 @@ export class RdDTMRDialog extends Dialog {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async manageCaseSpeciale(cellDescr, coordTMR) { async manageCaseSpeciale(tmr) {
for (let caseTMR of this.casesSpeciales) { for (let caseTMR of this.casesSpeciales) {
if (caseTMR.data.coord == coordTMR) { // Match ! if (caseTMR.data.coord == tmr.coord) { // Match !
if (caseTMR.data.specific == 'trounoir') { if (caseTMR.data.specific == 'trounoir') {
let newTMR = TMRUtility.getTMRAleatoire(); let newTMR = TMRUtility.getTMRAleatoire();
let tmrPos = duplicate(this.actor.data.data.reve.tmrpos); let tmrPos = duplicate(this.actor.data.data.reve.tmrpos);
tmrPos.coord = newTMR; tmrPos.coord = newTMR.coord;
await this.actor.update({ "data.reve.tmrpos": tmrPos }); await this.actor.update({ "data.reve.tmrpos": tmrPos });
ChatMessage.create({ ChatMessage.create({
content: "Vous êtes rentré sur un Trou Noir : ré-insertion aléatoire.", content: "Vous êtes rentré sur un Trou Noir : ré-insertion aléatoire.",
@ -349,12 +350,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
isCaseMaitrisee(coordTMR) { isCaseMaitrisee(coordTMR) {
for (let caseTMR of this.casesSpeciales) { return this.casesSpeciales.find(it => it.data.coord = coordTMR && it.data.specific == 'maitrisee');
if (caseTMR.data.coord == coordTMR && caseTMR.data.specific == 'maitrisee') {
return true;
}
}
return false;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -364,19 +360,11 @@ export class RdDTMRDialog extends Dialog {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async manageCaseHumide(cellDescr, coordTMR) { async manageCaseHumide(tmr) {
if (this.viewOnly || this.currentRencontre) { if (this.viewOnly || this.currentRencontre) {
return; return;
} }
let isHumide = this.actor.checkIsAdditionnalHumide(cellDescr, coordTMR); if (this.isCaseHumide(tmr)) {
if (cellDescr.type == "lac" || cellDescr.type == "fleuve" || cellDescr.type == "marais" || isHumide) {
if (this.isCaseMaitrisee(coordTMR)) {
ChatMessage.create({
content: "Cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>",
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
return;
}
// TODO: permettre de choisir la voie de draconic? // TODO: permettre de choisir la voie de draconic?
let draconic = this.actor.getBestDraconic(); let draconic = this.actor.getBestDraconic();
@ -404,7 +392,7 @@ export class RdDTMRDialog extends Dialog {
explication += "Vous êtes entré sur une case humide, et vous avez <strong>réussi</strong> votre maîtrise !" explication += "Vous êtes entré sur une case humide, et vous avez <strong>réussi</strong> votre maîtrise !"
msg2MJ += game.user.name + " est rentré sur une case humides : Réussite !"; msg2MJ += game.user.name + " est rentré sur une case humides : Réussite !";
} }
explication += "<br><strong>Test : Rêve actuel / " + draconic.name + " / " + cellDescr.type + "</strong>" explication += "<br><strong>Test : Rêve actuel / " + draconic.name + " / " + tmr.type + "</strong>"
+ RdDResolutionTable.explain(rolled); + RdDResolutionTable.explain(rolled);
if (rolled.isETotal) { if (rolled.isETotal) {
@ -414,7 +402,7 @@ export class RdDTMRDialog extends Dialog {
} }
if (rolled.isPart) { if (rolled.isPart) {
explication += "<br>Vous avez fait une Réussite Particulière"; explication += "<br>Vous avez fait une Réussite Particulière";
this.actor._appliquerAjoutExperience({ rolled: rolled, seletedCarac: { label: 'reve' }, competence: draconic.name }) this.actor._appliquerAjoutExperience({ rolled: rolled, selectedCarac: { label: 'reve' }, competence: draconic.name })
msg2MJ += "<br>Et a fait une réussite particulière"; msg2MJ += "<br>Et a fait une réussite particulière";
} }
@ -432,6 +420,21 @@ export class RdDTMRDialog extends Dialog {
humideDiag.render(true); humideDiag.render(true);
} }
} }
isCaseHumide(tmr) {
if (this.isCaseMaitrisee(tmr.coord)) {
ChatMessage.create({
content: tmr.label + ": cette case humide est déja maitrisée grâce à votre Tête <strong>Quête des Eaux</strong>",
whisper: ChatMessage.getWhisperRecipients(game.user.name)
});
return false;
}
if (this.actor.isCaseHumideAdditionelle(tmr)) {
return true;
}
return tmr.type == "lac" || tmr.type == "fleuve" || tmr.type == "marais";
}
/* -------------------------------------------- */ /* -------------------------------------------- */
isReserveExtensible(coordTMR) { isReserveExtensible(coordTMR) {
for (let caseTMR of this.casesSpeciales) { for (let caseTMR of this.casesSpeciales) {
@ -537,60 +540,38 @@ export class RdDTMRDialog extends Dialog {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async deplacerDemiReve(event) { async onClickTMR(event) {
if (this.viewOnly) { if (this.viewOnly) {
return; return;
} }
let origEvent = event.data.originalEvent; let origEvent = event.data.originalEvent;
let myself = event.target.tmrObject; let tmrObject = event.target.tmrObject;
let eventCoord = RdDTMRDialog._computeEventCoord(origEvent); let eventPos = RdDTMRDialog._computeEventPos(origEvent);
let cellx = eventCoord.cellx; await tmrObject._onClickTMRPos(eventPos); // Vérifier l'état des compteurs reve/fatigue/vie
let celly = eventCoord.celly; }
console.log("deplacerDemiReve >>>>", cellx, celly);
let currentPos = TMRUtility.convertToCellCoord(myself.actor.data.data.reve.tmrpos.coord); async _onClickTMRPos(eventPos) {
let coordTMR = TMRUtility.convertToTMRCoord(cellx, celly); let currentPos = TMRUtility.convertToCellPos(this.actor.data.data.reve.tmrpos.coord);
let currentTMR = TMRUtility.convertToTMRCoord(currentPos.x, currentPos.y);
console.log("deplacerDemiReve >>>>", currentPos, eventPos);
let targetCoordTMR = TMRUtility.convertToTMRCoord(eventPos);
let currentCoordTMR = TMRUtility.convertToTMRCoord(currentPos);
// Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter) // Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter)
let deplacementType = 'erreur'; let deplacementType = 'erreur';
if (myself.rencontreState == 'aucune') { // Pas de recontre en post-processing, donc deplacement normal if (this.rencontreState == 'aucune') { // Pas de recontre en post-processing, donc deplacement normal
if (!RdDTMRDialog._horsDePortee(currentPos, cellx, celly) || myself.isTerreAttache(coordTMR) || myself.checkConnaissanceFleuve(currentTMR, coordTMR)) { if (!RdDTMRDialog._horsDePortee(currentPos, eventPos) || this.isTerreAttache(targetCoordTMR) || this.checkConnaissanceFleuve(currentCoordTMR, targetCoordTMR)) {
deplacementType = 'normal'; deplacementType = 'normal';
} }
} else { } else {
deplacementType = myself.processClickPostRencontre(coordTMR); deplacementType = this.processClickPostRencontre(targetCoordTMR);
} }
// Si le deplacement est valide // Si le deplacement est valide
if (deplacementType == 'normal' || deplacementType == 'saut') { if (deplacementType == 'normal' || deplacementType == 'saut') {
if (myself.currentRencontre != 'normal') await this._deplacerDemiReve(targetCoordTMR, deplacementType);
myself.nettoyerRencontre();
let cellDescr = TMRUtility.getTMR(coordTMR);
await myself.manageCaseSpeciale(cellDescr, coordTMR); // Gestion cases spéciales type Trou noir, etc
console.log("deplacerDemiReve: TMR column is", coordTMR, cellx, celly, cellDescr, this);
let tmrPos = duplicate(myself.actor.data.data.reve.tmrpos);
tmrPos.coord = coordTMR;
await myself.actor.update({ "data.reve.tmrpos": tmrPos });
myself._updateDemiReve(myself);
myself.nbFatigue += 1;
myself.updateValuesDisplay();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_tmr_move", data: {
actorId: myself.actor.data._id,
tmrPos: tmrPos
}
});
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
await myself.manageRencontre(coordTMR, cellDescr);
}
await myself.manageCaseHumide(cellDescr, coordTMR);
await myself.declencheSortEnReserve(coordTMR);
await myself.actor.checkSoufflePeage(cellDescr);
} else if (deplacementType == 'messager') { // Dans ce cas, ouverture du lancement de sort sur la case visée } else if (deplacementType == 'messager') { // Dans ce cas, ouverture du lancement de sort sur la case visée
/* /*
@ -598,29 +579,71 @@ export class RdDTMRDialog extends Dialog {
Si la case est le demi-rêve, ne pas lancer de 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) 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 myself.actor.rollUnSort(coordTMR); await this._messagerDemiReve(targetCoordTMR);
myself.nettoyerRencontre();
} else { } else {
ui.notifications.error("Vous ne pouvez vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre"); ui.notifications.error("Vous ne pouvez vous déplacer que sur des cases adjacentes à votre position ou valides dans le cas d'une rencontre");
console.log("STATUS :", myself.rencontreState, myself.currentRencontre); console.log("STATUS :", this.rencontreState, this.currentRencontre);
} }
myself.checkQuitterTMR(); // Vérifier l'état des compteurs reve/fatigue/vie this.checkQuitterTMR();
}
async _messagerDemiReve(targetCoordTMR) {
await this.actor.rollUnSort(targetCoordTMR);
this.nettoyerRencontre();
}
async _deplacerDemiReve(targetCoord, deplacementType) {
if (this.currentRencontre != 'normal') {
this.nettoyerRencontre();
}
let tmr = TMRUtility.getTMR(targetCoord);
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._updateDemiReve();
this.nbFatigue += 1;
this.updateValuesDisplay();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_tmr_move", data: {
actorId: this.actor.data._id,
tmrPos: tmrPos
}
});
if (deplacementType == 'normal') { // Pas de rencontres après un saut de type passeur/changeur/...
await this.manageRencontre(tmr, () => this.postRencontre(tmr));
}
else{
await this.postRencontre(tmr);
}
}
async postRencontre(tmr) {
await this.manageCaseHumide(tmr);
await this.declencheSortEnReserve(tmr.coord);
await this.actor.checkSoufflePeage(tmr);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async forceDemiRevePositionView(coordTMR) { async forceDemiRevePositionView(coordTMR) {
this._updateDemiReve(this); this._updateDemiReve();
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async forceDemiRevePosition(coordTMR) { async forceDemiRevePosition(coordTMR) {
await this.actor.updateCoordTMR(coordTMR); await this.actor.updateCoordTMR(coordTMR);
this._updateDemiReve(this); this._updateDemiReve();
let cellDescr = TMRUtility.getTMR(coordTMR); let tmr = TMRUtility.getTMR(coordTMR);
this.manageCaseHumide(cellDescr, coordTMR); this.manageCaseHumide(tmr);
await this.declencheSortEnReserve(coordTMR); await this.declencheSortEnReserve(tmr.coord);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -661,7 +684,7 @@ export class RdDTMRDialog extends Dialog {
mytmr.buttonMode = true; mytmr.buttonMode = true;
mytmr.tmrObject = this; mytmr.tmrObject = this;
if (!this.viewOnly) { if (!this.viewOnly) {
mytmr.on('pointerdown', this.deplacerDemiReve); mytmr.on('pointerdown', this.onClickTMR);
} }
this.pixiApp.stage.addChild(mytmr); this.pixiApp.stage.addChild(mytmr);
@ -676,42 +699,36 @@ export class RdDTMRDialog extends Dialog {
} }
// Gestion du cout de montée en points de rêve // Gestion du cout de montée en points de rêve
let reveCout = -1; let reveCout = (this.tmrdata.isRapide && !this.actor.checkTeteDeplacementAccelere()) ? -2 : -1;
if (this.actor.checkTeteDeplacementAccelere()) {
reveCout = -1;
} else {
reveCout = (this.tmrdata.isRapide) ? -2 : -1;
}
reveCout -= this.actor.checkMonteeLaborieuse(); reveCout -= this.actor.checkMonteeLaborieuse();
await this.actor.reveActuelIncDec(reveCout); await this.actor.reveActuelIncDec(reveCout);
// Le reste... // Le reste...
this.updateValuesDisplay(); this.updateValuesDisplay();
let coordTMR = this.actor.data.data.reve.tmrpos.coord; let tmr = TMRUtility.getTMR(this.actor.data.data.reve.tmrpos.coord);
let cellDescr = TMRUtility.getTMR(coordTMR); await this.manageRencontre(tmr, () => {
await this.manageRencontre(coordTMR, cellDescr); this.postRencontre(tmr);
this.manageCaseHumide(cellDescr, coordTMR);
// Mise à jour du nb de cases de Fatigue
this.nbFatigue = this.actor.getTMRFatigue(); this.nbFatigue = this.actor.getTMRFatigue();
this.actor.displayTMRQueueSouffleInformation(); this.actor.displayTMRQueueSouffleInformation();
});
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static _computeEventCoord(origEvent) { static _computeEventPos(origEvent) {
let canvasRect = origEvent.target.getBoundingClientRect(); let canvasRect = origEvent.target.getBoundingClientRect();
let x = origEvent.clientX - canvasRect.left; let x = origEvent.clientX - canvasRect.left;
let y = origEvent.clientY - canvasRect.top; let y = origEvent.clientY - canvasRect.top;
let cellx = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12] let cellx = Math.floor(x / tmrConstants.cellw); // [From 0 -> 12]
y -= (cellx % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; y -= (cellx % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let celly = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14] let celly = Math.floor(y / tmrConstants.cellh); // [From 0 -> 14]
return { cellx, celly }; return { x: cellx, y: celly };
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static _horsDePortee(pos, cellx, celly) { static _horsDePortee(origin, target) {
return Math.abs(cellx - pos.x) > 1 return Math.abs(target.x - origin.x) > 1
|| Math.abs(celly - pos.y) > 1 || Math.abs(target.y - origin.y) > 1
|| (pos.y == 0 && celly > pos.y && cellx != pos.x && pos.x % 2 == 0) || (origin.y == 0 && target.y > origin.y && target.x != origin.x && origin.x % 2 == 0)
|| (celly == 0 && celly < pos.y && cellx != pos.x && pos.x % 2 == 1); || (target.y == 0 && target.y < origin.y && target.x != origin.x && origin.x % 2 == 1);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -811,14 +828,14 @@ export class RdDTMRDialog extends Dialog {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_updateDemiReve(myself) { _updateDemiReve() {
myself._setTokenPosition(myself.demiReve); this._setTokenPosition(this.demiReve);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
/** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */ /** Retourne les coordonnées x, h, w, h du rectangle d'une case donnée */
_getCaseRectangleCoord(coord) { _getCaseRectangleCoord(coord) {
let coordXY = TMRUtility.convertToCellCoord(coord); let coordXY = TMRUtility.convertToCellPos(coord);
let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let x = tmrConstants.gridx + (coordXY.x * tmrConstants.cellw) - (tmrConstants.cellw / 2); let x = tmrConstants.gridx + (coordXY.x * tmrConstants.cellw) - (tmrConstants.cellw / 2);
let y = tmrConstants.gridy + (coordXY.y * tmrConstants.cellh) - (tmrConstants.cellh / 2) + decallagePairImpair; let y = tmrConstants.gridy + (coordXY.y * tmrConstants.cellh) - (tmrConstants.cellh / 2) + decallagePairImpair;
@ -827,7 +844,7 @@ export class RdDTMRDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
_setTokenPosition(token) { _setTokenPosition(token) {
let coordXY = TMRUtility.convertToCellCoord(token.coordTMR()); let coordXY = TMRUtility.convertToCellPos(token.coordTMR());
let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y; let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
let dx = (token.sprite.decallage == undefined) ? 0 : token.sprite.decallage.x; let dx = (token.sprite.decallage == undefined) ? 0 : token.sprite.decallage.x;
let dy = (token.sprite.decallage == undefined) ? 0 : token.sprite.decallage.y; let dy = (token.sprite.decallage == undefined) ? 0 : token.sprite.decallage.y;

View File

@ -2,20 +2,20 @@
export class RdDTMRRencontreDialog extends Dialog { export class RdDTMRRencontreDialog extends Dialog {
/* -------------------------------------------- */ /* -------------------------------------------- */
constructor(html, tmrApp, rencontre) { constructor(html, tmrApp, rencontre, postRencontre) {
const dialogConf = { const dialogConf = {
title: "Rencontre en TMR!", title: "Rencontre en TMR!",
content: "Vous recontrez un " + rencontre.name + " de force " + rencontre.force + "<br>", content: "Vous recontrez un " + rencontre.name + " de force " + rencontre.force + "<br>",
buttons: { buttons: {
derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => { this.toClose = true; this.tmrApp.derober() } }, derober: { icon: '<i class="fas fa-check"></i>', label: "Se dérober", callback: () => { this.onButtonFuir(() => tmrApp.derober()); } },
refouler: { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => { this.toClose = true; this.tmrApp.refouler() } }, refouler: { icon: '<i class="fas fa-check"></i>', label: "Refouler", callback: () => this.onButtonAction(() => tmrApp.refouler()) },
maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => { this.toClose = true; this.tmrApp.maitriser() } } maitiser: { icon: '<i class="fas fa-check"></i>', label: "Maîtriser", callback: () => this.onButtonAction(() => tmrApp.maitriser()) }
}, },
default: "derober" default: "derober"
} };
if (rencontre.ignorer) { if (rencontre.ignorer) {
dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => { this.toClose = true; this.tmrApp.ignorerRencontre() }}; dialogConf.buttons.ignorer = { icon: '<i class="fas fa-check"></i>', label: "Ignorer", callback: () => this.onButtonAction(() => tmrApp.ignorerRencontre()) }
} };
const dialogOptions = { const dialogOptions = {
classes: ["tmrrencdialog"], classes: ["tmrrencdialog"],
@ -26,10 +26,22 @@ export class RdDTMRRencontreDialog extends Dialog {
this.toClose = false; this.toClose = false;
this.rencontreData = duplicate(rencontre); this.rencontreData = duplicate(rencontre);
this.postRencontre = postRencontre;
this.tmrApp = tmrApp; this.tmrApp = tmrApp;
this.tmrApp.minimize(); this.tmrApp.minimize();
} }
async onButtonAction(action) {
this.toClose = true;
await action();
this.postRencontre();
}
onButtonFuir(action) {
this.toClose = true;
await action();
}
/* -------------------------------------------- */ /* -------------------------------------------- */
close() { close() {
if (this.toClose) { if (this.toClose) {

View File

@ -84,7 +84,7 @@ const typeRencontres = {
}, },
changeur: { changeur: {
msgSucces: (data) => `Le ${data.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[data.tmr.type]} de votre choix en échange de sa liberté.`, msgSucces: (data) => `Le ${data.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[data.tmr.type].name} de votre choix en échange de sa liberté.`,
msgEchec: (data) => { msgEchec: (data) => {
data.newTMR = TMRUtility.getTMRAleatoire(data.tmr.type); data.newTMR = TMRUtility.getTMRAleatoire(data.tmr.type);
return `Le ${data.rencontre.name} vous embobine avec des promesses, et vous transporte en ${data.newTMR.label} sans attendre votre avis.`; return `Le ${data.rencontre.name} vous embobine avec des promesses, et vous transporte en ${data.newTMR.label} sans attendre votre avis.`;

View File

@ -1,6 +1,7 @@
import { DeDraconique } from "./de-draconique.js"; import { DeDraconique } from "./de-draconique.js";
import { TMRRencontres } from "./tmr-rencontres.js"; import { TMRRencontres } from "./tmr-rencontres.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
const TMRMapping = { const TMRMapping = {
@ -210,20 +211,20 @@ const TMRMapping = {
} }
export const TMRType = { export const TMRType = {
cite: "cité", cite: {name:"cité"},
sanctuaire: "sanctuaire", sanctuaire: {name:"sanctuaire"},
plaines: "plaines", plaines: {name:"plaines"},
pont: "pont", pont: {name:"pont"},
collines: "collines", collines: {name:"collines"},
foret: "forêt", foret: {name:"forêt"},
monts: "monts", monts: {name:"monts"},
desert: "désert", desert: {name:"désert"},
fleuve: "fleuve", fleuve: {name:"fleuve"},
lac: "lac", lac: {name:"lac"},
marais: "marais", marais: {name:"marais"},
gouffre: "gouffre", gouffre: {name:"gouffre"},
necropole: "nécropole", necropole: {name:"nécropole"},
desolation: "désolation" desolation: {name:"désolation"}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -257,14 +258,17 @@ export class TMRUtility {
for (let coord in TMRMapping) { for (let coord in TMRMapping) {
TMRMapping[coord].coord = coord; TMRMapping[coord].coord = coord;
} }
let tmrByType = Misc.classify(Object.values(TMRMapping));
for (const [type, list] of Object.entries(tmrByType)) {
TMRType[type].list = list;
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static convertToTMRCoord( x, y ) static convertToTMRCoord( pos )
{ {
y = y + 1 let letterX = String.fromCharCode(65+ (pos.x));
let letterX = String.fromCharCode(65+x); return letterX + (pos.y +1)
return letterX+y
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -280,7 +284,7 @@ export class TMRUtility {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static convertToCellCoord( coordTMR ) static convertToCellPos( coordTMR )
{ {
let x = coordTMR.charCodeAt(0) - 65; let x = coordTMR.charCodeAt(0) - 65;
let y = coordTMR.substr(1) - 1; let y = coordTMR.substr(1) - 1;
@ -328,13 +332,13 @@ export class TMRUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static deplaceTMRSelonPattern( coord, direction, nTime ) { static deplaceTMRSelonPattern( coord, direction, nTime ) {
for (let i=0; i <nTime; i++) { for (let i=0; i <nTime; i++) {
let currentPosXY = TMRUtility.convertToCellCoord(coord); let currentPosXY = TMRUtility.convertToCellPos(coord);
currentPosXY.x = currentPosXY.x + direction.x; currentPosXY.x = currentPosXY.x + direction.x;
currentPosXY.y = currentPosXY.y + direction.y; currentPosXY.y = currentPosXY.y + direction.y;
if ( this._checkTMRCoord(currentPosXY.x, currentPosXY.y) ) { // Sortie de carte ! Ré-insertion aléatoire if ( this._checkTMRCoord(currentPosXY.x, currentPosXY.y) ) { // Sortie de carte ! Ré-insertion aléatoire
coord = TMRUtility.convertToTMRCoord(currentPosXY.x, currentPosXY.y); coord = TMRUtility.convertToTMRCoord(currentPosXY);
} else { } else {
coord = this.getTMRAleatoire(); coord = this.getTMRAleatoire().coord;
} }
console.log("Nouvelle case iteration !!!", i, coord); console.log("Nouvelle case iteration !!!", i, coord);
} }
@ -361,41 +365,18 @@ export class TMRUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static getListTMR(terrain) { static getListTMR(terrain) {
let list = []; return TMRType[terrain].list;
for (let index in TMRMapping) {
if (TMRMapping[index].type == terrain){
list.push(TMRMapping[index]);
}
}
return list;
} }
static getListCoordTMR(terrain) { static getListCoordTMR(terrain) {
return this.getListTMR(terrain).map(it=>it.coord); return this.getListTMR(terrain).map(it=>it.coord);
} }
/* -------------------------------------------- */ static getTMRAleatoire(terrain = undefined) {
static getTMRAleatoire(terrain=undefined) let list = terrain ? TMRUtility.getListTMR(terrain) : Object.values(TMRMapping);
{
if (terrain) {
let list = TMRUtility.getListTMR(terrain);
let index = new Roll("1d" + list.length).evaluate().total - 1; let index = new Roll("1d" + list.length).evaluate().total - 1;
return list[index]; return list[index];
} }
let num = new Roll("1d15").roll().total;
let letter, letterValue;
if ( num == 15) {
letterValue = new Roll( "1d7").roll().total;
letter = String.fromCharCode( 65 + ((parseInt(letterValue)-1)*2) );
} else {
letterValue = new Roll( "1d13 + 64" ).roll().total;
letter = String.fromCharCode( letterValue );
}
let caseIndex = letter+num;
ChatMessage.create( { content: "Case aléatoire : " + letter+num + " - " + TMRMapping[caseIndex].label ,
whisper: ChatMessage.getWhisperRecipients("GM") } );
return caseIndex;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static _checkTMRCoord( x, y ) { static _checkTMRCoord( x, y ) {
@ -432,22 +413,22 @@ export class TMRUtility {
/** Returns a list of case inside a given distance /** Returns a list of case inside a given distance
* *
*/ */
static getTMRPortee(coord, portee) { static getTMRPortee(centerCoord, portee) {
return TMRUtility.getTMRArea(coord, portee, tmrConstants); return TMRUtility.getTMRArea(centerCoord, portee, tmrConstants);
} }
static getTMRArea( coord, distance, tmrConstants ) { static getTMRArea( centerCoord, distance, tmrConstants ) {
let pos = this.convertToCellCoord( coord ); let centerPos = this.convertToCellPos( centerCoord );
let posPic = this.computeRealPictureCoordinates( pos, tmrConstants ); let posPic = this.computeRealPictureCoordinates( centerPos, tmrConstants );
let caseList = []; let caseList = [];
for (let x=pos.x-distance; x<=pos.x+distance; x++ ) { // Loop thru lines for (let dx=-distance; dx<=distance; dx++ ) { // Loop thru lines
for (let y=pos.y-distance; y<=pos.y+distance; y++ ) { // Loop thru lines for (let dy=-distance; dy<=distance; dy++ ) { // Loop thru lines
//console.log("Parsing position", x, y); const currentPos = { x: centerPos.x+dx, y: centerPos.y+dy };
if ( this._checkTMRCoord(x, y) ) { // Coordinate is valie if ( this._checkTMRCoord(currentPos.x, currentPos.y) ) { // Coordinate is valie
let posPicNow = this.computeRealPictureCoordinates( {x: x, y: y}, tmrConstants ); let posPicNow = this.computeRealPictureCoordinates( currentPos, tmrConstants );
let dist = Math.sqrt(Math.pow(posPicNow.x - posPic.x,2) + Math.pow(posPicNow.y - posPic.y, 2)) / tmrConstants.cellw; let dist = Math.sqrt(Math.pow(posPicNow.x - posPic.x,2) + Math.pow(posPicNow.y - posPic.y, 2)) / tmrConstants.cellw;
if ( dist < distance+0.5) { if ( dist < distance+0.5) {
caseList.push( this.convertToTMRCoord(x, y) ); // Inside the area caseList.push( this.convertToTMRCoord(currentPos) ); // Inside the area
} }
} }
} }

File diff suppressed because one or more lines are too long