mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-09 16:45:46 -07:00
XP Drop 1.3
This commit is contained in:
parent
b8c7a1150f
commit
8b42b58b87
4 changed files with 158 additions and 41 deletions
|
|
@ -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,9 +191,9 @@ 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,
|
||||||
|
|
@ -122,16 +201,48 @@ class plugin : Plugin() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
BIN
plugin-playground/src/main/kotlin/XPDropPlugin/res/rl-lvls.png
Normal file
BIN
plugin-playground/src/main/kotlin/XPDropPlugin/res/rl-lvls.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 348 B |
BIN
plugin-playground/src/main/kotlin/XPDropPlugin/res/xpIco.png
Normal file
BIN
plugin-playground/src/main/kotlin/XPDropPlugin/res/xpIco.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 329 B |
Loading…
Add table
Add a link
Reference in a new issue