fix: match Kinglet aircraft exactly
This commit is contained in:
@@ -36,6 +36,7 @@ type PointerEventLike = { pointerId?: number; clientX?: number; clientY?: number
|
||||
const scumMapLayerImages = { terrain: new URL("../assets/map/scum-map-terrain-4096.webp", import.meta.url).href, topo: new URL("../assets/map/scum-map-topo-4096.webp", import.meta.url).href, night: new URL("../assets/map/scum-map-night-4096.webp", import.meta.url).href, zones: new URL("../assets/map/scum-map-building-zones-4096.png", import.meta.url).href } as const;
|
||||
const scumMapBaseLayers: ReadonlyArray<readonly [ScumMapLayer, string]> = [["terrain", "地形"], ["topo", "等高线"], ["night", "夜间"]];
|
||||
const scumMapVehicleFilters: ReadonlyArray<readonly [MapVehicleFilter, string]> = [["all", "全部载具"], ["land", "陆地载具"], ["water", "水上载具"], ["air", "飞行类载具"], ["other", "其他载具"]];
|
||||
const scumFlightVehicleKeys = new Set(["kinglet_duster", "kinglet_mariner", "kinglet_scout"]);
|
||||
const scumCatalogKinds: ReadonlyArray<readonly [string, string]> = [["all", "全部"], ["item", "物品"], ["vehicle", "载具"], ["zombie", "丧尸"], ["animal", "动物"], ["armed-npc", "NPC"]];
|
||||
const scumCatalogPickLimit = 48;
|
||||
const scumMapSize = 4096;
|
||||
@@ -1408,14 +1409,16 @@ function positionOf(row: RecordMap | undefined): RecordMap | undefined { const n
|
||||
function hasCoordinates(row: RecordMap | undefined): row is RecordMap { return Boolean(row) && Number.isFinite(Number(field(row, "x", "locationX"))) && Number.isFinite(Number(field(row, "y", "locationY"))); }
|
||||
function layerOf(point: RecordMap): MapLayer { const value = textField(point, "layer", "subjectType", "type").toLowerCase(); if (value.includes("player") || value.includes("user")) return "players"; if (value.includes("vehicle")) return "vehicles"; if (value.includes("flag")) return "flags"; if (value.includes("region") || value.includes("zone") || value === "base") return "regions"; return "other"; }
|
||||
function layerLabel(layer: MapLayer): string { return layer === "players" ? "用户" : layer === "vehicles" ? "载具" : layer === "flags" ? "旗帜" : layer === "regions" ? "区域" : "其他"; }
|
||||
function mapVehicleCategory(point: RecordMap): MapVehicleFilter {
|
||||
export function mapVehicleCategory(point: RecordMap): MapVehicleFilter {
|
||||
const entry = scumVehicleEntry(textField(point, "className", "vehicleClass", "entityClass", "vehicleType", "name", "label"));
|
||||
const value = [textField(point, "vehicleType", "className", "vehicleClass", "entityClass", "name", "label"), entry?.code || "", entry?.name || ""].join(" ").toLowerCase();
|
||||
if (/kinglet|duster|mariner|scout|aircraft|airplane|aeroplane|helicopter|plane|flight|飞行/.test(value)) return "air";
|
||||
const values = [textField(point, "vehicleType", "className", "vehicleClass", "entityClass", "name", "label"), entry?.code || "", entry?.name || ""];
|
||||
if (values.some((value) => scumFlightVehicleKeys.has(mapVehicleKey(value)))) return "air";
|
||||
const value = values.join(" ").toLowerCase();
|
||||
if (/boat|dinghy|raft|motorboat|barba|sup|water|船|水上/.test(value)) return "water";
|
||||
if (/bike|bicycle|motorcycle|sidecar|cruiser|laika|rager|ris|wolfswagen|tractor|pickup|suv|quad|sportbike|wheelbarrow|car|land|陆地/.test(value)) return "land";
|
||||
return "other";
|
||||
}
|
||||
function mapVehicleKey(value: string): string { return normalizedVehicleClass(value.replace(/^#spawnvehicle\s+/i, "")).replace(/^(?:bpc_|bp_)/i, "").replace(/[^a-z0-9]+/gi, "_").replace(/^_+|_+$/g, "").toLowerCase(); }
|
||||
function pointTitle(point: RecordMap): string { return textField(point, "displayName", "name", "label", "subjectName") || textField(point, "subjectType", "type") || textField(point, "subjectId", "id") || "地图点"; }
|
||||
function mapPointIdentity(point: RecordMap): string { const subject = textField(point, "subjectId", "gamePlayerId", "vehicleId", "flagId", "regionId"); if (subject) return `${layerOf(point)}:${subject}`; const record = textField(point, "id", "_recordKey"); if (record) return `${layerOf(point)}:${record}`; return `${layerOf(point)}:${pointTitle(point).toLowerCase()}:${numField(point, "x", "locationX")}:${numField(point, "y", "locationY")}`; }
|
||||
export function mapScenePoint(point: RecordMap, bounds: RecordMap): { x: number; y: number } {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { fileURLToPath } from "node:url";
|
||||
|
||||
import { migrateConfigurationRecord, migrateGiftGrantRecord, migratePlayerProfileRecord, migratePlayerRecord, migrateStatePatchRecord, migrateTrajectoryHistoryRecord, migrateTrajectoryRecord, migrationStatus } from "../examples/scum-server-plugin/features/migration.js";
|
||||
import { createGiftDelivery, deleteGiftDefinition, loadSCUMSurface, parseGiftCommands, parseGiftItems, queueGiftDelivery, resetGiftClaim, resetPendingGift, resolveMapBounds, saveEventProduce, saveGiftDefinition, saveMapSettings, scumCollections, startEvent, type RecordMap, type SCUMSurfaceData, type SCUMWorkspaceActions } from "../examples/scum-server-plugin/features/page-data.js";
|
||||
import { advanceMapPlayback, bundledVehicleImageUrl, collectMapPoints, mapPointStyle, playbackStartView, playbackFollowView } from "../examples/scum-server-plugin/features/page.js";
|
||||
import { advanceMapPlayback, bundledVehicleImageUrl, collectMapPoints, mapPointStyle, mapVehicleCategory, playbackStartView, playbackFollowView } from "../examples/scum-server-plugin/features/page.js";
|
||||
import type { MapTrack, MapTrackPoint } from "../examples/scum-server-plugin/features/contracts.js";
|
||||
import { renderPluginPage } from "../examples/scum-server-plugin/page-bundle/index.js";
|
||||
import { configurationCatalog, validateConfigPatch, validateStatePatch, validateVehicleSpawn, vehicleSpawnCatalog } from "../examples/scum-server-plugin/features/schemas.js";
|
||||
@@ -346,6 +346,14 @@ describe("SCUM plugin feature module", () => {
|
||||
expect(view.texts).toContain("Mira · 4 点");
|
||||
});
|
||||
|
||||
it("recognizes only the three Kinglet aircraft names in the flight filter", () => {
|
||||
expect(mapVehicleCategory({ className: "Kinglet_Duster_ES" })).toBe("air");
|
||||
expect(mapVehicleCategory({ className: "BPC_Kinglet_Mariner_C" })).toBe("air");
|
||||
expect(mapVehicleCategory({ label: "Kinglet Scout" })).toBe("air");
|
||||
expect(mapVehicleCategory({ className: "BPC_Laika_C" })).not.toBe("air");
|
||||
expect(mapVehicleCategory({ className: "Scout_ES" })).not.toBe("air");
|
||||
});
|
||||
|
||||
it("keeps the extracted icon catalog closed until an editor asks for it", () => {
|
||||
const gifts = renderAndCollect({ pageKey: "gifts", pageTitle: "礼包管理" });
|
||||
expect(gifts.texts).not.toContain("从 SCUM 目录选择礼包物品");
|
||||
|
||||
Reference in New Issue
Block a user