Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Inventory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub const ServerSide = struct { // MARK: ServerSide
if (self.managed == .internallyManaged) {
if (self.inv.type.shouldDepositToUserOnClose()) {
const playerInventory = getInventoryFromSource(.{.playerInventory = user.id}) orelse @panic("Could not find player inventory");
sync.ServerSide.executeCommand(.{.depositOrDrop = .{.dest = playerInventory, .source = self.inv, .dropLocation = user.player.pos}}, null);
sync.ServerSide.executeCommand(.{.depositOrDrop = .initWithInventories(&.{playerInventory}, self.inv, user.player.pos)}, null);
}
inventoryCreationMutex.lock();
defer inventoryCreationMutex.unlock();
Expand Down Expand Up @@ -445,10 +445,10 @@ pub const ClientInventory = struct { // MARK: ClientInventory
}
}

pub fn depositOrDrop(dest: ClientInventory, source: ClientInventory) void {
std.debug.assert(dest.type == .serverShared);
pub fn depositOrDrop(source: ClientInventory, destinations: []const ClientInventory) void {
for (destinations) |dest| 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}});
main.sync.ClientSide.executeCommand(.{.depositOrDrop = .init(destinations, source.super, undefined)});
}

pub fn depositToAny(source: ClientInventory, sourceSlot: u32, destinations: []const ClientInventory, amount: u16) void {
Expand Down
2 changes: 1 addition & 1 deletion src/gui/gui.zig
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ pub fn toggleGameMenu() void {
if (!main.Window.grabbed) {
hideGui = false;
} else { // Take of the currently held item stack and close some windows
main.game.Player.inventory.depositOrDrop(inventory.carried);
inventory.carried.depositOrDrop(&.{main.game.Player.inventory});
hoveredItemSlot = null;
var i: usize = 0;
while (i < openWindows.items.len) {
Expand Down
49 changes: 43 additions & 6 deletions src/sync.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1330,18 +1330,42 @@ pub const Command = struct { // MARK: Command
};

const DepositOrDrop = struct { // MARK: DepositOrDrop
dest: Inventory,
destinations: []const Inventory,
source: Inventory,
dropLocation: Vec3d,

pub fn init(destinations: []const Inventory.ClientInventory, source: Inventory, dropLocation: Vec3d) DepositOrDrop {
const copy = main.globalAllocator.alloc(Inventory, destinations.len);
for (copy, destinations) |*d, s| d.* = s.super;
return .{
.destinations = copy,
.source = source,
.dropLocation = dropLocation,
};
}

pub fn initWithInventories(destinations: []const Inventory, source: Inventory, dropLocation: Vec3d) DepositOrDrop {
return .{
.destinations = main.globalAllocator.dupe(Inventory, destinations),
.source = source,
.dropLocation = dropLocation,
};
}

fn finalize(self: DepositOrDrop, _: Side, _: *BinaryReader) !void {
main.globalAllocator.free(self.destinations);
}

pub fn run(self: DepositOrDrop, ctx: Context) error{serverFailure}!void {
std.debug.assert(self.dest.type == .normal);
for (self.destinations) |dest| {
std.debug.assert(dest.type == .normal);
}
if (self.source.type == .crafting) return;
var sourceItems = self.source._items;
if (self.source.type == .workbench) sourceItems = self.source._items[0..25];
for (sourceItems, 0..) |*sourceStack, sourceSlot| {
if (sourceStack.item == .null) continue;
put_items_into.do(ctx, &.{self.dest}, sourceStack.amount, .{.move = .{.inv = self.source, .slot = @intCast(sourceSlot)}});
put_items_into.do(ctx, self.destinations, sourceStack.amount, .{.move = .{.inv = self.source, .slot = @intCast(sourceSlot)}});
if (sourceStack.amount == 0) continue;
if (ctx.side == .server) {
const direction = if (ctx.user) |_user| vec.rotateZ(vec.rotateX(Vec3f{0, 1, 0}, -_user.player.rot[0]), -_user.player.rot[2]) else Vec3f{0, 0, 0};
Expand All @@ -1355,15 +1379,28 @@ pub const Command = struct { // MARK: Command
}

fn serialize(self: DepositOrDrop, writer: *BinaryWriter) void {
writer.writeEnum(InventoryId, self.dest.id);
writer.writeVarInt(usize, self.destinations.len);
for (self.destinations) |dest| {
writer.writeEnum(InventoryId, dest.id);
}
writer.writeEnum(InventoryId, self.source.id);
}

fn deserialize(reader: *BinaryReader, side: Side, user: ?*main.server.User) !DepositOrDrop {
const destId = try reader.readEnum(InventoryId);
const destinationsSize = try reader.readVarInt(usize);
if (destinationsSize == 0) return error.Invalid;
if (destinationsSize*@sizeOf(InventoryId) >= reader.remaining.len) return error.Invalid;

const destinations = main.globalAllocator.alloc(Inventory, destinationsSize);
errdefer main.globalAllocator.free(destinations);

for (destinations) |*dest| {
const invId = try reader.readEnum(InventoryId);
dest.* = Inventory.getInventory(invId, side, user) orelse return error.InventoryNotFound;
}
const sourceId = try reader.readEnum(InventoryId);
return .{
.dest = Inventory.getInventory(destId, side, user) orelse return error.InventoryNotFound,
.destinations = destinations[0..],
.source = Inventory.getInventory(sourceId, side, user) orelse return error.InventoryNotFound,
.dropLocation = (user orelse return error.Invalid).player.pos,
};
Expand Down