-
Notifications
You must be signed in to change notification settings - Fork 708
Bomb Direction #2435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Bomb Direction #2435
Conversation
|
Warning Rate limit exceeded@ryanbarlow97 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 26 minutes and 35 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThreads a new Changes
Sequence Diagram(s)sequenceDiagram
actor Player
participant InputHandler
participant EventBus
participant UIState
participant NukePreview as NukeTrajectoryPreviewLayer
participant Parabola as ParabolaPathFinder
participant ExecMgr as ExecutionManager
participant NukeExec as NukeExecution
Player->>InputHandler: release KeyU
InputHandler->>EventBus: emit SwapRocketDirectionEvent
EventBus->>NukePreview: deliver SwapRocketDirectionEvent
NukePreview->>UIState: toggle rocketDirectionUp
NukePreview->>NukePreview: invalidate cached trajectory
NukePreview->>Parabola: computeControlPoints(orig,dst,..., directionUp=UIState.rocketDirectionUp)
Parabola-->>NukePreview: control points
Note right of ExecMgr: Build intent includes rocketDirectionUp when building bombs
ExecMgr->>NukeExec: new NukeExecution(..., rocketDirectionUp)
NukeExec->>Parabola: computeControlPoints(..., directionUp=rocketDirectionUp)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
tests/InputHandler.test.ts (1)
40-40: Consider adding tests for SwapRocketDirectionEvent.The
rocketDirectionUp: trueaddition is correct to satisfy the updated UIState interface. However, there are no tests verifying that pressing the swap direction key (KeyU) actually emits a SwapRocketDirectionEvent.Would you like me to generate a test case for the swap direction functionality?
src/client/graphics/layers/StructureIconsLayer.ts (1)
337-347: Extract a shared helper for rocket direction unitsThe same
AtomBomb/HydrogenBombcheck now lives here and inBuildMenu.ts. A tiny helper likeisDirectionalNuke(unitType: UnitType): unitType is UnitType.AtomBomb | UnitType.HydrogenBomb(or a small readonly set) would keep the rule in one place and make future tweaks safer.src/client/graphics/layers/BuildMenu.ts (1)
400-407: Reuse a helper for directional nukesWe now repeat the
AtomBomb/HydrogenBombguard here and inStructureIconsLayer. Pulling it into a small helper (for exampleisDirectionalNuke(unitType)) keeps the list of directional units in one place and stays friendly for future changes.src/client/graphics/GameRenderer.ts (1)
52-56: Prefer type-safeuiStateinitializationCasting with
as UIStatehides missing or extra fields. Declaring the variable with an explicit type (orsatisfies UIState) keeps the compiler on our side:- const uiState = { - attackRatio: 20, - ghostStructure: null, - rocketDirectionUp: true, - } as UIState; + const uiState: UIState = { + attackRatio: 20, + ghostStructure: null, + rocketDirectionUp: true, + };Simple change, but it saves us from silent shape drift later.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/client/InputHandler.ts(3 hunks)src/client/Transport.ts(2 hunks)src/client/graphics/GameRenderer.ts(3 hunks)src/client/graphics/UIState.ts(1 hunks)src/client/graphics/layers/BuildMenu.ts(3 hunks)src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts(4 hunks)src/client/graphics/layers/StructureIconsLayer.ts(1 hunks)src/core/Schemas.ts(1 hunks)src/core/execution/ConstructionExecution.ts(2 hunks)src/core/execution/ExecutionManager.ts(1 hunks)src/core/execution/NukeExecution.ts(2 hunks)src/core/pathfinding/PathFinding.ts(2 hunks)tests/InputHandler.test.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-08-24T11:13:08.495Z
Learnt from: DevelopingTom
Repo: openfrontio/OpenFrontIO PR: 1900
File: src/core/execution/SAMLauncherExecution.ts:103-111
Timestamp: 2025-08-24T11:13:08.495Z
Learning: In SAMLauncherExecution.ts, the cached target bug can only occur if: 1) SAM is not on cooldown when nuke is in range, 2) SAM goes on cooldown right after computing trajectory, 3) SAM becomes available again before nuke explodes. This is not possible with current cooldown values but the fix is still valuable for robustness.
Applied to files:
src/core/execution/NukeExecution.tssrc/client/graphics/layers/NukeTrajectoryPreviewLayer.ts
📚 Learning: 2025-10-20T20:15:28.858Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:51-51
Timestamp: 2025-10-20T20:15:28.858Z
Learning: In src/core/execution/FakeHumanExecution.ts, game balance constants like MIRV_COOLDOWN_TICKS, MIRV_HESITATION_ODDS, VICTORY_DENIAL_TEAM_THRESHOLD, VICTORY_DENIAL_INDIVIDUAL_THRESHOLD, and STEAMROLL_CITY_GAP_MULTIPLIER are experimental tuning parameters subject to frequent change during balance testing. Do not flag changes to these values as issues or compare them against previous values.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ExecutionManager.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-27T09:47:26.395Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:770-795
Timestamp: 2025-10-27T09:47:26.395Z
Learning: In src/core/execution/FakeHumanExecution.ts, the selectSteamrollStopTarget() method intentionally allows MIRV targeting when secondHighest city count is 0 (e.g., nuclear endgame scenarios where structures are destroyed). This is valid game design—"if you can afford it, you're good to go"—and should not be flagged as requiring a guard condition.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-18T17:54:01.311Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:172-173
Timestamp: 2025-10-18T17:54:01.311Z
Learning: In src/core/execution/FakeHumanExecution.ts, MIRVs and ground attacks should not be mutually exclusive. The considerMIRV() method should not short-circuit maybeAttack() - both actions can occur in the same tick.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ExecutionManager.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from UnitType values (specifically bomb-related values like AtomBomb, HydrogenBomb, MIRV, and MIRVWarhead) rather than a separate enum. This means comparing NukeType values against UnitType values in switch statements is valid and intentional.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-18T11:00:57.142Z
Learnt from: NewYearNewPhil
Repo: openfrontio/OpenFrontIO PR: 2230
File: src/client/graphics/GameRenderer.ts:269-277
Timestamp: 2025-10-18T11:00:57.142Z
Learning: In src/client/graphics/GameRenderer.ts, the GameRecapCapture implementation does not use setCaptureRenderEnabled on layers. Instead, it uses RecapCaptureSurface.capture() to render capture layers (TerrainLayer, TerritoryLayer, RailroadLayer, StructureIconsLayer, UnitLayer) directly to an off-screen canvas without requiring layer-level capture mode methods.
Applied to files:
src/client/graphics/GameRenderer.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.
Applied to files:
src/client/graphics/GameRenderer.ts
📚 Learning: 2025-08-12T00:31:50.144Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 1752
File: src/core/game/Game.ts:750-752
Timestamp: 2025-08-12T00:31:50.144Z
Learning: In the OpenFrontIO codebase, changes to the PlayerInteraction interface (like adding canDonateGold and canDonateTroops flags) do not require corresponding updates to src/core/Schemas.ts or server serialization code.
Applied to files:
src/core/Schemas.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from specific UnitType enum values (AtomBomb, HydrogenBomb, MIRV, MIRVWarhead). This means that comparisons in switch statements between a NukeType parameter and UnitType enum values are valid and will work correctly at runtime.
Applied to files:
src/core/execution/ConstructionExecution.ts
🧬 Code graph analysis (7)
src/client/InputHandler.ts (1)
src/core/EventBus.ts (1)
GameEvent(1-1)
src/client/graphics/layers/BuildMenu.ts (2)
src/client/graphics/UIState.ts (1)
UIState(3-7)src/client/Transport.ts (1)
BuildUnitIntentEvent(88-94)
src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts (2)
src/client/graphics/UIState.ts (1)
UIState(3-7)src/client/InputHandler.ts (1)
SwapRocketDirectionEvent(92-92)
src/core/execution/ExecutionManager.ts (1)
src/core/execution/ConstructionExecution.ts (1)
ConstructionExecution(21-160)
src/client/graphics/GameRenderer.ts (2)
src/client/graphics/UIState.ts (1)
UIState(3-7)src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts (1)
NukeTrajectoryPreviewLayer(19-275)
src/client/graphics/layers/StructureIconsLayer.ts (1)
src/client/Transport.ts (1)
BuildUnitIntentEvent(88-94)
src/core/execution/ConstructionExecution.ts (1)
src/core/execution/NukeExecution.ts (1)
NukeExecution(19-338)
🔇 Additional comments (11)
src/client/InputHandler.ts (2)
92-93: LGTM!Event definition follows the established pattern for parameterless events in this codebase.
205-205: LGTM!Keybind definition follows the existing pattern and can be customized by users via localStorage.
src/client/graphics/UIState.ts (1)
6-6: LGTM!Adding
rocketDirectionUpto the UIState interface is the correct approach for shared UI state. The property is appropriately typed and named.src/core/execution/ExecutionManager.ts (1)
108-113: LGTM!The
rocketDirectionUpparameter is correctly threaded from the intent to the ConstructionExecution. The optional parameter will beundefinedwhen not provided, which aligns with the ConstructionExecution constructor signature.src/core/execution/ConstructionExecution.ts (2)
34-34: LGTM!The optional
rocketDirectionUpparameter is correctly added to the constructor, providing backward compatibility when the parameter is not provided.
108-116: No changes needed—MIRV direction control is intentional design.MirvExecution deliberately accepts only
(player, dst)parameters with no direction control, unlike NukeExecution which acceptsrocketDirectionUp. This is by design: AtomBomb and HydrogenBomb use a single directional arc (up or down), while MIRV uses intelligent dispersal across multiple targets in a scatter pattern. Both weapon types work as intended.src/core/Schemas.ts (1)
305-305: LGTM!The optional
rocketDirectionUpfield is correctly added to the BuildUnitIntentSchema. Making it optional ensures backward compatibility with existing code that doesn't provide this parameter.src/client/Transport.ts (2)
92-92: LGTM!The optional
rocketDirectionUpparameter is correctly added to BuildUnitIntentEvent, maintaining backward compatibility for existing callers.
553-553: LGTM!The
rocketDirectionUpparameter is correctly propagated from the event to the intent payload. When undefined, this will result in the field being omitted from the payload or serialized as undefined, which aligns with the optional schema definition.src/core/execution/NukeExecution.ts (2)
33-33: LGTM!The default value of
trueforrocketDirectionUppreserves the existing upward trajectory behavior, ensuring backward compatibility for code paths that don't explicitly provide this parameter.
119-119: LGTM!The
rocketDirectionUpparameter is correctly passed to the pathfinder, enabling direction-aware trajectory computation as intended by this PR.
|
This seems good yea |
HimangshuPronoy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything seems good. high quality code.
cheers |
|
I've just added the "U" hotkey instruction to the helpmodal + en.json list as I forgot to do this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
resources/lang/en.json(1 hunks)src/client/HelpModal.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from UnitType values (specifically bomb-related values like AtomBomb, HydrogenBomb, MIRV, and MIRVWarhead) rather than a separate enum. This means comparing NukeType values against UnitType values in switch statements is valid and intentional.
🧬 Code graph analysis (1)
src/client/HelpModal.ts (2)
src/client/Utils.ts (1)
translateText(92-147)src/client/LangSelector.ts (1)
translateText(254-274)
🔇 Additional comments (1)
src/client/HelpModal.ts (1)
58-61: LGTM!The hotkey table row is correctly implemented and follows the established pattern. The translation key properly references the new entry in en.json.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/core/execution/NukeExecution.ts (1)
26-34: Good default preserves existing behavior.The default
trueensures backward compatibility—existing callers that do not specify direction will continue to get the upward arc trajectory.One observation: this constructor now has 7 positional parameters. If more optional fields are added later, consider grouping optional params into an options object for readability. Not blocking for this PR.
Example pattern for future consideration:
interface NukeOptions { src?: TileRef | null; speed?: number; waitTicks?: number; rocketDirectionUp?: boolean; } constructor( private nukeType: NukeType, private player: Player, private dst: TileRef, options: NukeOptions = {}, ) { this.src = options.src ?? null; this.speed = options.speed ?? -1; this.waitTicks = options.waitTicks ?? 0; this.rocketDirectionUp = options.rocketDirectionUp ?? true; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
resources/lang/en.json(1 hunks)src/client/graphics/layers/StructureIconsLayer.ts(1 hunks)src/core/execution/ConstructionExecution.ts(2 hunks)src/core/execution/NukeExecution.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/client/graphics/layers/StructureIconsLayer.ts
- resources/lang/en.json
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-08-24T11:13:08.495Z
Learnt from: DevelopingTom
Repo: openfrontio/OpenFrontIO PR: 1900
File: src/core/execution/SAMLauncherExecution.ts:103-111
Timestamp: 2025-08-24T11:13:08.495Z
Learning: In SAMLauncherExecution.ts, the cached target bug can only occur if: 1) SAM is not on cooldown when nuke is in range, 2) SAM goes on cooldown right after computing trajectory, 3) SAM becomes available again before nuke explodes. This is not possible with current cooldown values but the fix is still valuable for robustness.
Applied to files:
src/core/execution/NukeExecution.ts
📚 Learning: 2025-10-20T20:15:28.858Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:51-51
Timestamp: 2025-10-20T20:15:28.858Z
Learning: In src/core/execution/FakeHumanExecution.ts, game balance constants like MIRV_COOLDOWN_TICKS, MIRV_HESITATION_ODDS, VICTORY_DENIAL_TEAM_THRESHOLD, VICTORY_DENIAL_INDIVIDUAL_THRESHOLD, and STEAMROLL_CITY_GAP_MULTIPLIER are experimental tuning parameters subject to frequent change during balance testing. Do not flag changes to these values as issues or compare them against previous values.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-27T09:47:26.395Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:770-795
Timestamp: 2025-10-27T09:47:26.395Z
Learning: In src/core/execution/FakeHumanExecution.ts, the selectSteamrollStopTarget() method intentionally allows MIRV targeting when secondHighest city count is 0 (e.g., nuclear endgame scenarios where structures are destroyed). This is valid game design—"if you can afford it, you're good to go"—and should not be flagged as requiring a guard condition.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-18T17:54:01.311Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:172-173
Timestamp: 2025-10-18T17:54:01.311Z
Learning: In src/core/execution/FakeHumanExecution.ts, MIRVs and ground attacks should not be mutually exclusive. The considerMIRV() method should not short-circuit maybeAttack() - both actions can occur in the same tick.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from UnitType values (specifically bomb-related values like AtomBomb, HydrogenBomb, MIRV, and MIRVWarhead) rather than a separate enum. This means comparing NukeType values against UnitType values in switch statements is valid and intentional.
Applied to files:
src/core/execution/NukeExecution.tssrc/core/execution/ConstructionExecution.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from specific UnitType enum values (AtomBomb, HydrogenBomb, MIRV, MIRVWarhead). This means that comparisons in switch statements between a NukeType parameter and UnitType enum values are valid and will work correctly at runtime.
Applied to files:
src/core/execution/ConstructionExecution.ts
🧬 Code graph analysis (1)
src/core/execution/ConstructionExecution.ts (1)
src/core/execution/NukeExecution.ts (1)
NukeExecution(19-338)
🔇 Additional comments (3)
src/core/execution/ConstructionExecution.ts (2)
20-25: Clean addition of the direction parameter.The optional
rocketDirectionUpparameter integrates well with the existing constructor signature. When not provided, it staysundefined, which will trigger the default value (true) in the downstreamNukeExecutionconstructor—preserving backward compatibility.
105-120: Correct propagation to NukeExecution for AtomBomb and HydrogenBomb.The
rocketDirectionUpflag is passed through correctly. Note thatMirvExecution(line 120) does not receive this flag, which appears intentional since MIRVs have distinct trajectory behavior that ignores this parameter.src/core/execution/NukeExecution.ts (1)
114-120: Trajectory computation correctly uses the direction flag.The
rocketDirectionUpvalue is passed tocomputeControlPointsas the 5th argument, enabling the parabola pathfinder to compute either upward or downward arcs based on user input. This integrates cleanly with the existing trajectory logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a bomb direction toggle feature that allows players to invert the trajectory arc of Atom and Hydrogen bombs by pressing the "U" hotkey. The feature adds UI state management for tracking the rocket direction preference and propagates it through the execution pipeline to control the parabolic path calculation.
- Adds
rocketDirectionUpboolean to UIState to track the current bomb trajectory preference - Implements hotkey "U" to toggle between upward and downward bomb arcs
- Updates pathfinding logic to support inverted trajectories with proper map boundary constraints
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/core/pathfinding/PathFinding.ts | Adds directionUp parameter to computeControlPoints to control trajectory direction with boundary clamping |
| src/core/execution/NukeExecution.ts | Passes rocketDirectionUp parameter through to pathfinding for Atom/Hydrogen bombs |
| src/core/execution/ConstructionExecution.ts | Accepts and forwards rocketDirectionUp to NukeExecution for Atom/Hydrogen bombs |
| src/core/execution/ExecutionManager.ts | Extracts rocketDirectionUp from intent and passes to ConstructionExecution |
| src/core/Schemas.ts | Adds optional rocketDirectionUp field to BuildUnitIntent schema |
| src/client/graphics/UIState.ts | Adds rocketDirectionUp boolean field to track user preference |
| src/client/graphics/GameRenderer.ts | Initializes rocketDirectionUp to true and wires uiState to BuildMenu |
| src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts | Handles SwapRocketDirectionEvent and uses uiState for preview trajectory calculation |
| src/client/graphics/layers/StructureIconsLayer.ts | Includes rocketDirectionUp in BuildUnitIntentEvent for Atom/Hydrogen bombs |
| src/client/graphics/layers/BuildMenu.ts | Includes rocketDirectionUp in BuildUnitIntentEvent for Atom/Hydrogen bombs |
| src/client/Transport.ts | Adds rocketDirectionUp parameter to BuildUnitIntentEvent and transport layer |
| src/client/InputHandler.ts | Adds swapDirection keybind and emits SwapRocketDirectionEvent on "U" press |
| src/client/HelpModal.ts | Adds help entry for "U" key bomb direction toggle |
| resources/lang/en.json | Adds localization text for bomb direction feature |
| tests/InputHandler.test.ts | Updates test to include rocketDirectionUp in UIState initialization |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Resolves #2434
Description:
Allows bomb direction to be inverted by pressing a hotkey - currently "U".
Check the issue for screenshots / videos.
Please complete the following:
Please put your Discord username so you can be contacted if a bug or regression is found:
w.o.n