Fixes nombreux sur tmr

- rencontre sur case humide ne causait pas de maîtrise
- détermination de la liste des tmrs par type à l'init (classify)
- tirages aléatoire par type de tmr dans les commandes
- amélioration de messages (nom de case)
- fix expérience case humide
- correction gestion des débordement
- montées très laborieuses multiples
- renommages et extraits méthodes
- distinction de pos (x, y) vs coord (A1)
This commit is contained in:
Vincent Vandemeulebrouck 2021-02-05 01:38:40 +01:00
parent d53077d862
commit 9fd7db2ccf
11 changed files with 282 additions and 246 deletions

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));
return true; 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 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

@ -9,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)?/;
@ -21,20 +21,23 @@ export class RdDCommands {
const rddCommands = new RdDCommands(); const rddCommands = new RdDCommands();
rddCommands.registerCommand({ path: ["/aide"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" }); rddCommands.registerCommand({ path: ["/aide"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
rddCommands.registerCommand({ path: ["/help"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" }); rddCommands.registerCommand({ path: ["/help"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" });
rddCommands.registerCommand({ path: ["/table", "queues"], func: (content, msg, params) => RdDRollTables.getQueue(true), descr: "Tire une Queue de Dragon" }); rddCommands.registerCommand({ path: ["/table", "queues"], func: (content, msg, params) => RdDRollTables.getQueue(), descr: "Tire une Queue de Dragon" });
rddCommands.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre(true), descr: "Tire une Ombre de Dragon" }); rddCommands.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre(), descr: "Tire une Ombre de Dragon" });
rddCommands.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR(true), descr: "Tire une Tête de Dragon pour Hauts Revants" }); rddCommands.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR(), descr: "Tire une Tête de Dragon pour Hauts Revants" });
rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(true), 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(true), 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(true), 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: ["/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({
@ -53,27 +56,24 @@ export class RdDCommands {
rddCommands.registerCommand({ rddCommands.registerCommand({
path: ["/rdd"], func: (content, msg, params) => rddCommands.rollRdd(msg, params), path: ["/rdd"], func: (content, msg, params) => rddCommands.rollRdd(msg, params),
descr: `Effectue un jet de dés dans la table de résolution. Exemples: descr: `Effectue un jet de dés dans la table de résolution. Exemples:
<br><strong>/rdd</strong> ouvre la table de résolution <br><strong>/rdd</strong> ouvre la table de résolution
<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" });
rddCommands.registerCommand({ rddCommands.registerCommand({
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;
} }
@ -185,7 +185,7 @@ export class RdDCommands {
/* -------------------------------------------- */ /* -------------------------------------------- */
async getRencontreTMR(params) { async getRencontreTMR(params) {
if (params.length == 1 || params.length ==2) { if (params.length == 1 || params.length == 2) {
return TMRRencontres.rollRencontre(params[0], params[1]) return TMRRencontres.rollRencontre(params[0], params[1])
} }
else { else {
@ -232,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

@ -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,20 +247,22 @@ 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) {
if (nbRounds < 0) { setTimeout(() => {
ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}"`); if (nbRounds < 0) {
} ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}"`);
else {
for (let i = 1; i < nbRounds; i++) {
ChatUtility.removeChatMessageContaining(`<h4 data-categorie="tmr" data-actor-id="${actor._id}" data-rencontre-round="${i}">`);
} }
} else {
for (let i = 1; i < nbRounds; 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); this.nbFatigue = this.actor.getTMRFatigue();
// Mise à jour du nb de cases de Fatigue this.actor.displayTMRQueueSouffleInformation();
this.nbFatigue = this.actor.getTMRFatigue(); });
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

@ -1,22 +1,22 @@
/* -------------------------------------------- */ /* -------------------------------------------- */
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"],
width: 320, height: 240, width: 320, height: 240,
@ -26,13 +26,25 @@ 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) {
this.tmrApp.maximize(); this.tmrApp.maximize();
return super.close(); return super.close();
} }

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,40 +365,17 @@ 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);
{ let index = new Roll("1d" + list.length).evaluate().total - 1;
if (terrain) { return list[index];
let list = TMRUtility.getListTMR(terrain);
let index = new Roll("1d" + list.length).evaluate().total - 1;
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;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -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
} }
} }
} }