Initial import
This commit is contained in:
commit
ab891a315c
773 changed files with 257255 additions and 0 deletions
145
src/mapEditorPopup/graphicsDocumentHelpers.ts
Normal file
145
src/mapEditorPopup/graphicsDocumentHelpers.ts
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
import {
|
||||
getSpriteRows,
|
||||
normalizeImageRecordForSave,
|
||||
normalizeImagesPayloadForSave,
|
||||
normalizeTileRecordForSave,
|
||||
type JsonObject,
|
||||
type JsonValue,
|
||||
} from "../editorCore";
|
||||
|
||||
export type GraphicRole = "tile" | "sprite" | "other";
|
||||
|
||||
export function normalizeGraphicRoles(value: unknown): string[] {
|
||||
if (!Array.isArray(value)) {
|
||||
return [];
|
||||
}
|
||||
return Array.from(new Set(
|
||||
value
|
||||
.map((entry) => String(entry || "").trim().toLowerCase())
|
||||
.filter((entry) => entry === "tile" || entry === "sprite"),
|
||||
));
|
||||
}
|
||||
|
||||
export function hydrateImageRecordRows(entry: JsonObject | null | undefined): JsonObject | null {
|
||||
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...entry,
|
||||
rows: getSpriteRows(entry),
|
||||
};
|
||||
}
|
||||
|
||||
export function getImageRecordFromPayload(
|
||||
imagesPayload: JsonObject | null | undefined,
|
||||
recordId: string,
|
||||
): JsonObject | null {
|
||||
const normalizedId = String(recordId || "").trim();
|
||||
if (!normalizedId) {
|
||||
return null;
|
||||
}
|
||||
const records = Array.isArray(imagesPayload?.images) ? imagesPayload.images : [];
|
||||
const matchedEntry = (records.find((entry) => (
|
||||
entry
|
||||
&& typeof entry === "object"
|
||||
&& !Array.isArray(entry)
|
||||
&& String((entry as JsonObject).id || "").trim() === normalizedId
|
||||
)) as JsonObject | undefined) || null;
|
||||
return hydrateImageRecordRows(matchedEntry);
|
||||
}
|
||||
|
||||
export function buildImageRecordFromTileRecord(
|
||||
record: JsonObject,
|
||||
existingRecord?: JsonObject | null,
|
||||
cloneValue: <T>(value: T) => T = structuredClone,
|
||||
): JsonObject {
|
||||
const existing = existingRecord && typeof existingRecord === "object" && !Array.isArray(existingRecord)
|
||||
? existingRecord
|
||||
: {};
|
||||
const existingRoles = normalizeGraphicRoles(existing.roles);
|
||||
return normalizeImageRecordForSave({
|
||||
...cloneValue(existing),
|
||||
id: String(record?.id || existing.id || "").trim(),
|
||||
name: String(record?.name || existing.name || "").trim(),
|
||||
description: String(record?.description || existing.description || "").trim(),
|
||||
width: Math.max(1, Number(record?.width) || Number(existing.width) || 16),
|
||||
height: Math.max(1, Number(record?.height) || Number(existing.height) || 16),
|
||||
pixelScale: Math.max(1, Number(record?.pixelScale) || Number(existing.pixelScale) || 1),
|
||||
opacity: Math.max(0, Math.min(1, Number(record?.opacity ?? existing.opacity ?? 1))),
|
||||
rows: Array.isArray(record?.rows)
|
||||
? record.rows.map((row) => String(row || ""))
|
||||
: getSpriteRows(existing),
|
||||
tags: cloneValue(record?.tags) || cloneValue(existing.tags) || [],
|
||||
roles: Array.from(new Set([...existingRoles, "tile"])),
|
||||
tileSymbol: String(record?.tileSymbol || record?.symbol || existing.tileSymbol || "").trim().charAt(0),
|
||||
});
|
||||
}
|
||||
|
||||
export function buildImageRecordFromSpriteRecord(
|
||||
record: JsonObject,
|
||||
graphicRole: GraphicRole,
|
||||
existingRecord?: JsonObject | null,
|
||||
cloneValue: <T>(value: T) => T = structuredClone,
|
||||
): JsonObject {
|
||||
const existing = existingRecord && typeof existingRecord === "object" && !Array.isArray(existingRecord)
|
||||
? existingRecord
|
||||
: {};
|
||||
const existingRoles = normalizeGraphicRoles(existing.roles);
|
||||
const wantsSpriteRole = graphicRole !== "other";
|
||||
const nextRoles = wantsSpriteRole
|
||||
? Array.from(new Set([...existingRoles, "sprite"]))
|
||||
: existingRoles.filter((entry) => entry !== "sprite");
|
||||
return normalizeImageRecordForSave({
|
||||
...cloneValue(existing),
|
||||
id: String(record?.id || existing.id || "").trim(),
|
||||
name: String(record?.name || existing.name || "").trim(),
|
||||
description: String(record?.description || existing.description || "").trim(),
|
||||
width: Math.max(1, Number(record?.width) || Number(existing.width) || 16),
|
||||
height: Math.max(1, Number(record?.height) || Number(existing.height) || 16),
|
||||
pixelScale: Math.max(1, Number(record?.pixelScale) || Number(existing.pixelScale) || 1),
|
||||
opacity: Math.max(0, Math.min(1, Number(record?.opacity ?? existing.opacity ?? 1))),
|
||||
rows: Array.isArray(record?.rows)
|
||||
? record.rows.map((row) => String(row || ""))
|
||||
: getSpriteRows(existing),
|
||||
tags: cloneValue(record?.tags) || cloneValue(existing.tags) || [],
|
||||
roles: nextRoles,
|
||||
tileSymbol: String(existing.tileSymbol || record?.tileSymbol || record?.symbol || "").trim().charAt(0),
|
||||
});
|
||||
}
|
||||
|
||||
export function normalizeImagesPayloadSnapshot(
|
||||
payload: JsonObject | null | undefined,
|
||||
cloneValue: <T>(value: T) => T = structuredClone,
|
||||
): JsonObject {
|
||||
const normalized = (normalizeImagesPayloadForSave(cloneValue(payload || { schemaVersion: 1, images: [] }) as JsonValue) as JsonObject) || {
|
||||
schemaVersion: 1,
|
||||
images: [],
|
||||
};
|
||||
const records = Array.isArray(normalized.images) ? normalized.images : [];
|
||||
return {
|
||||
...normalized,
|
||||
images: records.map((entry) => {
|
||||
const hydratedEntry = hydrateImageRecordRows(
|
||||
entry && typeof entry === "object" && !Array.isArray(entry)
|
||||
? entry as JsonObject
|
||||
: null,
|
||||
);
|
||||
return hydratedEntry || entry;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildTileRecordFromImageRecord(entry: JsonObject, cloneValue: <T>(value: T) => T = structuredClone): JsonObject {
|
||||
return normalizeTileRecordForSave({
|
||||
id: String(entry.id || "").trim(),
|
||||
symbol: String(entry.tileSymbol || entry.symbol || "").trim().charAt(0),
|
||||
name: String(entry.name || "").trim(),
|
||||
description: String(entry.description || "").trim(),
|
||||
width: Number(entry.width) || 16,
|
||||
height: Number(entry.height) || 16,
|
||||
pixelScale: Number(entry.pixelScale) || 1,
|
||||
opacity: Number(entry.opacity ?? 1),
|
||||
rows: getSpriteRows(entry),
|
||||
tags: cloneValue(entry.tags) || [],
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue