diff --git a/resources/flags/Sakhalin.svg b/resources/flags/Sakhalin.svg new file mode 100644 index 000000000..ff85f0646 --- /dev/null +++ b/resources/flags/Sakhalin.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/maps/Europe.json b/resources/maps/Europe.json index 2fdc5694f..33ff48987 100644 --- a/resources/maps/Europe.json +++ b/resources/maps/Europe.json @@ -187,7 +187,7 @@ "coordinates": [1254, 899], "name": "Slovak Republic", "strength": 3, - "flag": "SK" + "flag": "sk" }, { "coordinates": [1002, 1061], @@ -244,7 +244,7 @@ "flag": "gb-sct" }, { - "coordinates": [2239, 3215], + "coordinates": [2300, 510], "name": "USSR", "strength": 3, "flag": "ussr" @@ -259,7 +259,7 @@ "coordinates": [1522, 48], "name": "Polar Bears", "strength": 2, - "flag": "polar_bear" + "flag": "polar_bears" }, { "coordinates": [821, 628], @@ -280,7 +280,7 @@ "flag": "eg" }, { - "coordinates": [1188, 1612], + "coordinates": [1115, 1650], "name": "State of Libya", "strength": 1, "flag": "ly" @@ -289,13 +289,13 @@ "coordinates": [1919, 1608], "name": "Hashemite Kingdom of Jordan", "strength": 1, - "flag": "hu" + "flag": "jo" }, { "coordinates": [1898, 1535], "name": "Lebanese Republic", "strength": 1, - "flag": "hu" + "flag": "lb" } ] } diff --git a/resources/maps/GatewayToTheAtlantic.json b/resources/maps/GatewayToTheAtlantic.json index c36454b2a..0f90f7fb3 100644 --- a/resources/maps/GatewayToTheAtlantic.json +++ b/resources/maps/GatewayToTheAtlantic.json @@ -19,7 +19,7 @@ "coordinates": [1334, 537], "name": "Duchy of Aquitaine", "strength": 2, - "flag": "aquitane" + "flag": "aquitaine" }, { "coordinates": [2115, 684], @@ -31,7 +31,7 @@ "coordinates": [1207, 763], "name": "The Basque", "strength": 3, - "flag": "" + "flag": "es-pv" }, { "coordinates": [1281, 1142], @@ -49,7 +49,7 @@ "coordinates": [561, 764], "name": "Kingdom of Galicia", "strength": 2, - "flag": "galicia" + "flag": "es-ga" }, { "coordinates": [1004, 1436], @@ -115,13 +115,13 @@ "coordinates": [1755, 1130], "name": "The Old Ones", "strength": 3, - "flag": "nuragic" + "flag": "neuragic_empire" }, { "coordinates": [2097, 1670], - "name": "Jesuit Monks", + "name": "Tamazgha", "strength": 2, - "flag": "" + "flag": "Amazigh flag" }, { "coordinates": [979, 1013], @@ -151,7 +151,7 @@ "coordinates": [1017, 180], "name": "Kingdom of Brittany", "strength": 2, - "flag": "britanny" + "flag": "brittany" }, { "coordinates": [2072, 567], @@ -175,7 +175,7 @@ "coordinates": [1475, 1657], "name": "French Foreign Legion", "strength": 3, - "flag": "french_foreign_legion" + "flag": "French foreign legion" }, { "coordinates": [1685, 417], diff --git a/resources/maps/Japan.json b/resources/maps/Japan.json index 3f9ab541d..9f3c53bd9 100644 --- a/resources/maps/Japan.json +++ b/resources/maps/Japan.json @@ -4,7 +4,7 @@ "height": 1646, "nations": [ { - "coordinates": [1151, 709], + "coordinates": [1150, 660], "name": "Hokkaido", "strength": 1, "flag": "jp" @@ -31,7 +31,7 @@ "coordinates": [1162, 154], "name": "Sakhalin", "strength": 2, - "flag": "" + "flag": "Sakhalin" }, { "coordinates": [571, 1116], @@ -40,7 +40,7 @@ "flag": "jp" }, { - "coordinates": [8612, 1183], + "coordinates": [595, 1190], "name": "Shikoku", "strength": 2, "flag": "jp" diff --git a/resources/maps/Mars.json b/resources/maps/Mars.json index 342c707ec..c5d0a9f2d 100644 --- a/resources/maps/Mars.json +++ b/resources/maps/Mars.json @@ -13,7 +13,7 @@ "coordinates": [122, 750], "name": "USSR", "strength": 2, - "flag": "" + "flag": "ussr" }, { "coordinates": [1232, 735], diff --git a/resources/maps/NorthAmerica.json b/resources/maps/NorthAmerica.json index ac55c5ef6..ea8ee8494 100644 --- a/resources/maps/NorthAmerica.json +++ b/resources/maps/NorthAmerica.json @@ -4,37 +4,37 @@ "height": 1448, "nations": [ { - "coordinates": [1693, 1045], + "coordinates": [1625, 1040], "name": "Florida", "strength": 3, "flag": "Florida" }, { - "coordinates": [1001, 427], + "coordinates": [1010, 435], "name": "Canada", "strength": 2, "flag": "ca" }, { - "coordinates": [1364, 1179], + "coordinates": [1250, 1130], "name": "Mexico", "strength": 2, "flag": "mx" }, { - "coordinates": [1556, 1295], + "coordinates": [1460, 1275], "name": "Guatemala", "strength": 1, "flag": "gt" }, { - "coordinates": [1612, 1289], + "coordinates": [1530, 1290], "name": "Honduras", "strength": 1, "flag": "hn" }, { - "coordinates": [1642, 1348], + "coordinates": [1570, 1350], "name": "Nicaragua", "strength": 1, "flag": "ni" @@ -58,7 +58,7 @@ "flag": "ve" }, { - "coordinates": [1775, 1183], + "coordinates": [1725, 1180], "name": "Cuba", "strength": 1, "flag": "cu" @@ -94,7 +94,7 @@ "flag": "Georgia_US" }, { - "coordinates": [420, 1209], + "coordinates": [250, 1200], "name": "Hawaii", "strength": 1, "flag": "Hawaii" @@ -283,10 +283,10 @@ "coordinates": [1189, 240], "name": "Polar Bears", "strength": 3, - "flag": "polar_bear" + "flag": "polar_bears" }, { - "coordinates": [1480, 343], + "coordinates": [1480, 350], "name": "Frost Giants", "strength": 3, "flag": "frost_giant" diff --git a/resources/maps/SouthAmerica.json b/resources/maps/SouthAmerica.json index 36807cf01..ed56a9f8d 100644 --- a/resources/maps/SouthAmerica.json +++ b/resources/maps/SouthAmerica.json @@ -1,7 +1,7 @@ { "name": "Americas", "width": 1746, - "height": 2380, + "height": 2378, "nations": [ { "coordinates": [438, 58], @@ -94,7 +94,7 @@ "flag": "gf" }, { - "coordinates": [801, 242], + "coordinates": [800, 410], "name": "Guyana", "strength": 1, "flag": "gy" @@ -133,7 +133,7 @@ "coordinates": [1270, 1035], "name": "The Biggest Snakes", "strength": 3, - "flag": "" + "flag": "Aztec Empire" }, { "coordinates": [894, 693], diff --git a/src/client/Main.ts b/src/client/Main.ts index 2eb479cb5..af2a60788 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -203,8 +203,8 @@ class Client { logoutDiscordButton.hidden = true; return; } - // TODO: Update the page for logged in user loginDiscordButton.translationKey = "main.logged_in"; + loginDiscordButton.hidden = true; const { user, player } = userMeResponse; TerritoryModal.onUserMe(userMeResponse); }); diff --git a/src/client/UsernameInput.ts b/src/client/UsernameInput.ts index 1f699da06..c0cd900c9 100644 --- a/src/client/UsernameInput.ts +++ b/src/client/UsernameInput.ts @@ -47,7 +47,7 @@ export class UsernameInput extends LitElement { /> ${this.validationError ? html`
${this.validationError}
` diff --git a/src/client/graphics/GameRenderer.ts b/src/client/graphics/GameRenderer.ts index ad114234c..149706c8f 100644 --- a/src/client/graphics/GameRenderer.ts +++ b/src/client/graphics/GameRenderer.ts @@ -191,7 +191,7 @@ export function createRenderer( const layers: Layer[] = [ new TerrainLayer(game, transformHandler), - new TerritoryLayer(game, eventBus), + new TerritoryLayer(game, eventBus, transformHandler), structureLayer, new UnitLayer(game, eventBus, transformHandler), new FxLayer(game), diff --git a/src/client/graphics/layers/ControlPanel.ts b/src/client/graphics/layers/ControlPanel.ts index 19d2bd02c..9ce3cc7cf 100644 --- a/src/client/graphics/layers/ControlPanel.ts +++ b/src/client/graphics/layers/ControlPanel.ts @@ -16,13 +16,13 @@ export class ControlPanel extends LitElement implements Layer { public uiState: UIState; @state() - private attackRatio: number = 0.2; + private attackRatio: number = 0.3; @state() - private targetTroopRatio = 0.95; + private targetTroopRatio = 0.6; @state() - private currentTroopRatio = 0.95; + private currentTroopRatio = 0.6; @state() private _population: number; @@ -59,10 +59,10 @@ export class ControlPanel extends LitElement implements Layer { init() { this.attackRatio = Number( - localStorage.getItem("settings.attackRatio") ?? "0.2", + localStorage.getItem("settings.attackRatio") ?? "0.3", ); this.targetTroopRatio = Number( - localStorage.getItem("settings.troopRatio") ?? "0.95", + localStorage.getItem("settings.troopRatio") ?? "0.6", ); this.init_ = true; this.uiState.attackRatio = this.attackRatio; diff --git a/src/client/graphics/layers/NameLayer.ts b/src/client/graphics/layers/NameLayer.ts index 2f8c36a3d..0d56c76e4 100644 --- a/src/client/graphics/layers/NameLayer.ts +++ b/src/client/graphics/layers/NameLayer.ts @@ -218,10 +218,19 @@ export class NameLayer implements Layer { shieldDiv.style.display = "flex"; shieldDiv.style.alignItems = "center"; shieldDiv.style.gap = "0px"; - shieldDiv.innerHTML = ` - - 0 - `; + const shieldImg = document.createElement("img"); + shieldImg.src = this.shieldIconImage.src; + shieldImg.style.width = "16px"; + shieldImg.style.height = "16px"; + + const shieldSpan = document.createElement("span"); + shieldSpan.textContent = "0"; + shieldSpan.style.color = "black"; + shieldSpan.style.fontSize = "10px"; + shieldSpan.style.marginTop = "-2px"; + + shieldDiv.appendChild(shieldImg); + shieldDiv.appendChild(shieldSpan); element.appendChild(shieldDiv); // Start off invisible so it doesn't flash at 0,0 diff --git a/src/client/graphics/layers/TerritoryLayer.ts b/src/client/graphics/layers/TerritoryLayer.ts index 480b62997..dbb4f1d94 100644 --- a/src/client/graphics/layers/TerritoryLayer.ts +++ b/src/client/graphics/layers/TerritoryLayer.ts @@ -9,6 +9,7 @@ import { GameView, PlayerView } from "../../../core/game/GameView"; import { PseudoRandom } from "../../../core/PseudoRandom"; import { AlternateViewEvent, DragEvent } from "../../InputHandler"; import { PatternDecoder } from "../../TerritoryPatterns"; +import { TransformHandler } from "../TransformHandler"; import { Layer } from "./Layer"; export class TerritoryLayer implements Layer { @@ -33,7 +34,7 @@ export class TerritoryLayer implements Layer { private lastDragTime = 0; private nodrawDragDuration = 200; - private refreshRate = 10; + private refreshRate = 10; //refresh every 10ms private lastRefresh = 0; private lastFocusedPlayer: PlayerView | null = null; @@ -41,6 +42,7 @@ export class TerritoryLayer implements Layer { constructor( private game: GameView, private eventBus: EventBus, + private transformHandler: TransformHandler, ) { this.theme = game.config().theme(); } @@ -49,11 +51,10 @@ export class TerritoryLayer implements Layer { return true; } - paintPlayerBorder(player: PlayerView) { - player.borderTiles().then((playerBorderTiles) => { - playerBorderTiles.borderTiles.forEach((tile: TileRef) => { - this.paintTerritory(tile, true); // Immediately paint the tile instead of enqueueing - }); + async paintPlayerBorder(player: PlayerView) { + const tiles = await player.borderTiles(); + tiles.borderTiles.forEach((tile: TileRef) => { + this.paintTerritory(tile, true); // Immediately paint the tile instead of enqueueing }); } @@ -129,11 +130,7 @@ export class TerritoryLayer implements Layer { euclDistFN(centerTile, 9, true), )) { if (!this.game.hasOwner(tile)) { - this.paintHighlightCell( - new Cell(this.game.x(tile), this.game.y(tile)), - color, - 255, - ); + this.paintHighlightTile(tile, color, 255); } } } @@ -156,16 +153,16 @@ export class TerritoryLayer implements Layer { const context = this.canvas.getContext("2d"); if (context === null) throw new Error("2d context not supported"); this.context = context; + this.canvas.width = this.game.width(); + this.canvas.height = this.game.height(); this.imageData = this.context.getImageData( 0, 0, - this.game.width(), - this.game.height(), + this.canvas.width, + this.canvas.height, ); this.initImageData(); - this.canvas.width = this.game.width(); - this.canvas.height = this.game.height(); this.context.putImageData(this.imageData, 0, 0); // Add a second canvas for highlights @@ -200,7 +197,19 @@ export class TerritoryLayer implements Layer { ) { this.lastRefresh = now; this.renderTerritory(); - this.context.putImageData(this.imageData, 0, 0); + + const [topLeft, bottomRight] = this.transformHandler.screenBoundingRect(); + const vx0 = Math.max(0, topLeft.x); + const vy0 = Math.max(0, topLeft.y); + const vx1 = Math.min(this.game.width() - 1, bottomRight.x); + const vy1 = Math.min(this.game.height() - 1, bottomRight.y); + + const w = vx1 - vx0 + 1; + const h = vy1 - vy0 + 1; + + if (w > 0 && h > 0) { + this.context.putImageData(this.imageData, 0, 0, vx0, vy0, w, h); + } } if (this.alternativeView) { return; @@ -246,15 +255,10 @@ export class TerritoryLayer implements Layer { } if (!this.game.hasOwner(tile)) { if (this.game.hasFallout(tile)) { - this.paintCell( - this.game.x(tile), - this.game.y(tile), - this.theme.falloutColor(), - 150, - ); + this.paintTile(tile, this.theme.falloutColor(), 150); return; } - this.clearCell(new Cell(this.game.x(tile), this.game.y(tile))); + this.clearTile(tile); return; } const owner = this.game.owner(tile) as PlayerView; @@ -274,17 +278,12 @@ export class TerritoryLayer implements Layer { const lightTile = (x % 2 === 0 && y % 2 === 0) || (y % 2 === 1 && x % 2 === 1); const borderColor = lightTile ? borderColors.light : borderColors.dark; - this.paintCell(x, y, borderColor, 255); + this.paintTile(tile, borderColor, 255); } else { const useBorderColor = playerIsFocused ? this.theme.focusedBorderColor() : this.theme.borderColor(owner); - this.paintCell( - this.game.x(tile), - this.game.y(tile), - useBorderColor, - 255, - ); + this.paintTile(tile, useBorderColor, 255); } } else { const patternName = owner.pattern(); @@ -303,23 +302,21 @@ export class TerritoryLayer implements Layer { const decoder = new PatternDecoder(patternName ?? ""); const bit = decoder.isSet(x, y) ? 1 : 0; const colorToUse = bit ? baseColor.darken(0.2) : baseColor; - this.paintCell(x, y, colorToUse, 150); + this.paintTile(tile, colorToUse, 150); } } } - paintCell(x: number, y: number, color: Colord, alpha: number) { - const index = y * this.game.width() + x; - const offset = index * 4; + paintTile(tile: TileRef, color: Colord, alpha: number) { + const offset = tile * 4; this.imageData.data[offset] = color.rgba.r; this.imageData.data[offset + 1] = color.rgba.g; this.imageData.data[offset + 2] = color.rgba.b; this.imageData.data[offset + 3] = alpha; } - clearCell(cell: Cell) { - const index = cell.y * this.game.width() + cell.x; - const offset = index * 4; + clearTile(tile: TileRef) { + const offset = tile * 4; this.imageData.data[offset + 3] = 0; // Set alpha to 0 (fully transparent) } @@ -337,13 +334,17 @@ export class TerritoryLayer implements Layer { }); } - paintHighlightCell(cell: Cell, color: Colord, alpha: number) { - this.clearCell(cell); + paintHighlightTile(tile: TileRef, color: Colord, alpha: number) { + this.clearTile(tile); + const x = this.game.x(tile); + const y = this.game.y(tile); this.highlightContext.fillStyle = color.alpha(alpha / 255).toRgbString(); - this.highlightContext.fillRect(cell.x, cell.y, 1, 1); + this.highlightContext.fillRect(x, y, 1, 1); } - clearHighlightCell(cell: Cell) { - this.highlightContext.clearRect(cell.x, cell.y, 1, 1); + clearHighlightTile(tile: TileRef) { + const x = this.game.x(tile); + const y = this.game.y(tile); + this.highlightContext.clearRect(x, y, 1, 1); } } diff --git a/src/client/index.html b/src/client/index.html index 7110edf23..e7acb1a29 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -99,6 +99,11 @@ display: none; } } + + /* display:none if child has class parent-hidden since we can't use shadow DOM in Lit due to Tailwind */ + .component-hideable:has(> .parent-hidden) { + display: none; + } @@ -231,7 +236,9 @@ > - +
diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index a921ad34e..52ef90a7e 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -107,7 +107,7 @@ export class PlayerImpl implements Player { private readonly _team: Team | null, ) { this._name = sanitizeUsername(playerInfo.name); - this._targetTroopRatio = 95n; + this._targetTroopRatio = 60n; this._troops = toInt(startTroops); this._workers = 0n; this._gold = 0n;