diff --git a/src/Inventory.zig b/src/Inventory.zig index 68ed5b24e..21b6bf69a 100644 --- a/src/Inventory.zig +++ b/src/Inventory.zig @@ -1103,11 +1103,15 @@ pub const Command = struct { // MARK: Command }; } - fn tryCraftingTo(self: *Command, allocator: NeverFailingAllocator, dest: Inventory, source: InventoryAndSlot, side: Side, user: ?*main.server.User) void { // MARK: tryCraftingTo() + fn tryCraftingTo(self: *Command, allocator: NeverFailingAllocator, destinations: []const Inventory, source: InventoryAndSlot, side: Side, user: ?*main.server.User) void { // MARK: tryCraftingTo() std.debug.assert(source.inv.type == .crafting); - std.debug.assert(dest.type == .normal); + var destinationsCanHold = false; + for(destinations) |dest| { + std.debug.assert(dest.type == .normal); + if(dest.canHold(source.ref().*)) destinationsCanHold = true; + } + if(!destinationsCanHold) return; if(source.slot != source.inv._items.len - 1) return; - if(!dest.canHold(source.ref().*)) return; 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) { @@ -1160,16 +1164,18 @@ pub const Command = struct { // MARK: Command } var remainingAmount: u16 = source.ref().amount; - for(dest._items, 0..) |*destStack, destSlot| { - if(std.meta.eql(destStack.item, source.ref().item) or destStack.item == .null) { - const amount = @min(source.ref().item.stackSize() - destStack.amount, remainingAmount); - self.executeBaseOperation(allocator, .{.create = .{ - .dest = .{.inv = dest, .slot = @intCast(destSlot)}, - .amount = amount, - .item = source.ref().item, - }}, side); - remainingAmount -= amount; - if(remainingAmount == 0) break; + outer: for(destinations) |dest| { + for(dest._items, 0..) |*destStack, destSlot| { + if(std.meta.eql(destStack.item, source.ref().item) or destStack.item == .null) { + const amount = @min(source.ref().item.stackSize() - destStack.amount, remainingAmount); + self.executeBaseOperation(allocator, .{.create = .{ + .dest = .{.inv = dest, .slot = @intCast(destSlot)}, + .amount = amount, + .item = source.ref().item, + }}, side); + remainingAmount -= amount; + if(remainingAmount == 0) break :outer; + } } } std.debug.assert(remainingAmount == 0); @@ -1323,7 +1329,7 @@ pub const Command = struct { // MARK: Command return; } if(self.dest.inv.type == .crafting) { - ctx.cmd.tryCraftingTo(ctx.allocator, self.source.inv, self.dest, ctx.side, ctx.user); + ctx.cmd.tryCraftingTo(ctx.allocator, &.{self.source.inv}, self.dest, ctx.side, ctx.user); return; } if(self.dest.inv.type == .workbench and self.dest.slot != 25 and self.dest.inv.type.workbench.slotInfos()[self.dest.slot].disabled) return; @@ -1444,7 +1450,7 @@ pub const Command = struct { // MARK: Command return; } if(self.source.inv.type == .crafting) { - ctx.cmd.tryCraftingTo(ctx.allocator, self.dest.inv, self.source, ctx.side, ctx.user); + ctx.cmd.tryCraftingTo(ctx.allocator, &.{self.dest.inv}, self.source, ctx.side, ctx.user); return; } if(self.source.inv.type == .workbench and self.source.slot != 25 and self.source.inv.type.workbench.slotInfos()[self.source.slot].disabled) return; @@ -1512,7 +1518,7 @@ pub const Command = struct { // MARK: Command .source = undefined, .callbacks = .{}, }; - ctx.cmd.tryCraftingTo(ctx.allocator, temp, self.source, ctx.side, ctx.user); + ctx.cmd.tryCraftingTo(ctx.allocator, &.{temp}, self.source, ctx.side, ctx.user); std.debug.assert(ctx.cmd.baseOperations.pop().create.dest.inv._items.ptr == temp._items.ptr); // Remove the extra step from undo list (we cannot undo dropped items) if(_items[0].item != .null) { if(ctx.side == .server) { @@ -1693,7 +1699,7 @@ pub const Command = struct { // MARK: Command if(dest.type == .workbench) return; } if(self.source.inv.type == .crafting) { - ctx.cmd.tryCraftingTo(ctx.allocator, self.destinations[0], self.source, ctx.side, ctx.user); + ctx.cmd.tryCraftingTo(ctx.allocator, self.destinations, self.source, ctx.side, ctx.user); return; } const sourceStack = self.source.ref();