Skip to content

Commit e3c4cef

Browse files
Fog of War
1 parent 5749968 commit e3c4cef

3 files changed

Lines changed: 132 additions & 0 deletions

File tree

.github/workflows/build-dev.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Build Development
2+
3+
on:
4+
push:
5+
branches: [master]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
17+
- name: Setup bun
18+
uses: oven-sh/setup-bun@v2
19+
20+
- name: Install bun dependencies
21+
run: cd web && bun install
22+
23+
- name: Build frontend
24+
run: cd web && bun run build
25+
26+
- name: Set up JDK 21
27+
uses: actions/setup-java@v4
28+
with:
29+
java-version: 21
30+
distribution: temurin
31+
32+
- name: Setup Gradle
33+
uses: gradle/actions/setup-gradle@v4
34+
35+
- name: Build
36+
run: ./gradlew shadowJar
37+
38+
- name: Extract repository name
39+
run: echo "NAME=$(basename ${{ github.repository }})" >> $GITHUB_ENV
40+
41+
- name: Upload Build
42+
uses: marvinpinto/action-automatic-releases@master
43+
with:
44+
title: "${{ env.NAME }}"
45+
automatic_release_tag: "latest"
46+
repo_token: "${{ secrets.GITHUB_TOKEN }}"
47+
files: "build/libs/*.jar"
48+
prerelease: false

web/src/js/FogOfWar.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import L from "leaflet";
2+
import { S } from "./Squaremap.js";
3+
4+
export const FogOfWar = L.Layer.extend({
5+
onAdd: function (map) {
6+
this._map = map;
7+
this._canvas = L.DomUtil.create("canvas", "leaflet-fog-of-war");
8+
this._canvas.style.position = "absolute";
9+
this._canvas.style.top = "0";
10+
this._canvas.style.left = "0";
11+
this._canvas.style.pointerEvents = "none";
12+
this._canvas.style.zIndex = "400";
13+
14+
const pane = map.getPane("overlayPane");
15+
pane.appendChild(this._canvas);
16+
17+
this._ctx = this._canvas.getContext("2d");
18+
19+
map.on("moveend resize zoomend", this._update, this);
20+
map.on("viewreset", this._update, this);
21+
22+
this._update();
23+
},
24+
25+
onRemove: function (map) {
26+
L.DomUtil.remove(this._canvas);
27+
map.off("moveend resize zoomend viewreset", this._update, this);
28+
},
29+
30+
_update: function () {
31+
if (!this._map || !S.playerList) return;
32+
33+
const size = this._map.getSize();
34+
this._canvas.width = size.x;
35+
this._canvas.height = size.y;
36+
this._canvas.style.width = size.x + "px";
37+
this._canvas.style.height = size.y + "px";
38+
39+
this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
40+
41+
// Fill entire canvas with dark overlay
42+
this._ctx.fillStyle = "rgba(0, 0, 0, 0.85)";
43+
this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);
44+
45+
// Clear circles around each player (flashlight effect)
46+
this._ctx.globalCompositeOperation = "destination-out";
47+
48+
const radius = 80; // pixels - adjust for flashlight size
49+
50+
if (S.playerList.markers) {
51+
S.playerList.markers.forEach((marker, uuid) => {
52+
const player = S.playerList.players.get(uuid);
53+
if (!player) return;
54+
55+
const pos = this._map.latLngToContainerPoint(marker.getLatLng());
56+
57+
// Create radial gradient for soft edge
58+
const gradient = this._ctx.createRadialGradient(pos.x, pos.y, radius * 0.3, pos.x, pos.y, radius);
59+
gradient.addColorStop(0, "rgba(0, 0, 0, 1)");
60+
gradient.addColorStop(1, "rgba(0, 0, 0, 0)");
61+
62+
this._ctx.fillStyle = gradient;
63+
this._ctx.beginPath();
64+
this._ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);
65+
this._ctx.fill();
66+
});
67+
}
68+
69+
this._ctx.globalCompositeOperation = "source-over";
70+
},
71+
});
72+
73+
export function fogOfWar() {
74+
return new FogOfWar();
75+
}

web/src/js/Squaremap.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { WorldList } from "./WorldList.js";
44
import { UICoordinates } from "./UICoordinates.js";
55
import { UILink } from "./UILink.js";
66
import { LayerControl } from "./LayerControl.js";
7+
import { FogOfWar } from "./FogOfWar.js";
78
import L from "leaflet";
89
import "./addons/Ellipse.js";
910
import "./addons/RotateMarker.js";
@@ -33,6 +34,8 @@ class SquaremapMap {
3334
tick_count;
3435
/** @type {boolean} */
3536
showControls;
37+
/** @type {FogOfWar} */
38+
fogOfWar;
3639

3740
constructor() {
3841
this.map = L.map("map", {
@@ -58,6 +61,8 @@ class SquaremapMap {
5861
this.tick_count = 1;
5962

6063
this.layerControl = new LayerControl();
64+
this.fogOfWar = new FogOfWar();
65+
this.fogOfWar.addTo(this.map);
6166

6267
this.init();
6368
}
@@ -73,6 +78,10 @@ class SquaremapMap {
7378
this.playerList.tick();
7479
// tick world
7580
this.worldList.curWorld.tick();
81+
// update fog of war
82+
if (this.fogOfWar) {
83+
this.fogOfWar._update();
84+
}
7685
}
7786
init() {
7887
this.getJSON(

0 commit comments

Comments
 (0)