Skip to content

Commit 524f33b

Browse files
committed
pending interaction improvements
1 parent 9ce0fda commit 524f33b

File tree

5 files changed

+88
-75
lines changed

5 files changed

+88
-75
lines changed

common/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ data class BreakContext(
3838
override val pov: Vec3d,
3939
override val result: BlockHitResult,
4040
override val rotation: RotationRequest,
41-
override val checkedState: BlockState,
41+
override var checkedState: BlockState,
4242
override val targetState: TargetState,
4343
override var hotbarIndex: Int,
4444
var instantBreak: Boolean,

common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package com.lambda.interaction.construction.verify
1919

2020
import com.lambda.interaction.material.container.ContainerManager.findDisposable
2121
import com.lambda.module.modules.client.TaskFlowModule
22-
import com.lambda.util.BlockUtils.blockState
22+
import com.lambda.util.BlockUtils.matches
2323
import com.lambda.util.StringUtils.capitalize
2424
import com.lambda.util.item.ItemUtils.block
2525
import net.minecraft.block.BlockState
@@ -80,9 +80,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
8080
override fun toString() = "State of $blockState"
8181

8282
override fun matches(state: BlockState, pos: BlockPos, world: ClientWorld) =
83-
state.block == blockState.block && state.properties.all {
84-
/*it in TaskFlowModule.defaultIgnoreTags ||*/ state[it] == blockState[it]
85-
}
83+
state.matches(blockState)
8684

8785
override fun getStack(world: ClientWorld, pos: BlockPos): ItemStack =
8886
blockState.block.getPickStack(world, pos, blockState)

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

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

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

20+
import com.lambda.Lambda.mc
2021
import com.lambda.config.groups.BuildConfig
2122
import com.lambda.context.SafeContext
2223
import com.lambda.event.EventFlow.post
@@ -42,6 +43,7 @@ import com.lambda.module.modules.client.TaskFlowModule
4243
import com.lambda.util.BlockUtils.blockState
4344
import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta
4445
import com.lambda.util.BlockUtils.fluidState
46+
import com.lambda.util.BlockUtils.matches
4547
import com.lambda.util.Communication.info
4648
import com.lambda.util.Communication.warn
4749
import com.lambda.util.collections.LimitedDecayQueue
@@ -70,7 +72,10 @@ object BreakManager : RequestHandler<BreakRequest>(), PositionBlocking {
7072

7173
private val pendingInteractions = LimitedDecayQueue<BreakInfo>(
7274
TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
73-
) { info("${it::class.simpleName} at ${it.context.expectedPos.toShortString()} timed out") }
75+
) {
76+
info("${it::class.simpleName} at ${it.context.expectedPos.toShortString()} timed out")
77+
mc.world?.setBlockState(it.context.expectedPos, it.context.checkedState)
78+
}
7479

7580
override val blockedPositions
7681
get() = breakingInfos.mapNotNull { it?.context?.expectedPos } + pendingInteractions.map { it.context.expectedPos }
@@ -187,21 +192,36 @@ object BreakManager : RequestHandler<BreakRequest>(), PositionBlocking {
187192
pendingInteractions
188193
.firstOrNull { it.context.expectedPos == event.pos }
189194
?.let { pending ->
195+
// return if the state hasn't changed
196+
if (event.newState.matches(pending.context.checkedState))
197+
return@listen
198+
190199
pendingInteractions.remove(pending)
191-
if (!matchesTargetState(event.pos, pending.context.targetState, event.newState)) return@listen
192-
if (pending.breakConfig.breakConfirmation == BreakConfirmationMode.AwaitThenBreak)
200+
// return if the block's not broken
201+
if (!matchesTargetState(event.pos, pending.context.targetState, event.newState))
202+
return@listen
203+
204+
if (pending.breakConfig.breakConfirmation == BreakConfirmationMode.AwaitThenBreak) {
193205
destroyBlock(pending)
206+
}
194207
pending.onBreak()
208+
return@listen
195209
}
196-
?: breakingInfos
197-
.filterNotNull()
198-
.firstOrNull { it.context.expectedPos == event.pos }
199-
?.let { info ->
200-
if (!matchesTargetState(event.pos, info.context.targetState, event.newState)) return@listen
201-
info.nullify()
202-
destroyBlock(info)
203-
info.onBreak()
210+
211+
breakingInfos
212+
.filterNotNull()
213+
.firstOrNull { it.context.expectedPos == event.pos }
214+
?.let { info ->
215+
// if not broken
216+
if (!matchesTargetState(event.pos, info.context.targetState, event.newState)) {
217+
// update the checked state
218+
info.context.checkedState = event.newState
219+
return@listen
204220
}
221+
destroyBlock(info)
222+
info.onBreak()
223+
info.nullify()
224+
}
205225
}
206226

207227
//ToDo: drop callback stuff

common/src/main/kotlin/com/lambda/interaction/request/placing/PlaceManager.kt

Lines changed: 49 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

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

20-
import com.lambda.config.groups.BuildConfig
20+
import com.lambda.Lambda.mc
2121
import com.lambda.context.SafeContext
2222
import com.lambda.event.EventFlow.post
2323
import com.lambda.event.events.MovementEvent
@@ -36,6 +36,8 @@ import com.lambda.interaction.request.rotation.RotationManager.onRotate
3636
import com.lambda.interaction.request.rotation.RotationManager.onRotatePost
3737
import com.lambda.interaction.request.rotation.RotationRequest
3838
import com.lambda.module.modules.client.TaskFlowModule
39+
import com.lambda.util.BlockUtils.item
40+
import com.lambda.util.BlockUtils.matches
3941
import com.lambda.util.Communication.info
4042
import com.lambda.util.Communication.warn
4143
import com.lambda.util.collections.LimitedDecayQueue
@@ -56,15 +58,17 @@ import net.minecraft.util.Hand
5658
import net.minecraft.util.hit.BlockHitResult
5759
import net.minecraft.util.math.BlockPos
5860
import net.minecraft.world.GameMode
59-
import org.apache.commons.lang3.mutable.MutableObject
6061

6162
object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
62-
private val pendingInteractions = LimitedDecayQueue<PlaceInfo>(
63+
private val pendingInteractions = LimitedDecayQueue<PlaceRequest>(
6364
TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
64-
) { info("${it::class.simpleName} at ${it.context.expectedPos.toShortString()} timed out") }
65+
) {
66+
info("${it::class.simpleName} at ${it.placeContext.expectedPos.toShortString()} timed out")
67+
mc.world?.setBlockState(it.placeContext.expectedPos, it.placeContext.checkedState)
68+
}
6569

6670
override val blockedPositions
67-
get() = pendingInteractions.map { it.context.expectedPos }
71+
get() = pendingInteractions.map { it.placeContext.expectedPos }
6872

6973
private var rotation: RotationRequest? = null
7074
private var validRotation = false
@@ -95,6 +99,7 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
9599
return@listen
96100

97101
placeBlock(request, Hand.MAIN_HAND)
102+
activeThisTick = true
98103
}
99104
}
100105

@@ -117,8 +122,6 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
117122
return@onRotate
118123
}
119124

120-
activeThisTick = true
121-
122125
rotation = if (request.buildConfig.placeSettings.rotateForPlace)
123126
request.rotationConfig.request(request.placeContext.rotation)
124127
else null
@@ -139,20 +142,27 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
139142

140143
listen<WorldEvent.BlockUpdate.Server> { event ->
141144
pendingInteractions
142-
.firstOrNull { it.context.expectedPos == event.pos }
143-
?.let { pending ->
144-
pendingInteractions.remove(pending)
145-
if (!matchesTargetState(event.pos, pending.context.targetState, event.newState)) return@listen
146-
if (pending.buildConfig.placeSettings.placeConfirmationMode == PlaceConfig.PlaceConfirmationMode.AwaitThenPlace)
147-
placeSound(pending.item, pending.context.expectedState, pending.context.expectedPos)
148-
pending.onPlace()
145+
.firstOrNull { it.placeContext.expectedPos == event.pos }
146+
?.let { request ->
147+
pendingInteractions.remove(request)
148+
149+
// return if the block wasn't placed
150+
if (!matchesTargetState(event.pos, request.placeContext.targetState, event.newState))
151+
return@listen
152+
153+
if (request.buildConfig.placeSettings.placeConfirmationMode == PlaceConfig.PlaceConfirmationMode.AwaitThenPlace)
154+
with (request.placeContext) {
155+
placeSound(expectedState.block.item as BlockItem, expectedState, expectedPos)
156+
}
157+
request.onPlace()
158+
return@listen
149159
}
150160
}
151161
}
152162

153163
private fun canPlace(placeContext: PlaceContext) =
154164
pendingInteractions.none { pending ->
155-
pending.context.expectedPos == placeContext.expectedPos
165+
pending.placeContext.expectedPos == placeContext.expectedPos
156166
}
157167

158168
private fun SafeContext.matchesTargetState(pos: BlockPos, targetState: TargetState, newState: BlockState) =
@@ -162,48 +172,35 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
162172
false
163173
}
164174

165-
private fun SafeContext.placeBlock(request: PlaceRequest, hand: Hand) {
166-
val stackInHand = player.getStackInHand(hand)
167-
val item = stackInHand.item as? BlockItem ?: return
168-
val stackCountPre = stackInHand.count
169-
val actionResult = interactBlock(request.buildConfig.placeSettings, hand, request.placeContext.result)
170-
171-
if (actionResult.isAccepted) {
172-
if (request.buildConfig.placeSettings.placeConfirmationMode == PlaceConfig.PlaceConfirmationMode.None)
173-
request.onPlace()
174-
else {
175-
pendingInteractions.add(
176-
PlaceInfo(
177-
request.placeContext,
178-
item,
179-
request.buildConfig,
180-
request.onPlace
181-
)
182-
)
183-
}
184-
185-
if (actionResult.shouldSwingHand() && request.buildConfig.placeSettings.swing) {
186-
swingHand(request.buildConfig.placeSettings.swingType)
187-
}
175+
private fun SafeContext.placeBlock(request: PlaceRequest, hand: Hand) =
176+
interactBlock(request, request.buildConfig.placeSettings, hand, request.placeContext.result)
188177

189-
if (!stackInHand.isEmpty && (stackInHand.count != stackCountPre || interaction.hasCreativeInventory())) {
190-
mc.gameRenderer.firstPersonRenderer.resetEquipProgress(hand)
191-
}
192-
} else {
193-
warn("Placement interaction failed with $actionResult")
194-
}
195-
}
196-
197-
private fun SafeContext.interactBlock(placeConfig: PlaceConfig, hand: Hand, hitResult: BlockHitResult): ActionResult {
178+
private fun SafeContext.interactBlock(request: PlaceRequest, placeConfig: PlaceConfig, hand: Hand, hitResult: BlockHitResult) {
198179
interaction.syncSelectedSlot()
199-
if (!world.worldBorder.contains(hitResult.blockPos)) return ActionResult.FAIL
180+
if (!world.worldBorder.contains(hitResult.blockPos)) return
200181

201-
val mutableActionResult = MutableObject<ActionResult>()
202182
interaction.sendSequencedPacket(world) { sequence: Int ->
203-
mutableActionResult.value = interactBlockInternal(placeConfig, hand, hitResult)
183+
val stackInHand = player.getStackInHand(hand)
184+
val stackCountPre = stackInHand.count
185+
val actionResult = interactBlockInternal(placeConfig, hand, hitResult)
186+
if (actionResult.isAccepted) {
187+
if (request.buildConfig.placeSettings.placeConfirmationMode == PlaceConfig.PlaceConfirmationMode.None)
188+
request.onPlace()
189+
else
190+
pendingInteractions.add(request)
191+
192+
if (actionResult.shouldSwingHand() && request.buildConfig.placeSettings.swing) {
193+
swingHand(request.buildConfig.placeSettings.swingType)
194+
}
195+
196+
if (!stackInHand.isEmpty && (stackInHand.count != stackCountPre || interaction.hasCreativeInventory())) {
197+
mc.gameRenderer.firstPersonRenderer.resetEquipProgress(hand)
198+
}
199+
} else {
200+
warn("Placement interaction failed with $actionResult")
201+
}
204202
PlayerInteractBlockC2SPacket(hand, hitResult, sequence)
205203
}
206-
return mutableActionResult.value
207204
}
208205

209206
private fun SafeContext.interactBlockInternal(
@@ -212,7 +209,7 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
212209
hitResult: BlockHitResult
213210
): ActionResult {
214211
val itemStack = player.getStackInHand(hand)
215-
if (gamemode == GameMode.SPECTATOR) return ActionResult.SUCCESS
212+
if (gamemode == GameMode.SPECTATOR) return ActionResult.PASS
216213

217214
// checks if the player should be able to interact with the block for if its something
218215
// like a furnace or chest where an action would happen
@@ -297,13 +294,6 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
297294
)
298295
}
299296

300-
data class PlaceInfo(
301-
val context: PlaceContext,
302-
val item: BlockItem,
303-
val buildConfig: BuildConfig,
304-
val onPlace: () -> Unit
305-
)
306-
307297
override fun preEvent() = UpdateManagerEvent.Place.Pre().post()
308298
override fun postEvent() = UpdateManagerEvent.Place.Post().post()
309299
}

common/src/main/kotlin/com/lambda/util/BlockUtils.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ object BlockUtils {
236236
fun SafeContext.fluidState(pos: BlockPos): FluidState = world.getFluidState(pos)
237237
fun SafeContext.blockEntity(pos: BlockPos) = world.getBlockEntity(pos)
238238

239+
fun BlockState.matches(state: BlockState) =
240+
this.block == state.block && this.properties.all {
241+
/*it in TaskFlowModule.defaultIgnoreTags ||*/ this[it] == state[it]
242+
}
243+
239244
fun SafeContext.instantBreakable(blockState: BlockState, blockPos: BlockPos, breakThreshold: Float): Boolean {
240245
val ticksNeeded = 1 / (blockState.calcBlockBreakingDelta(player, world, blockPos) / breakThreshold)
241246
return (ticksNeeded <= 1 && ticksNeeded != 0f) || gamemode.isCreative

0 commit comments

Comments
 (0)