mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 22:43:36 +00:00
Merge branch 'main' into patterned-territory
This commit is contained in:
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 13 KiB |
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"coordinates": [122, 750],
|
||||
"name": "USSR",
|
||||
"strength": 2,
|
||||
"flag": ""
|
||||
"flag": "ussr"
|
||||
},
|
||||
{
|
||||
"coordinates": [1232, 735],
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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],
|
||||
|
||||
+1
-1
@@ -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);
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ export class UsernameInput extends LitElement {
|
||||
/>
|
||||
${this.validationError
|
||||
? html`<div
|
||||
class="absolute w-full mt-2 px-3 py-1 text-lg border rounded bg-white text-red-600 border-red-600 dark:bg-gray-700 dark:text-red-300 dark:border-red-300"
|
||||
class="absolute z-10 w-full mt-2 px-3 py-1 text-lg border rounded bg-white text-red-600 border-red-600 dark:bg-gray-700 dark:text-red-300 dark:border-red-300"
|
||||
>
|
||||
${this.validationError}
|
||||
</div>`
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -218,10 +218,19 @@ export class NameLayer implements Layer {
|
||||
shieldDiv.style.display = "flex";
|
||||
shieldDiv.style.alignItems = "center";
|
||||
shieldDiv.style.gap = "0px";
|
||||
shieldDiv.innerHTML = `
|
||||
<img src="${this.shieldIconImage.src}" style="width: 16px; height: 16px;" />
|
||||
<span style="color: black; font-size: 10px; margin-top: -2px;">0</span>
|
||||
`;
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Immediate execution to prevent FOUC -->
|
||||
@@ -231,7 +236,9 @@
|
||||
></button>
|
||||
</territory-patterns-modal>
|
||||
<username-input class="relative w-full"></username-input>
|
||||
<news-button class="w-[20%] md:w-[15%]"></news-button>
|
||||
<news-button
|
||||
class="w-[20%] md:w-[15%] component-hideable"
|
||||
></news-button>
|
||||
</div>
|
||||
<div></div>
|
||||
<div>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user