mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 12:00:15 +00:00
Keybind Ground Attack (#1258)
## Description: - Implement ground attack logic in ClientGameRunner - Move cursor location logic from doBoatAttackUnderCursor to getTileUnderCursor for reusability. - New keybind G for Ground Attack - Add translations for ground attack labels in English ## 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 - [X] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors <img width="902" alt="image" src="https://github.com/user-attachments/assets/54bb3178-af2e-4715-bfa2-82b7fe0e8e85" /> *The getTileUnderCursor() and doGroundAttackUnderCursor() methods are private with many dependencies. I did not do isolated unit testing and thus zero tests where added. ## Please put your Discord username so you can be contacted if a bug or regression is found: eng.la --------- Co-authored-by: evanpelle <evanpelle@gmail.com>
This commit is contained in:
@@ -269,6 +269,8 @@
|
||||
"attack_keybinds": "Attack Keybinds",
|
||||
"boat_attack": "Boat Attack",
|
||||
"boat_attack_desc": "Send a boat attack to the tile under your cursor.",
|
||||
"ground_attack": "Ground Attack",
|
||||
"ground_attack_desc": "Send a ground attack to the tile under your cursor.",
|
||||
"zoom_controls": "Zoom Controls",
|
||||
"zoom_out": "Zoom Out",
|
||||
"zoom_out_desc": "Zoom out the map",
|
||||
|
||||
@@ -27,6 +27,7 @@ import { UserSettings } from "../core/game/UserSettings";
|
||||
import { WorkerClient } from "../core/worker/WorkerClient";
|
||||
import {
|
||||
DoBoatAttackEvent,
|
||||
DoGroundAttackEvent,
|
||||
InputHandler,
|
||||
MouseMoveEvent,
|
||||
MouseUpEvent,
|
||||
@@ -246,9 +247,16 @@ export class ClientGameRunner {
|
||||
1000,
|
||||
);
|
||||
}, 20000);
|
||||
this.eventBus.on(MouseUpEvent, (e) => this.inputEvent(e));
|
||||
this.eventBus.on(MouseMoveEvent, (e) => this.onMouseMove(e));
|
||||
this.eventBus.on(DoBoatAttackEvent, (e) => this.doBoatAttackUnderCursor());
|
||||
this.eventBus.on(MouseUpEvent, this.inputEvent.bind(this));
|
||||
this.eventBus.on(MouseMoveEvent, this.onMouseMove.bind(this));
|
||||
this.eventBus.on(
|
||||
DoBoatAttackEvent,
|
||||
this.doBoatAttackUnderCursor.bind(this),
|
||||
);
|
||||
this.eventBus.on(
|
||||
DoGroundAttackEvent,
|
||||
this.doGroundAttackUnderCursor.bind(this),
|
||||
);
|
||||
|
||||
this.renderer.initialize();
|
||||
this.input.initialize();
|
||||
@@ -418,20 +426,10 @@ export class ClientGameRunner {
|
||||
}
|
||||
|
||||
private doBoatAttackUnderCursor(): void {
|
||||
if (!this.isActive || !this.lastMousePosition) {
|
||||
const tile = this.getTileUnderCursor();
|
||||
if (tile === null) {
|
||||
return;
|
||||
}
|
||||
if (this.gameView.inSpawnPhase()) {
|
||||
return;
|
||||
}
|
||||
const cell = this.renderer.transformHandler.screenToWorldCoordinates(
|
||||
this.lastMousePosition.x,
|
||||
this.lastMousePosition.y,
|
||||
);
|
||||
if (!this.gameView.isValidCoord(cell.x, cell.y)) {
|
||||
return;
|
||||
}
|
||||
const tile = this.gameView.ref(cell.x, cell.y);
|
||||
|
||||
if (this.myPlayer === null) {
|
||||
const myPlayer = this.gameView.playerByClientID(this.lobby.clientID);
|
||||
@@ -446,6 +444,48 @@ export class ClientGameRunner {
|
||||
});
|
||||
}
|
||||
|
||||
private doGroundAttackUnderCursor(): void {
|
||||
const tile = this.getTileUnderCursor();
|
||||
if (tile === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.myPlayer === null) {
|
||||
const myPlayer = this.gameView.playerByClientID(this.lobby.clientID);
|
||||
if (myPlayer === null) return;
|
||||
this.myPlayer = myPlayer;
|
||||
}
|
||||
|
||||
this.myPlayer.actions(tile).then((actions) => {
|
||||
if (this.myPlayer === null) return;
|
||||
if (actions.canAttack) {
|
||||
this.eventBus.emit(
|
||||
new SendAttackIntentEvent(
|
||||
this.gameView.owner(tile).id(),
|
||||
this.myPlayer.troops() * this.renderer.uiState.attackRatio,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getTileUnderCursor(): TileRef | null {
|
||||
if (!this.isActive || !this.lastMousePosition) {
|
||||
return null;
|
||||
}
|
||||
if (this.gameView.inSpawnPhase()) {
|
||||
return null;
|
||||
}
|
||||
const cell = this.renderer.transformHandler.screenToWorldCoordinates(
|
||||
this.lastMousePosition.x,
|
||||
this.lastMousePosition.y,
|
||||
);
|
||||
if (!this.gameView.isValidCoord(cell.x, cell.y)) {
|
||||
return null;
|
||||
}
|
||||
return this.gameView.ref(cell.x, cell.y);
|
||||
}
|
||||
|
||||
private canBoatAttack(actions: PlayerActions, tile: TileRef): boolean {
|
||||
const bu = actions.buildableUnits.find(
|
||||
(bu) => bu.type === UnitType.TransportShip,
|
||||
|
||||
@@ -79,6 +79,8 @@ export class ShowEmojiMenuEvent implements GameEvent {
|
||||
|
||||
export class DoBoatAttackEvent implements GameEvent {}
|
||||
|
||||
export class DoGroundAttackEvent implements GameEvent {}
|
||||
|
||||
export class AttackRatioEvent implements GameEvent {
|
||||
constructor(public readonly attackRatio: number) {}
|
||||
}
|
||||
@@ -133,6 +135,7 @@ export class InputHandler {
|
||||
attackRatioDown: "Digit1",
|
||||
attackRatioUp: "Digit2",
|
||||
boatAttack: "KeyB",
|
||||
groundAttack: "KeyG",
|
||||
modifierKey: "ControlLeft",
|
||||
altKey: "AltLeft",
|
||||
...JSON.parse(localStorage.getItem("settings.keybinds") ?? "{}"),
|
||||
@@ -265,6 +268,11 @@ export class InputHandler {
|
||||
this.eventBus.emit(new DoBoatAttackEvent());
|
||||
}
|
||||
|
||||
if (e.code === this.keybinds.groundAttack) {
|
||||
e.preventDefault();
|
||||
this.eventBus.emit(new DoGroundAttackEvent());
|
||||
}
|
||||
|
||||
if (e.code === this.keybinds.attackRatioDown) {
|
||||
e.preventDefault();
|
||||
this.eventBus.emit(new AttackRatioEvent(-10));
|
||||
|
||||
@@ -416,6 +416,15 @@ export class UserSettingModal extends LitElement {
|
||||
@change=${this.handleKeybindChange}
|
||||
></setting-keybind>
|
||||
|
||||
<setting-keybind
|
||||
action="groundAttack"
|
||||
label=${translateText("user_setting.ground_attack")}
|
||||
description=${translateText("user_setting.ground_attack_desc")}
|
||||
defaultKey="KeyG"
|
||||
.value=${this.keybinds["groundAttack"] ?? ""}
|
||||
@change=${this.handleKeybindChange}
|
||||
></setting-keybind>
|
||||
|
||||
<div class="text-center text-white text-base font-semibold mt-5 mb-2">
|
||||
${translateText("user_setting.zoom_controls")}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user