Skip to content

Commit

Permalink
Improved Performance + Bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
Thunderblade73 committed Dec 8, 2023
1 parent 0700862 commit 631ed8b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/main/java/at/hannibal2/skyhanni/data/mob/Mob.kt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class Mob(
}

private fun removeExtraEntitiesFromChecking() =
extraEntities?.count { MobData.retries.contains(MobData.RetryEntityInstancing(it, 0)) }?.also {
extraEntities?.count { MobData.retries.contains(MobData.RetryEntityInstancing(it)) }?.also {
MobData.externRemoveOfRetryAmount += it
}

Expand Down
74 changes: 56 additions & 18 deletions src/main/java/at/hannibal2/skyhanni/data/mob/MobData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import at.hannibal2.skyhanni.utils.getLorenzVec
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.item.EntityArmorStand
import net.minecraft.entity.passive.EntityBat
import net.minecraft.entity.passive.EntityVillager
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.network.play.server.S0CPacketSpawnPlayer
import net.minecraft.network.play.server.S0FPacketSpawnMob
Expand All @@ -27,7 +28,8 @@ import java.util.TreeSet
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.atomic.AtomicBoolean

private const val MAX_RETRIES = 100
private const val MAX_RETRIES = 20 * 5


class MobData {
private val forceReset get() = SkyHanniMod.feature.dev.mobDebug.forceReset
Expand All @@ -53,6 +55,7 @@ class MobData {

const val ENTITY_RENDER_RANGE_IN_BLOCKS = 80.0 // Entity DeRender after ~5 Chunks
const val DETECTION_RANGE = 22.0
private const val DISPLAY_NPC_DETECTION_RANGE = 24.0 // 24.0

var externRemoveOfRetryAmount = 0
}
Expand Down Expand Up @@ -111,14 +114,20 @@ class MobData {
}
}

private fun EntitySpawn(entity: EntityLivingBase): Boolean {
private fun EntityLivingBase.getRoughType() = when {
this is EntityPlayer && this.isRealPlayer() -> Mob.Type.Player
this.isDisplayNPC() -> Mob.Type.DisplayNPC
this.isSkyBlockMob() -> Mob.Type.Basic
else -> null
}

private fun EntitySpawn(entity: EntityLivingBase, roughType: Mob.Type): Boolean {
MobDevTracker.data.spawn++
when {
entity is EntityPlayer && entity.isRealPlayer() -> MobEvent.Spawn.Player(MobFactories.player(entity))
.postAndCatch()
when (roughType) {
Mob.Type.Player -> MobEvent.Spawn.Player(MobFactories.player(entity)).postAndCatch()

entity.isDisplayNPC() -> return MobFilter.createDisplayNPC(entity)
entity.isSkyBlockMob() -> {
Mob.Type.DisplayNPC -> return MobFilter.createDisplayNPC(entity)
Mob.Type.Basic -> {
if (islandException()) return true
val it = MobFilter.createSkyblockEntity(entity)
if (it.result == Result.NotYetFound) return false
Expand All @@ -127,34 +136,55 @@ class MobData {
when (it.mob.mobType) {
Mob.Type.Summon -> MobEvent.Spawn.Summon(it.mob).postAndCatch()

Mob.Type.Basic, Mob.Type.Dungeon, Mob.Type.Boss, Mob.Type.Slayer -> MobEvent.Spawn.SkyblockMob(it.mob)
.postAndCatch()
Mob.Type.Basic, Mob.Type.Dungeon, Mob.Type.Boss, Mob.Type.Slayer -> MobEvent.Spawn.SkyblockMob(it.mob).postAndCatch()

Mob.Type.Special -> MobEvent.Spawn.Special(it.mob).postAndCatch()
Mob.Type.Projectile -> MobEvent.Spawn.Projectile(it.mob).postAndCatch()
else -> {}
}
}

else -> return true
}
return true
}

private val batFromPacket = LinkedBlockingQueue<Int>()
private val villagerFromPacket = LinkedBlockingQueue<Int>()

private fun handleMobsFromPacket() {
while (batFromPacket.isNotEmpty()) {
val entity = EntityUtils.getEntityByID(batFromPacket.take()) as? EntityLivingBase ?: continue
if (entityToMob[entity] != null) continue
retries.remove(RetryEntityInstancing(entity, 0))
retries.remove(RetryEntityInstancing(entity))
MobEvent.Spawn.Projectile(MobFactories.projectile(entity, "Spirit Scepter Bat")).postAndCatch() // Needs different handling because 6 is default health of Bat
}
while (villagerFromPacket.isNotEmpty()) {
val entity = EntityUtils.getEntityByID(villagerFromPacket.take()) as? EntityLivingBase ?: continue
val mob = entityToMob[entity]
if (mob != null && mob.mobType == Mob.Type.DisplayNPC) {
MobEvent.DeSpawn.DisplayNPC(mob)
retry(entity)
continue
}
val retryInstance = RetryEntityInstancing(entity)
retries.find { it == retryInstance }?.let {
if (it.roughType == Mob.Type.DisplayNPC) {
retries.remove(retryInstance)
retry(entity)
}
}
}
}

@SubscribeEvent
fun onEntityHealthUpdateEvent(event: EntityHealthUpdateEvent) {
if (event.entity is EntityBat && event.health == 6) {
batFromPacket.add(event.entity.entityId)
}
if (event.entity is EntityVillager && event.health != 20) {
villagerFromPacket.add(event.entity.entityId)
}
}


Expand All @@ -179,12 +209,16 @@ class MobData {
packetEntityIds.remove(entity.entityId)
}

private fun retry(entity: EntityLivingBase) =
retries.add(RetryEntityInstancing(entity, 0)).also { MobDevTracker.data.startedRetries++ }
private fun retry(entity: EntityLivingBase) = entity.getRoughType()?.let { type ->
retries.add(RetryEntityInstancing(entity, 0, type)).also { MobDevTracker.data.startedRetries++ }
}

private fun removeRetry(entity: EntityLivingBase) = retries.removeIf { it.entity == entity }
private fun removeRetry(entity: EntityLivingBase) = retries.remove(RetryEntityInstancing(entity))

class RetryEntityInstancing(var entity: EntityLivingBase, var times: Int, val roughType: Mob.Type) : Comparable<RetryEntityInstancing> {

constructor(entity: EntityLivingBase) : this(entity, 0, Mob.Type.Special) // Only use this for compare

class RetryEntityInstancing(var entity: EntityLivingBase, var times: Int) : Comparable<RetryEntityInstancing> {
override fun hashCode() = entity.hashCode()
override fun compareTo(other: RetryEntityInstancing) = this.hashCode() - other.hashCode()
override fun equals(other: Any?) = (other as? EntityLivingBase) == entity
Expand All @@ -200,16 +234,20 @@ class MobData {
continue
}
val entity = retry.entity
if (entity.getLorenzVec()
.distanceChebyshevIgnoreY(LocationUtils.playerLocation()) > DETECTION_RANGE
val type = retry.roughType
if (entity.getLorenzVec().distanceChebyshevIgnoreY(LocationUtils.playerLocation()) > when (type) {
Mob.Type.DisplayNPC -> DISPLAY_NPC_DETECTION_RANGE
Mob.Type.Player -> Double.POSITIVE_INFINITY
else -> DETECTION_RANGE
}
) {
MobDevTracker.data.outOfRangeRetries++
continue
}
MobDevTracker.data.retries++
if (retry.times > MAX_RETRIES) {
LorenzDebug.log(
"I (`${retry.entity.name}`${retry.entity.entityId} missed. Position: ${retry.entity.getLorenzVec()} Distance: ${
"I (`${retry.entity.name}`${retry.entity.entityId} missed (Found? ${entityToMob[retry.entity] != null}). Position: ${retry.entity.getLorenzVec()} Distance: ${
entity.getLorenzVec().distanceChebyshevIgnoreY(LocationUtils.playerLocation())
} , ${
entity.getLorenzVec().subtract(LocationUtils.playerLocation())
Expand All @@ -221,7 +259,7 @@ class MobData {
retry.times = Int.MIN_VALUE
// continue
}
if (!EntitySpawn(entity)) {
if (!EntitySpawn(entity, type)) {
retry.times++
continue
}
Expand Down
20 changes: 9 additions & 11 deletions src/main/java/at/hannibal2/skyhanni/data/mob/MobFilter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import at.hannibal2.skyhanni.utils.MobUtils.isDefaultValue
import at.hannibal2.skyhanni.utils.MobUtils.makeMobResult
import at.hannibal2.skyhanni.utils.MobUtils.takeNonDefault
import net.minecraft.client.entity.EntityOtherPlayerMP
import net.minecraft.client.entity.EntityPlayerSP
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.boss.EntityDragon
Expand Down Expand Up @@ -68,10 +67,9 @@ object MobFilter {
fun Entity.isSkyBlockMob(): Boolean = when {
this !is EntityLivingBase -> false
this is EntityArmorStand -> false
this is EntityOtherPlayerMP && this.isRealPlayer() -> false
this is EntityPlayer && this.isRealPlayer() -> false
this.isDisplayNPC() -> false
this is EntityWither && (this.entityId < 0 || this.invulTime == 800) -> false
this is EntityPlayerSP -> false
this is EntityWither && this.entityId < 0 -> false
else -> true
}

Expand All @@ -82,9 +80,8 @@ object MobFilter {
extraDisplayNPCByName.contains(this.name) -> true
else -> false
}) || (this is EntityVillager && this.maxHealth == 20.0f) // Villager NPCs in the Village
|| (this is EntityWitch && this.entityId == 253) // Alchemist NPC
|| (this is EntityCow && this.entityId == 175) // Shania NPC
|| (this is EntityCow && this.entityId == 275) // Shania NPC in Rift
|| (this is EntityWitch && this.entityId <= 500) // Alchemist NPC
|| (this is EntityCow && this.entityId <= 500) // Shania NPC (in Rift and Outside)
|| (this is EntityPlayer && extraDisplayNPCByName.contains(this.name))

private val extraDisplayNPCByName = setOf(
Expand Down Expand Up @@ -151,6 +148,7 @@ object MobFilter {
if (baseEntity is EntityGiantZombie && baseEntity.name == "Dinnerbone") return MobData.MobResult(Found, MobFactories.projectile(baseEntity, "Giant Sword")) // Will false trigger if there is another Dinnerbone Giant
if (baseEntity is EntityCaveSpider) MobUtils.getArmorStand(baseEntity, -1)?.takeIf { it.cleanName().matches(summonOwnerRegex) }
?.let { MobData.entityToMob[MobUtils.getNextEntity(baseEntity, -4)]?.internalAddEntity(baseEntity)?.also { return MobData.MobResult(Illegal, null) } }
if (baseEntity is EntityWither && baseEntity.invulTime == 800) return MobData.MobResult(Found, MobFactories.special(baseEntity, "Mini Wither"))
return null
}

Expand Down Expand Up @@ -178,7 +176,7 @@ object MobFilter {
IslandType.HUB -> {
if (baseEntity is EntityZombie) { // Rat
val from = 3
val to = 9
val to = 11
generateSequence(from) { it + 1 }.take(to - from + 1).map { i ->
MobUtils.getArmorStand(
baseEntity, i
Expand Down Expand Up @@ -272,7 +270,7 @@ object MobFilter {
fun createDisplayNPC(entity: EntityLivingBase): Boolean =
MobUtils.getArmorStandByRangeAll(entity, 2.0).firstOrNull { armorStand ->
!illegalDisplayNPCArmorStandNames.any { armorStand.name.startsWith(it) } && !armorStand.isDefaultValue()
}?.let { armorStand ->
MobEvent.Spawn.DisplayNPC(MobFactories.displayNPC(entity, armorStand)).postAndCatch().also { true }
} ?: false
}?.also { armorStand ->
MobEvent.Spawn.DisplayNPC(MobFactories.displayNPC(entity, armorStand)).postAndCatch()
}?.let { true } ?: false
}

0 comments on commit 631ed8b

Please sign in to comment.