Skip to content

Commit 41c3f02

Browse files
committed
feat: introduce burrow estimation based on harp sound
1 parent 3d21b9e commit 41c3f02

File tree

3 files changed

+134
-14
lines changed

3 files changed

+134
-14
lines changed

src/main/kotlin/gg/skytils/skytilsmod/features/impl/events/GriffinBurrows.kt

Lines changed: 130 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,27 @@ package gg.skytils.skytilsmod.features.impl.events
1919

2020
import com.google.common.collect.EvictingQueue
2121
import gg.essential.universal.UMatrixStack
22+
import gg.essential.universal.UMinecraft
23+
import gg.essential.universal.wrappers.UPlayer
2224
import gg.skytils.skytilsmod.Skytils
2325
import gg.skytils.skytilsmod.Skytils.Companion.mc
2426
import gg.skytils.skytilsmod.events.impl.MainReceivePacketEvent
2527
import gg.skytils.skytilsmod.events.impl.PacketEvent
2628
import gg.skytils.skytilsmod.utils.*
2729
import net.minecraft.client.renderer.GlStateManager
30+
import net.minecraft.entity.item.EntityArmorStand
2831
import net.minecraft.init.Blocks
32+
import net.minecraft.init.Items
2933
import net.minecraft.item.ItemStack
3034
import net.minecraft.network.play.client.C07PacketPlayerDigging
3135
import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement
36+
import net.minecraft.network.play.server.S04PacketEntityEquipment
37+
import net.minecraft.network.play.server.S29PacketSoundEffect
3238
import net.minecraft.network.play.server.S2APacketParticles
3339
import net.minecraft.util.AxisAlignedBB
3440
import net.minecraft.util.BlockPos
3541
import net.minecraft.util.EnumParticleTypes
42+
import net.minecraft.util.Vec3
3643
import net.minecraft.util.Vec3i
3744
import net.minecraftforge.client.event.ClientChatReceivedEvent
3845
import net.minecraftforge.client.event.RenderWorldLastEvent
@@ -42,6 +49,11 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
4249
import net.minecraftforge.fml.common.gameevent.TickEvent
4350
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent
4451
import java.awt.Color
52+
import java.time.Duration
53+
import java.time.Instant
54+
import kotlin.math.PI
55+
import kotlin.math.cos
56+
import kotlin.math.sin
4557

4658
object GriffinBurrows {
4759
val particleBurrows = hashMapOf<BlockPos, ParticleBurrow>()
@@ -50,13 +62,32 @@ object GriffinBurrows {
5062

5163
var hasSpadeInHotbar = false
5264

65+
object BurrowEstimation {
66+
val arrows = mutableMapOf<Arrow, Instant>()
67+
val guesses = mutableMapOf<BurrowGuess, Instant>()
68+
fun getDistanceFromPitch(pitch: Double) =
69+
2805 * pitch + 1375
70+
71+
val grassData by lazy {
72+
this::class.java.getResource("/assets/skytils/grassdata.txt")!!.readBytes()
73+
}
74+
75+
class Arrow(val directionVector: Vec3, val pos: Vec3)
76+
}
77+
5378

5479
@SubscribeEvent
5580
fun onTick(event: ClientTickEvent) {
5681
if (event.phase != TickEvent.Phase.START) return
5782
hasSpadeInHotbar = mc.thePlayer != null && Utils.inSkyblock && (0..7).any {
5883
mc.thePlayer.inventory.getStackInSlot(it).isSpade
5984
}
85+
BurrowEstimation.guesses.entries.removeIf { (_, instant) ->
86+
Duration.between(instant, Instant.now()).toMinutes() > 30
87+
}
88+
BurrowEstimation.arrows.entries.removeIf { (_, instant) ->
89+
Duration.between(instant, Instant.now()).toMinutes() > 5
90+
}
6091
}
6192

6293
@SubscribeEvent(receiveCanceled = true, priority = EventPriority.HIGHEST)
@@ -106,6 +137,23 @@ object GriffinBurrows {
106137
pb.drawWaypoint(event.partialTicks, matrixStack)
107138
}
108139
}
140+
for (bg in BurrowEstimation.guesses.keys) {
141+
bg.drawWaypoint(event.partialTicks, matrixStack)
142+
}
143+
for (arrow in BurrowEstimation.arrows.keys) {
144+
RenderUtil.drawCircle(
145+
matrixStack,
146+
arrow.pos.x,
147+
arrow.pos.y + 0.2,
148+
arrow.pos.z,
149+
event.partialTicks,
150+
5.0,
151+
100,
152+
255,
153+
128,
154+
0,
155+
)
156+
}
109157
}
110158
}
111159

@@ -118,23 +166,81 @@ object GriffinBurrows {
118166
@SubscribeEvent
119167
fun onReceivePacket(event: MainReceivePacketEvent<*, *>) {
120168
if (!Utils.inSkyblock) return
121-
if (Skytils.config.showGriffinBurrows && hasSpadeInHotbar && event.packet is S2APacketParticles) {
122-
if (SBInfo.mode != SkyblockIsland.Hub.mode) return
123-
event.packet.apply {
124-
val type = ParticleType.getParticleType(this) ?: return
125-
val pos = BlockPos(x, y, z).down()
126-
if (recentlyDugParticleBurrows.contains(pos)) return
127-
val burrow = particleBurrows.getOrPut(pos) {
128-
ParticleBurrow(pos, hasFootstep = false, hasEnchant = false, type = -1)
169+
when (event.packet) {
170+
is S2APacketParticles -> {
171+
if (Skytils.config.showGriffinBurrows && hasSpadeInHotbar) {
172+
if (SBInfo.mode != SkyblockIsland.Hub.mode) return
173+
event.packet.apply {
174+
val type = ParticleType.getParticleType(this) ?: return
175+
val pos = BlockPos(x, y, z).down()
176+
if (recentlyDugParticleBurrows.contains(pos)) return
177+
BurrowEstimation.guesses.keys.associateWith { guess ->
178+
pos.distanceSq(
179+
guess.x.toDouble(),
180+
guess.y.toDouble(),
181+
guess.z.toDouble()
182+
)
183+
}.minByOrNull { it.value }?.let { (guess, distance) ->
184+
printDevMessage("Nearest guess is $distance blocks away", "griffin", "griffinguess")
185+
if (distance <= 625) {
186+
BurrowEstimation.guesses.remove(guess)
187+
}
188+
}
189+
val burrow = particleBurrows.getOrPut(pos) {
190+
ParticleBurrow(pos, hasFootstep = false, hasEnchant = false, type = -1)
191+
}
192+
when (type) {
193+
ParticleType.FOOTSTEP -> burrow.hasFootstep = true
194+
ParticleType.ENCHANT -> burrow.hasEnchant = true
195+
ParticleType.EMPTY -> burrow.type = 0
196+
ParticleType.MOB -> burrow.type = 1
197+
ParticleType.TREASURE -> burrow.type = 2
198+
}
199+
}
129200
}
130-
when (type) {
131-
ParticleType.FOOTSTEP -> burrow.hasFootstep = true
132-
ParticleType.ENCHANT -> burrow.hasEnchant = true
133-
ParticleType.EMPTY -> burrow.type = 0
134-
ParticleType.MOB -> burrow.type = 1
135-
ParticleType.TREASURE -> burrow.type = 2
201+
}
202+
is S04PacketEntityEquipment -> {
203+
val entity = UMinecraft.getMinecraft().theWorld.getEntityByID(event.packet.entityID)
204+
(entity as? EntityArmorStand)?.let { armorStand ->
205+
if (event.packet.itemStack.item != Items.arrow) return
206+
if (armorStand.getDistanceSq(UPlayer.getPlayer()?.position) >= 27) return
207+
printDevMessage("Found armor stand with arrow", "griffin", "griffinguess")
208+
val yaw = Math.toRadians(armorStand.rotationYaw.toDouble())
209+
val lookVec = Vec3(
210+
-sin(yaw),
211+
0.0,
212+
cos(yaw)
213+
)
214+
val offset = Vec3(-sin(yaw + PI/2), 0.0, cos(yaw + PI/2)) * 0.9
215+
val origin = armorStand.positionVector.add(offset)
216+
BurrowEstimation.arrows.put(BurrowEstimation.Arrow(lookVec, origin), Instant.now())
136217
}
137218
}
219+
is S29PacketSoundEffect -> {
220+
if (event.packet.soundName != "note.harp") return
221+
val (arrow, distance) = BurrowEstimation.arrows.keys
222+
.associateWith { arrow ->
223+
arrow.pos.squareDistanceTo(event.packet.x, event.packet.y, event.packet.z)
224+
}.minByOrNull { it.value } ?: return
225+
printDevMessage("Nearest arrow is $distance blocks away ${arrow.pos}", "griffin", "griffinguess")
226+
if (distance > 25) return
227+
val guessPos = arrow.pos.add(
228+
arrow.directionVector * BurrowEstimation.getDistanceFromPitch(event.packet.pitch.toDouble())
229+
)
230+
231+
var y: Int
232+
var x = guessPos.x.toInt()
233+
var z = guessPos.z.toInt()
234+
// offset of 300 blocks for both x and z
235+
// x ranges from 195 to -281
236+
// z ranges from 207 to -233
237+
do {
238+
y = BurrowEstimation.grassData.get((x++ % 507) * 507 + (z++ % 495)).toInt()
239+
} while (y < 2)
240+
val guess = BurrowGuess(guessPos.x.toInt(), y, guessPos.z.toInt())
241+
BurrowEstimation.arrows.remove(arrow)
242+
BurrowEstimation.guesses[guess] = Instant.now()
243+
}
138244
}
139245
}
140246

@@ -181,6 +287,16 @@ object GriffinBurrows {
181287
}
182288
}
183289

290+
data class BurrowGuess(
291+
override val x: Int,
292+
override val y: Int,
293+
override val z: Int
294+
) : Diggable() {
295+
override var type = 0
296+
override val waypointText = "§aBurrow §6(Guess)"
297+
override val color = Color.ORANGE
298+
}
299+
184300
data class ParticleBurrow(
185301
override val x: Int,
186302
override val y: Int,

src/main/kotlin/gg/skytils/skytilsmod/utils/Utils.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,9 @@ operator fun Vec3.minus(other: Vec3): Vec3 = subtract(other)
414414

415415
operator fun Vec3.times(scaleValue: Double): Vec3 = Vec3(xCoord * scaleValue, yCoord * scaleValue, zCoord * scaleValue)
416416

417+
fun Vec3.squareDistanceTo(x: Double, y: Double, z: Double)=
418+
(x - xCoord) * (x - xCoord) + (y - yCoord) * (y - yCoord) + (z - zCoord) * (z - zCoord)
419+
417420
/**
418421
* @author Ilya
419422
* @link https://stackoverflow.com/a/56043547

src/main/resources/assets/skytils/grassdata.txt

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)