import { DeDraconique } from "./de-draconique.js"; import { TMRRencontres } from "./tmr-rencontres.js"; import { Grammar } from "./grammar.js"; import { Misc } from "./misc.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"} } export const TMRType = { cite: {name:"cité"}, sanctuaire: {name:"sanctuaire"}, plaines: {name:"plaines"}, pont: {name:"pont"}, collines: {name:"collines"}, foret: {name:"forêt"}, monts: {name:"monts"}, desert: {name:"désert"}, fleuve: {name:"fleuve"}, lac: {name:"lac"}, marais: {name:"marais"}, gouffre: {name:"gouffre"}, necropole: {name:"nécropole"}, desolation: {name:"désolation"} } /* -------------------------------------------- */ const caseSpecificModes = [ "attache", "trounoir", "debordement", "reserve_extensible", "maitrisee" ]; /* -------------------------------------------- */ const tmrRandomMovePatten = [ { name: 'top', x: 0, y: -1 }, { name: 'topright', x: 1, y: -1 }, { name: 'botright', x: 1, y: 1 }, { name: 'bot', x: 0, y: 1 }, { name: 'botleft', x: -1, y: 1 }, { name: 'topleft', x: -1, y: -1 } ] /* -------------------------------------------- */ export const tmrConstants = { col1_y: 30, col2_y: 55, cellw: 55, cellh: 55, gridx: 28, gridy: 28 } /* -------------------------------------------- */ /* -------------------------------------------- */ export class TMRUtility { static init() { for (let coord in TMRMapping) { 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( pos ) { let letterX = String.fromCharCode(65+ (pos.x)); return letterX + (pos.y +1) } /* -------------------------------------------- */ 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 convertToCellPos( coordTMR ) { let x = coordTMR.charCodeAt(0) - 65; let y = coordTMR.substr(1) - 1; return {x: x, y: y} } /* -------------------------------------------- */ static getTMR( coordTMR) { return TMRMapping[coordTMR]; } /* -------------------------------------------- */ /** Some debug functions */ static async setForceRencontre( index, force = undefined ) { this.prochaineRencontre = TMRRencontres.getRencontre( index ); if (this.prochaineRencontre ) { if (force) { this.prochaineRencontre.force = force; } else{ await TMRRencontres.evaluerForceRencontre(this.prochaineRencontre) } console.log("La prochaine rencontre sera:", this.prochaineRencontre.name, " force:", this.prochaineRencontre.force); } else { ui.notifications.warn("Pas de prochaine rencontre valide pour "+index); } } /* -------------------------------------------- */ static isForceRencontre() { return this.prochaineRencontre } /* -------------------------------------------- */ static getDirectionPattern() { let roll = new Roll("1d"+tmrRandomMovePatten.length).evaluate().total; return tmrRandomMovePatten[roll -1]; } static deplaceTMRAleatoire(coord) { return TMRUtility.deplaceTMRSelonPattern(coord, TMRUtility.getDirectionPattern(), 1); } /* -------------------------------------------- */ static deplaceTMRSelonPattern( coord, direction, nTime ) { for (let i=0; i it.coord); } static getTMRAleatoire(terrain = undefined) { let list = terrain ? TMRUtility.getListTMR(terrain) : Object.values(TMRMapping); let index = new Roll("1d" + list.length).evaluate().total - 1; return list[index]; } /* -------------------------------------------- */ static _checkTMRCoord( x, y ) { if (x >= 0 && x < 13 && y >= 0 && y < 14 ) return true; if (x >= 0 && x < 13 && x%2 == 0 && y == 14 ) 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 getSortReserveList( reserveList, coordTMR ) { // TODO : Gérer les têtes spéciales réserve! let sortReserveList let tmrDescr = this.getTMR(coordTMR); //console.log("Sort réserve : ", tmrDescr); if ( tmrDescr.type == 'fleuve') { // Gestion de la reserve en Fleuve sortReserveList = reserveList.filter(it => TMRUtility.getTMR(it.coord).type == 'fleuve' ); } else { // Reserve sur un case "normale" sortReserveList = reserveList.filter(it => it.coord == coordTMR); } //console.log("Sort réserve : ", tmrDescr, sortReserve, reserveList); return sortReserveList; } /* -------------------------------------------- */ /** Returns a list of case inside a given distance * */ static getTMRPortee(centerCoord, portee) { return TMRUtility.getTMRArea(centerCoord, portee, tmrConstants); } static getTMRArea( centerCoord, distance, tmrConstants ) { let centerPos = this.convertToCellPos( centerCoord ); let posPic = this.computeRealPictureCoordinates( centerPos, tmrConstants ); let caseList = []; for (let dx=-distance; dx<=distance; dx++ ) { // Loop thru lines for (let dy=-distance; dy<=distance; dy++ ) { // Loop thru lines const currentPos = { x: centerPos.x+dx, y: centerPos.y+dy }; if ( this._checkTMRCoord(currentPos.x, currentPos.y) ) { // Coordinate is valie 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; if ( dist < distance+0.5) { caseList.push( this.convertToTMRCoord(currentPos) ); // Inside the area } } } } return caseList; } }