Skip to content

Commit 43eb8e0

Browse files
committed
PacketBreakBlock task init with the contents from the BreakBlock task for testing, and the start of the packet mine rewrite module
1 parent 8151f90 commit 43eb8e0

File tree

2 files changed

+292
-0
lines changed

2 files changed

+292
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.module.modules.player
19+
20+
import com.lambda.event.events.PlayerEvent
21+
import com.lambda.event.listener.SafeListener.Companion.listen
22+
import com.lambda.interaction.RotationManager
23+
import com.lambda.interaction.construction.context.BreakContext
24+
import com.lambda.interaction.material.StackSelection.Companion.select
25+
import com.lambda.interaction.material.container.ContainerManager.findBestAvailableTool
26+
import com.lambda.interaction.rotation.RotationContext
27+
import com.lambda.module.Module
28+
import com.lambda.module.modules.client.TaskFlowModule
29+
import com.lambda.module.tag.ModuleTag
30+
import com.lambda.task.TaskFlow.run
31+
import com.lambda.task.tasks.PacketBreakBlock
32+
import com.lambda.util.BlockUtils.blockState
33+
import com.lambda.util.BlockUtils.instantBreakable
34+
import com.lambda.util.math.VecUtils.vec3d
35+
import net.minecraft.block.BlockState
36+
import net.minecraft.util.Hand
37+
import net.minecraft.util.hit.BlockHitResult
38+
import net.minecraft.util.hit.HitResult
39+
import net.minecraft.util.math.BlockPos
40+
import net.minecraft.util.math.Direction
41+
42+
object PacketMineTaskRewrite : Module(
43+
"Packet Mine Rewrite",
44+
"A rewrite for the packet mine module to use the task system",
45+
setOf(ModuleTag.PLAYER)
46+
) {
47+
private val page by setting("Page", Page.General)
48+
49+
private val doubleBreak = setting(
50+
"Double Break",
51+
false,
52+
"Lets the player break two blocks at once"
53+
) { page == Page.General }
54+
private val breakThreshold = setting(
55+
"Break Threshold",
56+
0.7f,
57+
0.0f..1.1f,
58+
0.1f,
59+
"The time taken to break a block compared to vanilla speed (lower is faster)"
60+
) { page == Page.General }
61+
private val validateBreak = setting(
62+
"Validate Break",
63+
false,
64+
"Awaits the servers response before confirming the block to be broken"
65+
) { page == Page.General }
66+
private val useInventory = setting(
67+
"Use Inventory",
68+
false,
69+
"Allows usage of tools within the players inventory"
70+
) { page == Page.General }
71+
72+
private var primaryBreakTask: PacketBreakInfo? = null
73+
private var secondaryBreakTask: PacketBreakInfo? = null
74+
75+
init {
76+
listen<PlayerEvent.Attack.Block> { event ->
77+
event.cancel()
78+
79+
val pos = event.pos
80+
val vec3dPos = event.pos.vec3d
81+
val hitResult = BlockHitResult(vec3dPos, event.side, pos, false)
82+
val blockState = pos.blockState(world)
83+
val bestTool =
84+
findBestAvailableTool(blockState)?.select()?.itemStack
85+
?: player.mainHandStack
86+
87+
primaryBreakTask?.cancelBreak()
88+
primaryBreakTask = PacketBreakInfo(
89+
pos,
90+
blockState,
91+
player.activeHand,
92+
event.side,
93+
instantBreakable(blockState, pos, bestTool)
94+
).run()
95+
}
96+
97+
onDisable {
98+
99+
}
100+
}
101+
102+
class PacketBreakInfo(
103+
val pos: BlockPos,
104+
val blockState: BlockState,
105+
val hand: Hand,
106+
val side: Direction,
107+
instantBreak: Boolean
108+
) {
109+
private val breakContext: BreakContext
110+
private val packetBreakTask: PacketBreakBlock
111+
112+
init {
113+
val vec3dPos = pos.vec3d
114+
val rotation = RotationManager.currentRotation
115+
val hitResult = BlockHitResult(vec3dPos, side, pos, false)
116+
breakContext = BreakContext(
117+
vec3dPos,
118+
hitResult,
119+
RotationContext(rotation, TaskFlowModule.rotation, hitResult as HitResult),
120+
blockState,
121+
hand,
122+
instantBreak
123+
)
124+
packetBreakTask = PacketBreakBlock(
125+
breakContext
126+
)
127+
}
128+
129+
fun run(): PacketBreakInfo {
130+
packetBreakTask.run()
131+
return this
132+
}
133+
134+
fun cancelBreak() {
135+
packetBreakTask.cancel()
136+
}
137+
}
138+
139+
private enum class Page {
140+
General,
141+
Rebreak,
142+
Render
143+
}
144+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.task.tasks
19+
20+
import baritone.api.pathing.goals.GoalBlock
21+
import com.lambda.config.groups.InteractionConfig
22+
import com.lambda.config.groups.RotationConfig
23+
import com.lambda.context.SafeContext
24+
import com.lambda.event.events.TickEvent
25+
import com.lambda.event.events.WorldEvent
26+
import com.lambda.event.listener.SafeListener.Companion.listen
27+
import com.lambda.interaction.RotationManager.rotate
28+
import com.lambda.interaction.construction.context.BreakContext
29+
import com.lambda.interaction.visibilty.VisibilityChecker.lookAtBlock
30+
import com.lambda.module.modules.client.TaskFlowModule
31+
import com.lambda.task.Task
32+
import com.lambda.util.BaritoneUtils
33+
import com.lambda.util.BlockUtils.blockState
34+
import com.lambda.util.extension.inventorySlots
35+
import com.lambda.util.item.ItemUtils.block
36+
import com.lambda.util.player.SlotUtils.clickSlot
37+
import com.lambda.util.player.SlotUtils.hotbarAndStorage
38+
import net.minecraft.block.BlockState
39+
import net.minecraft.entity.ItemEntity
40+
import net.minecraft.screen.slot.SlotActionType
41+
import net.minecraft.util.math.BlockPos
42+
import net.minecraft.util.math.Direction
43+
44+
class PacketBreakBlock @Ta5kBuilder constructor(
45+
private val ctx: BreakContext,
46+
private val collectDrop: Boolean = false,
47+
private val rotation: RotationConfig = TaskFlowModule.rotation,
48+
private val interact: InteractionConfig = TaskFlowModule.interact,
49+
private val sides: Set<Direction> = Direction.entries.toSet(),
50+
private val rotate: Boolean = TaskFlowModule.build.rotateForBreak,
51+
private val swingHand: Boolean = TaskFlowModule.interact.swingHand,
52+
) : Task<ItemEntity?>() {
53+
override val name get() = "Packet breaking ${ctx.result.blockPos.toShortString()}"
54+
55+
val blockPos: BlockPos get() = ctx.result.blockPos
56+
57+
private var beginState: BlockState? = null
58+
val SafeContext.blockState: BlockState
59+
get() = blockPos.blockState(world)
60+
61+
private var drop: ItemEntity? = null
62+
private var state = State.BREAKING
63+
private var isValid = false
64+
65+
enum class State {
66+
BREAKING, COLLECTING
67+
}
68+
69+
override fun SafeContext.onStart() {
70+
if (done()) {
71+
success(null)
72+
return
73+
}
74+
75+
beginState = blockState
76+
77+
if (!rotate || ctx.instantBreak) {
78+
hitBlock(ctx.result.side)
79+
}
80+
}
81+
82+
init {
83+
rotate {
84+
onUpdate {
85+
if (state != State.BREAKING) return@onUpdate null
86+
if (!rotate || ctx.instantBreak) return@onUpdate null
87+
88+
lookAtBlock(blockPos, rotation, interact, sides)
89+
}
90+
onReceive { context ->
91+
isValid = context.isValid
92+
}
93+
}
94+
95+
listen<TickEvent.Pre> {
96+
drop?.let { itemDrop ->
97+
if (!world.entities.contains(itemDrop)) {
98+
BaritoneUtils.cancel()
99+
success(itemDrop)
100+
return@listen
101+
}
102+
103+
if (player.hotbarAndStorage.none { it.isEmpty }) {
104+
player.currentScreenHandler.inventorySlots.firstOrNull {
105+
it.stack.item.block in TaskFlowModule.inventory.disposables
106+
}?.let {
107+
clickSlot(it.id, 1, SlotActionType.THROW)
108+
}
109+
return@listen
110+
}
111+
112+
BaritoneUtils.setGoalAndPath(GoalBlock(itemDrop.blockPos))
113+
return@listen
114+
} ?: BaritoneUtils.cancel()
115+
116+
if (isValid || !rotate || ctx.instantBreak) {
117+
hitBlock(ctx.result.side)
118+
}
119+
120+
if (done()) {
121+
if (!collectDrop) {
122+
BaritoneUtils.cancel()
123+
success(null)
124+
}
125+
}
126+
}
127+
128+
// ToDo: Find out when the stack entity is filled with the item
129+
listen<WorldEvent.EntityUpdate> {
130+
if (collectDrop
131+
&& it.entity is ItemEntity
132+
&& it.entity.pos.isInRange(blockPos.toCenterPos(), 0.5)
133+
) {
134+
drop = it.entity
135+
state = State.COLLECTING
136+
}
137+
}
138+
}
139+
140+
private fun SafeContext.done() = blockState.isAir && !collectDrop
141+
142+
private fun SafeContext.hitBlock(side: Direction) {
143+
if (interaction.updateBlockBreakingProgress(blockPos, side)) {
144+
if (player.isCreative) interaction.blockBreakingCooldown = 0
145+
if (swingHand) player.swingHand(ctx.hand)
146+
}
147+
}
148+
}

0 commit comments

Comments
 (0)