Ajout des commandes de creation de rencontre/NJ

This commit is contained in:
2026-04-17 16:34:16 +02:00
commit 90911c2e60
232 changed files with 53843 additions and 0 deletions

131
scripts/travellerMapApi.js Normal file
View File

@@ -0,0 +1,131 @@
/**
* MGT2 Commerce Client API Traveller Map
*
* Documentation : https://travellermap.com/doc/api
*
* Deux fonctions exportées :
* searchWorlds(query) → [{name, sector, hex, uwp, zone}]
* fetchWorldDetail(sector, hex) → {uwp, zone} (zone: 'normal'|'amber'|'red')
*/
const BASE_URL = 'https://travellermap.com';
/** Convertit la zone Traveller Map ('A', 'R', '') vers notre convention. */
function normalizeZone(z) {
if (z === 'A') return 'amber';
if (z === 'R') return 'red';
return 'normal';
}
/**
* Recherche des mondes par nom via l'API Traveller Map.
*
* @param {string} query Nom partiel ou complet (ex. "Regina")
* @returns {Promise<Array<{name:string, sector:string, hex:string, uwp:string}>>}
* Tableau de résultats (uniquement les mondes, pas secteurs/subsecteurs).
* Vide si erreur réseau.
*/
export async function searchWorlds(query) {
if (!query || query.trim().length < 2) return [];
const url = `${BASE_URL}/api/search?q=${encodeURIComponent(query.trim())}`;
let data;
try {
const resp = await fetch(url);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
data = await resp.json();
} catch (err) {
console.warn('MGT2 Commerce | Traveller Map search error:', err);
return [];
}
const items = data?.Results?.Items ?? [];
return items
.filter(item => item.World) // garder uniquement les mondes
.map(item => {
const w = item.World;
// Formatter le code hex sur 4 chiffres (HexX→XX, HexY→YY)
const hex = String(w.HexX).padStart(2, '0') + String(w.HexY).padStart(2, '0');
return {
name: w.Name,
sector: w.Sector,
hex,
uwp: w.Uwp ?? '',
};
});
}
/**
* Récupère les coordonnées absolues d'un monde en parsecs.
* Utilise l'endpoint /api/coordinates.
*
* @param {string} sector Nom du secteur (ex. "Spinward Marches")
* @param {string} hex Code hex 4 chiffres (ex. "1910")
* @returns {Promise<{x:number, y:number}|null>}
*/
export async function fetchWorldCoordinates(sector, hex) {
const url = `${BASE_URL}/api/coordinates?sector=${encodeURIComponent(sector)}&hex=${encodeURIComponent(hex)}`;
try {
const resp = await fetch(url);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
if (data?.x == null || data?.y == null) return null;
return { x: data.x, y: data.y };
} catch (err) {
console.warn('MGT2 Commerce | Traveller Map coordinates error:', err);
return null;
}
}
/**
* Calcule la distance en parsecs entre deux mondes à partir de leurs
* coordonnées absolues (retournées par fetchWorldCoordinates).
* Utilise la formule de distance en coordonnées cubiques pour grille hexagonale.
*
* Dans le système Traveller Map : les colonnes impaires (hx impair) sont
* décalées vers le bas. En coordonnées API, hx impair ↔ x pair.
* Conversion offset→cube : q=x, r=y⌈x/2⌉, s=qr.
* Distance = max(|Δq|, |Δr|, |Δs|).
*
* @param {{x:number,y:number}} c1
* @param {{x:number,y:number}} c2
* @returns {number} Distance en parsecs (entier, minimum 1)
*/
export function calcParsecs(c1, c2) {
const q1 = c1.x, r1 = c1.y - Math.ceil(c1.x / 2);
const q2 = c2.x, r2 = c2.y - Math.ceil(c2.x / 2);
const dq = q2 - q1, dr = r2 - r1, ds = -dq - dr;
return Math.max(1, Math.max(Math.abs(dq), Math.abs(dr), Math.abs(ds)));
}
/**
* Récupère les détails d'un monde pour obtenir la zone de voyage.
* Utilise l'endpoint /data/{sector}/{hex} (jump=0).
*
* @param {string} sector Nom du secteur (ex. "Spinward Marches")
* @param {string} hex Code hex 4 chiffres (ex. "1910")
* @returns {Promise<{uwp:string, zone:string}>}
*/
export async function fetchWorldDetail(sector, hex) {
const url = `${BASE_URL}/data/${encodeURIComponent(sector)}/${hex}`;
let data;
try {
const resp = await fetch(url);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
data = await resp.json();
} catch (err) {
console.warn('MGT2 Commerce | Traveller Map detail error:', err);
return null;
}
const world = data?.Worlds?.[0];
if (!world) return null;
return {
uwp: world.UWP ?? '',
zone: normalizeZone(world.Zone ?? ''),
};
}