Skip to content

Commit

Permalink
feat: fine sort by self-damage (CCBlueX#5535)
Browse files Browse the repository at this point in the history
  • Loading branch information
ccetl authored and DataM0del committed Feb 7, 2025
1 parent e177cc3 commit cec893c
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura

import it.unimi.dsi.fastutil.floats.FloatFloatImmutablePair
import it.unimi.dsi.fastutil.floats.FloatFloatPair
import net.ccbluex.liquidbounce.config.types.Configurable
import net.ccbluex.liquidbounce.features.misc.FriendManager
import net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura.ModuleCrystalAura.currentTarget
Expand Down Expand Up @@ -56,9 +58,11 @@ object CrystalAuraDamageOptions : Configurable("Damage") {
val cacheMap = LruCache<DamageConstellation, DamageProvider>(64)

/**
* Approximates how favorable an explosion of a crystal at [pos] in a given [world] would be
*/ // TODO by equal positions take self min damage
internal fun approximateExplosionDamage(pos: Vec3d, requestingSubmodule: RequestingSubmodule): Float? {
* Approximates how favorable an explosion of a crystal at [pos] in a given [world] would be.
*
* The first float is the self-damage, the second is the enemy damage.
*/
internal fun approximateExplosionDamage(pos: Vec3d, requestingSubmodule: RequestingSubmodule): FloatFloatPair? {
val target = currentTarget ?: return null
val damageToTarget = target.getDamage(pos, requestingSubmodule, CheckedEntity.TARGET)
val notEnoughDamage = damageToTarget.isSmallerThan(minEnemyDamage)
Expand Down Expand Up @@ -92,7 +96,7 @@ object CrystalAuraDamageOptions : Configurable("Damage") {
return null
}

return damageToTarget.getFixed()
return FloatFloatImmutablePair(selfDamage.getFixed(), damageToTarget.getFixed())
}

private fun LivingEntity.getDamage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/
package net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura.destroy

import it.unimi.dsi.fastutil.objects.ObjectFloatImmutablePair
import net.ccbluex.liquidbounce.features.module.MinecraftShortcuts
import net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura.CrystalAuraDamageOptions
import net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura.destroy.SubmoduleCrystalDestroyer.getMaxRange
Expand Down Expand Up @@ -50,8 +49,8 @@ object CrystalAuraDestroyTargetFactory : MinecraftShortcuts {

val damage = dealsEnoughDamage(it) ?: return@mapNotNull null

ObjectFloatImmutablePair(it as EndCrystalEntity, damage)
}.maxByOrNull { it.secondFloat() }?.first()
ComparisonListEntry(it as EndCrystalEntity, damage.firstFloat(), damage.secondFloat())
}.maxOrNull()?.crystalEntity
}

/**
Expand Down Expand Up @@ -88,4 +87,25 @@ object CrystalAuraDestroyTargetFactory : MinecraftShortcuts {
wallsRange = wallsRange.toDouble()
)

private class ComparisonListEntry(
val crystalEntity: EndCrystalEntity,
val selfDamage: Float,
val enemyDamage: Float
) : Comparable<ComparisonListEntry> {

override fun compareTo(other: ComparisonListEntry): Int {
// coarse sorting
val enemyDamageComparison = this.enemyDamage.compareTo(other.enemyDamage)

// not equal
if (enemyDamageComparison != 0) {
return enemyDamageComparison
}

// equal -> fine sorting
return other.selfDamage.compareTo(this.selfDamage)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,12 @@ object CrystalAuraPlaceTargetFactory : MinecraftShortcuts {
currentBasePlaceTarget: PlacementPositionCandidate?
): PlacementPositionCandidate? {
// choose the target with the maximum damage
var bestTarget = finalPositions.maxByOrNull { it.explosionDamage!! } ?: return null
var bestTarget = finalPositions.maxOrNull() ?: return null

// find a target position that will not require base place if possible
if (bestTarget.requiresBasePlace) {
finalPositions.filterNot { it.requiresBasePlace }.maxByOrNull { it.explosionDamage!! }?.let {
if (it.explosionDamage!! - bestTarget.explosionDamage!! >= SubmoduleBasePlace.minAdvantage) {
finalPositions.filterNot { it.requiresBasePlace }.maxOrNull()?.let {
if (it.enemyDamage!! - bestTarget.enemyDamage!! >= SubmoduleBasePlace.minAdvantage) {
bestTarget = it
}
}
Expand All @@ -141,7 +141,7 @@ object CrystalAuraPlaceTargetFactory : MinecraftShortcuts {
currentBasePlaceTarget?.let {
it.calculate()
if (it.isNotInvalid() &&
it.explosionDamage!! - bestTarget.explosionDamage!! >= SubmoduleBasePlace.minAdvantage
it.enemyDamage!! - bestTarget.enemyDamage!! >= SubmoduleBasePlace.minAdvantage
) {
bestTarget = it
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,30 @@
package net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura.place

import net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura.CrystalAuraDamageOptions
import net.ccbluex.liquidbounce.utils.client.player
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d

class PlacementPositionCandidate(
val pos: BlockPos, // the block the crystal should be placed on
val notBlockedByCrystal: Boolean,
val requiresBasePlace: Boolean
) {
) : Comparable<PlacementPositionCandidate> {

/**
* The damage a crystal at the specific position would deal.
* The damage a crystal at the specific position would deal to the enemy.
*/
var explosionDamage: Float? = null
var enemyDamage: Float? = null

/**
* The damage a crystal at the specific position would deal to the enemy.
*/
private var selfDamage: Float? = null

/**
* The distance to us.
*/
private val distanceSq by lazy { pos.getSquaredDistance(player.pos) }

init {
calculate()
Expand All @@ -42,17 +53,46 @@ class PlacementPositionCandidate(
*/
fun calculate() {
val damageSourceLoc = Vec3d.of(pos).add(0.5, 1.0, 0.5)
explosionDamage = CrystalAuraDamageOptions.approximateExplosionDamage(
val explosionDamage = CrystalAuraDamageOptions.approximateExplosionDamage(
damageSourceLoc,
if (requiresBasePlace) {
CrystalAuraDamageOptions.RequestingSubmodule.BASE_PLACE
} else {
CrystalAuraDamageOptions.RequestingSubmodule.PLACE
}
)

explosionDamage?.let {
selfDamage = it.firstFloat()
enemyDamage = it.secondFloat()
} ?: run {
selfDamage = null
enemyDamage = null
}
}

fun isNotInvalid() = explosionDamage != null
fun isNotInvalid() = enemyDamage != null

override fun compareTo(other: PlacementPositionCandidate): Int {
// coarse sorting
val enemyDamageComparison = this.enemyDamage!!.compareTo(other.enemyDamage!!)

// not equal
if (enemyDamageComparison != 0) {
return enemyDamageComparison
}

// equal -> fine sorting 1
val selfDamageComparison = other.selfDamage!!.compareTo(this.selfDamage!!)

// not equal
if (selfDamageComparison != 0) {
return selfDamageComparison
}

// equal -> fine sorting 2
return other.distanceSq.compareTo(this.distanceSq)
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down

0 comments on commit cec893c

Please sign in to comment.