diff --git a/assets/cubyz/items/selection_wand.zig.zon b/assets/cubyz/items/selection_wand.zig.zon new file mode 100644 index 00000000..0ab5a685 --- /dev/null +++ b/assets/cubyz/items/selection_wand.zig.zon @@ -0,0 +1,4 @@ +.{ + .texture = "selection_wand.png", + .stackSize = 1, +} diff --git a/assets/cubyz/items/textures/selection_wand.png b/assets/cubyz/items/textures/selection_wand.png new file mode 100644 index 00000000..6032041c Binary files /dev/null and b/assets/cubyz/items/textures/selection_wand.png differ diff --git a/src/network.zig b/src/network.zig index 24cfa80e..9fcb3990 100644 --- a/src/network.zig +++ b/src/network.zig @@ -973,19 +973,28 @@ pub const Protocols = struct { }, .worldEditPos => { const typ = try reader.readEnum(WorldEditPosition); - switch(typ) { - .selectedPos1, .selectedPos2 => { - const pos = try reader.readVec(Vec3i); - switch(typ) { - .selectedPos1 => game.Player.selectionPosition1 = pos, - .selectedPos2 => game.Player.selectionPosition2 = pos, - else => unreachable, - } - }, - .clear => { - game.Player.selectionPosition1 = null; - game.Player.selectionPosition2 = null; - }, + const pos: ?Vec3i = switch(typ) { + .selectedPos1, .selectedPos2 => try reader.readVec(Vec3i), + .clear => null, + }; + if(conn.isServerSide()) { + switch(typ) { + .selectedPos1 => conn.user.?.worldEditData.selectionPosition1 = pos.?, + .selectedPos2 => conn.user.?.worldEditData.selectionPosition2 = pos.?, + .clear => { + conn.user.?.worldEditData.selectionPosition1 = null; + conn.user.?.worldEditData.selectionPosition2 = null; + }, + } + } else { + switch(typ) { + .selectedPos1 => game.Player.selectionPosition1 = pos, + .selectedPos2 => game.Player.selectionPosition2 = pos, + .clear => { + game.Player.selectionPosition1 = null; + game.Player.selectionPosition2 = null; + }, + } } }, .timeAndBiome => { @@ -1789,6 +1798,10 @@ pub const Connection = struct { // MARK: Connection return self.connectionState.load(.unordered) == .connected; } + fn isServerSide(conn: *Connection) bool { + return conn.user != null; + } + fn handlePacketLoss(self: *Connection, loss: LossStatus) void { if(loss == .noLoss) return; self.slowStart = false; diff --git a/src/renderer.zig b/src/renderer.zig index eeedcf60..490173a1 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -840,6 +840,11 @@ pub const MeshSelection = struct { // MARK: MeshSelection } } } + if(std.mem.eql(u8, baseItem.id, "cubyz:selection_wand")) { + game.Player.selectionPosition2 = selectedPos; + main.network.Protocols.genericUpdate.sendWorldEditPos(main.game.world.?.conn, .selectedPos2, selectedPos); + return; + } }, .tool => |tool| { _ = tool; // TODO: Tools might change existing blocks. @@ -851,6 +856,14 @@ pub const MeshSelection = struct { // MARK: MeshSelection pub fn breakBlock(inventory: main.items.Inventory, slot: u32, deltaTime: f64) void { if(selectedBlockPos) |selectedPos| { + const stack = inventory.getStack(slot); + const isSelectionWand = stack.item != null and stack.item.? == .baseItem and std.mem.eql(u8, stack.item.?.baseItem.id, "cubyz:selection_wand"); + if(isSelectionWand) { + game.Player.selectionPosition1 = selectedPos; + main.network.Protocols.genericUpdate.sendWorldEditPos(main.game.world.?.conn, .selectedPos1, selectedPos); + return; + } + if(@reduce(.Or, lastSelectedBlockPos != selectedPos)) { mesh_storage.removeBreakingAnimation(lastSelectedBlockPos); lastSelectedBlockPos = selectedPos; @@ -863,7 +876,6 @@ pub const MeshSelection = struct { // MARK: MeshSelection main.items.Inventory.Sync.ClientSide.mutex.lock(); if(!game.Player.isCreative()) { - const stack = inventory.getStack(slot); var damage: f32 = 1; const isTool = stack.item != null and stack.item.? == .tool; if(isTool) {