11 Commits

Author SHA1 Message Date
Bartosz Woźniak 936928fed9 Enhance InputHandler to allow using NumPad (#3317)
## Description:

Adds **Enter** and **Numpad Enter** as confirmation for placing a ghost
structure after selecting a building with hotkeys (1–0 or numpad).
Players can cancel with Esc but previously had to click to confirm; they
can now confirm with Enter or Numpad Enter at the current cursor
position. This supports keyboard-only or mouse + numpad workflows (e.g.
one hand on numpad for select + confirm, one on mouse for aiming).

## 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:

.wozniakpl
2026-03-07 15:27:25 -08:00
Mattia Migliorini ba2a947061 Feat: Display ghost railways when building cities and ports (#3202)
## Description:

Based on [this suggestion on
Discord](https://discord.com/channels/1284581928254701718/1447110257196138577)
and feedback gathered in [this
thread](https://discord.com/channels/1359946986937258015/1469598906173227184).

Supersedes #3143 

This PR introduces "ghost railways": when you are going to place a city
or port, previews railway connections that will be made when actually
building the structure.

Ghost railways are skipped if the structure is going to be snapped to
existing railways (as in railway snapping functionality introduced in
#3156 ).

### Video


https://github.com/user-attachments/assets/ff8cf325-6501-4df8-801d-c8ae3ced3d0e


### Ghost rails color revisited

black with 40% opacity

<img width="695" height="430" alt="image"
src="https://github.com/user-attachments/assets/272efbcc-4185-426a-921c-7fae61f6c462"
/>


## 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:

deshack_82603
2026-02-18 21:44:08 +00:00
DevelopingTom c6c793f6b3 Highlight hovering railroad (#3156)
## Description:


![rail_snap](https://github.com/user-attachments/assets/1dc66dc8-5df8-4826-8a8e-521d72a1f8aa)

The `RailroadLayer` simply displays tiles as instructed by the core
worker. While it's practical for the layer to only care about the tiles,
it also means it has no understanding of railroads as entities (their
paths, connections, or identities).

It also means that the core worker is responsible for rendering tasks
such as tile orientation and construction animation, which is not
expected.

To support ID-based events and better separation of concerns, the
rendering layer needs to be aware of complete railroads. With this
change, the core worker can send the tiles once and subsequently
reference railroads only by ID for all other events.

#### Changes:
- `RailroadLayer` now stores full railroad data instead of only
individual tiles
- `RailroadLayer` is responsible for animating newly built railroads
- Add a new `RailroadSnapUpdate` sent when a new structure is built over
an existing railroad. This event is used by `RailroadLayer` to keep
railroad ID in sync.

- When hovering over a railroad, the render worker is querying the core
worker about overlapping railroads.
Alternatively, RailroadLayer could compute overlaps itself now that it
has full railroad knowledge, but this logic would need to be duplicated
and kept in sync across workers. Keeping a single source of truth in the
core worker is preferred.


#### Edgecases:
- When a structure snaps over a railroad, the original railroad is split
into two new railroads. If the construction animation is still in
progress, instead of resuming the animation at the correct point on the
new railroads, all remaining tiles are rendered immediately
- Previously, `RailroadUpdate` handled both construction and
destruction. This no longer works with `RailroadSnapUpdate`, as event
ordering is now pretty important and IDs may be lost before they are
consumed.
To address this, RailroadUpdate is split in two:
`RailroadConstructionUpdate` and `RailroadDestructionUpdate`.


## 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:

IngloriousTom

---------

Co-authored-by: jrouillard <jon@rouillard.org>
2026-02-09 13:37:27 -08:00
Evan ed9900e313 Added afterEach cleanup to call inputHandler.destroy(), which clears the setInterval before jsdom tears down and removes window. (#3030)
## Description:

Fixes the failing test:coverage ci.

## 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:

evan
2026-01-25 20:34:48 -08:00
Stepan Hembarovskyi 97fffaf49e fix: Correctly handles unbound keybinds (#2854)
Resolves #2652 #2291

## Description:

Resolves a regression after a new design changes where keybinds
explicitly set to "Null" were incorrectly reverted to default values
instead of remaining unbound.

Updates the input handler to preserve "Null" as the designated value for
an unbound key. The UI now reflects this by displaying "None" for
keybinds that are set to "Null", providing clear user feedback.

Before/After:
<img width="378" height="371" alt="image"
src="https://github.com/user-attachments/assets/d1d640f2-93aa-47f1-be8e-7d8c68183aa1"
/> <img width="379" height="370" alt="image"
src="https://github.com/user-attachments/assets/f0512cce-c6e9-4180-9517-7669aed76f6f"
/>

## 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:

webdev.js

Co-authored-by: antigrid <Stepan.Hembarovskyi@Inu.edu.ua>
2026-01-10 10:06:47 -08:00
evanpelle b5a0541202 Revert "Fix Ctrl+Click for Macs, and alphabetize gitignore (#2720)"
This reverts commit 40eea22007.

Commit breaks map dragging ability.
2025-12-30 16:50:57 -08:00
Bruce Clounie 40eea22007 Fix Ctrl+Click for Macs, and alphabetize gitignore (#2720)
Resolves #2719 
- [X] Ran `npm run format`
- [X] Ran `npm run lint:fix`
- [X] Ran `npm test`
- [X] Manually tested fixes

## Description:

### What problem(s) was I solving?

On Mac, `Ctrl+Click` is commonly used as a substitute for right-click to
open context menus. However, in OpenFront, `Ctrl+Click` was triggering
both the context menu, AND causing an attack.

This effectively prevented Mac users from being able to ally with
bots/nations, as trying to ally would cause you to attack them.

### What changes did I make?
- `Ctrl+Click` on Mac no longer triggers an attack, allowing players to
properly interact with the alliance system

### How I implemented it

1. Added an `isMac()` method to `InputHandler` which encapsulates the
"is mac" logic, and lets it be mocked during tests
2. In the `onPointerUp` handler, added a check: if on Mac and
`ControlLeft` is held, emit a `ContextMenuEvent`, and then return
(instead of continuing to also create a `MouseUpEvent`)
3. Extracted magic numbers for mouse button checks into descriptive
helper methods (`isMiddleMouseButton`, `isNonLeftMouseButton`) for
improved code clarity
4. Added clarifying comments throughout the pointer event handlers

Last, alphabetized the `.gitignore` file and organized it into "Folders"
and "Files" sections to make it easier to read.

### How to verify it

#### Manual Testing
- [X] On a Mac, hold `Ctrl` and left-click on another nation - verify
the context menu opens (not an attack)
- [X] On a Mac, right-click should still open the context menu as
expected
- [X] On Windows/Linux, `Ctrl+Click` continue to work as before
(modifier key for build menu if configured)
- [X] Regular left-click still triggers attacks/interactions as expected

#### Automated Testing
- [x] New unit test added: `Mac Ctrl+Click Context Menu` - verifies that
`Ctrl+Click` on Mac emits `ContextMenuEvent` instead of `MouseUpEvent`

### Description for the changelog

Fixed `Ctrl+Click` on Mac to properly open the context menu instead of
triggering an attack, restoring the ability for Mac users to form
alliances with other nations.

## 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:
Terekhov
2025-12-31 00:26:00 +00:00
Ryan f1561df470 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>
2025-12-29 09:03:46 -08:00
Wraith 26f5d40819 build: migrate build system to Vite and test runner to Vitest & Remove depracated husky usage (#2703)
- Replace Webpack with Vite for faster client bundling and HMR.
- Migrate tests from Jest to Vitest and update configuration.
- Update Web Worker instantiation to standard ESM syntax.
- Implement Env utility in `src/core` for safe, hybrid environment
variable access (Vite vs Node).
- Refactor configuration loaders to remove direct `process.env`
dependencies in shared code.
- Update TypeScript environment definitions and project scripts for the
new toolchain.
- Remove the [depracated usage of the
husky](https://github.com/typicode/husky/releases/tag/v9.0.1).

## Description:

migrate build system to Vite and test runner to Vitest & Remove
depracated husky usage

## 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
- [ ] 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:

wraith4081

---------

Co-authored-by: evanpelle <evanpelle@gmail.com>
2025-12-28 22:10:26 -08:00
Vivacious Box 311d43ab4f Build bar (#2059)
## Description:

Make the unit display bar a proper unit build bar
Add shortcuts for all structures and units
Add ranges for ranged structures and units
Changed the shortcuts to use the key instead of the code for
internationalization purposes


![buildbar](https://github.com/user-attachments/assets/6407dc9c-14b4-40cc-8faa-cdd9e88c9fd2)
<img width="285" height="517" alt="image"
src="https://github.com/user-attachments/assets/91bb01e6-e48c-4255-ace1-306af9cdc25b"
/>

## 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:

Mr.Box

---------

Co-authored-by: evanpelle <evanpelle@gmail.com>
Co-authored-by: icslucas <carolinacarazolli@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-02 12:38:28 -07:00
Kipstz c3576a50b9 Add auto-upgrade buildings feature with middle mouse click (#1597)
## Description:

This PR implements a new feature allowing automatic upgrade of the
nearest building using the middle mouse button. This feature greatly
simplifies the upgrade process that previously required a right-click +
building recreation.

## 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 have read and accepted the CLA agreement (only required once).

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

Kipstzz

---------

Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
2025-09-03 16:00:22 -07:00