Skip to content

Commit fbd505b

Browse files
committed
abide by break sequence timings
1 parent 37c28b9 commit fbd505b

File tree

1 file changed

+79
-54
lines changed
  • common/src/main/kotlin/com/lambda/interaction/request/breaking

1 file changed

+79
-54
lines changed

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

Lines changed: 79 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.lambda.context.SafeContext
2323
import com.lambda.event.EventFlow.post
2424
import com.lambda.event.events.ConnectionEvent
2525
import com.lambda.event.events.EntityEvent
26+
import com.lambda.event.events.MovementEvent
2627
import com.lambda.event.events.UpdateManagerEvent
2728
import com.lambda.event.events.WorldEvent
2829
import com.lambda.event.listener.SafeListener.Companion.listen
@@ -131,57 +132,7 @@ object BreakManager : RequestHandler<BreakRequest>(), PositionBlocking {
131132
?: breakInfos.firstOrNull { it != null }?.request?.hotbarConfig
132133
?: return@listen
133134

134-
hotbarRequest = HotbarRequest(hotbarConfig) {
135-
if (isOnBreakCooldown()) {
136-
blockBreakingCooldown--
137-
} else if (currentRequest == null) {
138-
breakInfos.forEach { it?.cancelBreak() }
139-
} else currentRequest?.let request@ { request ->
140-
val breakConfig = request.buildConfig.breakSettings
141-
142-
newBreaks = request.contexts
143-
.filter { ctx -> canAccept(ctx) }
144-
.sortedWith(
145-
compareByDescending<BreakContext> { it.instantBreak }
146-
.thenByDescending { it.hotbarIndex == HotbarManager.serverSlot }
147-
).toMutableList()
148-
149-
refreshOrCancelBreaks(newBreaks, request)
150-
if (atMaxBreakInfos(breakConfig)) return@request
151-
152-
val maxBreaks = getMaxBreaks(breakConfig)
153-
if (maxBreaks <= 0) return@request
154-
val maxInstantBreaks = breakConfig.instantBreaksPerTick.coerceAtMost(maxBreaks)
155-
156-
val uncappedInstantBreaks = newBreaks.filter { it.instantBreak }
157-
instantBreaks = uncappedInstantBreaks.take(maxInstantBreaks)
158-
excessInstantBreaks = uncappedInstantBreaks.size > instantBreaks.size
159-
160-
instantBreaks.forEach { ctx ->
161-
if (!swapTo(ctx.hotbarIndex)) return@request
162-
val breakInfo = handleNewBreak(ctx, request) ?: return@request
163-
request.onAccept?.invoke(ctx.expectedPos)
164-
updateBreakProgress(breakInfo)
165-
}
166-
if (excessInstantBreaks) return@request
167-
processNewBreaks(newBreaks, request)
168-
}
169-
170-
updateLiveBreakInfos()
171-
rotation = liveBreakInfos.firstOrNull { it.breakConfig.rotateForBreak }?.let { info ->
172-
info.rotationConfig.request(info.context.rotation)
173-
}
174-
175-
// Reversed so that the breaking order feels natural to the user as the primary break has to
176-
// be started after the secondary
177-
liveBreakInfos
178-
.reversed()
179-
.forEach { info ->
180-
if (!swapTo(info.context.hotbarIndex) || !validRotation) return@HotbarRequest
181-
updateBreakProgress(info)
182-
}
183-
done()
184-
}
135+
hotbarRequest = HotbarRequest(hotbarConfig) { if (update(::swapTo, tickPre = true)) done() }
185136
hotbarRequest?.let { hotbarRequest ->
186137
hotbarConfig.request(hotbarRequest)
187138
}
@@ -190,6 +141,15 @@ object BreakManager : RequestHandler<BreakRequest>(), PositionBlocking {
190141
}
191142
}
192143

144+
listen<MovementEvent.Player.Post> {
145+
val sequenceMode = currentRequest?.buildConfig?.breakSettings?.sequenceMode
146+
?: breakInfos.find { it != null }?.breakConfig?.sequenceMode
147+
?: return@listen
148+
if (sequenceMode == BuildConfig.InteractSequenceMode.PostMovement) {
149+
update(null)
150+
}
151+
}
152+
193153
listen<WorldEvent.BlockUpdate.Server>(priority = Int.MIN_VALUE + 1) { event ->
194154
pendingBreaks
195155
.firstOrNull { it.context.expectedPos == event.pos }
@@ -259,14 +219,75 @@ object BreakManager : RequestHandler<BreakRequest>(), PositionBlocking {
259219
}
260220
}
261221

222+
private fun SafeContext.update(swapTo: ((slot: Int) -> Boolean)?, tickPre: Boolean = false): Boolean {
223+
if (tickPre) {
224+
if (isOnBreakCooldown()) {
225+
blockBreakingCooldown--
226+
} else if (currentRequest == null) {
227+
breakInfos.forEach { it?.cancelBreak() }
228+
}
229+
}
230+
231+
if (!isOnBreakCooldown()) currentRequest?.let request@ { request ->
232+
val breakConfig = request.buildConfig.breakSettings
233+
234+
if (tickPre) {
235+
newBreaks = request.contexts
236+
.filter { ctx -> canAccept(ctx) }
237+
.sortedWith(
238+
compareByDescending<BreakContext> { it.instantBreak }
239+
.thenByDescending { it.hotbarIndex == HotbarManager.serverSlot }
240+
).toMutableList()
241+
242+
refreshOrCancelBreaks(newBreaks, request)
243+
244+
val maxBreaks = getMaxBreaks(breakConfig).coerceAtLeast(0)
245+
val maxInstantBreaks = breakConfig.instantBreaksPerTick.coerceAtMost(maxBreaks)
246+
247+
val uncappedInstantBreaks = newBreaks.filter { it.instantBreak }
248+
instantBreaks = uncappedInstantBreaks.take(maxInstantBreaks)
249+
excessInstantBreaks = uncappedInstantBreaks.size > instantBreaks.size
250+
}
251+
252+
if (atMaxBreakInfos(breakConfig)) return@request
253+
instantBreaks.forEach { ctx ->
254+
swapTo?.invoke(ctx.hotbarIndex)
255+
val mismatchedTiming = tickPre && breakConfig.sequenceMode != BuildConfig.InteractSequenceMode.TickStart
256+
if (mismatchedTiming) return false
257+
if (!swapped) return@request
258+
val breakInfo = handleNewBreak(ctx, request) ?: return@request
259+
request.onAccept?.invoke(ctx.expectedPos)
260+
updateBreakProgress(breakInfo)
261+
}
262+
if (!excessInstantBreaks) processNewBreaks(newBreaks, request)
263+
}
264+
265+
updateLiveBreakInfos()
266+
rotation = liveBreakInfos.firstOrNull { it.breakConfig.rotateForBreak }?.let { info ->
267+
info.rotationConfig.request(info.context.rotation)
268+
}
269+
270+
// Reversed so that the breaking order feels natural to the user as the primary break has to
271+
// be started after the secondary
272+
liveBreakInfos
273+
.reversed()
274+
.forEach { info ->
275+
swapTo?.invoke(info.context.hotbarIndex)
276+
val mismatchedTiming = tickPre && info.breakConfig.sequenceMode != BuildConfig.InteractSequenceMode.TickStart
277+
if (!swapped || !validRotation || mismatchedTiming) return false
278+
updateBreakProgress(info)
279+
}
280+
281+
return true
282+
}
283+
262284
private fun refreshOrCancelBreaks(newContexts: MutableCollection<BreakContext>, request: BreakRequest) {
263285
breakInfos
264-
.filterNotNull()
265-
.forEach { info ->
286+
.forEachNotNull { info ->
266287
newContexts.find { ctx -> ctx.expectedPos == info.context.expectedPos }?.let { ctx ->
267288
info.updateInfo(ctx, request)
268289
newContexts.remove(ctx)
269-
return@forEach
290+
return@forEachNotNull
270291
}
271292

272293
info.cancelBreak()
@@ -598,6 +619,10 @@ object BreakManager : RequestHandler<BreakRequest>(), PositionBlocking {
598619
else -> secondaryBreak = null
599620
}
600621

622+
private fun Array<BreakInfo?>.forEachNotNull(block: (BreakInfo) -> Unit) {
623+
for (info in this) info?.run(block)
624+
}
625+
601626
override fun preEvent() = UpdateManagerEvent.Break.Pre().post()
602627
override fun postEvent() = UpdateManagerEvent.Break.Post().post()
603628
}

0 commit comments

Comments
 (0)