From b40191cbd984e50980800ab610327bb9ebfd71b0 Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Wed, 15 Jul 2026 18:45:21 -0700 Subject: [PATCH 01/16] finish --- assets/cubyz/recipes/cloth_recipes.zig.zon | 6 +++++ .../block/client/open_crafting_window.zig | 25 +++++++++++++++++++ src/gui/windows/inventory_crafting.zig | 19 ++++++++++++++ src/items.zig | 20 ++++++++++++++- src/items/recipes.zig | 15 ++++++++--- src/tag.zig | 1 + 6 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 src/callbacks/block/client/open_crafting_window.zig diff --git a/assets/cubyz/recipes/cloth_recipes.zig.zon b/assets/cubyz/recipes/cloth_recipes.zig.zon index 9a5e00ffa3..2b2f19a71d 100644 --- a/assets/cubyz/recipes/cloth_recipes.zig.zon +++ b/assets/cubyz/recipes/cloth_recipes.zig.zon @@ -4,4 +4,10 @@ .output = "cubyz:cloth/block/{color}", .reversible = true, }, + .{ + .inputs = .{"4 cubyz:copper_ingot"}, + .output = "cubyz:silver_ingot", + .reversible = true, + .craftingTags = .{.alchemy} + }, } diff --git a/src/callbacks/block/client/open_crafting_window.zig b/src/callbacks/block/client/open_crafting_window.zig new file mode 100644 index 0000000000..e7270cb881 --- /dev/null +++ b/src/callbacks/block/client/open_crafting_window.zig @@ -0,0 +1,25 @@ +const std = @import("std"); + +const main = @import("main"); +const Block = main.blocks.Block; +const vec = main.vec; +const Vec3i = vec.Vec3i; +const ZonElement = main.ZonElement; + +craftingTags: []main.Tag, + +pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() { + const result = main.worldArena.create(@This()); + const craftingTags = main.Tag.loadTagsFromZon(main.stackAllocator, zon.getChild("craftingTags")); + if (craftingTags.len == 0) std.log.err("Missing craftingTags \"name\" for open_crafting_window event.", .{}) + result.* = .{ + .craftingTags = craftingTags + }; + return result; +} + +pub fn run(self: *@This(), _: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result { + main.gui.windowlist.inventory_crafting.openFromCallback(craftingTags) + main.Window.setMouseGrabbed(false); + return .handled; +} diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index 9224473a95..ba56aab8f7 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -37,13 +37,24 @@ var itemAmount: main.ListManaged(u32) = undefined; var inventories: main.ListManaged(ClientInventory) = undefined; pub var arrowTexture: Texture = undefined; +pub var craftableFromTags: []main.Tag = undefined; pub fn init() void { arrowTexture = Texture.initFromFile("assets/cubyz/ui/inventory/crafting_arrow.png"); + craftableFromTags = main.stackAllocator.alloc(main.Tag, 1); + craftableFromTags[0] = main.Tag.handCraftable; } pub fn deinit() void { arrowTexture.deinit(); + main.stackAllocator.free(craftableFromTags); +} + +pub fn openFromCallback(craftingTags: []main.Tag) void { + gui.closeWindowFromRef(&window); + gui.openWindowFromRef(&window); + craftableFromTags = craftingTags; + main.Window.setMouseGrabbed(false); } fn addItemStackToAvailable(itemStack: ItemStack) void { @@ -93,6 +104,14 @@ fn findAvailableRecipes(list: *VerticalList) bool { } continue :outer; // Ingredient not found. } + middle: for (recipe.craftingTags) |tag| { + for (craftableFromTags) |craftingStationTag| { + if (tag == craftingStationTag) { + continue :middle; + } + } + continue :outer; // Ingredient not found or not craftable by this. + } // All ingredients found: Add it to the list. const inv = ClientInventory.init(main.globalAllocator, recipe.sourceItems.len + 1, .{.crafting = recipe}, .other, .{}); diff --git a/src/items.zig b/src/items.zig index 8fe590f816..d153742562 100644 --- a/src/items.zig +++ b/src/items.zig @@ -1160,16 +1160,21 @@ pub const Recipe = struct { // MARK: Recipe sourceAmounts: []u16, resultItem: BaseItemIndex, resultAmount: u16, + craftingTags: []Tag, fn getValidRecipe(self: Recipe) error{Invalid}!*Recipe { outer: for (main.items.getRecipes()) |*recipe| { if (recipe.resultItem != self.resultItem) continue; if (recipe.resultAmount != self.resultAmount) continue; if (recipe.sourceItems.len != self.sourceItems.len) continue; + if (recipe.craftingTags.len != self.craftingTags.len) continue; for (recipe.sourceItems, recipe.sourceAmounts, self.sourceItems, self.sourceAmounts) |recipeItem, recipeAmount, selfItem, selfAmount| { if (recipeItem != selfItem) continue :outer; if (recipeAmount != selfAmount) continue :outer; } + for (recipe.craftingTags, self.craftingTags) |recipeCraftingTag, selfCraftingTag| { + if (recipeCraftingTag != selfCraftingTag) continue :outer; + } return recipe; } return error.Invalid; @@ -1178,11 +1183,16 @@ pub const Recipe = struct { // MARK: Recipe pub fn toBytes(self: *const Recipe, writer: *BinaryWriter) void { writer.writeEnum(BaseItemIndex, self.resultItem); writer.writeVarInt(u16, self.resultAmount); + writer.writeVarInt(u16, self.resultAmount); writer.writeVarInt(usize, self.sourceItems.len); for (self.sourceItems, self.sourceAmounts) |item, amount| { writer.writeEnum(BaseItemIndex, item); writer.writeVarInt(u16, amount); } + writer.writeVarInt(usize, self.craftingTags.len); + for (self.craftingTags) |tag| { + writer.writeEnum(Tag, tag); + } } pub fn fromBytes(reader: *BinaryReader) !*Recipe { @@ -1200,7 +1210,15 @@ pub const Recipe = struct { // MARK: Recipe sourceAmounts.append(main.stackAllocator, try reader.readVarInt(u16)); } - return getValidRecipe(.{.sourceItems = sourceItems.items, .sourceAmounts = sourceAmounts.items, .resultItem = resultItem, .resultAmount = resultAmount}); + const tagCount = try reader.readVarInt(usize); + var craftingTagTypes: main.List(Tag) = .initCapacity(main.stackAllocator, @min(256, tagCount)); + defer craftingTagTypes.deinit(main.stackAllocator); + + while (reader.remaining.len > 0 and craftingTagTypes.items.len < tagCount) { + craftingTagTypes.append(main.stackAllocator, try reader.readEnum(Tag)); + } + + return getValidRecipe(.{.sourceItems = sourceItems.items, .sourceAmounts = sourceAmounts.items, .resultItem = resultItem, .resultAmount = resultAmount, .craftingTags = craftingTagTypes.items}); } }; diff --git a/src/items/recipes.zig b/src/items/recipes.zig index ab79b3bb0e..cd18049891 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -190,7 +190,7 @@ fn generateItemCombos(allocator: NeverFailingAllocator, recipe: []const ZonEleme return newInputCombos; } -pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Recipe)) void { +pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Recipe), craftingTags: []Tag) void { const inputs = itemCombo[0 .. itemCombo.len - 1]; const output = itemCombo[itemCombo.len - 1]; const recipe = Recipe{ @@ -198,11 +198,15 @@ pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Reci .sourceAmounts = main.worldArena.alloc(u16, inputs.len), .resultItem = output.item, .resultAmount = output.amount, + .craftingTags = main.worldArena.alloc(Tag, craftingTags.len) }; for (inputs, 0..) |input, i| { recipe.sourceItems[i] = input.item; recipe.sourceAmounts[i] = input.amount; } + for (craftingTags, 0..) |tag, i| { + recipe.craftingTags[i] = tag; + } list.append(recipe); } @@ -218,11 +222,16 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { return error.InvalidReversibleRecipe; } + var defaultCraftingTags = arena.alloc(main.Tag, 1); + defaultCraftingTags[0] = main.Tag.handCraftable; + const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags")); + const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else defaultCraftingTags; + const itemCombos = try generateItemCombos(arena, recipeItems); for (itemCombos) |itemCombo| { - addRecipe(itemCombo, list); + addRecipe(itemCombo, list, craftingTags); if (reversible) { - addRecipe(&.{itemCombo[1], itemCombo[0]}, list); + addRecipe(&.{itemCombo[1], itemCombo[0]}, list, craftingTags); } } } diff --git a/src/tag.zig b/src/tag.zig index 5474f581af..b09cbfcc09 100644 --- a/src/tag.zig +++ b/src/tag.zig @@ -12,6 +12,7 @@ pub const Tag = enum(u32) { fluidPlaceable = 3, chiselable = 4, playerModel = 5, + handCraftable = 6, _, pub fn initTags() void { From 8810f3331ef0660f0d6896c3be30ccff9d957a5f Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Wed, 15 Jul 2026 20:44:22 -0700 Subject: [PATCH 02/16] i dont understand why this is leaking --- .../cubyz/blocks/transmutation_workbench.zig.zon | 14 ++++++++++++++ src/callbacks/block/client/_list.zig | 1 + src/callbacks/block/client/edit_sign.zig | 2 +- src/callbacks/block/client/open_chest.zig | 2 +- .../block/client/open_crafting_window.zig | 6 +++--- src/callbacks/block/client/open_window.zig | 2 +- src/gui/windows/inventory_crafting.zig | 1 + src/items/recipes.zig | 5 ++++- 8 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 assets/cubyz/blocks/transmutation_workbench.zig.zon diff --git a/assets/cubyz/blocks/transmutation_workbench.zig.zon b/assets/cubyz/blocks/transmutation_workbench.zig.zon new file mode 100644 index 0000000000..cde732cf25 --- /dev/null +++ b/assets/cubyz/blocks/transmutation_workbench.zig.zon @@ -0,0 +1,14 @@ +.{ + .tags = .{.diggable}, + .blockHealth = 6.5, + .drops = .{ + .{.items = .{.auto}}, + }, + .model = "cubyz:cube", + .rotation = "cubyz:stairs", + .texture = "cubyz:aerosoil", + .onInteract = .{ + .type = .open_crafting_window, + .craftingTags = .{.alchemy} + }, +} diff --git a/src/callbacks/block/client/_list.zig b/src/callbacks/block/client/_list.zig index 9a77fb7eb6..c056756e4a 100644 --- a/src/callbacks/block/client/_list.zig +++ b/src/callbacks/block/client/_list.zig @@ -1,3 +1,4 @@ pub const edit_sign = @import("edit_sign.zig"); pub const open_chest = @import("open_chest.zig"); pub const open_window = @import("open_window.zig"); +pub const open_crafting_window = @import("open_crafting_window.zig"); diff --git a/src/callbacks/block/client/edit_sign.zig b/src/callbacks/block/client/edit_sign.zig index ba6b1de9ae..860baf9105 100644 --- a/src/callbacks/block/client/edit_sign.zig +++ b/src/callbacks/block/client/edit_sign.zig @@ -12,7 +12,7 @@ pub fn init(_: ZonElement, _: main.callbacks.Creator) ?*anyopaque { pub fn run(_: *anyopaque, params: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result { if (params.block.blockEntity() == null or !std.mem.eql(u8, params.block.blockEntity().?.id, "cubyz:sign")) { - std.log.err("Can only edit sign if block entity of the block is a sign.", .{}); + std.log.err("Error: Can only edit sign if block entity of the block is a sign.", .{}); return .ignored; } main.block_entity.BlockEntityTypes.@"cubyz:sign".StorageClient.mutex.lock(); diff --git a/src/callbacks/block/client/open_chest.zig b/src/callbacks/block/client/open_chest.zig index a4846117ab..e4fe21cf13 100644 --- a/src/callbacks/block/client/open_chest.zig +++ b/src/callbacks/block/client/open_chest.zig @@ -12,7 +12,7 @@ pub fn init(_: ZonElement, _: main.callbacks.Creator) ?*anyopaque { pub fn run(_: *anyopaque, params: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result { if (params.block.blockEntity() == null or !std.mem.eql(u8, params.block.blockEntity().?.id, "cubyz:chest")) { - std.log.err("Can only open chest if block entity of the block is a chest.", .{}); + std.log.err("Error: Can only open chest if block entity of the block is a chest.", .{}); return .ignored; } main.network.protocols.blockEntityUpdate.sendClientDataUpdateToServer(main.game.world.?.conn, params.blockPos); diff --git a/src/callbacks/block/client/open_crafting_window.zig b/src/callbacks/block/client/open_crafting_window.zig index e7270cb881..2740d59d65 100644 --- a/src/callbacks/block/client/open_crafting_window.zig +++ b/src/callbacks/block/client/open_crafting_window.zig @@ -11,15 +11,15 @@ craftingTags: []main.Tag, pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() { const result = main.worldArena.create(@This()); const craftingTags = main.Tag.loadTagsFromZon(main.stackAllocator, zon.getChild("craftingTags")); - if (craftingTags.len == 0) std.log.err("Missing craftingTags \"name\" for open_crafting_window event.", .{}) + if (craftingTags.len == 0) std.log.err("Error: Missing craftingTags \"name\" for open_crafting_window event.", .{}); result.* = .{ - .craftingTags = craftingTags + .craftingTags = craftingTags, }; return result; } pub fn run(self: *@This(), _: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result { - main.gui.windowlist.inventory_crafting.openFromCallback(craftingTags) + main.gui.windowlist.inventory_crafting.openFromCallback(self.craftingTags); main.Window.setMouseGrabbed(false); return .handled; } diff --git a/src/callbacks/block/client/open_window.zig b/src/callbacks/block/client/open_window.zig index f67fa9bfc0..ea08f8722a 100644 --- a/src/callbacks/block/client/open_window.zig +++ b/src/callbacks/block/client/open_window.zig @@ -12,7 +12,7 @@ pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() { const result = main.worldArena.create(@This()); result.* = .{ .windowName = main.worldArena.dupe(u8, zon.get([]const u8, "name") orelse { - std.log.err("Missing field \"name\" for open_window event.", .{}); + std.log.err("Error: Missing field \"name\" for open_window event.", .{}); return null; }), }; diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index ba56aab8f7..84c80c1297 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -43,6 +43,7 @@ pub fn init() void { arrowTexture = Texture.initFromFile("assets/cubyz/ui/inventory/crafting_arrow.png"); craftableFromTags = main.stackAllocator.alloc(main.Tag, 1); craftableFromTags[0] = main.Tag.handCraftable; + main.stackAllocator.free(craftableFromTags); } pub fn deinit() void { diff --git a/src/items/recipes.zig b/src/items/recipes.zig index cd18049891..04dc0de36a 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -198,7 +198,7 @@ pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Reci .sourceAmounts = main.worldArena.alloc(u16, inputs.len), .resultItem = output.item, .resultAmount = output.amount, - .craftingTags = main.worldArena.alloc(Tag, craftingTags.len) + .craftingTags = main.worldArena.alloc(Tag, craftingTags.len), }; for (inputs, 0..) |input, i| { recipe.sourceItems[i] = input.item; @@ -226,6 +226,9 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { defaultCraftingTags[0] = main.Tag.handCraftable; const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags")); const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else defaultCraftingTags; + defer arena.free(foundCraftingTags); + defer arena.free(defaultCraftingTags); + defer arena.free(craftingTags); const itemCombos = try generateItemCombos(arena, recipeItems); for (itemCombos) |itemCombo| { From 1f80df6502e73556aebf8d91718ab2aadfc1ec17 Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Wed, 15 Jul 2026 20:57:38 -0700 Subject: [PATCH 03/16] formatting --- assets/cubyz/recipes/cloth_recipes.zig.zon | 2 +- src/callbacks/block/client/open_crafting_window.zig | 1 + src/gui/windows/inventory_crafting.zig | 3 +-- src/items/recipes.zig | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/cubyz/recipes/cloth_recipes.zig.zon b/assets/cubyz/recipes/cloth_recipes.zig.zon index 2b2f19a71d..a8da98d2d1 100644 --- a/assets/cubyz/recipes/cloth_recipes.zig.zon +++ b/assets/cubyz/recipes/cloth_recipes.zig.zon @@ -8,6 +8,6 @@ .inputs = .{"4 cubyz:copper_ingot"}, .output = "cubyz:silver_ingot", .reversible = true, - .craftingTags = .{.alchemy} + .craftingTags = .{.alchemy}, }, } diff --git a/src/callbacks/block/client/open_crafting_window.zig b/src/callbacks/block/client/open_crafting_window.zig index 2740d59d65..3ce9930513 100644 --- a/src/callbacks/block/client/open_crafting_window.zig +++ b/src/callbacks/block/client/open_crafting_window.zig @@ -21,5 +21,6 @@ pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() { pub fn run(self: *@This(), _: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result { main.gui.windowlist.inventory_crafting.openFromCallback(self.craftingTags); main.Window.setMouseGrabbed(false); + defer main.stackAllocator.free(self.craftingTags); return .handled; } diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index 84c80c1297..77d8e5fdfd 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -43,7 +43,6 @@ pub fn init() void { arrowTexture = Texture.initFromFile("assets/cubyz/ui/inventory/crafting_arrow.png"); craftableFromTags = main.stackAllocator.alloc(main.Tag, 1); craftableFromTags[0] = main.Tag.handCraftable; - main.stackAllocator.free(craftableFromTags); } pub fn deinit() void { @@ -111,7 +110,7 @@ fn findAvailableRecipes(list: *VerticalList) bool { continue :middle; } } - continue :outer; // Ingredient not found or not craftable by this. + continue :outer; // Recipe not craftable by this. } // All ingredients found: Add it to the list. const inv = ClientInventory.init(main.globalAllocator, recipe.sourceItems.len + 1, .{.crafting = recipe}, .other, .{}); diff --git a/src/items/recipes.zig b/src/items/recipes.zig index 04dc0de36a..a32b929d37 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -226,8 +226,8 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { defaultCraftingTags[0] = main.Tag.handCraftable; const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags")); const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else defaultCraftingTags; - defer arena.free(foundCraftingTags); defer arena.free(defaultCraftingTags); + defer arena.free(foundCraftingTags); defer arena.free(craftingTags); const itemCombos = try generateItemCombos(arena, recipeItems); From 26832f3a6a281d1352833e41485b60475a94c677 Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Wed, 15 Jul 2026 20:59:23 -0700 Subject: [PATCH 04/16] Update transmutation_workbench.zig.zon --- assets/cubyz/blocks/transmutation_workbench.zig.zon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/cubyz/blocks/transmutation_workbench.zig.zon b/assets/cubyz/blocks/transmutation_workbench.zig.zon index cde732cf25..032cfdfb4c 100644 --- a/assets/cubyz/blocks/transmutation_workbench.zig.zon +++ b/assets/cubyz/blocks/transmutation_workbench.zig.zon @@ -9,6 +9,6 @@ .texture = "cubyz:aerosoil", .onInteract = .{ .type = .open_crafting_window, - .craftingTags = .{.alchemy} + .craftingTags = .{.alchemy}, }, } From 55114ce7250f4addb885158a6a57e303a9b10eee Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Thu, 16 Jul 2026 13:17:05 -0700 Subject: [PATCH 05/16] its not yelling about a leak anymore --- src/callbacks/block/client/open_crafting_window.zig | 4 ++-- src/items/recipes.zig | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/callbacks/block/client/open_crafting_window.zig b/src/callbacks/block/client/open_crafting_window.zig index 3ce9930513..9d6f39e3dd 100644 --- a/src/callbacks/block/client/open_crafting_window.zig +++ b/src/callbacks/block/client/open_crafting_window.zig @@ -10,7 +10,7 @@ craftingTags: []main.Tag, pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() { const result = main.worldArena.create(@This()); - const craftingTags = main.Tag.loadTagsFromZon(main.stackAllocator, zon.getChild("craftingTags")); + const craftingTags = main.Tag.loadTagsFromZon(main.worldArena, zon.getChild("craftingTags")); if (craftingTags.len == 0) std.log.err("Error: Missing craftingTags \"name\" for open_crafting_window event.", .{}); result.* = .{ .craftingTags = craftingTags, @@ -21,6 +21,6 @@ pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() { pub fn run(self: *@This(), _: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result { main.gui.windowlist.inventory_crafting.openFromCallback(self.craftingTags); main.Window.setMouseGrabbed(false); - defer main.stackAllocator.free(self.craftingTags); + defer main.worldArena.free(self.craftingTags); return .handled; } diff --git a/src/items/recipes.zig b/src/items/recipes.zig index a32b929d37..13a3a7dac3 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -226,9 +226,6 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { defaultCraftingTags[0] = main.Tag.handCraftable; const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags")); const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else defaultCraftingTags; - defer arena.free(defaultCraftingTags); - defer arena.free(foundCraftingTags); - defer arena.free(craftingTags); const itemCombos = try generateItemCombos(arena, recipeItems); for (itemCombos) |itemCombo| { From c5a32af9357ad9bfcfb8a0aabc4923f3a9cb324f Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Sat, 18 Jul 2026 08:09:19 -0700 Subject: [PATCH 06/16] Update open_crafting_window.zig --- src/callbacks/block/client/open_crafting_window.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/callbacks/block/client/open_crafting_window.zig b/src/callbacks/block/client/open_crafting_window.zig index 9d6f39e3dd..e26bc30074 100644 --- a/src/callbacks/block/client/open_crafting_window.zig +++ b/src/callbacks/block/client/open_crafting_window.zig @@ -21,6 +21,5 @@ pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() { pub fn run(self: *@This(), _: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result { main.gui.windowlist.inventory_crafting.openFromCallback(self.craftingTags); main.Window.setMouseGrabbed(false); - defer main.worldArena.free(self.craftingTags); return .handled; } From 6f22ed3448d16f30adb1830fcabd5f1abc21b649 Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Wed, 22 Jul 2026 10:47:22 -0700 Subject: [PATCH 07/16] Update inventory_crafting.zig --- src/gui/windows/inventory_crafting.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index 77d8e5fdfd..56363cc26b 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -47,7 +47,6 @@ pub fn init() void { pub fn deinit() void { arrowTexture.deinit(); - main.stackAllocator.free(craftableFromTags); } pub fn openFromCallback(craftingTags: []main.Tag) void { From 173fac241dc5e23db9c8a6b8981b9012deed940c Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Wed, 22 Jul 2026 11:41:11 -0700 Subject: [PATCH 08/16] fixed getting stuck with crafting table recipie bug --- src/gui/GuiWindow.zig | 2 ++ src/gui/gui.zig | 1 + src/gui/windows/inventory_crafting.zig | 5 +++++ src/items.zig | 1 - 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gui/GuiWindow.zig b/src/gui/GuiWindow.zig index 60f9e87c1b..83ce45c5a0 100644 --- a/src/gui/GuiWindow.zig +++ b/src/gui/GuiWindow.zig @@ -73,6 +73,8 @@ onOpenFn: *const fn () void = &defaultFunction, onCloseFn: *const fn () void = &defaultFunction, +onToggleWindowFn: *const fn () void = &defaultFunction, + var grabbedWindow: *const GuiWindow = undefined; var windowMoving: bool = false; var grabPosition: ?Vec2f = null; diff --git a/src/gui/gui.zig b/src/gui/gui.zig index f3ea6d7993..b9632953fa 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -642,6 +642,7 @@ pub fn toggleGameMenu() void { _ = openWindows.swapRemove(i); window.onCloseFn(); } else { + window.onToggleWindowFn(); i += 1; } } diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index 56363cc26b..720ecfc043 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -189,6 +189,11 @@ pub fn onClose() void { inventories.deinit(); } +pub fn onToggleWindowFn() void { + craftableFromTags[0] = main.Tag.handCraftable; + refresh(); +} + pub fn update() void { refresh(); } diff --git a/src/items.zig b/src/items.zig index 0a2c2d094e..38c53b0fb8 100644 --- a/src/items.zig +++ b/src/items.zig @@ -1323,7 +1323,6 @@ pub const Recipe = struct { // MARK: Recipe pub fn toBytes(self: *const Recipe, writer: *BinaryWriter) void { writer.writeEnum(BaseItemIndex, self.resultItem); writer.writeVarInt(u16, self.resultAmount); - writer.writeVarInt(u16, self.resultAmount); writer.writeVarInt(usize, self.sourceItems.len); for (self.sourceItems, self.sourceAmounts) |item, amount| { writer.writeEnum(BaseItemIndex, item); From 099780c54d4a019e1f72ad9e36a6b4ee14aa04ae Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Wed, 22 Jul 2026 13:44:18 -0700 Subject: [PATCH 09/16] Update inventory_crafting.zig --- src/gui/windows/inventory_crafting.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index 720ecfc043..7383dde3dc 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -47,6 +47,7 @@ pub fn init() void { pub fn deinit() void { arrowTexture.deinit(); + main.stackAllocator.free(craftableFromTags); } pub fn openFromCallback(craftingTags: []main.Tag) void { From af0a3eb647f5bb77931c60a229efcfbab625a2e0 Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Thu, 27 Aug 2026 10:42:33 -0700 Subject: [PATCH 10/16] still kinda broken --- src/gui/gui.zig | 2 +- src/gui/windows/inventory_crafting.zig | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/gui/gui.zig b/src/gui/gui.zig index b9632953fa..3d525351ad 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -131,7 +131,7 @@ pub fn initWindowList() void { const windowStruct = @field(windowlist, decl.name); windowStruct.window.id = decl.name; addWindow(&windowStruct.window); - const functionNames = [_][]const u8{"render", "update", "updateSelected", "updateHovered", "onOpen", "onClose"}; + const functionNames = [_][]const u8{"render", "update", "updateSelected", "updateHovered", "onOpen", "onClose", "onToggleWindow"}; inline for (functionNames) |function| { if (@hasDecl(windowStruct, function)) { @field(windowStruct.window, function ++ "Fn") = &@field(windowStruct, function); diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index 7383dde3dc..a7f8e7dc31 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -41,13 +41,11 @@ pub var craftableFromTags: []main.Tag = undefined; pub fn init() void { arrowTexture = Texture.initFromFile("assets/cubyz/ui/inventory/crafting_arrow.png"); - craftableFromTags = main.stackAllocator.alloc(main.Tag, 1); - craftableFromTags[0] = main.Tag.handCraftable; + craftableFromTags = .{main.Tag.handCraftable}; } pub fn deinit() void { arrowTexture.deinit(); - main.stackAllocator.free(craftableFromTags); } pub fn openFromCallback(craftingTags: []main.Tag) void { @@ -190,8 +188,9 @@ pub fn onClose() void { inventories.deinit(); } -pub fn onToggleWindowFn() void { - craftableFromTags[0] = main.Tag.handCraftable; +pub fn onToggleWindow() void { + craftableFromTags[0] = .{main.Tag.handCraftable}; + std.log.debug("hello", .{}); refresh(); } From c271e6a32a57f94abeaf0410e683830e6466485f Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Tue, 8 Sep 2026 19:19:27 -0700 Subject: [PATCH 11/16] finished the crafting table --- src/gui/windows/inventory_crafting.zig | 30 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index a7f8e7dc31..7e10ed706d 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -35,23 +35,31 @@ const padding: f32 = 8; var availableItems: main.ListManaged(BaseItemIndex) = undefined; var itemAmount: main.ListManaged(u32) = undefined; var inventories: main.ListManaged(ClientInventory) = undefined; +var craftableFromTags: main.ListManaged(main.Tag) = undefined; +var foundNewTags: bool = false; +var defaultCraftingTags: []main.Tag = undefined; pub var arrowTexture: Texture = undefined; -pub var craftableFromTags: []main.Tag = undefined; pub fn init() void { arrowTexture = Texture.initFromFile("assets/cubyz/ui/inventory/crafting_arrow.png"); - craftableFromTags = .{main.Tag.handCraftable}; + defaultCraftingTags = main.globalAllocator.alloc(main.Tag, 1); + defaultCraftingTags[0] = main.Tag.handCraftable; + craftableFromTags = .init(main.globalAllocator); + changeCraftingTags(defaultCraftingTags); } pub fn deinit() void { arrowTexture.deinit(); + craftableFromTags.clearAndFree(); + craftableFromTags.deinit(); + main.globalAllocator.free(defaultCraftingTags); } pub fn openFromCallback(craftingTags: []main.Tag) void { + changeCraftingTags(craftingTags); gui.closeWindowFromRef(&window); gui.openWindowFromRef(&window); - craftableFromTags = craftingTags; main.Window.setMouseGrabbed(false); } @@ -79,7 +87,8 @@ fn findAvailableRecipes(list: *VerticalList) bool { for (0..main.game.Player.inventory.size()) |i| { addItemStackToAvailable(main.game.Player.inventory.getStack(i)); } - if (std.mem.eql(u32, oldAmounts, itemAmount.items)) return false; + if (std.mem.eql(u32, oldAmounts, itemAmount.items) and (!foundNewTags)) return false; + foundNewTags = false; // Remove no longer present items: var i: u32 = 0; while (i < availableItems.items.len) : (i += 1) { @@ -103,7 +112,7 @@ fn findAvailableRecipes(list: *VerticalList) bool { continue :outer; // Ingredient not found. } middle: for (recipe.craftingTags) |tag| { - for (craftableFromTags) |craftingStationTag| { + for (craftableFromTags.items) |craftingStationTag| { if (tag == craftingStationTag) { continue :middle; } @@ -189,11 +198,18 @@ pub fn onClose() void { } pub fn onToggleWindow() void { - craftableFromTags[0] = .{main.Tag.handCraftable}; - std.log.debug("hello", .{}); + changeCraftingTags(defaultCraftingTags); refresh(); } pub fn update() void { refresh(); } + +fn changeCraftingTags(newCraftingTags: []main.Tag) void { + foundNewTags = true; + if (std.mem.eql(main.Tag, craftableFromTags.items, newCraftingTags)) return; + craftableFromTags.deinit(); + craftableFromTags = .initCapacity(main.globalAllocator, newCraftingTags.len); + craftableFromTags.appendSlice(newCraftingTags); +} From ad6c79577aac51d7abc83cc2adcfc26c69730e39 Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Thu, 24 Sep 2026 11:08:00 -0700 Subject: [PATCH 12/16] small wunka adjustments --- src/items.zig | 2 +- src/items/recipes.zig | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/items.zig b/src/items.zig index 38c53b0fb8..d42d20000f 100644 --- a/src/items.zig +++ b/src/items.zig @@ -1350,7 +1350,7 @@ pub const Recipe = struct { // MARK: Recipe } const tagCount = try reader.readVarInt(usize); - var craftingTagTypes: main.List(Tag) = .initCapacity(main.stackAllocator, @min(256, tagCount)); + var craftingTagTypes: main.List(Tag) = .initCapacity(main.stackAllocator, @min(256, std.math.maxInt)); defer craftingTagTypes.deinit(main.stackAllocator); while (reader.remaining.len > 0 and craftingTagTypes.items.len < tagCount) { diff --git a/src/items/recipes.zig b/src/items/recipes.zig index 13a3a7dac3..af64cc43bd 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -198,15 +198,12 @@ pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Reci .sourceAmounts = main.worldArena.alloc(u16, inputs.len), .resultItem = output.item, .resultAmount = output.amount, - .craftingTags = main.worldArena.alloc(Tag, craftingTags.len), + .craftingTags = main.worldArena.dupe(Tag, craftingTags), }; for (inputs, 0..) |input, i| { recipe.sourceItems[i] = input.item; recipe.sourceAmounts[i] = input.amount; } - for (craftingTags, 0..) |tag, i| { - recipe.craftingTags[i] = tag; - } list.append(recipe); } @@ -222,10 +219,12 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { return error.InvalidReversibleRecipe; } - var defaultCraftingTags = arena.alloc(main.Tag, 1); - defaultCraftingTags[0] = main.Tag.handCraftable; const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags")); - const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else defaultCraftingTags; + const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else blk: { + var defaultCraftingTags = arena.alloc(main.Tag, 1); + defaultCraftingTags[0] = main.Tag.handCraftable; + break :blk defaultCraftingTags; + }; const itemCombos = try generateItemCombos(arena, recipeItems); for (itemCombos) |itemCombo| { From ebf20d28297f30857730f3ee2efb807d7c92b60a Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Thu, 24 Sep 2026 11:09:24 -0700 Subject: [PATCH 13/16] why is this min at all --- src/items.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items.zig b/src/items.zig index d42d20000f..5fbfb549f1 100644 --- a/src/items.zig +++ b/src/items.zig @@ -1350,7 +1350,7 @@ pub const Recipe = struct { // MARK: Recipe } const tagCount = try reader.readVarInt(usize); - var craftingTagTypes: main.List(Tag) = .initCapacity(main.stackAllocator, @min(256, std.math.maxInt)); + var craftingTagTypes: main.List(Tag) = .initCapacity(main.stackAllocator, tagCount); defer craftingTagTypes.deinit(main.stackAllocator); while (reader.remaining.len > 0 and craftingTagTypes.items.len < tagCount) { From 57fce27c0947a1f4f13e641e860f2ca71680a3ac Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Thu, 24 Sep 2026 11:16:29 -0700 Subject: [PATCH 14/16] default crafting tags changed again for formatting --- src/items/recipes.zig | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/items/recipes.zig b/src/items/recipes.zig index af64cc43bd..4f0bc496b5 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -207,6 +207,8 @@ pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Reci list.append(recipe); } +var defaultCraftingTags: [1]Tag = .{.handCraftable}; + pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { const arena = main.stackAllocator.createArena(); defer main.stackAllocator.destroyArena(arena); @@ -220,11 +222,7 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { } const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags")); - const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else blk: { - var defaultCraftingTags = arena.alloc(main.Tag, 1); - defaultCraftingTags[0] = main.Tag.handCraftable; - break :blk defaultCraftingTags; - }; + const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else arena.dupe(Tag, &defaultCraftingTags); const itemCombos = try generateItemCombos(arena, recipeItems); for (itemCombos) |itemCombo| { From 33863873a30d2cf48730b9919802df80976e459b Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Thu, 24 Sep 2026 11:18:30 -0700 Subject: [PATCH 15/16] const --- src/items/recipes.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/recipes.zig b/src/items/recipes.zig index 4f0bc496b5..ef49e85355 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -207,7 +207,7 @@ pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Reci list.append(recipe); } -var defaultCraftingTags: [1]Tag = .{.handCraftable}; +const defaultCraftingTags: [1]Tag = .{.handCraftable}; pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { const arena = main.stackAllocator.createArena(); From 4fb02980e27740644ffe0e35e5e3382f3779db6d Mon Sep 17 00:00:00 2001 From: Vinywar123 Date: Thu, 24 Sep 2026 11:25:05 -0700 Subject: [PATCH 16/16] changing defaults formatting agin --- src/items/recipes.zig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/items/recipes.zig b/src/items/recipes.zig index ef49e85355..77c5aa7889 100644 --- a/src/items/recipes.zig +++ b/src/items/recipes.zig @@ -207,8 +207,6 @@ pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Reci list.append(recipe); } -const defaultCraftingTags: [1]Tag = .{.handCraftable}; - pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { const arena = main.stackAllocator.createArena(); defer main.stackAllocator.destroyArena(arena); @@ -222,7 +220,7 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void { } const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags")); - const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else arena.dupe(Tag, &defaultCraftingTags); + const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else .{.handCraftable}; const itemCombos = try generateItemCombos(arena, recipeItems); for (itemCombos) |itemCombo| {