mirror of
https://gitlab.com/2009scape/tools/2009scape-map-viewer.git
synced 2026-08-01 14:39:25 -06:00
Scrolling, QOL
This commit is contained in:
parent
41e98f89d4
commit
655ca258f2
8 changed files with 190 additions and 100 deletions
102
src/main/kotlin/NPCSpawnPanel.kt
Normal file
102
src/main/kotlin/NPCSpawnPanel.kt
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
import cacheops.cache.definition.decoder.NPC
|
||||
import misc.ImgButton
|
||||
import java.awt.Color
|
||||
import java.awt.Dimension
|
||||
import java.awt.FlowLayout
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import javax.swing.BoxLayout
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
import javax.swing.border.MatteBorder
|
||||
|
||||
class NPCSpawnPanel : JPanel() {
|
||||
val rowBorder = MatteBorder(1, 1, 1, 1, Color.WHITE)
|
||||
init {
|
||||
layout = BoxLayout(this, BoxLayout.PAGE_AXIS)
|
||||
|
||||
add(NPCSpawnerPanel())
|
||||
|
||||
Rs2MapEditor.npcs.forEach {
|
||||
val row = NPCRow(it, this)
|
||||
row.border = rowBorder
|
||||
Rs2MapEditor.npcRows.add(row)
|
||||
add(row)
|
||||
}
|
||||
}
|
||||
|
||||
fun redrawRows() {
|
||||
Rs2MapEditor.npcRows.forEach {
|
||||
remove(it)
|
||||
}
|
||||
Rs2MapEditor.npcRows.clear()
|
||||
Rs2MapEditor.npcs.forEach {
|
||||
val row = NPCRow(it, this)
|
||||
row.border = rowBorder
|
||||
Rs2MapEditor.npcRows.add(row)
|
||||
add(row)
|
||||
}
|
||||
repaint()
|
||||
}
|
||||
|
||||
class NPCSpawnerPanel : JPanel() {
|
||||
init {
|
||||
val addButton = ImgButton("/add_hi.png", "/add_dark.png")
|
||||
addButton.onClick {
|
||||
Rs2MapEditor.state = EditorState.ADD_NPC
|
||||
}
|
||||
Rs2MapEditor.npcIdInput.minimumSize = Dimension(200, 25)
|
||||
Rs2MapEditor.npcIdInput.maximumSize = Dimension(200, 25)
|
||||
Rs2MapEditor.npcIdInput.preferredSize = Dimension(200, 25)
|
||||
minimumSize = Dimension(300, 60)
|
||||
preferredSize = Dimension(300, 60)
|
||||
maximumSize = Dimension(300, 60)
|
||||
|
||||
layout = FlowLayout()
|
||||
add(Rs2MapEditor.npcIdInput)
|
||||
add(addButton)
|
||||
border = MatteBorder(1, 1, 1, 1, Color.GREEN)
|
||||
}
|
||||
}
|
||||
|
||||
class NPCRow(val npc: NPC, val parent: JPanel) : JPanel(){
|
||||
init {
|
||||
layout = FlowLayout()
|
||||
add(JLabel("${npc.definition.name} (LVL ${npc.definition.combat}) [${npc.x} | ${npc.y} | ${npc.plane}]"))
|
||||
val deleteButton = ImgButton("/trash_hi.png", "/trash_dark.png")
|
||||
add(deleteButton)
|
||||
minimumSize = Dimension(300, 40)
|
||||
preferredSize = Dimension(300, 40)
|
||||
maximumSize = Dimension(300, 40)
|
||||
deleteButton.onClick {
|
||||
Rs2MapEditor.npcs.remove(npc)
|
||||
parent.remove(this)
|
||||
parent.repaint()
|
||||
Rs2MapEditor.npcRows.remove(this)
|
||||
if(Rs2MapEditor.npcs.filter { it.x == npc.x && it.y == npc.y }.isEmpty()){
|
||||
Rs2MapEditor.componentPointMap.filter { it.key.x == npc.x && it.key.y == npc.y }.forEach { (_,cell) ->
|
||||
cell.components.forEach { c ->
|
||||
if(c is JLabel) cell.remove(c)
|
||||
}
|
||||
cell.repaint()
|
||||
Rs2MapEditor.npcsUpdated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addMouseListener(object : MouseAdapter(){
|
||||
val border = MatteBorder(1, 1, 1, 1, Color.YELLOW)
|
||||
val defaultBorder = MatteBorder(1, 1, 1, 1, Color.GRAY)
|
||||
override fun mouseEntered(e: MouseEvent?) {
|
||||
super.mouseEntered(e)
|
||||
Rs2MapEditor.componentPointMap.filter { it.key.x == npc.x && it.key.y == npc.y }.forEach { it.value.border = border }
|
||||
}
|
||||
|
||||
override fun mouseExited(e: MouseEvent?) {
|
||||
super.mouseExited(e)
|
||||
Rs2MapEditor.componentPointMap.filter { it.key.x == npc.x && it.key.y == npc.y }.forEach{ it.value.border = defaultBorder }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ import com.displee.cache.CacheLibrary
|
|||
import com.formdev.flatlaf.FlatDarculaLaf
|
||||
import const.Image.RED_DOT
|
||||
import const.Image.YELLOW_DOT
|
||||
import misc.CustomEventQueue
|
||||
import misc.ImgButton
|
||||
import java.awt.*
|
||||
import java.awt.event.KeyEvent
|
||||
import java.awt.event.MouseAdapter
|
||||
|
|
@ -18,13 +20,16 @@ import kotlin.system.exitProcess
|
|||
|
||||
object Rs2MapEditor {
|
||||
|
||||
val library = CacheLibrary.create("K:\\RSPSDev\\2-009Scape-578\\Server\\data\\cache")
|
||||
val library = CacheLibrary.create("/home/ceikry/IdeaProjects/rs09-remake/Server/data/cache/")
|
||||
var region = 12850
|
||||
var npcs = NPCSpawnParser.parseNPCSpawns(region)
|
||||
var items = GroundItemSpawnParser.parseItemSpawns(region)
|
||||
val npcRows = ArrayList<NPCSpawnPanel.NPCRow>()
|
||||
var npcsUpdated = false
|
||||
var tileDataUpdated = false
|
||||
lateinit var mapPanel: MapPane
|
||||
lateinit var npcPanel: NPCSpawnPanel
|
||||
lateinit var infoPane: InfoPane
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
|
|
@ -61,7 +66,7 @@ object Rs2MapEditor {
|
|||
var infoLabel = JLabel()
|
||||
var underlayInfo = JLabel("Right click a tile to get more information")
|
||||
var underlayLabel = JLabel()
|
||||
val npcIdInput = JTextField()
|
||||
lateinit var npcIdInput: JTextField
|
||||
var state = EditorState.NONE
|
||||
|
||||
class MainFrame : JFrame("Praesecho Map Editor v0.3") {
|
||||
|
|
@ -80,17 +85,18 @@ object Rs2MapEditor {
|
|||
defaultCloseOperation = EXIT_ON_CLOSE
|
||||
jMenuBar = MenuBar()
|
||||
mapPanel = MapPane()
|
||||
npcIdInput = JTextField()
|
||||
npcPanel = NPCSpawnPanel()
|
||||
add(SettingsPane(), BorderLayout.PAGE_START)
|
||||
infoPane = InfoPane()
|
||||
add(ScrollPane(), BorderLayout.CENTER)
|
||||
add(ScrollPane2(), BorderLayout.EAST)
|
||||
add(statusBar, BorderLayout.SOUTH)
|
||||
infoLabel.text = "Information"
|
||||
statusLabel.text = "-"
|
||||
//frame.pack()
|
||||
setLocationRelativeTo(null)
|
||||
isResizable = false
|
||||
isVisible = true
|
||||
CustomEventQueue.install()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +132,7 @@ object Rs2MapEditor {
|
|||
if (overlayID == 0) {
|
||||
mapCell.background = underlayMap[MapTileParser.definition.getTile(column, flippedY, 0).underlayId]!!.getRGB()
|
||||
} else {
|
||||
mapCell.background = Color(overlayMap[overlayID]!!.color)
|
||||
mapCell.background = overlayMap[overlayID]!!.getRGB()
|
||||
}
|
||||
|
||||
mapCell.border = border
|
||||
|
|
@ -297,6 +303,7 @@ object Rs2MapEditor {
|
|||
println("${selectedPointX} : ${selectedPointY}")
|
||||
string.append("</tbody></table><br/>")
|
||||
underlayInfo.text = String.format("<html><body style=\"text-align: center;\">%s</body></html>", string.toString())
|
||||
infoPane.selectedIndex = 0
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -307,8 +314,9 @@ object Rs2MapEditor {
|
|||
init {
|
||||
// Scroll bar
|
||||
val scrollFrame = JScrollPane(mapPanel)
|
||||
scrollFrame.maximumSize = Dimension(1300, 700)
|
||||
scrollFrame.preferredSize = Dimension(1300, 700)
|
||||
scrollFrame.maximumSize = Dimension(1300, 750)
|
||||
scrollFrame.preferredSize = Dimension(1300, 750)
|
||||
scrollFrame.verticalScrollBar.unitIncrement = 20
|
||||
add(scrollFrame, BorderLayout.CENTER)
|
||||
}
|
||||
}
|
||||
|
|
@ -317,8 +325,9 @@ object Rs2MapEditor {
|
|||
init {
|
||||
// Scroll bar
|
||||
layout = BorderLayout()
|
||||
val scrollFrame = JScrollPane(InfoPane())
|
||||
val scrollFrame = JScrollPane(infoPane)
|
||||
scrollFrame.preferredSize = Dimension(255, 980)
|
||||
scrollFrame.verticalScrollBar.unitIncrement = 20
|
||||
add(scrollFrame, BorderLayout.CENTER)
|
||||
}
|
||||
}
|
||||
|
|
@ -380,96 +389,6 @@ object Rs2MapEditor {
|
|||
}
|
||||
}
|
||||
|
||||
class NPCSpawnPanel : JPanel() {
|
||||
val rowBorder = MatteBorder(1,1,1,1,Color.WHITE)
|
||||
init {
|
||||
layout = BoxLayout(this, BoxLayout.PAGE_AXIS)
|
||||
|
||||
add(NPCSpawnerPanel())
|
||||
|
||||
npcs.forEach {
|
||||
val row = NPCRow(it, this)
|
||||
row.border = rowBorder
|
||||
npcRows.add(row)
|
||||
add(row)
|
||||
}
|
||||
}
|
||||
|
||||
fun redrawRows() {
|
||||
npcRows.forEach {
|
||||
remove(it)
|
||||
}
|
||||
npcRows.clear()
|
||||
npcs.forEach {
|
||||
val row = NPCRow(it, this)
|
||||
row.border = rowBorder
|
||||
npcRows.add(row)
|
||||
add(row)
|
||||
}
|
||||
repaint()
|
||||
}
|
||||
|
||||
class NPCSpawnerPanel : JPanel() {
|
||||
init {
|
||||
val addButton = ImgButton("add_hi.png","add_dark.png")
|
||||
addButton.onClick {
|
||||
state = EditorState.ADD_NPC
|
||||
}
|
||||
npcIdInput.minimumSize = Dimension(200,25)
|
||||
npcIdInput.maximumSize = Dimension(200,25)
|
||||
npcIdInput.preferredSize = Dimension(200,25)
|
||||
minimumSize = Dimension(300, 60)
|
||||
preferredSize = Dimension(300, 60)
|
||||
maximumSize = Dimension(300, 60)
|
||||
|
||||
layout = FlowLayout()
|
||||
add(npcIdInput)
|
||||
add(addButton)
|
||||
border = MatteBorder(1,1,1,1, Color.GREEN)
|
||||
}
|
||||
}
|
||||
|
||||
class NPCRow(val npc: NPC, val parent: JPanel) : JPanel(){
|
||||
init {
|
||||
layout = FlowLayout()
|
||||
add(JLabel("${npc.definition.name} (LVL ${npc.definition.combat}) [${npc.x} | ${npc.y} | ${npc.plane}]"))
|
||||
val deleteButton = ImgButton("trash_hi.png","trash_dark.png")
|
||||
add(deleteButton)
|
||||
minimumSize = Dimension(300, 40)
|
||||
preferredSize = Dimension(300, 40)
|
||||
maximumSize = Dimension(300, 40)
|
||||
deleteButton.onClick {
|
||||
npcs.remove(npc)
|
||||
parent.remove(this)
|
||||
parent.repaint()
|
||||
npcRows.remove(this)
|
||||
if(npcs.filter { it.x == npc.x && it.y == npc.y }.isEmpty()){
|
||||
componentPointMap.filter { it.key.x == npc.x && it.key.y == npc.y }.forEach { (_,cell) ->
|
||||
cell.components.forEach { c ->
|
||||
if(c is JLabel) cell.remove(c)
|
||||
}
|
||||
cell.repaint()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addMouseListener(object : MouseAdapter(){
|
||||
val border = MatteBorder(1,1,1,1,Color.YELLOW)
|
||||
val defaultBorder = MatteBorder(1,1,1,1, Color.GRAY)
|
||||
override fun mouseEntered(e: MouseEvent?) {
|
||||
super.mouseEntered(e)
|
||||
componentPointMap.filter { it.key.x == npc.x && it.key.y == npc.y }.forEach { it.value.border = border }
|
||||
}
|
||||
|
||||
override fun mouseExited(e: MouseEvent?) {
|
||||
super.mouseExited(e)
|
||||
componentPointMap.filter { it.key.x == npc.x && it.key.y == npc.y }.forEach{ it.value.border = defaultBorder }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnderlaySquarePanel(color: Color, size: Int, val id: Any) : JPanel() {
|
||||
init {
|
||||
when (id) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import Rs2MapEditor
|
|||
import cacheops.cache.definition.decoder.NPC
|
||||
import const.Indices
|
||||
import java.nio.ByteBuffer
|
||||
import javax.swing.JOptionPane
|
||||
|
||||
object NPCSpawnEncoder {
|
||||
|
||||
|
|
@ -25,6 +26,8 @@ object NPCSpawnEncoder {
|
|||
if (dataArray != null) {
|
||||
Rs2MapEditor.library.put(Indices.LANDSCAPES, "n${x}_${y}", dataArray, intArrayOf(0,0,0,0))
|
||||
Rs2MapEditor.library.update()
|
||||
JOptionPane.showMessageDialog(Rs2MapEditor.mapPanel, "NPCs written to cache. [✓]")
|
||||
Rs2MapEditor.npcsUpdated = false
|
||||
} else {
|
||||
System.err.println("Panic! Something went VERY wrong!")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ package const
|
|||
import cacheops.cache.Cache
|
||||
import cacheops.cache.CacheDelegate
|
||||
|
||||
val cache: Cache = CacheDelegate("K:\\RSPSDev\\2-009Scape-578\\Server\\data\\cache")
|
||||
val cache: Cache = CacheDelegate("/home/ceikry/IdeaProjects/rs09-remake/Server/data/cache/")
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package ext
|
|||
import java.nio.ByteBuffer
|
||||
|
||||
fun ByteBuffer.medium(): Int {
|
||||
return ((get().toInt() shl 16 and 0xff0000) + (get().toInt() shl 8 and 0xff00) + (get().toInt() and 0xff))
|
||||
return (((get().toInt() shl 16) and 0xff0000) + ((get().toInt() shl 8) and 0xff00) + (get().toInt() and 0xff))
|
||||
// return ((get().toInt() and 0xff) + (get().toInt() shl 8 and 0xff00) + )
|
||||
}
|
||||
|
||||
|
|
|
|||
22
src/main/kotlin/misc/CustomEventQueue.kt
Normal file
22
src/main/kotlin/misc/CustomEventQueue.kt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package misc
|
||||
|
||||
import java.awt.AWTEvent
|
||||
import java.awt.Event
|
||||
import java.awt.EventQueue
|
||||
import java.awt.Toolkit
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
class CustomEventQueue : EventQueue() {
|
||||
override fun dispatchEvent(event: AWTEvent?) {
|
||||
if(event is KeyEvent){
|
||||
GlobalKeybinds.handle(event)
|
||||
}
|
||||
super.dispatchEvent(event)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun install() {
|
||||
Toolkit.getDefaultToolkit().systemEventQueue.push(CustomEventQueue())
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/main/kotlin/misc/GlobalKeybinds.kt
Normal file
42
src/main/kotlin/misc/GlobalKeybinds.kt
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package misc
|
||||
|
||||
import cacheops.cache.definition.encoder.NPCSpawnEncoder
|
||||
import java.awt.Event
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
var ctrlPressed = false
|
||||
|
||||
object GlobalKeybinds{
|
||||
fun handle(event: KeyEvent){
|
||||
if(event.id == Event.KEY_PRESS){
|
||||
if(event.keyCode == KeyEvent.VK_CONTROL) {
|
||||
ctrlPressed = true
|
||||
}
|
||||
return
|
||||
}
|
||||
if(event.id == Event.KEY_RELEASE){
|
||||
if(event.keyCode == KeyEvent.VK_CONTROL) {
|
||||
ctrlPressed = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if(ctrlPressed){ //Handle keybinds that rely on control being pressed
|
||||
when(event.keyCode){
|
||||
|
||||
|
||||
KeyEvent.VK_S -> { //CTRL+S
|
||||
if(Rs2MapEditor.npcsUpdated){
|
||||
NPCSpawnEncoder.write(Rs2MapEditor.npcs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else when(event.keyCode){
|
||||
KeyEvent.VK_ESCAPE -> Rs2MapEditor.state = EditorState.NONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
package misc
|
||||
|
||||
import java.awt.Image
|
||||
import java.awt.event.MouseEvent
|
||||
import java.awt.event.MouseListener
|
||||
Loading…
Add table
Add a link
Reference in a new issue