Skip to content

Commit f450676

Browse files
authored
Merge pull request #10 from Avanatiker/feature/combat
Merge working entity utils into master
2 parents 5fa46e1 + 3d3ce9c commit f450676

File tree

7 files changed

+340
-14
lines changed

7 files changed

+340
-14
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.lambda.module.modules
2+
3+
import com.lambda.event.events.TickEvent
4+
import com.lambda.event.listener.SafeListener.Companion.listener
5+
import com.lambda.module.Module
6+
import com.lambda.util.world.EntityUtils.getClosestEntity
7+
import net.minecraft.entity.Entity
8+
9+
object EntityTest : Module(
10+
name = "EntityTest",
11+
description = "Test entity",
12+
defaultTags = setOf()
13+
) {
14+
init {
15+
listener<TickEvent.Pre> {
16+
repeat(10000) {
17+
getClosestEntity<Entity>(player.eyePos, 7.0)
18+
}
19+
}
20+
}
21+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.lambda.module.modules.combat
2+
3+
import com.lambda.config.InteractionSettings
4+
import com.lambda.config.RotationSettings
5+
import com.lambda.event.events.RotationEvent
6+
import com.lambda.event.events.TickEvent
7+
import com.lambda.event.listener.SafeListener.Companion.concurrentListener
8+
import com.lambda.event.listener.SafeListener.Companion.listener
9+
import com.lambda.module.Module
10+
import com.lambda.module.tag.ModuleTag
11+
import com.lambda.util.Communication.info
12+
import com.lambda.util.combat.Explosion.velocity
13+
import com.lambda.util.world.EntityUtils.getClosestEntity
14+
import com.lambda.util.world.EntityUtils.getFastEntities
15+
import net.minecraft.entity.Entity
16+
import net.minecraft.entity.LivingEntity
17+
import net.minecraft.util.Hand
18+
import net.minecraft.world.explosion.Explosion
19+
20+
object CrystalAura : Module(
21+
name = "CrystalAura",
22+
description = "Automatically attacks entities with crystals",
23+
defaultTags = setOf(ModuleTag.COMBAT),
24+
) {
25+
private val page by setting("Page", Page.General)
26+
27+
/* Rotation */
28+
private val rotation = RotationSettings(this) { page == Page.Targeting }
29+
30+
/* Placing */
31+
private val swap by setting("Swap", Hand.MAIN_HAND, "Automatically swap to crystals") { page == Page.Placing }
32+
private val multiPlace by setting("Multi Place", true, "Place multiple crystals") { page == Page.Placing }
33+
private val placeDelay by setting("Place Delay", 0, 0..20, 1, "Delay between crystal placements", unit = "ticks", visibility = { page == Page.Placing })
34+
private val placeRange by setting("Place Range", 5.0, 0.1..7.0, 0.1, "Range to place crystals from the player eyes", visibility = { page == Page.Placing })
35+
private val placeRangeWalls by setting("Place Range Walls", 3.5, 0.1..7.0, 0.1, "Range to place crystals through walls", visibility = { page == Page.Placing })
36+
private val placeMinHealth by setting("Place Min Health", 10.0, 0.0..20.0, 0.5, "Minimum health to place a crystal", visibility = { page == Page.Placing })
37+
private val placeMaxSelfDamage by setting("Place Max Self Damage", 8.0, 0.0..20.0, 0.5, "Maximum self damage to place a crystal", visibility = { page == Page.Placing })
38+
private val placeMinDamage by setting("Place Min Damage", 6.0, 0.0..20.0, 0.5, "Minimum damage to place a crystal", visibility = { page == Page.Placing })
39+
40+
/* Exploding */
41+
private val explode by setting("Explode", true, "Explode crystals") { page == Page.Exploding }
42+
private val explodeDelay by setting("Explode Delay", 0, 0..20, 1, "Delay between crystal explosions", unit = "ticks", visibility = { page == Page.Exploding })
43+
private val explodeRange by setting("Explode Range", 5.0, 0.1..7.0, 0.1, "Range to explode crystals", visibility = { page == Page.Exploding })
44+
private val explodeRangeWalls by setting("Explode Range Walls", 3.5, 0.1..7.0, 0.1, "Range to explode crystals through walls", visibility = { page == Page.Exploding })
45+
private val preventDeath by setting("Prevent Death", true, "Prevent death from crystal explosions", visibility = { page == Page.Exploding })
46+
private val explodeMinDamage by setting("Explode Min Damage", 6.0, 0.0..20.0, 0.5, "Minimum damage to explode a crystal", visibility = { page == Page.Exploding })
47+
private val noWeakness by setting("No Weakness", true, "Switch to a weapon when you have a weakness effect", visibility = { page == Page.Exploding })
48+
49+
/* Rendering */
50+
51+
52+
/* Interaction */
53+
private val interac = InteractionSettings(this) // Canadian interbank meme
54+
55+
private enum class Page {
56+
General, Targeting, Placing, Exploding, Rendering
57+
}
58+
59+
init {
60+
concurrentListener<TickEvent.Pre> {}
61+
62+
/*listener<RotationEvent.Pre> { event ->
63+
event.lookAtEntity(rotation, interac, getClosestEntity<LivingEntity>(player.eyePos, placeRange) ?: return@listener)
64+
}*/
65+
66+
listener<TickEvent.Pre> {
67+
getClosestEntity<LivingEntity>(player.eyePos, 64.0)
68+
}
69+
}
70+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.lambda.util.collections
2+
3+
/**
4+
* Filters elements of the iterable by their runtime type and a predicate, and adds the matching elements to the specified mutable collection.
5+
*
6+
* This function allows filtering elements of an iterable based on their runtime type and a provided predicate function.
7+
* The elements that match both the type constraint and the predicate are added to the destination mutable collection.
8+
* Because we do not want additional overhead, this function acts as pointer receiver to a collection.
9+
* The predicate function determines whether an element should be included based on its type and any additional criteria.
10+
*
11+
* @param R The target type to filter elements to.
12+
* @param C The type of the destination mutable collection.
13+
* @param destination The mutable collection to which the filtered elements will be added.
14+
* @param predicate The predicate function that determines whether an element should be included based on its type and other criteria.
15+
*/
16+
inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceTo(
17+
destination: C,
18+
predicate: (R) -> Boolean
19+
) {
20+
for (element in this) if (element is R && predicate(element)) destination.add(element)
21+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.lambda.util.combat
2+
3+
import net.minecraft.enchantment.EnchantmentHelper
4+
import net.minecraft.entity.LivingEntity
5+
import net.minecraft.entity.damage.DamageSource
6+
import net.minecraft.entity.effect.StatusEffects
7+
import net.minecraft.registry.tag.DamageTypeTags
8+
import kotlin.math.max
9+
import kotlin.math.min
10+
11+
object Damage {
12+
/**
13+
* @param entity The entity to calculate the damage for
14+
* @param damage The damage to apply
15+
* @return The damage dealt by the explosion
16+
*/
17+
fun mask(entity: LivingEntity, damage: Double, source: DamageSource): Double {
18+
val resistanceAmplifier = entity.getStatusEffect(StatusEffects.RESISTANCE)?.amplifier ?: -1
19+
20+
if (source.isIn(DamageTypeTags.BYPASSES_EFFECTS)) return damage
21+
22+
if (entity.hasStatusEffect(StatusEffects.RESISTANCE) && !source.isIn(DamageTypeTags.BYPASSES_RESISTANCE))
23+
return (damage - max(damage * (25 - (resistanceAmplifier + 1) * 5) / 25.0, 0.0)).coerceAtLeast(0.0)
24+
25+
if (source.isIn(DamageTypeTags.BYPASSES_ENCHANTMENTS)) return damage
26+
27+
val protectionAmount = EnchantmentHelper.getProtectionAmount(entity.armorItems, source)
28+
29+
if (protectionAmount > 0) return damage * (1.0 - min(protectionAmount, 20) / 25.0)
30+
31+
return damage
32+
}
33+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.lambda.util.combat
2+
3+
import com.lambda.context.SafeContext
4+
import com.lambda.util.math.VecUtils.minus
5+
import com.lambda.util.math.VecUtils.times
6+
import com.lambda.util.world.EntityUtils.getFastEntities
7+
import net.minecraft.enchantment.ProtectionEnchantment
8+
import net.minecraft.entity.LivingEntity
9+
import net.minecraft.util.math.BlockPos
10+
import net.minecraft.util.math.Vec3d
11+
import net.minecraft.world.explosion.Explosion
12+
import kotlin.math.max
13+
14+
object Explosion {
15+
/**
16+
* Calculates the damage dealt by an explosion to a living entity.
17+
* @param source The source of the explosion.
18+
* @param entity The entity to calculate the damage for.
19+
* @return The damage dealt by the explosion.
20+
*/
21+
fun SafeContext.damage(source: Explosion, entity: LivingEntity) =
22+
damage(source.position, entity, source.power.toDouble())
23+
24+
/**
25+
* Calculates the damage dealt by an explosion to a living entity.
26+
* @param position The position of the explosion.
27+
* @param entity The entity to calculate the damage for.
28+
* @param power The strength of the explosion above 0.
29+
* @return The damage dealt by the explosion.
30+
*/
31+
fun SafeContext.damage(position: Vec3d, entity: LivingEntity, power: Double): Double {
32+
val distance = entity.pos.distanceTo(position)
33+
34+
val impact = (1.0 - distance / (power * 2.0)) *
35+
Explosion.getExposure(position, entity) *
36+
0.4
37+
38+
val damage = world.difficulty.id * 3 *
39+
power *
40+
(impact * impact + impact) + 1
41+
42+
return Damage.mask(entity, damage, Explosion.createDamageSource(world, null))
43+
}
44+
45+
/**
46+
* Calculates the velocity of entities in the explosion.
47+
* @param explosion The explosion to calculate the velocity for.
48+
* @return The velocity of the entities.
49+
*/
50+
fun SafeContext.velocity(explosion: Explosion) =
51+
getFastEntities<LivingEntity>(explosion.position, explosion.power * 2.0)
52+
.associateWith { entity -> velocity(entity, explosion) }
53+
54+
/**
55+
* Calculates the velocity of a living entity affected by an explosion.
56+
* @param entity The entity to calculate the velocity for.
57+
* @param explosion The explosion to calculate the velocity for.
58+
* @return The velocity of the entity.
59+
*/
60+
fun SafeContext.velocity(entity: LivingEntity, explosion: Explosion) =
61+
velocity(entity, explosion.position, explosion.power.toDouble())
62+
63+
/**
64+
* Calculates the velocity of a living entity affected by an explosion.
65+
* @param entity The entity to calculate the velocity for.
66+
* @param position The position of the explosion.
67+
* @param power The strength of the explosion.
68+
* @return The velocity of the entity.
69+
*/
70+
fun SafeContext.velocity(entity: LivingEntity, position: Vec3d, power: Double): Vec3d {
71+
val distance = entity.pos.distanceTo(position)
72+
73+
val size = power * 2.0
74+
val vel = ProtectionEnchantment.transformExplosionKnockback(
75+
entity,
76+
(1.0 - distance / size) * Explosion.getExposure(position, entity)
77+
)
78+
79+
val diff = entity.eyePos - position
80+
return diff.normalize() * vel
81+
}
82+
83+
fun SafeContext.destruction(source: Explosion): List<Vec3d> {
84+
val affected = mutableListOf<Vec3d>()
85+
86+
repeat(16) { x ->
87+
repeat(16) { y ->
88+
repeat(16) { z ->
89+
if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) {
90+
val vec = Vec3d(x / 30.0 - 1.0, y / 30.0 - 1.0, z / 30.0 - 1.0)
91+
val len = vec.length()
92+
93+
val dx = vec.x / len
94+
val dy = vec.y / len
95+
val dz = vec.z / len
96+
97+
var explosionX = source.position.x
98+
var explosionY = source.position.y
99+
var explosionZ = source.position.z
100+
101+
var intensity = source.power * (0.7 + world.random.nextDouble() * 0.6)
102+
103+
while (intensity > 0) {
104+
val blockPos = BlockPos.ofFloored(explosionX, explosionY, explosionZ)
105+
val block = world.getBlockState(blockPos)
106+
val fluid = world.getFluidState(blockPos)
107+
if (!world.isInBuildLimit(blockPos)) {
108+
break
109+
}
110+
111+
val resistance = max(block.block.blastResistance, fluid.blastResistance)
112+
intensity -= (resistance + 0.3) * 0.3
113+
114+
if (intensity > 0 && source.behavior.canDestroyBlock(source, world, blockPos, block, intensity.toFloat())) {
115+
affected.add(Vec3d(explosionX, explosionY, explosionZ))
116+
}
117+
118+
explosionX += dx * 0.3
119+
explosionY += dy * 0.3
120+
explosionZ += dz * 0.3
121+
122+
intensity -= 0.225
123+
}
124+
}
125+
}
126+
}
127+
}
128+
129+
return affected
130+
}
131+
}

0 commit comments

Comments
 (0)