Basic crops system
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { assert, assertEquals } from "@std/assert";
|
||||
import { bake_model, block_variant, BUILTIN_MODELS, type ModelJson, resolve_texture } from "$/common/block_models.ts";
|
||||
import { block_from_json } from "$/common/mod_data.ts";
|
||||
import { set_state_value } from "$/common/utils.ts";
|
||||
|
||||
const cube = BUILTIN_MODELS["engine:cube"];
|
||||
|
||||
Deno.test("cubes resolve the old texture shapes", () => {
|
||||
assertEquals(resolve_texture("#top", "a:all", cube), "a:all");
|
||||
const pillar = { top: "a:top", bottom: "a:bottom", side: "a:side" };
|
||||
assertEquals(["#top", "#bottom", "#front", "#side"].map((t) => resolve_texture(t, pillar, cube)), [
|
||||
"a:top",
|
||||
"a:bottom",
|
||||
"a:side",
|
||||
"a:side",
|
||||
]);
|
||||
const furnace = { front: "a:front", side: "a:side" };
|
||||
assertEquals(["#top", "#bottom", "#front"].map((t) => resolve_texture(t, furnace, cube)), [
|
||||
"a:side",
|
||||
"a:side",
|
||||
"a:front",
|
||||
]);
|
||||
assertEquals(resolve_texture("#nothing", { crop: "a:crop" }), "engine:missing");
|
||||
});
|
||||
|
||||
Deno.test("a cube bakes into six full faces that cull against their neighbors", () => {
|
||||
const quads = bake_model(cube, "a:all");
|
||||
assertEquals(quads.length, 6);
|
||||
assert(quads.every((q) => q.flush && q.cull === q.face && q.texture === "a:all"));
|
||||
// the top face, corners and uvs like the mesher always had
|
||||
assertEquals(quads[0].positions, [0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0]);
|
||||
assertEquals(quads[0].uvs, [0, 16, 16, 16, 16, 0, 0, 0]);
|
||||
});
|
||||
|
||||
Deno.test("crop and cross models are planes inside the block, seen from both sides", () => {
|
||||
const crop = bake_model(BUILTIN_MODELS["engine:crop"], { crop: "a:wheat" });
|
||||
assertEquals(crop.length, 8);
|
||||
assert(crop.every((q) => !q.flush && q.cull === -1 && !q.shade && q.texture === "a:wheat"));
|
||||
assertEquals(crop[0].positions.filter((_, i) => i % 3 === 0), [0.25, 0.25, 0.25, 0.25]);
|
||||
|
||||
const cross = bake_model(BUILTIN_MODELS["engine:cross"], { cross: "a:flower" });
|
||||
assertEquals(cross.length, 4);
|
||||
// rescaled so the diagonal planes stay as wide as the block, like minecraft's (0.8 to 15.2 pixels)
|
||||
for (const quad of cross) {
|
||||
for (const v of quad.positions) assert(v > -1e-6 && v < 1 + 1e-6, `${v} is outside the block`);
|
||||
}
|
||||
const xs = cross[0].positions.filter((_, i) => i % 3 === 0).map((v) => Math.round(v * 1000) / 1000);
|
||||
assertEquals(new Set(xs), new Set([0.05, 0.95]));
|
||||
});
|
||||
|
||||
Deno.test("turning a model moves its faces and cullfaces", () => {
|
||||
const model: ModelJson = {
|
||||
id: "a:half",
|
||||
elements: [{
|
||||
from: [0, 0, 0],
|
||||
to: [16, 16, 8],
|
||||
faces: { north: { texture: "a:x", cullface: "north" } },
|
||||
}],
|
||||
};
|
||||
const [north] = bake_model(model, undefined, 0);
|
||||
const [east] = bake_model(model, undefined, 90);
|
||||
assertEquals([north.face, north.cull], [3, 3]);
|
||||
assertEquals([east.face, east.cull], [5, 5]);
|
||||
assert(east.flush);
|
||||
});
|
||||
|
||||
Deno.test("variants pick textures by state", () => {
|
||||
const { block } = block_from_json(JSON.parse(Deno.readTextFileSync("mods/bworld/blocks/wheat.json")).block);
|
||||
assertEquals(block_variant(block, { age: 5 }).textures, { crop: "bworld:wheat_stage_5" });
|
||||
assertEquals(block_variant(block, { age: 5 }).model, "engine:crop");
|
||||
assertEquals(block_variant(block).textures, { crop: "bworld:wheat_stage_0" });
|
||||
// states live above the numeric id
|
||||
assertEquals(set_state_value(7, block, "age", 3), (3 << 16) | 7);
|
||||
});
|
||||
Reference in New Issue
Block a user