XP Drop 1.3

This commit is contained in:
downthecrop 2024-10-08 01:23:00 -07:00
parent b8c7a1150f
commit 8b42b58b87
4 changed files with 158 additions and 41 deletions

View file

@ -1,12 +1,34 @@
package XPDropPlugin; package XPDropPlugin
import KondoKit.Exposed
import plugin.Plugin import plugin.Plugin
import plugin.annotations.PluginMeta import plugin.api.API
import plugin.api.* import plugin.api.API.*
import plugin.api.FontColor.fromColor
import plugin.api.FontType
import plugin.api.TextModifier
import plugin.api.WindowMode
import rt4.Sprite
import rt4.client
import java.awt.Color import java.awt.Color
import java.awt.image.BufferedImage
import java.io.InputStream
import javax.imageio.ImageIO
import kotlin.math.ceil import kotlin.math.ceil
class plugin : Plugin() { class plugin : Plugin() {
enum class Theme {
DEFAULT, RUNELITE
}
@Exposed
private var theme = Theme.DEFAULT
@Exposed
private var alwaysShow = false
private val displayTimeout = 10000L // 10 seconds private val displayTimeout = 10000L // 10 seconds
private val drawStart = 175 private val drawStart = 175
private val drawPadding = 25 private val drawPadding = 25
@ -15,41 +37,50 @@ class plugin : Plugin() {
private var totalXp = 0 private var totalXp = 0
private val activeGains = ArrayList<XPGain>() private val activeGains = ArrayList<XPGain>()
private var lastGain = 0L private var lastGain = 0L
private val IN_GAME = 30
private val spriteCache = HashMap<Int, Sprite?>()
override fun Init() {
val themeIndex = (GetData("xp-drop-theme") as? String) ?: "DEFAULT"
theme = Theme.valueOf(themeIndex)
alwaysShow = (GetData("xp-drop-alwaysShow") as? Boolean) ?: false
}
override fun Draw(deltaTime: Long) { override fun Draw(deltaTime: Long) {
if (System.currentTimeMillis() - lastGain >= displayTimeout && activeGains.isEmpty()) if (shouldSkipDrawing()) return
return
drawTotalXPBox() drawTotalXPBox()
val removeList = ArrayList<XPGain>() val removeList = ArrayList<XPGain>()
var posX = API.GetWindowDimensions().width / 2
if (API.GetWindowMode() == WindowMode.FIXED) val movementSpeedFactor = deltaTime / 16.666 // 60 FPS
posX += 60
for(gain in activeGains) { for (gain in activeGains) {
gain.currentPos -= ceil(deltaTime / 20.0).toInt() gain.currentPos -= ceil(movementSpeedFactor).toInt() // Adjust movement based on deltaTime
if (gain.currentPos <= drawClear) { if (gain.currentPos <= drawClear) {
removeList.add(gain) removeList.add(gain)
totalXp += gain.xp totalXp += gain.xp
} else if (gain.currentPos <= drawStart){ } else if (gain.currentPos <= drawStart) {
val sprite = XPSprites.getSpriteForSkill(skillId = gain.skill) drawXPDrops(gain)
sprite?.render(posX - 25, gain.currentPos - 20)
API.DrawText(
FontType.SMALL,
FontColor.fromColor(Color.WHITE),
TextModifier.LEFT,
addCommas(gain.xp.toString()),
posX,
gain.currentPos
)
} }
} }
activeGains.removeAll(removeList.toSet()) activeGains.removeAll(removeList.toSet())
} }
private fun shouldSkipDrawing(): Boolean {
return client.gameState < IN_GAME || (!alwaysShow && isDisplayTimeoutExpired() && activeGains.isEmpty())
}
fun OnKondoValueUpdated() {
StoreData("xp-drop-theme",theme.toString())
StoreData("xp-drop-alwaysShow",alwaysShow)
}
private fun isDisplayTimeoutExpired(): Boolean {
return System.currentTimeMillis() - lastGain >= displayTimeout
}
override fun OnXPUpdate(skill: Int, xp: Int) { override fun OnXPUpdate(skill: Int, xp: Int) {
if (xp == lastXp[skill]) return if (xp == lastXp[skill]) return
@ -81,6 +112,54 @@ class plugin : Plugin() {
} }
private fun drawTotalXPBox() { private fun drawTotalXPBox() {
when (theme) {
Theme.DEFAULT -> drawDefaultXPBox()
Theme.RUNELITE -> drawRuneliteXPBox()
}
}
private fun drawXPDrops(gain : XPGain) {
when (theme) {
Theme.DEFAULT -> drawDefaultXPDrop(gain)
Theme.RUNELITE -> drawRuneliteXPDrops(gain)
}
}
private fun drawDefaultXPDrop(gain: XPGain) {
var posX = API.GetWindowDimensions().width / 2
if (API.GetWindowMode() == WindowMode.FIXED)
posX += 60
val sprite = spriteCache.getOrPut(gain.skill) { XPSprites.getSpriteForSkill(skillId = gain.skill) }
sprite?.render(posX - 25, gain.currentPos - 20)
DrawText(
FontType.SMALL,
fromColor(Color.WHITE),
TextModifier.LEFT,
addCommas(gain.xp.toString()),
posX,
gain.currentPos
)
}
private fun drawRuneliteXPDrops(gain: XPGain) {
val w = API.GetWindowDimensions().width
val offset = if(API.GetWindowMode() == WindowMode.FIXED) 251 else 225
val extra = 2;
val posX = w - (offset + extra)
val str = addCommas(gain.xp.toString())
val fontCharWidth = 4
val displace = str.length*fontCharWidth + 30
// should be scaled https://github.com/runelite/runelite/blob/0500906f8de9cd20875c168a7a59e5e066ed5058/runelite-client/src/main/java/net/runelite/client/game/SkillIconManager.java#L50
// but for now this is good enough
val sprite = spriteCache.getOrPut(gain.skill) { XPSprites.getSpriteForSkill(skillId = gain.skill) }
sprite?.render(posX - displace, gain.currentPos - 20)
drawTextWithDropShadow(posX, gain.currentPos, Color.WHITE, addCommas(gain.xp.toString()))
}
private fun drawDefaultXPBox() {
var posX = API.GetWindowDimensions().width / 2 var posX = API.GetWindowDimensions().width / 2
val posY = API.GetWindowDimensions().height / 4 val posY = API.GetWindowDimensions().height / 4
@ -89,13 +168,13 @@ class plugin : Plugin() {
API.ClipRect(0, 0, posX * 2, posY * 4) API.ClipRect(0, 0, posX * 2, posY * 4)
val horizontal = API.GetSprite(822) val horizontal = spriteCache.getOrPut(822) { API.GetSprite(822) }
val horizontalTop = API.GetSprite(820) val horizontalTop = spriteCache.getOrPut(820) { API.GetSprite(820) }
val tlCorner = API.GetSprite(824) val tlCorner = spriteCache.getOrPut(824) { API.GetSprite(824) }
val blCorner = API.GetSprite(826) val blCorner = spriteCache.getOrPut(826) { API.GetSprite(826) }
val trCorner = API.GetSprite(825) val trCorner = spriteCache.getOrPut(825) { API.GetSprite(825) }
val brCorner = API.GetSprite(827) val brCorner = spriteCache.getOrPut(827) { API.GetSprite(827) }
val bg = API.GetSprite(657) val bg = spriteCache.getOrPut(657) { API.GetSprite(657) }
bg?.render(posX - 77, 10) bg?.render(posX - 77, 10)
API.FillRect(posX - 75, 5, 140, 30, 0, 64) API.FillRect(posX - 75, 5, 140, 30, 0, 64)
@ -112,26 +191,58 @@ class plugin : Plugin() {
horizontalTop?.render(posX + 9, -8) horizontalTop?.render(posX + 9, -8)
horizontal?.render(posX + 9, 22) horizontal?.render(posX + 9, 22)
API.DrawText( DrawText(
FontType.SMALL, FontType.SMALL,
FontColor.fromColor(Color.WHITE), fromColor(Color.WHITE),
TextModifier.LEFT, TextModifier.LEFT,
"Total Xp: ${addCommas(totalXp.toString())}", "Total Xp: ${addCommas(totalXp.toString())}",
posX - 65, posX - 65,
28 28
) )
} }
private fun drawRuneliteXPBox() {
val boxHeight = 29
val boxWidth = 119
val posX = API.GetWindowDimensions().width
val innerBorderColor = Color(90, 82, 69).rgb
val outerBorderColor = Color(56,48,35).rgb
val offset = if(API.GetWindowMode() == WindowMode.FIXED) 251 else 225
val boxStart = posX - (offset + boxWidth)
val yOffset = if(API.GetWindowMode() == WindowMode.FIXED) 4 else 0
val lvlIcon = 898;
val sprite = spriteCache.getOrPut(lvlIcon){
val imageStream: InputStream = plugin::class.java.getResourceAsStream("res/rl-lvls.png")
imageStream.use { imageStream ->
val image: BufferedImage = ImageIO.read(imageStream)
API.GetSpriteFromPNG(image)
}
}
// Draw a simple rectangle instead of the default box design
API.FillRect(boxStart, yOffset, boxWidth, boxHeight, innerBorderColor, 150)
drawTextWithDropShadow(boxStart+boxWidth-4, 18+yOffset, Color.WHITE, addCommas(totalXp.toString()))
// Inner Border
API.DrawRect(boxStart+1, 1+yOffset, boxWidth-2, boxHeight-2, innerBorderColor)
// redraw around the border
API.DrawRect(boxStart, yOffset, boxWidth, boxHeight, outerBorderColor)
sprite?.render(boxStart + 3, 3+yOffset)
}
data class XPGain(val skill: Int, val xp: Int, var currentPos: Int) data class XPGain(val skill: Int, val xp: Int, var currentPos: Int)
fun addCommas(num: String): String{ fun addCommas(num: String): String {
var newString = "" var newString = ""
if(num.length > 9){ if (num.length > 9) {
return "Lots!" return "Lots!"
} }
var counter = 1 var counter = 1
num.reversed().forEach { num.reversed().forEach {
if(counter % 3 == 0 && counter != num.length){ if (counter % 3 == 0 && counter != num.length) {
newString += "$it," newString += "$it,"
} else { } else {
newString += it newString += it
@ -140,4 +251,10 @@ class plugin : Plugin() {
} }
return newString.reversed() return newString.reversed()
} }
private fun drawTextWithDropShadow(x: Int, y: Int, color: Color, text: String, mod : TextModifier = TextModifier.RIGHT) {
DrawText(FontType.SMALL, fromColor(Color(0)), mod, text, x + 1, y + 1)
DrawText(FontType.SMALL, fromColor(color), mod, text, x, y)
}
} }

View file

@ -1,3 +1,3 @@
AUTHOR='Ceikry' AUTHOR='Ceikry'
DESCRIPTION='Draws nice and clean experience drops onto the screen.' DESCRIPTION='Draws nice and clean experience drops onto the screen.'
VERSION=1.2 VERSION=1.3

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B