@@ -29,11 +29,15 @@ import com.lambda.util.NamedEnum
2929import com.lambda.util.extension.fullHealth
3030import com.lambda.util.math.distSq
3131import com.lambda.util.world.fastEntitySearch
32+ import com.lambda.world.LambdaAngerManagement
3233import net.minecraft.client.network.ClientPlayerEntity
3334import net.minecraft.client.network.OtherClientPlayerEntity
3435import net.minecraft.entity.LivingEntity
3536import net.minecraft.entity.decoration.ArmorStandEntity
37+ import net.minecraft.entity.mob.AmbientEntity
38+ import net.minecraft.entity.mob.Angerable
3639import net.minecraft.entity.mob.HostileEntity
40+ import net.minecraft.entity.passive.AnimalEntity
3741import net.minecraft.entity.passive.PassiveEntity
3842import java.util.*
3943
@@ -50,166 +54,194 @@ import java.util.*
5054 * @param maxRange The maximum range within which entities can be targeted.
5155 */
5256abstract class Targeting (
53- private val c : Configurable ,
54- baseGroup : NamedEnum ,
55- private val defaultRange : Double ,
56- private val maxRange : Double ,
57+ private val c : Configurable ,
58+ baseGroup : NamedEnum ,
59+ private val defaultRange : Double ,
60+ private val maxRange : Double ,
5761) : SettingGroup(c), TargetingConfig {
58- /* *
59- * The range within which entities can be targeted. This value is configurable and constrained
60- * between 1.0 and [maxRange].
61- */
62- override val targetingRange by c.setting(" Targeting Range" , defaultRange, 1.0 .. maxRange, 0.05 ).group(baseGroup)
63-
64- /* *
65- * Whether players are included in the targeting scope.
66- */
67- override val players by c.setting(" Players" , true ).group(baseGroup)
68-
69- /* *
70- * Whether friends are included in the targeting scope.
71- * Requires [players] to be true.
72- */
73- override val friends by c.setting(" Friends" , false ) { players }.group(baseGroup)
74-
75- /* *
76- * Whether mobs are included in the targeting scope.
77- */
78- private val mobs by c.setting(" Mobs" , true ).group(baseGroup)
79-
80- /* *
81- * Whether hostile mobs are included in the targeting scope
82- */
83- private val hostilesSetting by c.setting(" Hostiles" , true ) { mobs }.group(baseGroup)
84-
85- /* *
86- * Whether passive animals are included in the targeting scope
87- */
88- private val animalsSetting by c.setting(" Animals" , true ) { mobs }.group(baseGroup)
89-
90- /* *
91- * Indicates whether hostile entities are included in the targeting scope.
92- */
93- override val hostiles get() = mobs && hostilesSetting
94-
95- /* *
96- * Indicates whether passive animals are included in the targeting scope.
97- */
98- override val animals get() = mobs && animalsSetting
99-
100- /* *
101- * Whether invisible entities are included in the targeting scope.
102- */
103- override val invisible by c.setting(" Invisible" , true ).group(baseGroup)
104-
105- /* *
106- * Whether dead entities are included in the targeting scope.
107- */
108- override val dead by c.setting(" Dead" , false ).group(baseGroup)
109-
110- /* *
111- * Validates whether a given entity is targetable by the player based on current settings.
112- *
113- * @param player The [ClientPlayerEntity] performing the targeting.
114- * @param entity The [LivingEntity] being evaluated.
115- * @return `true` if the entity is valid for targeting, `false` otherwise.
116- */
117- open fun validate (player : ClientPlayerEntity , entity : LivingEntity ) = when {
118- ! players && entity is OtherClientPlayerEntity -> false
119- players && entity is OtherClientPlayerEntity && entity.isFriend -> false
120- ! animals && entity is PassiveEntity -> false
121- ! hostiles && entity is HostileEntity -> false
122- entity is ArmorStandEntity -> false
123-
124- ! invisible && entity.isInvisibleTo(player) -> false
125- ! dead && entity.isDead -> false
126-
127- else -> true
128- }
129-
130- /* *
131- * Subclass for targeting entities specifically for combat purposes.
132- *
133- * @property fov The field of view limit within which entities are considered for targeting. Configurable.
134- * @property priority The priority used to determine which entity is targeted when multiple candidates are available.
135- */
136- class Combat (
137- c : Configurable ,
138- baseGroup : NamedEnum ,
139- defaultRange : Double = 5.0 ,
140- maxRange : Double = 16.0 ,
141- ) : Targeting(c, baseGroup, defaultRange, maxRange) {
142-
143- /* *
144- * The field of view limit for targeting entities. Configurable between 5 and 180 degrees.
145- */
146- val fov by c.setting(" FOV Limit" , 180 , 5 .. 180 , 1 ) { priority == Priority .Fov }.group(baseGroup)
147-
148- /* *
149- * The priority used to determine which entity is targeted. Configurable with default set to [Priority.Distance].
150- */
151- val priority by c.setting(" Priority" , Priority .Distance ).group(baseGroup)
152-
153- /* *
154- * Validates whether a given entity is targetable for combat based on the field of view limit and other settings.
155- *
156- * @param player The [ClientPlayerEntity] performing the targeting.
157- * @param entity The [LivingEntity] being evaluated.
158- * @return `true` if the entity is valid for targeting, `false` otherwise.
159- */
160- override fun validate (player : ClientPlayerEntity , entity : LivingEntity ): Boolean {
161- if (fov < 180 && player.rotation dist player.eyePos.rotationTo(entity.pos) > fov) return false
162- if (entity.uuid in illegalTargets) return false
163- return super .validate(player, entity)
164- }
165-
166- /* *
167- * Gets the best target for combat based on the current settings and priority.
168- *
169- * @return The best [LivingEntity] target, or `null` if no valid target is found.
170- */
171- fun target (): LivingEntity ? = runSafe {
172- return @runSafe fastEntitySearch<LivingEntity >(targetingRange) {
173- validate(player, it)
174- }.minByOrNull {
175- priority.factor(this , it)
176- }
177- }
178-
179- private val illegalTargets = setOf (
180- UUID (5706954458220675710 , - 6736729783554821869 ),
181- UUID (- 2945922493004570036 , - 7599209072395336449 )
182- )
183- }
184-
185- /* *
186- * Subclass for targeting entities for ESP (Extrasensory Perception) purposes.
187- */
188- class ESP (
189- c : Configurable ,
190- baseGroup : NamedEnum ,
191- ) : Targeting(c, baseGroup, 128.0 , 1024.0 )
192-
193- /* *
194- * Enum representing the different priority factors used for determining the best target.
195- *
196- * @property factor A lambda function that calculates the priority factor for a given [LivingEntity].
197- */
198- @Suppress(" Unused" )
199- enum class Priority (val factor : SafeContext .(LivingEntity ) -> Double ) {
200- /* *
201- * Prioritizes entities based on their distance from the player.
202- */
203- Distance ({ player.pos distSq it.pos }),
204-
205- /* *
206- * Prioritizes entities based on their health.
207- */
208- Health ({ it.fullHealth }),
209-
210- /* *
211- * Prioritizes entities based on their angle relative to the player's field of view.
212- */
213- Fov ({ player.rotation dist player.eyePos.rotationTo(it.pos) })
214- }
62+ /* *
63+ * The range within which entities can be targeted. This value is configurable and constrained
64+ * between 1.0 and [maxRange].
65+ */
66+ override val targetingRange by c.setting(" Targeting Range" , defaultRange, 1.0 .. maxRange, 0.05 ).group(baseGroup)
67+
68+ /* *
69+ * Whether players are included in the targeting scope.
70+ */
71+ override val players by c.setting(" Players" , true ).group(baseGroup)
72+
73+ /* *
74+ * Whether friends are included in the targeting scope.
75+ * Requires [players] to be true.
76+ */
77+ override val friends by c.setting(" Friends" , false ) { players }.group(baseGroup)
78+
79+ /* *
80+ * Whether mobs are included in the targeting scope.
81+ */
82+ private val mobs by c.setting(" Mobs" , true ).group(baseGroup)
83+
84+ /* *
85+ * Whether hostile mobs are included in the targeting scope
86+ */
87+ private val hostilesSetting by c.setting(" Hostiles" , true ) { mobs }.group(baseGroup)
88+
89+ /* *
90+ * Whether hostile entities should be only attacked when they are angry
91+ */
92+ private val hostileOnlyAngrySetting by c.setting(
93+ " Hostiles Only Angry" , true ,
94+ " Only attacks angerable entities if they are angered. This does not affect for example zombies but does affect endermen."
95+ ) { hostilesSetting }.group(baseGroup)
96+
97+ /* *
98+ * Whether passive entities are included in the targeting scope
99+ */
100+ private val passivesSetting by c.setting(" Passives" , false ) { mobs }.group(baseGroup)
101+
102+ /* *
103+ * Whether animals are included in the targeting scope
104+ */
105+ private val animalsSetting by c.setting(" Animals" , true ) { mobs }.group(baseGroup)
106+
107+ /* *
108+ * Indicates whether hostile entities are included in the targeting scope.
109+ */
110+ override val hostiles get() = mobs && hostilesSetting
111+
112+ override val hostilesOnlyAngry: Boolean
113+ get() = mobs && hostilesSetting && hostileOnlyAngrySetting
114+
115+ /* *
116+ * Indicates whether passive entities are included in the targeting scope.
117+ */
118+ override val passives get() = mobs && passivesSetting
119+
120+ /* *
121+ * Indicates whether animals are included in the targeting scope.
122+ */
123+ override val animals get() = mobs && animalsSetting
124+
125+ /* *
126+ * Whether invisible entities are included in the targeting scope.
127+ */
128+ override val invisible by c.setting(" Invisible" , true ).group(baseGroup)
129+
130+ /* *
131+ * Whether dead entities are included in the targeting scope.
132+ */
133+ override val dead by c.setting(" Dead" , false ).group(baseGroup)
134+
135+ /* *
136+ * Validates whether a given entity is targetable by the player based on current settings.
137+ *
138+ * @param player The [ClientPlayerEntity] performing the targeting.
139+ * @param entity The [LivingEntity] being evaluated.
140+ * @return `true` if the entity is valid for targeting, `false` otherwise.
141+ */
142+ open fun validate (player : ClientPlayerEntity , entity : LivingEntity ) = when {
143+ players && entity is OtherClientPlayerEntity -> true
144+ ! players && entity is OtherClientPlayerEntity && entity.isFriend -> true
145+ animals && (entity is AnimalEntity || entity is AmbientEntity ) -> true
146+ passives && entity is PassiveEntity -> true
147+ hostiles && entity is HostileEntity -> {
148+ if (hostilesOnlyAngry && entity is Angerable ) {
149+ LambdaAngerManagement .isEntityAngry(entity.uuid)
150+ } else {
151+ true
152+ }
153+ }
154+ entity is ArmorStandEntity -> false
155+
156+ invisible && entity.isInvisibleTo(player) -> true
157+ dead && entity.isDead -> true
158+
159+ else -> false
160+ }
161+
162+ /* *
163+ * Subclass for targeting entities specifically for combat purposes.
164+ *
165+ * @property fov The field of view limit within which entities are considered for targeting. Configurable.
166+ * @property priority The priority used to determine which entity is targeted when multiple candidates are available.
167+ */
168+ class Combat (
169+ c : Configurable ,
170+ baseGroup : NamedEnum ,
171+ defaultRange : Double = 5.0 ,
172+ maxRange : Double = 16.0 ,
173+ ) : Targeting(c, baseGroup, defaultRange, maxRange) {
174+
175+ /* *
176+ * The field of view limit for targeting entities. Configurable between 5 and 180 degrees.
177+ */
178+ val fov by c.setting(" FOV Limit" , 180 , 5 .. 180 , 1 ) { priority == Priority .Fov }.group(baseGroup)
179+
180+ /* *
181+ * The priority used to determine which entity is targeted. Configurable with default set to [Priority.Distance].
182+ */
183+ val priority by c.setting(" Priority" , Priority .Distance ).group(baseGroup)
184+
185+ /* *
186+ * Validates whether a given entity is targetable for combat based on the field of view limit and other settings.
187+ *
188+ * @param player The [ClientPlayerEntity] performing the targeting.
189+ * @param entity The [LivingEntity] being evaluated.
190+ * @return `true` if the entity is valid for targeting, `false` otherwise.
191+ */
192+ override fun validate (player : ClientPlayerEntity , entity : LivingEntity ): Boolean {
193+ if (fov < 180 && player.rotation dist player.eyePos.rotationTo(entity.pos) > fov) return false
194+ if (entity.uuid in illegalTargets) return false
195+ return super .validate(player, entity)
196+ }
197+
198+ /* *
199+ * Gets the best target for combat based on the current settings and priority.
200+ *
201+ * @return The best [LivingEntity] target, or `null` if no valid target is found.
202+ */
203+ fun target (): LivingEntity ? = runSafe {
204+ return @runSafe fastEntitySearch<LivingEntity >(targetingRange) {
205+ validate(player, it)
206+ }.minByOrNull {
207+ priority.factor(this , it)
208+ }
209+ }
210+
211+ private val illegalTargets = setOf (
212+ UUID (5706954458220675710 , - 6736729783554821869 ),
213+ UUID (- 2945922493004570036 , - 7599209072395336449 )
214+ )
215+ }
216+
217+ /* *
218+ * Subclass for targeting entities for ESP (Extrasensory Perception) purposes.
219+ */
220+ class ESP (
221+ c : Configurable ,
222+ baseGroup : NamedEnum ,
223+ ) : Targeting(c, baseGroup, 128.0 , 1024.0 )
224+
225+ /* *
226+ * Enum representing the different priority factors used for determining the best target.
227+ *
228+ * @property factor A lambda function that calculates the priority factor for a given [LivingEntity].
229+ */
230+ @Suppress(" Unused" )
231+ enum class Priority (val factor : SafeContext .(LivingEntity ) -> Double ) {
232+ /* *
233+ * Prioritizes entities based on their distance from the player.
234+ */
235+ Distance ({ player.pos distSq it.pos }),
236+
237+ /* *
238+ * Prioritizes entities based on their health.
239+ */
240+ Health ({ it.fullHealth }),
241+
242+ /* *
243+ * Prioritizes entities based on their angle relative to the player's field of view.
244+ */
245+ Fov ({ player.rotation dist player.eyePos.rotationTo(it.pos) })
246+ }
215247}
0 commit comments