Skip to content

Commit 832a2a4

Browse files
committed
BrokenBlockHandler and removed preOpen and postClose in favor of onOpen and onClose
1 parent 770ec32 commit 832a2a4

File tree

6 files changed

+200
-158
lines changed

6 files changed

+200
-158
lines changed

common/src/main/kotlin/com/lambda/interaction/request/RequestHandler.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ import com.lambda.threading.runSafe
3131
*/
3232
abstract class RequestHandler<R : Request>(
3333
vararg openStages: TickStage,
34-
val preOpen: (SafeContext.() -> Unit)? = null,
35-
val onOpen: (SafeContext.() -> Unit)? = null,
36-
val postClose: (SafeContext.() -> Unit)? = null
34+
private val onOpen: (SafeContext.() -> Unit)? = null,
35+
private val onClose: (SafeContext.() -> Unit)? = null
3736
) {
3837
/**
3938
* Represents if the handler is accepting requests at any given time
@@ -77,18 +76,18 @@ abstract class RequestHandler<R : Request>(
7776
private inline fun <reified T : Event> openRequestsFor(stage: TickStage) {
7877
listen<T>(priority = Int.MAX_VALUE) {
7978
tickStage = stage
80-
preOpen?.invoke(this)
8179
queuedRequest?.let { request ->
8280
handleRequest(request)
8381
request.fresh = false
8482
queuedRequest = null
8583
}
8684
acceptingRequests = true
8785
onOpen?.invoke(this)
86+
preEvent()
8887
}
8988
listen<T>(priority = Int.MIN_VALUE) {
89+
onClose?.invoke(this)
9090
acceptingRequests = false
91-
postClose?.invoke(this)
9291
}
9392
}
9493

common/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt

Lines changed: 39 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
package com.lambda.interaction.request.breaking
1919

20-
import com.lambda.Lambda.mc
2120
import com.lambda.config.groups.TickStage
2221
import com.lambda.context.SafeContext
2322
import com.lambda.event.Event
@@ -37,26 +36,23 @@ import com.lambda.interaction.request.RequestHandler
3736
import com.lambda.interaction.request.breaking.BreakConfig.BreakConfirmationMode
3837
import com.lambda.interaction.request.breaking.BreakConfig.BreakMode
3938
import com.lambda.interaction.request.breaking.BreakManager.activeRequest
40-
import com.lambda.interaction.request.breaking.BreakManager.preEvent
4139
import com.lambda.interaction.request.breaking.BreakManager.processRequest
4240
import com.lambda.interaction.request.breaking.BreakType.Primary
41+
import com.lambda.interaction.request.breaking.BrokenBlockHandler.destroyBlock
42+
import com.lambda.interaction.request.breaking.BrokenBlockHandler.pendingBreaks
43+
import com.lambda.interaction.request.breaking.BrokenBlockHandler.setPendingConfigs
44+
import com.lambda.interaction.request.breaking.BrokenBlockHandler.startPending
4345
import com.lambda.interaction.request.hotbar.HotbarManager
4446
import com.lambda.interaction.request.placing.PlaceManager
4547
import com.lambda.interaction.request.rotation.RotationRequest
46-
import com.lambda.module.modules.client.TaskFlowModule
4748
import com.lambda.threading.runSafe
4849
import com.lambda.util.BlockUtils.blockState
4950
import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta
50-
import com.lambda.util.BlockUtils.fluidState
51-
import com.lambda.util.BlockUtils.matches
52-
import com.lambda.util.Communication.info
5351
import com.lambda.util.Communication.warn
54-
import com.lambda.util.collections.LimitedDecayQueue
5552
import com.lambda.util.item.ItemUtils.block
5653
import com.lambda.util.player.gamemode
5754
import com.lambda.util.player.swingHand
5855
import net.minecraft.block.BlockState
59-
import net.minecraft.block.OperatorBlock
6056
import net.minecraft.client.sound.PositionedSoundInstance
6157
import net.minecraft.client.sound.SoundInstance
6258
import net.minecraft.entity.ItemEntity
@@ -65,12 +61,10 @@ import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action
6561
import net.minecraft.sound.SoundCategory
6662
import net.minecraft.util.Hand
6763
import net.minecraft.util.math.BlockPos
68-
import net.minecraft.util.math.ChunkSectionPos
6964

7065
object BreakManager : RequestHandler<BreakRequest>(
7166
*TickStage.entries.toTypedArray(),
72-
preOpen = { activeRequest?.let { processRequest(it) } },
73-
onOpen = { preEvent() }
67+
onOpen = { activeRequest?.let { processRequest(it) } }
7468
), PositionBlocking {
7569
private var primaryBreak: BreakInfo?
7670
get() = breakInfos[0]
@@ -80,30 +74,12 @@ object BreakManager : RequestHandler<BreakRequest>(
8074
set(value) { breakInfos[1] = value }
8175
private val breakInfos = arrayOfNulls<BreakInfo>(2)
8276

83-
private val pendingBreaks = LimitedDecayQueue<BreakInfo>(
84-
TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
85-
) { info ->
86-
mc.world?.let { world ->
87-
val pos = info.context.expectedPos
88-
val loaded = world.isChunkLoaded(ChunkSectionPos.getSectionCoord(pos.x), ChunkSectionPos.getSectionCoord(pos.z))
89-
if (!loaded) return@let
90-
91-
info("${info::class.simpleName} at ${info.context.expectedPos.toShortString()} timed out")
92-
93-
val awaitThenBreak = info.breakConfig.breakConfirmation != BreakConfirmationMode.AwaitThenBreak
94-
if (!info.broken && awaitThenBreak) {
95-
world.setBlockState(info.context.expectedPos, info.context.checkedState)
96-
}
97-
}
98-
info.pendingInteractions.remove(info.context)
99-
}
10077
private val pendingBreakCount get() = breakInfos.count { it != null } + pendingBreaks.size
101-
102-
private var activeRequest: BreakRequest? = null
103-
10478
override val blockedPositions
10579
get() = breakInfos.mapNotNull { it?.context?.expectedPos } + pendingBreaks.map { it.context.expectedPos }
10680

81+
private var activeRequest: BreakRequest? = null
82+
10783
private var rotationRequest: RotationRequest? = null
10884
private val rotated get() = rotationRequest?.done != false
10985

@@ -140,29 +116,6 @@ object BreakManager : RequestHandler<BreakRequest>(
140116
}
141117

142118
listen<WorldEvent.BlockUpdate.Server>(priority = Int.MIN_VALUE + 1) { event ->
143-
pendingBreaks
144-
.firstOrNull { it.context.expectedPos == event.pos }
145-
?.let { pending ->
146-
// return if the state hasn't changed
147-
if (event.newState.matches(pending.context.checkedState))
148-
return@listen
149-
150-
// return if the block's not broken
151-
if (!matchesTargetState(event.pos, pending.context.targetState, event.newState)) {
152-
pending.stopPending()
153-
return@listen
154-
}
155-
156-
if (pending.breakConfig.breakConfirmation == BreakConfirmationMode.AwaitThenBreak) {
157-
destroyBlock(pending)
158-
}
159-
pending.internalOnBreak()
160-
if (pending.callbacksCompleted) {
161-
pending.stopPending()
162-
}
163-
return@listen
164-
}
165-
166119
breakInfos
167120
.filterNotNull()
168121
.firstOrNull { it.context.expectedPos == event.pos }
@@ -185,15 +138,6 @@ object BreakManager : RequestHandler<BreakRequest>(
185138
// ToDo: Dependent on the tracked data order. When set stack is called after position it wont work
186139
listen<EntityEvent.EntityUpdate>(priority = Int.MIN_VALUE + 1) {
187140
if (it.entity !is ItemEntity) return@listen
188-
pendingBreaks
189-
.firstOrNull { info -> matchesBlockItem(info, it.entity) }
190-
?.let { pending ->
191-
pending.internalOnItemDrop(it.entity)
192-
if (pending.callbacksCompleted) {
193-
pending.stopPending()
194-
}
195-
return@listen
196-
}
197141

198142
breakInfos
199143
.filterNotNull()
@@ -203,7 +147,6 @@ object BreakManager : RequestHandler<BreakRequest>(
203147

204148
listenUnsafe<ConnectionEvent.Connect.Pre>(priority = Int.MIN_VALUE + 1) {
205149
breakInfos.forEach { it?.nullify() }
206-
pendingBreaks.clear()
207150
breakCooldown = 0
208151
}
209152
}
@@ -286,6 +229,20 @@ object BreakManager : RequestHandler<BreakRequest>(
286229
maxBreaksThisTick = breakConfig.breaksPerTick.coerceAtMost(pendingLimit)
287230
}
288231

232+
/**
233+
* @return if the break context can be accepted.
234+
*/
235+
private fun SafeContext.canAccept(ctx: BreakContext): Boolean {
236+
if (pendingBreaks.any { it.context.expectedPos == ctx.expectedPos }) return false
237+
238+
breakInfos.firstOrNull { it != null && !it.isRedundant }
239+
?.let { info ->
240+
if ( ctx.hotbarIndex != info.context.hotbarIndex) return false
241+
}
242+
243+
return !blockState(ctx.expectedPos).isAir
244+
}
245+
289246
/**
290247
* Attempts to break as many [BreakContext]'s as possible from the [instantBreaks] collection within this tick.
291248
*
@@ -359,8 +316,7 @@ object BreakManager : RequestHandler<BreakRequest>(
359316
}
360317

361318
primaryBreak = breakInfo
362-
pendingBreaks.setSizeLimit(request.build.breaking.maxPendingBreaks)
363-
pendingBreaks.setDecayTime(request.build.interactionTimeout * 50L)
319+
setPendingConfigs(request)
364320
return primaryBreak
365321
}
366322

@@ -372,41 +328,6 @@ object BreakManager : RequestHandler<BreakRequest>(
372328
return breakInfos.take(possibleBreakingCount).all { it != null }
373329
}
374330

375-
/**
376-
* @return if the [ItemEntity] matches the [BreakInfo]'s expected item drop.
377-
*/
378-
private fun matchesBlockItem(info: BreakInfo, entity: ItemEntity): Boolean {
379-
val inRange = info.context.expectedPos.toCenterPos().isInRange(entity.pos, 0.5)
380-
val correctMaterial = info.context.checkedState.block == entity.stack.item.block
381-
return inRange && correctMaterial
382-
}
383-
384-
/**
385-
* @return if the [newState] matches the [targetState].
386-
*
387-
* @see TargetState
388-
*/
389-
private fun SafeContext.matchesTargetState(pos: BlockPos, targetState: TargetState, newState: BlockState) =
390-
if (targetState.matches(newState, pos, world)) true
391-
else {
392-
this@BreakManager.warn("Break at ${pos.toShortString()} was rejected with $newState instead of $targetState")
393-
false
394-
}
395-
396-
/**
397-
* @return if the break context can be accepted.
398-
*/
399-
private fun SafeContext.canAccept(ctx: BreakContext): Boolean {
400-
if (pendingBreaks.any { it.context.expectedPos == ctx.expectedPos }) return false
401-
402-
breakInfos.firstOrNull { it != null && !it.isRedundant }
403-
?.let { info ->
404-
if ( ctx.hotbarIndex != info.context.hotbarIndex) return false
405-
}
406-
407-
return !blockState(ctx.expectedPos).isAir
408-
}
409-
410331
/**
411332
* Begins the post-break logic sequence for the given [info].
412333
*
@@ -446,22 +367,6 @@ object BreakManager : RequestHandler<BreakRequest>(
446367
info.nullify()
447368
}
448369

449-
/**
450-
* Adds the [info] to the break manager, and requesters, pending interaction collections.
451-
*/
452-
private fun BreakInfo.startPending() {
453-
pendingBreaks.add(this)
454-
pendingInteractions.add(context)
455-
}
456-
457-
/**
458-
* Removes the [info] from the break manager, and requesters, pending interation collections.
459-
*/
460-
private fun BreakInfo.stopPending() {
461-
pendingBreaks.remove(this)
462-
pendingInteractions.remove(context)
463-
}
464-
465370
/**
466371
* Makes the [BreakInfo] a secondary if not already.
467372
*/
@@ -686,35 +591,25 @@ object BreakManager : RequestHandler<BreakRequest>(
686591
}
687592

688593
/**
689-
* A modified version of the minecraft breakBlock method.
690-
*
691-
* Performs the actions required to display break particles, sounds, texture overlay, etc.
692-
* based on the users settings.
693-
*
694-
* @return if the blocks state was set or not.
695-
*
696-
* @see net.minecraft.client.world.ClientWorld.breakBlock
594+
* @return if the [ItemEntity] matches the [BreakInfo]'s expected item drop.
697595
*/
698-
private fun SafeContext.destroyBlock(info: BreakInfo): Boolean {
699-
val ctx = info.context
700-
701-
if (player.isBlockBreakingRestricted(world, ctx.expectedPos, gamemode)) return false
702-
703-
if (!player.mainHandStack.item.canMine(ctx.checkedState, world, ctx.expectedPos, player))
704-
return false
705-
val block = ctx.checkedState.block
706-
if (block is OperatorBlock && !player.isCreativeLevelTwoOp) return false
707-
if (ctx.checkedState.isAir) return false
708-
709-
block.onBreak(world, ctx.expectedPos, ctx.checkedState, player)
710-
val fluidState = fluidState(ctx.expectedPos)
711-
val setState = world.setBlockState(ctx.expectedPos, fluidState.blockState, 11)
712-
if (setState) block.onBroken(world, ctx.expectedPos, ctx.checkedState)
713-
714-
if (info.breakConfig.breakingTexture) info.setBreakingTextureStage(player, world, -1)
715-
716-
return setState
596+
fun matchesBlockItem(info: BreakInfo, entity: ItemEntity): Boolean {
597+
val inRange = info.context.expectedPos.toCenterPos().isInRange(entity.pos, 0.5)
598+
val correctMaterial = info.context.checkedState.block == entity.stack.item.block
599+
return inRange && correctMaterial
717600
}
718601

602+
/**
603+
* @return if the [newState] matches the [targetState].
604+
*
605+
* @see TargetState
606+
*/
607+
fun SafeContext.matchesTargetState(pos: BlockPos, targetState: TargetState, newState: BlockState) =
608+
if (targetState.matches(newState, pos, world)) true
609+
else {
610+
this@BreakManager.warn("Break at ${pos.toShortString()} was rejected with $newState instead of $targetState")
611+
false
612+
}
613+
719614
override fun preEvent(): Event = UpdateManagerEvent.Break().post()
720615
}

0 commit comments

Comments
 (0)