Skip to content

Commit f40b103

Browse files
committed
various setting changes
1 parent 88d74be commit f40b103

File tree

20 files changed

+233
-126
lines changed

20 files changed

+233
-126
lines changed

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,18 @@ import com.lambda.config.settings.numeric.LongSetting
4444
import com.lambda.util.Communication.logError
4545
import com.lambda.util.KeyCode
4646
import com.lambda.util.Nameable
47+
import com.lambda.util.reflections.getInstancesImplementingWithParameters
4748
import imgui.flag.ImGuiInputTextFlags
49+
import io.github.classgraph.ClassInfoList
4850
import net.minecraft.block.Block
4951
import net.minecraft.item.Item
52+
import net.minecraft.network.listener.ClientPlayPacketListener
53+
import net.minecraft.network.packet.Packet
5054
import net.minecraft.registry.Registries
5155
import net.minecraft.util.math.BlockPos
5256
import net.minecraft.util.math.Vec3d
5357
import java.awt.Color
58+
import kotlin.reflect.KClass
5459

5560
/**
5661
* Represents a set of [AbstractSetting]s that are associated with the [name] of the [Configurable].
@@ -132,11 +137,12 @@ abstract class Configurable(
132137
fun setting(
133138
name: String,
134139
defaultValue: Collection<Block>,
140+
immutableCollection: Collection<Block> = Registries.BLOCK.toList(),
135141
description: String = "",
136142
visibility: () -> Boolean = { true },
137143
) = BlockCollectionSetting(
138144
name,
139-
Registries.BLOCK.toList(),
145+
immutableCollection,
140146
defaultValue.toMutableList(),
141147
description,
142148
visibility,
@@ -145,37 +151,38 @@ abstract class Configurable(
145151
fun setting(
146152
name: String,
147153
defaultValue: Collection<Item>,
154+
immutableCollection: Collection<Item> = Registries.ITEM.toList(),
148155
description: String = "",
149156
visibility: () -> Boolean = { true },
150157
) = ItemCollectionSetting(
151158
name,
152-
Registries.ITEM.toList(),
159+
immutableCollection,
153160
defaultValue.toMutableList(),
154161
description,
155162
visibility,
156163
).register()
157164

158165
inline fun <reified T : Comparable<T>> setting(
159166
name: String,
160-
immutableList: Collection<T>,
161-
defaultValue: Collection<T> = immutableList,
167+
defaultValue: Collection<T>,
168+
immutableList: Collection<T> = defaultValue,
162169
description: String = "",
163170
noinline visibility: () -> Boolean = { true },
164171
) = CollectionSetting(
165172
name,
166-
immutableList,
167173
defaultValue.toMutableList(),
174+
immutableList,
168175
TypeToken.getParameterized(Collection::class.java, T::class.java).type,
169176
description,
170177
visibility,
171178
).register()
172179

173180
inline fun <reified T : Any> setting(
174-
name: String,
175-
immutableList: Collection<T>,
176-
defaultValue: Collection<T> = immutableList,
177-
description: String = "",
178-
noinline visibility: () -> Boolean = { true },
181+
name: String,
182+
defaultValue: Collection<T>,
183+
immutableList: Collection<T> = defaultValue,
184+
description: String = "",
185+
noinline visibility: () -> Boolean = { true },
179186
) = ClassCollectionSetting(
180187
name,
181188
immutableList,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import com.lambda.config.configurations.UserAutomationConfigs
2121
import com.lambda.module.ModuleRegistry.moduleNameMap
2222

2323
class UserAutomationConfig(override val name: String) : AutomationConfig(name, UserAutomationConfigs) {
24-
val linkedModules = setting<String>("Linked Modules", moduleNameMap.filter { it.value.defaultAutomationConfig != Companion.DEFAULT }.keys, emptySet())
24+
val linkedModules = setting<String>("Linked Modules", emptySet(), moduleNameMap.filter { it.value.defaultAutomationConfig != Companion.DEFAULT }.keys)
2525
.onSelect { module -> moduleNameMap[module]?.automationConfig = this@UserAutomationConfig }
2626
.onDeselect { module ->
2727
moduleNameMap[module]?.let { module ->

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ open class BreakSettings(
5757
override val breakDelay by c.setting("Break Delay", 0, 0..6, 1, "The delay between breaking blocks", " tick(s)").group(baseGroup, Group.General).index()
5858

5959
// Timing
60-
override val tickStageMask by c.setting("Break Stage Mask", ALL_STAGES.toSet(), setOf(TickEvent.Input.Post), description = "The sub-tick timing at which break actions can be performed").group(baseGroup, Group.General).index()
60+
override val tickStageMask by c.setting("Break Stage Mask", setOf(TickEvent.Input.Post), ALL_STAGES.toSet(), description = "The sub-tick timing at which break actions can be performed").group(baseGroup, Group.General).index()
6161

6262
// Swap
6363
override val swapMode by c.setting("Swap Mode", BreakConfig.SwapMode.End, "Decides when to swap to the best suited tool when breaking a block").group(baseGroup, Group.General).index()

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package com.lambda.config.groups
2020
import com.lambda.config.Configurable
2121
import com.lambda.config.SettingGroup
2222
import com.lambda.util.NamedEnum
23-
import net.minecraft.item.Item
2423
import net.minecraft.item.Items
2524

2625
class EatSettings(
@@ -35,13 +34,13 @@ class EatSettings(
3534
override val eatOnHunger by c.setting("Eat On Hunger", true, "Whether to eat when hungry").group(baseGroup).index()
3635
override val minFoodLevel by c.setting("Minimum Food Level", 6, 0..20, 1, "The minimum food level to eat food", " food level") { eatOnHunger }.group(baseGroup).index()
3736
override val saturated by c.setting("Saturated", EatConfig.Saturation.EatSmart, "When to stop eating") { eatOnHunger }.group(baseGroup).index()
38-
override val nutritiousFood by c.setting("Nutritious Food", nutritiousFoodDefaults, description = "Items that are be considered nutritious") { eatOnHunger }.group(baseGroup).index()
37+
override val nutritiousFood by c.setting("Nutritious Food", nutritiousFoodDefaults, nutritiousFoodDefaults, "Items that are be considered nutritious") { eatOnHunger }.group(baseGroup).index()
3938
override val selectionPriority by c.setting("Selection Priority", EatConfig.SelectionPriority.MostNutritious, "The priority for selecting food items") { eatOnHunger }.group(baseGroup).index()
4039
override val eatOnFire by c.setting("Eat On Fire", true, "Whether to eat when on fire").group(baseGroup).index()
41-
override val resistanceFood by c.setting("Resistance Food", resistanceFoodDefaults, description = "Items that give Fire Resistance") { eatOnFire }.group(baseGroup).index()
40+
override val resistanceFood by c.setting("Resistance Food", resistanceFoodDefaults, resistanceFoodDefaults, "Items that give Fire Resistance") { eatOnFire }.group(baseGroup).index()
4241
override val eatOnDamage by c.setting("Eat On Damage", true, "Whether to eat when damaged").group(baseGroup).index()
4342
override val minDamage by c.setting("Minimum Damage", 10, 0..20, 1, "The minimum damage threshold to trigger eating") { eatOnDamage }.group(baseGroup).index()
44-
override val regenerationFood by c.setting("Regeneration Food", regenerationFoodDefaults, description = "Items that give Regeneration") { eatOnDamage }.group(baseGroup).index()
43+
override val regenerationFood by c.setting("Regeneration Food", regenerationFoodDefaults, regenerationFoodDefaults, "Items that give Regeneration") { eatOnDamage }.group(baseGroup).index()
4544
override val ignoreBadFood by c.setting("Ignore Bad Food", true, "Whether to eat when the food is bad").group(baseGroup).index()
46-
override val badFood by c.setting("Bad Food", negativeFoodDefaults, description = "Items that are considered bad food") { ignoreBadFood }.group(baseGroup).index()
45+
override val badFood by c.setting("Bad Food", negativeFoodDefaults, negativeFoodDefaults, "Items that are considered bad food") { ignoreBadFood }.group(baseGroup).index()
4746
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@ class HotbarSettings(
3232
override val swapDelay by c.setting("Swap Delay", 0, 0..3, 1, "The number of ticks delay before allowing another hotbar selection swap", " ticks").group(baseGroup).index()
3333
override val swapsPerTick by c.setting("Swaps Per Tick", 3, 1..10, 1, "The number of hotbar selection swaps that can take place each tick") { swapDelay <= 0 }.group(baseGroup).index()
3434
override val swapPause by c.setting("Swap Pause", 0, 0..20, 1, "The delay in ticks to pause actions after switching to the slot", " ticks").group(baseGroup).index()
35-
override val tickStageMask by c.setting("Hotbar Stage Mask", ALL_STAGES.toSet(), setOf(TickEvent.Input.Post), description = "The sub-tick timing at which hotbar actions are performed").group(baseGroup).index()
35+
override val tickStageMask by c.setting("Hotbar Stage Mask", setOf(TickEvent.Input.Post), ALL_STAGES.toSet(), description = "The sub-tick timing at which hotbar actions are performed").group(baseGroup).index()
3636
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class InteractSettings(
3131
override val rotate by c.setting("Rotate For Interact", true, "Rotates the player to look at the block when interacting").group(baseGroup).index()
3232
override val sorter by c.setting("Interact Sorter", ActionConfig.SortMode.Tool, "The order in which interactions are performed").group(baseGroup).index()
3333
override val swingHand by c.setting("Swing On Interact", true, "Swings the players hand after interacting").group(baseGroup).index()
34-
override val tickStageMask by c.setting("Interact Stage Mask", ALL_STAGES.toSet(), setOf(TickEvent.Input.Post), description = "The sub-tick timing at which interact actions are performed").group(baseGroup).index()
34+
override val tickStageMask by c.setting("Interact Stage Mask", setOf(TickEvent.Input.Post), ALL_STAGES.toSet(), description = "The sub-tick timing at which interact actions are performed").group(baseGroup).index()
3535
override val interactSwingType by c.setting("Interact Swing Type", BuildConfig.SwingType.Vanilla, "The style of swing") { swingHand }.group(baseGroup).index()
3636
override val interactConfirmationMode by c.setting("Interact Confirmation Mode", InteractConfig.InteractConfirmationMode.InteractThenAwait, "The style of confirmation for interactions").group(baseGroup).index()
3737
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class PlaceSettings(
3434
override val airPlace by c.setting("Air Place", AirPlaceMode.None, "Allows for placing blocks without adjacent faces").group(baseGroup).index()
3535
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") { airPlace.isEnabled }.group(baseGroup).index()
3636
override val sorter by c.setting("Place Sorter", ActionConfig.SortMode.Tool, "The order in which placements are performed").group(baseGroup).index()
37-
override val tickStageMask by c.setting("Place Stage Mask", ALL_STAGES.toSet(), setOf(TickEvent.Input.Post), description = "The sub-tick timing at which place actions are performed").group(baseGroup).index()
37+
override val tickStageMask by c.setting("Place Stage Mask", setOf(TickEvent.Input.Post), ALL_STAGES.toSet(), description = "The sub-tick timing at which place actions are performed").group(baseGroup).index()
3838
override val placeConfirmationMode by c.setting("Place Confirmation", PlaceConfirmationMode.PlaceThenAwait, "Wait for block placement confirmation").group(baseGroup).index()
3939
override val maxPendingPlacements by c.setting("Max Pending Placements", 5, 0..30, 1, "The maximum amount of pending placements").group(baseGroup).index()
4040
override val placementsPerTick by c.setting("Places Per Tick", 1, 1..30, 1, "Maximum instant block places per tick").group(baseGroup).index()

src/main/kotlin/com/lambda/config/settings/collections/BlockCollectionSetting.kt

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import com.google.gson.reflect.TypeToken
2222
import com.lambda.Lambda.gson
2323
import com.lambda.config.serializer.BlockCodec
2424
import com.lambda.gui.dsl.ImGuiBuilder
25+
import com.lambda.util.StringUtils.levenshteinDistance
26+
import imgui.ImGuiListClipper
27+
import imgui.flag.ImGuiChildFlags
2528
import imgui.flag.ImGuiSelectableFlags.DontClosePopups
2629
import net.minecraft.block.Block
2730

@@ -33,40 +36,46 @@ class BlockCollectionSetting(
3336
visibility: () -> Boolean,
3437
) : CollectionSetting<Block>(
3538
name,
36-
immutableCollection,
3739
defaultValue,
40+
immutableCollection,
3841
TypeToken.getParameterized(Collection::class.java, Block::class.java).type,
3942
description,
4043
visibility,
4144
) {
45+
private var searchFilter = ""
46+
4247
override fun ImGuiBuilder.buildLayout() {
4348
val text = if (value.size == 1) "block" else "blocks"
4449

4550
combo("##$name", "$name: ${value.size} $text") {
46-
value.toMutableList() // Copy the list instead of iterating the immutable one
47-
.forEach {
48-
selectable(
49-
label = BlockCodec.stringify(it),
50-
selected = true,
51-
flags = DontClosePopups
52-
) { value.remove(it) }
53-
}
54-
}
51+
inputText("##$name-SearchBox", ::searchFilter)
5552

56-
button("Add") { openPopup("Blocks") }
53+
child(
54+
strId = "##$name-ComboOptionsChild",
55+
childFlags = ImGuiChildFlags.AutoResizeY or ImGuiChildFlags.AlwaysAutoResize,
56+
) {
57+
val list = immutableCollection
58+
.filter { searchFilter == "" || searchFilter.levenshteinDistance(BlockCodec.stringify(it)) < 3 }
5759

58-
popup("Blocks") {
59-
filter("Search for blocks") { filter ->
60-
immutableCollection
61-
.filter {
62-
//filter.inputBuffer.levenshteinDistance(ItemCodec.stringify(it)) < 3 &&
63-
!value.contains(it)
64-
}
65-
.forEach {
66-
text(BlockCodec.stringify(it))
67-
sameLine()
68-
button("Add") { value.add(it) }
60+
ImGuiListClipper.forEach { // not actually iterating
61+
it.begin(list.size)
62+
63+
while (it.step()) {
64+
for (i in it.displayStart..it.displayEnd) {
65+
val v = list.getOrNull(i) ?: continue
66+
val selected = value.contains(v)
67+
68+
selectable(
69+
label = BlockCodec.stringify(v),
70+
selected = selected,
71+
flags = DontClosePopups
72+
) {
73+
if (selected) value.remove(v)
74+
else value.add(v)
75+
}
76+
}
6977
}
78+
}
7079
}
7180
}
7281
}

src/main/kotlin/com/lambda/config/settings/collections/ClassCollectionSetting.kt

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ import com.google.gson.JsonElement
2121
import com.google.gson.reflect.TypeToken
2222
import com.lambda.Lambda.gson
2323
import com.lambda.gui.dsl.ImGuiBuilder
24+
import com.lambda.util.StringUtils.levenshteinDistance
25+
import com.lambda.util.reflections.className
26+
import imgui.ImGuiListClipper
27+
import imgui.flag.ImGuiChildFlags
2428
import imgui.flag.ImGuiSelectableFlags.DontClosePopups
2529

2630
/**
27-
* @see [com.lambda.config.settings.collections.CollectionSettings]
31+
* @see [com.lambda.config.settings.collections.CollectionSetting]
2832
* @see [com.lambda.config.Configurable]
2933
*/
3034
class ClassCollectionSetting<T : Any>(
@@ -35,34 +39,50 @@ class ClassCollectionSetting<T : Any>(
3539
visibility: () -> Boolean,
3640
) : CollectionSetting<T>(
3741
name,
38-
immutableCollection,
3942
defaultValue,
43+
immutableCollection,
4044
TypeToken.getParameterized(Collection::class.java, Any::class.java).type,
4145
description,
4246
visibility,
4347
) {
48+
private var searchFilter = ""
49+
4450
override fun ImGuiBuilder.buildLayout() {
45-
combo("##$name", "$name: ${value.size} item(s)") {
46-
immutableCollection
47-
.forEach {
48-
val isSelected = value.contains(it)
51+
val text = if (value.size == 1) "item" else "items"
52+
53+
combo("##$name", "$name: ${value.size} $text") {
54+
inputText("##$name-SearchBox", ::searchFilter)
4955

50-
selectable(
51-
label = it.className,
52-
selected = isSelected,
53-
flags = DontClosePopups,
54-
) {
55-
if (isSelected) value.remove(it)
56-
else value.add(it)
56+
child(
57+
strId = "##$name-ComboOptionsChild",
58+
childFlags = ImGuiChildFlags.AutoResizeY or ImGuiChildFlags.AlwaysAutoResize,
59+
) {
60+
val list = immutableCollection
61+
.filter { searchFilter == "" || searchFilter.levenshteinDistance(it.className) < 3 }
62+
63+
ImGuiListClipper.forEach { // not actually iterating
64+
it.begin(list.size)
65+
66+
while (it.step()) {
67+
for (i in it.displayStart..it.displayEnd) {
68+
val v = list.getOrNull(i) ?: continue
69+
val selected = value.contains(v)
70+
71+
selectable(
72+
label = v.className,
73+
selected = selected,
74+
flags = DontClosePopups
75+
) {
76+
if (selected) value.remove(v)
77+
else value.add(v)
78+
}
79+
}
5780
}
5881
}
82+
}
5983
}
6084
}
6185

62-
val Any.className: String get() = this::class.java.name
63-
.substringAfter("${this::class.java.packageName}.")
64-
.replace('$', '.')
65-
6686
// When serializing the list to json we do not want to serialize the elements' classes, but their stringified representation.
6787
// If we do serialize the classes we'll run into missing type adapters errors by Gson.
6888
// This is intended behaviour. If you wish your collection settings to display something else then you must extend this class.

src/main/kotlin/com/lambda/config/settings/collections/CollectionSetting.kt

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import com.lambda.config.SettingEditorDsl
2525
import com.lambda.config.SettingGroupEditor
2626
import com.lambda.context.SafeContext
2727
import com.lambda.gui.dsl.ImGuiBuilder
28+
import com.lambda.util.StringUtils.levenshteinDistance
29+
import imgui.ImGuiListClipper
30+
import imgui.flag.ImGuiChildFlags
2831
import imgui.flag.ImGuiSelectableFlags.DontClosePopups
2932
import java.lang.reflect.Type
3033

@@ -40,8 +43,8 @@ import java.lang.reflect.Type
4043
*/
4144
open class CollectionSetting<T : Any>(
4245
override var name: String,
43-
private var immutableCollection: Collection<T>,
4446
defaultValue: MutableCollection<T>,
47+
private var immutableCollection: Collection<T>,
4548
type: Type,
4649
description: String,
4750
visibility: () -> Boolean,
@@ -52,6 +55,7 @@ open class CollectionSetting<T : Any>(
5255
description,
5356
visibility
5457
) {
58+
private var searchFilter = ""
5559
private val strListType =
5660
TypeToken.getParameterized(Collection::class.java, String::class.java).type
5761

@@ -67,20 +71,38 @@ open class CollectionSetting<T : Any>(
6771
}
6872

6973
override fun ImGuiBuilder.buildLayout() {
70-
combo("##$name", "$name: ${value.size} item(s)") {
71-
immutableCollection
72-
.forEach {
73-
val isSelected = value.contains(it)
74-
75-
selectable(
76-
label = it.toString(),
77-
selected = isSelected,
78-
flags = DontClosePopups,
79-
) {
80-
if (isSelected) value.remove(it)
81-
else value.add(it)
74+
val text = if (value.size == 1) "item" else "items"
75+
76+
combo("##$name", "$name: ${value.size} $text") {
77+
inputText("##$name-SearchBox", ::searchFilter)
78+
79+
child(
80+
strId = "##$name-ComboOptionsChild",
81+
childFlags = ImGuiChildFlags.AutoResizeY or ImGuiChildFlags.AlwaysAutoResize,
82+
) {
83+
val list = immutableCollection
84+
.filter { searchFilter == "" || searchFilter.levenshteinDistance(it.toString()) < 3 }
85+
86+
ImGuiListClipper.forEach { // not actually iterating
87+
it.begin(list.size)
88+
89+
while (it.step()) {
90+
for (i in it.displayStart..it.displayEnd) {
91+
val v = list.getOrNull(i) ?: continue
92+
val selected = value.contains(v)
93+
94+
selectable(
95+
label = v.toString(),
96+
selected = selected,
97+
flags = DontClosePopups
98+
) {
99+
if (selected) value.remove(v)
100+
else value.add(v)
101+
}
102+
}
82103
}
83104
}
105+
}
84106
}
85107
}
86108

0 commit comments

Comments
 (0)