@@ -46,13 +46,14 @@ import com.lambda.interaction.request.breaking.BreakManager.breakInfos
4646import com.lambda.interaction.request.breaking.BreakManager.breaks
4747import com.lambda.interaction.request.breaking.BreakManager.canAccept
4848import com.lambda.interaction.request.breaking.BreakManager.cancelBreak
49+ import com.lambda.interaction.request.breaking.BreakManager.checkForCancels
4950import com.lambda.interaction.request.breaking.BreakManager.initNewBreak
5051import com.lambda.interaction.request.breaking.BreakManager.instantBreaks
51- import com.lambda.interaction.request.breaking.BreakManager.makeRedundant
5252import com.lambda.interaction.request.breaking.BreakManager.maxBreaksThisTick
5353import com.lambda.interaction.request.breaking.BreakManager.performInstantBreaks
5454import com.lambda.interaction.request.breaking.BreakManager.processNewBreaks
5555import com.lambda.interaction.request.breaking.BreakManager.processRequest
56+ import com.lambda.interaction.request.breaking.BreakManager.simulateAbandoned
5657import com.lambda.interaction.request.breaking.BreakManager.updateBreakProgress
5758import com.lambda.interaction.request.breaking.BreakType.Primary
5859import com.lambda.interaction.request.breaking.BreakType.ReBreak
@@ -91,7 +92,8 @@ object BreakManager : RequestHandler<BreakRequest>(
9192 TickEvent .Input .Pre ,
9293 TickEvent .Input .Post ,
9394 TickEvent .Player .Post ,
94- onOpen = { processRequest(activeRequest) }
95+ onOpen = { simulateAbandoned(); processRequest(activeRequest) },
96+ onClose = { checkForCancels() }
9597), PositionBlocking {
9698 private var primaryBreak: BreakInfo ?
9799 get() = breakInfos[0 ]
@@ -134,41 +136,12 @@ object BreakManager : RequestHandler<BreakRequest>(
134136 override fun load (): String {
135137 super .load()
136138
137- listen<TickEvent .Pre >(priority = Int .MAX_VALUE ) {
138- // Cancelled but double breaking so requires break manager to continue the simulation
139- breakInfos
140- .asSequence()
141- .filterNotNull()
142- .filter { it.abandoned && ! it.isRedundant }
143- .forEach { info ->
144- with (info.request) {
145- info.context.blockPos
146- .toStructure(TargetState .Empty )
147- .toBlueprint()
148- .simulate(player.eyePos, interact, rotation, inventory, build)
149- .asSequence()
150- .filterIsInstance<BreakResult .Break >()
151- .sorted()
152- .let { sim ->
153- info.updateInfo(sim.firstOrNull()?.context ? : return @forEach)
154- }
155- }
156- }
157- }
158-
159139 listen<TickEvent .Post >(priority = Int .MIN_VALUE ) {
160140 if (breakCooldown > 0 ) {
161141 breakCooldown--
162142 }
163143 breakInfos.forEach { info ->
164- info?.apply {
165- if (isRedundant) updateBreakProgress(this )
166- else if (! updatedThisTick) {
167- this .cancelBreak()
168- return @apply
169- }
170- tickStats()
171- }
144+ info?.tickStats()
172145 }
173146 activeRequest = null
174147 breaks = mutableListOf ()
@@ -305,7 +278,7 @@ object BreakManager : RequestHandler<BreakRequest>(
305278 }
306279 .asReversed()
307280 .forEach { info ->
308- if (info.updatedProgressThisTick ) return @forEach
281+ if (info.progressedThisTick ) return @forEach
309282 val minKeepTicks = if (info.isSecondary) {
310283 val breakDelta = info.context.cachedState.calcBreakDelta(
311284 player,
@@ -334,6 +307,39 @@ object BreakManager : RequestHandler<BreakRequest>(
334307 }
335308 }
336309
310+ private fun SafeContext.simulateAbandoned () {
311+ // Cancelled but double breaking so requires break manager to continue the simulation
312+ breakInfos
313+ .asSequence()
314+ .filterNotNull()
315+ .filter { it.abandoned && ! it.isRedundant }
316+ .forEach { info ->
317+ with (info.request) {
318+ info.context.blockPos
319+ .toStructure(TargetState .Empty )
320+ .toBlueprint()
321+ .simulate(player.eyePos, interact, rotation, inventory, build)
322+ .asSequence()
323+ .filterIsInstance<BreakResult .Break >()
324+ .sorted()
325+ .let { sim ->
326+ info.updateInfo(sim.firstOrNull()?.context ? : return @forEach)
327+ }
328+ }
329+ }
330+ }
331+
332+ private fun SafeContext.checkForCancels () {
333+ breakInfos
334+ .filterNotNull()
335+ .asSequence()
336+ .filter { ! it.updatedThisTick && tickStage in it.breakConfig.breakStageMask }
337+ .forEach { info ->
338+ if (info.isRedundant && ! info.progressedThisTick) updateBreakProgress(info)
339+ else info.cancelBreak()
340+ }
341+ }
342+
337343 /* *
338344 * Filters the requests [BreakContext]s, and iterates over the [breakInfos] collection looking for matches
339345 * in positions. If a match is found, the [BreakInfo] is updated with the new context. Otherwise, the break is cancelled.
@@ -362,15 +368,13 @@ object BreakManager : RequestHandler<BreakRequest>(
362368 newBreaks.find { ctx -> ctx.blockPos == info.context.blockPos }?.let { ctx ->
363369 if (! info.updatedThisTick || info.abandoned) {
364370 info.updateInfo(ctx, request)
365- if (info.isRedundant) {
366- info.type = BreakType .Secondary
371+ if (info.isRedundant)
367372 info.request.onStart?.invoke(info.context.blockPos)
368- } else if (info.abandoned) {
373+ else if (info.abandoned) {
369374 info.abandoned = false
370375 info.request.onStart?.invoke(info.context.blockPos)
371- } else {
376+ } else
372377 info.request.onUpdate?.invoke(info.context.blockPos)
373- }
374378 }
375379 newBreaks.remove(ctx)
376380 return @forEach
@@ -552,8 +556,6 @@ object BreakManager : RequestHandler<BreakRequest>(
552556 *
553557 * If the user has [BreakConfig.unsafeCancels] enabled, the info is made redundant, and mostly ignored.
554558 * If not, the break continues.
555- *
556- * @see makeRedundant
557559 */
558560 private fun BreakInfo.cancelBreak () =
559561 runSafe {
@@ -564,7 +566,7 @@ object BreakManager : RequestHandler<BreakRequest>(
564566 request.onCancel?.invoke(context.blockPos)
565567 } else if (isSecondary) {
566568 if (breakConfig.unsafeCancels) {
567- makeRedundant()
569+ type = BreakType . RedundantSecondary
568570 setBreakingTextureStage(player, world, - 1 )
569571 request.onCancel?.invoke(context.blockPos)
570572 } else {
@@ -578,13 +580,6 @@ object BreakManager : RequestHandler<BreakRequest>(
578580 */
579581 private fun BreakInfo.nullify () = type.nullify()
580582
581- /* *
582- * Makes the [BreakInfo] redundant and triggers the [BreakInfo.internalOnCancel] callback
583- */
584- private fun BreakInfo.makeRedundant () {
585- type = BreakType .RedundantSecondary
586- }
587-
588583 /* *
589584 * Nullifies the [BreakInfo] reference in the [breakInfos] array based on the [BreakType]
590585 */
@@ -603,8 +598,9 @@ object BreakManager : RequestHandler<BreakRequest>(
603598 * @see net.minecraft.client.network.ClientPlayerInteractionManager.updateBlockBreakingProgress
604599 */
605600 private fun SafeContext.updateBreakProgress (info : BreakInfo ): Boolean {
601+ info.progressedThisTick = true
602+
606603 val config = info.breakConfig
607- info.updatedProgressThisTick = true
608604 val ctx = info.context
609605 val hitResult = ctx.result
610606
0 commit comments