diff --git a/src/Inventory.zig b/src/Inventory.zig index 5b1838208..d32177096 100644 --- a/src/Inventory.zig +++ b/src/Inventory.zig @@ -382,17 +382,135 @@ pub const Source = union(SourceType) { other: void, }; +pub const ClientInventory = struct { // MARK: ClientInventory + const ClientType = enum { + serverShared, + creative, + }; + super: Inventory, + type: ClientType, + + pub fn init(allocator: NeverFailingAllocator, _size: usize, _type: Type, clientType: ClientType, source: Source, callbacks: Callbacks) ClientInventory { + const self: ClientInventory = .{ + .super = Inventory._init(allocator, _size, _type, source, .client, callbacks), + .type = clientType, + }; + if(clientType == .serverShared) { + sync.ClientSide.executeCommand(.{.open = .{.inv = self.super, .source = source}}); + } + return self; + } + + pub fn deinit(self: ClientInventory, allocator: NeverFailingAllocator) void { + if(main.game.world.?.connected) { + sync.ClientSide.executeCommand(.{.close = .{.inv = self.super, .allocator = allocator}}); + } else { + main.sync.ClientSide.mutex.lock(); + defer main.sync.ClientSide.mutex.unlock(); + self.super._deinit(allocator, .client); + } + } + + pub fn depositOrSwap(dest: ClientInventory, destSlot: u32, carried: ClientInventory) void { + if(dest.type == .creative) { + carried.fillFromCreative(0, dest.getItem(destSlot)); + return; + } + main.sync.ClientSide.executeCommand(.{.depositOrSwap = .{.dest = .{.inv = dest.super, .slot = destSlot}, .source = .{.inv = carried.super, .slot = 0}}}); + } + + pub fn deposit(dest: ClientInventory, destSlot: u32, source: ClientInventory, sourceSlot: u32, amount: u16) void { + if(source.type == .creative) { + std.debug.assert(dest.type == .serverShared); + dest.fillFromCreative(destSlot, source.getItem(sourceSlot)); + return; + } + std.debug.assert(source.type == .serverShared); + main.sync.ClientSide.executeCommand(.{.deposit = .{.dest = .{.inv = dest.super, .slot = destSlot}, .source = .{.inv = source.super, .slot = sourceSlot}, .amount = amount}}); + } + + pub fn takeHalf(source: ClientInventory, sourceSlot: u32, carried: ClientInventory) void { + if(carried.type == .creative) { + carried.fillFromCreative(0, source.getItem(sourceSlot)); + return; + } + main.sync.ClientSide.executeCommand(.{.takeHalf = .{.dest = .{.inv = carried.super, .slot = 0}, .source = .{.inv = source.super, .slot = sourceSlot}}}); + } + + pub fn distribute(carried: ClientInventory, destinationInventories: []const ClientInventory, destinationSlots: []const u32) void { + const amount = carried.getAmount(0)/destinationInventories.len; + if(amount == 0) return; + for(0..destinationInventories.len) |i| { + destinationInventories[i].deposit(destinationSlots[i], carried, 0, @intCast(amount)); + } + } + + pub fn depositOrDrop(dest: ClientInventory, source: ClientInventory) void { + std.debug.assert(dest.type == .serverShared); + std.debug.assert(source.type != .creative); + main.sync.ClientSide.executeCommand(.{.depositOrDrop = .{.dest = dest.super, .source = source.super, .dropLocation = undefined}}); + } + + pub fn depositToAny(source: ClientInventory, sourceSlot: u32, destinations: []const ClientInventory, amount: u16) void { + std.debug.assert(source.type != .creative); + for(destinations) |inv| std.debug.assert(inv.super.type == .normal); + main.sync.ClientSide.executeCommand(.{.depositToAny = .init(destinations, .{.inv = source.super, .slot = sourceSlot}, amount)}); + } + + pub fn dropStack(source: ClientInventory, sourceSlot: u32) void { + if(source.type == .creative) return; + main.sync.ClientSide.executeCommand(.{.drop = .{.source = .{.inv = source.super, .slot = sourceSlot}}}); + } + + pub fn dropOne(source: ClientInventory, sourceSlot: u32) void { + if(source.type == .creative) return; + main.sync.ClientSide.executeCommand(.{.drop = .{.source = .{.inv = source.super, .slot = sourceSlot}, .desiredAmount = 1}}); + } + + pub fn fillFromCreative(dest: ClientInventory, destSlot: u32, item: Item) void { + main.sync.ClientSide.executeCommand(.{.fillFromCreative = .{.dest = .{.inv = dest.super, .slot = destSlot}, .item = item}}); + } + + pub fn fillAmountFromCreative(dest: ClientInventory, destSlot: u32, item: Item, amount: u16) void { + main.sync.ClientSide.executeCommand(.{.fillFromCreative = .{.dest = .{.inv = dest.super, .slot = destSlot}, .item = item, .amount = amount}}); + } + + pub fn placeBlock(self: ClientInventory, slot: u32) void { + std.debug.assert(self.type == .serverShared); + main.renderer.MeshSelection.placeBlock(self, slot); + } + + pub fn breakBlock(self: ClientInventory, slot: u32, deltaTime: f64) void { + std.debug.assert(self.type == .serverShared); + main.renderer.MeshSelection.breakBlock(self, slot, deltaTime); + } + + pub fn size(self: ClientInventory) usize { + return self.super.size(); + } + + pub fn getItem(self: ClientInventory, slot: usize) Item { + return self.super.getItem(slot); + } + + pub fn getStack(self: ClientInventory, slot: usize) ItemStack { + return self.super.getStack(slot); + } + + pub fn getAmount(self: ClientInventory, slot: usize) u16 { + return self.super.getAmount(slot); + } +}; + const Inventory = @This(); // MARK: Inventory pub const TypeEnum = enum(u8) { normal = 0, - creative = 1, crafting = 2, workbench = 3, }; pub const Type = union(TypeEnum) { normal: void, - creative: void, crafting: void, workbench: ToolTypeIndex, @@ -400,18 +518,13 @@ pub const Type = union(TypeEnum) { return self == .workbench; } }; + type: Type, id: InventoryId, _items: []ItemStack, source: Source, callbacks: Callbacks, -pub fn init(allocator: NeverFailingAllocator, _size: usize, _type: Type, source: Source, callbacks: Callbacks) Inventory { - const self = _init(allocator, _size, _type, source, .client, callbacks); - sync.ClientSide.executeCommand(.{.open = .{.inv = self, .source = source}}); - return self; -} - fn _init(allocator: NeverFailingAllocator, _size: usize, _type: Type, source: Source, side: sync.Side, callbacks: Callbacks) Inventory { if(_type == .workbench) std.debug.assert(_size == 26); const self = Inventory{ @@ -430,16 +543,6 @@ fn _init(allocator: NeverFailingAllocator, _size: usize, _type: Type, source: So return self; } -pub fn deinit(self: Inventory, allocator: NeverFailingAllocator) void { - if(main.game.world.?.connected) { - sync.ClientSide.executeCommand(.{.close = .{.inv = self, .allocator = allocator}}); - } else { - main.sync.ClientSide.mutex.lock(); - defer main.sync.ClientSide.mutex.unlock(); - self._deinit(allocator, .client); - } -} - pub fn _deinit(self: Inventory, allocator: NeverFailingAllocator, side: sync.Side) void { switch(side) { .client => ClientSide.freeId(self.id), @@ -482,58 +585,6 @@ pub fn update(self: Inventory) void { } } -pub fn depositOrSwap(dest: Inventory, destSlot: u32, carried: Inventory) void { - main.sync.ClientSide.executeCommand(.{.depositOrSwap = .{.dest = .{.inv = dest, .slot = destSlot}, .source = .{.inv = carried, .slot = 0}}}); -} - -pub fn deposit(dest: Inventory, destSlot: u32, source: Inventory, sourceSlot: u32, amount: u16) void { - main.sync.ClientSide.executeCommand(.{.deposit = .{.dest = .{.inv = dest, .slot = destSlot}, .source = .{.inv = source, .slot = sourceSlot}, .amount = amount}}); -} - -pub fn takeHalf(source: Inventory, sourceSlot: u32, carried: Inventory) void { - main.sync.ClientSide.executeCommand(.{.takeHalf = .{.dest = .{.inv = carried, .slot = 0}, .source = .{.inv = source, .slot = sourceSlot}}}); -} - -pub fn distribute(carried: Inventory, destinationInventories: []const Inventory, destinationSlots: []const u32) void { - const amount = carried._items[0].amount/destinationInventories.len; - if(amount == 0) return; - for(0..destinationInventories.len) |i| { - destinationInventories[i].deposit(destinationSlots[i], carried, 0, @intCast(amount)); - } -} - -pub fn depositOrDrop(dest: Inventory, source: Inventory) void { - main.sync.ClientSide.executeCommand(.{.depositOrDrop = .{.dest = dest, .source = source, .dropLocation = undefined}}); -} - -pub fn depositToAny(source: Inventory, sourceSlot: u32, destinations: []const Inventory, amount: u16) void { - main.sync.ClientSide.executeCommand(.{.depositToAny = .init(destinations, .{.inv = source, .slot = sourceSlot}, amount)}); -} - -pub fn dropStack(source: Inventory, sourceSlot: u32) void { - main.sync.ClientSide.executeCommand(.{.drop = .{.source = .{.inv = source, .slot = sourceSlot}}}); -} - -pub fn dropOne(source: Inventory, sourceSlot: u32) void { - main.sync.ClientSide.executeCommand(.{.drop = .{.source = .{.inv = source, .slot = sourceSlot}, .desiredAmount = 1}}); -} - -pub fn fillFromCreative(dest: Inventory, destSlot: u32, item: Item) void { - main.sync.ClientSide.executeCommand(.{.fillFromCreative = .{.dest = .{.inv = dest, .slot = destSlot}, .item = item}}); -} - -pub fn fillAmountFromCreative(dest: Inventory, destSlot: u32, item: Item, amount: u16) void { - main.sync.ClientSide.executeCommand(.{.fillFromCreative = .{.dest = .{.inv = dest, .slot = destSlot}, .item = item, .amount = amount}}); -} - -pub fn placeBlock(self: Inventory, slot: u32) void { - main.renderer.MeshSelection.placeBlock(self, slot); -} - -pub fn breakBlock(self: Inventory, slot: u32, deltaTime: f64) void { - main.renderer.MeshSelection.breakBlock(self, slot, deltaTime); -} - pub fn size(self: Inventory) usize { return self._items.len; } diff --git a/src/block_entity.zig b/src/block_entity.zig index 8e2e518f7..5dcd044bb 100644 --- a/src/block_entity.zig +++ b/src/block_entity.zig @@ -251,7 +251,7 @@ pub const BlockEntityTypes = struct { pub fn onInteract(pos: Vec3i, _: *Chunk) main.callbacks.Result { main.network.protocols.blockEntityUpdate.sendClientDataUpdateToServer(main.game.world.?.conn, pos); - const inventory = main.items.Inventory.init(main.globalAllocator, inventorySize, .normal, .{.blockInventory = pos}, .{}); + const inventory = main.items.Inventory.ClientInventory.init(main.globalAllocator, inventorySize, .normal, .serverShared, .{.blockInventory = pos}, .{}); main.gui.windowlist.chest.setInventory(inventory); main.gui.openWindow("chest"); diff --git a/src/game.zig b/src/game.zig index 0f0202b07..a4c3c153b 100644 --- a/src/game.zig +++ b/src/game.zig @@ -5,7 +5,7 @@ const assets = @import("assets.zig"); const itemdrop = @import("itemdrop.zig"); const ClientItemDropManager = itemdrop.ClientItemDropManager; const items = @import("items.zig"); -const Inventory = items.Inventory; +const ClientInventory = items.Inventory.ClientInventory; const ZonElement = @import("zon.zig").ZonElement; const main = @import("main"); const network = @import("network.zig"); @@ -429,7 +429,7 @@ pub const Player = struct { // MARK: Player pub var hyperSpeed: Atomic(bool) = .init(false); pub var mutex: std.Thread.Mutex = .{}; pub const inventorySize = 32; - pub var inventory: Inventory = undefined; + pub var inventory: ClientInventory = undefined; pub var selectedSlot: u32 = 0; pub const defaultBlockDamage: f32 = 1; @@ -695,7 +695,7 @@ pub const World = struct { // MARK: World defer main.stackAllocator.free(path); try assets.loadWorldAssets(path, self.blockPalette, self.itemPalette, self.toolPalette, self.biomePalette); Player.id = zon.get(u32, "player_id", std.math.maxInt(u32)); - Player.inventory = Inventory.init(main.globalAllocator, Player.inventorySize, .normal, .{.playerInventory = Player.id}, .{}); + Player.inventory = ClientInventory.init(main.globalAllocator, Player.inventorySize, .normal, .serverShared, .{.playerInventory = Player.id}, .{}); Player.loadFrom(zon.getChild("player")); self.playerBiome = .init(main.server.terrain.biomes.getPlaceholderBiome()); main.audio.setMusic(self.playerBiome.raw.preferredMusic); diff --git a/src/gui/GuiWindow.zig b/src/gui/GuiWindow.zig index 7273142ef..77bf86087 100644 --- a/src/gui/GuiWindow.zig +++ b/src/gui/GuiWindow.zig @@ -63,7 +63,7 @@ closeIfMouseIsGrabbed: bool = false, closeable: bool = true, isHud: bool = false, -shiftClickableInventory: ?main.items.Inventory = null, +shiftClickableInventory: ?main.items.Inventory.ClientInventory = null, /// Called every frame. renderFn: *const fn() void = &defaultFunction, diff --git a/src/gui/components/ItemSlot.zig b/src/gui/components/ItemSlot.zig index 52320d847..4efc03c32 100644 --- a/src/gui/components/ItemSlot.zig +++ b/src/gui/components/ItemSlot.zig @@ -1,7 +1,7 @@ const std = @import("std"); const main = @import("main"); -const Inventory = main.items.Inventory; +const ClientInventory = main.items.Inventory.ClientInventory; const graphics = main.graphics; const draw = graphics.draw; const Texture = graphics.Texture; @@ -26,7 +26,7 @@ const Mode = enum { pos: Vec2f, size: Vec2f = @splat(sizeWithBorder), -inventory: Inventory, +inventory: ClientInventory, itemSlot: u32, lastItemAmount: u16 = 0, text: TextBuffer, @@ -69,7 +69,7 @@ pub fn __deinit() void { craftingResultTexture.deinit(); } -pub fn init(pos: Vec2f, inventory: Inventory, itemSlot: u32, texture: TextureParamType, mode: Mode) *ItemSlot { +pub fn init(pos: Vec2f, inventory: ClientInventory, itemSlot: u32, texture: TextureParamType, mode: Mode) *ItemSlot { const self = main.globalAllocator.create(ItemSlot); const amount = inventory.getAmount(itemSlot); var buf: [16]u8 = undefined; diff --git a/src/gui/gui.zig b/src/gui/gui.zig index 20193b598..6b2628876 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -591,8 +591,8 @@ pub fn toggleGameMenu() void { pub const inventory = struct { // MARK: inventory const ItemStack = main.items.ItemStack; - const Inventory = main.items.Inventory; - pub var carried: Inventory = undefined; + const ClientInventory = main.items.Inventory.ClientInventory; + pub var carried: ClientInventory = undefined; var carriedItemSlot: *ItemSlot = undefined; var leftClickSlots: List(*ItemSlot) = .init(main.globalAllocator); var rightClickSlots: List(*ItemSlot) = .init(main.globalAllocator); @@ -605,7 +605,7 @@ pub const inventory = struct { // MARK: inventory var isCrafting: bool = false; pub fn init() void { - carried = Inventory.init(main.globalAllocator, 1, .normal, .{.hand = main.game.Player.id}, .{}); + carried = ClientInventory.init(main.globalAllocator, 1, .normal, .serverShared, .{.hand = main.game.Player.id}, .{}); carriedItemSlot = ItemSlot.init(.{0, 0}, carried, 0, .default, .normal); carriedItemSlot.renderFrame = false; initialized = true; @@ -651,7 +651,7 @@ pub const inventory = struct { // MARK: inventory const mainGuiButton = main.KeyBoard.key("mainGuiButton"); const secondaryGuiButton = main.KeyBoard.key("secondaryGuiButton"); - if(itemSlot.inventory.type == .crafting and itemSlot.mode == .takeOnly and mainGuiButton.pressed and (recipeItem != .null or itemSlot.pressed)) { + if(itemSlot.inventory.super.type == .crafting and itemSlot.mode == .takeOnly and mainGuiButton.pressed and (recipeItem != .null or itemSlot.pressed)) { const item = itemSlot.inventory.getItem(itemSlot.itemSlot); if(recipeItem == .null and item != .null) recipeItem = item.clone(); if(!std.meta.eql(item, recipeItem)) return; @@ -679,7 +679,7 @@ pub const inventory = struct { // MARK: inventory if(itemSlot.mode != .normal) return; if(mainGuiButton.pressed and mainGuiButton.modsOnPress.shift) { - if(itemSlot.inventory.id == main.game.Player.inventory.id) { + if(itemSlot.inventory.super.id == main.game.Player.inventory.super.id) { var iterator = std.mem.reverseIterator(openWindows.items); while(iterator.next()) |window| { if(window.shiftClickableInventory) |inv| { @@ -719,7 +719,7 @@ pub const inventory = struct { // MARK: inventory recipeItem = .null; isCrafting = false; if(leftClickSlots.items.len != 0) { - const targetInventories = main.stackAllocator.alloc(Inventory, leftClickSlots.items.len); + const targetInventories = main.stackAllocator.alloc(ClientInventory, leftClickSlots.items.len); defer main.stackAllocator.free(targetInventories); const targetSlots = main.stackAllocator.alloc(u32, leftClickSlots.items.len); defer main.stackAllocator.free(targetSlots); @@ -730,7 +730,7 @@ pub const inventory = struct { // MARK: inventory carried.distribute(targetInventories, targetSlots); leftClickSlots.clearRetainingCapacity(); } else if(hoveredItemSlot) |hovered| { - if(hovered.inventory.type == .crafting and hovered.mode == .takeOnly) return; + if(hovered.inventory.super.type == .crafting and hovered.mode == .takeOnly) return; hovered.inventory.depositOrSwap(hovered.itemSlot, carried); } else if(!hoveredAWindow) { carried.dropStack(0); @@ -739,7 +739,7 @@ pub const inventory = struct { // MARK: inventory if(rightClickSlots.items.len != 0) { rightClickSlots.clearRetainingCapacity(); } else if(hoveredItemSlot) |hovered| { - if(hovered.inventory.type == .crafting and hovered.mode == .takeOnly) return; + if(hovered.inventory.super.type == .crafting and hovered.mode == .takeOnly) return; if(hovered.inventory.type == .creative) { carried.deposit(0, hovered.inventory, hovered.itemSlot, 1); } else { diff --git a/src/gui/windows/chest.zig b/src/gui/windows/chest.zig index bacb8575e..1e8283461 100644 --- a/src/gui/windows/chest.zig +++ b/src/gui/windows/chest.zig @@ -37,9 +37,9 @@ pub fn deinit() void { itemSlots.deinit(); } -pub var openInventory: main.items.Inventory = undefined; +pub var openInventory: main.items.Inventory.ClientInventory = undefined; -pub fn setInventory(selectedInventory: main.items.Inventory) void { +pub fn setInventory(selectedInventory: main.items.Inventory.ClientInventory) void { openInventory = selectedInventory; } diff --git a/src/gui/windows/creative_inventory.zig b/src/gui/windows/creative_inventory.zig index 09d920cfe..a37e62d28 100644 --- a/src/gui/windows/creative_inventory.zig +++ b/src/gui/windows/creative_inventory.zig @@ -2,7 +2,7 @@ const std = @import("std"); const main = @import("main"); const Item = main.items.Item; -const Inventory = main.items.Inventory; +const ClientInventory = main.items.Inventory.ClientInventory; const Player = main.game.Player; const Vec2f = main.vec.Vec2f; @@ -27,7 +27,7 @@ pub var window = GuiWindow{ const padding: f32 = 8; const slotsPerRow: u32 = 10; var items: main.List(Item) = undefined; -var inventory: Inventory = undefined; +var inventory: ClientInventory = undefined; var searchInput: *TextInput = undefined; var searchString: []const u8 = undefined; @@ -98,9 +98,9 @@ fn initContent() void { std.mem.sort(Item, items.items, {}, lessThan); const slotCount = items.items.len + (slotsPerRow - items.items.len%slotsPerRow); - inventory = Inventory.init(main.globalAllocator, slotCount, .creative, .other, .{}); + inventory = ClientInventory.init(main.globalAllocator, slotCount, .normal, .creative, .other, .{}); for(0..items.items.len) |i| { - inventory.fillAmountFromCreative(@intCast(i), items.items[i], 1); + inventory.super._items[i] = .{.item = items.items[i], .amount = 1}; } var i: u32 = 0; while(i < items.items.len) { diff --git a/src/gui/windows/inventory_crafting.zig b/src/gui/windows/inventory_crafting.zig index d43219b6c..0c9718fbf 100644 --- a/src/gui/windows/inventory_crafting.zig +++ b/src/gui/windows/inventory_crafting.zig @@ -3,7 +3,7 @@ const std = @import("std"); const main = @import("main"); const items = main.items; const BaseItemIndex = items.BaseItemIndex; -const Inventory = items.Inventory; +const ClientInventory = items.Inventory.ClientInventory; const ItemStack = items.ItemStack; const Player = main.game.Player; const Texture = main.graphics.Texture; @@ -34,7 +34,7 @@ const padding: f32 = 8; var availableItems: main.List(BaseItemIndex) = undefined; var itemAmount: main.List(u32) = undefined; -var inventories: main.List(Inventory) = undefined; +var inventories: main.List(ClientInventory) = undefined; pub var arrowTexture: Texture = undefined; @@ -92,7 +92,7 @@ fn findAvailableRecipes(list: *VerticalList) bool { } // All ingredients found: Add it to the list. if(recipe.cachedInventory == null) { - recipe.cachedInventory = Inventory.init(main.globalAllocator, recipe.sourceItems.len + 1, .crafting, .{.recipe = recipe}, .{}); + recipe.cachedInventory = ClientInventory.init(main.globalAllocator, recipe.sourceItems.len + 1, .crafting, .serverShared, .{.recipe = recipe}, .{}); } const inv = recipe.cachedInventory.?; inventories.append(inv); diff --git a/src/gui/windows/workbench.zig b/src/gui/windows/workbench.zig index 4193018a0..c0f20bf65 100644 --- a/src/gui/windows/workbench.zig +++ b/src/gui/windows/workbench.zig @@ -3,7 +3,7 @@ const std = @import("std"); const main = @import("main"); const items = main.items; const BaseItem = items.BaseItem; -const Inventory = items.Inventory; +const ClientInventory = items.Inventory.ClientInventory; const Item = items.Item; const Tool = items.Tool; const ToolType = items.ToolType; @@ -35,7 +35,7 @@ pub var window = GuiWindow{ const padding: f32 = 8; -var inv: Inventory = undefined; +var inv: ClientInventory = undefined; var itemSlots: [25]*ItemSlot = undefined; @@ -54,7 +54,7 @@ fn toggleTool() void { } fn openInventory() void { - inv = Inventory.init(main.globalAllocator, 26, .{.workbench = toolTypes.items[currentToolType]}, .other, .{}); + inv = ClientInventory.init(main.globalAllocator, 26, .{.workbench = toolTypes.items[currentToolType]}, .serverShared, .other, .{}); const list = HorizontalList.init(); { // crafting grid const grid = VerticalList.init(.{0, 0}, 300, 0); @@ -108,7 +108,7 @@ pub fn update() void { } pub fn render() void { - const currentResult = inv._items[25].item; + const currentResult = inv.getItem(25); if(currentResult == .null) return; const offsetX = 5*ItemSlot.sizeWithBorder + 20; diff --git a/src/items.zig b/src/items.zig index 8b879e641..0caa630f0 100644 --- a/src/items.zig +++ b/src/items.zig @@ -1061,7 +1061,7 @@ pub const Recipe = struct { // MARK: Recipe sourceAmounts: []u16, resultItem: BaseItemIndex, resultAmount: u16, - cachedInventory: ?Inventory = null, + cachedInventory: ?Inventory.ClientInventory = null, }; var toolTypeList: ListUnmanaged(ToolType) = .{}; diff --git a/src/renderer.zig b/src/renderer.zig index 5f6a5533d..4851d5038 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -974,7 +974,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection return true; // TODO: Check other entities } - pub fn placeBlock(inventory: main.items.Inventory, slot: u32) void { + pub fn placeBlock(inventory: main.items.Inventory.ClientInventory, slot: u32) void { if(selectedBlockPos) |selectedPos| { var oldBlock = mesh_storage.getBlockFromRenderThread(selectedPos[0], selectedPos[1], selectedPos[2]) orelse return; var block = oldBlock; @@ -1036,7 +1036,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection } } - pub fn breakBlock(inventory: main.items.Inventory, slot: u32, deltaTime: f64) void { + pub fn breakBlock(inventory: main.items.Inventory.ClientInventory, slot: u32, deltaTime: f64) void { if(selectedBlockPos) |selectedPos| { const stack = inventory.getStack(slot); const isSelectionWand = stack.item == .baseItem and std.mem.eql(u8, stack.item.baseItem.id(), "cubyz:selection_wand"); @@ -1106,10 +1106,10 @@ pub const MeshSelection = struct { // MARK: MeshSelection } } - fn updateBlockAndSendUpdate(source: main.items.Inventory, slot: u32, x: i32, y: i32, z: i32, oldBlock: blocks.Block, newBlock: blocks.Block) void { + fn updateBlockAndSendUpdate(source: main.items.Inventory.ClientInventory, slot: u32, x: i32, y: i32, z: i32, oldBlock: blocks.Block, newBlock: blocks.Block) void { main.sync.ClientSide.executeCommand(.{ .updateBlock = .{ - .source = .{.inv = source, .slot = slot}, + .source = .{.inv = source.super, .slot = slot}, .pos = .{x, y, z}, .dropLocation = .{ .dir = selectionFace, diff --git a/src/sync.zig b/src/sync.zig index 6b97108c8..f2c42dea1 100644 --- a/src/sync.zig +++ b/src/sync.zig @@ -787,7 +787,7 @@ pub const Command = struct { // MARK: Command if(source.ref().item == .null) return; // Can happen if the we didn't receive the inventory information from the server yet. const playerInventory: Inventory = switch(side) { - .client => main.game.Player.inventory, + .client => main.game.Player.inventory.super, .server => blk: { if(user) |_user| { var it = _user.inventoryClientToServerIdMap.valueIterator(); @@ -907,7 +907,7 @@ pub const Command = struct { // MARK: Command .alreadyFreed => unreachable, } switch(self.inv.type) { - .normal, .creative, .crafting => {}, + .normal, .crafting => {}, .workbench => { writer.writeSlice(self.inv.type.workbench.id()); }, @@ -950,7 +950,7 @@ pub const Command = struct { // MARK: Command .alreadyFreed => return error.Invalid, }; const typ: Inventory.Type = switch(typeEnum) { - inline .normal, .creative, .crafting => |tag| tag, + inline .normal, .crafting => |tag| tag, .workbench => .{.workbench = main.items.ToolTypeIndex.fromId(reader.remaining) orelse return error.Invalid}, }; try Inventory.ServerSide.createInventory(user.?, id, len, typ, source); @@ -994,10 +994,6 @@ pub const Command = struct { // MARK: Command fn run(self: DepositOrSwap, ctx: Context) error{serverFailure}!void { std.debug.assert(self.source.inv.type == .normal); - if(self.dest.inv.type == .creative) { - try FillFromCreative.run(.{.dest = self.source, .item = self.dest.ref().item}, ctx); - return; - } if(self.dest.inv.type == .crafting) { ctx.cmd.tryCraftingTo(ctx.allocator, self.source.inv, self.dest, ctx.side, ctx.user); return; @@ -1056,20 +1052,12 @@ pub const Command = struct { // MARK: Command amount: u16, fn run(self: Deposit, ctx: Context) error{serverFailure}!void { - if(self.source.inv.type != .normal and (self.source.inv.type != .creative or self.dest.inv.type != .normal)) return error.serverFailure; + if(self.source.inv.type != .normal and self.dest.inv.type != .normal) return error.serverFailure; if(self.dest.inv.type == .crafting) return; if(self.dest.inv.type == .workbench and (self.dest.slot == 25 or self.dest.inv.type.workbench.slotInfos()[self.dest.slot].disabled)) return; if(self.dest.inv.type == .workbench and !canPutIntoWorkbench(self.source)) return; const itemSource = self.source.ref().item; if(itemSource == .null) return; - if(self.source.inv.type == .creative) { - var amount: u16 = self.amount; - if(std.meta.eql(self.dest.ref().item, itemSource)) { - amount = @min(self.dest.ref().amount + self.amount, itemSource.stackSize()); - } - try FillFromCreative.run(.{.dest = self.dest, .item = itemSource, .amount = amount}, ctx); - return; - } const itemDest = self.dest.ref().item; if(itemDest != .null) { if(std.meta.eql(itemDest, itemSource)) { @@ -1112,13 +1100,6 @@ pub const Command = struct { // MARK: Command fn run(self: TakeHalf, ctx: Context) error{serverFailure}!void { std.debug.assert(self.dest.inv.type == .normal); - if(self.source.inv.type == .creative) { - if(self.dest.ref().item == .null) { - const item = self.source.ref().item; - try FillFromCreative.run(.{.dest = self.dest, .item = item}, ctx); - } - return; - } if(self.source.inv.type == .crafting) { ctx.cmd.tryCraftingTo(ctx.allocator, self.dest.inv, self.source, ctx.side, ctx.user); return; @@ -1176,7 +1157,6 @@ pub const Command = struct { // MARK: Command desiredAmount: u16 = 0xffff, fn run(self: Drop, ctx: Context) error{serverFailure}!void { - if(self.source.inv.type == .creative) return; if(self.source.ref().item == .null) return; if(self.source.inv.type == .crafting) { if(self.source.slot != self.source.inv._items.len - 1) return; @@ -1290,7 +1270,6 @@ pub const Command = struct { // MARK: Command pub fn run(self: DepositOrDrop, ctx: Context) error{serverFailure}!void { std.debug.assert(self.dest.type == .normal); - if(self.source.type == .creative) return; if(self.source.type == .crafting) return; var sourceItems = self.source._items; if(self.source.type == .workbench) sourceItems = self.source._items[0..25]; @@ -1350,9 +1329,11 @@ pub const Command = struct { // MARK: Command source: InventoryAndSlot, amount: u16, - pub fn init(destinations: []const Inventory, source: InventoryAndSlot, amount: u16) DepositToAny { + pub fn init(destinations: []const Inventory.ClientInventory, source: InventoryAndSlot, amount: u16) DepositToAny { + const copy = main.globalAllocator.alloc(Inventory, destinations.len); + for(copy, destinations) |*d, s| d.* = s.super; return .{ - .destinations = main.globalAllocator.dupe(Inventory, destinations), + .destinations = copy, .source = source, .amount = amount, }; @@ -1364,9 +1345,7 @@ pub const Command = struct { // MARK: Command fn run(self: DepositToAny, ctx: Context) error{serverFailure}!void { for(self.destinations) |dest| { - if(dest.type == .creative) return; - if(dest.type == .crafting) return; - if(dest.type == .workbench) return; + if(dest.type != .normal) return; } if(self.source.inv.type == .crafting) { ctx.cmd.tryCraftingTo(ctx.allocator, self.destinations[0], self.source, ctx.side, ctx.user); @@ -1456,7 +1435,6 @@ pub const Command = struct { // MARK: Command inv: Inventory, pub fn run(self: Clear, ctx: Context) error{serverFailure}!void { - if(self.inv.type == .creative) return; if(self.inv.type == .crafting) return; var items = self.inv._items; if(self.inv.type == .workbench) items = self.inv._items[0..25];