diff --git a/AGENTS.md b/AGENTS.md index f0d937d..5940f60 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -214,6 +214,17 @@ Leaflet world map at `/map` (top-level sidebar entry, whole unit views it). Full - **GameRules**: `proximityThreshold` now means meters (default 1000; migration backfilled rows still at the old default 10). Both call sites (shipments/actions.ts, structures/actions.ts transferResource) use meters. - **Tests**: `tests/int/map-system.int.spec.ts` (routing graph/snap/refusals, cross-map refusal, ground route + path snapshot, air straight-line, proximity, terrain/range validation, placeStructure happy/water/range cases, construction tick lifecycle, permission gating, label/styling helpers + save-action styling validation). Gotcha: Payload applies select `filterOptions` server-side, so test fixtures must use `approvalStatus: "in_progress"`. +## Mission Planning Map (Arma 3 markers) + +Optional per-mission planning layer: the mission's own map (`classification.map`) rendered on the mission page with Arma 3 map markers that belong to that mission only (never on the shared world map). + +- **Marker assets**: `bun run markers:arma` (`src/tools/arma/extractMarkers.ts`, needs the game install + `hemtt`; default game root `/mnt/LData/SteamLibrary/steamapps/common/Arma 3`, override `--game`). Scans `Dta`, `Addons` and every DLC `addons` dir (skips `@` mod folders), parses + merges `CfgMarkers` / `CfgMarkerColors` / `CfgMarkerBrushes` / `CfgMarkerClasses` with inheritance, resolves `$STR_` names via stringtables, converts icons to PNG in `public/arma/markers/` (committed, so prod needs no game files) and regenerates `src/lib/arma-markers/catalog.generated.ts` (never edit by hand). Side-color expressions resolve to Arma's default profile colors (BLUFOR 0,0.3,0.6 etc.). +- **Catalog lib** (`src/lib/arma-markers/`, pure, client-safe): `index.ts` (case-insensitive `markerTypeOf`/`markerColorOf`/`markerBrushOf`, `resolveMarkerRgba` where color `Default` = the type's own config color, `markerTypesByCategory`), `missionMarkers.ts` (marker model mirroring Arma: shape icon/rectangle/ellipse/polyline + type/color/brush/text/size/direction/alpha/points; `normalizeMarkerInput` validation; `areaOutline` (direction = degrees clockwise from north, size = half-extents like `markerSize`); `hatchSegments` for pattern brushes; `armaGridRef`; `markersToSqf` export, y flipped against world height). +- **Collection**: `mission-map-markers` (`src/collections/intelligence/MissionMapMarkers.ts`, permission group "Mission Map Markers", REST access permission-gated). Missions gained `classification.planningMapEnabled` (opt-in) and a `beforeDelete` hook that removes the mission's markers (the FK is NOT NULL, so Payload's default ON DELETE SET NULL would fail the delete). Migration `20261003_190000_add_mission_map_markers` (hand-written; matches the generated schema). +- **Rules**: read = anyone who can read the mission (user-scoped `findByID`); edit = `missions:update` or the mission's `createdBy`. Service `src/lib/intelligence/missionMap.ts`; server actions `src/app/(frontend)/intelligence/missions/mapActions.ts` (`setMissionPlanningMap`, `getMissionMapMarkers`, `saveMissionMapMarker`, `deleteMissionMapMarker`, `clearMissionMapMarkers`; events `mission:planning-map-toggle` / `mission:map-marker-*` / `mission:map-markers-clear`, target `missions`). Max 1000 markers per mission. +- **UI**: `src/components/frontend/intelligence/missionMap/` (tactical dossier section above the mission detail grid). `MissionPlanningMap` (state, debounced per-marker saves, 30s background refresh, Delete/Escape keys, SQF copy, Arma grid readout), `MissionMapCanvas` (Leaflet, basemap + roads/zones via `GET /api/map-features?mapId=&layers=base`, which skips structures/nodes/shipments), `MarkerToolPanel` (tools, type picker, colors, brush, text, scale/size, direction, opacity), `markerIcon.ts` + `iconStyle.ts` (icons render as texture MULTIPLIED by the marker color and masked by the texture alpha, exactly like Arma: white glyphs take the color, flags keep theirs). Editors see an "Enable planning map" card until it is on; non-editors see nothing until enabled. +- **Gotchas**: leaflet click/dblclick/mousedown/mouseup fire faster than React re-renders, so draft line vertices and the area drag start live in refs (state only drives the preview). URLs inside divIcon HTML must use single quotes (`url('...')`): a double quote ends the `style` attribute and the glyph silently disappears. Radix Select keeps `pointer-events: none` on `` briefly after closing (affects scripted drags right after choosing a brush). Tests: `tests/int/mission-map.int.spec.ts`, `tests/e2e/mission-planning-map.e2e.spec.ts`. + ## Personnel (NPC directory) - `/personnel/contacts` — NPC directory over `game-npcs` (`src/components/frontend/personnel/`: `NpcDirectory`, `NpcCard`); `/personnel/contacts/[id]` — NPC profile (faction, in-game vs generated badges, vendor listings, `NpcProfile`). diff --git a/docs/map-system.md b/docs/map-system.md index 850347a..94faad4 100644 --- a/docs/map-system.md +++ b/docs/map-system.md @@ -273,3 +273,20 @@ Per map, in the Payload admin panel (World: Maps): map's `minZoom` to the lowest level your pyramid actually serves). - `minZoom`/`maxZoom`/`defaultZoom` and `defaultCenterX`/`defaultCenterY` (meters) tune the initial view. `isActive` hides maps from the page. + +## Mission planning maps + +A mission can opt in to a planning map (`classification.planningMapEnabled`). +The mission page then shows that mission's map (basemap, plus roads and zones +as toggles) with a layer of Arma 3 markers stored in `mission-map-markers`. +Those markers belong to the one mission and never appear on `/map`. + +- Marker coordinates use the same meters as every other map feature (origin + top-left, y south). The SQF export flips y against the world height, so + `worldSizeWidth`/`worldSizeHeight` must match the terrain's real size for + exported markers to land in the right place in-game. +- The base layers come from `GET /api/map-features?mapId=&layers=base`, + which skips the structure, node and shipment queries. +- Icons, colors and brushes come from the game config via + `bun run markers:arma`. See the "Mission Planning Map" section in AGENTS.md + for the full wiring. diff --git a/src/collections/AGENTS.md b/src/collections/AGENTS.md index 18b1cab..86f5b86 100644 --- a/src/collections/AGENTS.md +++ b/src/collections/AGENTS.md @@ -17,7 +17,8 @@ collections/ users/ 11 files # Users (auth), Ranks, Profiles (incl. minigame stats), Awards, # Qualifications, Assignments, AssignmentTransfers, Experience, # Evaluations, Roles (dynamic RBAC), UserNotifications - intelligence/ 5 files # Missions, MissionAttendances, Campaigns, Factions, Technologies + intelligence/ 5 files # Missions, MissionAttendances, MissionRoleSignups, + # MissionMapMarkers (planning-map markers), Campaigns, Factions, Technologies logistics/ 5 files # Structures (staffing defaults), Resources, Assets, Vehicles, Shipments banking/ 3 files # BankAccounts, BankTransactions, LedgerEntries market/ 2 files # MarketListings, MarketNegotiations @@ -51,6 +52,7 @@ GameStructures ── NpcStaffing ── LaborClassifications GameVehicles ── Vehicles (template) GameNpcs ── MarketListings ── MarketNegotiations MissionAttendances ── Missions ── Campaigns +MissionMapMarkers ── Missions (removed by Missions beforeDelete) ``` ## Access control pattern