-
-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvement: Berberis Helper Rework #3147
base: beta
Are you sure you want to change the base?
Changes from 1 commit
40636dd
09933a7
739b8fd
c680061
fcecd08
12b8a4a
486350a
3bf04aa
9558018
d4390aa
67bc299
e31bcf5
6e5d77d
92c7f03
0ed8811
3f04b13
af18940
a35e02c
a90fe07
f320b52
fc19acb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
import at.hannibal2.skyhanni.utils.RenderUtils.drawFilledBoundingBoxNea | ||
import at.hannibal2.skyhanni.utils.RenderUtils.expandBlock | ||
import at.hannibal2.skyhanni.utils.SimpleTimeMark | ||
import at.hannibal2.skyhanni.utils.SpecialColor.toSpecialColor | ||
import at.hannibal2.skyhanni.utils.toLorenzVec | ||
import net.minecraft.client.Minecraft | ||
import net.minecraft.init.Blocks | ||
|
@@ -31,19 +32,16 @@ | |
|
||
@SkyHanniModule | ||
object RiftWiltedBerberisHelper { | ||
// not a great programmer, but it's better than nothing :p -maj | ||
|
||
private val config get() = RiftAPI.config.area.dreadfarm.wiltedBerberis | ||
private var isOnFarmland = false | ||
private var hasFarmingToolInHand = false | ||
|
||
// list of berberis in the current plot, in the order they appeared in | ||
private var berberisList = listOf<LorenzVec>() | ||
private var lastSpawn = SimpleTimeMark.now() | ||
private var lastSyncedAt = SimpleTimeMark.now() | ||
private var lastUpdated = SimpleTimeMark.now() | ||
|
||
// array of the bounds of each berberis plot | ||
// the bounds of each berberis plot | ||
private val plots = arrayOf( | ||
Plot(LorenzVec(-54, 71, -128), LorenzVec(-41, 70, -117)), | ||
Plot(LorenzVec(-77, 72, -143), LorenzVec(-59, 71, -125)), | ||
|
@@ -53,17 +51,12 @@ | |
Plot(LorenzVec(-42, 72, -155), LorenzVec(-22, 70, -126)), | ||
) | ||
|
||
// the closest plot to the player | ||
private var closestPlot = 0 | ||
|
||
// the closest plot to the player last tick | ||
private var oldClosest = 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change those two variable sto be of type |
||
|
||
data class Plot(var c1: LorenzVec, var c2: LorenzVec) | ||
|
||
private var fallback = false | ||
|
||
// original system stuff: | ||
data class Plot(var a: LorenzVec, var b: LorenzVec) | ||
|
||
private var list = listOf<WiltedBerberis>() | ||
|
||
data class WiltedBerberis(var currentParticles: LorenzVec) { | ||
|
@@ -73,82 +66,22 @@ | |
var lastTime = SimpleTimeMark.now() | ||
} | ||
|
||
private fun nearestBerberis(location: LorenzVec): WiltedBerberis? = | ||
list.filter { it.currentParticles.distanceSq(location) < 8 } | ||
.minByOrNull { it.currentParticles.distanceSq(location) } | ||
|
||
private fun LorenzVec.fixLocation(wiltedBerberis: WiltedBerberis): LorenzVec { | ||
val x = x - 0.5 | ||
val y = wiltedBerberis.y | ||
val z = z - 0.5 | ||
return LorenzVec(x, y, z) | ||
} | ||
// end original system stuff | ||
|
||
@SubscribeEvent | ||
fun onTick(event: LorenzTickEvent) { | ||
RevengeLordOfMaj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!isEnabled()) return | ||
if (!event.isMod(5)) return | ||
|
||
// calculates the player's distance to the center of each plot, then sets closestPlot to the smallest | ||
val plotDistances = arrayListOf(0.0, 0.0, 0.0, 0.0, 0.0, 0.0) | ||
for (i in 0..5) plotDistances[i] = LocationUtils.playerLocation().distance(plots[i].c1.middle(plots[i].c2)) | ||
for (i in 0..5) if (plotDistances[i] < plotDistances[closestPlot]) closestPlot = i | ||
|
||
// if the player enters a new plot, clear the list of berberis locations | ||
if (closestPlot != oldClosest) berberisList = berberisList.editCopy { clear() } | ||
oldClosest = closestPlot | ||
|
||
// when a berberis grows in the current plot, add its location to the end of the list | ||
for (block in BlockPos.getAllInBox(plots[closestPlot].c1.toBlockPos(), plots[closestPlot].c2.toBlockPos())) { | ||
if (block.toLorenzVec().getBlockAt() == Blocks.deadbush && !berberisList.contains(block.toLorenzVec())) { | ||
berberisList = berberisList.editCopy { add(block.toLorenzVec()) } | ||
lastSpawn = SimpleTimeMark.now() | ||
lastUpdated = SimpleTimeMark.now() | ||
} | ||
} | ||
getClosestPlot() | ||
updateBerberisList() | ||
sync() | ||
|
||
// remove first berberis from list if broken and no berberis have grown in the last 1/4 seccond | ||
// (to stop you from breaking it before they all spawn in) | ||
while (berberisList.isNotEmpty() && berberisList[0].getBlockAt() != Blocks.deadbush && lastSpawn.passedSince() > 250.milliseconds) { | ||
berberisList = berberisList.editCopy { removeFirst() } | ||
lastUpdated = SimpleTimeMark.now() | ||
} | ||
|
||
// check if the new system is right about which bush to break. If the particle is still moving, assume it's right for now | ||
for (berberis in list) { | ||
with(berberis) { | ||
// if there is a particle in the same place as where the new helper thinks the next bush is, | ||
if (berberisList.isNotEmpty() && (currentParticles.distance(berberisList[0])) < 1.3 && | ||
currentParticles.distanceToPlayer() <= 20 && y != 0.0 | ||
) { | ||
lastSyncedAt = SimpleTimeMark.now() | ||
} | ||
// or if there is a moving particle | ||
if (moving) { | ||
lastSyncedAt = SimpleTimeMark.now() | ||
} | ||
} | ||
} | ||
|
||
// if we've been desynced (new system wrong) for more than 2 secconds and the list hasn't updated in that time, | ||
// switch to fallback mode. switch off of fallback once the plot is cleared | ||
if (lastSyncedAt.passedSince() > 1000.milliseconds && lastUpdated.passedSince() > 1000.milliseconds) fallback = true | ||
if (berberisList.isEmpty()) fallback = false | ||
|
||
// get if player holding farming wand | ||
hasFarmingToolInHand = InventoryUtils.getItemInHand()?.getInternalName() == RiftAPI.farmingTool | ||
|
||
// get if player is on farmland | ||
if (Minecraft.getMinecraft().thePlayer.onGround) { | ||
val block = LorenzVec.getBlockBelowPlayer().getBlockAt() | ||
val currentY = LocationUtils.playerLocation().y | ||
isOnFarmland = block == Blocks.farmland && (currentY % 1 == 0.0) | ||
} | ||
|
||
// original system stuff: | ||
list = list.editCopy { removeIf { it.lastTime.passedSince() > 500.milliseconds } } | ||
|
||
} | ||
|
||
@SubscribeEvent | ||
|
@@ -166,12 +99,11 @@ | |
} | ||
return | ||
} | ||
// the firework sparks in the center just get cancelled, but the below code runs on them | ||
// the firework sparks in the center may get cancelled, but the below code runs on them | ||
if (config.hideParticles) { | ||
event.cancel() | ||
} | ||
|
||
// original system stuff: | ||
if (berberis == null) { | ||
list = list.editCopy { add(WiltedBerberis(location)) } | ||
return | ||
|
@@ -195,7 +127,6 @@ | |
moving = isMoving | ||
currentParticles = location | ||
lastTime = SimpleTimeMark.now() | ||
// end original system stuff | ||
} | ||
} | ||
|
||
|
@@ -216,58 +147,132 @@ | |
if (!hasFarmingToolInHand) return | ||
if (config.onlyOnFarmland && !isOnFarmland) return | ||
|
||
// original system: | ||
if (fallback) { | ||
for (berberis in list) { | ||
with(berberis) { | ||
if (currentParticles.distanceToPlayer() > 20) continue | ||
if (y == 0.0) continue | ||
|
||
val location = currentParticles.fixLocation(berberis) | ||
if (!moving) { | ||
event.drawFilledBoundingBoxNea(axisAlignedBB(location), Color.YELLOW, 0.7f) | ||
event.drawDynamicText(location.up(), "§eWilted Berberis", 1.5, ignoreBlocks = false) | ||
} else { | ||
event.drawFilledBoundingBoxNea(axisAlignedBB(location), Color.WHITE, 0.5f) | ||
previous?.fixLocation(berberis)?.let { | ||
event.drawFilledBoundingBoxNea(axisAlignedBB(it), Color.LIGHT_GRAY, 0.2f) | ||
event.draw3DLine(it.add(0.5, 0.0, 0.5), location.add(0.5, 0.0, 0.5), Color.WHITE, 3, false) | ||
} | ||
} | ||
if (fallback) fallbackRender(event) | ||
else primaryRender(event) | ||
} | ||
|
||
@HandleEvent | ||
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { | ||
event.move(60, "rift.area.dreadfarm.wiltedBerberis.hideparticles", "rift.area.dreadfarm.wiltedBerberis.hideParticles") | ||
jani270 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
private fun getClosestPlot() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. instead of this approach with array list, two for loops and manual comparing each entry against the prevous losetest plot, you can use lamda functions on a map like .minBy() to get the clostest plot. i think of something like |
||
// calculates the player's distance to the center of each plot, then sets closestPlot to the smallest | ||
val plotDistances = arrayListOf(0.0, 0.0, 0.0, 0.0, 0.0, 0.0) | ||
for (i in 0..5) { | ||
val plotCenter = plots[i].a.middle(plots[i].b) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please only calculate the middle location once, then reuse the same value |
||
plotDistances[i] = LocationUtils.playerLocation().distance(plotCenter) | ||
} | ||
for (i in 0..5) if (plotDistances[i] < plotDistances[closestPlot]) closestPlot = i | ||
} | ||
|
||
private fun updateBerberisList() { | ||
// if the player enters a new plot, clear the list of berberis locations | ||
if (closestPlot != oldClosest) berberisList = berberisList.editCopy { clear() } | ||
oldClosest = closestPlot | ||
|
||
// when a berberis grows in the current plot, add its location to the end of the list | ||
val plotCornerA = plots[closestPlot].a.toBlockPos() | ||
val plotCornerB = plots[closestPlot].b.toBlockPos() | ||
for (block in BlockPos.getAllInBox(plotCornerA, plotCornerB)) { | ||
if (block.toLorenzVec().getBlockAt() == Blocks.deadbush && !berberisList.contains(block.toLorenzVec())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. merge all usages of |
||
berberisList = berberisList.editCopy { add(block.toLorenzVec()) } | ||
lastSpawn = SimpleTimeMark.now() | ||
lastUpdated = SimpleTimeMark.now() | ||
} | ||
} | ||
|
||
// remove first berberis from list if broken and no berberis have grown in the last 1/4 seccond | ||
// (to stop you from breaking it before they all spawn in) | ||
while (berberisList.isNotEmpty() && berberisList[0].getBlockAt() != Blocks.deadbush && lastSpawn.passedSince() > 250.milliseconds) { | ||
berberisList = berberisList.editCopy { removeFirst() } | ||
lastUpdated = SimpleTimeMark.now() | ||
} | ||
|
||
// update the berberis list for the original system | ||
list = list.editCopy { removeIf { it.lastTime.passedSince() > 500.milliseconds } } | ||
} | ||
|
||
private fun sync() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. give this function a better name |
||
// check if the new system is right about which bush to break. If the particle is still moving, assume it's right for now | ||
for (berberis in list) { | ||
with(berberis) { | ||
// if there is a particle in the same place as where the new helper thinks the next bush is, | ||
if (berberisList.isNotEmpty() && (currentParticles.distance(berberisList[0])) < 1.3 && | ||
currentParticles.distanceToPlayer() <= 20 && y != 0.0 | ||
) { | ||
lastSyncedAt = SimpleTimeMark.now() | ||
} | ||
// or if there is a moving particle | ||
if (moving) { | ||
lastSyncedAt = SimpleTimeMark.now() | ||
} | ||
} | ||
} else { | ||
// new system | ||
if (berberisList.isEmpty()) return | ||
var alpha = 0.8f | ||
var previousBerberis: LorenzVec? = null | ||
event.drawDynamicText(berberisList[0].up(), "§eWilted Berberis", 1.5, ignoreBlocks = false) | ||
|
||
berberisList.take(3).forEachIndexed { i, loc -> | ||
// box it with half the opacity of the previous box, first in list is yellow | ||
if (i == 0) event.drawFilledBoundingBoxNea(axisAlignedBB(loc), Color.YELLOW, alpha) | ||
else event.drawFilledBoundingBoxNea(axisAlignedBB(loc), Color.WHITE, alpha) | ||
alpha /= 2f | ||
|
||
// if there's a previous berberis, draw a line to it. The line from the 2nd to the 1st should be yellow | ||
if (i == 1) { | ||
previousBerberis?.let { | ||
event.draw3DLine(loc.add(0.5, 0.5, 0.5), it.add(0.5, 0.5, 0.5), Color.YELLOW, 4, false) | ||
} | ||
} | ||
|
||
// if we've been desynced (new system wrong) for more than 2 secconds and the list hasn't updated in that time, | ||
// switch to fallback mode. switch off of fallback once the plot is cleared | ||
if (lastSyncedAt.passedSince() > 1000.milliseconds && lastUpdated.passedSince() > 1000.milliseconds) fallback = true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use |
||
if (berberisList.isEmpty()) fallback = false | ||
} | ||
|
||
private fun fallbackRender(event: LorenzRenderWorldEvent) { | ||
for (berberis in list) { | ||
with(berberis) { | ||
if (currentParticles.distanceToPlayer() > 20) continue | ||
if (y == 0.0) continue | ||
|
||
val location = currentParticles.fixLocation(berberis) | ||
if (!moving) { | ||
event.drawFilledBoundingBoxNea(axisAlignedBB(location), config.highlightColor.toSpecialColor(), 0.7f) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. toSpecialColor is a heavy logic, please move it outside of the for loop |
||
event.drawDynamicText(location.up(), "§eWilted Berberis", 1.5, ignoreBlocks = false) | ||
} else { | ||
previousBerberis?.let { | ||
event.draw3DLine(loc.add(0.5, 0.5, 0.5), it.add(0.5, 0.5, 0.5), Color.WHITE, 2, false) | ||
event.drawFilledBoundingBoxNea(axisAlignedBB(location), Color.WHITE, 0.5f) | ||
previous?.fixLocation(berberis)?.let { | ||
event.drawFilledBoundingBoxNea(axisAlignedBB(it), Color.LIGHT_GRAY, 0.2f) | ||
event.draw3DLine(it.add(0.5, 0.0, 0.5), location.add(0.5, 0.0, 0.5), Color.WHITE, 3, false) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
previousBerberis = loc | ||
private fun primaryRender(event: LorenzRenderWorldEvent) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better name |
||
if (berberisList.isEmpty()) return | ||
var alpha = 0.8f | ||
var previousBerberis: LorenzVec? = null | ||
event.drawDynamicText(berberisList[0].up(), "§eWilted Berberis", 1.5, ignoreBlocks = false) | ||
|
||
berberisList.take(config.previewCount+1).forEachIndexed { i, loc -> | ||
// box it with half the opacity of the previous box, first in list is highlighted | ||
if (i == 0) event.drawFilledBoundingBoxNea(axisAlignedBB(loc), config.highlightColor.toSpecialColor(), alpha) | ||
else event.drawFilledBoundingBoxNea(axisAlignedBB(loc), Color.WHITE, alpha) | ||
alpha *= 0.6f | ||
|
||
// if there's a previous berberis, draw a line to it. The line from the 2nd to the 1st should be highlighted | ||
if (i == 1) { | ||
previousBerberis?.let { | ||
event.draw3DLine(loc.add(0.5, 0.5, 0.5), it.add(0.5, 0.5, 0.5), config.highlightColor.toSpecialColor(), 4, false) | ||
} | ||
} else { | ||
previousBerberis?.let { | ||
event.draw3DLine(loc.add(0.5, 0.5, 0.5), it.add(0.5, 0.5, 0.5), Color.WHITE, 2, false) | ||
} | ||
} | ||
|
||
previousBerberis = loc | ||
} | ||
} | ||
|
||
@HandleEvent | ||
fun onConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) { | ||
event.move(60, "rift.area.dreadfarm.wiltedBerberis.hideparticles", "rift.area.dreadfarm.wiltedBerberis.hideParticles") | ||
private fun nearestBerberis(location: LorenzVec): WiltedBerberis? = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. try to change the logic so that the distance is only getting calculated once per entry, not twice |
||
list.filter { it.currentParticles.distanceSq(location) < 8 } | ||
.minByOrNull { it.currentParticles.distanceSq(location) } | ||
|
||
private fun LorenzVec.fixLocation(wiltedBerberis: WiltedBerberis): LorenzVec { | ||
val x = x - 0.5 | ||
val y = wiltedBerberis.y | ||
val z = z - 0.5 | ||
return LorenzVec(x, y, z) | ||
} | ||
|
||
private fun axisAlignedBB(loc: LorenzVec) = loc.add(0.1, -0.1, 0.1).boundingToOffset(0.8, 1.0, 0.8).expandBlock() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
give this
list
below better names to differentiate