mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-15 02:50:23 -07:00
Move some logic from the base plugin to the views as callbacks
This commit is contained in:
parent
fec060626b
commit
4a053d5698
7 changed files with 295 additions and 130 deletions
|
|
@ -1,40 +1,18 @@
|
|||
package KondoKit
|
||||
|
||||
import KondoKit.Helpers.formatHtmlLabelText
|
||||
import KondoKit.Helpers.formatNumber
|
||||
import KondoKit.Helpers.getSpriteId
|
||||
import KondoKit.Helpers.showAlert
|
||||
import KondoKit.views.HiscoresView
|
||||
import KondoKit.views.LootTrackerView
|
||||
import KondoKit.views.ReflectiveEditorView
|
||||
import KondoKit.views.*
|
||||
import KondoKit.views.OnUpdateCallback
|
||||
import KondoKit.views.OnDrawCallback
|
||||
import KondoKit.views.OnXPUpdateCallback
|
||||
import KondoKit.views.OnKillingBlowNPCCallback
|
||||
import KondoKit.views.OnPostClientTickCallback
|
||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||
import KondoKit.Themes.Theme
|
||||
import KondoKit.Themes.ThemeType
|
||||
import KondoKit.Themes.getTheme
|
||||
import KondoKit.components.ScrollablePanel
|
||||
import KondoKit.views.XPTrackerView
|
||||
import KondoKit.plugin.StateManager.focusedView
|
||||
import KondoKit.views.Constants.COMBAT_LVL_SPRITE
|
||||
import KondoKit.views.HiscoresView.createHiscoreSearchView
|
||||
import KondoKit.views.HiscoresView.hiScoreView
|
||||
import KondoKit.views.LootTrackerView.BAG_ICON
|
||||
import KondoKit.views.LootTrackerView.createLootTrackerView
|
||||
import KondoKit.views.LootTrackerView.lootTrackerView
|
||||
import KondoKit.views.LootTrackerView.npcDeathSnapshots
|
||||
import KondoKit.views.LootTrackerView.onPostClientTick
|
||||
import KondoKit.views.LootTrackerView.takeGroundSnapshot
|
||||
import KondoKit.views.ReflectiveEditorView.addPlugins
|
||||
import KondoKit.views.ReflectiveEditorView.createReflectiveEditorView
|
||||
import KondoKit.views.ReflectiveEditorView.reflectiveEditorView
|
||||
import KondoKit.views.XPTrackerView.createXPTrackerView
|
||||
import KondoKit.views.XPTrackerView.createXPWidget
|
||||
import KondoKit.views.XPTrackerView.initialXP
|
||||
import KondoKit.views.XPTrackerView.resetXPTracker
|
||||
import KondoKit.views.XPTrackerView.totalXPWidget
|
||||
import KondoKit.views.XPTrackerView.updateWidget
|
||||
import KondoKit.views.XPTrackerView.wrappedWidget
|
||||
import KondoKit.views.XPTrackerView.xpTrackerView
|
||||
import KondoKit.views.XPTrackerView.xpWidgets
|
||||
import plugin.Plugin
|
||||
import plugin.api.*
|
||||
import plugin.api.API.*
|
||||
|
|
@ -103,9 +81,9 @@ class plugin : Plugin() {
|
|||
const val FIXED_HEIGHT = 503
|
||||
private const val NAVBAR_WIDTH = 30
|
||||
private const val MAIN_CONTENT_WIDTH = 242
|
||||
private const val WRENCH_ICON = 907
|
||||
private const val LOOT_ICON = 777
|
||||
private const val MAG_SPRITE = 1423
|
||||
const val WRENCH_ICON = 907
|
||||
const val LOOT_ICON = 777
|
||||
const val MAG_SPRITE = 1423
|
||||
const val LVL_ICON = 898
|
||||
private lateinit var cardLayout: CardLayout
|
||||
private lateinit var mainContentPanel: JPanel
|
||||
|
|
@ -123,12 +101,38 @@ class plugin : Plugin() {
|
|||
private const val HIDDEN_VIEW = "HIDDEN"
|
||||
private var altCanvas: AltCanvas? = null
|
||||
private val drawActions = mutableListOf<() -> Unit>()
|
||||
private val views = mutableListOf<View>()
|
||||
private val updateCallbacks = mutableListOf<OnUpdateCallback>()
|
||||
private val drawCallbacks = mutableListOf<OnDrawCallback>()
|
||||
private val xpUpdateCallbacks = mutableListOf<OnXPUpdateCallback>()
|
||||
private val killingBlowNPCCallbacks = mutableListOf<OnKillingBlowNPCCallback>()
|
||||
private val postClientTickCallbacks = mutableListOf<OnPostClientTickCallback>()
|
||||
|
||||
fun registerDrawAction(action: () -> Unit) {
|
||||
synchronized(drawActions) {
|
||||
drawActions.add(action)
|
||||
}
|
||||
}
|
||||
|
||||
fun registerUpdateCallback(callback: OnUpdateCallback) {
|
||||
updateCallbacks.add(callback)
|
||||
}
|
||||
|
||||
fun registerDrawCallback(callback: OnDrawCallback) {
|
||||
drawCallbacks.add(callback)
|
||||
}
|
||||
|
||||
fun registerXPUpdateCallback(callback: OnXPUpdateCallback) {
|
||||
xpUpdateCallbacks.add(callback)
|
||||
}
|
||||
|
||||
fun registerKillingBlowNPCCallback(callback: OnKillingBlowNPCCallback) {
|
||||
killingBlowNPCCallbacks.add(callback)
|
||||
}
|
||||
|
||||
fun registerPostClientTickCallback(callback: OnPostClientTickCallback) {
|
||||
postClientTickCallbacks.add(callback)
|
||||
}
|
||||
}
|
||||
|
||||
override fun Init() {
|
||||
|
|
@ -142,7 +146,7 @@ class plugin : Plugin() {
|
|||
if (lastLogin != "" && lastLogin != Player.usernameInput.toString()) {
|
||||
// if we logged in with a new character
|
||||
// we need to reset the trackers
|
||||
xpTrackerView?.let { resetXPTracker(it) }
|
||||
XPTrackerView.xpTrackerView?.let { XPTrackerView.resetXPTracker(it) }
|
||||
}
|
||||
lastLogin = Player.usernameInput.toString()
|
||||
}
|
||||
|
|
@ -177,6 +181,9 @@ class plugin : Plugin() {
|
|||
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) }
|
||||
frame.revalidate()
|
||||
frame.repaint()
|
||||
|
||||
// Rebuild the reflective editor UI on the EDT and in one batch
|
||||
ReflectiveEditorView.addPlugins(ReflectiveEditorView.panel)
|
||||
}
|
||||
pluginsReloaded = true
|
||||
reloadInterfaces = true
|
||||
|
|
@ -184,52 +191,10 @@ class plugin : Plugin() {
|
|||
}
|
||||
|
||||
override fun OnXPUpdate(skillId: Int, xp: Int) {
|
||||
if (!initialXP.containsKey(skillId)) {
|
||||
initialXP[skillId] = xp
|
||||
return
|
||||
}
|
||||
val previousXpSnapshot = initialXP[skillId] ?: xp
|
||||
if (xp == initialXP[skillId]) return
|
||||
|
||||
val ensureOnEdt = Runnable {
|
||||
var xpWidget = xpWidgets[skillId]
|
||||
if (xpWidget != null) {
|
||||
updateWidget(xpWidget, xp)
|
||||
} else {
|
||||
xpWidget = createXPWidget(skillId, previousXpSnapshot)
|
||||
xpWidgets[skillId] = xpWidget
|
||||
|
||||
val wrapped = wrappedWidget(xpWidget.container)
|
||||
// Attach per-widget remove menu
|
||||
val popupMenu = XPTrackerView.removeXPWidgetMenu(wrapped, skillId)
|
||||
val rightClickListener = object : MouseAdapter() {
|
||||
override fun mousePressed(e: MouseEvent) {
|
||||
if (e.isPopupTrigger) popupMenu.show(e.component, e.x, e.y)
|
||||
}
|
||||
override fun mouseReleased(e: MouseEvent) {
|
||||
if (e.isPopupTrigger) popupMenu.show(e.component, e.x, e.y)
|
||||
}
|
||||
}
|
||||
Helpers.addMouseListenerToAll(wrapped, rightClickListener)
|
||||
wrapped.addMouseListener(rightClickListener)
|
||||
|
||||
xpTrackerView?.add(wrapped)
|
||||
xpTrackerView?.add(Box.createVerticalStrut(5))
|
||||
|
||||
if(focusedView == XPTrackerView.VIEW_NAME) {
|
||||
xpTrackerView?.revalidate()
|
||||
xpTrackerView?.repaint()
|
||||
}
|
||||
|
||||
updateWidget(xpWidget, xp)
|
||||
}
|
||||
}
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
ensureOnEdt.run()
|
||||
} else {
|
||||
SwingUtilities.invokeLater(ensureOnEdt)
|
||||
}
|
||||
// Call registered XP update callbacks
|
||||
xpUpdateCallbacks.forEach { callback ->
|
||||
callback.onXPUpdate(skillId, xp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun Draw(timeDelta: Long) {
|
||||
|
|
@ -241,7 +206,7 @@ class plugin : Plugin() {
|
|||
if (pluginsReloaded) {
|
||||
// Rebuild the reflective editor UI on the EDT and in one batch
|
||||
SwingUtilities.invokeLater {
|
||||
reflectiveEditorView?.let { addPlugins(it) }
|
||||
ReflectiveEditorView.addPlugins(ReflectiveEditorView.panel)
|
||||
}
|
||||
pluginsReloaded = false
|
||||
}
|
||||
|
|
@ -253,10 +218,18 @@ class plugin : Plugin() {
|
|||
|
||||
accumulatedTime += timeDelta
|
||||
if (accumulatedTime >= TICK_INTERVAL) {
|
||||
lootTrackerView?.let { onPostClientTick(it) }
|
||||
// Call registered post client tick callbacks
|
||||
postClientTickCallbacks.forEach { callback ->
|
||||
callback.onPostClientTick()
|
||||
}
|
||||
accumulatedTime = 0L
|
||||
}
|
||||
|
||||
// Call registered draw callbacks
|
||||
drawCallbacks.forEach { callback ->
|
||||
callback.onDraw(timeDelta)
|
||||
}
|
||||
|
||||
// Draw synced actions (that require to be done between glBegin and glEnd)
|
||||
if (drawActions.isNotEmpty()) {
|
||||
synchronized(drawActions) {
|
||||
|
|
@ -294,32 +267,17 @@ class plugin : Plugin() {
|
|||
}
|
||||
|
||||
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()
|
||||
// Call registered update callbacks
|
||||
updateCallbacks.forEach { callback ->
|
||||
callback.onUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun OnKillingBlowNPC(npcID: Int, x: Int, z: Int) {
|
||||
val preDeathSnapshot = takeGroundSnapshot(Pair(x,z))
|
||||
npcDeathSnapshots[npcID] = LootTrackerView.GroundSnapshot(preDeathSnapshot, Pair(x, z), 0)
|
||||
// Call registered killing blow NPC callbacks
|
||||
killingBlowNPCCallbacks.forEach { callback ->
|
||||
callback.onKillingBlowNPC(npcID, x, z)
|
||||
}
|
||||
}
|
||||
|
||||
private fun allSpritesLoaded() : Boolean {
|
||||
|
|
@ -330,7 +288,7 @@ class plugin : Plugin() {
|
|||
return false
|
||||
}
|
||||
}
|
||||
val otherIcons = arrayOf(LVL_ICON, MAG_SPRITE, LOOT_ICON, WRENCH_ICON, COMBAT_LVL_SPRITE, BAG_ICON)
|
||||
val otherIcons = arrayOf(LVL_ICON, MAG_SPRITE, LOOT_ICON, WRENCH_ICON, Constants.COMBAT_LVL_SPRITE, LootTrackerView.BAG_ICON)
|
||||
for (icon in otherIcons) {
|
||||
if(!js5Archive8.isFileReady(icon)){
|
||||
return false
|
||||
|
|
@ -443,7 +401,7 @@ class plugin : Plugin() {
|
|||
private fun searchHiscore(username: String): Runnable {
|
||||
return Runnable {
|
||||
setActiveView(HiscoresView.VIEW_NAME)
|
||||
val customSearchField = hiScoreView?.let { HiscoresView.CustomSearchField(it) }
|
||||
val customSearchField = HiscoresView.hiScoreView?.let { HiscoresView.CustomSearchField(it) }
|
||||
|
||||
customSearchField?.searchPlayer(username) ?: run {
|
||||
println("searchView is null or CustomSearchField creation failed.")
|
||||
|
|
@ -481,15 +439,33 @@ class plugin : Plugin() {
|
|||
}
|
||||
|
||||
// Register Views
|
||||
createXPTrackerView()
|
||||
createHiscoreSearchView()
|
||||
createLootTrackerView()
|
||||
createReflectiveEditorView()
|
||||
val xpTrackerView = XPTrackerView
|
||||
val hiscoresView = HiscoresView
|
||||
val lootTrackerView = LootTrackerView
|
||||
val reflectiveEditorView = ReflectiveEditorView
|
||||
|
||||
// Create views
|
||||
xpTrackerView.createView()
|
||||
hiscoresView.createView()
|
||||
lootTrackerView.createView()
|
||||
reflectiveEditorView.createView()
|
||||
|
||||
// Register views
|
||||
views.add(xpTrackerView)
|
||||
views.add(hiscoresView)
|
||||
views.add(lootTrackerView)
|
||||
views.add(reflectiveEditorView)
|
||||
|
||||
// Register view functions
|
||||
xpTrackerView.registerFunctions()
|
||||
hiscoresView.registerFunctions()
|
||||
lootTrackerView.registerFunctions()
|
||||
reflectiveEditorView.registerFunctions()
|
||||
|
||||
mainContentPanel.add(ScrollablePanel(xpTrackerView!!), XPTrackerView.VIEW_NAME)
|
||||
mainContentPanel.add(ScrollablePanel(hiScoreView!!), HiscoresView.VIEW_NAME)
|
||||
mainContentPanel.add(ScrollablePanel(lootTrackerView!!), LootTrackerView.VIEW_NAME)
|
||||
mainContentPanel.add(ScrollablePanel(reflectiveEditorView!!), ReflectiveEditorView.VIEW_NAME)
|
||||
mainContentPanel.add(ScrollablePanel(xpTrackerView.panel), xpTrackerView.name)
|
||||
mainContentPanel.add(ScrollablePanel(hiscoresView.panel), hiscoresView.name)
|
||||
mainContentPanel.add(ScrollablePanel(lootTrackerView.panel), lootTrackerView.name)
|
||||
mainContentPanel.add(ScrollablePanel(reflectiveEditorView.panel), reflectiveEditorView.name)
|
||||
|
||||
val navPanel = Panel().apply {
|
||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||
|
|
@ -497,10 +473,10 @@ class plugin : Plugin() {
|
|||
preferredSize = Dimension(NAVBAR_WIDTH, frame.height)
|
||||
}
|
||||
|
||||
navPanel.add(createNavButton(LVL_ICON, XPTrackerView.VIEW_NAME))
|
||||
navPanel.add(createNavButton(MAG_SPRITE, HiscoresView.VIEW_NAME))
|
||||
navPanel.add(createNavButton(LOOT_ICON, LootTrackerView.VIEW_NAME))
|
||||
navPanel.add(createNavButton(WRENCH_ICON, ReflectiveEditorView.VIEW_NAME))
|
||||
navPanel.add(createNavButton(xpTrackerView.iconSpriteId, xpTrackerView.name))
|
||||
navPanel.add(createNavButton(hiscoresView.iconSpriteId, hiscoresView.name))
|
||||
navPanel.add(createNavButton(lootTrackerView.iconSpriteId, lootTrackerView.name))
|
||||
navPanel.add(createNavButton(reflectiveEditorView.iconSpriteId, reflectiveEditorView.name))
|
||||
|
||||
val rightPanel = Panel(BorderLayout()).apply {
|
||||
add(mainContentPanel, BorderLayout.CENTER)
|
||||
|
|
@ -515,7 +491,7 @@ class plugin : Plugin() {
|
|||
verticalScrollBarPolicy = JScrollPane.VERTICAL_SCROLLBAR_NEVER
|
||||
}
|
||||
|
||||
val desiredView = if (launchMinimized) HIDDEN_VIEW else XPTrackerView.VIEW_NAME
|
||||
val desiredView = if (launchMinimized) HIDDEN_VIEW else xpTrackerView.name
|
||||
// Commit layout synchronously on the EDT to avoid initial misplacement
|
||||
val commit = Runnable {
|
||||
frame.layout = BorderLayout()
|
||||
|
|
@ -580,8 +556,7 @@ class plugin : Plugin() {
|
|||
} else {
|
||||
mainContentPanel.repaint()
|
||||
}
|
||||
|
||||
focusedView = viewName
|
||||
StateManager.focusedView = viewName
|
||||
}
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
|
|
@ -604,7 +579,7 @@ class plugin : Plugin() {
|
|||
}
|
||||
lastClickTime = currentTime
|
||||
|
||||
if (focusedView == viewName) {
|
||||
if (StateManager.focusedView == viewName) {
|
||||
setActiveView("HIDDEN")
|
||||
} else {
|
||||
setActiveView(viewName)
|
||||
|
|
|
|||
|
|
@ -57,11 +57,24 @@ object Constants {
|
|||
val SKILL_DISPLAY_ORDER = arrayOf(0,3,14,2,16,13,1,15,10,4,17,7,5,12,11,6,9,8,20,18,19,22,21,23)
|
||||
}
|
||||
|
||||
object HiscoresView {
|
||||
object HiscoresView : View {
|
||||
|
||||
const val VIEW_NAME = "HISCORE_SEARCH_VIEW"
|
||||
var hiScoreView: JPanel? = null
|
||||
override val name: String = VIEW_NAME
|
||||
override val iconSpriteId: Int = Constants.MAG_SPRITE
|
||||
|
||||
override val panel: JPanel
|
||||
get() = hiScoreView ?: JPanel()
|
||||
|
||||
override fun createView() {
|
||||
createHiscoreSearchView()
|
||||
}
|
||||
|
||||
override fun registerFunctions() {
|
||||
// Hiscores functions are handled within the view itself
|
||||
}
|
||||
|
||||
class CustomSearchField(private val hiscoresPanel: JPanel) : SearchField(
|
||||
onSearch = { _ -> }, // Placeholder, will be replaced
|
||||
viewName = VIEW_NAME
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import KondoKit.plugin.Companion.primaryColor
|
|||
import KondoKit.plugin.Companion.registerDrawAction
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import KondoKit.plugin.StateManager.focusedView
|
||||
import KondoKit.views.OnKillingBlowNPCCallback
|
||||
import KondoKit.views.OnPostClientTickCallback
|
||||
import plugin.api.API
|
||||
import rt4.*
|
||||
import java.awt.*
|
||||
|
|
@ -31,7 +33,7 @@ import java.text.DecimalFormat
|
|||
import javax.swing.*
|
||||
import kotlin.math.ceil
|
||||
|
||||
object LootTrackerView {
|
||||
object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallback {
|
||||
private const val SNAPSHOT_LIFESPAN = 10
|
||||
const val BAG_ICON = 900
|
||||
val npcDeathSnapshots = mutableMapOf<Int, GroundSnapshot>()
|
||||
|
|
@ -43,6 +45,30 @@ object LootTrackerView {
|
|||
var lastConfirmedKillNpcId = -1
|
||||
private var customToolTipWindow: JWindow? = null
|
||||
var lootTrackerView: JPanel? = null
|
||||
override val name: String = VIEW_NAME
|
||||
override val iconSpriteId: Int = BAG_ICON
|
||||
|
||||
override val panel: JPanel
|
||||
get() = lootTrackerView ?: JPanel()
|
||||
|
||||
override fun createView() {
|
||||
createLootTrackerView()
|
||||
}
|
||||
|
||||
override fun registerFunctions() {
|
||||
// Register callbacks with the plugin
|
||||
KondoKit.plugin.registerPostClientTickCallback(this)
|
||||
KondoKit.plugin.registerKillingBlowNPCCallback(this)
|
||||
}
|
||||
|
||||
override fun onPostClientTick() {
|
||||
lootTrackerView?.let { onPostClientTick(it) }
|
||||
}
|
||||
|
||||
override fun onKillingBlowNPC(npcID: Int, x: Int, z: Int) {
|
||||
val preDeathSnapshot = takeGroundSnapshot(Pair(x,z))
|
||||
npcDeathSnapshots[npcID] = GroundSnapshot(preDeathSnapshot, Pair(x, z), 0)
|
||||
}
|
||||
|
||||
fun loadGEPrices(): Map<String, String> {
|
||||
return if (useLiveGEPrices) {
|
||||
|
|
@ -373,7 +399,8 @@ object LootTrackerView {
|
|||
fun onPostClientTick(lootTrackerView: JPanel) {
|
||||
val toRemove = mutableListOf<Int>()
|
||||
|
||||
npcDeathSnapshots.entries.forEach { (npcId, snapshot) ->
|
||||
npcDeathSnapshots.entries.forEach { entry ->
|
||||
val (npcId, snapshot) = entry
|
||||
val postDeathSnapshot = takeGroundSnapshot(Pair(snapshot.location.first, snapshot.location.second))
|
||||
val newDrops = postDeathSnapshot.subtract(snapshot.items)
|
||||
|
||||
|
|
@ -389,7 +416,9 @@ object LootTrackerView {
|
|||
}
|
||||
}
|
||||
|
||||
toRemove.forEach { npcDeathSnapshots.remove(it) }
|
||||
toRemove.forEach { npcId ->
|
||||
npcDeathSnapshots.remove(npcId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -602,4 +631,18 @@ object LootTrackerView {
|
|||
|
||||
data class GroundSnapshot(val items: Set<Item>, val location: Pair<Int, Int>, var age: Int)
|
||||
data class Item(val id: Int, val quantity: Int)
|
||||
}
|
||||
|
||||
// XPWidget data class for loot tracking
|
||||
data class XPWidget(
|
||||
val container: Container,
|
||||
val skillId: Int,
|
||||
val xpGainedLabel: JLabel,
|
||||
val xpLeftLabel: JLabel,
|
||||
val xpPerHourLabel: JLabel,
|
||||
val actionsRemainingLabel: JLabel,
|
||||
val progressBar: ProgressBar,
|
||||
var totalXpGained: Int = 0,
|
||||
var startTime: Long = System.currentTimeMillis(),
|
||||
var previousXp: Int = 0
|
||||
)
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ import kotlin.math.ceil
|
|||
*/
|
||||
|
||||
|
||||
object ReflectiveEditorView {
|
||||
object ReflectiveEditorView : View {
|
||||
var reflectiveEditorView: JPanel? = null
|
||||
private val loadedPlugins: MutableList<String> = mutableListOf()
|
||||
const val VIEW_NAME = "REFLECTIVE_EDITOR_VIEW"
|
||||
|
|
@ -72,6 +72,19 @@ object ReflectiveEditorView {
|
|||
// Search text for filtering plugins
|
||||
private var pluginSearchText: String = ""
|
||||
|
||||
override val name: String = VIEW_NAME
|
||||
override val iconSpriteId: Int = KondoKit.plugin.WRENCH_ICON
|
||||
override val panel: JPanel
|
||||
get() = reflectiveEditorView ?: JPanel()
|
||||
|
||||
override fun createView() {
|
||||
createReflectiveEditorView()
|
||||
}
|
||||
|
||||
override fun registerFunctions() {
|
||||
// Reflective editor functions are handled within the view itself
|
||||
}
|
||||
|
||||
fun createReflectiveEditorView() {
|
||||
// Load the cog icon once
|
||||
loadCogIcon()
|
||||
|
|
@ -749,4 +762,4 @@ object ReflectiveEditorView {
|
|||
g2.fillRoundRect(x, y, width - 1, height - 1, radius, radius)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
plugin-playground/src/main/kotlin/KondoKit/views/View.kt
Normal file
12
plugin-playground/src/main/kotlin/KondoKit/views/View.kt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package KondoKit.views
|
||||
|
||||
import javax.swing.JPanel
|
||||
|
||||
interface View {
|
||||
val name: String
|
||||
val iconSpriteId: Int
|
||||
val panel: JPanel
|
||||
|
||||
fun createView()
|
||||
fun registerFunctions()
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package KondoKit.views
|
||||
|
||||
interface OnUpdateCallback {
|
||||
fun onUpdate()
|
||||
}
|
||||
|
||||
interface OnDrawCallback {
|
||||
fun onDraw(timeDelta: Long)
|
||||
}
|
||||
|
||||
interface OnXPUpdateCallback {
|
||||
fun onXPUpdate(skillId: Int, xp: Int)
|
||||
}
|
||||
|
||||
interface OnKillingBlowNPCCallback {
|
||||
fun onKillingBlowNPC(npcID: Int, x: Int, z: Int)
|
||||
}
|
||||
|
||||
interface OnPostClientTickCallback {
|
||||
fun onPostClientTick()
|
||||
}
|
||||
|
|
@ -24,6 +24,8 @@ import KondoKit.plugin.Companion.primaryColor
|
|||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import KondoKit.plugin.StateManager.focusedView
|
||||
import KondoKit.views.BaseView
|
||||
import KondoKit.views.OnUpdateCallback
|
||||
import KondoKit.views.OnXPUpdateCallback
|
||||
import plugin.api.API
|
||||
import java.awt.*
|
||||
import java.awt.event.MouseAdapter
|
||||
|
|
@ -33,13 +35,15 @@ import java.io.InputStreamReader
|
|||
import java.nio.charset.StandardCharsets
|
||||
import javax.swing.*
|
||||
|
||||
object XPTrackerView {
|
||||
object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
||||
private val COMBAT_SKILLS = intArrayOf(0,1,2,3,4)
|
||||
val xpWidgets: MutableMap<Int, XPWidget> = HashMap()
|
||||
var totalXPWidget: XPWidget? = null
|
||||
val initialXP: MutableMap<Int, Int> = HashMap()
|
||||
var xpTrackerView: JPanel? = null
|
||||
const val VIEW_NAME = "XP_TRACKER_VIEW"
|
||||
override val name: String = VIEW_NAME
|
||||
override val iconSpriteId: Int = KondoKit.plugin.LVL_ICON
|
||||
private val skillIconCache: MutableMap<Int, java.awt.image.BufferedImage> = HashMap()
|
||||
|
||||
|
||||
|
|
@ -64,6 +68,91 @@ object XPTrackerView {
|
|||
emptyMap()
|
||||
}
|
||||
|
||||
override val panel: JPanel
|
||||
get() = xpTrackerView ?: JPanel()
|
||||
|
||||
override fun createView() {
|
||||
createXPTrackerView()
|
||||
}
|
||||
|
||||
override fun registerFunctions() {
|
||||
// Register callbacks with the plugin
|
||||
KondoKit.plugin.registerUpdateCallback(this)
|
||||
KondoKit.plugin.registerXPUpdateCallback(this)
|
||||
}
|
||||
|
||||
override fun onUpdate() {
|
||||
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 { widget ->
|
||||
val elapsedTime = (System.currentTimeMillis() - widget.startTime) / 1000.0 / 60.0 / 60.0
|
||||
val totalXPPerHour = if (elapsedTime > 0) (widget.totalXpGained / elapsedTime).toInt() else 0
|
||||
val formattedTotalXpPerHour = formatNumber(totalXPPerHour)
|
||||
widget.xpPerHourLabel.text =
|
||||
formatHtmlLabelText("XP /hr: ", primaryColor, formattedTotalXpPerHour, secondaryColor)
|
||||
widget.container.repaint()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onXPUpdate(skillId: Int, xp: Int) {
|
||||
if (!initialXP.containsKey(skillId)) {
|
||||
initialXP[skillId] = xp
|
||||
return
|
||||
}
|
||||
val previousXpSnapshot = initialXP[skillId] ?: xp
|
||||
if (xp == initialXP[skillId]) return
|
||||
|
||||
val ensureOnEdt = Runnable {
|
||||
var xpWidget = xpWidgets[skillId]
|
||||
if (xpWidget != null) {
|
||||
updateWidget(xpWidget, xp)
|
||||
} else {
|
||||
xpWidget = createXPWidget(skillId, previousXpSnapshot)
|
||||
xpWidgets[skillId] = xpWidget
|
||||
|
||||
val wrapped = wrappedWidget(xpWidget.container)
|
||||
// Attach per-widget remove menu
|
||||
val popupMenu = removeXPWidgetMenu(wrapped, skillId)
|
||||
val rightClickListener = object : MouseAdapter() {
|
||||
override fun mousePressed(e: MouseEvent) {
|
||||
if (e.isPopupTrigger) popupMenu.show(e.component, e.x, e.y)
|
||||
}
|
||||
override fun mouseReleased(e: MouseEvent) {
|
||||
if (e.isPopupTrigger) popupMenu.show(e.component, e.x, e.y)
|
||||
}
|
||||
}
|
||||
addMouseListenerToAll(wrapped, rightClickListener)
|
||||
wrapped.addMouseListener(rightClickListener)
|
||||
|
||||
xpTrackerView?.add(wrapped)
|
||||
xpTrackerView?.add(Box.createVerticalStrut(5))
|
||||
|
||||
if(focusedView == VIEW_NAME) {
|
||||
xpTrackerView?.revalidate()
|
||||
xpTrackerView?.repaint()
|
||||
}
|
||||
|
||||
updateWidget(xpWidget, xp)
|
||||
}
|
||||
}
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
ensureOnEdt.run()
|
||||
} else {
|
||||
SwingUtilities.invokeLater(ensureOnEdt)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateWidget(xpWidget: XPWidget, xp: Int) {
|
||||
val (currentLevel, xpGainedSinceLastLevel) = XPTable.getLevelForXp(xp)
|
||||
|
||||
|
|
@ -489,7 +578,6 @@ object XPTrackerView {
|
|||
}
|
||||
|
||||
|
||||
|
||||
data class XPWidget(
|
||||
val container: Container,
|
||||
val skillId: Int,
|
||||
|
|
@ -501,4 +589,4 @@ data class XPWidget(
|
|||
var totalXpGained: Int = 0,
|
||||
var startTime: Long = System.currentTimeMillis(),
|
||||
var previousXp: Int = 0
|
||||
)
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue