mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-09 16:45:46 -07:00
Merge branch 'FIXED-RESIZE' into 'KondoKit-2.0'
Fixed Streched See merge request downthecrop/rt4-client!4
This commit is contained in:
commit
1de6638a12
14 changed files with 602 additions and 299 deletions
|
|
@ -13,6 +13,7 @@ import rt4.Tile;
|
||||||
*/
|
*/
|
||||||
public abstract class Plugin {
|
public abstract class Plugin {
|
||||||
long timeOfLastDraw;
|
long timeOfLastDraw;
|
||||||
|
long timeOfLastLateDraw;
|
||||||
|
|
||||||
void _init() {
|
void _init() {
|
||||||
Init();
|
Init();
|
||||||
|
|
@ -24,6 +25,12 @@ public abstract class Plugin {
|
||||||
timeOfLastDraw = nowTime;
|
timeOfLastDraw = nowTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _lateDraw() {
|
||||||
|
long nowTime = System.currentTimeMillis();
|
||||||
|
LateDraw(nowTime - timeOfLastLateDraw);
|
||||||
|
timeOfLastLateDraw = nowTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw() is called by the client rendering loop so that plugins can draw information onto the screen.
|
* Draw() is called by the client rendering loop so that plugins can draw information onto the screen.
|
||||||
* This will be called once per frame, meaning it is framerate bound.
|
* This will be called once per frame, meaning it is framerate bound.
|
||||||
|
|
@ -31,6 +38,14 @@ public abstract class Plugin {
|
||||||
*/
|
*/
|
||||||
public void Draw(long timeDelta) {}
|
public void Draw(long timeDelta) {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LateDraw() is called at the end of a finalized frame
|
||||||
|
* This will be called once per frame, meaning it is framerate bound.
|
||||||
|
* @param timeDelta the time (ms) elapsed since the last draw call.
|
||||||
|
*/
|
||||||
|
public void LateDraw(long timeDelta) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init() is called when the plugin is first loaded
|
* Init() is called when the plugin is first loaded
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,11 @@ public class PluginRepository {
|
||||||
pluginsSnapshot.forEach(Plugin::_draw);
|
pluginsSnapshot.forEach(Plugin::_draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LateDraw() {
|
||||||
|
List<Plugin> pluginsSnapshot = new ArrayList<>(loadedPlugins.values());
|
||||||
|
pluginsSnapshot.forEach(Plugin::_lateDraw);
|
||||||
|
}
|
||||||
|
|
||||||
public static void NPCOverheadDraw(Npc npc, int screenX, int screenY) {
|
public static void NPCOverheadDraw(Npc npc, int screenX, int screenY) {
|
||||||
loadedPlugins.values().forEach((plugin) -> plugin.NPCOverheadDraw(npc, screenX, screenY));
|
loadedPlugins.values().forEach((plugin) -> plugin.NPCOverheadDraw(npc, screenX, screenY));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import java.awt.*;
|
||||||
public abstract class FrameBuffer {
|
public abstract class FrameBuffer {
|
||||||
|
|
||||||
@OriginalMember(owner = "client!vk", name = "e", descriptor = "[I")
|
@OriginalMember(owner = "client!vk", name = "e", descriptor = "[I")
|
||||||
protected int[] pixels;
|
public int[] pixels;
|
||||||
|
|
||||||
@OriginalMember(owner = "client!vk", name = "g", descriptor = "Ljava/awt/Image;")
|
@OriginalMember(owner = "client!vk", name = "g", descriptor = "Ljava/awt/Image;")
|
||||||
protected Image image;
|
protected Image image;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import org.openrs2.deob.annotation.OriginalMember;
|
||||||
import org.openrs2.deob.annotation.Pc;
|
import org.openrs2.deob.annotation.Pc;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
@ -24,6 +25,11 @@ public final class GlRenderer {
|
||||||
public static float hFOV = 0;
|
public static float hFOV = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static ByteBuffer pixelByteBuffer;
|
||||||
|
private static IntBuffer pixelIntBuffer;
|
||||||
|
public static int[] pixelData;
|
||||||
|
|
||||||
@OriginalMember(owner = "client!tf", name = "c", descriptor = "F")
|
@OriginalMember(owner = "client!tf", name = "c", descriptor = "F")
|
||||||
private static float aFloat30;
|
private static float aFloat30;
|
||||||
|
|
||||||
|
|
@ -200,10 +206,34 @@ public final class GlRenderer {
|
||||||
public static void swapBuffers() {
|
public static void swapBuffers() {
|
||||||
try {
|
try {
|
||||||
drawable.swapBuffers();
|
drawable.swapBuffers();
|
||||||
|
readPixels();
|
||||||
} catch (@Pc(3) Exception local3) {
|
} catch (@Pc(3) Exception local3) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void initializePixelBuffer(int width, int height) {
|
||||||
|
// Allocate ByteBuffer for BGRA pixels (4 bytes per pixel)
|
||||||
|
pixelByteBuffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder());
|
||||||
|
pixelIntBuffer = pixelByteBuffer.asIntBuffer();
|
||||||
|
pixelData = new int[width * height];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void readPixels() {
|
||||||
|
// Ensure the pixel buffer is initialized with the correct size
|
||||||
|
if (pixelByteBuffer == null || pixelIntBuffer.capacity() != canvasWidth * canvasHeight) {
|
||||||
|
initializePixelBuffer(canvasWidth, canvasHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read pixels into the direct ByteBuffer
|
||||||
|
gl.glReadPixels(0, 0, canvasWidth, canvasHeight, GL2.GL_BGRA,
|
||||||
|
GlRenderer.bigEndian ? GL2.GL_UNSIGNED_INT_8_8_8_8_REV : GL2.GL_UNSIGNED_BYTE,
|
||||||
|
pixelByteBuffer);
|
||||||
|
|
||||||
|
// Convert to int array if needed
|
||||||
|
pixelIntBuffer.rewind(); // Prepare the IntBuffer for reading
|
||||||
|
pixelIntBuffer.get(pixelData, 0, pixelData.length); // Transfer to pixelData array if necessary
|
||||||
|
}
|
||||||
|
|
||||||
@OriginalMember(owner = "client!tf", name = "a", descriptor = "(Z)V")
|
@OriginalMember(owner = "client!tf", name = "a", descriptor = "(Z)V")
|
||||||
public static void setFogEnabled(@OriginalArg(0) boolean enabled) {
|
public static void setFogEnabled(@OriginalArg(0) boolean enabled) {
|
||||||
if (enabled == fogEnabled) {
|
if (enabled == fogEnabled) {
|
||||||
|
|
|
||||||
|
|
@ -921,6 +921,7 @@ public final class client extends GameShell {
|
||||||
Preferences.safeMode = false;
|
Preferences.safeMode = false;
|
||||||
Preferences.write(GameShell.signLink);
|
Preferences.write(GameShell.signLink);
|
||||||
}
|
}
|
||||||
|
PluginRepository.LateDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@OriginalMember(owner = "client!client", name = "c", descriptor = "(B)V")
|
@OriginalMember(owner = "client!client", name = "c", descriptor = "(B)V")
|
||||||
|
|
|
||||||
166
plugin-playground/src/main/kotlin/KondoKit/AltCanvas.kt
Normal file
166
plugin-playground/src/main/kotlin/KondoKit/AltCanvas.kt
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
package KondoKit
|
||||||
|
|
||||||
|
import KondoKit.plugin.Companion.FIXED_HEIGHT
|
||||||
|
import KondoKit.plugin.Companion.FIXED_WIDTH
|
||||||
|
import plugin.api.API.IsHD
|
||||||
|
import rt4.GameShell.canvas
|
||||||
|
import rt4.GlRenderer
|
||||||
|
import rt4.SoftwareRaster
|
||||||
|
import java.awt.*
|
||||||
|
import java.awt.event.*
|
||||||
|
import java.awt.geom.AffineTransform
|
||||||
|
import java.awt.image.AffineTransformOp
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.awt.image.VolatileImage
|
||||||
|
|
||||||
|
class AltCanvas : Canvas() {
|
||||||
|
private var gameImage: VolatileImage? = null
|
||||||
|
private var op: AffineTransformOp? = null
|
||||||
|
private var transform: AffineTransform? = null
|
||||||
|
|
||||||
|
private var flippedImage: BufferedImage? = null
|
||||||
|
private var bufferImage = BufferedImage(FIXED_WIDTH, FIXED_HEIGHT, BufferedImage.TYPE_INT_BGR)
|
||||||
|
|
||||||
|
private var lastImageWidth = -1
|
||||||
|
private var lastImageHeight = -1
|
||||||
|
|
||||||
|
init {
|
||||||
|
isFocusable = true
|
||||||
|
requestFocusInWindow()
|
||||||
|
|
||||||
|
addMouseListener(object : MouseAdapter() {
|
||||||
|
override fun mousePressed(e: MouseEvent) = relayMouseEvent(e)
|
||||||
|
override fun mouseReleased(e: MouseEvent) = relayMouseEvent(e)
|
||||||
|
override fun mouseClicked(e: MouseEvent) = relayMouseEvent(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
addMouseMotionListener(object : MouseMotionAdapter() {
|
||||||
|
override fun mouseMoved(e: MouseEvent) = relayMouseEvent(e)
|
||||||
|
override fun mouseDragged(e: MouseEvent) = relayMouseEvent(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
addKeyListener(object : KeyAdapter() {
|
||||||
|
override fun keyPressed(e: KeyEvent) = relayKeyEvent { it.keyPressed(e) }
|
||||||
|
override fun keyReleased(e: KeyEvent) = relayKeyEvent { it.keyReleased(e) }
|
||||||
|
override fun keyTyped(e: KeyEvent) = relayKeyEvent { it.keyTyped(e) }
|
||||||
|
})
|
||||||
|
|
||||||
|
addMouseWheelListener(MouseWheelListener { e -> relayMouseWheelEvent(e) })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(g: Graphics) = paint(g)
|
||||||
|
|
||||||
|
override fun addNotify() {
|
||||||
|
super.addNotify()
|
||||||
|
createBufferStrategy(2) // Double-buffering
|
||||||
|
validateGameImage()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateGameImage() {
|
||||||
|
val gc = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice.defaultConfiguration
|
||||||
|
gameImage?.let {
|
||||||
|
when (it.validate(gc)) {
|
||||||
|
VolatileImage.IMAGE_INCOMPATIBLE -> createGameImage(gc)
|
||||||
|
VolatileImage.IMAGE_RESTORED -> renderGameImage()
|
||||||
|
}
|
||||||
|
} ?: createGameImage(gc)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createGameImage(gc: GraphicsConfiguration) {
|
||||||
|
gameImage = gc.createCompatibleVolatileImage(FIXED_WIDTH, FIXED_HEIGHT, Transparency.OPAQUE)
|
||||||
|
renderGameImage()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderGameImage() {
|
||||||
|
gameImage?.createGraphics()?.apply {
|
||||||
|
color = Color.DARK_GRAY
|
||||||
|
fillRect(0, 0, gameImage!!.width, gameImage!!.height)
|
||||||
|
color = Color.BLACK
|
||||||
|
drawString("KondoKit Scaled Fixed Canvas", 20, 20)
|
||||||
|
dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun paint(g: Graphics) {
|
||||||
|
bufferStrategy?.let { strategy ->
|
||||||
|
val g2d = strategy.drawGraphics as? Graphics2D ?: return
|
||||||
|
|
||||||
|
g2d.color = Color.BLACK
|
||||||
|
g2d.fillRect(0, 0, width, height)
|
||||||
|
|
||||||
|
gameImage?.let { image ->
|
||||||
|
val scale = minOf(width.toDouble() / image.width, height.toDouble() / image.height)
|
||||||
|
val x = ((width - image.width * scale) / 2).toInt()
|
||||||
|
val y = ((height - image.height * scale) / 2).toInt()
|
||||||
|
g2d.drawImage(image, x, y, (image.width * scale).toInt(), (image.height * scale).toInt(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
g2d.dispose() // Release the graphics context
|
||||||
|
strategy.show() // Display the buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun relayMouseEvent(e: MouseEvent) {
|
||||||
|
requestFocusInWindow()
|
||||||
|
val scale = minOf(width.toDouble() / gameImage!!.width, height.toDouble() / gameImage!!.height)
|
||||||
|
val xOffset = ((width - gameImage!!.width * scale) / 2)
|
||||||
|
val yOffset = ((height - gameImage!!.height * scale) / 2)
|
||||||
|
|
||||||
|
val adjustedX = ((e.x - xOffset) / scale).toInt().coerceIn(0, gameImage!!.width - 1)
|
||||||
|
val adjustedY = ((e.y - yOffset) / scale).toInt().coerceIn(0, gameImage!!.height - 1)
|
||||||
|
|
||||||
|
canvas.dispatchEvent(MouseEvent(this, e.id, e.`when`, e.modifiersEx, adjustedX, adjustedY, e.clickCount, e.isPopupTrigger, e.button))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun relayKeyEvent(action: (KeyListener) -> Unit) {
|
||||||
|
for (listener in canvas.keyListeners) action(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun relayMouseWheelEvent(e: MouseWheelEvent) {
|
||||||
|
val scale = minOf(width.toDouble() / gameImage!!.width, height.toDouble() / gameImage!!.height)
|
||||||
|
val xOffset = ((width - gameImage!!.width * scale) / 2)
|
||||||
|
val yOffset = ((height - gameImage!!.height * scale) / 2)
|
||||||
|
|
||||||
|
val adjustedX = ((e.x - xOffset) / scale).toInt().coerceIn(0, gameImage!!.width - 1)
|
||||||
|
val adjustedY = ((e.y - yOffset) / scale).toInt().coerceIn(0, gameImage!!.height - 1)
|
||||||
|
|
||||||
|
canvas.dispatchEvent(MouseWheelEvent(this, e.id, e.`when`, e.modifiersEx, adjustedX, adjustedY, e.clickCount, e.isPopupTrigger, e.scrollType, e.scrollAmount, e.wheelRotation))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateGameImage() {
|
||||||
|
if (IsHD()) renderGlRaster() else renderSoftwareRaster()
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderGlRaster() {
|
||||||
|
val width = gameImage!!.width
|
||||||
|
val height = gameImage!!.height
|
||||||
|
|
||||||
|
bufferImage.setRGB(0, 0, width, height, GlRenderer.pixelData, 0, width)
|
||||||
|
|
||||||
|
if (width != lastImageWidth || height != lastImageHeight) {
|
||||||
|
transform = AffineTransform.getScaleInstance(1.0, -1.0).apply {
|
||||||
|
translate(0.0, -height.toDouble())
|
||||||
|
}
|
||||||
|
op = AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR)
|
||||||
|
flippedImage = BufferedImage(width, height, bufferImage.type)
|
||||||
|
lastImageWidth = width
|
||||||
|
lastImageHeight = height
|
||||||
|
}
|
||||||
|
|
||||||
|
op!!.filter(bufferImage, flippedImage)
|
||||||
|
|
||||||
|
gameImage?.createGraphics()?.apply {
|
||||||
|
drawImage(flippedImage, 0, 0, null)
|
||||||
|
dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderSoftwareRaster() {
|
||||||
|
gameImage?.createGraphics()?.apply {
|
||||||
|
SoftwareRaster.frameBuffer.draw(this)
|
||||||
|
dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -68,7 +68,7 @@ object Helpers {
|
||||||
|
|
||||||
|
|
||||||
// Adjust for parent component location if it exists
|
// Adjust for parent component location if it exists
|
||||||
if (parentComponent != null) {
|
if (parentComponent != null && GameShell.canvas.isShowing) {
|
||||||
val parentLocation = parentComponent.locationOnScreen
|
val parentLocation = parentComponent.locationOnScreen
|
||||||
val x = parentLocation.x
|
val x = parentLocation.x
|
||||||
val y = GameShell.canvas.locationOnScreen.y
|
val y = GameShell.canvas.locationOnScreen.y
|
||||||
|
|
@ -95,10 +95,8 @@ object Helpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun convertToColor(value: String): Color {
|
||||||
fun convertToColor(value: String): Color {
|
return Color.decode(value)
|
||||||
val color = Color.decode(value) // Assumes value is in format "#RRGGBB" or "0xRRGGBB"
|
|
||||||
return color
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun colorToHex(color: Color): String {
|
fun colorToHex(color: Color): String {
|
||||||
|
|
@ -134,11 +132,7 @@ object Helpers {
|
||||||
class FieldNotifier(private val plugin: Any) {
|
class FieldNotifier(private val plugin: Any) {
|
||||||
private val observers = mutableListOf<FieldObserver>()
|
private val observers = mutableListOf<FieldObserver>()
|
||||||
|
|
||||||
fun addObserver(observer: FieldObserver) {
|
private fun notifyFieldChange(field: Field, newValue: Any?) {
|
||||||
observers.add(observer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun notifyFieldChange(field: Field, newValue: Any?) {
|
|
||||||
for (observer in observers) {
|
for (observer in observers) {
|
||||||
observer.onFieldChange(field, newValue)
|
observer.onFieldChange(field, newValue)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@ import KondoKit.Helpers.formatHtmlLabelText
|
||||||
import KondoKit.Helpers.getSpriteId
|
import KondoKit.Helpers.getSpriteId
|
||||||
import KondoKit.Helpers.showToast
|
import KondoKit.Helpers.showToast
|
||||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||||
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
|
||||||
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
|
||||||
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||||
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
||||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||||
|
|
@ -77,8 +75,8 @@ object HiscoresView {
|
||||||
private var cursorVisible: Boolean = true
|
private var cursorVisible: Boolean = true
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|
||||||
val bufferedImageSprite = getBufferedImageFromSprite(API.GetSprite(Constants.MAG_SPRITE))
|
private val bufferedImageSprite = getBufferedImageFromSprite(API.GetSprite(Constants.MAG_SPRITE))
|
||||||
val imageCanvas = bufferedImageSprite.let {
|
private val imageCanvas = bufferedImageSprite.let {
|
||||||
ImageCanvas(it).apply {
|
ImageCanvas(it).apply {
|
||||||
preferredSize = Constants.ICON_DIMENSION_SMALL
|
preferredSize = Constants.ICON_DIMENSION_SMALL
|
||||||
size = preferredSize
|
size = preferredSize
|
||||||
|
|
@ -112,7 +110,9 @@ object HiscoresView {
|
||||||
} else {
|
} else {
|
||||||
text += e.keyChar
|
text += e.keyChar
|
||||||
}
|
}
|
||||||
repaint()
|
SwingUtilities.invokeLater {
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
override fun keyPressed(e: KeyEvent) {
|
override fun keyPressed(e: KeyEvent) {
|
||||||
if (e.isControlDown) {
|
if (e.isControlDown) {
|
||||||
|
|
@ -125,7 +125,9 @@ object HiscoresView {
|
||||||
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||||
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
||||||
text += pasteText
|
text += pasteText
|
||||||
repaint()
|
SwingUtilities.invokeLater {
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +138,9 @@ object HiscoresView {
|
||||||
override fun mouseClicked(e: MouseEvent) {
|
override fun mouseClicked(e: MouseEvent) {
|
||||||
if (e.x > width - 20 && e.y < 20) {
|
if (e.x > width - 20 && e.y < 20) {
|
||||||
text = ""
|
text = ""
|
||||||
repaint()
|
SwingUtilities.invokeLater {
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -144,7 +148,9 @@ object HiscoresView {
|
||||||
Timer(500) {
|
Timer(500) {
|
||||||
cursorVisible = !cursorVisible
|
cursorVisible = !cursorVisible
|
||||||
if(focusedView == VIEW_NAME)
|
if(focusedView == VIEW_NAME)
|
||||||
repaint()
|
SwingUtilities.invokeLater {
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,7 +241,7 @@ object HiscoresView {
|
||||||
playerNameLabel?.revalidate()
|
playerNameLabel?.revalidate()
|
||||||
playerNameLabel?.repaint()
|
playerNameLabel?.repaint()
|
||||||
|
|
||||||
if(data == null) return;
|
if(data == null) return
|
||||||
|
|
||||||
playerNameLabel?.removeAll()
|
playerNameLabel?.removeAll()
|
||||||
|
|
||||||
|
|
@ -319,10 +325,6 @@ object HiscoresView {
|
||||||
return Math.round((base + maxCombatType + summoningFactor) * 1000.0) / 1000.0
|
return Math.round((base + maxCombatType + summoningFactor) * 1000.0) / 1000.0
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showError(message: String) {
|
|
||||||
JOptionPane.showMessageDialog(null, message, "Error", JOptionPane.ERROR_MESSAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findComponentByName(container: Container, name: String): Component? {
|
private fun findComponentByName(container: Container, name: String): Component? {
|
||||||
for (component in container.components) {
|
for (component in container.components) {
|
||||||
if (name == component.name) {
|
if (name == component.name) {
|
||||||
|
|
@ -437,7 +439,7 @@ object HiscoresView {
|
||||||
minimumSize = preferredSize
|
minimumSize = preferredSize
|
||||||
}
|
}
|
||||||
|
|
||||||
val bufferedImageSprite = getBufferedImageFromSprite(API.GetSprite(Constants.LVL_BAR_SPRITE));
|
val bufferedImageSprite = getBufferedImageFromSprite(API.GetSprite(Constants.LVL_BAR_SPRITE))
|
||||||
|
|
||||||
val totalLevelIcon = ImageCanvas(bufferedImageSprite).apply {
|
val totalLevelIcon = ImageCanvas(bufferedImageSprite).apply {
|
||||||
fillColor = COLOR_BACKGROUND_DARK
|
fillColor = COLOR_BACKGROUND_DARK
|
||||||
|
|
@ -486,7 +488,7 @@ object HiscoresView {
|
||||||
hiscorePanel.add(totalCombatPanel)
|
hiscorePanel.add(totalCombatPanel)
|
||||||
hiscorePanel.add(Box.createVerticalStrut(10))
|
hiscorePanel.add(Box.createVerticalStrut(10))
|
||||||
|
|
||||||
hiScoreView = hiscorePanel;
|
hiScoreView = hiscorePanel
|
||||||
}
|
}
|
||||||
|
|
||||||
data class HiscoresResponse(
|
data class HiscoresResponse(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import KondoKit.Helpers.addMouseListenerToAll
|
||||||
import KondoKit.Helpers.formatHtmlLabelText
|
import KondoKit.Helpers.formatHtmlLabelText
|
||||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||||
import KondoKit.XPTrackerView.wrappedWidget
|
import KondoKit.XPTrackerView.wrappedWidget
|
||||||
import KondoKit.plugin.Companion.IMAGE_SIZE
|
|
||||||
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
||||||
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||||
|
|
@ -33,15 +32,15 @@ import kotlin.math.ceil
|
||||||
|
|
||||||
object LootTrackerView {
|
object LootTrackerView {
|
||||||
private const val SNAPSHOT_LIFESPAN = 10
|
private const val SNAPSHOT_LIFESPAN = 10
|
||||||
const val BAG_ICON = 900;
|
const val BAG_ICON = 900
|
||||||
val npcDeathSnapshots = mutableMapOf<Int, GroundSnapshot>()
|
val npcDeathSnapshots = mutableMapOf<Int, GroundSnapshot>()
|
||||||
var gePriceMap = loadGEPrices()
|
var gePriceMap = loadGEPrices()
|
||||||
const val VIEW_NAME = "LOOT_TRACKER_VIEW";
|
const val VIEW_NAME = "LOOT_TRACKER_VIEW"
|
||||||
private val lootItemPanels = mutableMapOf<String, MutableMap<Int, Int>>()
|
private val lootItemPanels = mutableMapOf<String, MutableMap<Int, Int>>()
|
||||||
private val npcKillCounts = mutableMapOf<String, Int>()
|
private val npcKillCounts = mutableMapOf<String, Int>()
|
||||||
private var totalTrackerWidget: XPWidget? = null
|
private var totalTrackerWidget: XPWidget? = null
|
||||||
var lastConfirmedKillNpcId = -1
|
var lastConfirmedKillNpcId = -1
|
||||||
var customToolTipWindow: JWindow? = null
|
private var customToolTipWindow: JWindow? = null
|
||||||
var lootTrackerView: JPanel? = null
|
var lootTrackerView: JPanel? = null
|
||||||
|
|
||||||
fun loadGEPrices(): Map<String, String> {
|
fun loadGEPrices(): Map<String, String> {
|
||||||
|
|
@ -284,7 +283,7 @@ object LootTrackerView {
|
||||||
|
|
||||||
// Function to show the custom tooltip
|
// Function to show the custom tooltip
|
||||||
fun showCustomToolTip(location: Point, itemId: Int, quantity: Int, parentComponent: ImageCanvas) {
|
fun showCustomToolTip(location: Point, itemId: Int, quantity: Int, parentComponent: ImageCanvas) {
|
||||||
var itemDef = ObjTypeList.get(itemId)
|
val itemDef = ObjTypeList.get(itemId)
|
||||||
val gePricePerItem = gePriceMap[itemDef.id.toString()]?.toInt() ?: 0
|
val gePricePerItem = gePriceMap[itemDef.id.toString()]?.toInt() ?: 0
|
||||||
val totalGePrice = gePricePerItem * quantity
|
val totalGePrice = gePricePerItem * quantity
|
||||||
val totalHaPrice = itemDef.cost * quantity
|
val totalHaPrice = itemDef.cost * quantity
|
||||||
|
|
@ -351,6 +350,7 @@ object LootTrackerView {
|
||||||
?.apply {
|
?.apply {
|
||||||
val newValue = (getClientProperty("val") as? Int ?: 0) + valueOfNewDrops.toInt()
|
val newValue = (getClientProperty("val") as? Int ?: 0) + valueOfNewDrops.toInt()
|
||||||
text = "${formatValue(newValue)} gp"
|
text = "${formatValue(newValue)} gp"
|
||||||
|
foreground = primaryColor
|
||||||
putClientProperty("val", newValue)
|
putClientProperty("val", newValue)
|
||||||
revalidate()
|
revalidate()
|
||||||
if(focusedView == VIEW_NAME)
|
if(focusedView == VIEW_NAME)
|
||||||
|
|
@ -382,7 +382,7 @@ object LootTrackerView {
|
||||||
|
|
||||||
if (newDrops.isNotEmpty()) {
|
if (newDrops.isNotEmpty()) {
|
||||||
val npcName = NpcTypeList.get(npcId).name
|
val npcName = NpcTypeList.get(npcId).name
|
||||||
lastConfirmedKillNpcId = npcId;
|
lastConfirmedKillNpcId = npcId
|
||||||
handleNewDrops(npcName.toString(), newDrops, lootTrackerView)
|
handleNewDrops(npcName.toString(), newDrops, lootTrackerView)
|
||||||
toRemove.add(npcId)
|
toRemove.add(npcId)
|
||||||
} else if (snapshot.age >= SNAPSHOT_LIFESPAN) {
|
} else if (snapshot.age >= SNAPSHOT_LIFESPAN) {
|
||||||
|
|
@ -501,7 +501,7 @@ object LootTrackerView {
|
||||||
return childFramePanel
|
return childFramePanel
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeLootFrameMenu(toRemove: JPanel, npcName: String): JPopupMenu {
|
private fun removeLootFrameMenu(toRemove: JPanel, npcName: String): JPopupMenu {
|
||||||
// Create a popup menu
|
// Create a popup menu
|
||||||
val popupMenu = JPopupMenu()
|
val popupMenu = JPopupMenu()
|
||||||
val rFont = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
val rFont = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
||||||
|
|
@ -538,7 +538,7 @@ object LootTrackerView {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun resetLootTrackerMenu(): JPopupMenu {
|
private fun resetLootTrackerMenu(): JPopupMenu {
|
||||||
// Create a popup menu
|
// Create a popup menu
|
||||||
val popupMenu = JPopupMenu()
|
val popupMenu = JPopupMenu()
|
||||||
val rFont = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
val rFont = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import kotlin.math.ceil
|
||||||
|
|
||||||
object ReflectiveEditorView {
|
object ReflectiveEditorView {
|
||||||
var reflectiveEditorView: JPanel? = null
|
var reflectiveEditorView: JPanel? = null
|
||||||
val loadedPlugins: MutableList<String> = mutableListOf()
|
private val loadedPlugins: MutableList<String> = mutableListOf()
|
||||||
const val VIEW_NAME = "REFLECTIVE_EDITOR_VIEW"
|
const val VIEW_NAME = "REFLECTIVE_EDITOR_VIEW"
|
||||||
fun createReflectiveEditorView() {
|
fun createReflectiveEditorView() {
|
||||||
val reflectiveEditorPanel = JPanel(BorderLayout())
|
val reflectiveEditorPanel = JPanel(BorderLayout())
|
||||||
|
|
@ -266,7 +266,7 @@ object ReflectiveEditorView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
loadedPlugins.add(plugin.javaClass.`package`.name);
|
loadedPlugins.add(plugin.javaClass.`package`.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import java.awt.Rectangle
|
||||||
import java.awt.event.*
|
import java.awt.event.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.swing.JPanel
|
import javax.swing.JPanel
|
||||||
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
class ScrollablePanel(private val content: JPanel) : JPanel() {
|
class ScrollablePanel(private val content: JPanel) : JPanel() {
|
||||||
private var lastMouseY = 0
|
private var lastMouseY = 0
|
||||||
|
|
@ -83,21 +84,23 @@ class ScrollablePanel(private val content: JPanel) : JPanel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleResize() {
|
private fun handleResize() {
|
||||||
// Ensure the ScrollablePanel resizes with the frame
|
SwingUtilities.invokeLater{
|
||||||
bounds = Rectangle(0, 0, 242, frame.height)
|
// Ensure the ScrollablePanel resizes with the frame
|
||||||
|
bounds = Rectangle(0, 0, 242, frame.height)
|
||||||
|
|
||||||
// Dynamically update content bounds and scrollbar on frame resize with buffer
|
// Dynamically update content bounds and scrollbar on frame resize with buffer
|
||||||
lastSize = content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer)
|
lastSize = content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer)
|
||||||
content.bounds = Rectangle(0, 0, 242, lastSize)
|
content.bounds = Rectangle(0, 0, 242, lastSize)
|
||||||
showScrollbar = content.height > frame.height
|
showScrollbar = content.height > frame.height
|
||||||
|
|
||||||
currentOffsetY = 0
|
currentOffsetY = 0
|
||||||
|
|
||||||
content.setLocation(0, currentOffsetY)
|
content.setLocation(0, currentOffsetY)
|
||||||
updateScrollbar()
|
updateScrollbar()
|
||||||
|
|
||||||
revalidate()
|
revalidate()
|
||||||
repaint()
|
repaint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scrollContent(deltaY: Int) {
|
private fun scrollContent(deltaY: Int) {
|
||||||
|
|
@ -106,40 +109,41 @@ class ScrollablePanel(private val content: JPanel) : JPanel() {
|
||||||
content.setLocation(0, currentOffsetY)
|
content.setLocation(0, currentOffsetY)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
currentOffsetY += deltaY
|
||||||
|
|
||||||
currentOffsetY += deltaY
|
// Apply buffer to maxOffset
|
||||||
|
val maxOffset = (frame.height - content.height + viewBuffer).coerceAtMost(0)
|
||||||
|
currentOffsetY = currentOffsetY.coerceAtMost(0).coerceAtLeast(maxOffset)
|
||||||
|
|
||||||
// Apply buffer to maxOffset
|
content.setLocation(0, currentOffsetY)
|
||||||
val maxOffset = (frame.height - content.height + viewBuffer).coerceAtMost(0)
|
|
||||||
currentOffsetY = currentOffsetY.coerceAtMost(0).coerceAtLeast(maxOffset)
|
|
||||||
|
|
||||||
content.setLocation(0, currentOffsetY)
|
val contentHeight = content.height
|
||||||
|
val viewHeight = frame.height + viewBuffer
|
||||||
val contentHeight = content.height
|
|
||||||
val viewHeight = frame.height + viewBuffer
|
|
||||||
val scrollableRatio = viewHeight.toDouble() / contentHeight
|
|
||||||
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
|
|
||||||
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
|
|
||||||
|
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateScrollbar() {
|
|
||||||
showScrollbar = content.height > frame.height
|
|
||||||
|
|
||||||
val contentHeight = content.height
|
|
||||||
val viewHeight = frame.height + viewBuffer
|
|
||||||
|
|
||||||
if (showScrollbar) {
|
|
||||||
val scrollableRatio = viewHeight.toDouble() / contentHeight
|
val scrollableRatio = viewHeight.toDouble() / contentHeight
|
||||||
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
|
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
|
||||||
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
|
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
|
||||||
} else {
|
repaint()
|
||||||
scrollbarY = 0
|
|
||||||
scrollbarHeight = 0
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
repaint()
|
private fun updateScrollbar() {
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
showScrollbar = content.height > frame.height
|
||||||
|
|
||||||
|
val contentHeight = content.height
|
||||||
|
val viewHeight = frame.height + viewBuffer
|
||||||
|
|
||||||
|
if (showScrollbar) {
|
||||||
|
val scrollableRatio = viewHeight.toDouble() / contentHeight
|
||||||
|
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
|
||||||
|
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
|
||||||
|
} else {
|
||||||
|
scrollbarY = 0
|
||||||
|
scrollbarHeight = 0
|
||||||
|
}
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun paintComponent(g: Graphics) {
|
override fun paintComponent(g: Graphics) {
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ object SpriteToBufferedImage {
|
||||||
* @param brightnessBoost A multiplier to boost the brightness of the image.
|
* @param brightnessBoost A multiplier to boost the brightness of the image.
|
||||||
* @return The BufferedImage created from the sprite.
|
* @return The BufferedImage created from the sprite.
|
||||||
*/
|
*/
|
||||||
fun convertToBufferedImage(
|
private fun convertToBufferedImage(
|
||||||
sprite: BaseSprite,
|
sprite: BaseSprite,
|
||||||
tint: Color? = null,
|
tint: Color? = null,
|
||||||
grayscale: Boolean = false,
|
grayscale: Boolean = false,
|
||||||
|
|
@ -88,7 +88,7 @@ object SpriteToBufferedImage {
|
||||||
for (y in 0 until height) {
|
for (y in 0 until height) {
|
||||||
for (x in 0 until width) {
|
for (x in 0 until width) {
|
||||||
val index = pixels[y * width + x].toInt() and 0xFF
|
val index = pixels[y * width + x].toInt() and 0xFF
|
||||||
var color = palette[index]
|
val color = palette[index]
|
||||||
|
|
||||||
// Apply grayscale or tint if provided
|
// Apply grayscale or tint if provided
|
||||||
val finalColor = if (grayscale) {
|
val finalColor = if (grayscale) {
|
||||||
|
|
@ -109,7 +109,7 @@ object SpriteToBufferedImage {
|
||||||
// Manually set pixels directly
|
// Manually set pixels directly
|
||||||
for (y in 0 until height) {
|
for (y in 0 until height) {
|
||||||
for (x in 0 until width) {
|
for (x in 0 until width) {
|
||||||
var color = pixels[y * width + x]
|
val color = pixels[y * width + x]
|
||||||
|
|
||||||
// Apply grayscale or tint if provided
|
// Apply grayscale or tint if provided
|
||||||
val finalColor = if (grayscale) {
|
val finalColor = if (grayscale) {
|
||||||
|
|
@ -137,7 +137,7 @@ object SpriteToBufferedImage {
|
||||||
* @param brightnessBoost A multiplier to boost the brightness of the image.
|
* @param brightnessBoost A multiplier to boost the brightness of the image.
|
||||||
* @return The tinted color.
|
* @return The tinted color.
|
||||||
*/
|
*/
|
||||||
fun applyTint(original: Color, tint: Color, brightnessBoost: Float): Color {
|
private fun applyTint(original: Color, tint: Color, brightnessBoost: Float): Color {
|
||||||
val boostedColor = applyBrightness(original, brightnessBoost)
|
val boostedColor = applyBrightness(original, brightnessBoost)
|
||||||
val r = (boostedColor.red * tint.red / 255).coerceIn(0, 255)
|
val r = (boostedColor.red * tint.red / 255).coerceIn(0, 255)
|
||||||
val g = (boostedColor.green * tint.green / 255).coerceIn(0, 255)
|
val g = (boostedColor.green * tint.green / 255).coerceIn(0, 255)
|
||||||
|
|
@ -152,7 +152,7 @@ object SpriteToBufferedImage {
|
||||||
* @param factor The multiplier to boost the brightness.
|
* @param factor The multiplier to boost the brightness.
|
||||||
* @return The color with boosted brightness.
|
* @return The color with boosted brightness.
|
||||||
*/
|
*/
|
||||||
fun applyBrightness(original: Color, factor: Float): Color {
|
private fun applyBrightness(original: Color, factor: Float): Color {
|
||||||
val r = (original.red * factor).coerceIn(0.0f, 255.0f).toInt()
|
val r = (original.red * factor).coerceIn(0.0f, 255.0f).toInt()
|
||||||
val g = (original.green * factor).coerceIn(0.0f, 255.0f).toInt()
|
val g = (original.green * factor).coerceIn(0.0f, 255.0f).toInt()
|
||||||
val b = (original.blue * factor).coerceIn(0.0f, 255.0f).toInt()
|
val b = (original.blue * factor).coerceIn(0.0f, 255.0f).toInt()
|
||||||
|
|
@ -166,7 +166,7 @@ object SpriteToBufferedImage {
|
||||||
* @param brightnessBoost A multiplier to boost the brightness.
|
* @param brightnessBoost A multiplier to boost the brightness.
|
||||||
* @return The grayscale version of the color with boosted brightness.
|
* @return The grayscale version of the color with boosted brightness.
|
||||||
*/
|
*/
|
||||||
fun applyGrayscale(original: Color, brightnessBoost: Float): Color {
|
private fun applyGrayscale(original: Color, brightnessBoost: Float): Color {
|
||||||
// Calculate the grayscale value using the luminosity method
|
// Calculate the grayscale value using the luminosity method
|
||||||
val grayValue = (0.3 * original.red + 0.59 * original.green + 0.11 * original.blue).toInt()
|
val grayValue = (0.3 * original.red + 0.59 * original.green + 0.11 * original.blue).toInt()
|
||||||
val boostedGray = (grayValue * brightnessBoost).coerceIn(0.0f, 255.0f).toInt()
|
val boostedGray = (grayValue * brightnessBoost).coerceIn(0.0f, 255.0f).toInt()
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ import rt4.Node
|
||||||
|
|
||||||
object XPTable {
|
object XPTable {
|
||||||
|
|
||||||
const val MAX_LEVEL = 99
|
private const val MAX_LEVEL = 99
|
||||||
const val INVALID_LEVEL = -1
|
private const val INVALID_LEVEL = -1
|
||||||
const val SKILLS_XP_TABLE = 716
|
private const val SKILLS_XP_TABLE = 716
|
||||||
|
|
||||||
private var xpTable: MutableList<Int> = mutableListOf()
|
private var xpTable: MutableList<Int> = mutableListOf()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,14 @@ import plugin.Plugin
|
||||||
import plugin.api.*
|
import plugin.api.*
|
||||||
import plugin.api.API.*
|
import plugin.api.API.*
|
||||||
import plugin.api.FontColor.fromColor
|
import plugin.api.FontColor.fromColor
|
||||||
import rt4.GameShell
|
import rt4.*
|
||||||
|
import rt4.DisplayMode
|
||||||
|
import rt4.GameShell.canvas
|
||||||
import rt4.GameShell.frame
|
import rt4.GameShell.frame
|
||||||
import rt4.GlRenderer
|
|
||||||
import rt4.InterfaceList
|
|
||||||
import rt4.Player
|
|
||||||
import rt4.client.js5Archive8
|
import rt4.client.js5Archive8
|
||||||
import rt4.client.mainLoadState
|
import rt4.client.mainLoadState
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
|
import java.awt.Font
|
||||||
import java.awt.event.ActionListener
|
import java.awt.event.ActionListener
|
||||||
import java.awt.event.MouseAdapter
|
import java.awt.event.MouseAdapter
|
||||||
import java.awt.event.MouseEvent
|
import java.awt.event.MouseEvent
|
||||||
|
|
@ -91,7 +91,11 @@ class plugin : Plugin() {
|
||||||
"perfectly snapped to the edge of the game due to window chrome you can update this to fix it")
|
"perfectly snapped to the edge of the game due to window chrome you can update this to fix it")
|
||||||
var uiOffset = 0
|
var uiOffset = 0
|
||||||
|
|
||||||
private const val FIXED_WIDTH = 765
|
@Exposed("Stretched/Scaled Fixed Mode Support")
|
||||||
|
var useScaledFixed = false
|
||||||
|
|
||||||
|
const val FIXED_WIDTH = 765
|
||||||
|
const val FIXED_HEIGHT = 503
|
||||||
private const val NAVBAR_WIDTH = 30
|
private const val NAVBAR_WIDTH = 30
|
||||||
private const val MAIN_CONTENT_WIDTH = 242
|
private const val MAIN_CONTENT_WIDTH = 242
|
||||||
private const val WRENCH_ICON = 907
|
private const val WRENCH_ICON = 907
|
||||||
|
|
@ -103,14 +107,16 @@ class plugin : Plugin() {
|
||||||
private var rightPanelWrapper: JScrollPane? = null
|
private var rightPanelWrapper: JScrollPane? = null
|
||||||
private var accumulatedTime = 0L
|
private var accumulatedTime = 0L
|
||||||
private var reloadInterfaces = false
|
private var reloadInterfaces = false
|
||||||
private const val tickInterval = 600L
|
private const val TICK_INTERVAL = 600L
|
||||||
private var pluginsReloaded = false
|
private var pluginsReloaded = false
|
||||||
private var loginScreen = 160
|
private var loginScreen = 160
|
||||||
private var lastLogin = ""
|
private var lastLogin = ""
|
||||||
private var initialized = false
|
private var initialized = false
|
||||||
private var lastClickTime = 0L
|
private var lastClickTime = 0L
|
||||||
private var lastUIOffset = 0
|
private var lastUIOffset = 0
|
||||||
|
private var themeName = "RUNELITE"
|
||||||
private const val HIDDEN_VIEW = "HIDDEN"
|
private const val HIDDEN_VIEW = "HIDDEN"
|
||||||
|
private var altCanvas: AltCanvas? = null
|
||||||
private val drawActions = mutableListOf<() -> Unit>()
|
private val drawActions = mutableListOf<() -> Unit>()
|
||||||
|
|
||||||
fun registerDrawAction(action: () -> Unit) {
|
fun registerDrawAction(action: () -> Unit) {
|
||||||
|
|
@ -120,24 +126,11 @@ class plugin : Plugin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allSpritesLoaded() : Boolean {
|
override fun Init() {
|
||||||
// Check all skill sprites
|
// Disable Font AA
|
||||||
try{
|
System.setProperty("sun.java2d.opengl", "false")
|
||||||
for (i in 0 until 24) {
|
System.setProperty("awt.useSystemAAFontSettings", "off")
|
||||||
if(!js5Archive8.isFileReady(getSpriteId(i))){
|
System.setProperty("swing.aatext", "false")
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val otherIcons = arrayOf(LVL_ICON, MAG_SPRITE, LOOT_ICON, WRENCH_ICON, COMBAT_LVL_SPRITE, BAG_ICON)
|
|
||||||
for (icon in otherIcons) {
|
|
||||||
if(!js5Archive8.isFileReady(icon)){
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e : Exception){
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun OnLogin() {
|
override fun OnLogin() {
|
||||||
|
|
@ -149,55 +142,6 @@ class plugin : Plugin() {
|
||||||
lastLogin = Player.usernameInput.toString()
|
lastLogin = Player.usernameInput.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Init() {
|
|
||||||
// Disable Font AA
|
|
||||||
System.setProperty("sun.java2d.opengl", "false")
|
|
||||||
System.setProperty("awt.useSystemAAFontSettings", "off")
|
|
||||||
System.setProperty("swing.aatext", "false")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun UpdateDisplaySettings() {
|
|
||||||
val mode = GetWindowMode()
|
|
||||||
val currentScrollPaneWidth = if (mainContentPanel.isVisible) NAVBAR_WIDTH + MAIN_CONTENT_WIDTH else NAVBAR_WIDTH
|
|
||||||
lastUIOffset = uiOffset
|
|
||||||
when (mode) {
|
|
||||||
WindowMode.FIXED -> {
|
|
||||||
if (frame.width < FIXED_WIDTH + currentScrollPaneWidth + uiOffset) {
|
|
||||||
frame.setSize(FIXED_WIDTH + currentScrollPaneWidth + uiOffset, frame.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
val difference = frame.width - (FIXED_WIDTH + uiOffset + currentScrollPaneWidth)
|
|
||||||
GameShell.leftMargin = difference / 2
|
|
||||||
}
|
|
||||||
WindowMode.RESIZABLE -> {
|
|
||||||
GameShell.canvasWidth = frame.width - (currentScrollPaneWidth + uiOffset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rightPanelWrapper?.preferredSize = Dimension(currentScrollPaneWidth, frame.height)
|
|
||||||
rightPanelWrapper?.revalidate()
|
|
||||||
rightPanelWrapper?.repaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun OnKondoValueUpdated(){
|
|
||||||
StoreData("kondoUseRemoteGE", useLiveGEPrices)
|
|
||||||
StoreData("kondoTheme", theme.toString())
|
|
||||||
if(appliedTheme != theme) {
|
|
||||||
showAlert(
|
|
||||||
"KondoKit Theme changes require a relaunch.",
|
|
||||||
"KondoKit",
|
|
||||||
JOptionPane.INFORMATION_MESSAGE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
StoreData("kondoPlayerXPMultiplier", playerXPMultiplier)
|
|
||||||
LootTrackerView.gePriceMap = LootTrackerView.loadGEPrices()
|
|
||||||
StoreData("kondoLaunchMinimized", launchMinimized)
|
|
||||||
StoreData("kondoUIOffset", uiOffset)
|
|
||||||
if(lastUIOffset != uiOffset){
|
|
||||||
UpdateDisplaySettings()
|
|
||||||
reloadInterfaces = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun OnMiniMenuCreate(currentEntries: Array<out MiniMenuEntry>?) {
|
override fun OnMiniMenuCreate(currentEntries: Array<out MiniMenuEntry>?) {
|
||||||
if (currentEntries != null) {
|
if (currentEntries != null) {
|
||||||
for ((index, entry) in currentEntries.withIndex()) {
|
for ((index, entry) in currentEntries.withIndex()) {
|
||||||
|
|
@ -218,59 +162,43 @@ class plugin : Plugin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchHiscore(username: String): Runnable {
|
|
||||||
return Runnable {
|
|
||||||
setActiveView(HiscoresView.VIEW_NAME)
|
|
||||||
val customSearchField = hiScoreView?.let { HiscoresView.CustomSearchField(it) }
|
|
||||||
|
|
||||||
customSearchField?.searchPlayer(username) ?: run {
|
|
||||||
println("searchView is null or CustomSearchField creation failed.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun OnPluginsReloaded(): Boolean {
|
override fun OnPluginsReloaded(): Boolean {
|
||||||
if (!initialized) return true
|
if (!initialized) return true
|
||||||
|
updateDisplaySettings()
|
||||||
UpdateDisplaySettings()
|
|
||||||
|
|
||||||
frame.remove(rightPanelWrapper)
|
frame.remove(rightPanelWrapper)
|
||||||
frame.layout = BorderLayout()
|
frame.layout = BorderLayout()
|
||||||
frame.add(rightPanelWrapper, BorderLayout.EAST)
|
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) }
|
||||||
|
|
||||||
frame.revalidate()
|
frame.revalidate()
|
||||||
frame.repaint()
|
|
||||||
pluginsReloaded = true
|
pluginsReloaded = true
|
||||||
reloadInterfaces = true
|
reloadInterfaces = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun OnXPUpdate(skillId: Int, xp: Int) {
|
override fun OnXPUpdate(skillId: Int, xp: Int) {
|
||||||
if (!initialXP.containsKey(skillId)) {
|
if (!initialXP.containsKey(skillId)) {
|
||||||
initialXP[skillId] = xp
|
initialXP[skillId] = xp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var xpWidget = xpWidgets[skillId]
|
||||||
|
if (xpWidget != null) {
|
||||||
|
updateWidget(xpWidget, xp)
|
||||||
|
} else {
|
||||||
|
val previousXp = initialXP[skillId] ?: xp
|
||||||
|
if (xp == initialXP[skillId]) return
|
||||||
|
|
||||||
var xpWidget = xpWidgets[skillId]
|
xpWidget = createXPWidget(skillId, previousXp)
|
||||||
|
xpWidgets[skillId] = xpWidget
|
||||||
|
|
||||||
if (xpWidget != null) {
|
xpTrackerView?.add(wrappedWidget(xpWidget.container))
|
||||||
updateWidget(xpWidget, xp)
|
xpTrackerView?.add(Box.createVerticalStrut(5))
|
||||||
} else {
|
|
||||||
val previousXp = initialXP[skillId] ?: xp
|
|
||||||
if (xp == initialXP[skillId]) return
|
|
||||||
|
|
||||||
xpWidget = createXPWidget(skillId, previousXp)
|
if(focusedView == XPTrackerView.VIEW_NAME) {
|
||||||
xpWidgets[skillId] = xpWidget
|
xpTrackerView?.revalidate()
|
||||||
|
xpTrackerView?.repaint()
|
||||||
|
}
|
||||||
|
|
||||||
xpTrackerView?.add(wrappedWidget(xpWidget.container))
|
updateWidget(xpWidget, xp)
|
||||||
xpTrackerView?.add(Box.createVerticalStrut(5))
|
}
|
||||||
|
|
||||||
xpTrackerView?.revalidate()
|
|
||||||
if(focusedView == XPTrackerView.VIEW_NAME)
|
|
||||||
xpTrackerView?.repaint()
|
|
||||||
|
|
||||||
updateWidget(xpWidget, xp)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Draw(timeDelta: Long) {
|
override fun Draw(timeDelta: Long) {
|
||||||
|
|
@ -290,7 +218,7 @@ class plugin : Plugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
accumulatedTime += timeDelta
|
accumulatedTime += timeDelta
|
||||||
if (accumulatedTime >= tickInterval) {
|
if (accumulatedTime >= TICK_INTERVAL) {
|
||||||
lootTrackerView?.let { onPostClientTick(it) }
|
lootTrackerView?.let { onPostClientTick(it) }
|
||||||
accumulatedTime = 0L
|
accumulatedTime = 0L
|
||||||
}
|
}
|
||||||
|
|
@ -312,82 +240,202 @@ class plugin : Plugin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initKondoUI(){
|
override fun LateDraw(timeDelta: Long) {
|
||||||
DrawText(FontType.LARGE, fromColor(Color(16777215)), TextModifier.CENTER, "KondoKit Loading Sprites...", GameShell.canvasWidth/2, GameShell.canvasHeight/2)
|
if (!initialized) return
|
||||||
if(!allSpritesLoaded()) return;
|
if(GameShell.fullScreenFrame != null) {
|
||||||
val frame: Frame? = GameShell.frame
|
DisplayMode.setWindowMode(true, 0, FIXED_WIDTH, FIXED_HEIGHT)
|
||||||
|
showAlert("Fullscreen is not supported by KondoKit. Disable the plugin first.",
|
||||||
|
"Error",
|
||||||
|
JOptionPane.INFORMATION_MESSAGE
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!useScaledFixed) return
|
||||||
|
if(GetWindowMode() == WindowMode.FIXED){
|
||||||
|
moveAltCanvasToFront()
|
||||||
|
} else {
|
||||||
|
moveCanvasToFront()
|
||||||
|
}
|
||||||
|
altCanvas?.updateGameImage() // Update the game image as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Update() {
|
||||||
|
|
||||||
|
val widgets = xpWidgets.values
|
||||||
|
val totalXP = totalXPWidget
|
||||||
|
|
||||||
|
widgets.forEach { xpWidget ->
|
||||||
|
val elapsedTime = (System.currentTimeMillis() - xpWidget.startTime) / 1000.0 / 60.0 / 60.0
|
||||||
|
val xpPerHour = if (elapsedTime > 0) (xpWidget.totalXpGained / elapsedTime).toInt() else 0
|
||||||
|
val formattedXpPerHour = formatNumber(xpPerHour)
|
||||||
|
xpWidget.xpPerHourLabel.text =
|
||||||
|
formatHtmlLabelText("XP /hr: ", primaryColor, formattedXpPerHour, secondaryColor)
|
||||||
|
xpWidget.container.repaint()
|
||||||
|
}
|
||||||
|
|
||||||
|
totalXP?.let { totalXPWidget ->
|
||||||
|
val elapsedTime = (System.currentTimeMillis() - totalXPWidget.startTime) / 1000.0 / 60.0 / 60.0
|
||||||
|
val totalXPPerHour = if (elapsedTime > 0) (totalXPWidget.totalXpGained / elapsedTime).toInt() else 0
|
||||||
|
val formattedTotalXpPerHour = formatNumber(totalXPPerHour)
|
||||||
|
totalXPWidget.xpPerHourLabel.text =
|
||||||
|
formatHtmlLabelText("XP /hr: ", primaryColor, formattedTotalXpPerHour, secondaryColor)
|
||||||
|
totalXPWidget.container.repaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnKillingBlowNPC(npcID: Int, x: Int, z: Int) {
|
||||||
|
val preDeathSnapshot = takeGroundSnapshot(Pair(x,z))
|
||||||
|
npcDeathSnapshots[npcID] = LootTrackerView.GroundSnapshot(preDeathSnapshot, Pair(x, z), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun allSpritesLoaded() : Boolean {
|
||||||
|
// Check all skill sprites
|
||||||
|
try{
|
||||||
|
for (i in 0 until 24) {
|
||||||
|
if(!js5Archive8.isFileReady(getSpriteId(i))){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val otherIcons = arrayOf(LVL_ICON, MAG_SPRITE, LOOT_ICON, WRENCH_ICON, COMBAT_LVL_SPRITE, BAG_ICON)
|
||||||
|
for (icon in otherIcons) {
|
||||||
|
if(!js5Archive8.isFileReady(icon)){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e : Exception){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initAltCanvas(){
|
||||||
if (frame != null) {
|
if (frame != null) {
|
||||||
|
altCanvas = AltCanvas().apply {
|
||||||
|
preferredSize = Dimension(FIXED_WIDTH, FIXED_HEIGHT)
|
||||||
|
}
|
||||||
|
altCanvas?.let { frame.add(it) }
|
||||||
|
moveAltCanvasToFront()
|
||||||
|
frame.setComponentZOrder(rightPanelWrapper, 2)
|
||||||
|
}
|
||||||
|
updateDisplaySettings()
|
||||||
|
}
|
||||||
|
|
||||||
loadFont()
|
private fun updateDisplaySettings() {
|
||||||
val themeIndex = (GetData("kondoTheme") as? String) ?: "RUNELITE"
|
val mode = GetWindowMode()
|
||||||
theme = ThemeType.valueOf(themeIndex)
|
val currentScrollPaneWidth = if (mainContentPanel.isVisible) NAVBAR_WIDTH + MAIN_CONTENT_WIDTH else NAVBAR_WIDTH
|
||||||
applyTheme(getTheme(theme))
|
lastUIOffset = uiOffset
|
||||||
appliedTheme = theme
|
|
||||||
|
|
||||||
try {
|
when (mode) {
|
||||||
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel")
|
WindowMode.FIXED -> {
|
||||||
|
if (frame.width < FIXED_WIDTH + currentScrollPaneWidth + uiOffset) {
|
||||||
|
frame.setSize(FIXED_WIDTH + currentScrollPaneWidth + uiOffset, frame.height)
|
||||||
|
}
|
||||||
|
|
||||||
// Modify the UI properties to match theme
|
val difference = frame.width - (uiOffset + currentScrollPaneWidth)
|
||||||
UIManager.put("control", VIEW_BACKGROUND_COLOR)
|
|
||||||
UIManager.put("info", VIEW_BACKGROUND_COLOR)
|
|
||||||
UIManager.put("nimbusBase", WIDGET_COLOR)
|
|
||||||
UIManager.put("nimbusBlueGrey", TITLE_BAR_COLOR)
|
|
||||||
|
|
||||||
UIManager.put("nimbusDisabledText", primaryColor)
|
if (useScaledFixed) {
|
||||||
UIManager.put("nimbusSelectedText", secondaryColor)
|
GameShell.leftMargin = 0
|
||||||
UIManager.put("text", secondaryColor)
|
val canvasWidth = difference + uiOffset / 2
|
||||||
|
val canvasHeight = frame.height - canvas.y // Restricting height to frame height
|
||||||
|
|
||||||
UIManager.put("nimbusFocus", TITLE_BAR_COLOR)
|
altCanvas?.size = Dimension(canvasWidth, canvasHeight)
|
||||||
UIManager.put("nimbusInfoBlue", POPUP_BACKGROUND)
|
altCanvas?.setLocation(0, canvas.y)
|
||||||
UIManager.put("nimbusLightBackground", WIDGET_COLOR)
|
canvas.setLocation(0, canvas.y)
|
||||||
UIManager.put("nimbusSelectionBackground", PROGRESS_BAR_FILL)
|
} else {
|
||||||
|
val difference = frame.width - (FIXED_WIDTH + uiOffset + currentScrollPaneWidth)
|
||||||
UIManager.put("Button.background", WIDGET_COLOR)
|
GameShell.leftMargin = difference / 2
|
||||||
UIManager.put("Button.foreground", secondaryColor)
|
}
|
||||||
|
|
||||||
UIManager.put("CheckBox.background", VIEW_BACKGROUND_COLOR)
|
|
||||||
UIManager.put("CheckBox.foreground", secondaryColor)
|
|
||||||
UIManager.put("CheckBox.icon", UIManager.getIcon("CheckBox.icon"))
|
|
||||||
|
|
||||||
UIManager.put("ComboBox.background", WIDGET_COLOR)
|
|
||||||
UIManager.put("ComboBox.foreground", secondaryColor)
|
|
||||||
UIManager.put("ComboBox.selectionBackground", PROGRESS_BAR_FILL)
|
|
||||||
UIManager.put("ComboBox.selectionForeground", primaryColor)
|
|
||||||
UIManager.put("ComboBox.buttonBackground", WIDGET_COLOR)
|
|
||||||
|
|
||||||
UIManager.put("Spinner.background", WIDGET_COLOR)
|
|
||||||
UIManager.put("Spinner.foreground", secondaryColor)
|
|
||||||
UIManager.put("Spinner.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
|
||||||
|
|
||||||
UIManager.put("TextField.background", WIDGET_COLOR)
|
|
||||||
UIManager.put("TextField.foreground", secondaryColor)
|
|
||||||
UIManager.put("TextField.caretForeground", secondaryColor)
|
|
||||||
UIManager.put("TextField.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
|
||||||
|
|
||||||
UIManager.put("ScrollBar.thumb", WIDGET_COLOR)
|
|
||||||
UIManager.put("ScrollBar.track", VIEW_BACKGROUND_COLOR)
|
|
||||||
UIManager.put("ScrollBar.thumbHighlight", TITLE_BAR_COLOR)
|
|
||||||
|
|
||||||
UIManager.put("ProgressBar.foreground", PROGRESS_BAR_FILL)
|
|
||||||
UIManager.put("ProgressBar.background", WIDGET_COLOR)
|
|
||||||
UIManager.put("ProgressBar.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
|
||||||
|
|
||||||
UIManager.put("ToolTip.background", VIEW_BACKGROUND_COLOR)
|
|
||||||
UIManager.put("ToolTip.foreground", secondaryColor)
|
|
||||||
UIManager.put("ToolTip.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
|
||||||
|
|
||||||
// Update component tree UI to apply the new theme
|
|
||||||
SwingUtilities.updateComponentTreeUI(GameShell.frame)
|
|
||||||
} catch (e : Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore saved values
|
WindowMode.RESIZABLE -> {
|
||||||
useLiveGEPrices = (GetData("kondoUseRemoteGE") as? Boolean) ?: true
|
GameShell.canvasWidth = frame.width - (currentScrollPaneWidth + uiOffset)
|
||||||
playerXPMultiplier = (GetData("kondoPlayerXPMultiplier") as? Int) ?: 5
|
}
|
||||||
val osName = System.getProperty("os.name").toLowerCase()
|
}
|
||||||
uiOffset = (GetData("kondoUIOffset") as? Int) ?: if (osName.contains("win")) 16 else 0
|
|
||||||
launchMinimized = (GetData("kondoLaunchMinimized") as? Boolean) ?: false
|
rightPanelWrapper?.preferredSize = Dimension(currentScrollPaneWidth, frame.height)
|
||||||
|
rightPanelWrapper?.isDoubleBuffered = true
|
||||||
|
rightPanelWrapper?.revalidate()
|
||||||
|
rightPanelWrapper?.repaint()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun OnKondoValueUpdated(){
|
||||||
|
StoreData("kondoUseRemoteGE", useLiveGEPrices)
|
||||||
|
StoreData("kondoTheme", theme.toString())
|
||||||
|
if(appliedTheme != theme) {
|
||||||
|
showAlert(
|
||||||
|
"KondoKit Theme changes require a relaunch.",
|
||||||
|
"KondoKit",
|
||||||
|
JOptionPane.INFORMATION_MESSAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
StoreData("kondoPlayerXPMultiplier", playerXPMultiplier)
|
||||||
|
LootTrackerView.gePriceMap = LootTrackerView.loadGEPrices()
|
||||||
|
StoreData("kondoLaunchMinimized", launchMinimized)
|
||||||
|
StoreData("kondoUIOffset", uiOffset)
|
||||||
|
StoreData("kondoScaledFixed", useScaledFixed)
|
||||||
|
if(altCanvas == null && useScaledFixed){
|
||||||
|
initAltCanvas()
|
||||||
|
} else if(altCanvas != null && !useScaledFixed){
|
||||||
|
destroyAltCanvas()
|
||||||
|
}
|
||||||
|
if(lastUIOffset != uiOffset){
|
||||||
|
updateDisplaySettings()
|
||||||
|
reloadInterfaces = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun destroyAltCanvas(){
|
||||||
|
moveCanvasToFront()
|
||||||
|
frame.remove(altCanvas)
|
||||||
|
altCanvas = null
|
||||||
|
updateDisplaySettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun searchHiscore(username: String): Runnable {
|
||||||
|
return Runnable {
|
||||||
|
setActiveView(HiscoresView.VIEW_NAME)
|
||||||
|
val customSearchField = hiScoreView?.let { HiscoresView.CustomSearchField(it) }
|
||||||
|
|
||||||
|
customSearchField?.searchPlayer(username) ?: run {
|
||||||
|
println("searchView is null or CustomSearchField creation failed.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun moveAltCanvasToFront(){
|
||||||
|
if(altCanvas == null) return
|
||||||
|
frame.setComponentZOrder(canvas, 2)
|
||||||
|
frame.setComponentZOrder(altCanvas, 1)
|
||||||
|
frame.setComponentZOrder(rightPanelWrapper, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun moveCanvasToFront(){
|
||||||
|
if(altCanvas == null) return
|
||||||
|
frame.setComponentZOrder(altCanvas, 2)
|
||||||
|
frame.setComponentZOrder(canvas, 1)
|
||||||
|
frame.setComponentZOrder(rightPanelWrapper, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun restoreSettings(){
|
||||||
|
themeName = (GetData("kondoTheme") as? String) ?: "RUNELITE"
|
||||||
|
useLiveGEPrices = (GetData("kondoUseRemoteGE") as? Boolean) ?: true
|
||||||
|
playerXPMultiplier = (GetData("kondoPlayerXPMultiplier") as? Int) ?: 5
|
||||||
|
val osName = System.getProperty("os.name").toLowerCase()
|
||||||
|
uiOffset = (GetData("kondoUIOffset") as? Int) ?: if (osName.contains("win")) 16 else 0
|
||||||
|
launchMinimized = (GetData("kondoLaunchMinimized") as? Boolean) ?: false
|
||||||
|
useScaledFixed = (GetData("kondoScaledFixed") as? Boolean) ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initKondoUI(){
|
||||||
|
DrawText(FontType.LARGE, fromColor(Color(16777215)), TextModifier.CENTER, "KondoKit Loading Sprites...", GameShell.canvasWidth/2, GameShell.canvasHeight/2)
|
||||||
|
if(!allSpritesLoaded()) return
|
||||||
|
val frame: Frame? = GameShell.frame
|
||||||
|
if (frame != null) {
|
||||||
|
restoreSettings()
|
||||||
|
theme = ThemeType.valueOf(themeName)
|
||||||
|
applyTheme(getTheme(theme))
|
||||||
|
appliedTheme = theme
|
||||||
|
configureLookAndFeel()
|
||||||
|
|
||||||
cardLayout = CardLayout()
|
cardLayout = CardLayout()
|
||||||
mainContentPanel = JPanel(cardLayout).apply {
|
mainContentPanel = JPanel(cardLayout).apply {
|
||||||
|
|
@ -419,7 +467,7 @@ class plugin : Plugin() {
|
||||||
navPanel.add(createNavButton(LOOT_ICON, LootTrackerView.VIEW_NAME))
|
navPanel.add(createNavButton(LOOT_ICON, LootTrackerView.VIEW_NAME))
|
||||||
navPanel.add(createNavButton(WRENCH_ICON, ReflectiveEditorView.VIEW_NAME))
|
navPanel.add(createNavButton(WRENCH_ICON, ReflectiveEditorView.VIEW_NAME))
|
||||||
|
|
||||||
var rightPanel = Panel(BorderLayout()).apply {
|
val rightPanel = Panel(BorderLayout()).apply {
|
||||||
add(mainContentPanel, BorderLayout.CENTER)
|
add(mainContentPanel, BorderLayout.CENTER)
|
||||||
add(navPanel, BorderLayout.EAST)
|
add(navPanel, BorderLayout.EAST)
|
||||||
}
|
}
|
||||||
|
|
@ -427,53 +475,29 @@ class plugin : Plugin() {
|
||||||
rightPanelWrapper = JScrollPane(rightPanel).apply {
|
rightPanelWrapper = JScrollPane(rightPanel).apply {
|
||||||
preferredSize = Dimension(NAVBAR_WIDTH + MAIN_CONTENT_WIDTH, frame.height)
|
preferredSize = Dimension(NAVBAR_WIDTH + MAIN_CONTENT_WIDTH, frame.height)
|
||||||
background = VIEW_BACKGROUND_COLOR
|
background = VIEW_BACKGROUND_COLOR
|
||||||
border = BorderFactory.createEmptyBorder() // Removes the border completely
|
border = BorderFactory.createEmptyBorder()
|
||||||
horizontalScrollBarPolicy = JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
|
horizontalScrollBarPolicy = JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
|
||||||
verticalScrollBarPolicy = JScrollPane.VERTICAL_SCROLLBAR_NEVER
|
verticalScrollBarPolicy = JScrollPane.VERTICAL_SCROLLBAR_NEVER
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.layout = BorderLayout()
|
frame.layout = BorderLayout()
|
||||||
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) }
|
rightPanelWrapper?.let {
|
||||||
|
frame.add(it, BorderLayout.EAST)
|
||||||
|
}
|
||||||
|
|
||||||
if(!launchMinimized){
|
if(launchMinimized){
|
||||||
setActiveView(XPTrackerView.VIEW_NAME)
|
|
||||||
} else {
|
|
||||||
setActiveView(HIDDEN_VIEW)
|
setActiveView(HIDDEN_VIEW)
|
||||||
|
} else {
|
||||||
|
setActiveView(XPTrackerView.VIEW_NAME)
|
||||||
|
}
|
||||||
|
if(useScaledFixed) {
|
||||||
|
initAltCanvas()
|
||||||
}
|
}
|
||||||
initialized = true
|
initialized = true
|
||||||
pluginsReloaded = true
|
pluginsReloaded = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Update() {
|
|
||||||
|
|
||||||
val widgets = xpWidgets.values
|
|
||||||
val totalXP = totalXPWidget
|
|
||||||
|
|
||||||
widgets.forEach { xpWidget ->
|
|
||||||
val elapsedTime = (System.currentTimeMillis() - xpWidget.startTime) / 1000.0 / 60.0 / 60.0
|
|
||||||
val xpPerHour = if (elapsedTime > 0) (xpWidget.totalXpGained / elapsedTime).toInt() else 0
|
|
||||||
val formattedXpPerHour = formatNumber(xpPerHour)
|
|
||||||
xpWidget.xpPerHourLabel.text =
|
|
||||||
formatHtmlLabelText("XP /hr: ", primaryColor, formattedXpPerHour, secondaryColor)
|
|
||||||
xpWidget.container.repaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
totalXP?.let { totalXPWidget ->
|
|
||||||
val elapsedTime = (System.currentTimeMillis() - totalXPWidget.startTime) / 1000.0 / 60.0 / 60.0
|
|
||||||
val totalXPPerHour = if (elapsedTime > 0) (totalXPWidget.totalXpGained / elapsedTime).toInt() else 0
|
|
||||||
val formattedTotalXpPerHour = formatNumber(totalXPPerHour)
|
|
||||||
totalXPWidget.xpPerHourLabel.text =
|
|
||||||
formatHtmlLabelText("XP /hr: ", primaryColor, formattedTotalXpPerHour, secondaryColor)
|
|
||||||
totalXPWidget.container.repaint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun OnKillingBlowNPC(npcID: Int, x: Int, z: Int) {
|
|
||||||
val preDeathSnapshot = takeGroundSnapshot(Pair(x,z))
|
|
||||||
npcDeathSnapshots[npcID] = LootTrackerView.GroundSnapshot(preDeathSnapshot, Pair(x, z), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setActiveView(viewName: String) {
|
private fun setActiveView(viewName: String) {
|
||||||
// Handle the visibility of the main content panel
|
// Handle the visibility of the main content panel
|
||||||
if (viewName == HIDDEN_VIEW) {
|
if (viewName == HIDDEN_VIEW) {
|
||||||
|
|
@ -486,14 +510,15 @@ class plugin : Plugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadInterfaces = true
|
reloadInterfaces = true
|
||||||
UpdateDisplaySettings()
|
updateDisplaySettings()
|
||||||
|
|
||||||
// Revalidate and repaint necessary panels
|
// Revalidate and repaint necessary panels
|
||||||
mainContentPanel.revalidate()
|
mainContentPanel.revalidate()
|
||||||
mainContentPanel.repaint()
|
|
||||||
rightPanelWrapper?.revalidate()
|
rightPanelWrapper?.revalidate()
|
||||||
rightPanelWrapper?.repaint()
|
|
||||||
frame?.revalidate()
|
frame?.revalidate()
|
||||||
|
|
||||||
|
mainContentPanel.repaint()
|
||||||
|
rightPanelWrapper?.repaint()
|
||||||
frame?.repaint()
|
frame?.repaint()
|
||||||
|
|
||||||
focusedView = viewName
|
focusedView = viewName
|
||||||
|
|
@ -543,7 +568,7 @@ class plugin : Plugin() {
|
||||||
maximumSize = buttonSize
|
maximumSize = buttonSize
|
||||||
minimumSize = buttonSize
|
minimumSize = buttonSize
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
isOpaque = true // Ensure background is painted
|
isOpaque = true
|
||||||
|
|
||||||
val gbc = GridBagConstraints().apply {
|
val gbc = GridBagConstraints().apply {
|
||||||
anchor = GridBagConstraints.CENTER
|
anchor = GridBagConstraints.CENTER
|
||||||
|
|
@ -580,8 +605,69 @@ class plugin : Plugin() {
|
||||||
return panelButton
|
return panelButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun configureLookAndFeel(){
|
||||||
|
loadFont()
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel")
|
||||||
|
|
||||||
fun loadFont(): Font? {
|
// Modify the UI properties to match theme
|
||||||
|
UIManager.put("control", VIEW_BACKGROUND_COLOR)
|
||||||
|
UIManager.put("info", VIEW_BACKGROUND_COLOR)
|
||||||
|
UIManager.put("nimbusBase", WIDGET_COLOR)
|
||||||
|
UIManager.put("nimbusBlueGrey", TITLE_BAR_COLOR)
|
||||||
|
|
||||||
|
UIManager.put("nimbusDisabledText", primaryColor)
|
||||||
|
UIManager.put("nimbusSelectedText", secondaryColor)
|
||||||
|
UIManager.put("text", secondaryColor)
|
||||||
|
|
||||||
|
UIManager.put("nimbusFocus", TITLE_BAR_COLOR)
|
||||||
|
UIManager.put("nimbusInfoBlue", POPUP_BACKGROUND)
|
||||||
|
UIManager.put("nimbusLightBackground", WIDGET_COLOR)
|
||||||
|
UIManager.put("nimbusSelectionBackground", PROGRESS_BAR_FILL)
|
||||||
|
|
||||||
|
UIManager.put("Button.background", WIDGET_COLOR)
|
||||||
|
UIManager.put("Button.foreground", secondaryColor)
|
||||||
|
|
||||||
|
UIManager.put("CheckBox.background", VIEW_BACKGROUND_COLOR)
|
||||||
|
UIManager.put("CheckBox.foreground", secondaryColor)
|
||||||
|
UIManager.put("CheckBox.icon", UIManager.getIcon("CheckBox.icon"))
|
||||||
|
|
||||||
|
UIManager.put("ComboBox.background", WIDGET_COLOR)
|
||||||
|
UIManager.put("ComboBox.foreground", secondaryColor)
|
||||||
|
UIManager.put("ComboBox.selectionBackground", PROGRESS_BAR_FILL)
|
||||||
|
UIManager.put("ComboBox.selectionForeground", primaryColor)
|
||||||
|
UIManager.put("ComboBox.buttonBackground", WIDGET_COLOR)
|
||||||
|
|
||||||
|
UIManager.put("Spinner.background", WIDGET_COLOR)
|
||||||
|
UIManager.put("Spinner.foreground", secondaryColor)
|
||||||
|
UIManager.put("Spinner.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
||||||
|
|
||||||
|
UIManager.put("TextField.background", WIDGET_COLOR)
|
||||||
|
UIManager.put("TextField.foreground", secondaryColor)
|
||||||
|
UIManager.put("TextField.caretForeground", secondaryColor)
|
||||||
|
UIManager.put("TextField.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
||||||
|
|
||||||
|
UIManager.put("ScrollBar.thumb", WIDGET_COLOR)
|
||||||
|
UIManager.put("ScrollBar.track", VIEW_BACKGROUND_COLOR)
|
||||||
|
UIManager.put("ScrollBar.thumbHighlight", TITLE_BAR_COLOR)
|
||||||
|
|
||||||
|
UIManager.put("ProgressBar.foreground", PROGRESS_BAR_FILL)
|
||||||
|
UIManager.put("ProgressBar.background", WIDGET_COLOR)
|
||||||
|
UIManager.put("ProgressBar.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
||||||
|
|
||||||
|
UIManager.put("ToolTip.background", VIEW_BACKGROUND_COLOR)
|
||||||
|
UIManager.put("ToolTip.foreground", secondaryColor)
|
||||||
|
UIManager.put("ToolTip.border", BorderFactory.createLineBorder(TITLE_BAR_COLOR))
|
||||||
|
|
||||||
|
// Update component tree UI to apply the new theme
|
||||||
|
SwingUtilities.updateComponentTreeUI(frame)
|
||||||
|
frame.background = Color.BLACK
|
||||||
|
} catch (e : Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadFont(): Font? {
|
||||||
val fontStream = plugin::class.java.getResourceAsStream("res/runescape_small.ttf")
|
val fontStream = plugin::class.java.getResourceAsStream("res/runescape_small.ttf")
|
||||||
return if (fontStream != null) {
|
return if (fontStream != null) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -603,7 +689,7 @@ class plugin : Plugin() {
|
||||||
var focusedView: String = ""
|
var focusedView: String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun applyTheme(theme: Theme) {
|
private fun applyTheme(theme: Theme) {
|
||||||
WIDGET_COLOR = theme.widgetColor
|
WIDGET_COLOR = theme.widgetColor
|
||||||
TITLE_BAR_COLOR = theme.titleBarColor
|
TITLE_BAR_COLOR = theme.titleBarColor
|
||||||
VIEW_BACKGROUND_COLOR = theme.viewBackgroundColor
|
VIEW_BACKGROUND_COLOR = theme.viewBackgroundColor
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue