@@ -52,7 +52,6 @@ import net.minecraft.client.sound.SoundInstance
5252import net.minecraft.client.world.ClientWorld
5353import net.minecraft.entity.ItemEntity
5454import net.minecraft.entity.player.PlayerEntity
55- import net.minecraft.item.ItemStack
5655import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket
5756import net.minecraft.sound.SoundCategory
5857import net.minecraft.util.math.BlockPos
@@ -75,85 +74,97 @@ object BreakManager : RequestHandler<BreakRequest>() {
7574
7675 private var blockBreakingCooldown = 0
7776
77+ private var instantBreaks = listOf<BreakContext >()
78+
7879 private var rotation: RotationRequest ? = null
7980 private var validRotation = false
8081
8182 init {
82- listen<TickEvent .Pre > {
83+ listen<TickEvent .Pre >(Int .MIN_VALUE ) {
84+ if (isOnBreakCooldown()) {
85+ blockBreakingCooldown--
86+ return @listen
87+ }
88+ if (PlaceManager .activeThisTick()) return @listen
89+
90+ currentRequest?.let request@ { request ->
91+ if (instantBreaks.isEmpty()) return @request
92+
93+ instantBreaks.forEach { ctx ->
94+ val breakInfo = with (request) {
95+ handleRequestContext(
96+ ctx,
97+ buildConfig, rotationConfig, hotbarConfig,
98+ onBreak, onItemDrop
99+ )
100+ } ? : return @request
101+ if (! breakInfo.requestHotbarSwap()) return @forEach
102+ updateBlockBreakingProgress(breakInfo)
103+ activeThisTick = true
104+ }
105+ instantBreaks = emptyList()
106+ }
107+
83108 if (! validRotation) return @listen
84109
110+ // Reversed so that the breaking order feels natural to the user as the primary break has to
111+ // be started after the secondary
85112 breakingInfos
86113 .filterNotNull()
87114 .reversed()
88115 .forEach { info ->
89- if (info.hotbarConfig.request(HotbarRequest (info.context.hotbarIndex)).done.not ()) return @forEach
90- updateBlockBreakingProgress(info, player.mainHandStack)
116+ if (! info.requestHotbarSwap()) return @forEach
117+ updateBlockBreakingProgress(info)
118+ activeThisTick = true
91119 }
92120 }
93121
94122 onRotate(priority = Int .MIN_VALUE ) {
95123 preEvent()
96124
97- if (isOnBreakCooldown()) {
98- blockBreakingCooldown--
99- updateRequest(true ) { true }
100- postEvent()
101- return @onRotate
102- }
103-
104- if (PlaceManager .activeThisTick()) {
105- updateRequest(true ) { true }
106- postEvent()
125+ if (! updateRequest { true }) {
126+ requestRotate()
107127 return @onRotate
108128 }
109129
110- // ToDo: improve instamine / non instamine integration
111- if (updateRequest { true }) {
112- currentRequest?.let request@ { request ->
113- var instaBreaks = 0
114- val config = breakingInfos.firstOrNull()?.breakConfig ? : request.buildConfig.breakSettings
115- val takeCount = config.maxPendingBreaks - (breakingInfos.count { it != null } + pendingInteractions.size)
116- request.contexts
117- .sortedBy { it.instantBreak }
118- .take(takeCount)
119- .forEach { requestCtx ->
120- if (! canAccept(requestCtx)) return @forEach
121- val breakType = with (request) {
122- handleRequestContext(requestCtx,
123- buildConfig, rotationConfig, hotbarConfig,
124- onBreak, onItemDrop
125- )
126- }
127- if (breakType == BreakType .Null ) return @request
128- if (requestCtx.instantBreak && instaBreaks < request.buildConfig.breakSettings.breaksPerTick) {
129- breakingInfos.getOrNull(breakType.index)?.let { info ->
130- if (request.hotbarConfig.request(HotbarRequest (info.context.hotbarIndex)).done.not ())
131- return @forEach
132- if (updateBlockBreakingProgress(info, player.mainHandStack)) {
133- instaBreaks++
134- activeThisTick = true
135- }
136- }
137- }
130+ currentRequest?.let request@ { request ->
131+ val breakConfig = request.buildConfig.breakSettings
132+ val takeCount = breakConfig.maxPendingBreaks - (breakingInfos.count { it != null } + pendingInteractions.size)
133+ val validContexts = request.contexts
134+ .filter { ctx -> canAccept(ctx) }
135+ .sortedBy { it.instantBreak }
136+ .take(takeCount)
137+
138+ instantBreaks = validContexts
139+ .take(breakConfig.breaksPerTick)
140+ .filter { it.instantBreak }
141+
142+ if (instantBreaks.isNotEmpty()) return @request
143+
144+ validContexts
145+ .filter { it.instantBreak.not () }
146+ .forEach { ctx ->
147+ val breakInfo = with (request) {
148+ handleRequestContext(
149+ ctx,
150+ buildConfig, rotationConfig, hotbarConfig,
151+ onBreak, onItemDrop
152+ )
138153 }
139- }
154+ if (breakInfo == null ) return @request
155+ }
140156 }
141157
142- breakingInfos
143- .filterNotNull()
144- .firstOrNull { it.breakConfig.rotateForBreak }
145- ?.let { info ->
146- rotation = info.rotationConfig.request(info.context.rotation)
147- }
158+ requestRotate()
148159 }
149160
150161 onRotatePost {
151- breakingInfos
162+ validRotation = breakingInfos
152163 .filterNotNull()
153- .firstOrNull()?. let { info ->
154- activeThisTick = true
155- validRotation = info.breakConfig.rotateForBreak && rotation?.done == true
156- }
164+ .firstOrNull()
165+ ?. let { info ->
166+ ! info.breakConfig.rotateForBreak || rotation?.done == true
167+ } ? : true
157168
158169 postEvent()
159170 }
@@ -206,36 +217,50 @@ object BreakManager : RequestHandler<BreakRequest>() {
206217 false
207218 }
208219
220+ private fun requestRotate () {
221+ rotation = breakingInfos
222+ .filterNotNull()
223+ .firstOrNull { it.breakConfig.rotateForBreak }
224+ ?.let { info ->
225+ info.rotationConfig.request(info.context.rotation)
226+ }
227+ }
228+
209229 private fun handleRequestContext (
210230 requestCtx : BreakContext ,
211231 buildConfig : BuildConfig ,
212232 rotationConfig : RotationConfig ,
213233 hotbarConfig : HotbarConfig ,
214234 onBreak : () -> Unit ,
215235 onItemDrop : (ItemEntity ) -> Unit
216- ): BreakType {
236+ ): BreakInfo ? {
217237 val breakInfo = BreakInfo (requestCtx, BreakType .Primary ,
218238 buildConfig.breakSettings, rotationConfig, hotbarConfig,
219239 onBreak, onItemDrop
220240 )
221241 primaryBreakingInfo?.let { primaryInfo ->
222- if (! primaryInfo.breakConfig.doubleBreak) return BreakType .Null
223- if (primaryInfo.startedWithSecondary) return BreakType .Null
242+ if (! primaryInfo.breakConfig.doubleBreak
243+ || primaryInfo.startedWithSecondary
244+ || secondaryBreakingInfo != null ) {
245+ return null
246+ }
247+
224248 if (! primaryInfo.breaking) {
225249 secondaryBreakingInfo = breakInfo.apply { type = BreakType .Secondary }
226- return BreakType .Secondary
227- } else {
228- primaryInfo.type = BreakType .Secondary
229- secondaryBreakingInfo = primaryInfo
230- primaryBreakingInfo = breakInfo
231- setPendingInteractionsLimits(buildConfig)
232- return BreakType .Primary
250+ return secondaryBreakingInfo
233251 }
234- } ? : run {
252+
253+ primaryInfo.type = BreakType .Secondary
254+ secondaryBreakingInfo = primaryInfo
235255 primaryBreakingInfo = breakInfo
256+
236257 setPendingInteractionsLimits(buildConfig)
237- return BreakType . Primary
258+ return primaryBreakingInfo
238259 }
260+
261+ primaryBreakingInfo = breakInfo
262+ setPendingInteractionsLimits(buildConfig)
263+ return primaryBreakingInfo
239264 }
240265
241266 private fun setPendingInteractionsLimits (buildConfig : BuildConfig ) {
@@ -248,7 +273,7 @@ object BreakManager : RequestHandler<BreakRequest>() {
248273 && breakingInfos.none { info -> info?.context?.expectedPos == ctx.expectedPos }
249274 && ! blockState(ctx.expectedPos).isAir
250275
251- private fun SafeContext.updateBlockBreakingProgress (info : BreakInfo , item : ItemStack ): Boolean {
276+ private fun SafeContext.updateBlockBreakingProgress (info : BreakInfo ): Boolean {
252277 val ctx = info.context
253278 val hitResult = ctx.result
254279
@@ -281,7 +306,7 @@ object BreakManager : RequestHandler<BreakRequest>() {
281306 player,
282307 world,
283308 ctx.expectedPos,
284- item
309+ player.mainHandStack
285310 ) * info.breakingTicks
286311
287312 if (info.breakConfig.sounds) {
@@ -452,6 +477,9 @@ object BreakManager : RequestHandler<BreakRequest>() {
452477 var soundsCooldown = 0.0f
453478 var startedWithSecondary = false
454479
480+ fun requestHotbarSwap () =
481+ hotbarConfig.request(HotbarRequest (context.hotbarIndex)).done
482+
455483 fun getBreakTextureProgress (player : PlayerEntity , world : ClientWorld ): Int {
456484 val breakDelta = context.checkedState.calcItemBlockBreakingDelta(
457485 player,
@@ -472,21 +500,18 @@ object BreakManager : RequestHandler<BreakRequest>() {
472500
473501 enum class BreakType (val index : Int ) {
474502 Primary (0 ),
475- Secondary (1 ),
476- Null (- 1 );
503+ Secondary (1 );
477504
478505 fun getBreakThreshold (breakConfig : BreakConfig ) =
479506 when (this ) {
480507 Primary -> breakConfig.breakThreshold
481508 Secondary -> 1.0f
482- else -> - 1.0f
483509 }
484510
485511 fun nullify () =
486512 when (this ) {
487513 Primary -> primaryBreakingInfo = null
488514 Secondary -> secondaryBreakingInfo = null
489- else -> {}
490515 }
491516 }
492517
0 commit comments