Deeper integration into the rest

This commit is contained in:
ceikry 2023-03-12 12:37:38 -05:00
parent 7dbe904ce7
commit ce461278a9
21 changed files with 190 additions and 444 deletions

View file

@ -9,7 +9,7 @@ import javax.swing.*
import javax.swing.event.ChangeEvent
import javax.swing.table.DefaultTableModel
class DropTableEditor(val table: NPCDropTable) : JFrame("Editing ${if(table.ids.isNotBlank()) TableData.npcNames[table.ids.split(",")[0].toInt()] ?: "Unknown Table" else "None"}") {
class DropTableEditor(val table: NPCDropTable) : JFrame("Editing ${if(table.ids.isNotBlank()) TableData.getNPCName(table.ids.split(",")[0].toInt()) ?: "Unknown Table" else "None"}") {
val IDsField = JTextField()
val descriptionField = JTextField()
val mainModel = object : DefaultTableModel(){}
@ -263,6 +263,7 @@ class DropTableEditor(val table: NPCDropTable) : JFrame("Editing ${if(table.ids.
super.windowClosing(e)
}
})
addWindowFocusListener(EditorFocusListener(EditorType.DROP_TABLES))
pack()

View file

@ -1,5 +1,7 @@
import com.github.weisj.darklaf.LafManager
import com.github.weisj.darklaf.theme.OneDarkTheme
import javax.swing.*
import java.awt.event.*
object EditorConstants {
var BUILD_NUMBER = "1.5.3"
@ -7,15 +9,59 @@ object EditorConstants {
var DARK_MODE = true
var CONFIG_PATH = ""
var CACHE_PATH = ""
var VALID_FILES = arrayOf("drop_tables.json","npc_configs.json","item_configs.json", "shops.json", "object_configs.json", "npc_spawns.json", "ground_item_spawns.json")
var VALID_FILES = arrayOf("drop_tables.json","npc_configs.json","item_configs.json", "shops.json", "object_configs.json", "npc_spawns.json", "ground_spawns.json", "xteas.json")
var CREDITS = arrayOf(
"weisJ - darklaf look and feel themes http://github.com/weisj",
"ceikry - design and programming http://gitlab.com/ceikry"
"ceikry - design and programming http://gitlab.com/ceikry",
"woahscam - design and programming http://gitlab.com/woahscam"
)
fun updateTheme(){
if(EditorConstants.DARK_MODE) LafManager.install(OneDarkTheme()) else LafManager.install()
}
}
var FOCUSED_EDITOR: EditorType = EditorType.NONE
fun setFocusedEditor (type: EditorType) {
Logger.logInfo("Set focused editor to ${type.name}")
FOCUSED_EDITOR = type
}
fun saveFocusedEditor () {
when (FOCUSED_EDITOR) {
EditorType.NONE -> Logger.logInfo("NO EDITOR FOCUSED - NOT SAVING")
EditorType.SPAWNS -> {
if (Rs2MapEditor.npcsUpdated)
Editors.NPC_SPAWNS.data.save()
if (Rs2MapEditor.itemsUpdated)
Editors.ITEM_SPAWNS.data.save()
}
EditorType.ITEM_CONFIGS -> Editors.ITEM_CONFIGS.data.save()
EditorType.NPC_CONFIGS -> Editors.NPC_CONFIGS.data.save()
EditorType.OBJECT_CONFIGS -> Editors.OBJECT_CONFIGS.data.save()
EditorType.SHOPS -> Editors.SHOPS.data.save()
EditorType.DROP_TABLES -> Editors.DROP_TABLES.data.save()
}
Logger.logInfo("Saving ${FOCUSED_EDITOR.name}...")
JOptionPane.showMessageDialog(null, "Saved ${FOCUSED_EDITOR.name.toLowerCase().replace('_', ' ')}!")
}
}
class EditorFocusListener(val type: EditorType) : WindowFocusListener {
override fun windowLostFocus(e: WindowEvent) {}
override fun windowGainedFocus(e: WindowEvent) { EditorConstants.setFocusedEditor(type) }
}
enum class EditorType {
SPAWNS,
ITEM_CONFIGS,
NPC_CONFIGS,
OBJECT_CONFIGS,
SHOPS,
DROP_TABLES,
NONE
}

View file

@ -1,5 +1,6 @@
import com.github.weisj.darklaf.LafManager
import com.github.weisj.darklaf.theme.DarculaTheme
import com.displee.cache.CacheLibrary
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.FlowLayout
@ -7,6 +8,9 @@ import java.io.File
import java.util.*
import javax.swing.*
import javax.swing.table.DefaultTableModel
import cacheops.cache.definition.decoder.FloorUnderlayConfiguration
import cacheops.cache.definition.decoder.FloorOverlayConfiguration
import cacheops.cache.definition.decoder.MapTileParser
object MainScreen : JFrame("RS09 Thanos Tool ${EditorConstants.BUILD_NUMBER}") {
val dirChooser = object : JFileChooser(DataStore.LastConfigPath){
@ -51,6 +55,7 @@ object MainScreen : JFrame("RS09 Thanos Tool ${EditorConstants.BUILD_NUMBER}") {
if(response == JFileChooser.APPROVE_OPTION){
Logger.logInfo("Selected directory: ${dirChooser.selectedFile.absolutePath}")
EditorConstants.CONFIG_PATH = dirChooser.selectedFile.absolutePath
EditorConstants.CACHE_PATH = dirChooser.selectedFile.parent + "/cache"
showLoaded()
if(loadedModel.rowCount > 0) {
selectDir.isEnabled = false
@ -81,7 +86,7 @@ object MainScreen : JFrame("RS09 Thanos Tool ${EditorConstants.BUILD_NUMBER}") {
}
openNpcItemSpawns.addActionListener {
Rs2MapEditor.main(arrayOf())
Rs2MapEditor.open()
}
val showCredits = JButton("Show Credits")
@ -130,6 +135,9 @@ fun showLoaded(){
val files = File(EditorConstants.CONFIG_PATH).listFiles() ?: return
var cacheExists = File(EditorConstants.CACHE_PATH).listFiles().isNotEmpty()
val spawnGating = arrayOf(false, false, false)
for(file in files){
if(file.name in EditorConstants.VALID_FILES){
MainScreen.loadedModel.addRow(arrayOf(file.name))
@ -139,11 +147,43 @@ fun showLoaded(){
"item_configs" -> MainScreen.openItem.isEnabled = true.also { Editors.ITEM_CONFIGS.data.parse() }
"shops" -> MainScreen.openShops.isEnabled = true.also { Editors.SHOPS.data.parse() }
"object_configs" -> MainScreen.openObjects.isEnabled = true.also { Editors.OBJECT_CONFIGS.data.parse()}
"npc_spawns" -> MainScreen.openNpcItemSpawns.isEnabled = true.also { Editors.NPC_SPAWNS.data.parse(); Editors.ITEM_SPAWNS.data.parse() }
"npc_spawns" -> spawnGating[0] = true
"ground_spawns" -> spawnGating[1] = true
"xteas" -> spawnGating[2] = true
}
}
}
if (cacheExists && spawnGating[0] && spawnGating[1] && spawnGating[2]) {
try {
Editors.ITEM_SPAWNS.data.parse()
Editors.NPC_SPAWNS.data.parse()
const.configureCacheDelegate(EditorConstants.CACHE_PATH, EditorConstants.CONFIG_PATH + File.separator + "xteas.json")
Rs2MapEditor.library = CacheLibrary.create(EditorConstants.CACHE_PATH)
FloorOverlayConfiguration.init()
FloorUnderlayConfiguration.init()
MapTileParser.init()
Rs2MapEditor.underlayMap = FloorUnderlayConfiguration.floorUnderlays
Rs2MapEditor.overlayMap = FloorOverlayConfiguration.floorOverlays
MainScreen.openNpcItemSpawns.isEnabled = true
} catch (e: Exception) {
e.printStackTrace()
}
}
if (!MainScreen.openDrops.isEnabled)
MainScreen.openDrops.toolTipText = "Needs drop_tables.json."
if (!MainScreen.openNPC.isEnabled)
MainScreen.openNPC.toolTipText = "Needs npc_configs.json"
if (!MainScreen.openItem.isEnabled)
MainScreen.openItem.toolTipText = "Needs item_configs.json"
if (!MainScreen.openShops.isEnabled)
MainScreen.openShops.toolTipText = "Needs shops.json"
if (!MainScreen.openObjects.isEnabled)
MainScreen.openObjects.toolTipText = "Needs object_configs.json"
if (!MainScreen.openNpcItemSpawns.isEnabled)
MainScreen.openNpcItemSpawns.toolTipText = "Needs cache next to configs folder\nNeeds xteas.json\nNeeds npc_spawns.json\nNeeds ground_spawns.json"
MainScreen.pane.revalidate()
MainScreen.pane.repaint()
}

View file

@ -6,10 +6,7 @@ import cacheops.cache.definition.decoder.*
import com.displee.cache.CacheLibrary
import const.Image.RED_DOT
import const.Image.YELLOW_DOT
import const.cachePath
import misc.CustomEventQueue
import tools.ItemSearchTool
import tools.NPCSearchTool
import tools.Util
import ui.*
import java.awt.*
@ -19,12 +16,10 @@ import javax.swing.border.*
import kotlin.system.exitProcess
object Rs2MapEditor {
val library = CacheLibrary.create(cachePath)
var region = 12850
var npcs = TableData.npcSpawns[region]
var items = TableData.itemSpawns[region]
var sceneries = TileSceneryParser.parseRegion(region)
var sceneries = ArrayList<Scenery>()
val npcRows = ArrayList<NPCSpawnPanel.NPCRow>()
val itemRows = ArrayList<ItemSpawnPanel.ItemRow>()
var npcsUpdated = false
@ -34,21 +29,12 @@ object Rs2MapEditor {
var visualizeHeight = false
var drawGrid = true
var previousHeight = -1
lateinit var library: CacheLibrary
lateinit var mapPanel: MapPane
lateinit var npcPanel: NPCSpawnPanel
lateinit var itemPanel: ItemSpawnPanel
lateinit var infoPane: InfoPane
@JvmStatic
fun main(args: Array<String>) {
FloorUnderlayConfiguration.init()
FloorOverlayConfiguration.init()
MapTileParser.init()
underlayMap = FloorUnderlayConfiguration.floorUnderlays
overlayMap = FloorOverlayConfiguration.floorOverlays
MainFrame()
}
var cellX = 20
var cellY = 20
@ -81,10 +67,20 @@ object Rs2MapEditor {
lateinit var itemRespawnInput: JTextField
lateinit var itemAmountInput: JTextField
lateinit var infoScrollPane: ScrollPane2
lateinit var editorWin: EditorWindow
var state = EditorState.NONE
var editorInit = false
class MainFrame : JFrame("2009scape Map Viewer v1.0") {
init {
fun open() {
if (!editorInit) {
editorWin = EditorWindow().also { it.initGui() }
loadRegion(12850)
}
editorWin.isVisible = true
}
class EditorWindow : JFrame("Zaros Spawn Editor") {
fun initGui() {
val statusBar = JPanel(FlowLayout(FlowLayout.LEFT))
statusBar.border = CompoundBorder(
LineBorder(Color.DARK_GRAY),
@ -127,9 +123,12 @@ object Rs2MapEditor {
statusLabel.text = "-"
setLocationRelativeTo(null)
isResizable = false
isVisible = true
isVisible = false
CustomEventQueue.install()
addWindowFocusListener(EditorFocusListener(EditorType.SPAWNS))
editorInit = true
}
}
@ -293,11 +292,18 @@ object Rs2MapEditor {
add(MoveRegionButton("EAST", 1, 0))
add(MoveRegionButton("WEST", -1, 0))
add(JSeparator(JSeparator.VERTICAL))
var saveButton = JButton("Save")
saveButton.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { EditorConstants.saveFocusedEditor() }
})
add(saveButton)
add(JSeparator(JSeparator.VERTICAL))
add(JLabel("Plane: "))
add(PlaneButton(0))
add(PlaneButton(1))
add(PlaneButton(2))
add(PlaneButton(3))
}
}

View file

@ -165,6 +165,7 @@ class ShopEdit(val shopID: Int) : JFrame("Edit Shop") {
val scrollPane = JScrollPane(itemTable)
add(scrollPane,BorderLayout.SOUTH)
addWindowFocusListener(EditorFocusListener(EditorType.SHOPS))
pack()
isVisible = false
@ -172,8 +173,8 @@ class ShopEdit(val shopID: Int) : JFrame("Edit Shop") {
fun open(){
for(item in shop?.stock ?: ArrayList()){
model.addRow(arrayOf(TableData.itemNames[item.id] ?: "unknown",item.id,item.amount,item.infinite, item.restockTime))
model.addRow(arrayOf(TableData.getItemName(item.id, false),item.id,item.amount,item.infinite, item.restockTime))
}
isVisible = true
}
}
}

View file

@ -96,6 +96,7 @@ class ShopList : JFrame("RS09 Shop Editor") {
val scrollPane = JScrollPane(itemTable)
add(scrollPane, BorderLayout.SOUTH)
addWindowFocusListener(EditorFocusListener(EditorType.SHOPS))
pack()
isVisible = false
}
@ -128,4 +129,4 @@ class ShopList : JFrame("RS09 Shop Editor") {
isVisible = true
}
}
}
}

View file

@ -6,6 +6,8 @@ import java.io.FileWriter
import java.io.IOException
import java.lang.StringBuilder
import javax.script.ScriptEngineManager
import cacheops.cache.definition.decoder.ItemParser
import cacheops.cache.definition.decoder.NPCParser
object TableData {
class Shop(var id: Int,var title: String,var stock: ArrayList<Item>,var npcs: String,var currency: Int,var general_store: Boolean,var high_alch: Boolean,var forceShared: Boolean)
@ -27,15 +29,22 @@ object TableData {
var itemConfigs = ArrayList<JSONObject>()
val shops = hashMapOf<Int,Shop>()
fun getItemName(id: Int): String{
return when(id){
31 -> "RDT Slot"
1 -> "Clue Scroll (easy)"
5733 -> "Clue Scroll (med)"
12070 -> "Clue Scroll (hard)"
0 -> "Nothing"
else -> itemNames[id] ?: "Unknown"
}
fun getItemName(id: Int, dropTable: Boolean = true): String{
if (dropTable) {
return when(id){
31 -> "RDT Slot"
1 -> "Clue Scroll (easy)"
5733 -> "Clue Scroll (med)"
12070 -> "Clue Scroll (hard)"
0 -> "Nothing"
else -> itemNames[id] ?: ItemParser.forId(id)?.name ?: "Undefined"
}
}
else return itemNames[id] ?: ItemParser.forId(id)?.name ?: "Undefined"
}
fun getNPCName(id: Int) : String {
return npcNames[id] ?: NPCParser.getDef(id)?.name ?: "Undefined"
}
}

View file

@ -107,6 +107,13 @@ class TableEditor(val editor: Editors) : JFrame("Editing ${editor.name.replace("
else -> ArrayList<JSONObject>()
}
val type = when (editor) {
Editors.NPC_CONFIGS -> EditorType.NPC_CONFIGS
Editors.ITEM_CONFIGS -> EditorType.ITEM_CONFIGS
Editors.OBJECT_CONFIGS -> EditorType.OBJECT_CONFIGS
else -> EditorType.NONE
}
if(editor == Editors.OBJECT_CONFIGS){
model.addColumn("ids")
model.addColumn("examine")
@ -183,6 +190,7 @@ class TableEditor(val editor: Editors) : JFrame("Editing ${editor.name.replace("
}
})
addWindowFocusListener(EditorFocusListener(type))
EditorConstants.updateTheme()
pack()
}
@ -236,4 +244,4 @@ class TableEditor(val editor: Editors) : JFrame("Editing ${editor.name.replace("
else -> ArrayList()
}
}
}
}

View file

@ -91,6 +91,7 @@ class TableList : JFrame("RS09 Drop Table Editor") {
val scrollPane = JScrollPane(itemTable)
add(scrollPane, BorderLayout.SOUTH)
addWindowFocusListener(EditorFocusListener(EditorType.DROP_TABLES))
pack()
isVisible = false
}
@ -114,7 +115,7 @@ class TableList : JFrame("RS09 Drop Table Editor") {
}
SwingUtilities.invokeLater {
for (table in TableData.tables) {
model.addRow(arrayOf<Any>(if(table.ids.isNotBlank()) TableData.npcNames[table.ids.split(",")[0].toInt()] ?: "Unknown Table" else "None"))
model.addRow(arrayOf<Any>(if(table.ids.isNotBlank()) TableData.getNPCName(table.ids.split(",")[0].toInt()) else "None"))
}
isVisible = true
populated = true
@ -123,4 +124,4 @@ class TableList : JFrame("RS09 Drop Table Editor") {
isVisible = true
}
}
}
}

View file

@ -1,53 +1,13 @@
package cacheops.cache.definition.decoder
import Rs2MapEditor
import cacheops.cache.definition.data.ItemDefinition
import const.cache
import ext.unsignedShort
import java.nio.ByteBuffer
val itemDecoder = ItemDecoder(cache)
class GroundItemDecoder {
fun decode(data: ByteArray): ArrayList<Item> {
val buffer = ByteBuffer.wrap(data)
val list = ArrayList<Item>()
while (buffer.hasRemaining()) {
val coords = buffer.unsignedShort()
val lz = coords shr 14
val lx = (coords shr 7) and 0x3f
val ly = coords and 0x3f
val itemID = buffer.unsignedShort()
val respawnTime = buffer.unsignedShort()
val amount = buffer.int
list.add(Item(itemID, lx, ly, lz, respawnTime, amount))
}
return list
object ItemParser {
var decoder: ItemDecoder? = null
fun forId (id: Int): ItemDefinition? {
if (decoder == null && cache == null) return null
if (decoder == null && cache != null) decoder = ItemDecoder(cache!!)
return decoder?.forId(id)
}
}
object GroundItemSpawnParser {
fun parseItemSpawns(regionId: Int): ArrayList<Item> {
val x = (regionId shr 8) and 0xFF
val y = regionId and 0xFF
val groundItemData = Rs2MapEditor.library.data(5, "i${x}_${y}")
if (groundItemData != null && groundItemData.isNotEmpty()) {
return GroundItemDecoder().decode(groundItemData)
}
return ArrayList()
}
}
class Item(val id: Int, val x: Int, val y: Int, val plane: Int, val respawnTime: Int, val amount: Int) {
val definition: ItemDefinition = itemDecoder.forId(id)
}

View file

@ -1,48 +1,15 @@
package cacheops.cache.definition.decoder
import Rs2MapEditor
import cacheops.cache.definition.data.NPCDefinition
import const.cache
import ext.unsignedShort
import java.nio.ByteBuffer
val decoder = NPCDecoder(cache, true)
class NPCSpawnDecoder {
object NPCParser {
var decoder: NPCDecoder? = null
fun decode(data: ByteArray): ArrayList<NPC> {
val buffer = ByteBuffer.wrap(data)
val list = ArrayList<NPC>()
while (buffer.hasRemaining()) {
val coords = buffer.unsignedShort()
val lz = coords shr 14
val lx = (coords shr 7) and 0x3f
val ly = coords and 0x3f
val npcID = buffer.unsignedShort()
list.add(NPC(npcID, lx, ly, lz))
}
return list
fun getDef (id: Int) : NPCDefinition? {
if (decoder == null && cache == null) return null
if (decoder == null && cache != null) decoder = NPCDecoder(cache!!, true)
return decoder?.forId(id)
}
}
object NPCSpawnParser {
fun parseNPCSpawns(regionId: Int): ArrayList<NPC> {
val x = (regionId shr 8) and 0xFF
val y = regionId and 0xFF
val npcSpawnData = Rs2MapEditor.library.data(5, "n${x}_${y}")
if (npcSpawnData != null && npcSpawnData.isNotEmpty()) {
return NPCSpawnDecoder().decode(npcSpawnData)
}
return ArrayList()
}
}
class NPC(val id: Int, val x: Int, val y: Int, val plane: Int) {
val definition: NPCDefinition = decoder.forId(id)
}

View file

@ -7,7 +7,6 @@ import ext.getBigSmart
import ext.getSmart
import java.nio.ByteBuffer
val objectDecoder = ObjectDecoder(cache, true, false)
object TileSceneryParser {
fun parseRegion(id: Int): ArrayList<Scenery>{
@ -53,7 +52,8 @@ object TileSceneryParser {
}
}
var objectDecoder: ObjectDecoder? = null
class Scenery(val id: Int, val x: Int, val y: Int, val plane: Int, val rotation: Int, val type: Int){
val definition = objectDecoder.forId(id)
val definition = objectDecoder?.forId(id) ?: if (cache != null) ObjectDecoder(cache!!, true, false).also { objectDecoder = it }.forId(id) else null
}

View file

@ -1,48 +0,0 @@
package cacheops.cache.definition.encoder
import Rs2MapEditor
import cacheops.cache.definition.decoder.Item
import const.Indices
import java.nio.ByteBuffer
import javax.swing.JOptionPane
object GroundItemEncoder {
fun write(item: ArrayList<Item>) {
// Setup buffer | Determine capacity (ArrayList size * (short2 + short2 + short2 + int4))
val buffer = ByteBuffer.allocate(item.size * 10)
// Put data to buffer
item.forEach {
val formattedCoord = (it.plane shl 14) or (it.x shl 7) or it.y
buffer.putShort(formattedCoord.toShort())
buffer.putShort(it.id.toShort())
buffer.putShort(it.respawnTime.toShort())
buffer.putInt(it.amount)
}
// Convert buffer to byte array
val dataArray = buffer.array()
// Get region information
val region = Rs2MapEditor.region
val x = (region shr 8) and 0xFF
val y = region and 0xFF
// Put region data
if (dataArray != null) {
Rs2MapEditor.library.put(Indices.LANDSCAPES, "i${x}_${y}", dataArray, intArrayOf(0,0,0,0))
Rs2MapEditor.library.update()
JOptionPane.showMessageDialog(Rs2MapEditor.mapPanel, "Items written to cache [✓]")
Rs2MapEditor.itemsUpdated = false
} else {
System.err.println("Panic! Something went VERY wrong!")
}
}
}
fun main() {
val itemList = arrayListOf<Item>(Item(946, 24, 2,0, 6, 1))
GroundItemEncoder.write(itemList)
}

View file

@ -1,35 +0,0 @@
package cacheops.cache.definition.encoder
import Rs2MapEditor
import cacheops.cache.definition.decoder.NPC
import const.Indices
import java.nio.ByteBuffer
import javax.swing.JOptionPane
object NPCSpawnEncoder {
fun write(npc: ArrayList<NPC>) {
val buffer = ByteBuffer.allocate(npc.size * 4)
npc.forEach {
val formattedCoord = (it.plane shl 14) or (it.x shl 7) or it.y
buffer.putShort(formattedCoord.toShort())
buffer.putShort(it.id.toShort())
}
val dataArray = buffer.array()
val region = Rs2MapEditor.region
val x = (region shr 8) and 0xFF
val y = region and 0xFF
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!")
}
}
}

View file

@ -3,6 +3,10 @@ package const
import cacheops.cache.Cache
import cacheops.cache.CacheDelegate
val cachePath = "/home/ceikry/IdeaProjects/2009scape/Server/data/cache"
val xteaJson = "/home/ceikry/IdeaProjects/2009scape/Server/data/configs/xteas.json"
val cache: Cache = CacheDelegate(cachePath)
var cache: Cache? = null
var xteaJson = ""
fun configureCacheDelegate (pathToCache: String, pathToXteas: String) {
cache = CacheDelegate(pathToCache)
xteaJson = pathToXteas
}

View file

@ -1,7 +1,5 @@
package misc
import cacheops.cache.definition.encoder.GroundItemEncoder
import cacheops.cache.definition.encoder.NPCSpawnEncoder
import java.awt.Event
import java.awt.event.KeyEvent
import tools.*
@ -26,32 +24,29 @@ object GlobalKeybinds{
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)
Editors.NPC_SPAWNS.data.save()
}
if(Rs2MapEditor.itemsUpdated){
//GroundItemEncoder.write(Rs2MapEditor.items)
Editors.ITEM_SPAWNS.data.save()
}
EditorConstants.saveFocusedEditor()
}
KeyEvent.VK_UP -> {
if (EditorConstants.FOCUSED_EDITOR != EditorType.SPAWNS) return
var newRegion = Util.getRegion (Rs2MapEditor.region, 0, 1)
Rs2MapEditor.loadRegion(newRegion)
}
KeyEvent.VK_DOWN -> {
var newRegion = Util.getRegion (Rs2MapEditor.region, 0, -1)
if (EditorConstants.FOCUSED_EDITOR != EditorType.SPAWNS) return
Rs2MapEditor.loadRegion(newRegion)
}
KeyEvent.VK_LEFT -> {
if (EditorConstants.FOCUSED_EDITOR != EditorType.SPAWNS) return
var newRegion = Util.getRegion (Rs2MapEditor.region, -1, 0)
Rs2MapEditor.loadRegion(newRegion)
}
KeyEvent.VK_RIGHT -> {
if (EditorConstants.FOCUSED_EDITOR != EditorType.SPAWNS) return
var newRegion = Util.getRegion (Rs2MapEditor.region, 1, 0)
Rs2MapEditor.loadRegion(newRegion)
}

View file

@ -1,101 +0,0 @@
package tools
import cacheops.cache.definition.decoder.decoder
import cacheops.cache.definition.decoder.itemDecoder
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.event.KeyEvent
import java.awt.event.KeyListener
import java.awt.event.MouseEvent
import java.awt.event.MouseListener
import java.util.*
import java.util.regex.PatternSyntaxException
import javax.swing.*
import javax.swing.table.DefaultTableCellRenderer
import javax.swing.table.DefaultTableModel
import javax.swing.table.TableRowSorter
object ItemSearchTool : JFrame("Item Search") {
var model = DefaultTableModel()
var searchField = JTextField()
var sorter = TableRowSorter(model)
var cellRenderer = DefaultTableCellRenderer()
var populated = false
var caller: ((Int,String) -> Unit)? = null
private fun filter() {
var rf: RowFilter<DefaultTableModel?, Any?>? = null
//If current expression doesn't parse, don't update.
rf = try {
RowFilter.regexFilter(searchField.text.capitalize(), 1)
} catch (e: PatternSyntaxException) {
return
}
sorter.rowFilter = rf
}
fun open() {
if (!populated) {
SwingUtilities.invokeLater {
for (i in 0..15431) {
model.addRow(arrayOf(i, itemDecoder.forId(i).name))
}
isVisible = true
populated = true
}
} else {
isVisible = true
}
}
init {
layout = BorderLayout()
cellRenderer.toolTipText = "Double-Click to select."
val searchPanel = JPanel()
val searchLabel = JLabel("Search for NPC:")
searchField.preferredSize = Dimension(100, 20)
searchPanel.add(searchLabel)
searchPanel.add(searchField)
add(searchPanel, BorderLayout.NORTH)
setLocationRelativeTo(null)
val itemTable: JTable = object : JTable(model) {
override fun editCellAt(i: Int, i1: Int, eventObject: EventObject): Boolean {
return false
}
}
model.addColumn("ID")
model.addColumn("Name")
itemTable.rowSorter = sorter
itemTable.columnModel.getColumn(0).maxWidth = 55
itemTable.columnModel.getColumn(0).cellRenderer = cellRenderer
itemTable.columnModel.getColumn(1).cellRenderer = cellRenderer
itemTable.addMouseListener(object : MouseListener {
override fun mouseClicked(mouseEvent: MouseEvent) {
if (mouseEvent.clickCount == 2) {
val table = mouseEvent.source as JTable
val row = table.selectedRow
val selectedID = table.getValueAt(row,0).toString().toInt()
val selectedName = table.getValueAt(row,1).toString()
caller?.invoke(selectedID,selectedName)
isVisible = false
}
}
override fun mousePressed(mouseEvent: MouseEvent) {}
override fun mouseReleased(mouseEvent: MouseEvent) {}
override fun mouseEntered(mouseEvent: MouseEvent) {}
override fun mouseExited(mouseEvent: MouseEvent) {}
})
searchField.addKeyListener(object : KeyListener {
override fun keyTyped(keyEvent: KeyEvent) {
filter()
}
override fun keyPressed(keyEvent: KeyEvent) {}
override fun keyReleased(keyEvent: KeyEvent) {}
})
val scrollPane = JScrollPane(itemTable)
add(scrollPane, BorderLayout.SOUTH)
pack()
isVisible = false
}
}

View file

@ -1,100 +0,0 @@
package tools
import cacheops.cache.definition.decoder.decoder
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.event.KeyEvent
import java.awt.event.KeyListener
import java.awt.event.MouseEvent
import java.awt.event.MouseListener
import java.util.*
import java.util.regex.PatternSyntaxException
import javax.swing.*
import javax.swing.table.DefaultTableCellRenderer
import javax.swing.table.DefaultTableModel
import javax.swing.table.TableRowSorter
object NPCSearchTool : JFrame("NPC Search") {
var model = DefaultTableModel()
var searchField = JTextField()
var sorter = TableRowSorter(model)
var cellRenderer = DefaultTableCellRenderer()
var populated = false
var caller: ((Int,String) -> Unit)? = null
private fun filter() {
var rf: RowFilter<DefaultTableModel?, Any?>? = null
//If current expression doesn't parse, don't update.
rf = try {
RowFilter.regexFilter(searchField.text.capitalize(), 1)
} catch (e: PatternSyntaxException) {
return
}
sorter.rowFilter = rf
}
fun open() {
if (!populated) {
SwingUtilities.invokeLater {
for (i in 0..9422) {
model.addRow(arrayOf(i, decoder.forId(i).name))
}
isVisible = true
populated = true
}
} else {
isVisible = true
}
}
init {
layout = BorderLayout()
cellRenderer.toolTipText = "Double-Click to select."
val searchPanel = JPanel()
val searchLabel = JLabel("Search for NPC:")
searchField.preferredSize = Dimension(100, 20)
searchPanel.add(searchLabel)
searchPanel.add(searchField)
add(searchPanel, BorderLayout.NORTH)
setLocationRelativeTo(null)
val npcTable: JTable = object : JTable(model) {
override fun editCellAt(i: Int, i1: Int, eventObject: EventObject): Boolean {
return false
}
}
model.addColumn("ID")
model.addColumn("Name")
npcTable.rowSorter = sorter
npcTable.columnModel.getColumn(0).maxWidth = 55
npcTable.columnModel.getColumn(0).cellRenderer = cellRenderer
npcTable.columnModel.getColumn(1).cellRenderer = cellRenderer
npcTable.addMouseListener(object : MouseListener {
override fun mouseClicked(mouseEvent: MouseEvent) {
if (mouseEvent.clickCount == 2) {
val table = mouseEvent.source as JTable
val row = table.selectedRow
val selectedID = table.getValueAt(row,0).toString().toInt()
val selectedName = table.getValueAt(row,1).toString()
caller?.invoke(selectedID,selectedName)
isVisible = false
}
}
override fun mousePressed(mouseEvent: MouseEvent) {}
override fun mouseReleased(mouseEvent: MouseEvent) {}
override fun mouseEntered(mouseEvent: MouseEvent) {}
override fun mouseExited(mouseEvent: MouseEvent) {}
})
searchField.addKeyListener(object : KeyListener {
override fun keyTyped(keyEvent: KeyEvent) {
filter()
}
override fun keyPressed(keyEvent: KeyEvent) {}
override fun keyReleased(keyEvent: KeyEvent) {}
})
val scrollPane = JScrollPane(npcTable)
add(scrollPane, BorderLayout.SOUTH)
pack()
isVisible = false
}
}

View file

@ -1,6 +1,5 @@
package ui
import cacheops.cache.definition.decoder.Item
import const.Image
import misc.ImgButton
import java.awt.BorderLayout
@ -103,7 +102,7 @@ class ItemSpawnPanel : JPanel() {
val botPanel = JPanel(FlowLayout())
val deleteButton = ImgButton(Image.DELETE_HI, Image.DELTE_LO)
topPanel.add(JLabel("${TableData.itemNames[item.id]} [${item.id}]"))
topPanel.add(JLabel("${TableData.getItemName(item.id, false)} [${item.id}]"))
topPanel.add(deleteButton)
midPanel.add(JLabel("{${item.location.x},${item.location.y},${item.location.z}}"))
botPanel.add(JLabel("AMT: ${item.amount} \uD83D\uDD64 ${item.respawnTicks}"))

View file

@ -5,9 +5,7 @@ import EditorState
import Rs2MapEditor
import TableData
import cacheops.cache.definition.data.MapTile
import cacheops.cache.definition.decoder.Item
import cacheops.cache.definition.decoder.MapTileParser
import cacheops.cache.definition.decoder.NPC
import cacheops.cache.definition.decoder.Scenery
import const.Image
import tools.Util
@ -38,12 +36,7 @@ class MapCell : JPanel() {
MapTileParser.coordinateX(
Rs2MapEditor.selectedPointY
)
}] | " +
"Viewing Underlay: ${
MapTileParser.definition.getTile(
Rs2MapEditor.selectedPointX,
Rs2MapEditor.selectedPointY, 0).underlayId} | " +
"Selected Underlay: ${if (Rs2MapEditor.selectedUnderlayId == null) "<font color='red'>No underlay selected!</font>" else "${Rs2MapEditor.selectedUnderlayId}"}</html>"
}]"
defaultBackground = background
if(Rs2MapEditor.state == EditorState.SET_UNDERLAY || Rs2MapEditor.state == EditorState.NONE) {
background = Color.BLUE
@ -194,7 +187,7 @@ class MapCell : JPanel() {
for (npc in npcsHere) {
string.append("<tr style=\"text-align:center\">")
string.append("<td>${npc.id}</td>")
string.append("<td>${TableData.npcNames[npc.id]}</td>")
string.append("<td>${TableData.getNPCName(npc.id)}</td>")
string.append("</tr>")
}
string.append("</tbody></table><br/>")
@ -212,7 +205,7 @@ class MapCell : JPanel() {
for (item in itemsHere) {
string.append("<tr style=\"text-align:center\">")
string.append("<td>${item.id}</td>")
string.append("<td>${TableData.itemNames[item.id]}[${item.amount}] \uD83D\uDD64${item.respawnTicks}</td>")
string.append("<td>${TableData.getItemName(item.id, false)}[${item.amount}] \uD83D\uDD64${item.respawnTicks}</td>")
string.append("</tr>")
}
string.append("</tbody></table><br/>")
@ -222,9 +215,9 @@ class MapCell : JPanel() {
string.append("<h3>Scenery Info</h3>")
for(sc in scenery) {
if (sc.id != -1) {
string.append("${sc.definition.name} [ID: ${sc.id}]<br/>")
string.append("Type: ${sc.type}<br/>")
string.append("Rotation: ${sc.rotation}<br/>")
string.append("${sc?.definition?.name} [ID: ${sc?.id}]<br/>")
string.append("Type: ${sc?.type}<br/>")
string.append("Rotation: ${sc?.rotation}<br/>")
string.append("---------------------<br/>")
}
}
@ -286,7 +279,7 @@ class MapCell : JPanel() {
pointX1 = 1; pointY1 = this.height - 1; pointX2 = this.width - 1; pointY2 = this.height - 1
}
}
if (sc.definition.interactive == 1 && sc.type == 0) {
if (sc?.definition?.interactive == 1 && sc?.type == 0) {
g.color = Color.RED
}
g.drawLine(pointX1, pointY1, pointX2, pointY2)
@ -311,7 +304,7 @@ class MapCell : JPanel() {
xArray = intArrayOf(1,1,1,this.width - 1); yArray = intArrayOf(1,this.height - 1, this.height - 1, this.height - 1)
}
}
if (sc.definition.interactive == 1) {
if (sc?.definition?.interactive == 1) {
g.color = Color.RED
}
g.drawPolyline(xArray, yArray, nPoints)

View file

@ -3,7 +3,6 @@ package ui
import EditorState
import Rs2MapEditor
import TableData
import cacheops.cache.definition.decoder.NPC
import const.Image
import misc.ImgButton
import tools.Util
@ -74,7 +73,7 @@ class NPCSpawnPanel : JPanel() {
}
else if (term.isNotEmpty()) {
for (row in rows) {
var name = TableData.npcNames[row.npc.id]?.toLowerCase() ?: "null"
var name = TableData.getNPCName(row.npc.id)?.toLowerCase() ?: "null"
if (!name.contains(term, ignoreCase = true) && !term.contains(name, ignoreCase = true) && term.toLowerCase() != name) {
removedRows.add(row)
Rs2MapEditor.npcRows.remove(row)
@ -163,7 +162,7 @@ class NPCSpawnPanel : JPanel() {
init {
layout = BorderLayout()
val topPanel = JPanel(FlowLayout())
topPanel.add(JLabel("${TableData.npcNames[npc.id]}[${npc.id}]"))
topPanel.add(JLabel("${TableData.getNPCName(npc.id)}[${npc.id}]"))
val deleteButton = ImgButton(Image.DELETE_HI, Image.DELTE_LO)
topPanel.add(deleteButton)