diff --git a/src/Inventory.zig b/src/Inventory.zig index 8438ddbf..87315c63 100644 --- a/src/Inventory.zig +++ b/src/Inventory.zig @@ -1551,8 +1551,8 @@ pub fn placeBlock(self: Inventory, slot: u32) void { main.renderer.MeshSelection.placeBlock(self, slot); } -pub fn breakBlock(self: Inventory, slot: u32) void { - main.renderer.MeshSelection.breakBlock(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 { diff --git a/src/game.zig b/src/game.zig index 91723504..6561d4bb 100644 --- a/src/game.zig +++ b/src/game.zig @@ -442,9 +442,9 @@ pub const Player = struct { // MARK: Player inventory.placeBlock(selectedSlot); } - pub fn breakBlock() void { // TODO: Breaking animation and tools + pub fn breakBlock(deltaTime: f64) void { if(!main.Window.grabbed) return; - inventory.breakBlock(selectedSlot); + inventory.breakBlock(selectedSlot, deltaTime); } pub fn acquireSelectedBlock() void { @@ -634,7 +634,7 @@ pub fn releasePlace() void { pub fn pressBreak() void { const time = std.time.milliTimestamp(); nextBlockBreakTime = time + main.settings.updateRepeatDelay; - Player.breakBlock(); + Player.breakBlock(0); } pub fn releaseBreak() void { @@ -894,9 +894,9 @@ pub fn update(deltaTime: f64) void { // MARK: update() } } if(nextBlockBreakTime) |*breakTime| { - if(time -% breakTime.* >= 0) { + if(time -% breakTime.* >= 0 or !Player.isCreative()) { breakTime.* += main.settings.updateRepeatSpeed; - Player.breakBlock(); + Player.breakBlock(deltaTime); } } diff --git a/src/renderer.zig b/src/renderer.zig index 6a2bdd01..9e139fa1 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -680,6 +680,8 @@ pub const MeshSelection = struct { // MARK: MeshSelection var posBeforeBlock: Vec3i = undefined; pub var selectedBlockPos: ?Vec3i = null; + var lastSelectedBlockPos: Vec3i = undefined; + var currentBlockProgress: f32 = 0; var selectionMin: Vec3f = undefined; var selectionMax: Vec3f = undefined; var lastPos: Vec3d = undefined; @@ -804,15 +806,45 @@ pub const MeshSelection = struct { // MARK: MeshSelection } } - pub fn breakBlock(inventory: main.items.Inventory, slot: u32) void { + pub fn breakBlock(inventory: main.items.Inventory, slot: u32, deltaTime: f64) void { if(selectedBlockPos) |selectedPos| { + if(@reduce(.Or, lastSelectedBlockPos != selectedPos)) { + lastSelectedBlockPos = selectedPos; + currentBlockProgress = 0; + } const block = mesh_storage.getBlock(selectedPos[0], selectedPos[1], selectedPos[2]) orelse return; - var newBlock = block; - // TODO: Breaking animation and tools. const relPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(selectedPos))); + main.items.Inventory.Sync.ClientSide.mutex.lock(); + if(!game.Player.isCreative()) { + const stack = inventory.getStack(slot); + var power: f32 = 0; + const isTool = stack.item != null and stack.item.? == .tool; + if(isTool) { + power = stack.item.?.tool.getPowerByBlockClass(block.blockClass()); + } + if(power >= block.breakingPower()) { + var breakTime: f32 = block.hardness(); + if(isTool) { + breakTime = breakTime*stack.item.?.tool.swingTime/power; + } + currentBlockProgress += @as(f32, @floatCast(deltaTime))/breakTime; + if(currentBlockProgress < 1) { + main.items.Inventory.Sync.ClientSide.mutex.unlock(); + return; + } else { + currentBlockProgress = 0; + } + } else { + main.items.Inventory.Sync.ClientSide.mutex.unlock(); + return; + } + } + + var newBlock = block; block.mode().onBlockBreaking(inventory.getStack(slot).item, relPos, lastDir, &newBlock); main.items.Inventory.Sync.ClientSide.mutex.unlock(); + if(!std.meta.eql(newBlock, block)) { updateBlockAndSendUpdate(inventory, slot, selectedPos[0], selectedPos[1], selectedPos[2], block, newBlock); }