626 lines
29 KiB
JavaScript
626 lines
29 KiB
JavaScript
import { RdDDice } from "./rdd-dice.js";
|
||
|
||
/* -------------------------------------------- */
|
||
const TMRMapping = {
|
||
A1: { type: "cite", label: "Cité Vide"},
|
||
B1: { type: "plaines", label: "Plaines d’Assorh"},
|
||
C1: { type: "necropole", label: "Nécropole de Kroak"},
|
||
D1: { type: "fleuve", label: "Fleuve"},
|
||
E1: { type: "monts", label: "Monts de Kanaï"},
|
||
F1: { type: "cite", label: "Cité Glauque"},
|
||
G1: { type: "desolation", label: "Désolation de Demain"},
|
||
H1: { type: "lac", label: "Lac d’Anticalme"},
|
||
I1: { type: "plaines", label: "Plaines Grises"},
|
||
J1: { type: "monts", label: "Monts Fainéants"},
|
||
K1: { type: "cite", label: "Cité d’Onkause"},
|
||
L1: { type: "fleuve", label: "Fleuve"},
|
||
M1: { type: "cite", label: "Cité Jalouse"},
|
||
|
||
A2: { type: "desert", label: "Désert de Mieux"},
|
||
B2: { type: "collines", label: "Collines de Dawell"},
|
||
C2: { type: "marais", label: "Marais Glignants"},
|
||
D2: { type: "cite", label: "Cité de Frost"},
|
||
E2: { type: "plaines", label: "Plaines de Fiask"},
|
||
F2: { type: "lac", label: "Lac de Misère"},
|
||
G2: { type: "marais", label: "Marais Nuisants"},
|
||
H2: { type: "collines", label: "Collines de Parta"},
|
||
I2: { type: "foret", label: "Forêt Fade"},
|
||
J2: { type: "desert", label: "Désert de Poly"},
|
||
K2: { type: "foret", label: "Forêt Tamée"},
|
||
L2: { type: "fleuve", label: "Fleuve"},
|
||
M2: { type: "necropole", label: "Nécropole de Logos"},
|
||
|
||
A3: { type: "desolation", label: "Désolation de Demain"},
|
||
B3: { type: "plaines", label: "Plaines de Rubéga"},
|
||
C3: { type: "fleuve", label: "Fleuve"},
|
||
D3: { type: "gouffre", label: "Gouffre d’Oki"},
|
||
E3: { type: "foret", label: "Forêt d’Estoubh"},
|
||
F3: { type: "fleuve", label: "Fleuve"},
|
||
G3: { type: "gouffre", label: "Gouffre de Sun"},
|
||
H3: { type: "foret", label: "Forêt de Ganna"},
|
||
I3: { type: "monts", label: "Monts Grinçants"},
|
||
J3: { type: "cite", label: "Cité Venin"},
|
||
K3: { type: "plaines", label: "Plaines de Dois"},
|
||
L3: { type: "lac", label: "Lac Laineux"},
|
||
M3: { type: "monts", label: "Monts de Vdah"},
|
||
|
||
A4: { type: "foret", label: "Forêt de Falconax"},
|
||
B4: { type: "monts", label: "Monts Crâneurs"},
|
||
C4: { type: "pont", label: "Pont de Giolii"},
|
||
D4: { type: "lac", label: "Lac de Foam"},
|
||
E4: { type: "plaines", label: "Plaines d’Orti"},
|
||
F4: { type: "fleuve", label: "Fleuve"},
|
||
G4: { type: "sanctuaire", label: "Sanctuaire Blanc"},
|
||
H4: { type: "plaines", label: "Plaines de Psark"},
|
||
I4: { type: "plaines", label: "Plaines de Xiax"},
|
||
J4: { type: "collines", label: "Collines d’Encre"},
|
||
K4: { type: "pont", label: "Pont de Fah"},
|
||
L4: { type: "sanctuaire", label: "Sanctuaire Mauve"},
|
||
M4: { type: "gouffre", label: "Gouffre Grisant"},
|
||
|
||
A5: { type: "plaines", label: "Plaines de Trilkh"},
|
||
B5: { type: "collines", label: "Collines de Tanegy"},
|
||
C5: { type: "marais", label: "Marais Flouants"},
|
||
D5: { type: "fleuve", label: "Fleuve"},
|
||
E5: { type: "monts", label: "Monts Brûlants"},
|
||
F5: { type: "cite", label: "Cité de Panople"},
|
||
G5: { type: "pont", label: "Pont d’Ik"},
|
||
H5: { type: "desert", label: "Désert de Krane"},
|
||
I5: { type: "desolation", label: "Désolation de Demain"},
|
||
J5: { type: "marais", label: "Marais de Jab"},
|
||
K5: { type: "fleuve", label: "Fleuve"},
|
||
L5: { type: "collines", label: "Collines Suaves"},
|
||
M5: { type: "cite", label: "Cité Rimarde"},
|
||
|
||
A6: { type: "necropole", label: "Nécropole de Zniak"},
|
||
B6: { type: "foret", label: "Forêt de Bust"},
|
||
C6: { type: "cite", label: "Cité Pavois"},
|
||
D6: { type: "fleuve", label: "Fleuve"},
|
||
E6: { type: "sanctuaire", label: "Sanctuaire de Plaine"},
|
||
F6: { type: "fleuve", label: "Fleuve"},
|
||
G6: { type: "marais", label: "Marais Glutants"},
|
||
H6: { type: "monts", label: "Monts Gurdes"},
|
||
I6: { type: "necropole", label: "Nécropole de Xotar"},
|
||
J6: { type: "lac", label: "Lac d’Iaupe"},
|
||
K6: { type: "desolation", label: "Désolation de Demain"},
|
||
L6: { type: "foret", label: "Forêt Gueuse"},
|
||
M6: { type: "desolation", label: "Désolation de Demain"},
|
||
|
||
A7: { type: "plaines", label: "Plaines de l’Arc"},
|
||
B7: { type: "marais", label: "Marais Bluants"},
|
||
C7: { type: "fleuve", label: "Fleuve"},
|
||
D7: { type: "plaines", label: "Plaines d’A!a"},
|
||
E7: { type: "foret", label: "Forêt de Glusks"},
|
||
F7: { type: "fleuve", label: "Fleuve"},
|
||
G7: { type: "cite", label: "Cité de Terwa"},
|
||
H7: { type: "gouffre", label: "Gouffre de Kapfa"},
|
||
I7: { type: "plaines", label: "Plaines de Troo"},
|
||
J7: { type: "fleuve", label: "Fleuve"},
|
||
K7: { type: "cite", label: "Cité de Kolix"},
|
||
L7: { type: "gouffre", label: "Gouffre d’Episophe"},
|
||
M7: { type: "desert", label: "Désert de Lave"},
|
||
|
||
A8: { type: "gouffre", label: "Gouffre de Shok"},
|
||
B8: { type: "fleuve", label: "Fleuve"},
|
||
C8: { type: "foret", label: "Forêt Turmide"},
|
||
D8: { type: "cite", label: "Cité d’Olak"},
|
||
E8: { type: "plaines", label: "Plaines d’Iolise"},
|
||
F8: { type: "lac", label: "Lac des Chats"},
|
||
G8: { type: "plaines", label: "Plaines Sans Joie"},
|
||
H8: { type: "foret", label: "Forêt d’Ourf"},
|
||
I8: { type: "fleuve", label: "Fleuve"},
|
||
J8: { type: "monts", label: "Monts Barask"},
|
||
K8: { type: "desert", label: "Désert de Fumée"},
|
||
L8: { type: "monts", label: "Monts Tavelés"},
|
||
M8: { type: "plaines", label: "Plaines Lavées"},
|
||
|
||
A9: { type: "collines", label: "Collines de Korrex"},
|
||
B9: { type: "lac", label: "Lac de Lucre"},
|
||
C9: { type: "monts", label: "Monts Tuméfiés"},
|
||
D9: { type: "pont", label: "Pont d’Orx"},
|
||
E9: { type: "fleuve", label: "Fleuve"},
|
||
F9: { type: "plaines", label: "Plaines de Foe"},
|
||
G9: { type: "desolation", label: "Désolation de Demain"},
|
||
H9: { type: "collines", label: "Collines de Noirseul"},
|
||
I9: { type: "fleuve", label: "Fleuve"},
|
||
J9: { type: "marais", label: "Marais Gronchants"},
|
||
K9: { type: "sanctuaire", label: "Sanctuaire Noir"},
|
||
L9: { type: "collines", label: "Collines Cornues"},
|
||
M9: { type: "necropole", label: "Nécropole de Zonar"},
|
||
|
||
A10: { type: "sanctuaire", label: "Sanctuaire d’Olis"},
|
||
B10: { type: "monts", label: "Monts Salés"},
|
||
C10: { type: "marais", label: "Marais de Dom"},
|
||
D10: { type: "fleuve", label: "Fleuve"},
|
||
E10: { type: "gouffre", label: "Gouffre de Junk"},
|
||
F10: { type: "marais", label: "Marais Zultants"},
|
||
G10: { type: "cite", label: "Cité de Sergal"},
|
||
H10: { type: "plaines", label: "Plaines Noires"},
|
||
I10: { type: "lac", label: "Lac Wanito"},
|
||
J10: { type: "fleuve", label: "Fleuve"},
|
||
K10: { type: "plaines", label: "Plaines Jaunes"},
|
||
L10: { type: "desert", label: "Désert de Nicrop"},
|
||
M10: { type: "foret", label: "Forêt de Jajou"},
|
||
|
||
A11: { type: "desolation", label: "Désolation de Demain"},
|
||
B11: { type: "cite", label: "Cité de Brilz"},
|
||
C11: { type: "pont", label: "Pont de Roï"},
|
||
D11: { type: "desolation", label: "Désolation de Demain"},
|
||
E11: { type: "lac", label: "Lac de Glinster"},
|
||
F11: { type: "cite", label: "Cité de Noape"},
|
||
G11: { type: "fleuve", label: "Fleuve"},
|
||
H11: { type: "fleuve", label: "Fleuve"},
|
||
I11: { type: "pont", label: "Pont de Yalm"},
|
||
J11: { type: "plaines", label: "Plaines de Miltiar"},
|
||
K11: { type: "cite", label: "Cité Tonnerre"},
|
||
L11: { type: "collines", label: "Collines de Kol"},
|
||
M11: { type: "cite", label: "Cité Crapaud"},
|
||
|
||
A12: { type: "plaines", label: "Plaines Sages"},
|
||
B12: { type: "fleuve", label: "Fleuve"},
|
||
C12: { type: "lac", label: "Lac de Fricassa"},
|
||
D12: { type: "collines", label: "Collines d’Huaï"},
|
||
E12: { type: "monts", label: "Monts Ajourés"},
|
||
F12: { type: "necropole", label: "Nécropole de Troat"},
|
||
G12: { type: "plaines", label: "Plaines de Lufmil"},
|
||
H12: { type: "collines", label: "Collines de Tooth"},
|
||
I12: { type: "gouffre", label: "Gouffre Abimeux"},
|
||
J12: { type: "cite", label: "Cité Folle"},
|
||
K12: { type: "desolation", label: "Désolation de Demain"},
|
||
L12: { type: "plaines", label: "Plaines Venteuses"},
|
||
M12: { type: "collines", label: "Collines Révulsantes"},
|
||
|
||
A13: { type: "fleuve", label: "Fleuve"},
|
||
B13: { type: "gouffre", label: "Gouffre des Litiges"},
|
||
C13: { type: "desert", label: "Désert de Neige"},
|
||
D13: { type: "cite", label: "Cité Sordide"},
|
||
E13: { type: "plaines", label: "Plaines de Xnez"},
|
||
F13: { type: "foret", label: "Forêt des Cris"},
|
||
G13: { type: "plaines", label: "Plaines Calcaires"},
|
||
H13: { type: "desolation", label: "Désolation de Demain"},
|
||
I13: { type: "monts", label: "Monts Bigleux"},
|
||
J13: { type: "gouffre", label: "Gouffre de Gromph"},
|
||
K13: { type: "foret", label: "Forêt de Kluth"},
|
||
L13: { type: "monts", label: "Monts Dormants"},
|
||
M13: { type: "plaines", label: "Plaines d’Anjou"},
|
||
|
||
A14: { type: "collines", label: "Collines de Stolis"},
|
||
B14: { type: "necropole", label: "Nécropole de Gorlo"},
|
||
C14: { type: "foret", label: "Forêt de Bissam"},
|
||
D14: { type: "sanctuaire", label: "Sanctuaire Plat"},
|
||
E14: { type: "monts", label: "Monts de Quath"},
|
||
F14: { type: "plaines", label: "Plaines Brisées"},
|
||
G14: { type: "desert", label: "Désert de Sek"},
|
||
H14: { type: "plaines", label: "Plaines Blanches"},
|
||
I14: { type: "cite", label: "Cité Destituée"},
|
||
J14: { type: "desert", label: "Désert de Sank"},
|
||
K14: { type: "necropole", label: "Nécropole d’Antinéar"},
|
||
L14: { type: "plaines", label: "Plaines de Jislith"},
|
||
M14: { type: "desolation", label: "Désolation de Demain"},
|
||
|
||
A15: { type: "cite", label: "Cité de Mielh"},
|
||
C15: { type: "plaines", label: "Plaines de Toué"},
|
||
E15: { type: "foret", label: "Forêt des Furies"},
|
||
G15: { type: "plaines", label: "Plaines des Soupirs"},
|
||
I15: { type: "monts", label: "Monts des Dragées"},
|
||
K15: { type: "collines", label: "Collines Pourpres"},
|
||
M15: { type: "cite", label: "Cité de Klana"}
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
const rencontresSpeciale = [
|
||
{name:"Mangeur de Rêve", data: { force: "1d6", ignorer: false, derober: true, refoulement: 2, quitterTMR: false } },
|
||
{name:"Mangeur de Rêve", data: { force: "2d6", ignorer: false, derober: true, refoulement: 2, quitterTMR: false } },
|
||
{name:"Reflet d'ancien Rêve", data: { force: "2d6+4", ignorer: false, derober: true, refoulement: 2, quitterTMR: false } },
|
||
{name:"Tourbillon blanc", data: { force: "2d6+4", ignorer: false, derober: true, refoulement: 2, quitterTMR: false } },
|
||
{name:"Tourbillon noir", data: { force: "2d8+4", ignorer: false, derober: true, refoulement: 2, quitterTMR: false } },
|
||
{name:"Passeur fou", data: { force: "2d8", ignorer: false, derober: true, refoulement: 2, quitterTMR: false } },
|
||
{name:"Tourbillon rouge", data: { force: "2d8", ignorer: false, derober: true, refoulement: 3, quitterTMR: false } }
|
||
]
|
||
|
||
/* -------------------------------------------- */
|
||
const rencontresTable = [
|
||
{name:"Messagers des Rêves", data: { force: "2d4", ignorer: true, derober: true, refoulement: 1, quitterTMR: false,
|
||
cite: "01-25", sanctuaire: "01-25", plaines: "01-20", pont: "01-20", collines: "01-15", foret: "01-15", monts: "01-10", desert: "01-10", fleuve: "01-05",
|
||
lac: "01-05", marais: "01-02", gouffre: "01-02", necropole: "00-00", desolation: "00-00" } },
|
||
{name:"Passeur des Rêves", data: { force: "2d4", ignorer: true, derober: true, refoulement: 1, quitterTMR: false,
|
||
cite: "26-50", sanctuaire: "26-50", plaines: "21-40", pont: "21-40", collines: "16-30", foret: "16-30", monts: "11-20", desert: "11-20", fleuve: "06-10",
|
||
lac: "06-10", marais: "03-04", gouffre: "03-04", necropole: "00-00", desolation: "00-00" } },
|
||
{name:"Fleur des Rêves", data: { force: "1d6", ignorer: true, derober: true, refoulement: 1, quitterTMR: false,
|
||
cite: "51-65", sanctuaire: "51-65", plaines: "41-55", pont: "41-55", collines: "31-42", foret: "31-42", monts: "21-26", desert: "21-26", fleuve: "11-13",
|
||
lac: "11-13", marais: "05-05", gouffre: "05-05", necropole: "00-00", desolation: "00-00" } },
|
||
{name:"Mangeur de Rêve", data: { force: "1d6", ignorer: false, derober: true, refoulement: 1, quitterTMR: false,
|
||
cite: "66-70", sanctuaire: "66-70", plaines: "56-60", pont: "56-60", collines: "43-54", foret: "43-54", monts: "27-44", desert: "27-44", fleuve: "14-37",
|
||
lac: "14-37", marais: "06-29", gouffre: "06-29", necropole: "01-20", desolation: "01-20" } },
|
||
{name:"Changeur de Rêve", data: { force: "2d6", ignorer: false, derober: true, refoulement: 1, quitterTMR: false,
|
||
cite: "71-80", sanctuaire: "71-80", plaines: "61-75", pont: "61-75", collines: "55-69", foret: "55-69", monts: "45-59", desert: "45-59", fleuve: "38-49",
|
||
lac: "38-49", marais: "30-39", gouffre: "30-39", necropole: "21-30", desolation: "21-30" } },
|
||
{name:"Briseur de Rêve", data: { force: "2d6", ignorer: false, derober: true, refoulement: 1, quitterTMR: true,
|
||
cite: "81-85", sanctuaire: "81-85", plaines: "76-82", pont: "76-82", collines: "70-82", foret: "70-82", monts: "60-75", desert: "60-75", fleuve: "50-65",
|
||
lac: "50-65", marais: "40-60", gouffre: "40-60", necropole: "31-50", desolation: "31-50" } },
|
||
{name:"Reflet d'ancien Rêve", data: { force: "2d6", ignorer: false, derober: true, refoulement: 1,quitterTMR: false,
|
||
cite: "86-90", sanctuaire: "86-90", plaines: "83-88", pont: "83-88", collines: "83-88", foret: "83-88", monts: "76-85", desert: "76-85", fleuve: "66-79",
|
||
lac: "66-79", marais: "61-75", gouffre: "61-75", necropole: "51-65", desolation: "51-65" } },
|
||
{name:"Tourbillon blanc", data: { force: "2d6", ignorer: false, derober: true, refoulement: 1, quitterTMR: false,
|
||
cite: "91-94", sanctuaire: "91-94", plaines: "89-93", pont: "89-93", collines: "89-93", foret: "89-93", monts: "86-92", desert: "86-92", fleuve: "80-89",
|
||
lac: "80-89", marais: "76-86", gouffre: "76-86", necropole: "66-80", desolation: "66-80" } },
|
||
{name:"Tourbillon noir", data: { force: "2d8", ignorer: false, derober: true, refoulement: 1, quitterTMR: false,
|
||
cite: "95-97", sanctuaire: "95-97", plaines: "94-97", pont: "94-97", collines: "94-97", foret: "94-97", monts: "93-97", desert: "93-97", fleuve: "90-97",
|
||
lac: "90-97", marais: "87-97", gouffre: "90-97", necropole: "81-97", desolation: "81-97" } },
|
||
{name:"Rêve de Dragon", data: { force: "1ddr + 7", ignorer: false, derober: true, refoulement: 2, quitterTMR: true,
|
||
cite: "98-00", sanctuaire: "98-00", plaines: "98-00", pont: "98-00", collines: "98-00", foret: "98-00", monts: "98-00", desert: "98-00", fleuve: "98-00",
|
||
lac: "98-00", marais: "98-00", gouffre: "98-00", necropole: "98-00", desolation: "98-00" } }
|
||
]
|
||
|
||
/* -------------------------------------------- */
|
||
const tmrMovePattern =
|
||
[ { name: 'top', x: 0, y: -1 },
|
||
{ name: 'topright', x: 1, y: -1 },
|
||
{ name: 'left', x: 1, y: 'alt' },
|
||
{ name: 'botright', x: 1, y: 1 },
|
||
{ name: 'bot', x: 0, y: 1 },
|
||
{ name: 'botleft', x: -1, y: 1 },
|
||
{ name: 'left', x: -1, y: 'alt' },
|
||
{ name: 'topleft', x: -1, y: -1 }
|
||
]
|
||
|
||
/* -------------------------------------------- */
|
||
|
||
/* -------------------------------------------- */
|
||
export class TMRUtility {
|
||
|
||
|
||
/* -------------------------------------------- */
|
||
static convertToTMRCoord( x, y )
|
||
{
|
||
y = y + 1
|
||
let letterX = String.fromCharCode(65+x);
|
||
return letterX+y
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static verifyTMRCoord( coord ) {
|
||
let TMRregexp = new RegExp(/([A-M])(\d+)/g);
|
||
let res = TMRregexp.exec( coord );
|
||
if (res && res[1] && res[2]) {
|
||
if (res[2] > 0 && res[2] < 16) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static convertToCellCoord( coordTMR )
|
||
{
|
||
let x = coordTMR.charCodeAt(0) - 65;
|
||
let y = coordTMR.substr(1) - 1;
|
||
return {x: x, y: y}
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getTMRDescription( coordTMR)
|
||
{
|
||
return TMRMapping[coordTMR];
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
/** Some debug functions */
|
||
static setForceRencontre( id, force ) {
|
||
this.forceRencontre = { id: id, force: force}
|
||
}
|
||
/* -------------------------------------------- */
|
||
static clearForceRencontre( id, force ) {
|
||
this.forceRencontre = undefined
|
||
}
|
||
/* -------------------------------------------- */
|
||
static isForceRencontre() {
|
||
return this.forceRencontre
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getDirectionPattern() {
|
||
let index = new Roll("1d"+tmrMovePattern.length+" -1").roll().total;
|
||
return tmrMovePattern[index];
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static deplaceTMRSelonPattern( pos, pattern, nTime ) {
|
||
for (let i=0; i <nTime; i++) {
|
||
let currentPosXY = TMRUtility.convertToCellCoord(pos);
|
||
currentPosXY.x = currentPosXY.x + pattern.x;
|
||
if (pattern.y == 'alt' ) { // Alternate version
|
||
pattern.y += (pattern.x % 2 == 0 ) ? -1 : 1;
|
||
} else {
|
||
currentPosXY.y = currentPosXY.y + pattern.y;
|
||
}
|
||
if ( this._checkTMRCoord(currentPosXY.x, currentPosXY.y) ) { // Sortie de carte ! Ré-insertion aléatoire
|
||
pos = TMRUtility.convertToTMRCoord(currentPosXY.x, currentPosXY.y);
|
||
} else {
|
||
pos = this.getTMRAleatoire();
|
||
}
|
||
console.log("Nouvelle case iteration !!!", i, pos);
|
||
}
|
||
return pos;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static async rencontreTMRRoll( coordTMR, cellDescr, isSpecial = false )
|
||
{
|
||
if ( this.forceRencontre ) {
|
||
// Forced
|
||
let rencontre = duplicate(rencontresTable[this.forceRencontre.id]);
|
||
rencontre.force = this.forceRencontre.force;
|
||
rencontre.coord = coordTMR;
|
||
rencontre.nbCases = 0; // Utilisé pour les Tourbillons
|
||
return rencontre;
|
||
}
|
||
let rencontre;
|
||
if ( isSpecial ) {
|
||
let index = new Roll("1d7").roll().total;
|
||
rencontre = rencontresSpeciale[index-1];
|
||
} else {
|
||
rencontre = await this.rencontreTMRTypeCase(cellDescr.type);
|
||
}
|
||
//let rencontre = rencontresTable[4];
|
||
if (rencontre) {
|
||
rencontre = duplicate(rencontre);
|
||
rencontre.force = await this.evaluerForceRencontre(rencontre);
|
||
rencontre.coord = coordTMR;
|
||
rencontre.nbCases = 0; // Utilisé pour les Tourbillons
|
||
rencontre.isSpecial = isSpecial; // Garder l'information
|
||
}
|
||
return rencontre;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static async rencontreTMRTypeCase(typeTMR, roll=undefined) {
|
||
if (!roll) {
|
||
//roll = await RdDDice.show(new Roll("d100").evaluate()).total;
|
||
roll = new Roll("1d100").roll().total;
|
||
console.log("rencontreTMRTypeCase", roll);
|
||
}
|
||
typeTMR = typeTMR.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||
for( let rencontre of rencontresTable) {
|
||
console.log("TMR !!!", typeTMR, roll);
|
||
let scoreDef = rencontre.data[typeTMR];
|
||
let min = scoreDef.substr(0,2);
|
||
let max = scoreDef.substr(3,2);
|
||
if (min=="00") min = 101;
|
||
if (max=="00") max = 100;
|
||
if (roll >= min && roll <= max) {
|
||
return rencontre;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
/**
|
||
* Retourne une recontre en fonction de la case et du tirage
|
||
* @param {*} caseName
|
||
* @param {*} roll
|
||
*/
|
||
static async getRencontre( caseName, roll ) {
|
||
if ( !caseName) {
|
||
ChatMessage.create({ content: "Un nom de case doit être indiqué (ie /tmrr desert ou /tmrr cite)" });
|
||
return false;
|
||
}
|
||
if (roll == undefined) {
|
||
roll = new Roll("1d100").evaluate().total;
|
||
}
|
||
roll = Math.max(1, Math.min(roll, 100));
|
||
|
||
let rencontre = await this.rencontreTMRTypeCase(caseName, roll);
|
||
if (rencontre) {
|
||
let force = await this.evaluerForceRencontre(rencontre);
|
||
ChatMessage.create({
|
||
user: game.user._id,
|
||
whisper: [game.user._id],
|
||
content: "Rencontre en " + caseName + "(jet : " + roll + "%)<br>Vous rencontrez un " + rencontre.name + " d'une force de " + force + " Points de Rêve"});
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getLocationTypeList( coordTMR ) {
|
||
let descr = this.getTMRDescription( coordTMR );
|
||
let typeList = [];
|
||
for (let index in TMRMapping) {
|
||
let caseTMR = TMRMapping[index];
|
||
if (caseTMR.type == descr.type)
|
||
typeList.push(index)
|
||
}
|
||
return typeList;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static async evaluerForceRencontre(rencontre) {
|
||
if (this.isReveDeDragon(rencontre)) {
|
||
let ddr = await RdDDice.deDraconique();
|
||
return ddr + 7;
|
||
}
|
||
else {
|
||
const roll = new Roll(rencontre.data.force).evaluate();
|
||
return roll.total;
|
||
}
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static isReveDeDragon(rencontre) {
|
||
return rencontre.name.toLowerCase() == "Rêve de Dragon".toLowerCase();
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static async processRencontreReussite( actor, rencontre, rolled ) {
|
||
let message = "<br>";
|
||
let state = "aucune";
|
||
|
||
console.log("processRencontreReussite", actor, rencontre);
|
||
if (rencontre.name == "Messagers des Rêves") {
|
||
message += "Le Messager des Rêves vous permet de lancer votre sort à " + rencontre.force + " cases !";
|
||
state = 'messager';
|
||
|
||
} else if (rencontre.name == "Passeur des Rêves") {
|
||
message += "Le Passeur des Rêves vous permet de vous téléporter à " + rencontre.force + " cases !";
|
||
state = 'passeur';
|
||
|
||
} else if (rencontre.name == "Fleur des Rêves") {
|
||
await actor.reveActuelIncDec( rencontre.force );
|
||
message += "La Fleur des rêves s'évanouit en vous fournissant " + rencontre.force + " Points de Rêve";
|
||
|
||
} else if (rencontre.name == "Mangeur de Rêve") {
|
||
message += "Ce Mangeur des Rêves disparait !"
|
||
|
||
} else if (rencontre.name == "Changeur de Rêve") {
|
||
message += "Ce Changeur des Rêves vous propose de vous déplacer sur une autre case de même type."
|
||
state = 'changeur';
|
||
|
||
} else if (rencontre.name == "Briseur de Rêve") {
|
||
message += "Ce Briseur des Rêves disparait !"
|
||
|
||
} else if (rencontre.name == "Reflet d'ancien Rêve") {
|
||
message += "Ce Reflet d'ancien Rêve disparait !"
|
||
|
||
} else if (rencontre.name == "Tourbillon blanc") {
|
||
message += "Ce Tourbillon Blanc disparait !"
|
||
|
||
} else if (rencontre.name == "Tourbillon noir") {
|
||
message += "Ce Tourbillon Noir disparait !"
|
||
|
||
} else if (rencontre.name == "Rêve de Dragon") {
|
||
// TODO: xp particulière
|
||
message += "Vous maîtrisez le Rêve de Dragon !"
|
||
message += actor.appliquerReveDeDragon(rolled, rencontre.force);
|
||
}
|
||
return { message: message, state: state };
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static async processRencontreEchec( actor, rencontre, rolled, tmrDialog ) {
|
||
let message = "<br>";
|
||
let state = "aucune";
|
||
|
||
if (rencontre.name == "Messagers des Rêves") {
|
||
message += "Le Messager des Rêves s'éloigne de vous !";
|
||
|
||
} else if (rencontre.name == "Passeur des Rêves") {
|
||
message += "Le Passeur des Rêves s'éloigne de vous !";
|
||
|
||
} else if (rencontre.name == "Fleur des Rêves") {
|
||
message += "La Fleur des rêves s'éloigne de vous et se perd dans les Terres Médianes";
|
||
|
||
} else if (rencontre.name == "Mangeur de Rêve") {
|
||
await actor.reveActuelIncDec( -rencontre.force );
|
||
message += "Ce Mangeur des Rêves croque votre Rêve ! Vous perdez " + rencontre.force + " points de rêve actuels, votre nouveau total est de " + actor.data.data.reve.reve.value;
|
||
|
||
} else if (rencontre.name == "Changeur de Rêve") {
|
||
message += "Ce Changeur des Rêves vous déplace sur un autre case du même type.<br>"
|
||
let locList = this.getLocationTypeList( actor.data.data.reve.tmrpos.coord );
|
||
let index = new Roll("1d"+locList.length + " - 1").roll().total;
|
||
let newCoord = locList[index];
|
||
tmrDialog.forceDemiRevePosition(newCoord);
|
||
let cellDescr = TMRUtility.getTMRDescription(newCoord);
|
||
message += "Vous avez été téléporté en " + newCoord + " - " + cellDescr.label;
|
||
|
||
} else if (rencontre.name == "Briseur de Rêve") {
|
||
message += "Votre Rêve est Brisé, vous quittez les Terres Médianes";
|
||
|
||
} else if (rencontre.name == "Passeur fou") {
|
||
message += "Vous êtes déplacé sur la case de votre sort en réserve le plus proche, ou sinon aléatoirement dans une direction";
|
||
state = "passeurfou";
|
||
|
||
} else if (rencontre.name == "Reflet d'ancien Rêve") {
|
||
message += "Votre Rêve est figé, vous restez sur cette case tant que ce Reflet n'est pas vaincu!";
|
||
state = "reflet";
|
||
|
||
} else if (rencontre.name == "Tourbillon blanc") {
|
||
message += "Vous êtes emporté par le Tourbillon...";
|
||
state = "tourbillonblanc";
|
||
|
||
} else if (rencontre.name == "Tourbillon noir") {
|
||
message += "Vous êtes emporté par le Tourbillon...";
|
||
state = "tourbillonnoir";
|
||
|
||
} else if (rencontre.name == "Tourbillon rouge") {
|
||
message += "Vous êtes emporté par le Tourbillon...";
|
||
state = "tourbillonrouge";
|
||
|
||
} else if (rencontre.name == "Rêve de Dragon") {
|
||
message += "Le Rêve de Dragon tourne au cauchemar !"
|
||
message += actor.appliquerReveDeDragon(rolled, rencontre.force);
|
||
}
|
||
return { message: message, state: state };
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getTMRAleatoire()
|
||
{
|
||
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") } );
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static _checkTMRCoord( x, y ) {
|
||
if (x >= 0 && x < 13 && y >= 0 && y < 15 ) return true;
|
||
return false;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static computeRealPictureCoordinates( coordXY, tmrConstants ) {
|
||
let decallagePairImpair = (coordXY.x % 2 == 0) ? tmrConstants.col1_y : tmrConstants.col2_y;
|
||
return {
|
||
x: tmrConstants.gridx + (coordXY.x * tmrConstants.cellw),
|
||
y: tmrConstants.gridy + (coordXY.y * tmrConstants.cellh) + decallagePairImpair
|
||
}
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
static getSortReserve( reserveList, coordTMR ) {
|
||
// TODO : Gérer les têtes spéciales réserve!
|
||
let sortReserve
|
||
let tmrDescr = this.getTMRDescription(coordTMR);
|
||
console.log("Sort réserve : ", tmrDescr);
|
||
if ( tmrDescr.type == 'fleuve') { // Gestion de la reserve en Fleuve
|
||
sortReserve = reserveList.find(it => TMRUtility.getTMRDescription(it.coord).type == 'fleuve' );
|
||
} else { // Reserve sur un case "normale"
|
||
sortReserve = reserveList.find(it => it.coord == coordTMR);
|
||
}
|
||
console.log("Sort réserve : ", tmrDescr, sortReserve, reserveList);
|
||
return sortReserve;
|
||
}
|
||
|
||
/* -------------------------------------------- */
|
||
/** Returns a list of case inside a given distance
|
||
*
|
||
*/
|
||
static getTMRArea( coord, distance, tmrConstants ) {
|
||
let pos = this.convertToCellCoord( coord );
|
||
let posPic = this.computeRealPictureCoordinates( pos, tmrConstants );
|
||
let caseList = [];
|
||
for (let x=pos.x-distance; x<=pos.x+distance; x++ ) { // Loop thru lines
|
||
for (let y=pos.y-distance; y<=pos.y+distance; y++ ) { // Loop thru lines
|
||
//console.log("Parsing position", x, y);
|
||
if ( this._checkTMRCoord(x, y) ) { // Coordinate is valie
|
||
let posPicNow = this.computeRealPictureCoordinates( {x: x, y: y}, tmrConstants );
|
||
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) {
|
||
caseList.push( this.convertToTMRCoord(x, y) ); // Inside the area
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return caseList;
|
||
}
|
||
}
|
||
|