mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 03:53:49 +00:00
fix 'w'
This commit is contained in:
@@ -2,13 +2,7 @@ import { z } from "zod";
|
||||
import rawTerritoryPatterns from "../../resources/territory_patterns.json";
|
||||
|
||||
const PatternSchema = z.object({
|
||||
tileWidth: z.number().optional(),
|
||||
tileHeight: z.number().optional(),
|
||||
scale: z.number().optional(),
|
||||
patternBase64: z.string().optional(),
|
||||
patternData: z
|
||||
.custom<Uint8Array>((val) => val instanceof Uint8Array)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
const TerritoryPatternsSchema = z.object({
|
||||
@@ -18,13 +12,14 @@ const TerritoryPatternsSchema = z.object({
|
||||
export const territoryPatterns =
|
||||
TerritoryPatternsSchema.parse(rawTerritoryPatterns);
|
||||
|
||||
class PatternDecoder {
|
||||
static decodeBase64Pattern(base64: string): {
|
||||
data: Uint8Array;
|
||||
tileWidth: number;
|
||||
tileHeight: number;
|
||||
scale: number;
|
||||
} {
|
||||
export class PatternDecoder {
|
||||
private bytes: Uint8Array;
|
||||
private tileWidth: number;
|
||||
private tileHeight: number;
|
||||
private scale: number;
|
||||
private dataStart: number;
|
||||
|
||||
constructor(base64: string) {
|
||||
const byteString = atob(base64);
|
||||
const bytes = new Uint8Array(byteString.length);
|
||||
for (let i = 0; i < byteString.length; i++) {
|
||||
@@ -35,28 +30,38 @@ class PatternDecoder {
|
||||
if (version !== 1) {
|
||||
throw new Error("The pattern versions are different.");
|
||||
}
|
||||
const tileWidth = (bytes[1] << 8) | bytes[2];
|
||||
const tileHeight = (bytes[3] << 8) | bytes[4];
|
||||
const scale = (bytes[5] << 8) | bytes[6];
|
||||
|
||||
const totalBits = tileWidth * tileHeight;
|
||||
const totalBytes = Math.ceil(totalBits / 8);
|
||||
const data = bytes.slice(7, 7 + totalBytes);
|
||||
console.log("data", data);
|
||||
|
||||
return { data, tileWidth, tileHeight, scale };
|
||||
this.tileWidth = (bytes[1] << 8) | bytes[2];
|
||||
this.tileHeight = (bytes[3] << 8) | bytes[4];
|
||||
this.scale = (bytes[5] << 8) | bytes[6];
|
||||
this.dataStart = 7;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
}
|
||||
|
||||
export function initTerritoryPatterns(): void {
|
||||
for (const [key, value] of Object.entries(territoryPatterns.patterns)) {
|
||||
if (value.patternBase64) {
|
||||
const decoded = PatternDecoder.decodeBase64Pattern(value.patternBase64);
|
||||
value.patternData = decoded.data;
|
||||
value.tileWidth = decoded.tileWidth;
|
||||
value.tileHeight = decoded.tileHeight;
|
||||
value.scale = decoded.scale;
|
||||
}
|
||||
getTileWidth(): number {
|
||||
return this.tileWidth;
|
||||
}
|
||||
|
||||
getTileHeight(): number {
|
||||
return this.tileHeight;
|
||||
}
|
||||
|
||||
getScale(): number {
|
||||
return this.scale;
|
||||
}
|
||||
|
||||
isSet(x: number, y: number): boolean {
|
||||
const px =
|
||||
((Math.floor(x / this.scale) % this.tileWidth) + this.tileWidth) %
|
||||
this.tileWidth;
|
||||
const py =
|
||||
((Math.floor(y / this.scale) % this.tileHeight) + this.tileHeight) %
|
||||
this.tileHeight;
|
||||
const idx = py * this.tileWidth + px;
|
||||
const byteIndex = Math.floor(idx / 8);
|
||||
const bitIndex = 7 - (idx % 8);
|
||||
const byte = this.bytes[this.dataStart + byteIndex] ?? 0;
|
||||
return (byte & (1 << bitIndex)) !== 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { customElement, query, state } from "lit/decorators.js";
|
||||
import "./components/Difficulties";
|
||||
import "./components/Maps";
|
||||
import {
|
||||
initTerritoryPatterns,
|
||||
PatternDecoder,
|
||||
territoryPatterns,
|
||||
TerritoryPatternStorage,
|
||||
} from "./TerritoryPatterns";
|
||||
@@ -50,8 +50,6 @@ export class territoryPatternsModal extends LitElement {
|
||||
this.updatePreview();
|
||||
});
|
||||
|
||||
initTerritoryPatterns();
|
||||
|
||||
this.setLockedPatterns(["evan"], {
|
||||
evan: "This pattern is locked because it is restricted.",
|
||||
});
|
||||
@@ -116,8 +114,9 @@ export class territoryPatternsModal extends LitElement {
|
||||
"
|
||||
>
|
||||
${(() => {
|
||||
const cellCountX = pattern.tileWidth ?? 1;
|
||||
const cellCountY = pattern.tileHeight ?? 1;
|
||||
const decoder = new PatternDecoder(pattern.patternBase64!);
|
||||
const cellCountX = decoder.getTileWidth();
|
||||
const cellCountY = decoder.getTileHeight();
|
||||
const cellSize = Math.floor(
|
||||
this.buttonWidth / Math.max(cellCountX, cellCountY),
|
||||
);
|
||||
@@ -135,26 +134,25 @@ export class territoryPatternsModal extends LitElement {
|
||||
>
|
||||
${(() => {
|
||||
const tiles: TemplateResult[] = [];
|
||||
const total = cellCountX * cellCountY;
|
||||
for (let i = 0; i < total; i++) {
|
||||
const byteIndex = Math.floor(i / 8);
|
||||
const bitIndex = 7 - (i % 8);
|
||||
const bit =
|
||||
(pattern.patternData?.[byteIndex] ?? 0) &
|
||||
(1 << bitIndex);
|
||||
tiles.push(html`
|
||||
<div
|
||||
style="
|
||||
background-color: ${bit
|
||||
? "#000"
|
||||
: "transparent"};
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
width: ${cellSize}px;
|
||||
height: ${cellSize}px;
|
||||
border-radius: 1px;
|
||||
"
|
||||
></div>
|
||||
`);
|
||||
for (let py = 0; py < cellCountY; py++) {
|
||||
for (let px = 0; px < cellCountX; px++) {
|
||||
const x = px * decoder.getScale();
|
||||
const y = py * decoder.getScale();
|
||||
const bit = decoder.isSet(x, y);
|
||||
tiles.push(html`
|
||||
<div
|
||||
style="
|
||||
background-color: ${bit
|
||||
? "#000"
|
||||
: "transparent"};
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
width: ${cellSize}px;
|
||||
height: ${cellSize}px;
|
||||
border-radius: 1px;
|
||||
"
|
||||
></div>
|
||||
`);
|
||||
}
|
||||
}
|
||||
return tiles;
|
||||
})()}
|
||||
@@ -193,8 +191,9 @@ export class territoryPatternsModal extends LitElement {
|
||||
|
||||
const fixedHeight = 48;
|
||||
const fixedWidth = 48;
|
||||
const cellCountX = pattern.tileWidth ?? 1;
|
||||
const cellCountY = pattern.tileHeight ?? 1;
|
||||
const decoder = new PatternDecoder(pattern.patternBase64!);
|
||||
const cellCountX = decoder.getTileWidth();
|
||||
const cellCountY = decoder.getTileHeight();
|
||||
|
||||
const cellSize = Math.min(
|
||||
fixedHeight / cellCountY,
|
||||
@@ -228,23 +227,23 @@ export class territoryPatternsModal extends LitElement {
|
||||
>
|
||||
${(() => {
|
||||
const tiles: TemplateResult[] = [];
|
||||
const total = cellCountX * cellCountY;
|
||||
for (let i = 0; i < total; i++) {
|
||||
const byteIndex = Math.floor(i / 8);
|
||||
const bitIndex = 7 - (i % 8);
|
||||
const bit =
|
||||
(pattern.patternData?.[byteIndex] ?? 0) & (1 << bitIndex);
|
||||
tiles.push(html`
|
||||
<div
|
||||
style="
|
||||
background-color: ${bit ? "#000" : "transparent"};
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
width: ${cellSize}px;
|
||||
height: ${cellSize}px;
|
||||
border-radius: 1px;
|
||||
"
|
||||
></div>
|
||||
`);
|
||||
for (let py = 0; py < cellCountY; py++) {
|
||||
for (let px = 0; px < cellCountX; px++) {
|
||||
const x = px * decoder.getScale();
|
||||
const y = py * decoder.getScale();
|
||||
const bit = decoder.isSet(x, y);
|
||||
tiles.push(html`
|
||||
<div
|
||||
style="
|
||||
background-color: ${bit ? "#000" : "transparent"};
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
width: ${cellSize}px;
|
||||
height: ${cellSize}px;
|
||||
border-radius: 1px;
|
||||
"
|
||||
></div>
|
||||
`);
|
||||
}
|
||||
}
|
||||
return tiles;
|
||||
})()}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { GameUpdateType } from "../../../core/game/GameUpdates";
|
||||
import { GameView, PlayerView } from "../../../core/game/GameView";
|
||||
import { PseudoRandom } from "../../../core/PseudoRandom";
|
||||
import { AlternateViewEvent, DragEvent } from "../../InputHandler";
|
||||
import { territoryPatterns } from "../../TerritoryPatterns";
|
||||
import { PatternDecoder, territoryPatterns } from "../../TerritoryPatterns";
|
||||
import { Layer } from "./Layer";
|
||||
|
||||
export class TerritoryLayer implements Layer {
|
||||
@@ -301,22 +301,8 @@ export class TerritoryLayer implements Layer {
|
||||
const baseColor = this.theme.territoryColor(owner);
|
||||
const patternConfig = territoryPatterns.patterns[patternName];
|
||||
|
||||
const {
|
||||
tileWidth = 1,
|
||||
tileHeight = 1,
|
||||
scale = 1,
|
||||
patternData,
|
||||
} = patternConfig;
|
||||
|
||||
const px =
|
||||
((Math.floor(x / scale) % tileWidth) + tileWidth) % tileWidth;
|
||||
const py =
|
||||
((Math.floor(y / scale) % tileHeight) + tileHeight) % tileHeight;
|
||||
|
||||
const bitIndex = py * tileWidth + px;
|
||||
const byte = patternData?.[Math.floor(bitIndex / 8)] ?? 0;
|
||||
const bit = (byte >> (7 - (bitIndex % 8))) & 1;
|
||||
|
||||
const decoder = new PatternDecoder(patternConfig.patternBase64 ?? "");
|
||||
const bit = decoder.isSet(x, y) ? 1 : 0;
|
||||
const colorToUse = bit ? baseColor.darken(0.2) : baseColor;
|
||||
this.paintCell(x, y, colorToUse, 150);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user