Skip to content

Commit 4ed39b8

Browse files
committed
Better targeting so i don't die cuz of zombi pigmen
1 parent a4b960f commit 4ed39b8

File tree

3 files changed

+319
-161
lines changed

3 files changed

+319
-161
lines changed

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

Lines changed: 193 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ import com.lambda.util.NamedEnum
2929
import com.lambda.util.extension.fullHealth
3030
import com.lambda.util.math.distSq
3131
import com.lambda.util.world.fastEntitySearch
32+
import com.lambda.world.LambdaAngerManagement
3233
import net.minecraft.client.network.ClientPlayerEntity
3334
import net.minecraft.client.network.OtherClientPlayerEntity
3435
import net.minecraft.entity.LivingEntity
3536
import net.minecraft.entity.decoration.ArmorStandEntity
37+
import net.minecraft.entity.mob.AmbientEntity
38+
import net.minecraft.entity.mob.Angerable
3639
import net.minecraft.entity.mob.HostileEntity
40+
import net.minecraft.entity.passive.AnimalEntity
3741
import net.minecraft.entity.passive.PassiveEntity
3842
import java.util.*
3943

@@ -50,166 +54,194 @@ import java.util.*
5054
* @param maxRange The maximum range within which entities can be targeted.
5155
*/
5256
abstract 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
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ interface TargetingConfig {
2323
val players: Boolean
2424
val friends: Boolean
2525
val hostiles: Boolean
26+
val hostilesOnlyAngry: Boolean
27+
val passives: Boolean
2628
val animals: Boolean
2729

2830
val invisible: Boolean

0 commit comments

Comments
 (0)