fix: report downed patrol helicopters as crashes and off-map markers by direction - #77
Conversation
Report a patrol helicopter that disappears inside the map as a probable crash with its grid cell, and one that disappears at or beyond the border as having left toward a compass direction. Replace clamped edge-cell grid references for off-map markers with 8-point directions across cargo, heli and chinook announcements, commands and the #info embed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Route MapEventKind.HeliCrashed in EventsCommandHandler through GridReference.From directly, mirroring EventEmbedRenderer.Locate, so a future out-of-bounds crash can never resolve the nonexistent "command.event.helicrashed.dir" key. Also fixes an accent inconsistency in the French heli entered/left strings, adds test coverage for the border band's east/south edges and the classifier's WorldSize == 0 guard, and documents the small-world edge case on MapGrid.IsAtOrBeyondBorder. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The outer band of a Rust map is ocean, so a helicopter downed there leaves no lootable debris and its grid cell would name water. The band erring toward "left" costs nothing players can act on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Field declarations to the top of their class and one wrapped parameter list, per the pre-push formatter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes two live map-event reporting defects by (1) distinguishing patrol-helicopter “left” vs “crashed” based on last known position relative to a one-cell border band, and (2) rendering off-map marker locations as compass directions (localized) instead of clamped grid cells. This aligns event/command outputs with player expectations while preserving the existing “raw coordinates” fallback when map dimensions are unavailable.
Changes:
- Add map-math helpers (
IsOutsideWorld,IsAtOrBeyondBorder,DirectionFrom) plus a newMapDirectionenum and localized direction words. - Introduce
MapLocationformatting and apply it across event embeds/lines, commands, and the#infoevents embed so off-map locations become directions. - Split patrol heli marker removals into
HeliCrashedvsHeliLeftand add corresponding localized resource keys and tests.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/RustPlusBot.Localization.Tests/StringsResourceParityTests.cs | Updates expected localization key count to reflect new .dir/direction/crash keys. |
| tests/RustPlusBot.Features.Events.Tests/Rendering/EventEmbedRendererTests.cs | Adds coverage for crash vs left wording and off-map direction rendering in embeds/lines. |
| tests/RustPlusBot.Features.Events.Tests/Messages/ServerEventsMessageRendererTests.cs | Ensures #info events rows show compass directions for off-map markers. |
| tests/RustPlusBot.Features.Events.Tests/Formatting/MapLocationTests.cs | New tests for MapLocation grid-vs-direction behavior and localization. |
| tests/RustPlusBot.Features.Events.Tests/Classifying/MarkerEventClassifierTests.cs | Adds tests for heli removal classification (crash vs left) including null/zero dimensions fallback. |
| tests/RustPlusBot.Features.Commands.Tests/Handlers/EventHandlersTests.cs | Verifies command outputs (!heli, !events) render directions and crash messages correctly. |
| tests/RustPlusBot.Abstractions.Tests/Connections/MapGridTests.cs | Adds tests for compass binning and border/outside-world predicates. |
| src/RustPlusBot.Localization/Strings.resx | Adds English direction words and .dir/crash message variants. |
| src/RustPlusBot.Localization/Strings.fr.resx | Adds French direction words (with articles) and .dir/crash message variants. |
| src/RustPlusBot.Features.Events/Rendering/EventEmbedRenderer.cs | Routes embed and line rendering through MapLocation + .dir key suffixing; adds crash kind support. |
| src/RustPlusBot.Features.Events/Messages/ServerEventsMessageRenderer.cs | Uses MapLocation.Describe for active marker rows so off-map locations become directions. |
| src/RustPlusBot.Features.Events/Formatting/MapLocation.cs | New formatter returning (text, isDirection) to drive .dir suffix selection consistently. |
| src/RustPlusBot.Features.Events/Classifying/MarkerEventClassifier.cs | Splits patrol heli removals into crash vs left using IsAtOrBeyondBorder. |
| src/RustPlusBot.Features.Events/Classifying/MapEventKind.cs | Adds HeliCrashed = 5. |
| src/RustPlusBot.Features.Commands/Handlers/MarkerReply.cs | Updates marker commands to use .dir variants when location is a direction. |
| src/RustPlusBot.Features.Commands/Handlers/EventsCommandHandler.cs | Updates !events rendering to use .dir variants and handle HeliCrashed. |
| src/RustPlusBot.Abstractions/Connections/MapGrid.cs | Adds outside-world check, border-band predicate, and 8-way bearing binning. |
| src/RustPlusBot.Abstractions/Connections/MapDirection.cs | New enum ordered clockwise from north to support direct binning. |
| README.md | Updates feature description to document crash reporting + off-map direction behavior. |
| docs/superpowers/specs/2026-08-10-patrol-heli-crash-and-offmap-directions-design.md | New design spec documenting requirements and decisions. |
| docs/superpowers/plans/2026-08-10-patrol-heli-crash-and-offmap-directions.md | New implementation plan capturing tasks, constraints, and verification steps. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Fixes two defects in live map-event reporting.
1. A downed patrol helicopter was reported as having left
Every patrol-helicopter marker removal classified as
HeliLeft("🚁 Patrol Helicopter left (D7)"). The marker disappears for two very different reasons: the heli was shot down, or it finished its patrol and flew off the map edge. The shoot-down case is the one players care about — it marks loot on the ground — and it was indistinguishable from a routine departure.Now the split is position-based, with a one-cell (146.25 unit) tolerance band:
HeliCrashed→ "🚁 Patrol Helicopter probably crashed at N13"HeliLeft→ "🚁 Patrol Helicopter left the map to the west"The band exists because marker positions are sampled by polling, so a heli that has just crossed the border is usually still reported slightly inside it. A strict inside/outside test would misreport most routine departures as crashes.
2. Off-map markers reported a fake grid cell
MapGrid.LabelForclamps out-of-world coordinates to the nearest edge cell. Cargo ships, helicopters and chinooks spawn in the ocean outside the playable world, so their spawn announcement named a cell they are not in and may never visit.Those positions now render as an 8-point compass direction from the world centre, across announcements, team-chat lines, commands and the
#infoembed:!helioff-map#infoevents rowApproach
MapGridgainsDirectionFrom(bearing from the world centre, binned into 45° sectors centred on each compass point),IsOutsideWorld, andIsAtOrBeyondBorder.MapLocation.Describe/DescribeDirectionreturn the location text plus whether it names a direction. Renderers append.dirto the message key when it does.l'est,le nord-est) so one message value covers all eight without an elision problem.Verification
dotnet test RustPlusBot.slnx→ 1315 passed, 1 skipped (1269 before this branch; +46 tests). Build clean underTreatWarningsAsErrors.MapEventKindis not persisted anywhere, so appendingHeliCrashed = 5cannot affect stored state.Spec:
docs/superpowers/specs/2026-08-10-patrol-heli-crash-and-offmap-directions-design.mdPlan:
docs/superpowers/plans/2026-08-10-patrol-heli-crash-and-offmap-directions.md🤖 Generated with Claude Code