1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
package at.hannibal2.skyhanni.features.dungeon
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.CheckRenderEntityEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent
import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled
import at.hannibal2.skyhanni.utils.BlockUtils.getBlockStateAt
import at.hannibal2.skyhanni.utils.ColorUtils.withAlpha
import at.hannibal2.skyhanni.utils.EntityUtils
import at.hannibal2.skyhanni.utils.LocationUtils.distanceSqToPlayer
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzColor.Companion.toLorenzColor
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.RenderUtils.exactPlayerEyeLocation
import at.hannibal2.skyhanni.utils.getLorenzVec
import net.minecraft.block.BlockStainedGlass
import net.minecraft.client.Minecraft
import net.minecraft.client.entity.EntityOtherPlayerMP
import net.minecraft.client.entity.EntityPlayerSP
import net.minecraft.entity.item.EntityArmorStand
import net.minecraft.potion.Potion
import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object DungeonLividFinder {
private val config get() = SkyHanniMod.feature.dungeon.lividFinder
private val blockLocation = LorenzVec(6, 109, 43)
var lividEntity: EntityOtherPlayerMP? = null
private var lividArmorStand: EntityArmorStand? = null
private var gotBlinded = false
private var color: LorenzColor? = null
@SubscribeEvent
fun onTick(event: LorenzTickEvent) {
if (!inDungeon()) return
val isCurrentlyBlind = isCurrentlyBlind()
if (!gotBlinded) {
gotBlinded = isCurrentlyBlind
return
} else if (isCurrentlyBlind) return
if (!config.enabled) return
val dyeColor = blockLocation.getBlockStateAt().getValue(BlockStainedGlass.COLOR)
color = dyeColor.toLorenzColor() ?: error("No color found for dye color `$dyeColor`")
val color = color ?: return
val chatColor = color.getChatColor()
lividArmorStand = EntityUtils.getEntities<EntityArmorStand>()
.firstOrNull { it.name.startsWith("${chatColor}﴾ ${chatColor}§lLivid") }
val lividArmorStand = lividArmorStand ?: return
val aabb = with(lividArmorStand) {
AxisAlignedBB(
posX - 0.5,
posY - 2,
posZ - 0.5,
posX + 0.5,
posY,
posZ + 0.5
)
}
val world = Minecraft.getMinecraft().theWorld
val newLivid = world.getEntitiesWithinAABB(EntityOtherPlayerMP::class.java, aabb)
.takeIf { it.size == 1 }?.firstOrNull() ?: return
if (!newLivid.name.contains("Livid")) return
lividEntity = newLivid
RenderLivingEntityHelper.setEntityColorWithNoHurtTime(
newLivid,
color.toColor().withAlpha(30)
) { shouldHighlight() }
}
private fun shouldHighlight() = getLividAlive() != null && config.enabled
private fun getLividAlive() = lividEntity?.let {
if (!it.isDead && it.health > 0.5) it else null
}
@SubscribeEvent
fun onCheckRender(event: CheckRenderEntityEvent<*>) {
if (!inDungeon()) return
if (!config.hideWrong) return
if (!config.enabled) return
val entity = event.entity
if (entity is EntityPlayerSP) return
val livid = getLividAlive() ?: return
if (entity != livid && entity != lividArmorStand) {
if (entity.name.contains("Livid")) {
event.isCanceled = true
}
}
}
private fun isCurrentlyBlind() = if (Minecraft.getMinecraft().thePlayer.isPotionActive(Potion.blindness)) {
Minecraft.getMinecraft().thePlayer.getActivePotionEffect(Potion.blindness).duration > 10
} else false
@SubscribeEvent
fun onRenderWorld(event: LorenzRenderWorldEvent) {
if (!inDungeon()) return
if (!config.enabled) return
val livid = getLividAlive() ?: return
val location = livid.getLorenzVec().add(-0.5, 0.0, -0.5)
val lorenzColor = color ?: return
event.drawDynamicText(location, lorenzColor.getChatColor() + "Livid", 1.5)
if (location.distanceSqToPlayer() < 50) return
val color = lorenzColor.toColor()
event.draw3DLine(event.exactPlayerEyeLocation(), location.add(0.5, 0.0, 0.5), color, 3, true)
event.drawWaypointFilled(location, color, beacon = false, seeThroughBlocks = true)
}
@SubscribeEvent
fun onWorldChange(event: LorenzWorldChangeEvent) {
lividEntity = null
gotBlinded = false
}
private fun inDungeon(): Boolean {
if (!DungeonAPI.inDungeon()) return false
if (!DungeonAPI.inBossRoom) return false
if (!DungeonAPI.isOneOf("F5", "M5")) return false
return true
}
}
|