Skip to content

Commit 23a2a91

Browse files
committed
AutoEat prototype
1 parent 8bccf93 commit 23a2a91

File tree

17 files changed

+383
-69
lines changed

17 files changed

+383
-69
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,16 @@ class BreakSettings(
8080
override val ignoredBlocks by c.setting("Ignored Blocks", allSigns, description = "Blocks that wont be broken", visibility = vis).group(groupPath, Group.General)
8181

8282
// Tool
83-
override val suitableToolsOnly by c.setting("Suitable Tools Only", false, "Places a restriction to only use tools suitable for the given block", visibility = vis).group(groupPath, Group.General)
83+
override val suitableToolsOnly by c.setting("Suitable Tools Only", true, "Only use tools suitable for the given block (will get the item drop)", visibility = vis).group(groupPath, Group.General)
8484
override val forceSilkTouch by c.setting("Force Silk Touch", false, "Force silk touch when breaking blocks", visibility = vis).group(groupPath, Group.General)
8585
override val forceFortunePickaxe by c.setting("Force Fortune Pickaxe", false, "Force fortune pickaxe when breaking blocks", visibility = vis).group(groupPath, Group.General)
8686
override val minFortuneLevel by c.setting("Min Fortune Level", 1, 1..3, 1, "The minimum fortune level to use") { vis() && forceFortunePickaxe }.group(groupPath, Group.General)
87+
override val useWoodenTools by c.setting("Use Wooden Tools", true, "Use wooden tools when breaking blocks", visibility = vis).group(groupPath, Group.General)
88+
override val useStoneTools by c.setting("Use Stone Tools", true, "Use stone tools when breaking blocks", visibility = vis).group(groupPath, Group.General)
89+
override val useIronTools by c.setting("Use Iron Tools", true, "Use iron tools when breaking blocks", visibility = vis).group(groupPath, Group.General)
90+
override val useDiamondTools by c.setting("Use Diamond Tools", true, "Use diamond tools when breaking blocks", visibility = vis).group(groupPath, Group.General)
91+
override val useGoldTools by c.setting("Use Gold Tools", true, "Use gold tools when breaking blocks", visibility = vis).group(groupPath, Group.General)
92+
override val useNetheriteTools by c.setting("Use Netherite Tools", true, "Use netherite tools when breaking blocks", visibility = vis).group(groupPath, Group.General)
8793

8894
// Cosmetics
8995
override val sounds by c.setting("Break Sounds", true, "Plays the breaking sounds", visibility = vis).group(groupPath, Group.Cosmetic)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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.groups
19+
20+
import com.lambda.util.NamedEnum
21+
import net.minecraft.item.Item
22+
23+
interface EatConfig {
24+
val eatFood: Boolean
25+
val minFoodLevel: Int
26+
val eatUntilFull: Boolean
27+
val eatOnFire: Boolean
28+
val eatHeal: Boolean
29+
30+
val selectionMode: SelectionMode
31+
val whitelist: List<Item>
32+
val blacklist: List<Item>
33+
34+
enum class SelectionMode(override val displayName: String): NamedEnum {
35+
Whitelist("Whitelist"),
36+
Blacklist("Blacklist")
37+
}
38+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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.groups
19+
20+
import com.lambda.config.Configurable
21+
import com.lambda.event.events.TickEvent
22+
import com.lambda.interaction.request.hotbar.HotbarConfig
23+
import com.lambda.util.NamedEnum
24+
import net.minecraft.item.Item
25+
import net.minecraft.item.Items
26+
27+
class EatSettings(
28+
c: Configurable,
29+
baseGroup: NamedEnum,
30+
vis: () -> Boolean = { true }
31+
) : EatConfig {
32+
val defaultWhitelist = listOf(Items.GOLDEN_CARROT)
33+
34+
override val eatFood by c.setting("Eat Food", true, "Whether food should be eaten", vis).group(baseGroup)
35+
override val eatUntilFull by c.setting("Eat Until Full", false, "Eat until the food level is full") { vis() && eatFood }.group(baseGroup)
36+
override val minFoodLevel by c.setting("Minimum Food Level", 6, 0..20, 1, "The minimum food level to eat food", " food level") { vis() && eatFood }.group(baseGroup)
37+
override val eatOnFire by c.setting("Eat On Fire", false, "Eat when you are on fire") { vis() && eatFood }.group(baseGroup)
38+
override val eatHeal by c.setting("Eat Heal", false, "Eat healing food when you are below the minimum health level") { vis() && eatFood }.group(baseGroup)
39+
override val selectionMode by c.setting("Selection Mode", EatConfig.SelectionMode.Whitelist, "The selection mode for eating") { vis() && eatFood }.group(baseGroup)
40+
override val whitelist by c.setting("Whitelist", defaultWhitelist, defaultWhitelist, "The whitelist of items to eat") { vis() && eatFood }.group(baseGroup)
41+
override val blacklist by c.setting("Blacklist", listOf(), listOf<Item>(), "The blacklist of items to eat") { vis() && eatFood }.group(baseGroup)
42+
}

src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ abstract class BuildResult : ComparableResult<Rank>, Nameable {
9292
}
9393

9494
/**
95-
* The player has no permission to interact with the block. (E.g.: Spectator mode)
95+
* The player has no permission to interact with the block. (E.g.: Adventure mode)
9696
* @param blockPos The position of the block that is restricted.
9797
*/
9898
data class Restricted(
@@ -204,14 +204,12 @@ abstract class BuildResult : ComparableResult<Rank>, Nameable {
204204
override val pausesParent get() = true
205205

206206
override fun resolve() =
207-
neededSelection.let { selection ->
208-
selection.transfer(MainHandContainer, inventory)
209-
?: MaterialContainer.AwaitItemTask(
210-
"Couldn't find $neededSelection anywhere.",
211-
selection,
212-
inventory
213-
)
214-
}
207+
neededSelection.transfer(MainHandContainer, inventory)
208+
?: MaterialContainer.AwaitItemTask(
209+
"Couldn't find $neededSelection anywhere.",
210+
neededSelection,
211+
inventory
212+
)
215213

216214
override fun ShapeBuilder.buildRenderer() {
217215
box(blockPos, color, color)

src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import com.lambda.util.BlockUtils.hasFluid
6161
import com.lambda.util.BlockUtils.instantBreakable
6262
import com.lambda.util.BlockUtils.isEmpty
6363
import com.lambda.util.BlockUtils.isNotEmpty
64+
import com.lambda.util.Communication.info
6465
import com.lambda.util.Communication.warn
6566
import com.lambda.util.math.distSq
6667
import com.lambda.util.math.vec3d
@@ -85,6 +86,13 @@ import net.minecraft.item.Item
8586
import net.minecraft.item.ItemPlacementContext
8687
import net.minecraft.item.ItemStack
8788
import net.minecraft.item.ItemUsageContext
89+
import net.minecraft.item.Items
90+
import net.minecraft.registry.tag.ItemTags.DIAMOND_TOOL_MATERIALS
91+
import net.minecraft.registry.tag.ItemTags.GOLD_TOOL_MATERIALS
92+
import net.minecraft.registry.tag.ItemTags.IRON_TOOL_MATERIALS
93+
import net.minecraft.registry.tag.ItemTags.NETHERITE_TOOL_MATERIALS
94+
import net.minecraft.registry.tag.ItemTags.STONE_TOOL_MATERIALS
95+
import net.minecraft.registry.tag.ItemTags.WOODEN_TOOL_MATERIALS
8896
import net.minecraft.state.property.Properties
8997
import net.minecraft.util.Hand
9098
import net.minecraft.util.hit.BlockHitResult
@@ -396,9 +404,8 @@ object BuildSimulator {
396404
if (!currentState.isReplaceable && !statePromoting) return acc
397405

398406
preProcessing.sides.forEach { neighbor ->
399-
val hitPos = if (!place.airPlace.isEnabled && (currentState.isEmpty || statePromoting))
400-
pos.offset(neighbor)
401-
else pos
407+
val hitPos = if (!place.airPlace.isEnabled && (currentState.isAir || statePromoting))
408+
pos.offset(neighbor) else pos
402409
val hitSide = neighbor.opposite
403410

404411
val voxelShape = blockState(hitPos).getOutlineShape(world, hitPos).let { outlineShape ->
@@ -644,7 +651,7 @@ object BuildSimulator {
644651
val state = blockState(pos)
645652

646653
/* is a block that will be destroyed by breaking adjacent blocks */
647-
if (!breaking.breakWeakBlocks && state.block.hardness == 0f && state.isNotEmpty) {
654+
if (!breaking.breakWeakBlocks && state.block.hardness == 0f && !state.isAir && state.isNotEmpty) {
648655
acc.add(BuildResult.Ignored(pos))
649656
return acc
650657
}
@@ -831,13 +838,24 @@ object BuildSimulator {
831838
state.calcItemBlockBreakingDelta(player, world, pos, it)
832839
}
833840
) {
834-
run {
835-
if (breaking.suitableToolsOnly) isSuitableForBreaking(state)
836-
else StackSelection.EVERYTHING
837-
} and if (breaking.forceSilkTouch) {
838-
hasEnchantment(Enchantments.AQUA_AFFINITY)
839-
} else if (breaking.forceFortunePickaxe) {
840-
hasEnchantment(Enchantments.FORTUNE, breaking.minFortuneLevel)
841+
isTool() and if (breaking.suitableToolsOnly) {
842+
isSuitableForBreaking(state)
843+
} else StackSelection.EVERYTHING and if (breaking.forceSilkTouch) {
844+
hasEnchantment(Enchantments.SILK_TOUCH)
845+
} else StackSelection.EVERYTHING and if (breaking.forceFortunePickaxe) {
846+
hasEnchantment(Enchantments.FORTUNE)
847+
} else StackSelection.EVERYTHING and if (!breaking.useWoodenTools) {
848+
hasTag(WOODEN_TOOL_MATERIALS).not()
849+
} else StackSelection.EVERYTHING and if (!breaking.useStoneTools) {
850+
hasTag(STONE_TOOL_MATERIALS).not()
851+
} else StackSelection.EVERYTHING and if (!breaking.useIronTools) {
852+
hasTag(IRON_TOOL_MATERIALS).not()
853+
} else StackSelection.EVERYTHING and if (!breaking.useDiamondTools) {
854+
hasTag(DIAMOND_TOOL_MATERIALS).not()
855+
} else StackSelection.EVERYTHING and if (!breaking.useGoldTools) {
856+
hasTag(GOLD_TOOL_MATERIALS).not()
857+
} else StackSelection.EVERYTHING and if (!breaking.useNetheriteTools) {
858+
hasTag(NETHERITE_TOOL_MATERIALS).not()
841859
} else StackSelection.EVERYTHING
842860
}
843861

@@ -851,7 +869,8 @@ object BuildSimulator {
851869
return acc
852870
}
853871

854-
val swapStack = swapCandidates.map { it.matchingStacks(stackSelection) }
872+
val swapStack = swapCandidates
873+
.map { it.matchingStacks(stackSelection) }
855874
.asSequence()
856875
.flatten()
857876
.let { containerStacks ->

src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
4646
pos: BlockPos,
4747
world: ClientWorld,
4848
ignoredProperties: Collection<Property<*>>
49-
) =
50-
state.isEmpty
49+
) = state.isEmpty
5150

5251
override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack =
5352
ItemStack.EMPTY
@@ -63,8 +62,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
6362
pos: BlockPos,
6463
world: ClientWorld,
6564
ignoredProperties: Collection<Property<*>>
66-
) =
67-
state.isAir
65+
) = state.isAir
6866

6967
override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack =
7068
ItemStack.EMPTY

0 commit comments

Comments
 (0)