Skip to content

Commit 446870b

Browse files
committed
air place
1 parent 67b9a4a commit 446870b

File tree

9 files changed

+167
-23
lines changed

9 files changed

+167
-23
lines changed

src/main/kotlin/com/lambda/config/Setting.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ abstract class SettingCore<T : Any>(
9898
var defaultValue: T,
9999
val type: Type
100100
) {
101-
var value = defaultValue
101+
open var value = defaultValue
102102
set(value) {
103103
val oldValue = field
104104
field = value

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class BuildSettings(
5151

5252
override val checkSideVisibility by c.setting("Visibility Check", true, "Whether to check if an AABB side is visible").group(baseGroup, Group.Scan).index()
5353
override val strictRayCast by c.setting("Strict Raycast", false, "Whether to include the environment to the ray cast context").group(baseGroup, Group.Scan).index()
54-
override val resolution by c.setting("Resolution", 5, 1..20, 1, "The amount of grid divisions per surface of the hit box", "").group(baseGroup, Group.Scan).index()
54+
override val resolution by c.setting("Resolution", 5, 1..20, 1, "The amount of grid divisions per surface of the hit box", "") { strictRayCast }.group(baseGroup, Group.Scan).index()
5555
override val pointSelection by c.setting("Point Selection", PointSelection.Optimum, "The strategy to select the best hit point").group(baseGroup, Group.Scan).index()
5656

5757
companion object {

src/main/kotlin/com/lambda/config/settings/NumericSetting.kt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,29 @@ import imgui.ImGui.dummy
2929
import imgui.flag.ImGuiCol
3030
import java.text.NumberFormat
3131
import java.util.*
32-
import kotlin.reflect.KProperty
3332

3433
/**
3534
* @see [com.lambda.config.Configurable]
3635
*/
3736
abstract class NumericSetting<T>(
38-
value: T,
39-
open var range: ClosedRange<T>,
40-
open var step: T,
41-
var unit: String
37+
defaultValue: T,
38+
open var range: ClosedRange<T>,
39+
open var step: T,
40+
var unit: String
4241
) : SettingCore<T>(
43-
value,
44-
TypeToken.get(value::class.java).type
42+
defaultValue,
43+
TypeToken.get(defaultValue::class.java).type
4544
) where T : Number, T : Comparable<T> {
45+
override var value: T
46+
get() = super.value
47+
set(newVal) {
48+
super.value = newVal.coerceIn(range)
49+
}
50+
4651
private val formatter = NumberFormat.getNumberInstance(Locale.getDefault())
4752

4853
override fun toString() = "${formatter.format(value)}$unit"
4954

50-
operator fun setValue(thisRef: Any?, property: KProperty<*>, valueIn: T) {
51-
value = valueIn.coerceIn(range)
52-
}
53-
5455
/**
5556
* Subclasses must implement this to provide their specific slider widget.
5657
*/

src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ data class BreakRequest private constructor(
7070
override val done: Boolean
7171
get() = runSafe { contexts.all { blockState(it.blockPos).isEmpty } } == true
7272

73-
override fun submit(queueIfMismatchedStage: Boolean) =
74-
BreakManager.request(this, queueIfMismatchedStage)
75-
7673
override fun getLogContextBuilder(): LogContextBuilder.() -> Unit = {
7774
group("Break Request") {
7875
value("Request ID", requestId)
@@ -92,6 +89,10 @@ data class BreakRequest private constructor(
9289
@DslMarker
9390
annotation class BreakRequestDsl
9491

92+
@BreakRequestDsl
93+
override fun submit(queueIfMismatchedStage: Boolean) =
94+
BreakManager.request(this, queueIfMismatchedStage)
95+
9596
@BreakRequestDsl
9697
class BreakRequestBuilder(
9798
contexts: Collection<BreakContext>,

src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ data class InteractRequest private constructor(
4848
contexts.all { it.expectedState.matches(blockState(it.blockPos)) }
4949
} == true
5050

51-
override fun submit(queueIfMismatchedStage: Boolean) =
52-
InteractManager.request(this, queueIfMismatchedStage)
53-
5451
override fun getLogContextBuilder(): LogContextBuilder.() -> Unit = {
5552
group("PlaceRequest") {
5653
value("Request ID", requestId)
@@ -61,6 +58,10 @@ data class InteractRequest private constructor(
6158
@DslMarker
6259
annotation class PlaceRequestDsl
6360

61+
@PlaceRequestDsl
62+
override fun submit(queueIfMismatchedStage: Boolean) =
63+
InteractManager.request(this, queueIfMismatchedStage)
64+
6465
@PlaceRequestDsl
6566
class PlaceRequestBuilder(
6667
contexts: Collection<InteractContext>,

src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ import com.lambda.event.events.KeyboardEvent
2525
import com.lambda.event.events.MouseEvent
2626
import com.lambda.event.events.TickEvent
2727
import com.lambda.event.listener.SafeListener.Companion.listen
28-
import com.lambda.interaction.material.StackSelection.Companion.selectStack
2928
import com.lambda.interaction.managers.hotbar.HotbarRequest
3029
import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest
30+
import com.lambda.interaction.material.StackSelection.Companion.selectStack
3131
import com.lambda.module.Module
3232
import com.lambda.module.tag.ModuleTag
3333
import com.lambda.threading.runSafe
@@ -49,7 +49,7 @@ object BetterFirework : Module(
4949
tag = ModuleTag.MOVEMENT,
5050
) {
5151
private var activateButton by setting("Activate Key", Bind(0, 0, Mouse.Middle.ordinal), "Button to activate Firework")
52-
private var midFlightActivationKey by setting("Mid-Flight Activation Key", Bind(0, 0, KeyCode.Unbound.code), "Firework use key for mid flight activation")
52+
private var midFlightActivationKey by setting("Mid-Flight Activation Key", Bind(0, 0), "Firework use key for mid flight activation")
5353
private var middleClickCancel by setting("Middle Click Cancel", false, description = "Cancel pick block action on middle mouse click") { activateButton.key != KeyCode.Unbound.code }
5454
private var fireworkInteract by setting("Right Click Fly", true, "Automatically start flying when right clicking fireworks")
5555
private var fireworkInteractCancel by setting("Right Click Cancel", false, "Cancel block interactions while holding fireworks") { fireworkInteract }
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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.module.modules.player
19+
20+
import com.lambda.config.AutomationConfig.Companion.setDefaultAutomationConfig
21+
import com.lambda.config.applyEdits
22+
import com.lambda.config.settings.complex.Bind
23+
import com.lambda.event.events.MouseEvent
24+
import com.lambda.event.events.TickEvent
25+
import com.lambda.event.events.onStaticRender
26+
import com.lambda.event.listener.SafeListener.Companion.listen
27+
import com.lambda.interaction.construction.simulation.BuildSimulator.simulate
28+
import com.lambda.interaction.construction.simulation.context.BuildContext
29+
import com.lambda.interaction.construction.verify.TargetState
30+
import com.lambda.interaction.managers.interacting.InteractConfig
31+
import com.lambda.interaction.managers.interacting.InteractRequest.Companion.interactRequest
32+
import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation
33+
import com.lambda.module.Module
34+
import com.lambda.module.tag.ModuleTag
35+
import com.lambda.threading.runSafeAutomated
36+
import com.lambda.util.InputUtils.isSatisfied
37+
import com.lambda.util.KeyCode
38+
import com.lambda.util.NamedEnum
39+
import net.minecraft.block.BlockState
40+
import net.minecraft.item.BlockItem
41+
import net.minecraft.item.ItemPlacementContext
42+
import net.minecraft.util.Hand
43+
import net.minecraft.util.math.BlockPos
44+
import net.minecraft.util.math.Box
45+
import net.minecraft.world.RaycastContext
46+
import org.lwjgl.glfw.GLFW
47+
import java.awt.Color
48+
import java.util.concurrent.ConcurrentLinkedQueue
49+
50+
object AirPlace : Module(
51+
name = "AirPlace",
52+
description = "Allows placing blocks in air",
53+
tag = ModuleTag.PLAYER
54+
) {
55+
enum class Group(override val displayName: String) : NamedEnum {
56+
General("General"),
57+
Render("Render")
58+
}
59+
60+
private var distance by setting("Distance", 4.0, 1.0..7.0, 1.0).group(Group.General)
61+
private val scrollBind by setting("Scroll Bind", Bind(KeyCode.Unbound.code, GLFW.GLFW_MOD_CONTROL), "Allows you to hold the ctrl key and scroll to adjust distance").group(Group.General)
62+
63+
private val outlineColor by setting("Outline Color", Color.WHITE).group(Group.Render)
64+
65+
private var placementPos: BlockPos? = null
66+
private var placementState: BlockState? = null
67+
private val pendingInteractions = ConcurrentLinkedQueue<BuildContext>()
68+
69+
init {
70+
setDefaultAutomationConfig {
71+
applyEdits {
72+
interactConfig.apply {
73+
::airPlace.edit { defaultValue(InteractConfig.AirPlaceMode.Grim) }
74+
}
75+
hideAllGroupsExcept(interactConfig)
76+
}
77+
}
78+
79+
listen<TickEvent.Pre> {
80+
val selectedStack = player.inventory.selectedStack
81+
val blockItem = selectedStack.item as? BlockItem ?: run {
82+
placementPos = null
83+
placementState = null
84+
return@listen
85+
}
86+
val raycastEnd = player.rotation.vector.multiply(distance).add(player.eyePos)
87+
val raycastContext = RaycastContext(
88+
player.eyePos,
89+
raycastEnd,
90+
RaycastContext.ShapeType.OUTLINE,
91+
RaycastContext.FluidHandling.NONE,
92+
player
93+
)
94+
val placementContext = ItemPlacementContext(
95+
world,
96+
player, Hand.MAIN_HAND,
97+
selectedStack,
98+
world.raycast(raycastContext),
99+
)
100+
placementPos = placementContext.blockPos
101+
placementState = blockItem.getPlacementState(placementContext)
102+
if (!mc.options.useKey.isPressed) return@listen
103+
placementPos?.let { pos ->
104+
placementState?.let { state ->
105+
runSafeAutomated {
106+
mapOf(pos to TargetState.State(state))
107+
.simulate()
108+
.interactRequest(pendingInteractions)
109+
?.submit()
110+
}
111+
}
112+
}
113+
}
114+
115+
onStaticRender { event ->
116+
placementPos?.let { pos ->
117+
val boxes = placementState?.getOutlineShape(world, pos)?.boundingBoxes
118+
?: listOf(Box(0.0, 0.0, 0.0, 1.0, 1.0, 1.0))
119+
boxes.forEach { box ->
120+
event.outline(box.offset(pos), outlineColor)
121+
}
122+
}
123+
}
124+
125+
listen<MouseEvent.Scroll> { event ->
126+
if (!scrollBind.isSatisfied()) return@listen
127+
event.cancel()
128+
distance += event.delta.y
129+
}
130+
}
131+
}

src/main/kotlin/com/lambda/module/modules/player/Nuker.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ object Nuker : Module(
3535
description = "Breaks blocks around you",
3636
tag = ModuleTag.PLAYER,
3737
) {
38-
private val height by setting("Height", 4, 1..8, 1)
39-
private val width by setting("Width", 4, 1..8, 1)
38+
private val height by setting("Height", 6, 1..8, 1)
39+
private val width by setting("Width", 6, 1..8, 1)
4040
private val flatten by setting("Flatten", true)
4141
private val onGround by setting("On Ground", false, "Only break blocks when the player is standing on ground")
4242
private val fillFluids by setting("Fill Fluids", false, "Removes liquids by filling them in before breaking")

src/main/kotlin/com/lambda/util/InputUtils.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.lambda.util
1919

2020
import com.lambda.Lambda.mc
21+
import com.lambda.config.settings.complex.Bind
2122
import com.lambda.context.SafeContext
2223
import com.lambda.core.Loadable
2324
import com.lambda.event.events.KeyboardEvent
@@ -93,6 +94,15 @@ object InputUtils : Loadable {
9394
return MouseEvent.Click(mouse, GLFW_PRESS, mods)
9495
}
9596

97+
fun Bind.isSatisfied(): Boolean =
98+
(key == -1 || glfwGetKey(mc.window.handle, key).pressedOrRepeated) &&
99+
(mouse == -1 || glfwGetMouseButton(mc.window.handle, mouse).pressedOrRepeated) &&
100+
truemods.all {
101+
glfwGetKey(mc.window.handle, it.code).pressedOrRepeated
102+
}
103+
private val Int.pressedOrRepeated
104+
get() = this == 1 || this == 2
105+
96106
private val keys = KeyCode.entries.map { it.code }.filter { it > 0 }
97107
private val scancodes = keys.associateWith { GLFW.glfwGetKeyScancode(it) }
98108

0 commit comments

Comments
 (0)