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