Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions common/src/main/kotlin/com/lambda/module/modules/EntityTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.lambda.module.modules

import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listener
import com.lambda.module.Module
import com.lambda.util.world.EntityUtils.getClosestEntity
import net.minecraft.entity.Entity

object EntityTest : Module(
name = "EntityTest",
description = "Test entity",
defaultTags = setOf()
) {
init {
listener<TickEvent.Pre> {
repeat(10000) {
getClosestEntity<Entity>(player.eyePos, 7.0)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.lambda.module.modules.combat

import com.lambda.config.InteractionSettings
import com.lambda.config.RotationSettings
import com.lambda.event.events.RotationEvent
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.concurrentListener
import com.lambda.event.listener.SafeListener.Companion.listener
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
import com.lambda.util.Communication.info
import com.lambda.util.combat.Explosion.velocity
import com.lambda.util.world.EntityUtils.getClosestEntity
import com.lambda.util.world.EntityUtils.getFastEntities
import net.minecraft.entity.Entity
import net.minecraft.entity.LivingEntity
import net.minecraft.util.Hand
import net.minecraft.world.explosion.Explosion

object CrystalAura : Module(
name = "CrystalAura",
description = "Automatically attacks entities with crystals",
defaultTags = setOf(ModuleTag.COMBAT),
) {
private val page by setting("Page", Page.General)

/* Rotation */
private val rotation = RotationSettings(this) { page == Page.Targeting }

/* Placing */
private val swap by setting("Swap", Hand.MAIN_HAND, "Automatically swap to crystals") { page == Page.Placing }
private val multiPlace by setting("Multi Place", true, "Place multiple crystals") { page == Page.Placing }
private val placeDelay by setting("Place Delay", 0, 0..20, 1, "Delay between crystal placements", unit = "ticks", visibility = { page == Page.Placing })
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 })
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 })
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 })
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 })
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 })

/* Exploding */
private val explode by setting("Explode", true, "Explode crystals") { page == Page.Exploding }
private val explodeDelay by setting("Explode Delay", 0, 0..20, 1, "Delay between crystal explosions", unit = "ticks", visibility = { page == Page.Exploding })
private val explodeRange by setting("Explode Range", 5.0, 0.1..7.0, 0.1, "Range to explode crystals", visibility = { page == Page.Exploding })
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 })
private val preventDeath by setting("Prevent Death", true, "Prevent death from crystal explosions", visibility = { page == Page.Exploding })
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 })
private val noWeakness by setting("No Weakness", true, "Switch to a weapon when you have a weakness effect", visibility = { page == Page.Exploding })

/* Rendering */


/* Interaction */
private val interac = InteractionSettings(this) // Canadian interbank meme

private enum class Page {
General, Targeting, Placing, Exploding, Rendering
}

init {
concurrentListener<TickEvent.Pre> {}

/*listener<RotationEvent.Pre> { event ->
event.lookAtEntity(rotation, interac, getClosestEntity<LivingEntity>(player.eyePos, placeRange) ?: return@listener)
}*/

listener<TickEvent.Pre> {
getClosestEntity<LivingEntity>(player.eyePos, 64.0)
}
}
}
21 changes: 21 additions & 0 deletions common/src/main/kotlin/com/lambda/util/collections/Extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.lambda.util.collections

/**
* Filters elements of the iterable by their runtime type and a predicate, and adds the matching elements to the specified mutable collection.
*
* This function allows filtering elements of an iterable based on their runtime type and a provided predicate function.
* The elements that match both the type constraint and the predicate are added to the destination mutable collection.
* Because we do not want additional overhead, this function acts as pointer receiver to a collection.
* The predicate function determines whether an element should be included based on its type and any additional criteria.
*
* @param R The target type to filter elements to.
* @param C The type of the destination mutable collection.
* @param destination The mutable collection to which the filtered elements will be added.
* @param predicate The predicate function that determines whether an element should be included based on its type and other criteria.
*/
inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceTo(
destination: C,
predicate: (R) -> Boolean
) {
for (element in this) if (element is R && predicate(element)) destination.add(element)
}
33 changes: 33 additions & 0 deletions common/src/main/kotlin/com/lambda/util/combat/Damage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.lambda.util.combat

import net.minecraft.enchantment.EnchantmentHelper
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.damage.DamageSource
import net.minecraft.entity.effect.StatusEffects
import net.minecraft.registry.tag.DamageTypeTags
import kotlin.math.max
import kotlin.math.min

object Damage {
/**
* @param entity The entity to calculate the damage for
* @param damage The damage to apply
* @return The damage dealt by the explosion
*/
fun mask(entity: LivingEntity, damage: Double, source: DamageSource): Double {
val resistanceAmplifier = entity.getStatusEffect(StatusEffects.RESISTANCE)?.amplifier ?: -1

if (source.isIn(DamageTypeTags.BYPASSES_EFFECTS)) return damage

if (entity.hasStatusEffect(StatusEffects.RESISTANCE) && !source.isIn(DamageTypeTags.BYPASSES_RESISTANCE))
return (damage - max(damage * (25 - (resistanceAmplifier + 1) * 5) / 25.0, 0.0)).coerceAtLeast(0.0)

if (source.isIn(DamageTypeTags.BYPASSES_ENCHANTMENTS)) return damage

val protectionAmount = EnchantmentHelper.getProtectionAmount(entity.armorItems, source)

if (protectionAmount > 0) return damage * (1.0 - min(protectionAmount, 20) / 25.0)

return damage
}
}
131 changes: 131 additions & 0 deletions common/src/main/kotlin/com/lambda/util/combat/Explosion.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.lambda.util.combat

import com.lambda.context.SafeContext
import com.lambda.util.math.VecUtils.minus
import com.lambda.util.math.VecUtils.times
import com.lambda.util.world.EntityUtils.getFastEntities
import net.minecraft.enchantment.ProtectionEnchantment
import net.minecraft.entity.LivingEntity
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraft.world.explosion.Explosion
import kotlin.math.max

object Explosion {
/**
* Calculates the damage dealt by an explosion to a living entity.
* @param source The source of the explosion.
* @param entity The entity to calculate the damage for.
* @return The damage dealt by the explosion.
*/
fun SafeContext.damage(source: Explosion, entity: LivingEntity) =
damage(source.position, entity, source.power.toDouble())

/**
* Calculates the damage dealt by an explosion to a living entity.
* @param position The position of the explosion.
* @param entity The entity to calculate the damage for.
* @param power The strength of the explosion above 0.
* @return The damage dealt by the explosion.
*/
fun SafeContext.damage(position: Vec3d, entity: LivingEntity, power: Double): Double {
val distance = entity.pos.distanceTo(position)

val impact = (1.0 - distance / (power * 2.0)) *
Explosion.getExposure(position, entity) *
0.4

val damage = world.difficulty.id * 3 *
power *
(impact * impact + impact) + 1

return Damage.mask(entity, damage, Explosion.createDamageSource(world, null))
}

/**
* Calculates the velocity of entities in the explosion.
* @param explosion The explosion to calculate the velocity for.
* @return The velocity of the entities.
*/
fun SafeContext.velocity(explosion: Explosion) =
getFastEntities<LivingEntity>(explosion.position, explosion.power * 2.0)
.associateWith { entity -> velocity(entity, explosion) }

/**
* Calculates the velocity of a living entity affected by an explosion.
* @param entity The entity to calculate the velocity for.
* @param explosion The explosion to calculate the velocity for.
* @return The velocity of the entity.
*/
fun SafeContext.velocity(entity: LivingEntity, explosion: Explosion) =
velocity(entity, explosion.position, explosion.power.toDouble())

/**
* Calculates the velocity of a living entity affected by an explosion.
* @param entity The entity to calculate the velocity for.
* @param position The position of the explosion.
* @param power The strength of the explosion.
* @return The velocity of the entity.
*/
fun SafeContext.velocity(entity: LivingEntity, position: Vec3d, power: Double): Vec3d {
val distance = entity.pos.distanceTo(position)

val size = power * 2.0
val vel = ProtectionEnchantment.transformExplosionKnockback(
entity,
(1.0 - distance / size) * Explosion.getExposure(position, entity)
)

val diff = entity.eyePos - position
return diff.normalize() * vel
}

fun SafeContext.destruction(source: Explosion): List<Vec3d> {
val affected = mutableListOf<Vec3d>()

repeat(16) { x ->
repeat(16) { y ->
repeat(16) { z ->
if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) {
val vec = Vec3d(x / 30.0 - 1.0, y / 30.0 - 1.0, z / 30.0 - 1.0)
val len = vec.length()

val dx = vec.x / len
val dy = vec.y / len
val dz = vec.z / len

var explosionX = source.position.x
var explosionY = source.position.y
var explosionZ = source.position.z

var intensity = source.power * (0.7 + world.random.nextDouble() * 0.6)

while (intensity > 0) {
val blockPos = BlockPos.ofFloored(explosionX, explosionY, explosionZ)
val block = world.getBlockState(blockPos)
val fluid = world.getFluidState(blockPos)
if (!world.isInBuildLimit(blockPos)) {
break
}

val resistance = max(block.block.blastResistance, fluid.blastResistance)
intensity -= (resistance + 0.3) * 0.3

if (intensity > 0 && source.behavior.canDestroyBlock(source, world, blockPos, block, intensity.toFloat())) {
affected.add(Vec3d(explosionX, explosionY, explosionZ))
}

explosionX += dx * 0.3
explosionY += dy * 0.3
explosionZ += dz * 0.3

intensity -= 0.225
}
}
}
}
}

return affected
}
}
Loading