Skip to content

Commit 6d24cfb

Browse files
committed
fixed sim sort rule violation in result sorting
1 parent 4ffc9af commit 6d24cfb

File tree

23 files changed

+114
-144
lines changed

23 files changed

+114
-144
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.config.groups
19+
20+
import com.lambda.util.Describable
21+
import com.lambda.util.NamedEnum
22+
23+
interface ActionConfig {
24+
val sorter: SortMode
25+
26+
enum class SortMode(
27+
override val displayName: String,
28+
override val description: String
29+
) : NamedEnum, Describable {
30+
Closest("Closest", "Breaks blocks closest to the player eye position"),
31+
Farthest("Farthest", "Breaks blocks farthest from the player eye position"),
32+
Tool("Tool", "Breaks blocks with priority given to those with tools matching the current selected"),
33+
Rotation("Rotation", "Breaks blocks closest to the player rotation"),
34+
Random("Random", "Breaks blocks in a random order")
35+
}
36+
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import com.lambda.interaction.request.breaking.BreakConfig
2323
import com.lambda.interaction.request.breaking.BreakConfig.AnimationMode
2424
import com.lambda.interaction.request.breaking.BreakConfig.BreakConfirmationMode
2525
import com.lambda.interaction.request.breaking.BreakConfig.BreakMode
26-
import com.lambda.interaction.request.breaking.BreakConfig.SortMode
2726
import com.lambda.interaction.request.breaking.BreakConfig.SwingMode
2827
import com.lambda.util.BlockUtils.allSigns
2928
import com.lambda.util.NamedEnum
@@ -41,7 +40,7 @@ class BreakSettings(
4140

4241
// General
4342
override val breakMode by c.setting("Break Mode", BreakMode.Packet, visibility = vis).group(baseGroup, Group.General)
44-
override val sorter by c.setting("Sorter", SortMode.Tool, "The order in which breaks are performed", visibility = vis).group(baseGroup, Group.General)
43+
override val sorter by c.setting("Break Sorter", ActionConfig.SortMode.Tool, "The order in which breaks are performed", visibility = vis).group(baseGroup, Group.General)
4544
override val rebreak by c.setting("Rebreak", true, "Re-breaks blocks after they've been broken once", visibility = vis).group(baseGroup, Group.General)
4645

4746
// Double break

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class InteractSettings(
2828
vis: () -> Boolean = { true }
2929
) : InteractConfig, SettingGroup(c) {
3030
override val rotate by c.setting("Rotate For Interact", true, "Rotates the player to look at the block when interacting", visibility = vis).group(baseGroup)
31+
override val sorter by c.setting("Interact Sorter", ActionConfig.SortMode.Tool, "The order in which interactions are performed", visibility = vis).group(baseGroup)
3132
override val swingHand by c.setting("Swing On Interact", true, "Swings the players hand after interacting", visibility = vis).group(baseGroup)
3233
override val tickStageMask by c.setting("Interact Stage Mask", setOf<TickEvent>(TickEvent.Input.Post), description = "The sub-tick timing at which interact actions are performed", visibility = vis).group(baseGroup)
3334
override val interactSwingType by c.setting("Interact Swing Type", BuildConfig.SwingType.Vanilla, "The style of swing") { vis() && swingHand }.group(baseGroup)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class PlaceSettings(
3232
override val rotateForPlace by c.setting("Rotate For Place", true, "Rotate towards block while placing", visibility = vis).group(baseGroup)
3333
override val airPlace by c.setting("Air Place", AirPlaceMode.None, "Allows for placing blocks without adjacent faces", visibility = vis).group(baseGroup)
3434
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 }.group(baseGroup)
35+
override val sorter by c.setting("Place Sorter", ActionConfig.SortMode.Tool, "The order in which placements are performed", visibility = vis).group(baseGroup)
3536
override val tickStageMask by c.setting("Place Stage mask", setOf<TickEvent>(TickEvent.Input.Post), description = "The sub-tick timing at which place actions are performed", visibility = vis).group(baseGroup)
3637
override val placeConfirmationMode by c.setting("Place Confirmation", PlaceConfirmationMode.PlaceThenAwait, "Wait for block placement confirmation", visibility = vis).group(baseGroup)
3738
override val maxPendingPlacements by c.setting("Max Pending Placements", 5, 0..30, 1, "The maximum amount of pending placements", visibility = vis).group(baseGroup)

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

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,23 @@ import com.lambda.interaction.material.StackSelection
2525
import com.lambda.interaction.request.LogContext
2626
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
2727
import com.lambda.interaction.request.LogContext.Companion.getLogContextBuilder
28-
import com.lambda.interaction.request.breaking.BreakConfig
29-
import com.lambda.interaction.request.hotbar.HotbarManager
3028
import com.lambda.interaction.request.rotating.RotationRequest
3129
import com.lambda.threading.runSafe
3230
import com.lambda.util.BlockUtils.emptyState
33-
import net.minecraft.block.Block
3431
import net.minecraft.block.BlockState
3532
import net.minecraft.block.FallingBlock
3633
import net.minecraft.util.hit.BlockHitResult
3734
import net.minecraft.util.math.BlockPos
38-
import net.minecraft.util.math.Vec3d
3935
import java.awt.Color
4036
import kotlin.math.sqrt
41-
import kotlin.random.Random
4237

4338
data class BreakContext(
4439
override val hitResult: BlockHitResult,
4540
override val rotationRequest: RotationRequest,
4641
override val hotbarIndex: Int,
4742
val itemSelection: StackSelection,
4843
val instantBreak: Boolean,
44+
val insideBlock: Boolean,
4945
override var cachedState: BlockState,
5046
private val automated: Automated
5147
) : BuildContext(), LogContext, Automated by automated {
@@ -54,42 +50,19 @@ data class BreakContext(
5450

5551
override val blockPos: BlockPos = hitResult.blockPos
5652
override val expectedState = cachedState.emptyState
57-
58-
val random = Random.nextDouble()
59-
60-
override fun compareTo(other: BuildContext): Int = runSafe {
61-
return when (other) {
62-
is BreakContext -> compareByDescending<BreakContext> {
63-
if (breakConfig.sorter == BreakConfig.SortMode.Tool)
64-
it.hotbarIndex == HotbarManager.serverSlot
65-
else 0
66-
}.thenBy {
67-
when (breakConfig.sorter) {
68-
BreakConfig.SortMode.Tool,
69-
BreakConfig.SortMode.Closest -> player.eyePos.distance(it.hitResult.pos, it.cachedState.block)
70-
BreakConfig.SortMode.Farthest -> -player.eyePos.distance(it.hitResult.pos, it.cachedState.block)
71-
BreakConfig.SortMode.Rotation -> it.rotationRequest.target.angleDistance
72-
BreakConfig.SortMode.Random -> it.random
73-
}
74-
}.thenByDescending {
75-
it.hotbarIndex == HotbarManager.serverSlot
76-
}.thenBy {
77-
it.instantBreak
78-
}.compare(this@BreakContext, other)
79-
80-
else -> 1
81-
}
82-
} ?: 0
83-
84-
private fun Vec3d.distance(vec: Vec3d, block: Block): Double {
85-
val d = vec.x - x
86-
val e = (vec.y - y).let {
87-
if (block is FallingBlock) it - (buildConfig.attackReach / 2)
53+
override val sortDistance = runSafe {
54+
val pov = player.eyePos
55+
val vec = hitResult.pos
56+
val d = vec.x - pov.x
57+
val e = (vec.y - pov.y).let {
58+
if (cachedState.block is FallingBlock) it - (buildConfig.attackReach / 2)
8859
else it
8960
}
90-
val f = vec.z - z
91-
return sqrt(d * d + e * e + f * f)
92-
}
61+
val f = vec.z - pov.z
62+
sqrt(d * d + e * e + f * f)
63+
} ?: Double.MAX_VALUE
64+
65+
override val sorter get() = breakConfig.sorter
9366

9467
override fun ShapeBuilder.buildRenderer() {
9568
box(blockPos, cachedState, baseColor, sideColor, DirectionMask.ALL.exclude(hitResult.side))

src/main/kotlin/com/lambda/interaction/construction/context/BuildContext.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,30 @@
1717

1818
package com.lambda.interaction.construction.context
1919

20+
import com.lambda.config.groups.ActionConfig
2021
import com.lambda.context.Automated
2122
import com.lambda.interaction.construction.result.Drawable
2223
import com.lambda.interaction.request.rotating.RotationRequest
2324
import com.lambda.threading.runSafe
2425
import net.minecraft.block.BlockState
2526
import net.minecraft.util.hit.BlockHitResult
2627
import net.minecraft.util.math.BlockPos
28+
import kotlin.random.Random
2729

2830
/**
2931
* Holds the necessary information for managers to perform actions.
3032
*/
31-
abstract class BuildContext : Comparable<BuildContext>, Drawable, Automated {
33+
abstract class BuildContext : Drawable, Automated {
3234
abstract val hitResult: BlockHitResult
3335
abstract val rotationRequest: RotationRequest
3436
abstract val hotbarIndex: Int
3537
abstract val cachedState: BlockState
3638
abstract val expectedState: BlockState
3739
abstract val blockPos: BlockPos
40+
abstract val sorter: ActionConfig.SortMode
41+
val random = Random.nextDouble()
3842

39-
val distance by lazy {
43+
open val sortDistance by lazy {
4044
runSafe { player.eyePos.distanceTo(hitResult.pos) } ?: Double.MAX_VALUE
4145
}
4246
}

src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt renamed to src/main/kotlin/com/lambda/interaction/construction/context/InteractContext.kt

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,15 @@ import com.lambda.interaction.request.LogContext
2424
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
2525
import com.lambda.interaction.request.LogContext.Companion.getLogContextBuilder
2626
import com.lambda.interaction.request.Request.Companion.submit
27-
import com.lambda.interaction.request.hotbar.HotbarManager
2827
import com.lambda.interaction.request.hotbar.HotbarRequest
2928
import com.lambda.interaction.request.interacting.InteractRequest
3029
import com.lambda.interaction.request.rotating.RotationRequest
31-
import com.lambda.util.BlockUtils
3230
import net.minecraft.block.BlockState
3331
import net.minecraft.util.hit.BlockHitResult
3432
import net.minecraft.util.math.BlockPos
3533
import java.awt.Color
3634

37-
class InteractionContext(
35+
class InteractContext(
3836
override val hitResult: BlockHitResult,
3937
override val rotationRequest: RotationRequest,
4038
override var hotbarIndex: Int,
@@ -47,22 +45,7 @@ class InteractionContext(
4745

4846
override val blockPos: BlockPos = hitResult.blockPos
4947

50-
override fun compareTo(other: BuildContext) =
51-
when {
52-
other is InteractionContext -> compareBy<BuildContext> {
53-
BlockUtils.fluids.indexOf(it.cachedState.fluidState.fluid)
54-
}.thenByDescending {
55-
it.cachedState.fluidState.level
56-
}.thenBy {
57-
it.rotationRequest.target.angleDistance
58-
}.thenBy {
59-
it.hotbarIndex == HotbarManager.serverSlot
60-
}.thenBy {
61-
it.distance
62-
}.compare(this, other)
63-
64-
else -> 1
65-
}
48+
override val sorter get() = interactConfig.sorter
6649

6750
override fun ShapeBuilder.buildRenderer() {
6851
box(blockPos, expectedState, baseColor, sideColor, hitResult.side.mask)

src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,16 @@
1717

1818
package com.lambda.interaction.construction.context
1919

20-
import com.lambda.Lambda.mc
2120
import com.lambda.context.Automated
2221
import com.lambda.graphics.renderer.esp.DirectionMask.mask
2322
import com.lambda.graphics.renderer.esp.ShapeBuilder
2423
import com.lambda.interaction.request.LogContext
2524
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
2625
import com.lambda.interaction.request.LogContext.Companion.getLogContextBuilder
2726
import com.lambda.interaction.request.Request.Companion.submit
28-
import com.lambda.interaction.request.hotbar.HotbarManager
2927
import com.lambda.interaction.request.hotbar.HotbarRequest
3028
import com.lambda.interaction.request.placing.PlaceRequest
3129
import com.lambda.interaction.request.rotating.RotationRequest
32-
import com.lambda.util.BlockUtils
3330
import net.minecraft.block.BlockState
3431
import net.minecraft.util.hit.BlockHitResult
3532
import net.minecraft.util.math.BlockPos
@@ -43,35 +40,13 @@ data class PlaceContext(
4340
override var cachedState: BlockState,
4441
override val expectedState: BlockState,
4542
val sneak: Boolean,
46-
val insideBlock: Boolean,
4743
val currentDirIsValid: Boolean = false,
4844
private val automated: Automated
4945
) : BuildContext(), LogContext, Automated by automated {
5046
private val baseColor = Color(35, 188, 254, 25)
5147
private val sideColor = Color(35, 188, 254, 100)
5248

53-
override fun compareTo(other: BuildContext) =
54-
when (other) {
55-
is PlaceContext -> compareBy<PlaceContext> {
56-
BlockUtils.fluids.indexOf(it.cachedState.fluidState.fluid)
57-
}.thenByDescending {
58-
if (it.cachedState.fluidState.level != 0) it.blockPos.y else 0
59-
}.thenByDescending {
60-
it.cachedState.fluidState.level
61-
}.thenBy {
62-
it.sneak == (mc.player?.isSneaking ?: false)
63-
}.thenBy {
64-
it.rotationRequest.target.angleDistance
65-
}.thenBy {
66-
it.hotbarIndex == HotbarManager.serverSlot
67-
}.thenBy {
68-
it.distance
69-
}.thenBy {
70-
it.insideBlock
71-
}.compare(this, other)
72-
73-
else -> 1
74-
}
49+
override val sorter get() = placeConfig.sorter
7550

7651
override fun ShapeBuilder.buildRenderer() {
7752
box(blockPos, expectedState, baseColor, sideColor, hitResult.side.mask)
@@ -94,7 +69,6 @@ data class PlaceContext(
9469
value("Cached State", cachedState)
9570
value("Expected State", expectedState)
9671
value("Sneak", sneak)
97-
value("Inside Block", insideBlock)
9872
value("Current Dir Is Valid", currentDirIsValid)
9973
}
10074
}

src/main/kotlin/com/lambda/interaction/construction/result/Contextual.kt

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,50 @@
1717

1818
package com.lambda.interaction.construction.result
1919

20+
import com.lambda.config.groups.ActionConfig
21+
import com.lambda.interaction.construction.context.BreakContext
2022
import com.lambda.interaction.construction.context.BuildContext
23+
import com.lambda.interaction.construction.context.PlaceContext
2124
import com.lambda.interaction.request.hotbar.HotbarManager
25+
import com.lambda.threading.runSafe
26+
import com.lambda.util.BlockUtils
2227

2328
/**
2429
* Represents a result holding a [BuildContext].
2530
*/
2631
interface Contextual : ComparableResult<Rank> {
2732
val context: BuildContext
2833

29-
override fun compareResult(other: ComparableResult<Rank>) =
34+
override fun compareResult(other: ComparableResult<Rank>) = runSafe {
3035
when (other) {
31-
32-
is Contextual -> compareByDescending<Contextual> {
33-
it.context.hotbarIndex == HotbarManager.serverSlot
36+
is Contextual -> compareBy<BuildContext> {
37+
if (it is PlaceContext) BlockUtils.fluids.indexOf(it.cachedState.fluidState.fluid)
38+
else BlockUtils.fluids.size
39+
}.thenByDescending {
40+
if (it is PlaceContext && it.cachedState.fluidState.level != 0) it.blockPos.y
41+
else Int.MIN_VALUE
42+
}.thenByDescending {
43+
if (it is PlaceContext) it.cachedState.fluidState.level
44+
else Int.MIN_VALUE
45+
}.thenByDescending {
46+
context.sorter == ActionConfig.SortMode.Tool && it.hotbarIndex == HotbarManager.serverSlot
3447
}.thenBy {
35-
it.compareBy.rank
36-
}.compare(this, other)
48+
when (it.sorter) {
49+
ActionConfig.SortMode.Tool,
50+
ActionConfig.SortMode.Closest -> it.sortDistance
51+
ActionConfig.SortMode.Farthest -> -it.sortDistance
52+
ActionConfig.SortMode.Rotation -> it.rotationRequest.target.angleDistance
53+
ActionConfig.SortMode.Random -> it.random
54+
}
55+
}.thenByDescending {
56+
it is PlaceContext && it.sneak == player.isSneaking
57+
}.thenByDescending {
58+
it.hotbarIndex == HotbarManager.serverSlot
59+
}.thenByDescending {
60+
it is BreakContext && it.instantBreak
61+
}.compare(context, other.context)
3762

38-
else -> compareBy.rank.compareTo(other.compareBy.rank)
63+
else -> super.compareResult(other)
3964
}
65+
} ?: 0
4066
}

src/main/kotlin/com/lambda/interaction/construction/result/results/BreakResult.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ sealed class BreakResult : BuildResult() {
5757
override fun ShapeBuilder.buildRenderer() {
5858
with(context) { buildRenderer() }
5959
}
60-
61-
override fun compareResult(other: ComparableResult<Rank>) =
62-
when (other) {
63-
is Break -> context.compareTo(other.context)
64-
else -> super<Contextual>.compareResult(other)
65-
}
6660
}
6761

6862
/**

0 commit comments

Comments
 (0)