From 91cbb6c841ad7a08a1fedc64aabacb18d829e7de Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Sat, 9 Aug 2025 21:17:23 +0200 Subject: [PATCH] feat(app): add location read scope and update map angle calculations --- app.go | 13 +++++++----- frontend/src/components/RegionMap.tsx | 30 ++++++++++++++------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/app.go b/app.go index ee9c8d8..3ad6bd8 100644 --- a/app.go +++ b/app.go @@ -35,7 +35,8 @@ func (a *App) startup(ctx context.Context) { redirectURI = "http://localhost:8080/callback" } - a.ssi = NewESISSO(clientID, redirectURI, []string{"esi-ui.write_waypoint.v1"}) + // Add location read scope so we can fetch character locations + a.ssi = NewESISSO(clientID, redirectURI, []string{"esi-ui.write_waypoint.v1", "esi-location.read_location.v1"}) } // Greet returns a greeting for the given name @@ -130,8 +131,10 @@ func (a *App) ListCharacters() ([]CharacterInfo, error) { // GetCharacterLocations exposes current locations for all characters func (a *App) GetCharacterLocations() ([]CharacterLocation, error) { - if a.ssi == nil { return nil, errors.New("ESI not initialised") } - ctx, cancel := context.WithTimeout(a.ctx, 6*time.Second) - defer cancel() - return a.ssi.GetCharacterLocations(ctx) + if a.ssi == nil { + return nil, errors.New("ESI not initialised") + } + ctx, cancel := context.WithTimeout(a.ctx, 6*time.Second) + defer cancel() + return a.ssi.GetCharacterLocations(ctx) } diff --git a/frontend/src/components/RegionMap.tsx b/frontend/src/components/RegionMap.tsx index 7418a29..2be7460 100644 --- a/frontend/src/components/RegionMap.tsx +++ b/frontend/src/components/RegionMap.tsx @@ -133,23 +133,23 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho setPositions(positions); const connections = computeNodeConnections(systems); setConnections(connections); - // Compute per-system mean inbound angle from in-region neighbors + // Compute per-system mean outbound BEARING (0=north, clockwise positive) to in-region neighbors const angleMap: Record = {}; systems.forEach((sys, name) => { const neighbors = (sys.connectedSystems || '').split(',').map(s => s.trim()).filter(Boolean); - let sumX = 0, sumY = 0, count = 0; + let sumSin = 0, sumCos = 0, count = 0; for (const n of neighbors) { const neighbor = systems.get(n); if (!neighbor) continue; - const ax = sys.x - neighbor.x; - const ay = sys.y - neighbor.y; // vector pointing into this system - const a = Math.atan2(ay, ax); - sumX += Math.cos(a); - sumY += Math.sin(a); + const dx = neighbor.x - sys.x; + const dy = neighbor.y - sys.y; // screen coords (y down) + const bearing = Math.atan2(dx, -dy); // bearing relative to north + sumSin += Math.sin(bearing); + sumCos += Math.cos(bearing); count++; } if (count > 0) { - angleMap[name] = Math.atan2(sumY, sumX); + angleMap[name] = Math.atan2(sumSin, sumCos); // average bearing } }); setMeanInboundAngle(angleMap); @@ -226,12 +226,14 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho let angle: number | undefined = undefined; const inbound = meanInboundAngle[fromName]; if (inbound !== undefined) { - angle = inbound + Math.PI; // opposite direction of mean inbound + angle = inbound; // mean outbound bearing already computed } else { const curPos = universeRegionPosCache.get(regionName); const toPos = universeRegionPosCache.get(toRegion); if (curPos && toPos) { - angle = Math.atan2(toPos.y - curPos.y, toPos.x - curPos.x); + const dxr = toPos.x - curPos.x; + const dyr = toPos.y - curPos.y; + angle = Math.atan2(dxr, -dyr); // bearing to remote region } } if (angle === undefined) { @@ -670,8 +672,8 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho const yoff = -18 - (idx % 3) * 10; // stagger small vertical offsets if multiple in same system return ( - - {c.character_name} + + {c.character_name} ); })} @@ -682,8 +684,8 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho if (!pos) return null; const len = 26; const r0 = 10; // start just outside node - const dx = Math.cos(ind.angle); - const dy = Math.sin(ind.angle); + const dx = Math.sin(ind.angle); + const dy = -Math.cos(ind.angle); const x1 = pos.x + dx * r0; const y1 = pos.y + dy * r0; const x2 = x1 + dx * len;