diff --git a/assets/sprites/textures/copper_ingot.png b/assets/sprites/textures/copper_ingot.png new file mode 100644 index 0000000..649df0e Binary files /dev/null and b/assets/sprites/textures/copper_ingot.png differ diff --git a/assets/sprites/textures/gold_ingot.png b/assets/sprites/textures/gold_ingot.png new file mode 100644 index 0000000..19ec1b2 Binary files /dev/null and b/assets/sprites/textures/gold_ingot.png differ diff --git a/assets/sprites/textures/iron_ingot.png b/assets/sprites/textures/iron_ingot.png new file mode 100644 index 0000000..1581159 Binary files /dev/null and b/assets/sprites/textures/iron_ingot.png differ diff --git a/assets/sprites/textures/tin_ingot.png b/assets/sprites/textures/tin_ingot.png new file mode 100644 index 0000000..3df3d7a Binary files /dev/null and b/assets/sprites/textures/tin_ingot.png differ diff --git a/client/blocks/coal_ore.ts b/client/blocks/coal_ore.ts new file mode 100644 index 0000000..ee8d5fc --- /dev/null +++ b/client/blocks/coal_ore.ts @@ -0,0 +1,11 @@ +import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts"; +import { register_block_item } from "$/common/utils.ts"; + +const block = EverythingRegistry.register("blocks", "bworld:coal_ore", { + id: "bworld:coal_ore", + textures: "bworld:stone_coal", + has_collision: true, + drop_table: "bworld:coal_ore", +}); + +register_block_item(block); diff --git a/client/blocks/copper_ore.ts b/client/blocks/copper_ore.ts new file mode 100644 index 0000000..ed6222e --- /dev/null +++ b/client/blocks/copper_ore.ts @@ -0,0 +1,11 @@ +import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts"; +import { register_block_item } from "$/common/utils.ts"; + +const block = EverythingRegistry.register("blocks", "bworld:copper_ore", { + id: "bworld:copper_ore", + textures: "bworld:stone_copper", + has_collision: true, + drop_table: "bworld:copper_ore", +}); + +register_block_item(block); diff --git a/client/blocks/furnace.ts b/client/blocks/furnace.ts index e106a95..8e6840e 100644 --- a/client/blocks/furnace.ts +++ b/client/blocks/furnace.ts @@ -4,61 +4,110 @@ import { PlayerComponent } from "../player.ts"; import { GuiFurnace } from "$/client/gui/gui_furnace.ts"; import { register_block_item } from "../../common/utils.ts"; -function can_craft(container: Container) { - const input = container.get_item(0); - const output = container.get_item(2); +interface FurnaceRecipe { + input: string; + output: ItemStack; + cook_time: number; +} +const FURNACE_RECIPES: FurnaceRecipe[] = [ + { + input: "bworld:log", + output: new ItemStack("bworld:coal", 1), + cook_time: 100, + }, + { + input: "bworld:coal_ore", + output: new ItemStack("bworld:coal", 1), + cook_time: 100, + }, + { + input: "bworld:iron_ore", + output: new ItemStack("bworld:iron_ingot", 1), + cook_time: 200, + }, + { + input: "bworld:tin_ore", + output: new ItemStack("bworld:tin_ingot", 1), + cook_time: 200, + }, + { + input: "bworld:copper_ore", + output: new ItemStack("bworld:copper_ingot", 1), + cook_time: 200, + }, + { + input: "bworld:gold_ore", + output: new ItemStack("bworld:gold_ingot", 1), + cook_time: 200, + }, +]; + +function get_recipe(input?: ItemStack | undefined): FurnaceRecipe | undefined { if (!input) { + return; + } + + return FURNACE_RECIPES.find((r) => r.input === input.type_id); +} + +function can_craft(container: Container, recipe?: FurnaceRecipe) { + if (!recipe) { return false; } - if (["bworld:log"].includes(input.type_id)) { - return true; - } + const output = container.get_item(2); if (!output) { return true; } - if (output.amount >= output.max_amount) { + if (output.type_id !== recipe.output.type_id) { return false; } - return true; + return output.amount < output.max_amount; +} + +const FUEL_VALUES: Record = { + "bworld:coal": 1000, + "bworld:log": 100, +}; + +function get_fuel_value(item?: ItemStack | undefined): number { + if (!item) { + return 0; + } + return FUEL_VALUES[item.type_id] ?? 0; } function has_fuel(container: Container) { - const fuel = container.get_item(1); - - if (!fuel) { - return false; - } - - if (["bworld:coal", "bworld:log"].includes(fuel.type_id)) { - return true; - } - - return false; + return get_fuel_value(container.get_item(1)) > 0; } -function consume_fuel(container: Container) { - const fuel = container.get_item(1)!; - fuel.amount -= 1; - container.set_item(1, fuel); +function consume_fuel(container: Container): number { + const fuel = container.get_slot(1)!; + const value = get_fuel_value(fuel.get_item()); + + if (fuel.has_item()) { + fuel.amount! -= 1; + } + + return value; } -function craft(container: Container, item: ItemStack) { +function craft(container: Container, recipe: FurnaceRecipe) { const input = container.get_item(0)!; const output = container.get_item(2); if (!output) { - container.set_item(2, item); + container.set_item(2, recipe.output.clone()); } else { - output.amount += item.amount; + output.amount += recipe.output.amount; } input.amount -= 1; - container.set_item(0, input); + container.set_item(0, input.amount > 0 ? input : undefined); } interface TileChestData { @@ -106,25 +155,34 @@ const block = EverythingRegistry.register("blocks", "bworld:furna return; } - if (block_data.data.fuel > 0) { - block_data.data.fuel -= 1; + const data = block_data.data; + const container = data.inventory.container; + + const input = container.get_item(0); + const recipe = get_recipe(input); + + // burn fuel + if (data.fuel > 0) { + data.fuel -= 1; } - const container = block_data.data.inventory.container; + if (!can_craft(container, recipe)) { + data.progress = 0; + return; + } - if (can_craft(container)) { - if (block_data.data.fuel === 0 && has_fuel(container)) { - consume_fuel(container); - block_data.data.fuel = 200; - } + // refuel + if (data.fuel === 0 && has_fuel(container)) { + data.fuel = consume_fuel(container); + } - if (block_data.data.fuel > 0) { - block_data.data.progress += 1; + // cook + if (data.fuel > 0 && recipe) { + data.progress += 1; - if (block_data.data.progress >= 100) { - block_data.data.progress = 0; - craft(container, new ItemStack("bworld:coal")); - } + if (data.progress >= recipe.cook_time) { + data.progress = 0; + craft(container, recipe); } } }, diff --git a/client/blocks/gold_ore.ts b/client/blocks/gold_ore.ts new file mode 100644 index 0000000..2ffa421 --- /dev/null +++ b/client/blocks/gold_ore.ts @@ -0,0 +1,11 @@ +import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts"; +import { register_block_item } from "$/common/utils.ts"; + +const block = EverythingRegistry.register("blocks", "bworld:gold_ore", { + id: "bworld:gold_ore", + textures: "bworld:stone_gold", + has_collision: true, + drop_table: "bworld:gold_ore", +}); + +register_block_item(block); diff --git a/client/blocks/iron_ore.ts b/client/blocks/iron_ore.ts new file mode 100644 index 0000000..501c710 --- /dev/null +++ b/client/blocks/iron_ore.ts @@ -0,0 +1,11 @@ +import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts"; +import { register_block_item } from "$/common/utils.ts"; + +const block = EverythingRegistry.register("blocks", "bworld:iron_ore", { + id: "bworld:iron_ore", + textures: "bworld:stone_iron", + has_collision: true, + drop_table: "bworld:iron_ore", +}); + +register_block_item(block); diff --git a/client/blocks/mod.ts b/client/blocks/mod.ts index d1d96f3..c657305 100644 --- a/client/blocks/mod.ts +++ b/client/blocks/mod.ts @@ -11,3 +11,8 @@ import "./snow.ts"; import "./glass.ts"; import "./hoed_dirt.ts"; import "./leaves.ts"; +import "./coal_ore.ts"; +import "./copper_ore.ts"; +import "./iron_ore.ts"; +import "./tin_ore.ts"; +import "./gold_ore.ts"; diff --git a/client/blocks/tin_ore.ts b/client/blocks/tin_ore.ts new file mode 100644 index 0000000..4b55813 --- /dev/null +++ b/client/blocks/tin_ore.ts @@ -0,0 +1,11 @@ +import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts"; +import { register_block_item } from "$/common/utils.ts"; + +const block = EverythingRegistry.register("blocks", "bworld:tin_ore", { + id: "bworld:tin_ore", + textures: "bworld:stone_tin", + has_collision: true, + drop_table: "bworld:tin_ore", +}); + +register_block_item(block); diff --git a/client/generation.ts b/client/generation.ts index 4ce33a0..04f0ec5 100644 --- a/client/generation.ts +++ b/client/generation.ts @@ -1,4 +1,4 @@ -import { Alea, create_noise_2d, NoiseFunction2D } from "@paulaboks/rng"; +import { Alea, create_noise_2d, create_noise_3d, NoiseFunction2D } from "@paulaboks/rng"; import { CHUNK_SIZE, Dimension } from "./components/dimension.ts"; type Biome = @@ -12,6 +12,22 @@ type Biome = | "savanna" | "swamp"; +type OreDef = { + id: string; + min_y: number; + max_y: number; + scale: number; + threshold: number; +}; + +const ORES: OreDef[] = [ + { id: "bworld:coal_ore", min_y: 20, max_y: 120, scale: 0.05, threshold: 0.55 }, + { id: "bworld:copper_ore", min_y: 10, max_y: 80, scale: 0.06, threshold: 0.6 }, + { id: "bworld:tin_ore", min_y: 5, max_y: 60, scale: 0.06, threshold: 0.62 }, + { id: "bworld:iron_ore", min_y: 5, max_y: 50, scale: 0.05, threshold: 0.65 }, + { id: "bworld:gold_ore", min_y: 0, max_y: 30, scale: 0.04, threshold: 0.7 }, +]; + function get_biome(temp: number, moisture: number): Biome { if (temp > 0.6) { if (moisture < -0.2) { @@ -118,13 +134,6 @@ function place_tree(dimension: Dimension, x: number, y: number, z: number, biome const trunk_block = "bworld:log"; const leaves_block = "bworld:leaves"; - // if (biome === "jungle") { - // trunkBlock = "bworld:jungle_log"; - // leavesBlock = "bworld:jungle_leaves"; - // } else if (biome === "taiga") { - // leavesBlock = "bworld:spruce_leaves"; - // } - for (let i = 0; i < height; i++) { dimension.add_block({ x, y: y + i, z, id: trunk_block }); } @@ -167,6 +176,7 @@ export function generate_chunk(dimension: Dimension, cx: number, cz: number, see const temp_noise = create_noise_2d(new Alea(seed + "_temp")); const moisture_noise = create_noise_2d(new Alea(seed + "_moisture")); const feature_noise = create_noise_2d(new Alea(seed + "_feature")); + const ore_noises = ORES.map((ore) => create_noise_3d(new Alea(seed + "_" + ore.id))); const biome_scale = 0.003; const terrain_scale = 0.01; @@ -190,6 +200,26 @@ export function generate_chunk(dimension: Dimension, cx: number, cz: number, see for (let y = 0; y <= height; y++) { let block = "bworld:stone"; + + if (y < height - 3) { + for (let i = 0; i < ORES.length; i++) { + const ore = ORES[i]; + + if (y >= ore.min_y && y <= ore.max_y) { + const noise = ore_noises[i]( + wx * ore.scale, + y * ore.scale, + wz * ore.scale, + ); + + if (noise > ore.threshold) { + block = ore.id; + break; + } + } + } + } + if (y === height) { block = surface_block; } else if (y > height - 4) { diff --git a/client/gui/gui_player_inventory.ts b/client/gui/gui_player_inventory.ts index 6ea4318..704acf6 100644 --- a/client/gui/gui_player_inventory.ts +++ b/client/gui/gui_player_inventory.ts @@ -29,6 +29,22 @@ const recipes: CraftingRecipe[] = [ ], result: new ItemStack("bworld:chest", 1), }, + { + width: 3, + height: 3, + pattern: [ + "bworld:stone", + "bworld:stone", + "bworld:stone", + "bworld:stone", + undefined, + "bworld:stone", + "bworld:stone", + "bworld:stone", + "bworld:stone", + ], + result: new ItemStack("bworld:furnace", 1), + }, ]; const PADDING = 10; diff --git a/client/items/axe.ts b/client/items/axe.ts new file mode 100644 index 0000000..987f26f --- /dev/null +++ b/client/items/axe.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:axe", { + texture_id: "bworld:axe", +}); diff --git a/client/items/coal.ts b/client/items/coal.ts new file mode 100644 index 0000000..58df625 --- /dev/null +++ b/client/items/coal.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:coal", { + texture_id: "bworld:coal", +}); diff --git a/client/items/copper_ingot.ts b/client/items/copper_ingot.ts new file mode 100644 index 0000000..45cab7d --- /dev/null +++ b/client/items/copper_ingot.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:copper_ingot", { + texture_id: "bworld:copper_ingot", +}); diff --git a/client/items/gold_ingot.ts b/client/items/gold_ingot.ts new file mode 100644 index 0000000..0a536e7 --- /dev/null +++ b/client/items/gold_ingot.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:gold_ingot", { + texture_id: "bworld:gold_ingot", +}); diff --git a/client/items/hoe.ts b/client/items/hoe.ts new file mode 100644 index 0000000..bd09204 --- /dev/null +++ b/client/items/hoe.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:hoe", { + texture_id: "bworld:hoe", +}); diff --git a/client/items/iron_ingot.ts b/client/items/iron_ingot.ts new file mode 100644 index 0000000..2d14006 --- /dev/null +++ b/client/items/iron_ingot.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:iron_ingot", { + texture_id: "bworld:iron_ingot", +}); diff --git a/client/items/mod.ts b/client/items/mod.ts index 3436f6a..fa632e3 100644 --- a/client/items/mod.ts +++ b/client/items/mod.ts @@ -1 +1,9 @@ import "./watering_can.ts"; +import "./axe.ts"; +import "./pickaxe.ts"; +import "./hoe.ts"; +import "./coal.ts"; +import "./tin_ingot.ts"; +import "./iron_ingot.ts"; +import "./copper_ingot.ts"; +import "./gold_ingot.ts"; diff --git a/client/items/pickaxe.ts b/client/items/pickaxe.ts new file mode 100644 index 0000000..29b3465 --- /dev/null +++ b/client/items/pickaxe.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:pickaxe", { + texture_id: "bworld:pickaxe", +}); diff --git a/client/items/tin_ingot.ts b/client/items/tin_ingot.ts new file mode 100644 index 0000000..0f5578e --- /dev/null +++ b/client/items/tin_ingot.ts @@ -0,0 +1,5 @@ +import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; + +EverythingRegistry.register("items", "bworld:tin_ingot", { + texture_id: "bworld:tin_ingot", +}); diff --git a/client/player.ts b/client/player.ts index 8596e7c..b221bf4 100644 --- a/client/player.ts +++ b/client/player.ts @@ -39,7 +39,6 @@ export function create_player(world: ClientWorld) { // player_inventory.container.add_item(new ItemStack("bworld:potato_seeds", 64)); // player_inventory.container.add_item(new ItemStack("bworld:pumpkin_seeds", 64)); // player_inventory.container.add_item(new ItemStack("bworld:carrot_seeds", 64)); - player_inventory.container.add_item(new ItemStack("bworld:furnace", 1)); player.add(new Camera()); player.add(new CollisionCuboid(0.55, 1.79, 0.55)); diff --git a/client/renderer/core.ts b/client/renderer/core.ts index a1d27ad..e38e18b 100644 --- a/client/renderer/core.ts +++ b/client/renderer/core.ts @@ -299,6 +299,35 @@ export function push_quad( push_vertex(dx, y2, 0, u0, v1, r, g, b, a); } +export function push_quad_vertices( + x0: number, + y0: number, + x1: number, + y1: number, + x2: number, + y2: number, + x3: number, + y3: number, + u0: number, + v0: number, + u1: number, + v1: number, + r = 1, + g = 1, + b = 1, + a = 1, +) { + // triangle 1 + push_vertex(x0, y0, 0, u0, v0, r, g, b, a); + push_vertex(x1, y1, 0, u1, v0, r, g, b, a); + push_vertex(x2, y2, 0, u1, v1, r, g, b, a); + + // triangle 2 + push_vertex(x0, y0, 0, u0, v0, r, g, b, a); + push_vertex(x2, y2, 0, u1, v1, r, g, b, a); + push_vertex(x3, y3, 0, u0, v1, r, g, b, a); +} + // internal function update_camera() { diff --git a/client/renderer/textures.ts b/client/renderer/textures.ts index 9f60f8d..f46898a 100644 --- a/client/renderer/textures.ts +++ b/client/renderer/textures.ts @@ -1,4 +1,4 @@ -import { flush_batch, get_current_texture, gl, push_quad, set_current_texture } from "./core.ts"; +import { flush_batch, get_current_texture, gl, push_quad, push_quad_vertices, set_current_texture } from "./core.ts"; import { Texture } from "./types.ts"; export function load_texture(image: HTMLImageElement): Texture { @@ -93,3 +93,64 @@ export function draw_texture_region( push_quad(dx, dy, dw, dh, u0, v0, u1, v1, r, g, b, a); } + +export function draw_texture_region_skewed( + texture: Texture, + sx: number, + sy: number, + sw: number, + sh: number, + points: [ + { x: number; y: number }, // top-left + { x: number; y: number }, // top-right + { x: number; y: number }, // bottom-right + { x: number; y: number }, // bottom-left + ], + r = 1, + g = 1, + b = 1, + a = 1, + flip_x = false, + flip_y = false, +) { + if (get_current_texture() !== texture.tex) { + flush_batch(); + set_current_texture(texture.tex); + } + + let u0 = sx / texture.width; + let v0 = sy / texture.height; + let u1 = (sx + sw) / texture.width; + let v1 = (sy + sh) / texture.height; + + if (flip_x) { + [u0, u1] = [u1, u0]; + } + if (flip_y) { + [v0, v1] = [v1, v0]; + } + + const p0 = points[0]; + const p1 = points[1]; + const p2 = points[2]; + const p3 = points[3]; + + push_quad_vertices( + p0.x, + p0.y, + p1.x, + p1.y, + p2.x, + p2.y, + p3.x, + p3.y, + u0, + v0, + u1, + v1, + r, + g, + b, + a, + ); +} diff --git a/client/systems/rendering/render_utils.ts b/client/systems/rendering/render_utils.ts index f8524a7..fcf8d80 100644 --- a/client/systems/rendering/render_utils.ts +++ b/client/systems/rendering/render_utils.ts @@ -1,8 +1,9 @@ -import { SLOT_SIZE } from "$/common/constants.ts"; +import { SLOT_SIZE, TEXTURE_SIZE } from "$/common/constants.ts"; import { get_sprite_region } from "$/common/utils.ts"; +import { BlockRegistry, EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts"; import { AssetManager } from "$/client/assets.ts"; import { ItemStack } from "../../inventory.ts"; -import { draw_text, draw_texture_region, Texture } from "$/client/renderer/mod.ts"; +import { draw_text, draw_texture_region, draw_texture_region_skewed, Texture } from "$/client/renderer/mod.ts"; export function draw_nine_slice( image: Texture, @@ -199,18 +200,18 @@ export function draw_nine_slice( } export function draw_item(item: ItemStack, x: number, y: number) { - const sprite_region = get_sprite_region(item.type_id); - draw_texture_region( - AssetManager.instance.get("bworld:textures"), - sprite_region.x * 16, - sprite_region.y * 16, - 16, - 16, - x + 3, - y + 3, - SLOT_SIZE - 6, - SLOT_SIZE - 6, - ); + const item_info = EverythingRegistry.get("items", item.type_id); + + if (!item_info) { + throw Error(`Didn't find item registry for '${item.type_id}'`); + } + + if (item_info?.block_id) { + draw_item_block(item, item_info, x, y); + } else { + draw_item_item(item, item_info, x, y); + } + if (item.max_amount !== 1) { draw_text( String(item.amount), @@ -227,3 +228,107 @@ export function draw_item(item: ItemStack, x: number, y: number) { ); } } + +// ey its not a bad name +function draw_item_item(item: ItemStack, item_info: ItemRegistry, x: number, y: number) { + let texture_id = "bworld:missing"; + if (typeof item_info?.texture_id === "string") { + texture_id = item_info.texture_id; + } else if (typeof item_info?.texture_id === "function") { + texture_id = item_info.texture_id(item); + } + const sprite_region = get_sprite_region(texture_id); + draw_texture_region( + AssetManager.instance.get("bworld:textures"), + sprite_region.x * 16, + sprite_region.y * 16, + 16, + 16, + x + 3, + y + 3, + SLOT_SIZE - 6, + SLOT_SIZE - 6, + ); +} + +function draw_item_block(_item: ItemStack, item_info: ItemRegistry, x: number, y: number) { + const block_info = EverythingRegistry.get("blocks", item_info.block_id!); + + if (!block_info) throw new Error(`no textures for ${item_info.block_id}`); + + let front_texture = "bworld:missing"; + let top_texture = "bworld:missing"; + let left_texture = "bworld:missing"; + + const textures = block_info.textures; + + if (typeof textures === "string") { + front_texture = textures; + top_texture = textures; + left_texture = textures; + } else if ("top" in textures && "bottom" in textures && "side" in textures) { + top_texture = textures.top; + front_texture = textures.side; + left_texture = textures.side; + } else if ("front" in textures && "side" in textures) { + top_texture = textures.side; + front_texture = textures.front; + left_texture = textures.side; + } + + const atlas = AssetManager.instance.get("bworld:textures"); + + const top = get_sprite_region(top_texture); + const front = get_sprite_region(front_texture); + const left = get_sprite_region(left_texture); + + const padding = 4; + const size = (SLOT_SIZE - padding * 2) / 2; + + const cx = x + SLOT_SIZE / 2; + const cy = y + SLOT_SIZE / 2 - 10; + + const half_w = size; + const half_h = size / 2; + const height = size; + + draw_texture_region_skewed( + atlas, + top.x * TEXTURE_SIZE, + top.y * TEXTURE_SIZE, + TEXTURE_SIZE, + TEXTURE_SIZE, + [ + { x: cx, y: cy - half_h }, + { x: cx + half_w, y: cy }, + { x: cx, y: cy + half_h }, + { x: cx - half_w, y: cy }, + ], + ); + draw_texture_region_skewed( + atlas, + left.x * TEXTURE_SIZE, + left.y * TEXTURE_SIZE, + TEXTURE_SIZE, + TEXTURE_SIZE, + [ + { x: cx - half_w, y: cy }, + { x: cx, y: cy + half_h }, + { x: cx, y: cy + half_h + height }, + { x: cx - half_w, y: cy + height }, + ], + ); + draw_texture_region_skewed( + atlas, + front.x * TEXTURE_SIZE, + front.y * TEXTURE_SIZE, + TEXTURE_SIZE, + TEXTURE_SIZE, + [ + { x: cx + half_w, y: cy }, + { x: cx, y: cy + half_h }, + { x: cx, y: cy + half_h + height }, + { x: cx + half_w, y: cy + height }, + ], + ); +} diff --git a/deno.json b/deno.json index 08ca3c2..0ab7a5f 100644 --- a/deno.json +++ b/deno.json @@ -16,7 +16,7 @@ "imports": { "$/": "./", "@gfx/canvas-wasm": "jsr:@gfx/canvas-wasm@^0.4.2", - "@paulaboks/rng": "jsr:@paulaboks/rng@^0.0.2", + "@paulaboks/rng": "jsr:@paulaboks/rng@^0.0.3", "@std/fs": "jsr:@std/fs@^1.0.23", "gl-matrix": "npm:gl-matrix@^3.4.4", "marked": "npm:marked@^17.0.3" diff --git a/deno.lock b/deno.lock index c85a0e8..70ab4b2 100644 --- a/deno.lock +++ b/deno.lock @@ -2,7 +2,7 @@ "version": "5", "specifiers": { "jsr:@gfx/canvas-wasm@~0.4.2": "0.4.2", - "jsr:@paulaboks/rng@^0.0.2": "0.0.2", + "jsr:@paulaboks/rng@^0.0.3": "0.0.3", "jsr:@std/encoding@1.0.5": "1.0.5", "jsr:@std/fs@^1.0.23": "1.0.23", "jsr:@std/internal@^1.0.12": "1.0.12", @@ -17,8 +17,8 @@ "jsr:@std/encoding" ] }, - "@paulaboks/rng@0.0.2": { - "integrity": "9b4833c80f09f2b6455f3d477977caaab0aac1b04a89970166a2c5169ab4687d" + "@paulaboks/rng@0.0.3": { + "integrity": "8d2571f9f406dab2674178f4034825cc654c5a52aa7c2a176a25f8b713eee202" }, "@std/encoding@1.0.5": { "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" @@ -52,7 +52,7 @@ "workspace": { "dependencies": [ "jsr:@gfx/canvas-wasm@~0.4.2", - "jsr:@paulaboks/rng@^0.0.2", + "jsr:@paulaboks/rng@^0.0.3", "jsr:@std/fs@^1.0.23", "npm:gl-matrix@^3.4.4", "npm:marked@^17.0.3"