2021-02-05 01:38:40 +01:00
|
|
|
|
import { Misc } from "./misc.js";
|
2021-05-04 12:22:19 +02:00
|
|
|
|
import { Grammar } from "./grammar.js";
|
2021-05-11 21:45:43 +02:00
|
|
|
|
import { RdDDice } from "./rdd-dice.js";
|
2020-11-16 04:31:53 +01:00
|
|
|
|
|
2024-11-28 00:38:34 +01:00
|
|
|
|
export const TMRType = {
|
|
|
|
|
cite: { type: 'cite', name: "cité", genre: "f" },
|
|
|
|
|
sanctuaire: { type: 'sanctuaire', name: "sanctuaire", genre: 'm' },
|
|
|
|
|
plaines: { type: 'plaines', name: "plaines", genre: "fp" },
|
|
|
|
|
pont: { type: 'pont', name: "pont", genre: "m" },
|
|
|
|
|
collines: { type: 'collines', name: "collines", genre: "p" },
|
|
|
|
|
foret: { type: 'foret', name: "forêt", genre: "f" },
|
|
|
|
|
monts: { type: 'monts', name: "monts", genre: "p" },
|
|
|
|
|
desert: { type: 'desert', name: "désert", genre: "m" },
|
|
|
|
|
fleuve: { type: 'fleuve', name: "fleuve", genre: "m" },
|
|
|
|
|
lac: { type: 'lac', name: "lac", genre: "m" },
|
|
|
|
|
marais: { type: 'marais', name: "marais", genre: "m" },
|
|
|
|
|
gouffre: { type: 'gouffre', name: "gouffre", genre: "m" },
|
|
|
|
|
necropole: { type: 'necropole', name: "nécropole", genre: "f" },
|
|
|
|
|
desolation: { type: 'desolation', name: "désolation", genre: "f" }
|
2021-02-06 21:53:25 +01:00
|
|
|
|
}
|
2020-07-21 23:51:24 +02:00
|
|
|
|
|
2024-11-28 00:38:34 +01:00
|
|
|
|
export const FLEUVE_COORD = 'Fleuve'
|
|
|
|
|
|
|
|
|
|
const TMRMapping = {
|
|
|
|
|
Fleuve: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
A1: { type: TMRType.cite.type, label: "Cité Vide" },
|
|
|
|
|
B1: { type: TMRType.plaines.type, label: "Plaines d’Assorh" },
|
|
|
|
|
C1: { type: TMRType.necropole.type, label: "Nécropole de Kroak" },
|
|
|
|
|
D1: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
E1: { type: TMRType.monts.type, label: "Monts de Kanaï" },
|
|
|
|
|
F1: { type: TMRType.cite.type, label: "Cité Glauque" },
|
|
|
|
|
G1: { type: TMRType.desolation.type, label: "Désolation de Jamais" },
|
|
|
|
|
H1: { type: TMRType.lac.type, label: "Lac d’Anticalme" },
|
|
|
|
|
I1: { type: TMRType.plaines.type, label: "Plaines Grises" },
|
|
|
|
|
J1: { type: TMRType.monts.type, label: "Monts Fainéants" },
|
|
|
|
|
K1: { type: TMRType.cite.type, label: "Cité d’Onkause" },
|
|
|
|
|
L1: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
M1: { type: TMRType.cite.type, label: "Cité Jalouse" },
|
|
|
|
|
A2: { type: TMRType.desert.type, label: "Désert de Mieux" },
|
|
|
|
|
B2: { type: TMRType.collines.type, label: "Collines de Dawell" },
|
|
|
|
|
C2: { type: TMRType.marais.type, label: "Marais Glignants" },
|
|
|
|
|
D2: { type: TMRType.cite.type, label: "Cité de Frost" },
|
|
|
|
|
E2: { type: TMRType.plaines.type, label: "Plaines de Fiask" },
|
|
|
|
|
F2: { type: TMRType.lac.type, label: "Lac de Misère" },
|
|
|
|
|
G2: { type: TMRType.marais.type, label: "Marais Nuisants" },
|
|
|
|
|
H2: { type: TMRType.collines.type, label: "Collines de Parta" },
|
|
|
|
|
I2: { type: TMRType.foret.type, label: "Forêt Fade" },
|
|
|
|
|
J2: { type: TMRType.desert.type, label: "Désert de Poly" },
|
|
|
|
|
K2: { type: TMRType.foret.type, label: "Forêt Tamée" },
|
|
|
|
|
L2: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
M2: { type: TMRType.necropole.type, label: "Nécropole de Logos" },
|
|
|
|
|
A3: { type: TMRType.desolation.type, label: "Désolation de Demain" },
|
|
|
|
|
B3: { type: TMRType.plaines.type, label: "Plaines de Rubéga" },
|
|
|
|
|
C3: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
D3: { type: TMRType.gouffre.type, label: "Gouffre d’Oki" },
|
|
|
|
|
E3: { type: TMRType.foret.type, label: "Forêt d’Estoubh" },
|
|
|
|
|
F3: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
G3: { type: TMRType.gouffre.type, label: "Gouffre de Sun" },
|
|
|
|
|
H3: { type: TMRType.foret.type, label: "Forêt de Ganna" },
|
|
|
|
|
I3: { type: TMRType.monts.type, label: "Monts Grinçants" },
|
|
|
|
|
J3: { type: TMRType.cite.type, label: "Cité Venin" },
|
|
|
|
|
K3: { type: TMRType.plaines.type, label: "Plaines de Dois" },
|
|
|
|
|
L3: { type: TMRType.lac.type, label: "Lac Laineux" },
|
|
|
|
|
M3: { type: TMRType.monts.type, label: "Monts de Vdah" },
|
|
|
|
|
A4: { type: TMRType.foret.type, label: "Forêt de Falconax" },
|
|
|
|
|
B4: { type: TMRType.monts.type, label: "Monts Crâneurs" },
|
|
|
|
|
C4: { type: TMRType.pont.type, label: "Pont de Giolii" },
|
|
|
|
|
D4: { type: TMRType.lac.type, label: "Lac de Foam" },
|
|
|
|
|
E4: { type: TMRType.plaines.type, label: "Plaines d’Orti" },
|
|
|
|
|
F4: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
G4: { type: TMRType.sanctuaire.type, label: "Sanctuaire Blanc" },
|
|
|
|
|
H4: { type: TMRType.plaines.type, label: "Plaines de Psark" },
|
|
|
|
|
I4: { type: TMRType.plaines.type, label: "Plaines de Xiax" },
|
|
|
|
|
J4: { type: TMRType.collines.type, label: "Collines d’Encre" },
|
|
|
|
|
K4: { type: TMRType.pont.type, label: "Pont de Fah" },
|
|
|
|
|
L4: { type: TMRType.sanctuaire.type, label: "Sanctuaire Mauve" },
|
|
|
|
|
M4: { type: TMRType.gouffre.type, label: "Gouffre Grisant" },
|
|
|
|
|
A5: { type: TMRType.plaines.type, label: "Plaines de Trilkh" },
|
|
|
|
|
B5: { type: TMRType.collines.type, label: "Collines de Tanegy" },
|
|
|
|
|
C5: { type: TMRType.marais.type, label: "Marais Flouants" },
|
|
|
|
|
D5: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
E5: { type: TMRType.monts.type, label: "Monts Brûlants" },
|
|
|
|
|
F5: { type: TMRType.cite.type, label: "Cité de Panople" },
|
|
|
|
|
G5: { type: TMRType.pont.type, label: "Pont d’Ik" },
|
|
|
|
|
H5: { type: TMRType.desert.type, label: "Désert de Krane" },
|
|
|
|
|
I5: { type: TMRType.desolation.type, label: "Désolation de Toujours" },
|
|
|
|
|
J5: { type: TMRType.marais.type, label: "Marais de Jab" },
|
|
|
|
|
K5: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
L5: { type: TMRType.collines.type, label: "Collines Suaves" },
|
|
|
|
|
M5: { type: TMRType.cite.type, label: "Cité Rimarde" },
|
|
|
|
|
A6: { type: TMRType.necropole.type, label: "Nécropole de Zniak" },
|
|
|
|
|
B6: { type: TMRType.foret.type, label: "Forêt de Bust" },
|
|
|
|
|
C6: { type: TMRType.cite.type, label: "Cité Pavois" },
|
|
|
|
|
D6: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
E6: { type: TMRType.sanctuaire.type, label: "Sanctuaire de Plaine" },
|
|
|
|
|
F6: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
G6: { type: TMRType.marais.type, label: "Marais Glutants" },
|
|
|
|
|
H6: { type: TMRType.monts.type, label: "Monts Gurdes" },
|
|
|
|
|
I6: { type: TMRType.necropole.type, label: "Nécropole de Xotar" },
|
|
|
|
|
J6: { type: TMRType.lac.type, label: "Lac d’Iaupe" },
|
|
|
|
|
K6: { type: TMRType.desolation.type, label: "Désolation de Poor" },
|
|
|
|
|
L6: { type: TMRType.foret.type, label: "Forêt Gueuse" },
|
|
|
|
|
M6: { type: TMRType.desolation.type, label: "Désolation de Presque" },
|
|
|
|
|
A7: { type: TMRType.plaines.type, label: "Plaines de l’Arc" },
|
|
|
|
|
B7: { type: TMRType.marais.type, label: "Marais Bluants" },
|
|
|
|
|
C7: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
D7: { type: TMRType.plaines.type, label: "Plaines d’Affa" },
|
|
|
|
|
E7: { type: TMRType.foret.type, label: "Forêt de Glusks" },
|
|
|
|
|
F7: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
G7: { type: TMRType.cite.type, label: "Cité de Terwa" },
|
|
|
|
|
H7: { type: TMRType.gouffre.type, label: "Gouffre de Kapfa" },
|
|
|
|
|
I7: { type: TMRType.plaines.type, label: "Plaines de Troo" },
|
|
|
|
|
J7: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
K7: { type: TMRType.cite.type, label: "Cité de Kolix" },
|
|
|
|
|
L7: { type: TMRType.gouffre.type, label: "Gouffre d’Episophe" },
|
|
|
|
|
M7: { type: TMRType.desert.type, label: "Désert de Lave" },
|
|
|
|
|
A8: { type: TMRType.gouffre.type, label: "Gouffre de Shok" },
|
|
|
|
|
B8: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
C8: { type: TMRType.foret.type, label: "Forêt Turmide" },
|
|
|
|
|
D8: { type: TMRType.cite.type, label: "Cité d’Olak" },
|
|
|
|
|
E8: { type: TMRType.plaines.type, label: "Plaines d’Iolise" },
|
|
|
|
|
F8: { type: TMRType.lac.type, label: "Lac des Chats" },
|
|
|
|
|
G8: { type: TMRType.plaines.type, label: "Plaines Sans Joie" },
|
|
|
|
|
H8: { type: TMRType.foret.type, label: "Forêt d’Ourf" },
|
|
|
|
|
I8: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
J8: { type: TMRType.monts.type, label: "Monts Barask" },
|
|
|
|
|
K8: { type: TMRType.desert.type, label: "Désert de Fumée" },
|
|
|
|
|
L8: { type: TMRType.monts.type, label: "Monts Tavelés" },
|
|
|
|
|
M8: { type: TMRType.plaines.type, label: "Plaines Lavées" },
|
|
|
|
|
A9: { type: TMRType.collines.type, label: "Collines de Korrex" },
|
|
|
|
|
B9: { type: TMRType.lac.type, label: "Lac de Lucre" },
|
|
|
|
|
C9: { type: TMRType.monts.type, label: "Monts Tuméfiés" },
|
|
|
|
|
D9: { type: TMRType.pont.type, label: "Pont d’Orx" },
|
|
|
|
|
E9: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
F9: { type: TMRType.plaines.type, label: "Plaines de Foe" },
|
|
|
|
|
G9: { type: TMRType.desolation.type, label: "Désolation de Sel" },
|
|
|
|
|
H9: { type: TMRType.collines.type, label: "Collines de Noirseul" },
|
|
|
|
|
I9: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
J9: { type: TMRType.marais.type, label: "Marais Gronchants" },
|
|
|
|
|
K9: { type: TMRType.sanctuaire.type, label: "Sanctuaire Noir" },
|
|
|
|
|
L9: { type: TMRType.collines.type, label: "Collines Cornues" },
|
|
|
|
|
M9: { type: TMRType.necropole.type, label: "Nécropole de Zonar" },
|
|
|
|
|
A10: { type: TMRType.sanctuaire.type, label: "Sanctuaire d’Olis" },
|
|
|
|
|
B10: { type: TMRType.monts.type, label: "Monts Salés" },
|
|
|
|
|
C10: { type: TMRType.marais.type, label: "Marais de Dom" },
|
|
|
|
|
D10: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
E10: { type: TMRType.gouffre.type, label: "Gouffre de Junk" },
|
|
|
|
|
F10: { type: TMRType.marais.type, label: "Marais Zultants" },
|
|
|
|
|
G10: { type: TMRType.cite.type, label: "Cité de Sergal" },
|
|
|
|
|
H10: { type: TMRType.plaines.type, label: "Plaines Noires" },
|
|
|
|
|
I10: { type: TMRType.lac.type, label: "Lac Wanito" },
|
|
|
|
|
J10: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
K10: { type: TMRType.plaines.type, label: "Plaines Jaunes" },
|
|
|
|
|
L10: { type: TMRType.desert.type, label: "Désert de Nicrop" },
|
|
|
|
|
M10: { type: TMRType.foret.type, label: "Forêt de Jajou" },
|
|
|
|
|
A11: { type: TMRType.desolation.type, label: "Désolation d’Hier" },
|
|
|
|
|
B11: { type: TMRType.cite.type, label: "Cité de Brilz" },
|
|
|
|
|
C11: { type: TMRType.pont.type, label: "Pont de Roï" },
|
|
|
|
|
D11: { type: TMRType.desolation.type, label: "Désolation de Partout" },
|
|
|
|
|
E11: { type: TMRType.lac.type, label: "Lac de Glinster" },
|
|
|
|
|
F11: { type: TMRType.cite.type, label: "Cité de Noape" },
|
|
|
|
|
G11: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
H11: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
I11: { type: TMRType.pont.type, label: "Pont de Yalm" },
|
|
|
|
|
J11: { type: TMRType.plaines.type, label: "Plaines de Miltiar" },
|
|
|
|
|
K11: { type: TMRType.cite.type, label: "Cité Tonnerre" },
|
|
|
|
|
L11: { type: TMRType.collines.type, label: "Collines de Kol" },
|
|
|
|
|
M11: { type: TMRType.cite.type, label: "Cité Crapaud" },
|
|
|
|
|
A12: { type: TMRType.plaines.type, label: "Plaines Sages" },
|
|
|
|
|
B12: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
C12: { type: TMRType.lac.type, label: "Lac de Fricassa" },
|
|
|
|
|
D12: { type: TMRType.collines.type, label: "Collines d’Huaï" },
|
|
|
|
|
E12: { type: TMRType.monts.type, label: "Monts Ajourés" },
|
|
|
|
|
F12: { type: TMRType.necropole.type, label: "Nécropole de Throat" },
|
|
|
|
|
G12: { type: TMRType.plaines.type, label: "Plaines de Lufmil" },
|
|
|
|
|
H12: { type: TMRType.collines.type, label: "Collines de Tooth" },
|
|
|
|
|
I12: { type: TMRType.gouffre.type, label: "Gouffre Abimeux" },
|
|
|
|
|
J12: { type: TMRType.cite.type, label: "Cité Folle" },
|
|
|
|
|
K12: { type: TMRType.desolation.type, label: "Désolation d’Amour" },
|
|
|
|
|
L12: { type: TMRType.plaines.type, label: "Plaines Venteuses" },
|
|
|
|
|
M12: { type: TMRType.collines.type, label: "Collines Révulsantes" },
|
|
|
|
|
A13: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" },
|
|
|
|
|
B13: { type: TMRType.gouffre.type, label: "Gouffre des Litiges" },
|
|
|
|
|
C13: { type: TMRType.desert.type, label: "Désert de Neige" },
|
|
|
|
|
D13: { type: TMRType.cite.type, label: "Cité Sordide" },
|
|
|
|
|
E13: { type: TMRType.plaines.type, label: "Plaines de Xnez" },
|
|
|
|
|
F13: { type: TMRType.foret.type, label: "Forêt des Cris" },
|
|
|
|
|
G13: { type: TMRType.plaines.type, label: "Plaines Calcaires" },
|
|
|
|
|
H13: { type: TMRType.desolation.type, label: "Désolation de Rien" },
|
|
|
|
|
I13: { type: TMRType.monts.type, label: "Monts Bigleux" },
|
|
|
|
|
J13: { type: TMRType.gouffre.type, label: "Gouffre de Gromph" },
|
|
|
|
|
K13: { type: TMRType.foret.type, label: "Forêt de Kluth" },
|
|
|
|
|
L13: { type: TMRType.monts.type, label: "Monts Dormants" },
|
|
|
|
|
M13: { type: TMRType.plaines.type, label: "Plaines d’Anjou" },
|
|
|
|
|
A14: { type: TMRType.collines.type, label: "Collines de Stolis" },
|
|
|
|
|
B14: { type: TMRType.necropole.type, label: "Nécropole de Gorlo" },
|
|
|
|
|
C14: { type: TMRType.foret.type, label: "Forêt de Bissam" },
|
|
|
|
|
D14: { type: TMRType.sanctuaire.type, label: "Sanctuaire Plat" },
|
|
|
|
|
E14: { type: TMRType.monts.type, label: "Monts de Quath" },
|
|
|
|
|
F14: { type: TMRType.plaines.type, label: "Plaines Brisées" },
|
|
|
|
|
G14: { type: TMRType.desert.type, label: "Désert de Sek" },
|
|
|
|
|
H14: { type: TMRType.plaines.type, label: "Plaines Blanches" },
|
|
|
|
|
I14: { type: TMRType.cite.type, label: "Cité Destituée" },
|
|
|
|
|
J14: { type: TMRType.desert.type, label: "Désert de Sank" },
|
|
|
|
|
K14: { type: TMRType.necropole.type, label: "Nécropole d’Antinéar" },
|
|
|
|
|
L14: { type: TMRType.plaines.type, label: "Plaines de Jislith" },
|
|
|
|
|
M14: { type: TMRType.desolation.type, label: "Désolation d’Après" },
|
|
|
|
|
A15: { type: TMRType.cite.type, label: "Cité de Mielh" },
|
|
|
|
|
C15: { type: TMRType.plaines.type, label: "Plaines de Toué" },
|
|
|
|
|
E15: { type: TMRType.foret.type, label: "Forêt des Furies" },
|
|
|
|
|
G15: { type: TMRType.plaines.type, label: "Plaines des Soupirs" },
|
|
|
|
|
I15: { type: TMRType.monts.type, label: "Monts des Dragées" },
|
|
|
|
|
K15: { type: TMRType.collines.type, label: "Collines Pourpres" },
|
|
|
|
|
M15: { type: TMRType.cite.type, label: "Cité de Klana" }
|
2021-01-29 15:13:59 +01:00
|
|
|
|
}
|
2020-07-17 22:04:35 +02:00
|
|
|
|
|
2020-11-21 14:30:00 +01:00
|
|
|
|
/* -------------------------------------------- */
|
2023-11-15 22:11:44 +01:00
|
|
|
|
const TMR_MOVE = {
|
|
|
|
|
"top": { even: { row: -1, col: 0 }, odd: { row: -1, col: 0 }, },
|
|
|
|
|
"topleft": { even: { row: -1, col: -1 }, odd: { row: 0, col: -1 }, },
|
|
|
|
|
"topright": { even: { row: -1, col: 1 }, odd: { row: 0, col: 1 }, },
|
|
|
|
|
"bottomleft": { even: { row: 0, col: -1 }, odd: { row: 1, col: -1 }, },
|
|
|
|
|
"bottomright": { even: { row: 0, col: 1 }, odd: { row: 1, col: 1 }, },
|
|
|
|
|
"bottom": { even: { row: 1, col: 0 }, odd: { row: 1, col: 0 }, },
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-15 22:14:00 +01:00
|
|
|
|
/* --------------------------------------------
|
|
|
|
|
* Pour comprendre les conversions entre coordonnées
|
|
|
|
|
* - "TMR" A1, ... M15
|
|
|
|
|
* - oddq: {col, row}
|
|
|
|
|
* - axial: { q, r )
|
|
|
|
|
*
|
|
|
|
|
* Un site intéressant: https://www.redblobgames.com/grids/hexagons/#distances
|
|
|
|
|
*
|
|
|
|
|
* Pour être concis, le code TMR lettre(colonne)-ligne correspond à une grille hexagonale en coordonnées "odd-q"
|
|
|
|
|
* (lettre => col, ligne => row).
|
|
|
|
|
*
|
|
|
|
|
* Pour les calculs de distance, les coordonnées axiales sont beaucoup plus pratiques.
|
|
|
|
|
*/
|
2021-02-06 21:53:25 +01:00
|
|
|
|
export class TMRUtility {
|
2021-01-29 15:13:59 +01:00
|
|
|
|
static init() {
|
2024-11-28 00:38:34 +01:00
|
|
|
|
|
2021-01-29 15:13:59 +01:00
|
|
|
|
for (let coord in TMRMapping) {
|
2024-11-28 00:38:34 +01:00
|
|
|
|
const tmr = TMRMapping[coord]
|
|
|
|
|
tmr.coord = coord
|
|
|
|
|
tmr.genre = TMRType[tmr.type].genre
|
|
|
|
|
if (coord != FLEUVE_COORD) {
|
|
|
|
|
tmr.oddq = TMRUtility.coordTMRToOddq(coord)
|
|
|
|
|
}
|
2021-01-29 15:13:59 +01:00
|
|
|
|
}
|
2024-11-28 00:38:34 +01:00
|
|
|
|
let tmrByType = Misc.classify(Object.values(TMRMapping).filter(it => it.coord != FLEUVE_COORD))
|
2021-02-05 01:38:40 +01:00
|
|
|
|
for (const [type, list] of Object.entries(tmrByType)) {
|
|
|
|
|
TMRType[type].list = list;
|
|
|
|
|
}
|
2021-01-29 15:13:59 +01:00
|
|
|
|
}
|
2020-12-04 20:52:04 +01:00
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
2021-02-06 21:53:25 +01:00
|
|
|
|
static verifyTMRCoord(coord) {
|
2024-11-28 00:38:34 +01:00
|
|
|
|
return Grammar.equalsInsensitive(coord, FLEUVE_COORD) || TMRUtility.getTMR(coord);
|
2021-02-06 21:53:25 +01:00
|
|
|
|
}
|
2020-12-04 20:52:04 +01:00
|
|
|
|
|
2020-07-17 22:04:35 +02:00
|
|
|
|
/* -------------------------------------------- */
|
2021-02-12 01:11:03 +01:00
|
|
|
|
static getTMR(coord) {
|
2024-11-28 00:38:34 +01:00
|
|
|
|
return coord == FLEUVE_COORD ? TMRMapping['D1'] : TMRMapping[coord];
|
2020-07-17 22:04:35 +02:00
|
|
|
|
}
|
2021-02-12 01:11:03 +01:00
|
|
|
|
|
2024-11-28 00:38:34 +01:00
|
|
|
|
static isFleuve(coord) {
|
|
|
|
|
return TMRMapping[coord]?.type == TMRType.fleuve.type
|
|
|
|
|
}
|
2021-02-12 01:11:03 +01:00
|
|
|
|
static getTMRLabel(coord) {
|
2023-03-30 01:31:41 +02:00
|
|
|
|
return TMRUtility.getTMR(coord)?.label ?? (coord + ": case inconnue");
|
2021-02-28 01:56:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-28 00:48:39 +02:00
|
|
|
|
static getTMRType(coord) {
|
2023-03-30 01:31:41 +02:00
|
|
|
|
const tmr = TMRUtility.getTMR(coord);
|
2021-05-11 21:21:33 +02:00
|
|
|
|
return Misc.upperFirst(TMRType[tmr.type].name);
|
2021-04-28 00:48:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-28 01:56:17 +01:00
|
|
|
|
static getTMRDescr(coord) {
|
2023-03-30 01:31:41 +02:00
|
|
|
|
const tmr = TMRUtility.getTMR(coord);
|
2021-04-28 00:48:39 +02:00
|
|
|
|
return Grammar.articleDetermine(tmr.type) + ' ' + tmr.label;
|
2021-02-12 01:11:03 +01:00
|
|
|
|
}
|
2023-10-20 22:18:37 +02:00
|
|
|
|
|
|
|
|
|
static findTMRLike(type, options = { inclusMauvaise: true }) {
|
2022-11-17 01:22:45 +01:00
|
|
|
|
const choix = [...Object.values(TMRType)]
|
2023-10-20 22:18:37 +02:00
|
|
|
|
if (options.inclusMauvaise) {
|
|
|
|
|
choix.push({ name: 'Mauvaise' });
|
2022-11-17 01:22:45 +01:00
|
|
|
|
}
|
|
|
|
|
const selection = Misc.findAllLike(type, choix).map(it => it.name);
|
|
|
|
|
if (selection.length == 0) {
|
|
|
|
|
ui.notifications.warn(`Un type de TMR doit être indiqué, '${type}' n'est pas trouvé dans ${choix}`);
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
if (selection.length > 1) {
|
|
|
|
|
ui.notifications.warn(`Plusieurs types de TMR pourraient correspondre à '${type}': ${selection}`);
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
return selection[0];
|
|
|
|
|
}
|
2021-02-12 01:11:03 +01:00
|
|
|
|
|
2021-11-26 23:29:06 +01:00
|
|
|
|
static typeTmrName(type) {
|
2021-05-18 19:51:12 +02:00
|
|
|
|
return Misc.upperFirst(TMRType[Grammar.toLowerCaseNoAccent(type)].name);
|
|
|
|
|
}
|
2022-11-17 01:18:06 +01:00
|
|
|
|
|
2022-09-24 00:31:51 +02:00
|
|
|
|
static buildSelectionTypesTMR(typesTMR) {
|
2023-10-20 22:18:37 +02:00
|
|
|
|
typesTMR = typesTMR ?? [];
|
2021-05-11 00:52:25 +02:00
|
|
|
|
return Object.values(TMRType).map(value => Misc.upperFirst(value.name))
|
|
|
|
|
.sort()
|
|
|
|
|
.map(name => { return { name: name, selected: typesTMR.includes(name) } });
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-24 00:31:51 +02:00
|
|
|
|
static buildListTypesTMRSelection(selectionTMRs) {
|
|
|
|
|
return selectionTMRs.filter(it => it.selected).map(it => it.name).join(" ");
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-11 02:48:27 +01:00
|
|
|
|
static isCaseHumide(tmr) {
|
|
|
|
|
return tmr.type == 'fleuve' || tmr.type == 'lac' || tmr.type == 'marais';
|
|
|
|
|
}
|
2021-02-06 21:53:25 +01:00
|
|
|
|
|
2020-11-20 16:45:20 +01:00
|
|
|
|
/* -------------------------------------------- */
|
2023-11-15 22:11:44 +01:00
|
|
|
|
static deplacement(coordOrig, moveName) {
|
|
|
|
|
const tmrMove = TMR_MOVE[moveName];
|
|
|
|
|
if (! tmrMove) {
|
|
|
|
|
ui.notifications.error(`Le déplacement dans les TMR '${moveName}' est inconnu`)
|
|
|
|
|
return coordOrig
|
|
|
|
|
}
|
|
|
|
|
const fromOddq = TMRUtility.coordTMRToOddq(coordOrig);
|
|
|
|
|
const move = TMRUtility.getOddqMove(tmrMove, fromOddq);
|
|
|
|
|
const toOddq = TMRUtility.addOddq(fromOddq, move);
|
|
|
|
|
return TMRUtility.oddqToCoordTMR(toOddq);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static getOddqMove(tmrMove, oddq) {
|
|
|
|
|
return oddq.col % 2 == 1 ? tmrMove.odd : tmrMove.even;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static async getDirectionPattern(oddq) {
|
|
|
|
|
const tmrMove = await RdDDice.rollOneOf(Object.values(TMR_MOVE));
|
|
|
|
|
return TMRUtility.getOddqMove(tmrMove, oddq);
|
2020-11-21 14:30:00 +01:00
|
|
|
|
}
|
2021-01-29 15:13:59 +01:00
|
|
|
|
|
2021-04-25 10:08:40 +02:00
|
|
|
|
/* -------------------------------------------- */
|
2021-05-11 21:45:43 +02:00
|
|
|
|
static async deplaceTMRAleatoire(actor, coord) {
|
2023-11-15 22:11:44 +01:00
|
|
|
|
const oddq = TMRUtility.coordTMRToOddq(coord);
|
|
|
|
|
const direction = await TMRUtility.getDirectionPattern(oddq);
|
|
|
|
|
const currentOddq = TMRUtility.addOddq(oddq, direction)
|
2023-11-15 22:14:00 +01:00
|
|
|
|
if (TMRUtility.isOddqInTMR(currentOddq)) { // Sortie de carte ! Ré-insertion aléatoire
|
2022-11-07 00:04:43 +01:00
|
|
|
|
return TMRUtility.getTMR(TMRUtility.oddqToCoordTMR(currentOddq));
|
|
|
|
|
} else {
|
|
|
|
|
return await actor.reinsertionAleatoire('Sortie de carte');
|
2020-11-21 18:16:18 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-17 16:30:03 +01:00
|
|
|
|
/* -------------------------------------------- */
|
2021-01-29 15:13:59 +01:00
|
|
|
|
static getListTMR(terrain) {
|
2021-02-05 01:38:40 +01:00
|
|
|
|
return TMRType[terrain].list;
|
2020-11-16 04:31:53 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-11 02:48:27 +01:00
|
|
|
|
static filterTMR(filter) {
|
|
|
|
|
return Object.values(TMRMapping).filter(filter);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-07 00:04:43 +01:00
|
|
|
|
static getCasesType(type) {
|
|
|
|
|
return TMRUtility.filterTMR(it => it.type == type).map(it => it.coord);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-26 23:29:06 +01:00
|
|
|
|
static findTMR(search) {
|
2022-11-17 01:57:36 +01:00
|
|
|
|
return TMRUtility.filterTMR(it => Grammar.includesLowerCaseNoAccent(it.label, search) || it.coord == search);
|
2021-11-26 23:29:06 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-11 02:48:27 +01:00
|
|
|
|
static filterTMRCoord(filter) {
|
|
|
|
|
return TMRUtility.filterTMR(filter).map(it => it.coord);
|
2020-07-17 22:04:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-11 21:45:43 +02:00
|
|
|
|
static async getTMRAleatoire(filter = it => true) {
|
|
|
|
|
return await RdDDice.rollOneOf(TMRUtility.filterTMR(filter))
|
2020-09-13 23:08:52 +02:00
|
|
|
|
}
|
2020-11-18 23:49:05 +01:00
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
/** Returns a list of case inside a given distance
|
|
|
|
|
*
|
|
|
|
|
*/
|
2021-02-12 01:11:03 +01:00
|
|
|
|
static getTMRPortee(coord, portee) {
|
2023-11-15 22:14:00 +01:00
|
|
|
|
let centerOddq = TMRUtility.coordTMRToOddq(coord);
|
2020-11-18 23:49:05 +01:00
|
|
|
|
let caseList = [];
|
2021-12-12 17:36:22 +01:00
|
|
|
|
for (let dcol = -portee; dcol <= portee; dcol++) { // rows
|
|
|
|
|
for (let drow = -portee; drow <= portee; drow++) { // columns
|
|
|
|
|
const currentOddq = { col: centerOddq.col + dcol, row: centerOddq.row + drow };
|
2023-11-15 22:14:00 +01:00
|
|
|
|
if (TMRUtility.isOddqInTMR(currentOddq)) {
|
|
|
|
|
let dist = TMRUtility.distanceOddq(centerOddq, currentOddq);
|
2021-02-28 01:56:17 +01:00
|
|
|
|
if (dist <= portee) {
|
2023-11-15 22:14:00 +01:00
|
|
|
|
caseList.push(TMRUtility.oddqToCoordTMR(currentOddq)); // Inside the area
|
2020-11-18 23:49:05 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return caseList;
|
|
|
|
|
}
|
2021-02-28 01:56:17 +01:00
|
|
|
|
|
2021-12-12 17:36:22 +01:00
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
static coordTMRToOddq(coordTMR) {
|
|
|
|
|
let col = coordTMR.charCodeAt(0) - 65;
|
|
|
|
|
let row = coordTMR.substr(1) - 1;
|
|
|
|
|
return { col: col, row: row }
|
2021-02-28 01:56:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-25 10:08:40 +02:00
|
|
|
|
/* -------------------------------------------- */
|
2021-12-12 17:36:22 +01:00
|
|
|
|
static oddqToCoordTMR(oddq) {
|
|
|
|
|
let letterX = String.fromCharCode(65 + (oddq.col));
|
|
|
|
|
return letterX + (oddq.row + 1)
|
2021-02-28 01:56:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-12 17:36:22 +01:00
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
static isOddqInTMR(oddq) {
|
|
|
|
|
const col = oddq.col;
|
|
|
|
|
const row = oddq.row;
|
|
|
|
|
return (
|
|
|
|
|
col >= 0 && col < 13 &&
|
|
|
|
|
row >= 0 &&
|
|
|
|
|
(row + col % 2 <= 14)
|
2023-10-20 22:18:37 +02:00
|
|
|
|
);
|
2021-12-12 17:36:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
static distanceCoordTMR(coord1, coord2) {
|
2023-11-15 22:14:00 +01:00
|
|
|
|
let oddq1 = TMRUtility.coordTMRToOddq(coord1);
|
|
|
|
|
let oddq2 = TMRUtility.coordTMRToOddq(coord2);
|
|
|
|
|
return TMRUtility.distanceOddq(oddq1, oddq2);
|
2021-12-12 17:36:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
static distanceOddq(oddq1, oddq2) {
|
|
|
|
|
const axial1 = TMRUtility.oddqToAxial(oddq1);
|
|
|
|
|
const axial2 = TMRUtility.oddqToAxial(oddq2);
|
|
|
|
|
return TMRUtility.distanceAxial(axial1, axial2);
|
2023-11-15 22:11:44 +01:00
|
|
|
|
}
|
2021-12-12 17:36:22 +01:00
|
|
|
|
|
2023-11-15 22:11:44 +01:00
|
|
|
|
static addOddq(move, oddq) {
|
|
|
|
|
return {
|
|
|
|
|
row: oddq.row + move.row,
|
|
|
|
|
col: oddq.col + move.col
|
|
|
|
|
}
|
2021-12-12 17:36:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static oddqToAxial(pos) {
|
|
|
|
|
return {
|
|
|
|
|
q: pos.col,
|
|
|
|
|
r: pos.row - (pos.col - (pos.col & 1)) / 2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static distanceAxial(a, b) {
|
|
|
|
|
const vector = TMRUtility.axial_subtract(a, b)
|
|
|
|
|
return (Math.abs(vector.q)
|
|
|
|
|
+ Math.abs(vector.q + vector.r)
|
|
|
|
|
+ Math.abs(vector.r)) / 2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static axial_subtract(a, b) {
|
|
|
|
|
return {
|
2023-10-20 22:18:37 +02:00
|
|
|
|
q: a.q - b.q,
|
2021-12-12 17:36:22 +01:00
|
|
|
|
r: a.r - b.r
|
|
|
|
|
};
|
|
|
|
|
}
|
2020-07-17 22:04:35 +02:00
|
|
|
|
|
2021-12-12 17:36:22 +01:00
|
|
|
|
}
|