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.combat
19+
20+ import com.lambda.config.AutomationConfig.Companion.setDefaultAutomationConfig
21+ import com.lambda.config.applyEdits
22+ import com.lambda.context.SafeContext
23+ import com.lambda.friend.FriendManager.isFriend
24+ import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint
25+ import com.lambda.interaction.construction.verify.TargetState
26+ import com.lambda.interaction.managers.interacting.InteractConfig
27+ import com.lambda.module.Module
28+ import com.lambda.module.tag.ModuleTag
29+ import com.lambda.task.RootTask.run
30+ import com.lambda.task.Task
31+ import com.lambda.task.tasks.BuildTask.Companion.build
32+ import com.lambda.util.BlockUtils.blockState
33+ import com.lambda.util.item.ItemUtils.block
34+ import com.lambda.util.math.flooredBlockPos
35+ import com.lambda.util.player.SlotUtils.hotbarAndStorage
36+ import com.lambda.util.world.entitySearch
37+ import net.minecraft.block.Blocks
38+ import net.minecraft.client.network.OtherClientPlayerEntity
39+ import net.minecraft.entity.player.PlayerEntity
40+ import net.minecraft.item.BlockItem
41+ import net.minecraft.util.math.BlockPos
42+ import kotlin.jvm.optionals.getOrNull
43+
44+ object PlayerTrap : Module(
45+ name = " PlayerTrap" ,
46+ description = " Surrounds players with any given block" ,
47+ tag = ModuleTag .COMBAT
48+ ) {
49+ private val blocks by setting(" Blocks" , setOf (Blocks .OBSIDIAN , Blocks .ENDER_CHEST , Blocks .CRYING_OBSIDIAN ))
50+ private val friends by setting(" Friends" , false )
51+ private val self by setting(" Self" , false )
52+
53+ private var task: Task <* >? = null
54+
55+ init {
56+ setDefaultAutomationConfig {
57+ applyEdits {
58+ buildConfig.apply {
59+ editTyped(
60+ ::pathing,
61+ ::stayInRange,
62+ ::spleefEntities,
63+ ::collectDrops
64+ ) { defaultValue(false ); hide() }
65+ ::checkSideVisibility.edit { defaultValue(false ) }
66+ }
67+ interactConfig.apply {
68+ ::airPlace.edit { defaultValue(InteractConfig .AirPlaceMode .Grim ) }
69+ }
70+ hideGroup(eatConfig)
71+ }
72+ }
73+
74+ onEnable {
75+ task = tickingBlueprint {
76+ val block = player.hotbarAndStorage.firstOrNull {
77+ it.item is BlockItem && blocks.contains(it.item.block)
78+ }?.item?.block ? : return @tickingBlueprint emptyMap()
79+ val targetPlayer = if (self) player
80+ else entitySearch<OtherClientPlayerEntity >(
81+ buildConfig.interactReach,
82+ player.eyePos.flooredBlockPos
83+ ).firstOrNull { friends || ! isFriend(it.gameProfile) } ? : return @tickingBlueprint emptyMap()
84+ getTrapPositions(targetPlayer).associateWith { TargetState .Block (block) }
85+ }.build(finishOnDone = false ).run ()
86+ }
87+ onDisable { task?.cancel(); task = null }
88+ }
89+
90+ fun SafeContext.getTrapPositions (player : PlayerEntity ): Set <BlockPos > {
91+ val min = player.boundingBox.minPos.flooredBlockPos.add(- 1 , - 1 , - 1 )
92+ val max = player.boundingBox.maxPos.flooredBlockPos.add(1 , 1 , 1 )
93+
94+ return buildSet {
95+ (min.x + 1 .. < max.x).forEach { x ->
96+ (min.y + 1 .. < max.y).forEach { y ->
97+ add(BlockPos (x, y, min.z))
98+ add(BlockPos (x, y, max.z))
99+ }
100+ }
101+
102+ (min.z + 1 .. < max.z).forEach { z ->
103+ (min.y + 1 .. < max.y).forEach { y ->
104+ add(BlockPos (min.x, y, z))
105+ add(BlockPos (max.x, y, z))
106+ }
107+ }
108+
109+ (min.x + 1 .. < max.x).forEach { x ->
110+ (min.z + 1 .. < max.z).forEach { z ->
111+ BlockPos (x, min.y, z).let { pos ->
112+ if (pos != player.supportingBlockPos.getOrNull() || blockState(pos).isReplaceable) add(pos)
113+ }
114+ add(BlockPos (x, max.y, z))
115+ }
116+ }
117+ }
118+ }
119+ }
0 commit comments