feat: Figurenauswahl, Autos, Debug-Panel und Namensnennung
Task 11: Figuren (Mannequin/Superhero Male/Female) mit auf ual.glb retargeteten Animationen, Frisuren, vier SUVs auf angehefteten Chunks, ein lil-gui-Debug-Panel (Figur/Frisur/Höhe/Hitbox/Chunk-Grenzen/ Kartenbild/Nebel/Wahrzeichen-Sprung) und die verpflichtende Namensnennung fürs HUD (Kartenkacheln, Wahrzeichen, SUV, Texturen, Palme, Figuren — jede Quelle mit ihrer eigenen Lizenz). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
02d0f36580
commit
d30aae68a1
42 files changed
+13143
-4
No files matched your search
+27
-2
@@ -36,7 +36,7 @@ const emptyChunk = { chunk: [4, 6], origin: [0, -1000], land: [], surfaces: [],
|
||||
// Zentrum von Chunk 4_6 in three-Koordinaten: SLICE.x0 + 4.5*CHUNK_SIZE, -(SLICE.y1 - 6.5*CHUNK_SIZE).
|
||||
const emptyChunkCenter = { x: 125, z: -875 };
|
||||
|
||||
function makeStreamer(chunkData, props) {
|
||||
function makeStreamer(chunkData, props, pinned) {
|
||||
vi.stubGlobal("fetch", vi.fn(async () => ({ ok: true, json: async () => chunkData })));
|
||||
const player = {
|
||||
addCollider: vi.fn(() => ({ id: 42 })),
|
||||
@@ -47,7 +47,7 @@ function makeStreamer(chunkData, props) {
|
||||
collisionWorld: { get: vi.fn(() => ({ ready: false })) },
|
||||
};
|
||||
const scene = { add: vi.fn(), remove: vi.fn() };
|
||||
return { streamer: new ChunkStreamer({ scene, player, materials: {}, props }), player, scene };
|
||||
return { streamer: new ChunkStreamer({ scene, player, materials: {}, props, pinned }), player, scene };
|
||||
}
|
||||
|
||||
// #load() ist privat und läuft nebenläufig; zwei Mikrotask-Runden reichen, um
|
||||
@@ -127,6 +127,31 @@ describe("ChunkStreamer", () => {
|
||||
expect(ownDispose).toHaveBeenCalledTimes(1);
|
||||
expect(sharedDispose).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Task 11, Schritt 5: die vier Fahrzeug-Chunks werden festgehalten, weil ein Fahrzeug
|
||||
// ohne Boden ins Nichts fällt — #unload muss sie überspringen, statt sie beim
|
||||
// gewöhnlichen Entfernen-jenseits-des-Radius-Durchlauf trotzdem abzubauen. Mit echter
|
||||
// Landgeometrie (nicht emptyChunk), damit ein echtes Collider-Handle entsteht und die
|
||||
// removeCollider-Zusicherung unten etwas prüft, statt nach Ruling 51 trivial wahr zu sein.
|
||||
it("entlädt einen angehefteten Chunk nicht, auch jenseits des Entladeradius (Task 11)", async () => {
|
||||
const landChunk = {
|
||||
chunk: [4, 6], origin: [0, -1000],
|
||||
land: [[[[0, 0], [50, 0], [50, 50], [0, 50]]]],
|
||||
surfaces: [], roads: [], buildings: [],
|
||||
};
|
||||
const { streamer, player } = makeStreamer(landChunk, undefined, ["4_6"]);
|
||||
streamer.update(emptyChunkCenter);
|
||||
await flush();
|
||||
expect(streamer.active.has("4_6")).toBe(true);
|
||||
expect(player.addCollider).toHaveBeenCalledTimes(1); // sonst prüft removeCollider unten nichts
|
||||
|
||||
// Weit weg -> jenseits des Entladeradius (600); ohne pinned wäre "4_6" nun weg
|
||||
// (siehe Test oben, gleiches Setup ohne pinned).
|
||||
streamer.update({ x: emptyChunkCenter.x + 5000, z: emptyChunkCenter.z });
|
||||
|
||||
expect(streamer.active.has("4_6")).toBe(true);
|
||||
expect(player.removeCollider).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
// Fix-Runde 2, Befund C / Ruling 64: der Zweig `if (this.props)` in #load hatte keine
|
||||
|
||||
Reference in new issue
Block a user