Skip to content

Commit 16cb2d4

Browse files
committed
Merge branch '1.21.5' into improvement/inventory-move
2 parents 4c82643 + 4842d77 commit 16cb2d4

File tree

7 files changed

+131
-175
lines changed

7 files changed

+131
-175
lines changed

src/main/kotlin/com/lambda/config/groups/Targeting.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,33 @@ abstract class Targeting(
6060
* The range within which entities can be targeted. This value is configurable and constrained
6161
* between 1.0 and [maxRange].
6262
*/
63-
override val targetingRange by owner.setting("Targeting Range", defaultRange, 1.0..maxRange, 0.05) { predicate() }
63+
override val targetingRange by owner.setting("Targeting Range", defaultRange, 1.0..maxRange, 0.05) { predicate() }.group(baseGroup)
6464

6565
/**
6666
* Whether players are included in the targeting scope.
6767
*/
68-
override val players by owner.setting("Players", true) { predicate() }
68+
override val players by owner.setting("Players", true) { predicate() }.group(baseGroup)
6969

7070
/**
7171
* Whether friends are included in the targeting scope.
7272
* Requires [players] to be true.
7373
*/
74-
override val friends by owner.setting("Friends", false) { predicate() && players }
74+
override val friends by owner.setting("Friends", false) { predicate() && players }.group(baseGroup)
7575

7676
/**
7777
* Whether mobs are included in the targeting scope.
7878
*/
79-
private val mobs by owner.setting("Mobs", true) { predicate() }
79+
private val mobs by owner.setting("Mobs", true) { predicate() }.group(baseGroup)
8080

8181
/**
8282
* Whether hostile mobs are included in the targeting scope
8383
*/
84-
private val hostilesSetting by owner.setting("Hostiles", true) { predicate() && mobs }
84+
private val hostilesSetting by owner.setting("Hostiles", true) { predicate() && mobs }.group(baseGroup)
8585

8686
/**
8787
* Whether passive animals are included in the targeting scope
8888
*/
89-
private val animalsSetting by owner.setting("Animals", true) { predicate() && mobs }
89+
private val animalsSetting by owner.setting("Animals", true) { predicate() && mobs }.group(baseGroup)
9090

9191
/**
9292
* Indicates whether hostile entities are included in the targeting scope.
@@ -101,12 +101,12 @@ abstract class Targeting(
101101
/**
102102
* Whether invisible entities are included in the targeting scope.
103103
*/
104-
override val invisible by owner.setting("Invisible", true) { predicate() }
104+
override val invisible by owner.setting("Invisible", true) { predicate() }.group(baseGroup)
105105

106106
/**
107107
* Whether dead entities are included in the targeting scope.
108108
*/
109-
override val dead by owner.setting("Dead", false) { predicate() }
109+
override val dead by owner.setting("Dead", false) { predicate() }.group(baseGroup)
110110

111111
/**
112112
* Validates whether a given entity is targetable by the player based on current settings.
@@ -144,7 +144,7 @@ abstract class Targeting(
144144
/**
145145
* The field of view limit for targeting entities. Configurable between 5 and 180 degrees.
146146
*/
147-
val fov by owner.setting("FOV Limit", 180, 5..180, 1) { predicate() }.group(baseGroup)
147+
val fov by owner.setting("FOV Limit", 180, 5..180, 1) { predicate() && priority == Priority.FOV }.group(baseGroup)
148148

149149
/**
150150
* The priority used to determine which entity is targeted. Configurable with default set to [Priority.DISTANCE].

src/main/kotlin/com/lambda/interaction/material/StackSelection.kt

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import kotlin.reflect.KClass
3333
* [StackSelection] is a class that holds a predicate for matching [ItemStack]s.
3434
*/
3535
class StackSelection {
36-
var selector: (ItemStack) -> Boolean = { true }
37-
var comparator: Comparator<ItemStack>? = null
36+
var selector: (ItemStack) -> Boolean = EVERYTHING
37+
var comparator: Comparator<ItemStack> = NO_COMPARE
3838
var count: Int = DEFAULT_AMOUNT
3939
var inShulkerBox: Boolean = false
4040

@@ -48,25 +48,54 @@ class StackSelection {
4848
val optimalStack: ItemStack?
4949
get() = itemStack ?: item?.let { ItemStack(it, count) }
5050

51+
/**
52+
* Filters the given [stacks], sorts them with the [comparator] and returns the first value
53+
*/
54+
fun bestItemMatch(stacks: List<ItemStack>): ItemStack? = stacks.minWithOrNull(comparator)
55+
5156
fun filterStack(stack: ItemStack) =
5257
if (inShulkerBox) stack.shulkerBoxContents.any { selector(it) }
5358
else selector(stack)
5459

55-
fun filterSlot(slot: Slot) = filterStack(slot.stack)
60+
fun filterSlot(slot: Slot): Boolean = filterStack(slot.stack)
5661

5762
fun filterStacks(stacks: List<ItemStack>): List<ItemStack> =
58-
stacks.filter(::filterStack).let { filteredStacks ->
59-
comparator?.run {
60-
filteredStacks.sortedWith(this)
61-
} ?: filteredStacks
62-
}
63+
stacks.filter(::filterStack).sortedWith(comparator)
6364

6465
fun filterSlots(slots: List<Slot>): List<Slot> =
65-
slots.filter(::filterSlot).let { filteredSlots ->
66-
comparator?.run {
67-
filteredSlots.sortedWith { slot, slot2 -> compare(slot.stack, slot2.stack) }
68-
} ?: filteredSlots
69-
}
66+
slots.filter(::filterSlot).sortedWith { slot, slot2 -> comparator.compare(slot.stack, slot2.stack) }
67+
68+
@StackSelectionDsl
69+
fun <R : Comparable<R>> sortBy(selector: (ItemStack) -> R?): StackSelection = apply {
70+
comparator = compareBy(selector)
71+
}
72+
73+
@StackSelectionDsl
74+
fun <R : Comparable<R>> sortByDescending(selector: (ItemStack) -> R?): StackSelection = apply {
75+
comparator = compareByDescending(selector)
76+
}
77+
78+
@StackSelectionDsl
79+
fun <R : Comparable<R>> thenBy(selector: (ItemStack) -> R?): StackSelection = apply {
80+
check(comparator != NO_COMPARE) { "No comparator specified" }
81+
comparator = comparator.thenBy(selector)
82+
}
83+
84+
@StackSelectionDsl
85+
fun <R : Comparable<R>> thenByDescending(selector: (ItemStack) -> R?): StackSelection = apply {
86+
check(comparator != NO_COMPARE) { "No comparator specified" }
87+
comparator = comparator.thenByDescending(selector)
88+
}
89+
90+
@StackSelectionDsl
91+
fun sortWith(custom: Comparator<ItemStack>): StackSelection = apply {
92+
comparator = custom
93+
}
94+
95+
@StackSelectionDsl
96+
fun reversed(): StackSelection = apply {
97+
comparator = comparator.reversed()
98+
}
7099

71100
/**
72101
* returns a function that finds a shulker box to push matching items into.
@@ -235,14 +264,12 @@ class StackSelection {
235264
annotation class StackSelectionDsl
236265

237266
const val DEFAULT_AMOUNT = 1
238-
val FULL_SHULKERS: (ItemStack) -> Boolean = { stack ->
239-
stack.shulkerBoxContents.none { it.isEmpty }
240-
}
241-
val EMPTY_SHULKERS: (ItemStack) -> Boolean = { stack ->
242-
stack.shulkerBoxContents.all { it.isEmpty }
243-
}
267+
268+
val FULL_SHULKERS: (ItemStack) -> Boolean = { stack -> stack.shulkerBoxContents.none { it.isEmpty } }
269+
val EMPTY_SHULKERS: (ItemStack) -> Boolean = { stack -> stack.shulkerBoxContents.all { it.isEmpty } }
244270
val EVERYTHING: (ItemStack) -> Boolean = { true }
245271
val NOTHING: (ItemStack) -> Boolean = { false }
272+
val NO_COMPARE: Comparator<ItemStack> = Comparator { _, _ -> 0 }
246273

247274
@StackSelectionDsl
248275
fun Item.select() = selectStack { isItem(this@select) }
@@ -261,29 +288,12 @@ class StackSelection {
261288
@StackSelectionDsl
262289
fun ((ItemStack) -> Boolean).select() = selectStack { this@select }
263290

264-
/**
265-
* Builds a [StackSelection] with the given parameters.
266-
* @param count The count of items to be selected.
267-
* @param block The predicate to be used to select the items.
268-
* @return A [StackSelection] with the given parameters.
269-
*/
270-
@StackSelectionDsl
271-
fun selectStack(
272-
count: Int = DEFAULT_AMOUNT,
273-
inShulkerBox: Boolean = false,
274-
block: StackSelection.() -> (ItemStack) -> Boolean,
275-
) = StackSelection().apply {
276-
selector = block()
277-
this.count = count
278-
this.inShulkerBox = inShulkerBox
279-
}
280-
281291
@StackSelectionDsl
282292
fun selectStack(
283293
count: Int = DEFAULT_AMOUNT,
284294
inShulkerBox: Boolean = false,
285-
sorter: Comparator<ItemStack>? = null,
286-
block: StackSelection.() -> (ItemStack) -> Boolean,
295+
sorter: Comparator<ItemStack> = NO_COMPARE,
296+
block: StackSelection.() -> (ItemStack) -> Boolean = { EVERYTHING },
287297
) = StackSelection().apply {
288298
selector = block()
289299
comparator = sorter

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

Lines changed: 33 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,8 @@ import com.lambda.interaction.request.breaking.BreakManager.breaks
5454
import com.lambda.interaction.request.breaking.BreakManager.canAccept
5555
import com.lambda.interaction.request.breaking.BreakManager.checkForCancels
5656
import com.lambda.interaction.request.breaking.BreakManager.initNewBreak
57-
import com.lambda.interaction.request.breaking.BreakManager.instantBreaks
5857
import com.lambda.interaction.request.breaking.BreakManager.maxBreaksThisTick
59-
import com.lambda.interaction.request.breaking.BreakManager.performInstantBreaks
60-
import com.lambda.interaction.request.breaking.BreakManager.processNewBreaks
58+
import com.lambda.interaction.request.breaking.BreakManager.processNewBreak
6159
import com.lambda.interaction.request.breaking.BreakManager.processRequest
6260
import com.lambda.interaction.request.breaking.BreakManager.simulateAbandoned
6361
import com.lambda.interaction.request.breaking.BreakManager.updateBreakProgress
@@ -94,7 +92,6 @@ import net.minecraft.util.math.Box
9492
import net.minecraft.world.BlockView
9593
import kotlin.math.max
9694

97-
// ToDo: Fix root cause of breaks becoming redundant while the actual state is empty
9895
object BreakManager : RequestHandler<BreakRequest>(
9996
0,
10097
TickEvent.Pre,
@@ -155,7 +152,6 @@ object BreakManager : RequestHandler<BreakRequest>(
155152
private var maxBreaksThisTick = 0
156153

157154
private var breaks = mutableListOf<BreakContext>()
158-
private var instantBreaks = mutableListOf<BreakContext>()
159155

160156
var lastPosStarted: BlockPos? = null
161157
set(value) {
@@ -185,7 +181,6 @@ object BreakManager : RequestHandler<BreakRequest>(
185181
}
186182
activeRequest = null
187183
breaks = mutableListOf()
188-
instantBreaks = mutableListOf()
189184
breaksThisTick = 0
190185
}
191186

@@ -313,37 +308,45 @@ object BreakManager : RequestHandler<BreakRequest>(
313308
* or the player needs to swap to a different hotbar slot.
314309
*
315310
* @see performInstantBreaks
316-
* @see processNewBreaks
311+
* @see processNewBreak
317312
* @see updateBreakProgress
318313
*/
319314
private fun SafeContext.processRequest(breakRequest: BreakRequest?) {
320315
breakRequest?.let { request ->
321316
if (request.fresh) populateFrom(request)
322317
}
323318

324-
repeat(2) {
325-
breakRequest?.let { request ->
326-
if (performInstantBreaks(request)) {
327-
processNewBreaks(request)
328-
}
329-
}
319+
var noNew = false
320+
var noProgression = false
321+
322+
while (true) {
323+
noNew = breakRequest?.let { request ->
324+
!processNewBreak(request)
325+
} != false
330326

331327
// Reversed so that the breaking order feels natural to the user as the primary break is always the
332328
// last break to be started
333-
if (handlePreProcessing()) {
329+
noProgression = if (handlePreProcessing()) {
334330
activeInfos
335-
.filter { it.updatedThisTick }
331+
.filter { it.updatedThisTick && it.shouldProgress }
336332
.asReversed()
337-
.forEach { info ->
338-
if (info.shouldProgress)
339-
updateBreakProgress(info)
333+
.run {
334+
if (isEmpty()) {
335+
true
336+
} else {
337+
forEach { info ->
338+
updateBreakProgress(info)
339+
}
340+
false
341+
}
340342
}
341-
}
342-
}
343+
} else true
343344

344-
if (instantBreaks.isEmpty() && breaks.isEmpty()) {
345-
activeRequest = null
345+
if (noNew && noProgression) break
346346
}
347+
348+
if (breaks.isEmpty()) activeRequest = null
349+
347350
if (breaksThisTick > 0 || activeInfos.isNotEmpty()) {
348351
activeThisTick = true
349352
}
@@ -384,12 +387,8 @@ object BreakManager : RequestHandler<BreakRequest>(
384387
}
385388
}
386389

387-
instantBreaks = newBreaks
388-
.filter { it.instantBreak }
389-
.toMutableList()
390-
391390
breaks = newBreaks
392-
.filter { !it.instantBreak }
391+
.sortedByDescending { it.instantBreak }
393392
.toMutableList()
394393

395394
val breakConfig = request.config
@@ -451,50 +450,22 @@ object BreakManager : RequestHandler<BreakRequest>(
451450
return true
452451
}
453452

454-
/**
455-
* Attempts to break as many [BreakContext]'s as possible from the [instantBreaks] collection within this tick.
456-
*
457-
* @return false if a break could not be performed.
458-
*/
459-
private fun SafeContext.performInstantBreaks(request: BreakRequest): Boolean {
460-
val iterator = instantBreaks.iterator()
461-
while (iterator.hasNext()) {
462-
if (breaksThisTick + 1 > maxBreaksThisTick) return false
463-
464-
val ctx = iterator.next()
465-
466-
if (!canAccept(ctx)) continue
467-
468-
rotationRequest = if (request.config.rotateForBreak) ctx.rotation.submit(false) else null
469-
if (!rotated || tickStage !in request.config.breakStageMask) return false
470-
471-
val breakInfo = initNewBreak(ctx, request) ?: return false
472-
if (!handlePreProcessing()) return false
473-
474-
updateBreakProgress(breakInfo)
475-
iterator.remove()
476-
}
477-
return true
478-
}
479-
480453
/**
481454
* Attempts to start breaking as many [BreakContext]'s from the [breaks] collection as possible.
482455
*
483456
* @return false if a context cannot be started or the maximum active breaks has been reached.
484457
*
485458
* @see initNewBreak
486459
*/
487-
private fun SafeContext.processNewBreaks(request: BreakRequest): Boolean {
488-
val iterator = breaks.iterator()
489-
while (iterator.hasNext()) {
490-
val ctx = iterator.next()
491-
492-
if (!canAccept(ctx)) continue
460+
private fun SafeContext.processNewBreak(request: BreakRequest): Boolean {
461+
breaks.forEach { ctx ->
462+
if (!canAccept(ctx)) return@forEach
493463

494464
initNewBreak(ctx, request) ?: return false
495-
iterator.remove()
465+
breaks.remove(ctx)
466+
return true
496467
}
497-
return true
468+
return false
498469
}
499470

500471
/**
@@ -517,10 +488,7 @@ object BreakManager : RequestHandler<BreakRequest>(
517488
} else return null
518489
}
519490

520-
if (!primaryInfo.breaking) {
521-
secondaryBreak = breakInfo.apply { type = Secondary }
522-
return secondaryBreak
523-
}
491+
if (!primaryInfo.breaking) return null
524492

525493
secondaryBreak = primaryInfo.apply { type = Secondary }
526494
secondaryBreak?.stopBreakPacket(world, interaction)

src/main/kotlin/com/lambda/interaction/request/breaking/SwapInfo.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ data class SwapInfo(
6161

6262
val minKeepTicks = run {
6363
if (type == Primary) {
64-
val swapTickProgress = breakDelta * (breakTicks + breakConfig.serverSwapTicks - 1)
64+
val swapTickProgress = breakDelta * (breakTicks + breakConfig.serverSwapTicks - 1).coerceAtLeast(1)
6565
if (swapTickProgress >= threshold && swapStack.heldTicks < breakConfig.serverSwapTicks) 1
6666
else 0
6767
} else {
6868
val serverSwapTicks = breakConfig.serverSwapTicks.coerceAtLeast(3)
69-
val swapTickProgress = breakDelta * (breakTicks + serverSwapTicks - 1)
69+
val swapTickProgress = breakDelta * (breakTicks + serverSwapTicks - 1).coerceAtLeast(1)
7070
if (swapTickProgress >= threshold && swapStack.heldTicks < serverSwapTicks) 1
7171
else 0
7272
}

0 commit comments

Comments
 (0)