This commit is contained in:
Aotumuri
2025-05-22 20:15:04 +09:00
parent b145f41de1
commit 18e35400a3
4 changed files with 48 additions and 97 deletions
+16 -64
View File
@@ -1,100 +1,52 @@
{ {
"patterns": { "patterns": {
"stripes_v": { "stripes_v": {
"tileWidth": 2, "patternBase64": "AQACAAIACKA="
"tileHeight": 2,
"scale": 8,
"patternBase64": "oA=="
}, },
"stripes_h": { "stripes_h": {
"tileWidth": 2, "patternBase64": "AQACAAIACMA="
"tileHeight": 2,
"scale": 8,
"patternBase64": "wA=="
}, },
"checkerboard": { "checkerboard": {
"tileWidth": 2, "patternBase64": "AQACAAIACJA="
"tileHeight": 2,
"scale": 8,
"patternBase64": "kA=="
}, },
"diagonal": { "diagonal": {
"tileWidth": 16, "patternBase64": "AQAQABAAAYAAQAAgABAACAAEAAIAAQAAgABAACAAEAAIAAQAAgAB"
"tileHeight": 16,
"scale": 1,
"patternBase64": "gABAACAAEAAIAAQAAgABAACAAEAAIAAQAAgABAACAAE="
}, },
"cross": { "cross": {
"tileWidth": 16, "patternBase64": "AQAQABAAAYABQAIgBBAICBAEIAJAAYABgAJABCAIEBAIIARAAoAB"
"tileHeight": 16,
"scale": 1,
"patternBase64": "gAFAAiAEEAgIEAQgAkABgAGAAkAEIAgQEAggBEACgAE="
}, },
"mini_cross": { "mini_cross": {
"tileWidth": 16, "patternBase64": "AQAQAAgAAcADMAwMMAPAA8AMMDAMwAM="
"tileHeight": 8,
"scale": 1,
"patternBase64": "wAMwDAwwA8ADwAwwMAzAAw=="
}, },
"horizontal_stripes": { "horizontal_stripes": {
"tileWidth": 16, "patternBase64": "AQAQABAAAf//AAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA"
"tileHeight": 16,
"scale": 1,
"patternBase64": "//8AAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAA="
}, },
"sparse_dots": { "sparse_dots": {
"tileWidth": 16, "patternBase64": "AQAQABAAAYCAAAAAAAAAAAAAAAAAAACAgAAAAAAAAAAAAAAAAAAA"
"tileHeight": 16,
"scale": 1,
"patternBase64": "gIAAAAAAAAAAAAAAAAAAAICAAAAAAAAAAAAAAAAAAAA="
}, },
"evan": { "evan": {
"tileWidth": 24, "patternBase64": "AQAYAAcABQAAAHkjEkEkmnEnlkDEknjEkgAAAA=="
"tileHeight": 7,
"scale": 5,
"patternBase64": "AAAAeSMSQSSacSeWQMSSeMSSAAAA"
}, },
"diagonal_stripe": { "diagonal_stripe": {
"tileWidth": 16, "patternBase64": "AQAQAAgAAYABQAIgBBAICBAEIAJAAYA="
"tileHeight": 8,
"scale": 1,
"patternBase64": "gAFAAiAEEAgIEAQgAkABgA=="
}, },
"mountain_ridge": { "mountain_ridge": {
"tileWidth": 16, "patternBase64": "AQAQAAgAAQAAGBg8PH5+//9+fjw8GBg="
"tileHeight": 8,
"scale": 1,
"patternBase64": "AAAYGDw8fn7//35+PDwYGA=="
}, },
"scattered_dots": { "scattered_dots": {
"tileWidth": 16, "patternBase64": "AQAQAAgAAQAAQAQAAAAAAAAAABAIAAA="
"tileHeight": 8,
"scale": 1,
"patternBase64": "AABABAAAAAAAAAAAEAgAAA=="
}, },
"circuit_board": { "circuit_board": {
"tileWidth": 16, "patternBase64": "AQAQAAgAAcPDw8MwMDAwDDAMMMPDw8M="
"tileHeight": 8,
"scale": 1,
"patternBase64": "w8PDwzAwMDAMMAwww8PDww=="
}, },
"vertical_bars": { "vertical_bars": {
"tileWidth": 16, "patternBase64": "AQAQAAgAAZJJkkmSSZJJkkmSSZJJkkk="
"tileHeight": 8,
"scale": 1,
"patternBase64": "kkmSSZJJkkmSSZJJkkmSSQ=="
}, },
".w.": { ".w.": {
"tileWidth": 16, "patternBase64": "AQAQAAgAAQAAAAAAAEACQYIiRHQuaBY="
"tileHeight": 8,
"scale": 1,
"patternBase64": "AAAAAAAAQAJBgiJEdC5oFg=="
}, },
"openfront": { "openfront": {
"tileWidth": 66, "patternBase64": "AQBCAAoABQAAAAAAAAAAAAAAAAAAAAABw4+RD54cRfCJEgZCBEiZECJEgVCBEiVECJ48TDx4iTECJAgRCBQiRECJAgRCBIiREBxA+RCBEcREAAAAAAAAAAAA"
"tileHeight": 10,
"scale": 5,
"patternBase64": "AAAAAAAAAAAAAAAAAAAAAAHDj5EPnhxF8IkSBkIESJkQIkSBUIESJUQInjxMPHiJMQIkCBEIFCJEQIkCBEIEiJEQHED5EIERxEQAAAAAAAAAAAA="
} }
} }
} }
+22 -7
View File
@@ -2,9 +2,9 @@ import { z } from "zod";
import rawTerritoryPatterns from "../../resources/territory_patterns.json"; import rawTerritoryPatterns from "../../resources/territory_patterns.json";
const PatternSchema = z.object({ const PatternSchema = z.object({
tileWidth: z.number(), tileWidth: z.number().optional(),
tileHeight: z.number(), tileHeight: z.number().optional(),
scale: z.number(), scale: z.number().optional(),
pattern: z.array(z.array(z.number())).optional(), pattern: z.array(z.array(z.number())).optional(),
patternBase64: z.string().optional(), patternBase64: z.string().optional(),
}); });
@@ -24,24 +24,39 @@ for (const [key, value] of Object.entries(territoryPatterns.patterns)) {
bytes[i] = byteString.charCodeAt(i); bytes[i] = byteString.charCodeAt(i);
} }
const version = bytes[0];
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);
const bits: number[] = []; const bits: number[] = [];
for (const byte of bytes) { for (const byte of data) {
for (let i = 7; i >= 0; i--) { for (let i = 7; i >= 0; i--) {
bits.push((byte >> i) & 1); bits.push((byte >> i) & 1);
} }
} }
const pattern: number[][] = []; const pattern: number[][] = [];
for (let y = 0; y < value.tileHeight; y++) { for (let y = 0; y < tileHeight; y++) {
const row: number[] = []; const row: number[] = [];
for (let x = 0; x < value.tileWidth; x++) { for (let x = 0; x < tileWidth; x++) {
const index = y * value.tileWidth + x; const index = y * tileWidth + x;
row.push(bits[index] ?? 0); row.push(bits[index] ?? 0);
} }
pattern.push(row); pattern.push(row);
} }
value.pattern = pattern; value.pattern = pattern;
value.tileWidth = tileWidth;
value.tileHeight = tileHeight;
value.scale = scale;
} }
} }
+4 -25
View File
@@ -48,27 +48,6 @@ export class territoryPatternsModal extends LitElement {
this.updatePreview(); this.updatePreview();
}); });
for (const [key, p] of Object.entries(territoryPatterns.patterns)) {
if (!p.pattern && p.patternBase64) {
const bytes = Uint8Array.from(atob(p.patternBase64), (c) =>
c.charCodeAt(0),
);
const bits = Array.from(bytes).flatMap((byte) =>
[...Array(8)].map((_, i) => (byte >> (7 - i)) & 1),
);
const pattern: number[][] = [];
for (let y = 0; y < p.tileHeight; y++) {
const row: number[] = [];
for (let x = 0; x < p.tileWidth; x++) {
const index = y * p.tileWidth + x;
row.push(bits[index] ?? 0);
}
pattern.push(row);
}
p.pattern = pattern;
}
}
this.setLockedPatterns(["evan"], { this.setLockedPatterns(["evan"], {
evan: "This pattern is locked because it is restricted.", evan: "This pattern is locked because it is restricted.",
}); });
@@ -133,8 +112,8 @@ export class territoryPatternsModal extends LitElement {
" "
> >
${(() => { ${(() => {
const cellCountX = pattern.tileWidth; const cellCountX = pattern.tileWidth ?? 1;
const cellCountY = pattern.tileHeight; const cellCountY = pattern.tileHeight ?? 1;
const cellSize = Math.floor( const cellSize = Math.floor(
this.buttonWidth / Math.max(cellCountX, cellCountY), this.buttonWidth / Math.max(cellCountX, cellCountY),
); );
@@ -200,8 +179,8 @@ export class territoryPatternsModal extends LitElement {
const fixedHeight = 48; const fixedHeight = 48;
const fixedWidth = 48; const fixedWidth = 48;
const cellCountX = pattern.tileWidth; const cellCountX = pattern.tileWidth ?? 1;
const cellCountY = pattern.tileHeight; const cellCountY = pattern.tileHeight ?? 1;
const cellSize = Math.min( const cellSize = Math.min(
fixedHeight / cellCountY, fixedHeight / cellCountY,
+6 -1
View File
@@ -301,7 +301,12 @@ export class TerritoryLayer implements Layer {
const baseColor = this.theme.territoryColor(owner); const baseColor = this.theme.territoryColor(owner);
const patternConfig = territoryPatterns.patterns[patternName]; const patternConfig = territoryPatterns.patterns[patternName];
const { tileWidth, tileHeight, scale, pattern } = patternConfig; const {
tileWidth = 1,
tileHeight = 1,
scale = 1,
pattern,
} = patternConfig;
const px = Math.floor(x / scale) % tileWidth; const px = Math.floor(x / scale) % tileWidth;
const py = Math.floor(y / scale) % tileHeight; const py = Math.floor(y / scale) % tileHeight;