Skip to content

Commit b803bf1

Browse files
committed
sequence mode settings and an implementation in the place manager. Also a couple fixes for the hotbar manager
1 parent 6e2691d commit b803bf1

File tree

8 files changed

+85
-45
lines changed

8 files changed

+85
-45
lines changed

common/src/main/kotlin/com/lambda/config/groups/BreakSettings.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class BreakSettings(
3232
override val breakThreshold by c.setting("Break Threshold", 1.0f, 0.1f..1.0f, 0.02f, "The break amount at which the block is considered broken") { vis() }
3333
override val doubleBreak by c.setting("Double Break", false, "Allows breaking two blocks at once") { vis() }
3434
override val breakDelay by c.setting("Break Delay", 5, 0..5, 1, "The delay between breaking blocks", " ticks") { vis() }
35+
override val sequenceMode by c.setting("Break Sequence Mode", BuildConfig.InteractSequenceMode.PostMovement, "The sub-tick timing at which break actions are performed", vis)
3536
override val swing by c.setting("Swing Mode", SwingMode.Constant, "The times at which to swing the players hand") { vis() }
3637
override val swingType by c.setting("Break Swing Type", BuildConfig.SwingType.Vanilla, "The style of swing") { vis() && swing != SwingMode.None }
3738
override val sounds by c.setting("Break Sounds", true, "Plays the breaking sounds") { vis() }

common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,10 @@ interface BuildConfig {
3636
Server,
3737
Client
3838
}
39+
40+
enum class InteractSequenceMode {
41+
TickStart,
42+
Vanilla,
43+
PostMovement,
44+
}
3945
}

common/src/main/kotlin/com/lambda/config/groups/PlaceSettings.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class PlaceSettings(
2929
override val rotateForPlace by c.setting("Rotate For Place", true, "Rotate towards block while placing") { vis() }
3030
override val airPlace by c.setting("Air Place", AirPlaceMode.None, "Allows for placing blocks without adjacent faces") { vis() }
3131
override val axisRotateSetting by c.setting("Axis Rotate", true, "Overrides the Rotate For Place setting and rotates the player on each axis to air place rotational blocks") { vis() && airPlace.isEnabled() }
32+
override val sequenceMode by c.setting("Place Sequence Mode", BuildConfig.InteractSequenceMode.PostMovement, "The sub-tick timing at which break actions are performed") { vis() }
3233
override val placeConfirmationMode by c.setting("Place Confirmation", PlaceConfirmationMode.PlaceThenAwait, "Wait for block placement confirmation") { vis() }
3334
override val maxPendingPlacements by c.setting("Max Pending Placements", 5, 0..30, 1, "The maximum amount of pending placements") { vis() }
3435
override val placementsPerTick by c.setting("Places Per Tick", 1, 1..30, 1, "Maximum instant block places per tick") { vis() }

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ abstract class BreakConfig(
3030
abstract val breakThreshold: Float
3131
abstract val doubleBreak: Boolean
3232
abstract val breakDelay: Int
33+
abstract val sequenceMode: BuildConfig.InteractSequenceMode
3334
abstract val swing: SwingMode
3435
abstract val swingType: BuildConfig.SwingType
3536
abstract val sounds: Boolean

common/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarManager.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ object HotbarManager : RequestHandler<HotbarRequest>(), Loadable {
6969
listen<TickEvent.Pre>(priority = Int.MIN_VALUE) {
7070
preEvent()
7171

72-
swapsThisTick = 0
7372
if (swapDelay > 0) swapDelay--
7473

7574
if (requestMap.isNotEmpty()) {
@@ -122,14 +121,14 @@ object HotbarManager : RequestHandler<HotbarRequest>(), Loadable {
122121
slot: Int,
123122
keepTicks: Int = request.hotbarConfig.keepTicks
124123
): Boolean {
125-
request.swapSlot = SlotInfo(slot, keepTicks, request.hotbarConfig.swapDelay)
124+
request.swapSlot = SlotInfo(slot, keepTicks, request.hotbarConfig.swapPause)
126125
if (slot != currentSlotInfo?.slot) {
127126
if (swapsThisTick + 1 > maxSwapsThisTick || swapDelay > 0) {
128127
return false
129128
}
130129

131130
currentSlotInfo?.let { current ->
132-
if (current.activeRequestAge == 0 && (current.keepTicks > 0 || current.swapPause > 0)) {
131+
if (current.activeRequestAge == 0 && current.keepTicks > 0) {
133132
return false
134133
}
135134
}
@@ -141,7 +140,7 @@ object HotbarManager : RequestHandler<HotbarRequest>(), Loadable {
141140
}
142141
currentSlotInfo = request.swapSlot
143142
mc.interactionManager?.syncSelectedSlot()
144-
return true
143+
return request.done
145144
}
146145

147146
@ActionSequence
@@ -152,11 +151,12 @@ object HotbarManager : RequestHandler<HotbarRequest>(), Loadable {
152151

153152
data class SlotInfo(
154153
val slot: Int,
155-
var keepTicks: Int = 3,
156-
var swapPause: Int = 0
154+
var keepTicks: Int,
155+
var swapPause: Int
157156
) {
158157
var activeRequestAge = 0
159158
var swapPauseAge = 0
159+
val swapPaused get() = swapPauseAge < swapPause
160160
}
161161

162162
override fun preEvent() = UpdateManagerEvent.Hotbar.Pre().post()

common/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarRequest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class HotbarRequest(
2929

3030
var instantActionsComplete = false
3131
override val done: Boolean
32-
get() = swapSlot?.let { it.slot == HotbarManager.serverSlot && it.swapPauseAge >= it.swapPause } ?: true
32+
get() = swapSlot?.let { it.slot == HotbarManager.serverSlot && !it.swapPaused } ?: true
3333

3434
constructor (
3535
slot: Int,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ abstract class PlaceConfig(
3131
protected abstract val axisRotateSetting: Boolean
3232
val axisRotate
3333
get() = airPlace.isEnabled() && axisRotateSetting
34+
abstract val sequenceMode: BuildConfig.InteractSequenceMode
3435
abstract val placeConfirmationMode: PlaceConfirmationMode
3536
abstract val maxPendingPlacements: Int
3637
abstract val placementsPerTick: Int

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

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.lambda.interaction.request.placing
1919

2020
import com.lambda.Lambda.mc
21+
import com.lambda.config.groups.BuildConfig
2122
import com.lambda.context.SafeContext
2223
import com.lambda.event.EventFlow.post
2324
import com.lambda.event.events.MovementEvent
@@ -33,6 +34,7 @@ import com.lambda.interaction.request.RequestHandler
3334
import com.lambda.interaction.request.breaking.BreakManager
3435
import com.lambda.interaction.request.hotbar.HotbarManager
3536
import com.lambda.interaction.request.hotbar.HotbarRequest
37+
import com.lambda.interaction.request.rotation.RotationRequest
3638
import com.lambda.module.modules.client.TaskFlowModule
3739
import com.lambda.util.BlockUtils.blockState
3840
import com.lambda.util.BlockUtils.item
@@ -44,6 +46,7 @@ import com.lambda.util.player.isItemOnCooldown
4446
import com.lambda.util.player.swingHand
4547
import net.minecraft.block.BlockState
4648
import net.minecraft.block.pattern.CachedBlockPosition
49+
import net.minecraft.client.network.ClientPlayerEntity
4750
import net.minecraft.item.BlockItem
4851
import net.minecraft.item.ItemPlacementContext
4952
import net.minecraft.item.ItemStack
@@ -68,7 +71,19 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
6871
it.pendingInteractionsList.remove(it.context)
6972
}
7073

71-
private var shouldCrouch = false
74+
private var potentialPlacements = listOf<PlaceContext>()
75+
private var nextPredictedRotation: RotationRequest? = null
76+
77+
private var hotbarRequest: HotbarRequest? = null
78+
private val swappedTo: (Int) -> Boolean = { slot ->
79+
hotbarRequest?.let { hotbarRequest ->
80+
hotbarRequest.swapSlot?.slot == slot && hotbarRequest.done
81+
} ?: false
82+
}
83+
84+
private var shouldSneak = false
85+
private val validSneak: (player: ClientPlayerEntity) -> Boolean =
86+
{ player -> shouldSneak == player.isSneaking }
7287

7388
override val blockedPositions
7489
get() = pendingPlacements.map { it.context.expectedPos }
@@ -102,11 +117,11 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
102117

103118
currentRequest?.let request@ { request ->
104119
if (BreakManager.activeThisTick) return@request
120+
val placeConfig = request.buildConfig.placeSettings
105121

106-
pendingPlacements.setMaxSize(request.buildConfig.placeSettings.maxPendingPlacements)
122+
pendingPlacements.setMaxSize(placeConfig.maxPendingPlacements)
107123
pendingPlacements.setDecayTime(request.buildConfig.interactionTimeout * 50L)
108124

109-
val placeConfig = request.buildConfig.placeSettings
110125
val isSneaking = player.isSneaking
111126
val currentHotbarIndex = HotbarManager.serverSlot
112127
val placeContexts = request.placeContexts
@@ -118,50 +133,41 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
118133

119134
val maxPlacementsThisTick = (placeConfig.maxPendingPlacements - pendingPlacements.size).coerceAtLeast(0)
120135
val takeCount = (placeConfig.placementsPerTick.coerceAtMost(maxPlacementsThisTick))
121-
122-
val hotbarRequest = HotbarRequest(request.hotbarConfig) {
123-
placeContexts
124-
.take(takeCount)
125-
.forEach { ctx ->
126-
val notSneaking = !player.isSneaking
127-
val swapped = swapTo(ctx.hotbarIndex)
128-
if (placeConfig.rotate) {
129-
val rot = request.rotationConfig.request(ctx.rotation)
130-
if (!rot.done) {
131-
return@HotbarRequest
132-
}
133-
}
134-
if (ctx.sneak && notSneaking) {
135-
shouldCrouch = true
136-
return@HotbarRequest
137-
}
138-
if (!swapped) {
139-
return@HotbarRequest
140-
}
141-
142-
val actionResult = placeBlock(ctx, request, Hand.MAIN_HAND)
143-
if (!actionResult.isAccepted) {
144-
warn("Placement interaction failed with $actionResult")
145-
}
146-
activeThisTick = true
147-
}
148-
149-
placeContexts.getOrNull(takeCount)?.rotation?.let { rot ->
150-
request.rotationConfig.request(rot)
136+
nextPredictedRotation = if (request.rotationConfig.rotate) placeContexts.getOrNull(takeCount)?.rotation else null
137+
138+
hotbarRequest = HotbarRequest(request.hotbarConfig) {
139+
potentialPlacements = placeContexts.take(takeCount)
140+
potentialPlacements.forEach { ctx ->
141+
swapTo(ctx.hotbarIndex)
142+
if (request.buildConfig.placeSettings.rotate) request.rotationConfig.request(ctx.rotation)
143+
if (ctx.sneak) shouldSneak = true
144+
if (placeConfig.sequenceMode != BuildConfig.InteractSequenceMode.TickStart) return@HotbarRequest
145+
if (!attemptContextPlace(ctx, request)) return@HotbarRequest
151146
}
147+
requestNextPredictedRotation(request)
152148
done()
153149
}
154-
request.hotbarConfig.request(hotbarRequest)
150+
hotbarRequest?.let { hotbarRequest ->
151+
request.hotbarConfig.request(hotbarRequest)
152+
}
153+
if (potentialPlacements.isNotEmpty()) activeThisTick = true
155154
}
156155
}
157156

158-
listen<UpdateManagerEvent.Hotbar.Post>(priority = Int.MIN_VALUE) {
159-
postEvent()
157+
//ToDo: add mixin for vanilla place timings
158+
159+
listen<MovementEvent.Player.Post> {
160+
currentRequest?.let { request ->
161+
if (request.buildConfig.placeSettings.sequenceMode == BuildConfig.InteractSequenceMode.PostMovement) {
162+
handlePlacementContexts(request)
163+
postEvent()
164+
}
165+
}
160166
}
161167

162168
listen<MovementEvent.InputUpdate>(priority = Int.MIN_VALUE) {
163-
if (shouldCrouch) {
164-
shouldCrouch = false
169+
if (shouldSneak) {
170+
shouldSneak = false
165171
it.input.sneaking = true
166172
}
167173
}
@@ -186,6 +192,30 @@ object PlaceManager : RequestHandler<PlaceRequest>(), PositionBlocking {
186192
}
187193
}
188194

195+
private fun SafeContext.handlePlacementContexts(request: PlaceRequest): Boolean {
196+
potentialPlacements.forEach { ctx ->
197+
if (request.buildConfig.placeSettings.rotate) request.rotationConfig.request(ctx.rotation)
198+
if (ctx.sneak) shouldSneak = true
199+
if (!attemptContextPlace(ctx, request)) return false
200+
}
201+
requestNextPredictedRotation(request)
202+
return true
203+
}
204+
205+
private fun SafeContext.attemptContextPlace(ctx: PlaceContext, request: PlaceRequest): Boolean {
206+
if (!swappedTo(ctx.hotbarIndex) || !ctx.rotation.done || !validSneak(player)) return false
207+
208+
val actionResult = placeBlock(ctx, request, Hand.MAIN_HAND)
209+
if (!actionResult.isAccepted) {
210+
warn("Placement interaction failed with $actionResult")
211+
}
212+
return true
213+
}
214+
215+
private fun requestNextPredictedRotation(request: PlaceRequest) {
216+
nextPredictedRotation?.let { rot -> request.rotationConfig.request(rot) }
217+
}
218+
189219
private fun canPlace(placeContext: PlaceContext) =
190220
pendingPlacements.none { pending ->
191221
pending.context.expectedPos == placeContext.expectedPos

0 commit comments

Comments
 (0)