Skip to content

Commit e721653

Browse files
committed
semi working
1 parent 11e9e7d commit e721653

File tree

4 files changed

+208
-21
lines changed

4 files changed

+208
-21
lines changed

common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import com.lambda.event.EventFlow;
2121
import com.lambda.event.events.PlayerEvent;
22-
import net.minecraft.client.MinecraftClient;
2322
import net.minecraft.client.network.ClientPlayerEntity;
2423
import net.minecraft.client.network.ClientPlayerInteractionManager;
2524
import net.minecraft.entity.Entity;
@@ -31,7 +30,6 @@
3130
import net.minecraft.util.hit.EntityHitResult;
3231
import net.minecraft.util.math.BlockPos;
3332
import net.minecraft.util.math.Direction;
34-
import org.spongepowered.asm.mixin.Final;
3533
import org.spongepowered.asm.mixin.Mixin;
3634
import org.spongepowered.asm.mixin.Shadow;
3735
import org.spongepowered.asm.mixin.injection.At;

common/src/main/kotlin/com/lambda/module/modules/player/PacketMineTaskRewrite.kt

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import com.lambda.util.BlockUtils.blockState
3333
import com.lambda.util.BlockUtils.instantBreakable
3434
import com.lambda.util.math.VecUtils.vec3d
3535
import net.minecraft.block.BlockState
36+
import net.minecraft.item.Item
3637
import net.minecraft.util.Hand
3738
import net.minecraft.util.hit.BlockHitResult
3839
import net.minecraft.util.hit.HitResult
@@ -61,6 +62,14 @@ object PacketMineTaskRewrite : Module(
6162
false,
6263
"Allows usage of tools within the players inventory"
6364
) { page == Page.General }
65+
private val interactionDelay by setting(
66+
"Interact Delay",
67+
0,
68+
0..10,
69+
1,
70+
"The delay between interacting with blocks",
71+
"ticks"
72+
) { page == Page.General }
6473

6574
private val reBreak by setting(
6675
"Re-Break",
@@ -90,14 +99,12 @@ object PacketMineTaskRewrite : Module(
9099
private val blockQueue = ArrayDeque<BlockPos>()
91100

92101
init {
93-
listen<PlayerEvent.Attack.Block> { event ->
102+
listen<PlayerEvent.Attack.Block>(1) { event ->
94103
event.cancel()
95104

96105
val pos = event.pos
97106
val blockState = pos.blockState(world)
98-
val bestTool =
99-
findBestAvailableTool(blockState)?.select()?.itemStack
100-
?: player.mainHandStack
107+
val bestTool = findBestAvailableTool(blockState)
101108

102109
if (doubleBreak && secondaryBreakTask == null) {
103110
secondaryBreakTask = primaryBreakTask
@@ -110,7 +117,12 @@ object PacketMineTaskRewrite : Module(
110117
blockState,
111118
player.activeHand,
112119
event.side,
113-
instantBreakable(blockState, pos, bestTool)
120+
bestTool,
121+
instantBreakable(
122+
blockState,
123+
pos,
124+
bestTool?.select()?.itemStack ?: player.mainHandStack
125+
)
114126
).run()
115127
}
116128

@@ -128,6 +140,7 @@ object PacketMineTaskRewrite : Module(
128140
val blockState: BlockState,
129141
val hand: Hand,
130142
val side: Direction,
143+
bestTool: Item?,
131144
instantBreak: Boolean
132145
) {
133146
private val breakContext: BreakContext
@@ -147,13 +160,13 @@ object PacketMineTaskRewrite : Module(
147160
)
148161
packetBreakTask = PacketBreakBlock(
149162
breakContext,
163+
bestTool,
150164
false,
151-
TaskFlowModule.rotation,
152-
TaskFlowModule.interact,
153-
validateBreak,
154-
Direction.entries.toSet(),
155-
TaskFlowModule.build.rotateForBreak,
156165
PacketBreakBlock.SwingHandStyle.Start,
166+
breakingTexture = true,
167+
breakingSound = true,
168+
breakingParticles = true,
169+
collectDrop = false
157170
)
158171
}
159172

common/src/main/kotlin/com/lambda/task/tasks/PacketBreakBlock.kt

Lines changed: 180 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,44 @@ import com.lambda.event.events.WorldEvent
2626
import com.lambda.event.listener.SafeListener.Companion.listen
2727
import com.lambda.interaction.RotationManager.rotate
2828
import com.lambda.interaction.construction.context.BreakContext
29+
import com.lambda.interaction.material.StackSelection.Companion.select
2930
import com.lambda.interaction.visibilty.VisibilityChecker.lookAtBlock
3031
import com.lambda.module.modules.client.TaskFlowModule
3132
import com.lambda.task.Task
3233
import com.lambda.util.BaritoneUtils
3334
import com.lambda.util.BlockUtils.blockState
35+
import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta
3436
import com.lambda.util.extension.inventorySlots
37+
import com.lambda.util.item.ItemStackUtils.equal
3538
import com.lambda.util.item.ItemUtils.block
3639
import com.lambda.util.player.SlotUtils.clickSlot
3740
import com.lambda.util.player.SlotUtils.hotbarAndStorage
3841
import net.minecraft.block.BlockState
42+
import net.minecraft.client.sound.PositionedSoundInstance
43+
import net.minecraft.client.sound.SoundInstance
3944
import net.minecraft.entity.ItemEntity
45+
import net.minecraft.item.Item
46+
import net.minecraft.item.ItemStack
4047
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket
4148
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action
4249
import net.minecraft.screen.slot.SlotActionType
50+
import net.minecraft.sound.SoundCategory
4351
import net.minecraft.util.math.BlockPos
4452
import net.minecraft.util.math.Direction
4553

4654
class PacketBreakBlock @Ta5kBuilder constructor(
4755
private val ctx: BreakContext,
56+
private var tool: Item?,
57+
private val validateBreak: Boolean = true,
58+
private val swingHand: SwingHandStyle = SwingHandStyle.Start,
59+
private val breakingTexture: Boolean = true,
60+
private val breakingSound: Boolean = true,
61+
private val breakingParticles: Boolean = true,
4862
private val collectDrop: Boolean = false,
4963
private val rotation: RotationConfig = TaskFlowModule.rotation,
5064
private val interact: InteractionConfig = TaskFlowModule.interact,
51-
private val validateBreak: Boolean = true,
5265
private val sides: Set<Direction> = Direction.entries.toSet(),
5366
private val rotate: Boolean = TaskFlowModule.build.rotateForBreak,
54-
private val swingHand: SwingHandStyle = SwingHandStyle.Start,
5567
) : Task<ItemEntity?>() {
5668
override val name get() = "Packet breaking ${ctx.result.blockPos.toShortString()}"
5769

@@ -65,7 +77,11 @@ class PacketBreakBlock @Ta5kBuilder constructor(
6577
private var state = State.BREAKING
6678
private var isValid = false
6779

68-
private var breakAmount = 0f
80+
private var previousToolStack: ItemStack? = null
81+
private var toolStack: ItemStack? = null
82+
private var toolSlot: Int = -1
83+
84+
private var pendingConfirmation = false
6985

7086
enum class State {
7187
BREAKING, COLLECTING
@@ -80,8 +96,9 @@ class PacketBreakBlock @Ta5kBuilder constructor(
8096
beginState = blockState
8197

8298
if (!rotate || ctx.instantBreak) {
99+
updateToolInformation()
83100
stepDamage(ctx.result.side)
84-
if (swingHand != SwingHandStyle.End) player.swingHand(ctx.hand)
101+
if (swingHand != SwingHandStyle.End && swingHand.notNone()) swing()
85102
}
86103
}
87104

@@ -120,7 +137,27 @@ class PacketBreakBlock @Ta5kBuilder constructor(
120137
} ?: BaritoneUtils.cancel()
121138

122139
if (isValid || !rotate || ctx.instantBreak) {
140+
updateToolInformation()
141+
if (!toolStack.equal(previousToolStack)) {
142+
val currentBlockState = blockState
143+
val currentBreakDelta = currentBlockState.calcItemBlockBreakingDelta(
144+
player, world, ctx.expectedPos, toolStack!!
145+
)
146+
val previousBreakDelta = currentBlockState.calcItemBlockBreakingDelta(
147+
player, world, ctx.expectedPos, toolStack!!
148+
)
149+
val multiplier = previousBreakDelta / currentBreakDelta
150+
interaction.currentBreakingProgress *= multiplier
151+
}
123152
stepDamage(ctx.result.side)
153+
if ((
154+
swingHand != SwingHandStyle.Start && swingHand.notNone()
155+
&& interaction.blockBreakingProgress >= 1.0f
156+
)
157+
|| swingHand == SwingHandStyle.Constant
158+
) {
159+
swing()
160+
}
124161
}
125162

126163
if (done()) {
@@ -145,14 +182,145 @@ class PacketBreakBlock @Ta5kBuilder constructor(
145182
}
146183

147184
private fun SafeContext.done() =
148-
!collectDrop && (blockState.isAir || (!validateBreak && breakAmount >= 1.0f))
185+
!collectDrop && blockState.isAir
186+
187+
private fun SafeContext.stepDamage(side: Direction) =
188+
updateBlockBreakingProgress(blockPos, side)
189+
190+
/**
191+
* modified version of the vanilla method to change some behaviours like removing the block breaking cooldown
192+
* and allow for validating the break by waiting for the server to respond
193+
*/
194+
private fun SafeContext.updateBlockBreakingProgress(pos: BlockPos, side: Direction): Boolean {
195+
if (interaction.currentGameMode.isCreative && world.worldBorder.contains(pos)) {
196+
interaction.sendSequencedPacket(world) { sequence: Int ->
197+
interaction.breakBlock(pos)
198+
PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, side, sequence)
199+
}
200+
return true
201+
}
202+
203+
if (!interaction.isCurrentlyBreaking(pos)) return attackBlock(pos, side)
204+
205+
val blockState: BlockState = world.getBlockState(pos)
206+
if (blockState.isAir) {
207+
interaction.breakingBlock = false
208+
return false
209+
}
210+
211+
interaction.currentBreakingProgress += blockState.calcItemBlockBreakingDelta(
212+
player,
213+
world,
214+
pos,
215+
toolStack!!
216+
)
217+
218+
if (breakingSound && interaction.blockBreakingSoundCooldown % 4.0f == 0.0f) {
219+
val blockSoundGroup = blockState.soundGroup
220+
mc
221+
.soundManager
222+
.play(
223+
PositionedSoundInstance(
224+
blockSoundGroup.hitSound,
225+
SoundCategory.BLOCKS,
226+
(blockSoundGroup.getVolume() + 1.0f) / 8.0f,
227+
blockSoundGroup.getPitch() * 0.5f,
228+
SoundInstance.createRandom(),
229+
pos
230+
)
231+
)
232+
}
233+
234+
interaction.blockBreakingSoundCooldown++
235+
if (interaction.currentBreakingProgress >= 1.0f) {
236+
interaction.breakingBlock = false
237+
interaction.sendSequencedPacket(world) { sequence: Int ->
238+
interaction.breakBlock(pos)
239+
PlayerActionC2SPacket(Action.STOP_DESTROY_BLOCK, pos, side, sequence)
240+
}
241+
interaction.blockBreakingSoundCooldown = 0.0f
242+
}
149243

150-
private fun SafeContext.stepDamage(side: Direction) {
151-
if (interaction.updateBlockBreakingProgress(blockPos, side)) {
152-
if (player.isCreative) interaction.blockBreakingCooldown = 0
244+
if (breakingTexture) {
245+
world.setBlockBreakingInfo(
246+
player.id,
247+
interaction.currentBreakingPos,
248+
interaction.blockBreakingProgress
249+
)
153250
}
251+
252+
return true
154253
}
155254

255+
/**
256+
* modified version of the vanilla method
257+
*/
258+
private fun SafeContext.attackBlock(pos: BlockPos, side: Direction): Boolean {
259+
if (player.isBlockBreakingRestricted(world, pos, interaction.currentGameMode)) return false
260+
if (!world.worldBorder.contains(pos)) return false
261+
262+
if (interaction.currentGameMode.isCreative) {
263+
interaction.sendSequencedPacket(world) { sequence: Int ->
264+
interaction.breakBlock(pos)
265+
PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, side, sequence)
266+
}
267+
} else if (!interaction.breakingBlock || !interaction.isCurrentlyBreaking(pos)) {
268+
if (interaction.breakingBlock) {
269+
connection.sendPacket(
270+
PlayerActionC2SPacket(
271+
Action.ABORT_DESTROY_BLOCK,
272+
interaction.currentBreakingPos, side
273+
)
274+
)
275+
}
276+
277+
val blockState: BlockState = world.getBlockState(pos)
278+
interaction.sendSequencedPacket(world) { sequence: Int ->
279+
val notAir = !blockState.isAir
280+
if (notAir && interaction.currentBreakingProgress == 0.0f) {
281+
blockState.onBlockBreakStart(world, pos, player)
282+
}
283+
284+
if (notAir && blockState.calcItemBlockBreakingDelta(player, world, pos, getToolItemStack()) >= 1.0f) {
285+
interaction.breakBlock(pos)
286+
} else {
287+
interaction.apply {
288+
breakingBlock = true
289+
currentBreakingPos = pos
290+
selectedStack = toolStack
291+
currentBreakingProgress = 0.0f
292+
blockBreakingSoundCooldown = 0.0f
293+
if (breakingTexture) {
294+
world.setBlockBreakingInfo(
295+
player.id,
296+
currentBreakingPos,
297+
blockBreakingProgress
298+
)
299+
}
300+
}
301+
}
302+
PlayerActionC2SPacket(Action.START_DESTROY_BLOCK, pos, side, sequence)
303+
}
304+
}
305+
306+
return true
307+
}
308+
309+
private fun SafeContext.updateToolInformation() {
310+
previousToolStack = toolStack
311+
toolStack = tool?.select()?.itemStack ?: player.mainHandStack
312+
if (previousToolStack == null) {
313+
previousToolStack = toolStack
314+
}
315+
toolSlot = player.inventory.getSlotWithStack(toolStack)
316+
}
317+
318+
private fun SafeContext.swing() =
319+
player.swingHand(player.activeHand)
320+
321+
private fun SafeContext.getToolItemStack(): ItemStack =
322+
tool?.select()?.itemStack ?: player.mainHandStack
323+
156324
private fun SafeContext.startBreakPacket(pos: BlockPos, direction: Direction) =
157325
breakPacket(pos, direction, Action.START_DESTROY_BLOCK)
158326

@@ -175,6 +343,9 @@ class PacketBreakBlock @Ta5kBuilder constructor(
175343
Constant,
176344
StartAndEnd,
177345
Start,
178-
End
346+
End,
347+
None;
348+
349+
fun notNone() = this != None
179350
}
180351
}

common/src/main/resources/lambda.accesswidener

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ accessible field net/minecraft/client/world/ClientChunkManager$ClientChunkMap ch
1616
accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingProgress F
1717
accessible field net/minecraft/client/network/ClientPlayerInteractionManager blockBreakingCooldown I
1818
accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingPos Lnet/minecraft/util/math/BlockPos;
19+
accessible method net/minecraft/client/network/ClientPlayerInteractionManager sendSequencedPacket (Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/client/network/SequencedPacketCreator;)V
20+
accessible method net/minecraft/client/network/ClientPlayerInteractionManager isCurrentlyBreaking (Lnet/minecraft/util/math/BlockPos;)Z
21+
accessible field net/minecraft/client/network/ClientPlayerInteractionManager blockBreakingSoundCooldown F
22+
accessible field net/minecraft/client/network/ClientPlayerInteractionManager breakingBlock Z
23+
accessible field net/minecraft/client/network/ClientPlayerInteractionManager selectedStack Lnet/minecraft/item/ItemStack;
1924

2025
# Entity
2126
accessible field net/minecraft/entity/projectile/FireworkRocketEntity shooter Lnet/minecraft/entity/LivingEntity;

0 commit comments

Comments
 (0)