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
|
package at.hannibal2.skyhanni.features.garden.pests
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.ClickType
import at.hannibal2.skyhanni.events.ItemClickEvent
import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent
import at.hannibal2.skyhanni.events.ReceiveParticleEvent
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.GardenPlotAPI
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.DelayedRun
import at.hannibal2.skyhanni.utils.LocationUtils
import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils.isAnyOf
import at.hannibal2.skyhanni.utils.LorenzVec
import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLine_nea
import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText
import at.hannibal2.skyhanni.utils.RenderUtils.drawWaypointFilled
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import net.minecraft.util.EnumParticleTypes
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.seconds
// TODO remove this workaround once PestParticleWaypoint does work again
@SkyHanniModule
object PestParticleLine {
private val config get() = SkyHanniMod.feature.garden.pests.pestWaypoint
class ParticleLocation(val location: LorenzVec, val spawnTime: SimpleTimeMark)
private var lastPestTrackerUse = SimpleTimeMark.farPast()
private val locations = mutableListOf<MutableList<ParticleLocation>>()
@SubscribeEvent
fun onItemClick(event: ItemClickEvent) {
if (!isEnabled()) return
if (PestAPI.hasVacuumInHand()) {
if (event.clickType == ClickType.LEFT_CLICK) {
lastPestTrackerUse = SimpleTimeMark.now()
}
}
}
@SubscribeEvent
fun onReceiveParticle(event: ReceiveParticleEvent) {
if (!isEnabled()) return
// TODO time in config
if (lastPestTrackerUse.passedSince() > 5.seconds) return
if (event.type.isAnyOf(EnumParticleTypes.ENCHANTMENT_TABLE, EnumParticleTypes.VILLAGER_ANGRY)) {
if (config.hideParticles) event.cancel()
}
if (event.type != EnumParticleTypes.VILLAGER_ANGRY) return
val location = event.location
// run in main thread to avoid concurrent errors
DelayedRun.runNextTick {
getCurrentList(location).add(ParticleLocation(location, SimpleTimeMark.now()))
}
}
private fun getCurrentList(location: LorenzVec): MutableList<ParticleLocation> {
locations.lastOrNull()?.let {
val distance = it.last().location.distance(location)
if (distance < 4) {
return it
}
}
val newList = mutableListOf<ParticleLocation>()
locations.add(newList)
if (locations.size == 5) {
locations.removeAt(0)
}
return newList
}
@SubscribeEvent(priority = EventPriority.LOW)
fun onRenderWorld(event: LorenzRenderWorldEvent) {
if (!isEnabled()) return
// TODO time in config
if (lastPestTrackerUse.passedSince() > 10.seconds) {
locations.clear()
return
}
for (list in locations) {
draw(event, list)
}
showMiddle(event)
}
private fun showMiddle(event: LorenzRenderWorldEvent) {
if (!config.showMiddle) return
if (locations.size <= 0) return
val plot = GardenPlotAPI.getCurrentPlot() ?: return
val middle = plot.middle.copy(y = LocationUtils.playerLocation().y)
if (middle.distanceToPlayer() > 15) return
event.drawWaypointFilled(middle, LorenzColor.GRAY.toColor())
event.drawDynamicText(middle, "Middle", 1.0)
}
private fun draw(event: LorenzRenderWorldEvent, list: List<ParticleLocation>) {
val color = LorenzColor.YELLOW.toColor()
for ((prev, next) in list.asSequence().zipWithNext()) {
// TODO time in config
if (next.spawnTime.passedSince() > 5.seconds) continue
val location = next.location
event.draw3DLine_nea(
prev.location,
location,
color,
3,
false
)
val isVeryLast = list == locations.lastOrNull() && next == list.lastOrNull()
if (isVeryLast) {
val lastLocation = location.add(-0.5, -0.5, -0.5)
event.drawWaypointFilled(lastLocation, color, beacon = true)
event.drawDynamicText(lastLocation, "§ePest Guess", 1.3)
}
}
}
fun isEnabled() = GardenAPI.inGarden() && config.enabled
}
|