Fix: Address review on animated legendary camouflages

- Inline the camouflage preset lookup instead of a one-off `camouflagePreset` helper
- Move the `primitive` override into the `jsxTree` mergers, so `skinTree` takes plain mergers and falls back to `<primitive>` like the mesh and group defaults
This commit is contained in:
Mark Greene committed 2026-11-05 17:26:56 +13:00
1 parent 2150fb3758
commit fddf407cc0
5 files changed
+15 -22

No files matched your search

@@ -1,6 +1,5 @@
import {
CamouflageDefinitions,
camouflagePreset,
Sc2ReadStream,
type TankParameters,
} from "@blitzkit/core";
@@ -89,7 +88,10 @@ export abstract class ServerBlitzKitAPI2 extends ServerBlitzKitAPI1 {
);
const [nation, tankKey] = vehicle.split(":");
const preset = camouflagePreset(yamlEntry, nation, tankKey);
// some unique camos only set the preset for their one tank
const preset =
yamlEntry.preset ??
yamlEntry.override?.[nation]?.override?.[tankKey]?.preset;
let hasPreset = false;
if (preset !== undefined) {
@@ -12,15 +12,3 @@ export type CamouflagesYaml = Record<
>;
}
>;
// some unique camos only set the preset for their one tank
export function camouflagePreset(
camouflage: CamouflagesYaml[string],
nation: string,
tankKey: string,
) {
return (
camouflage.preset ??
camouflage.override?.[nation]?.override?.[tankKey]?.preset
);
}
@@ -30,6 +30,7 @@ export function jsxTree(
props: ComponentProps<"group">,
key: string,
) => ReactNode;
primitive?: (object3d: Object3D, key: string) => ReactNode;
},
): ReactNode {
if (node instanceof Mesh) {
@@ -1,4 +1,3 @@
import type { ReactNode } from "react";
import type { Material, Object3D } from "three";
import type { Skin } from "../../hooks/useSkin";
import { jsxTree } from "./jsxTree";
@@ -18,9 +17,7 @@ export function nameOf(object3d: Object3D): string {
export function skinTree(
node: Object3D,
skins: Skin[],
mergers: Mergers & {
primitive: (object: Object3D, key: string) => ReactNode;
},
mergers: NonNullable<Mergers>,
) {
const materials = new Map<string, Material>();
const states: Record<string, string | null> = {};
@@ -48,7 +45,7 @@ export function skinTree(
mesh(mesh, props, key) {
const material = materials.get((mesh.material as Material).name);
return mergers!.mesh!(
return mergers.mesh!(
mesh,
material ? { ...props, material } : props,
key,
@@ -60,7 +57,11 @@ export function skinTree(
{switchChildren(object3d) ?? props.children}
{skins.flatMap((skin) =>
(skin.parts.get(object3d.name) ?? []).map((part) =>
mergers.primitive(part, part.uuid),
mergers.primitive ? (
mergers.primitive(part, part.uuid)
) : (
<primitive key={part.uuid} object={part} />
),
),
)}
</group>
@@ -1,5 +1,4 @@
import {
camouflagePreset,
parseHierarchies,
Sc2ReadStream,
type CamouflagesXml,
@@ -74,7 +73,9 @@ export async function GET({ props }: APIContext<{ skin: number }>) {
include as { vehicle: { name: string } }
).vehicle.name.split(":");
const { customEntities } = camouflagesYaml[key];
const preset = camouflagePreset(camouflagesYaml[key], nation, tankKey);
const preset =
camouflagesYaml[key].preset ??
camouflagesYaml[key].override?.[nation]?.override?.[tankKey]?.preset;
const parameters = await vfs.yaml<TankParameters>(
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
);