Bomb Direction (#2435)

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:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

w.o.n

---------

Co-authored-by: Evan <evanpelle@gmail.com>
Co-authored-by: iamlewis <lewismmmm@gmail.com>
This commit is contained in:
Ryan
2025-12-29 17:03:46 +00:00
committed by GitHub
parent 6b14d9cca1
commit f1561df470
15 changed files with 90 additions and 12 deletions
+4
View File
@@ -138,6 +138,10 @@ export class HelpModal extends LitElement {
<td>${this.renderKey(keybinds.toggleView)}</td>
<td>${translateText("help_modal.action_alt_view")}</td>
</tr>
<tr>
<td><span class="key">U</span></td>
<td>${translateText("help_modal.bomb_direction")}</td>
</tr>
<tr>
<td>
<div class="scroll-combo-horizontal">
+8
View File
@@ -89,6 +89,8 @@ export class GhostStructureChangedEvent implements GameEvent {
constructor(public readonly ghostStructure: UnitType | null) {}
}
export class SwapRocketDirectionEvent implements GameEvent {}
export class ShowBuildMenuEvent implements GameEvent {
constructor(
public readonly x: number,
@@ -200,6 +202,7 @@ export class InputHandler {
attackRatioUp: "KeyY",
boatAttack: "KeyB",
groundAttack: "KeyG",
swapDirection: "KeyU",
modifierKey: isMac ? "MetaLeft" : "ControlLeft",
altKey: "AltLeft",
buildCity: "Digit1",
@@ -427,6 +430,11 @@ export class InputHandler {
this.setGhostStructure(UnitType.MIRV);
}
if (e.code === this.keybinds.swapDirection) {
e.preventDefault();
this.eventBus.emit(new SwapRocketDirectionEvent());
}
// Shift-D to toggle performance overlay
console.log(e.code, e.shiftKey, e.ctrlKey, e.altKey, e.metaKey);
if (e.code === "KeyD" && e.shiftKey) {
+2
View File
@@ -91,6 +91,7 @@ export class BuildUnitIntentEvent implements GameEvent {
constructor(
public readonly unit: UnitType,
public readonly tile: TileRef,
public readonly rocketDirectionUp?: boolean,
) {}
}
@@ -573,6 +574,7 @@ export class Transport {
clientID: this.lobbyConfig.clientID,
unit: event.unit,
tile: event.tile,
rocketDirectionUp: event.rocketDirectionUp,
});
}
+7 -2
View File
@@ -50,7 +50,11 @@ export function createRenderer(
const transformHandler = new TransformHandler(game, eventBus, canvas);
const userSettings = new UserSettings();
const uiState = { attackRatio: 20, ghostStructure: null } as UIState;
const uiState = {
attackRatio: 20,
ghostStructure: null,
rocketDirectionUp: true,
} as UIState;
//hide when the game renders
const startingModal = document.querySelector(
@@ -73,6 +77,7 @@ export function createRenderer(
}
buildMenu.game = game;
buildMenu.eventBus = eventBus;
buildMenu.uiState = uiState;
buildMenu.transformHandler = transformHandler;
const leaderboard = document.querySelector("leader-board") as Leaderboard;
@@ -241,7 +246,7 @@ export function createRenderer(
new UnitLayer(game, eventBus, transformHandler),
new FxLayer(game),
new UILayer(game, eventBus, transformHandler),
new NukeTrajectoryPreviewLayer(game, eventBus, transformHandler),
new NukeTrajectoryPreviewLayer(game, eventBus, transformHandler, uiState),
new StructureIconsLayer(game, eventBus, uiState, transformHandler),
new NameLayer(game, transformHandler, eventBus),
eventsDisplay,
+1
View File
@@ -3,4 +3,5 @@ import { UnitType } from "../../core/game/Game";
export interface UIState {
attackRatio: number;
ghostStructure: UnitType | null;
rocketDirectionUp: boolean;
}
+10 -1
View File
@@ -22,6 +22,7 @@ import {
} from "../../Transport";
import { renderNumber } from "../../Utils";
import { TransformHandler } from "../TransformHandler";
import { UIState } from "../UIState";
import { Layer } from "./Layer";
import warshipIcon from "/images/BattleshipIconWhite.svg?url";
import cityIcon from "/images/CityIconWhite.svg?url";
@@ -125,6 +126,7 @@ export const flattenedBuildTable = buildTable.flat();
export class BuildMenu extends LitElement implements Layer {
public game: GameView;
public eventBus: EventBus;
public uiState: UIState;
private clickedTile: TileRef;
public playerActions: PlayerActions | null;
private filteredBuildTable: BuildItemDisplay[][] = buildTable;
@@ -395,7 +397,14 @@ export class BuildMenu extends LitElement implements Layer {
),
);
} else if (buildableUnit.canBuild) {
this.eventBus.emit(new BuildUnitIntentEvent(buildableUnit.type, tile));
const rocketDirectionUp =
buildableUnit.type === UnitType.AtomBomb ||
buildableUnit.type === UnitType.HydrogenBomb
? this.uiState.rocketDirectionUp
: undefined;
this.eventBus.emit(
new BuildUnitIntentEvent(buildableUnit.type, tile, rocketDirectionUp),
);
}
this.hideMenu();
}
@@ -3,8 +3,13 @@ import { UnitType } from "../../../core/game/Game";
import { TileRef } from "../../../core/game/GameMap";
import { GameView } from "../../../core/game/GameView";
import { ParabolaPathFinder } from "../../../core/pathfinding/PathFinding";
import { GhostStructureChangedEvent, MouseMoveEvent } from "../../InputHandler";
import {
GhostStructureChangedEvent,
MouseMoveEvent,
SwapRocketDirectionEvent,
} from "../../InputHandler";
import { TransformHandler } from "../TransformHandler";
import { UIState } from "../UIState";
import { Layer } from "./Layer";
/**
@@ -27,6 +32,7 @@ export class NukeTrajectoryPreviewLayer implements Layer {
private game: GameView,
private eventBus: EventBus,
private transformHandler: TransformHandler,
private uiState: UIState,
) {}
shouldTransform(): boolean {
@@ -50,6 +56,12 @@ export class NukeTrajectoryPreviewLayer implements Layer {
this.cachedSpawnTile = null;
}
});
this.eventBus.on(SwapRocketDirectionEvent, () => {
// Toggle rocket direction
this.uiState.rocketDirectionUp = !this.uiState.rocketDirectionUp;
// Force trajectory recalculation
this.lastTargetTile = null;
});
}
tick() {
@@ -210,6 +222,7 @@ export class NukeTrajectoryPreviewLayer implements Layer {
targetTile,
speed,
distanceBasedHeight,
this.uiState.rocketDirectionUp,
);
this.trajectoryPoints = pathFinder.allTiles();
@@ -373,10 +373,16 @@ export class StructureIconsLayer implements Layer {
),
);
} else if (this.ghostUnit.buildableUnit.canBuild) {
const unitType = this.ghostUnit.buildableUnit.type;
const rocketDirectionUp =
unitType === UnitType.AtomBomb || unitType === UnitType.HydrogenBomb
? this.uiState.rocketDirectionUp
: undefined;
this.eventBus.emit(
new BuildUnitIntentEvent(
this.ghostUnit.buildableUnit.type,
unitType,
this.game.ref(tile.x, tile.y),
rocketDirectionUp,
),
);
}