Skip to content

Commit 8a2b456

Browse files
committed
litematica printer module
1 parent 2a37110 commit 8a2b456

File tree

6 files changed

+100
-3
lines changed

6 files changed

+100
-3
lines changed

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ val mockkVersion: String by project
3636
val spairVersion: String by project
3737
val lwjglVersion: String by project
3838
val sodiumVersion: String by project
39+
val litematicaVersion: String by project
3940

4041
val libs = file("libs")
4142
val targets = listOf("fabric.mod.json")
@@ -175,6 +176,7 @@ dependencies {
175176
// Add mods
176177
modImplementation("com.github.rfresh2:baritone-fabric:$minecraftVersion")
177178
modCompileOnly("maven.modrinth:sodium:$sodiumVersion")
179+
modCompileOnly("maven.modrinth:litematica:$litematicaVersion")
178180

179181
// Test implementations
180182
testImplementation(kotlin("test"))

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ yarnMappings=build.1
4848
fabricApiVersion=0.124.0
4949
kotlinFabricVersion=1.13.4+kotlin
5050
sodiumVersion=mc1.21.5-0.6.13-fabric
51+
litematicaVersion=0.22.2
5152

5253
# Kotlin https://kotlinlang.org/
5354
kotlin.code.style=official

src/main/kotlin/com/lambda/config/settings/comparable/EnumSetting.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ class EnumSetting<T : Enum<T>>(
7171
lambdaTooltip(description)
7272
}
7373

74-
7574
override fun CommandBuilder.buildCommand(registry: CommandRegistryAccess) {
7675
required(word(name)) { parameter ->
7776
suggests { _, builder ->

src/main/kotlin/com/lambda/context/AutomationConfig.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ object AutomationConfig : Configurable(LambdaConfig), Automated {
4040
Place("Place"),
4141
Interact("Interact"),
4242
Rotation("Rotation"),
43-
Interaction("Interaction"),
4443
Inventory("Inventory"),
4544
Hotbar("Hotbar"),
4645
Eat("Eat"),

src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ object MainHandContainer : MaterialContainer(Rank.MainHand) {
6666
return@inventoryRequest
6767
}
6868

69-
val slot = player.currentScreenHandler.slots.first { it.stack == moveStack } ?: throw NotInInventoryException()
69+
val slot = player.currentScreenHandler.slots.firstOrNull { it.stack == moveStack } ?: throw NotInInventoryException()
7070
swap(slot.id, player.inventory.selectedSlot)
7171

7272
if (hand == Hand.OFF_HAND) swapHands()
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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.groups.BreakSettings
21+
import com.lambda.config.groups.BuildSettings
22+
import com.lambda.config.groups.HotbarSettings
23+
import com.lambda.config.groups.InteractSettings
24+
import com.lambda.config.groups.InventorySettings
25+
import com.lambda.config.groups.PlaceSettings
26+
import com.lambda.config.groups.RotationSettings
27+
import com.lambda.interaction.construction.blueprint.TickingBlueprint
28+
import com.lambda.interaction.construction.verify.TargetState
29+
import com.lambda.interaction.request.placing.PlaceConfig
30+
import com.lambda.module.Module
31+
import com.lambda.module.tag.ModuleTag
32+
import com.lambda.task.RootTask.run
33+
import com.lambda.task.Task
34+
import com.lambda.task.tasks.BuildTask.Companion.build
35+
import com.lambda.util.BlockUtils.blockPos
36+
import com.lambda.util.NamedEnum
37+
import fi.dy.masa.litematica.world.SchematicWorldHandler
38+
import net.minecraft.util.math.BlockPos
39+
40+
object Printer : Module(
41+
name = "Printer",
42+
description = "Automatically prints schematics",
43+
tag = ModuleTag.PLAYER
44+
) {
45+
private fun isSchematicHandlerAvailable(): Boolean = runCatching {
46+
Class.forName("fi.dy.masa.litematica.world.SchematicWorldHandler")
47+
true
48+
}.getOrDefault(false)
49+
50+
private val range by setting("Range", 5, 1..7, 1).group(Group.General)
51+
override val buildConfig = BuildSettings(this, Group.Build).apply {
52+
editTyped(::pathing, ::stayInRange) { defaultValue(false) }
53+
}
54+
override val breakConfig = BreakSettings(this, Group.Break).apply {
55+
editTyped(::efficientOnly, ::suitableToolsOnly) { defaultValue(false) }
56+
}
57+
override val placeConfig = PlaceSettings(this, Group.Place).apply {
58+
::airPlace.edit { defaultValue(PlaceConfig.AirPlaceMode.Grim) }
59+
}
60+
override val interactConfig = InteractSettings(this, Group.Interact)
61+
override val rotationConfig = RotationSettings(this, Group.Rotation)
62+
override val inventoryConfig = InventorySettings(this, Group.Inventory)
63+
override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
64+
65+
private var buildTask: Task<*>? = null
66+
67+
private enum class Group(override val displayName: String) : NamedEnum {
68+
General("General"),
69+
Build("Build"),
70+
Break("Break"),
71+
Place("Place"),
72+
Interact("Interact"),
73+
Rotation("Rotation"),
74+
Inventory("Inventory"),
75+
Hotbar("Hotbar")
76+
}
77+
78+
init {
79+
onEnable {
80+
if (!isSchematicHandlerAvailable()) {
81+
error("Litematica is not installed!")
82+
disable()
83+
return@onEnable
84+
}
85+
buildTask = TickingBlueprint {
86+
val schematicWorld = SchematicWorldHandler.getSchematicWorld() ?: return@TickingBlueprint emptyMap()
87+
BlockPos.iterateOutwards(player.blockPos, range, range, range)
88+
.asSequence()
89+
.map { it.blockPos }
90+
.associateWith { TargetState.State(schematicWorld.getBlockState(it)) }
91+
}.build(finishOnDone = false).run()
92+
}
93+
94+
onDisable { buildTask?.cancel(); buildTask = null }
95+
}
96+
}

0 commit comments

Comments
 (0)