From ce461278a94e0ee9fe26826c02830efdc7dbb27d Mon Sep 17 00:00:00 2001 From: ceikry Date: Sun, 12 Mar 2023 12:37:38 -0500 Subject: [PATCH] Deeper integration into the rest --- src/main/kotlin/DropTableEditor.kt | 3 +- src/main/kotlin/EditorConstants.kt | 52 ++++++++- src/main/kotlin/MainScreen.kt | 44 +++++++- src/main/kotlin/Rs2MapEditor.kt | 44 ++++---- src/main/kotlin/ShopEdit.kt | 5 +- src/main/kotlin/ShopList.kt | 3 +- src/main/kotlin/TableData.kt | 27 +++-- src/main/kotlin/TableEditor.kt | 10 +- src/main/kotlin/TableList.kt | 5 +- .../definition/decoder/GroundItemDecoder.kt | 52 ++------- .../definition/decoder/NPCSpawnDecoder.kt | 45 ++------ .../definition/decoder/TileSceneryParser.kt | 4 +- .../definition/encoder/GroundItemEncoder.kt | 48 --------- .../definition/encoder/NPCSpawnEncoder.kt | 35 ------ src/main/kotlin/const/Misc.kt | 10 +- src/main/kotlin/misc/GlobalKeybinds.kt | 15 +-- src/main/kotlin/tools/ItemSearchTool.kt | 101 ------------------ src/main/kotlin/tools/NPCSearchTool.kt | 100 ----------------- src/main/kotlin/ui/ItemSpawnPanel.kt | 3 +- src/main/kotlin/ui/MapCell.kt | 23 ++-- src/main/kotlin/ui/NPCSpawnPanel.kt | 5 +- 21 files changed, 190 insertions(+), 444 deletions(-) delete mode 100644 src/main/kotlin/tools/ItemSearchTool.kt delete mode 100644 src/main/kotlin/tools/NPCSearchTool.kt diff --git a/src/main/kotlin/DropTableEditor.kt b/src/main/kotlin/DropTableEditor.kt index 1e015c2..2106473 100644 --- a/src/main/kotlin/DropTableEditor.kt +++ b/src/main/kotlin/DropTableEditor.kt @@ -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() diff --git a/src/main/kotlin/EditorConstants.kt b/src/main/kotlin/EditorConstants.kt index 5db7189..20be945 100644 --- a/src/main/kotlin/EditorConstants.kt +++ b/src/main/kotlin/EditorConstants.kt @@ -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() } -} \ No newline at end of file + + 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 +} diff --git a/src/main/kotlin/MainScreen.kt b/src/main/kotlin/MainScreen.kt index 1a8c44c..ca71c15 100644 --- a/src/main/kotlin/MainScreen.kt +++ b/src/main/kotlin/MainScreen.kt @@ -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() } diff --git a/src/main/kotlin/Rs2MapEditor.kt b/src/main/kotlin/Rs2MapEditor.kt index dae786f..064335a 100644 --- a/src/main/kotlin/Rs2MapEditor.kt +++ b/src/main/kotlin/Rs2MapEditor.kt @@ -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() val npcRows = ArrayList() val itemRows = ArrayList() 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) { - 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)) + } } diff --git a/src/main/kotlin/ShopEdit.kt b/src/main/kotlin/ShopEdit.kt index 80376d7..5cad559 100644 --- a/src/main/kotlin/ShopEdit.kt +++ b/src/main/kotlin/ShopEdit.kt @@ -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 } -} \ No newline at end of file +} diff --git a/src/main/kotlin/ShopList.kt b/src/main/kotlin/ShopList.kt index 0ae1e1c..1358378 100644 --- a/src/main/kotlin/ShopList.kt +++ b/src/main/kotlin/ShopList.kt @@ -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 } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/TableData.kt b/src/main/kotlin/TableData.kt index eaa1f5f..f5a73d2 100644 --- a/src/main/kotlin/TableData.kt +++ b/src/main/kotlin/TableData.kt @@ -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,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() val shops = hashMapOf() - 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" } } diff --git a/src/main/kotlin/TableEditor.kt b/src/main/kotlin/TableEditor.kt index cdd44b6..2717810 100644 --- a/src/main/kotlin/TableEditor.kt +++ b/src/main/kotlin/TableEditor.kt @@ -107,6 +107,13 @@ class TableEditor(val editor: Editors) : JFrame("Editing ${editor.name.replace(" else -> ArrayList() } + 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() } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/TableList.kt b/src/main/kotlin/TableList.kt index e8ec639..eead918 100644 --- a/src/main/kotlin/TableList.kt +++ b/src/main/kotlin/TableList.kt @@ -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(if(table.ids.isNotBlank()) TableData.npcNames[table.ids.split(",")[0].toInt()] ?: "Unknown Table" else "None")) + model.addRow(arrayOf(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 } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/cacheops/cache/definition/decoder/GroundItemDecoder.kt b/src/main/kotlin/cacheops/cache/definition/decoder/GroundItemDecoder.kt index 6e36764..58712ef 100644 --- a/src/main/kotlin/cacheops/cache/definition/decoder/GroundItemDecoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/decoder/GroundItemDecoder.kt @@ -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 { - - val buffer = ByteBuffer.wrap(data) - val list = ArrayList() - - 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 { - 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) -} \ No newline at end of file diff --git a/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt b/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt index bd482ee..c32ef76 100644 --- a/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt @@ -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 { - - val buffer = ByteBuffer.wrap(data) - val list = ArrayList() - - 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 { - 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) -} \ No newline at end of file diff --git a/src/main/kotlin/cacheops/cache/definition/decoder/TileSceneryParser.kt b/src/main/kotlin/cacheops/cache/definition/decoder/TileSceneryParser.kt index 0aee4f5..53884e5 100644 --- a/src/main/kotlin/cacheops/cache/definition/decoder/TileSceneryParser.kt +++ b/src/main/kotlin/cacheops/cache/definition/decoder/TileSceneryParser.kt @@ -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{ @@ -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 } diff --git a/src/main/kotlin/cacheops/cache/definition/encoder/GroundItemEncoder.kt b/src/main/kotlin/cacheops/cache/definition/encoder/GroundItemEncoder.kt index 03bafe1..e69de29 100644 --- a/src/main/kotlin/cacheops/cache/definition/encoder/GroundItemEncoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/encoder/GroundItemEncoder.kt @@ -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) { - - // 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(946, 24, 2,0, 6, 1)) - GroundItemEncoder.write(itemList) -} \ No newline at end of file diff --git a/src/main/kotlin/cacheops/cache/definition/encoder/NPCSpawnEncoder.kt b/src/main/kotlin/cacheops/cache/definition/encoder/NPCSpawnEncoder.kt index f3a0ee2..e69de29 100644 --- a/src/main/kotlin/cacheops/cache/definition/encoder/NPCSpawnEncoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/encoder/NPCSpawnEncoder.kt @@ -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) { - 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!") - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/const/Misc.kt b/src/main/kotlin/const/Misc.kt index 35285ca..cffcf16 100644 --- a/src/main/kotlin/const/Misc.kt +++ b/src/main/kotlin/const/Misc.kt @@ -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 +} diff --git a/src/main/kotlin/misc/GlobalKeybinds.kt b/src/main/kotlin/misc/GlobalKeybinds.kt index 3fd4446..c90cfad 100644 --- a/src/main/kotlin/misc/GlobalKeybinds.kt +++ b/src/main/kotlin/misc/GlobalKeybinds.kt @@ -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) } diff --git a/src/main/kotlin/tools/ItemSearchTool.kt b/src/main/kotlin/tools/ItemSearchTool.kt deleted file mode 100644 index f9cd65c..0000000 --- a/src/main/kotlin/tools/ItemSearchTool.kt +++ /dev/null @@ -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? = 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 - } -} \ No newline at end of file diff --git a/src/main/kotlin/tools/NPCSearchTool.kt b/src/main/kotlin/tools/NPCSearchTool.kt deleted file mode 100644 index 8747561..0000000 --- a/src/main/kotlin/tools/NPCSearchTool.kt +++ /dev/null @@ -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? = 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 - } -} \ No newline at end of file diff --git a/src/main/kotlin/ui/ItemSpawnPanel.kt b/src/main/kotlin/ui/ItemSpawnPanel.kt index 80d1db6..c15bacd 100644 --- a/src/main/kotlin/ui/ItemSpawnPanel.kt +++ b/src/main/kotlin/ui/ItemSpawnPanel.kt @@ -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}")) diff --git a/src/main/kotlin/ui/MapCell.kt b/src/main/kotlin/ui/MapCell.kt index f054e79..f95e1ec 100644 --- a/src/main/kotlin/ui/MapCell.kt +++ b/src/main/kotlin/ui/MapCell.kt @@ -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) "No underlay selected!" else "${Rs2MapEditor.selectedUnderlayId}"}" + }]" 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("") string.append("${npc.id}") - string.append("${TableData.npcNames[npc.id]}") + string.append("${TableData.getNPCName(npc.id)}") string.append("") } string.append("
") @@ -212,7 +205,7 @@ class MapCell : JPanel() { for (item in itemsHere) { string.append("") string.append("${item.id}") - string.append("${TableData.itemNames[item.id]}[${item.amount}] \uD83D\uDD64${item.respawnTicks}") + string.append("${TableData.getItemName(item.id, false)}[${item.amount}] \uD83D\uDD64${item.respawnTicks}") string.append("") } string.append("
") @@ -222,9 +215,9 @@ class MapCell : JPanel() { string.append("

Scenery Info

") for(sc in scenery) { if (sc.id != -1) { - string.append("${sc.definition.name} [ID: ${sc.id}]
") - string.append("Type: ${sc.type}
") - string.append("Rotation: ${sc.rotation}
") + string.append("${sc?.definition?.name} [ID: ${sc?.id}]
") + string.append("Type: ${sc?.type}
") + string.append("Rotation: ${sc?.rotation}
") string.append("---------------------
") } } @@ -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) diff --git a/src/main/kotlin/ui/NPCSpawnPanel.kt b/src/main/kotlin/ui/NPCSpawnPanel.kt index d1b916a..eed8b2f 100644 --- a/src/main/kotlin/ui/NPCSpawnPanel.kt +++ b/src/main/kotlin/ui/NPCSpawnPanel.kt @@ -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)