From cd0cabbbb8ea6773254e550a9dee283682695c07 Mon Sep 17 00:00:00 2001 From: OneAvargeCoder193 <85588535+OneAvargeCoder193@users.noreply.github.com> Date: Mon, 28 Apr 2025 11:17:39 -0400 Subject: [PATCH] Add Block Inventories (#1198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add chest block placeholder * Update location of chest.zig.zon * added chests * fix some stuff * dont create all inventories on the client * make it better * remove comment * fix formatting * fix more formatting issues * use chests instead of iron block * fix formatting * make blocks with inventories that are broken drop the items * fix compiler error * fix formatting * fix formatting * Trigger GitHub Actions * add inventory saving to bin * fix formatting * fix formatting again * fix formatting again again * small change * current changes * thing * Chest patch w/o quantums suggestions * small test pls no merge * it works with a couple segfaults that may or may not be in the base game * final thing i think * block inventories * haha * another thing * fix formatting * fix formatting again * remove saving for now * remove a comment * remove more comments * dont store inventory on the client * something * hardcode stuff for the future * remove getwindow * fix formatting * fixes --------- Co-authored-by: Krzysztof Wiśniewski --- src/Inventory.zig | 16 ++++++-- src/blocks.zig | 1 + src/entity_data.zig | 56 ++++++++----------------- src/gui/gui.zig | 2 + src/gui/windows/_windowlist.zig | 1 + src/gui/windows/chest.zig | 73 +++++++++++++++++++++++++++++++++ 6 files changed, 105 insertions(+), 44 deletions(-) create mode 100644 src/gui/windows/chest.zig diff --git a/src/Inventory.zig b/src/Inventory.zig index 94e3a57e..a8478a9a 100644 --- a/src/Inventory.zig +++ b/src/Inventory.zig @@ -302,7 +302,7 @@ pub const Sync = struct { // MARK: Sync fn createInventory(user: *main.server.User, clientId: u32, len: usize, typ: Inventory.Type, source: Source) void { main.utils.assertLocked(&mutex); switch(source) { - .sharedTestingInventory, .recipe => { + .sharedTestingInventory, .recipe, .blockInventory => { for(inventories.items) |*inv| { if(std.meta.eql(inv.source, source)) { inv.addUser(user, clientId); @@ -315,6 +315,9 @@ pub const Sync = struct { // MARK: Sync } const inventory = ServerInventory.init(len, typ, source); + inventories.items[inventory.inv.id] = inventory; + inventories.items[inventory.inv.id].addUser(user, clientId); + switch(source) { .sharedTestingInventory => {}, .playerInventory, .hand => { @@ -340,12 +343,11 @@ pub const Sync = struct { // MARK: Sync inventory.inv._items[inventory.inv._items.len - 1].amount = recipe.resultAmount; inventory.inv._items[inventory.inv._items.len - 1].item = .{.baseItem = recipe.resultItem}; }, + // TODO: Load block inventory data from save + .blockInventory => {}, .other => {}, .alreadyFreed => unreachable, } - - inventories.items[inventory.inv.id] = inventory; - inventories.items[inventory.inv.id].addUser(user, clientId); } fn closeInventory(user: *main.server.User, clientId: u32) !void { @@ -1096,6 +1098,9 @@ pub const Command = struct { // MARK: Command writer.writeWithDelimiter(val.sourceItems[i].id, 0); } }, + .blockInventory => |val| { + writer.writeVec(Vec3i, val); + }, .sharedTestingInventory, .other => {}, .alreadyFreed => unreachable, } @@ -1140,6 +1145,7 @@ pub const Command = struct { // MARK: Command return error.Invalid; }, }, + .blockInventory => .{.blockInventory = try reader.readVec(Vec3i)}, .other => .{.other = {}}, .alreadyFreed => unreachable, }; @@ -1779,6 +1785,7 @@ const SourceType = enum(u8) { sharedTestingInventory = 2, hand = 3, recipe = 4, + blockInventory = 5, other = 0xff, // TODO: List every type separately here. }; const Source = union(SourceType) { @@ -1787,6 +1794,7 @@ const Source = union(SourceType) { sharedTestingInventory: void, hand: u32, recipe: *const main.items.Recipe, + blockInventory: Vec3i, other: void, }; diff --git a/src/blocks.zig b/src/blocks.zig index e4f8275b..5c3b1667 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -74,6 +74,7 @@ var _modeData: [maxBlockCount]u16 = undefined; var _lodReplacement: [maxBlockCount]u16 = undefined; var _opaqueVariant: [maxBlockCount]u16 = undefined; var _friction: [maxBlockCount]f32 = undefined; + var _allowOres: [maxBlockCount]bool = undefined; var _touchFunction: [maxBlockCount]?*const TouchFunction = undefined; var _entityDataClass: [maxBlockCount]?*EntityDataClass = undefined; diff --git a/src/entity_data.zig b/src/entity_data.zig index 8c47ec6e..d3bdb695 100644 --- a/src/entity_data.zig +++ b/src/entity_data.zig @@ -176,63 +176,39 @@ pub const EntityDataClasses = struct { const StorageServer = BlockEntityDataStorage( .server, struct { - contents: u64, - }, - ); - const StorageClient = BlockEntityDataStorage( - .client, - struct { - contents: u64, + id: ?u32, }, ); pub const id = "chest"; pub fn init() void { StorageServer.init(); - StorageClient.init(); } pub fn deinit() void { StorageServer.deinit(); - StorageClient.deinit(); } pub fn reset() void { StorageServer.reset(); - StorageClient.reset(); } - pub fn onLoadClient(_: Vec3i, _: *Chunk) void { - std.log.debug("Chest.onLoadClient", .{}); - } - pub fn onUnloadClient(_: Vec3i, _: *Chunk) void { - std.log.debug("Chest.onUnloadClient", .{}); - } - pub fn onLoadServer(_: Vec3i, _: *Chunk) void { - std.log.debug("Chest.onLoadServer", .{}); - } - pub fn onUnloadServer(_: Vec3i, _: *Chunk) void { - std.log.debug("Chest.onUnloadServer", .{}); - } - pub fn onPlaceClient(pos: Vec3i, chunk: *Chunk) void { - std.log.debug("Chest.onPlaceClient", .{}); - StorageClient.add(pos, .{.contents = 0}, chunk); - } - pub fn onBreakClient(pos: Vec3i, chunk: *Chunk) void { - std.log.debug("Chest.onBreakClient", .{}); - StorageClient.remove(pos, chunk); - } - pub fn onPlaceServer(pos: Vec3i, chunk: *Chunk) void { - std.log.debug("Chest.onPlaceServer", .{}); - StorageServer.add(pos, .{.contents = 0}, chunk); - } + pub fn onLoadClient(_: Vec3i, _: *Chunk) void {} + pub fn onUnloadClient(_: Vec3i, _: *Chunk) void {} + pub fn onLoadServer(_: Vec3i, _: *Chunk) void {} + pub fn onUnloadServer(_: Vec3i, _: *Chunk) void {} + pub fn onPlaceClient(_: Vec3i, _: *Chunk) void {} + pub fn onBreakClient(_: Vec3i, _: *Chunk) void {} + pub fn onPlaceServer(_: Vec3i, _: *Chunk) void {} pub fn onBreakServer(pos: Vec3i, chunk: *Chunk) void { - std.log.debug("Chest.onBreakServer", .{}); StorageServer.remove(pos, chunk); } - pub fn onInteract(pos: Vec3i, chunk: *Chunk) EventStatus { - StorageClient.mutex.lock(); - defer StorageClient.mutex.unlock(); - const data = StorageClient.get(pos, chunk); - if(data == null) std.log.debug("Chest.onInteract: null", .{}) else std.log.debug("Chest.onInteract: {}", .{data.?.contents}); + pub fn onInteract(pos: Vec3i, _: *Chunk) EventStatus { + if(main.KeyBoard.key("shift").pressed) return .ignored; + + const inventory = main.items.Inventory.init(main.globalAllocator, 20, .normal, .{.blockInventory = pos}); + + main.gui.windowlist.chest.setInventory(inventory); + main.gui.openWindow("chest"); + main.Window.setMouseGrabbed(false); return .handled; } diff --git a/src/gui/gui.zig b/src/gui/gui.zig index 27c77e68..b23cfc65 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -303,12 +303,14 @@ fn addWindow(window: *GuiWindow) void { pub fn openWindow(id: []const u8) void { defer updateWindowPositions(); + for(windowList.items) |window| { if(std.mem.eql(u8, window.id, id)) { openWindowFromRef(window); return; } } + std.log.err("Could not find window with id {s}.", .{id}); } diff --git a/src/gui/windows/_windowlist.zig b/src/gui/windows/_windowlist.zig index e341da7b..f97835d3 100644 --- a/src/gui/windows/_windowlist.zig +++ b/src/gui/windows/_windowlist.zig @@ -1,6 +1,7 @@ pub const advanced_controls = @import("advanced_controls.zig"); pub const change_name = @import("change_name.zig"); pub const chat = @import("chat.zig"); +pub const chest = @import("chest.zig"); pub const controls = @import("controls.zig"); pub const creative_inventory = @import("creative_inventory.zig"); pub const crosshair = @import("crosshair.zig"); diff --git a/src/gui/windows/chest.zig b/src/gui/windows/chest.zig new file mode 100644 index 00000000..54ec4a5e --- /dev/null +++ b/src/gui/windows/chest.zig @@ -0,0 +1,73 @@ +const std = @import("std"); + +const main = @import("main"); +const Player = main.game.Player; +const ItemStack = main.items.ItemStack; +const Vec2f = main.vec.Vec2f; +const Texture = main.graphics.Texture; + +const gui = @import("../gui.zig"); +const GuiComponent = gui.GuiComponent; +const GuiWindow = gui.GuiWindow; +const Button = GuiComponent.Button; +const HorizontalList = GuiComponent.HorizontalList; +const VerticalList = GuiComponent.VerticalList; +const ItemSlot = GuiComponent.ItemSlot; + +const inventory = @import("inventory.zig"); + +pub var window = GuiWindow{ + .relativePosition = .{ + .{.attachedToWindow = .{.reference = &inventory.window, .selfAttachmentPoint = .middle, .otherAttachmentPoint = .middle}}, + .{.attachedToWindow = .{.reference = &inventory.window, .selfAttachmentPoint = .upper, .otherAttachmentPoint = .lower}}, + }, + .contentSize = Vec2f{64*10, 64*3}, + .scale = 0.75, + .closeIfMouseIsGrabbed = true, +}; + +const padding: f32 = 8; +var itemSlots: main.List(*ItemSlot) = undefined; + +pub fn init() void { + itemSlots = .init(main.globalAllocator); +} + +pub fn deinit() void { + itemSlots.deinit(); +} + +pub var openInventory: main.items.Inventory = undefined; + +pub fn setInventory(selectedInventory: main.items.Inventory) void { + openInventory = selectedInventory; +} + +pub fn onOpen() void { + const list = VerticalList.init(.{padding, padding + 16}, 300, 0); + + for(0..2) |y| { + const row = HorizontalList.init(); + for(0..10) |x| { + const index: usize = y*10 + x; + const slot = ItemSlot.init(.{0, 0}, openInventory, @intCast(index), .default, .normal); + itemSlots.append(slot); + row.add(slot); + } + list.add(row); + } + list.finish(.center); + window.rootComponent = list.toComponent(); + window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @as(Vec2f, @splat(padding)); + gui.updateWindowPositions(); +} + +pub fn onClose() void { + openInventory.deinit(main.globalAllocator); + + itemSlots.clearRetainingCapacity(); + if(window.rootComponent) |*comp| { + comp.deinit(); + window.rootComponent = null; + } +}