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
19+
20+ import com.lambda.config.configurations.AutomationConfigs
21+ import com.lambda.config.groups.BreakSettings
22+ import com.lambda.config.groups.BuildSettings
23+ import com.lambda.config.groups.EatSettings
24+ import com.lambda.config.groups.HotbarSettings
25+ import com.lambda.config.groups.InteractSettings
26+ import com.lambda.config.groups.InventorySettings
27+ import com.lambda.config.groups.PlaceSettings
28+ import com.lambda.config.groups.RotationSettings
29+ import com.lambda.context.Automated
30+ import com.lambda.event.events.onStaticRender
31+ import com.lambda.interaction.construction.result.Drawable
32+ import com.lambda.module.Module
33+ import com.lambda.util.NamedEnum
34+ import kotlin.reflect.KProperty0
35+ import kotlin.reflect.jvm.isAccessible
36+
37+ @Suppress(" unchecked_cast" , " unused" )
38+ open class AutomationConfig (
39+ override val name : String ,
40+ configuration : Configuration = AutomationConfigs
41+ ) : Configurable(configuration), Automated {
42+ enum class Group (override val displayName : String ) : NamedEnum {
43+ Build (" Build" ),
44+ Break (" Break" ),
45+ Place (" Place" ),
46+ Interact (" Interact" ),
47+ Rotation (" Rotation" ),
48+ Interaction (" Interaction" ),
49+ Inventory (" Inventory" ),
50+ Hotbar (" Hotbar" ),
51+ Eat (" Eat" ),
52+ Render (" Render" ),
53+ Debug (" Debug" )
54+ }
55+
56+ override val buildConfig = BuildSettings (this , Group .Build )
57+ override val breakConfig = BreakSettings (this , Group .Break )
58+ override val placeConfig = PlaceSettings (this , Group .Place )
59+ override val interactConfig = InteractSettings (this , Group .Interact )
60+ override val rotationConfig = RotationSettings (this , Group .Rotation )
61+ override val inventoryConfig = InventorySettings (this , Group .Inventory )
62+ override val hotbarConfig = HotbarSettings (this , Group .Hotbar )
63+ override val eatConfig = EatSettings (this , Group .Eat )
64+
65+ val hiddenSettings = mutableSetOf<AbstractSetting <* >>()
66+
67+ companion object {
68+ context(module: Module )
69+ fun automationConfig (name : String = module.name, edits : (AutomationConfig .() -> Unit )? = null): AutomationConfig =
70+ AutomationConfig (" Default $name Automation Config" ).apply { edits?.invoke(this ) }
71+
72+ fun automationConfig (name : String , edits : (AutomationConfig .() -> Unit )? = null): AutomationConfig =
73+ AutomationConfig (" Default $name Automation Config" ).apply { edits?.invoke(this ) }
74+
75+ object DEFAULT : AutomationConfig(" Default Automation Config" ) {
76+ val renders by setting(" Render" , false ).group(Group .Render )
77+ val avoidDesync by setting(" Avoid Desync" , true , " Cancels incoming inventory update packets if they match previous actions" ).group(Group .Debug )
78+ val desyncTimeout by setting(" Desync Timeout" , 30 , 1 .. 30 , 1 , unit = " ticks" , description = " Time to store previous inventory actions before dropping the cache" ) { avoidDesync }.group(Group .Debug )
79+ val showAllEntries by setting(" Show All Entries" , false , " Show all entries in the task tree" ).group(Group .Debug )
80+ val shrinkFactor by setting(" Shrink Factor" , 0.001 , 0.0 .. 1.0 , 0.001 ).group(Group .Debug )
81+ val ignoreItemDropWarnings by setting(" Ignore Drop Warnings" , false , " Hides the item drop warnings from the break manager" ).group(Group .Debug )
82+ val maxSimDependencies by setting(" Max Sim Dependencies" , 3 , 0 .. 10 , 1 , " Maximum dependency build results" ).group(Group .Debug )
83+
84+ @Volatile
85+ var drawables = listOf<Drawable >()
86+
87+ init {
88+ onStaticRender {
89+ if (renders)
90+ with (it) { drawables.forEach { with (it) { buildRenderer() } } }
91+ }
92+ }
93+ }
94+ }
95+
96+ @DslMarker
97+ annotation class SettingEditorDsl
98+
99+ private val KProperty0 <* >.delegate
100+ get() = try {
101+ apply { isAccessible = true }.getDelegate()
102+ } catch (e: Exception ) {
103+ throw IllegalStateException (" Could not access delegate for property $name " , e)
104+ }
105+
106+ @SettingEditorDsl
107+ internal inline fun <T : Any > KProperty0<T>.edit (edits : TypedEditBuilder <T >.(AbstractSetting <T >) -> Unit ) {
108+ val setting = delegate as ? AbstractSetting <T > ? : throw IllegalStateException (" Setting delegate did not match current value's type" )
109+ TypedEditBuilder (this @AutomationConfig, listOf (setting)).edits(setting)
110+ }
111+
112+ @SettingEditorDsl
113+ internal inline fun <T : Any , R : Any > KProperty0<T>.editWith (
114+ other : KProperty0 <R >,
115+ edits : TypedEditBuilder <T >.(AbstractSetting <R >) -> Unit
116+ ) {
117+ val setting = delegate as ? AbstractSetting <T > ? : throw IllegalStateException (" Setting delegate did not match current value's type" )
118+ TypedEditBuilder (this @AutomationConfig, listOf (setting)).edits(other.delegate as AbstractSetting <R >)
119+ }
120+
121+ @SettingEditorDsl
122+ fun edit (
123+ vararg settings : KProperty0 <* >,
124+ edits : BasicEditBuilder .() -> Unit
125+ ) { BasicEditBuilder (this @AutomationConfig, settings.map { it.delegate } as List <AbstractSetting <* >>).apply (edits) }
126+
127+ @SettingEditorDsl
128+ internal inline fun <T : Any > editWith (
129+ vararg settings : KProperty0 <* >,
130+ other : KProperty0 <T >,
131+ edits : BasicEditBuilder .(AbstractSetting <T >) -> Unit
132+ ) { BasicEditBuilder (this @AutomationConfig, settings.map { it.delegate } as List <AbstractSetting <* >>).edits(other.delegate as AbstractSetting <T >) }
133+
134+ @SettingEditorDsl
135+ internal inline fun <T : Any > editTyped (
136+ vararg settings : KProperty0 <T >,
137+ edits : TypedEditBuilder <T >.() -> Unit
138+ ) { TypedEditBuilder (this @AutomationConfig, settings.map { it.delegate } as List <AbstractSetting <T >>).apply (edits) }
139+
140+ @SettingEditorDsl
141+ internal inline fun <T : Any , R : Any > editTypedWith (
142+ vararg settings : KProperty0 <T >,
143+ other : KProperty0 <R >,
144+ edits : TypedEditBuilder <T >.(AbstractSetting <R >) -> Unit
145+ ) = TypedEditBuilder (this @AutomationConfig, settings.map { it.delegate } as List <AbstractSetting <T >>).edits(other.delegate as AbstractSetting <R >)
146+
147+ @SettingEditorDsl
148+ fun hide (vararg settings : KProperty0 <* >) {
149+ hideAll((settings.map { it.delegate } as List <AbstractSetting <* >>))
150+ }
151+
152+ @SettingEditorDsl
153+ fun hideAll (settingGroup : SettingGroup ) = hideAll(settingGroup.settings)
154+
155+ @SettingEditorDsl
156+ fun hideAll (settings : Collection <AbstractSetting <* >>) {
157+ this @AutomationConfig.settings.removeAll(settings)
158+ hiddenSettings.addAll(settings)
159+ }
160+
161+ @SettingEditorDsl
162+ fun hideAll (vararg settingGroups : SettingGroup ) {
163+ settingGroups.forEach { hideAll(it.settings) }
164+ }
165+
166+ @SettingEditorDsl
167+ fun hideAllExcept (settingGroup : SettingGroup , vararg settings : KProperty0 <* >) {
168+ this @AutomationConfig.settings.removeIf {
169+ return @removeIf if (it in settingGroup.settings && it !in (settings.toList() as List <AbstractSetting <* >>)) {
170+ hiddenSettings.add(it)
171+ true
172+ } else false
173+ }
174+ }
175+
176+ open class BasicEditBuilder (val c : AutomationConfig , open val settings : Collection <AbstractSetting <* >>) {
177+ @SettingEditorDsl
178+ fun visibility (vis : () -> Boolean ) =
179+ settings.forEach { it.visibility = vis }
180+
181+ @SettingEditorDsl
182+ fun hide () = c.hideAll(settings)
183+
184+ @SettingEditorDsl
185+ fun groups (vararg groups : NamedEnum ) =
186+ settings.forEach { it.groups = mutableListOf (groups.toList()) }
187+
188+ @SettingEditorDsl
189+ fun groups (groups : MutableList <List <NamedEnum >>) =
190+ settings.forEach { it.groups = groups }
191+ }
192+
193+ open class TypedEditBuilder <T : Any >(
194+ c : AutomationConfig ,
195+ override val settings : Collection <AbstractSetting <T >>
196+ ) : BasicEditBuilder(c, settings) {
197+ @SettingEditorDsl
198+ fun defaultValue (value : T ) =
199+ settings.forEach {
200+ it.defaultValue = value
201+ it.value = value
202+ }
203+ }
204+
205+ enum class InsertMode {
206+ Above ,
207+ Below
208+ }
209+ }
0 commit comments