diff --git a/src/main/kotlin/Rs2MapEditor.kt b/src/main/kotlin/Rs2MapEditor.kt index 672fdd2..2f1c0b1 100644 --- a/src/main/kotlin/Rs2MapEditor.kt +++ b/src/main/kotlin/Rs2MapEditor.kt @@ -6,6 +6,7 @@ import cacheops.cache.definition.decoder.* import cacheops.cache.definition.encoder.NPCSpawnEncoder import com.displee.cache.CacheLibrary import com.formdev.flatlaf.FlatDarculaLaf +import const.Image.RED_DOT import const.Image.YELLOW_DOT import java.awt.* import java.awt.event.KeyEvent @@ -18,8 +19,9 @@ import kotlin.system.exitProcess object Rs2MapEditor { val library = CacheLibrary.create("K:\\RSPSDev\\2-009Scape-578\\Server\\data\\cache") - var region = 12853 + var region = 12850 var npcs = NPCSpawnParser.parseNPCSpawns(region) + var items = GroundItemSpawnParser.parseItemSpawns(region) val npcRows = ArrayList() lateinit var mapPanel: MapPane lateinit var npcPanel: NPCSpawnPanel @@ -133,6 +135,11 @@ object Rs2MapEditor { mapCell.layout = BorderLayout() mapCell.add(JLabel(YELLOW_DOT)) } + val itemSpawnsHere = items.filter { it.x == column && it.y == flippedY && it.plane == 0 }.toList() + if (itemSpawnsHere.isNotEmpty()) { + mapCell.layout = BorderLayout() + mapCell.add(JLabel(RED_DOT)) + } componentPointMap[point] = mapCell add(mapCell, gbc) } diff --git a/src/main/kotlin/cacheops/cache/definition/decoder/GroundItemDecoder.kt b/src/main/kotlin/cacheops/cache/definition/decoder/GroundItemDecoder.kt new file mode 100644 index 0000000..6e36764 --- /dev/null +++ b/src/main/kotlin/cacheops/cache/definition/decoder/GroundItemDecoder.kt @@ -0,0 +1,53 @@ +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 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/ItemDecoder.kt b/src/main/kotlin/cacheops/cache/definition/decoder/ItemDecoder.kt index e099998..0333012 100644 --- a/src/main/kotlin/cacheops/cache/definition/decoder/ItemDecoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/decoder/ItemDecoder.kt @@ -8,12 +8,27 @@ import const.Indices class ItemDecoder(cache: Cache) : DefinitionDecoder(cache, Indices.CONFIGURATION_ITEMS) { + companion object { + val DEFINITIONS = HashMap() + } + override fun create() = ItemDefinition() override fun getFile(id: Int) = id and 0xff override fun getArchive(id: Int) = id ushr 8 + override fun readData(id: Int): ItemDefinition? { + return super.readData(id) + } + + fun forId(id : Int): ItemDefinition { + if(DEFINITIONS[id] != null) return DEFINITIONS[id]!! + val def = readData(id) + DEFINITIONS[id] = def!! + return def + } + override fun ItemDefinition.read(opcode: Int, buffer: Reader) { when (opcode) { 1 -> modelId = buffer.readShort() diff --git a/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt b/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt index 2662a3e..bd482ee 100644 --- a/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/decoder/NPCSpawnDecoder.kt @@ -2,7 +2,6 @@ package cacheops.cache.definition.decoder import Rs2MapEditor import cacheops.cache.definition.data.NPCDefinition -import const.Image import const.cache import ext.unsignedShort import java.nio.ByteBuffer diff --git a/src/main/kotlin/cacheops/cache/definition/encoder/GroundItemEncoder.kt b/src/main/kotlin/cacheops/cache/definition/encoder/GroundItemEncoder.kt new file mode 100644 index 0000000..2dbd7f6 --- /dev/null +++ b/src/main/kotlin/cacheops/cache/definition/encoder/GroundItemEncoder.kt @@ -0,0 +1,45 @@ +package cacheops.cache.definition.encoder + +import Rs2MapEditor +import cacheops.cache.definition.decoder.Item +import const.Indices +import java.nio.ByteBuffer + +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.y or (it.x shl 7)) or (it.plane shl 14)) + 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() + } 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/MapTileEncoder.kt b/src/main/kotlin/cacheops/cache/definition/encoder/MapTileEncoder.kt index 9f3422c..6316064 100644 --- a/src/main/kotlin/cacheops/cache/definition/encoder/MapTileEncoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/encoder/MapTileEncoder.kt @@ -1,11 +1,14 @@ package cacheops.cache.definition.encoder +import Rs2MapEditor import cacheops.cache.definition.data.MapDefinition +import cacheops.cache.definition.decoder.MapTileParser +import const.Indices import java.nio.ByteBuffer -class MapTileEncoder { +object MapTileEncoder { - fun write(definition: MapDefinition): ByteArray { + fun write(definition: MapDefinition) { val buffer = ByteBuffer.allocate(80000) for (plane in 0 until 4) { for (localX in 0 until 64) { @@ -30,6 +33,17 @@ class MapTileEncoder { } } } - return buffer.array().copyOf(buffer.position()) + val data = buffer.array().copyOf(buffer.position()) + val combinedData = data.plus(MapTileParser.atmosphereDataTail) + + val x = (Rs2MapEditor.region shr 8) and 0xFF + val y = Rs2MapEditor.region and 0xFF + + if (combinedData != null) { + Rs2MapEditor.library.put(Indices.LANDSCAPES, "m${x}_${y}", combinedData) + Rs2MapEditor.library.update() + } else { + System.err.println("Something went VERY wrong!") + } } } \ No newline at end of file diff --git a/src/main/kotlin/cacheops/cache/definition/encoder/MapTileWriter.kt b/src/main/kotlin/cacheops/cache/definition/encoder/MapTileWriter.kt deleted file mode 100644 index ee65aa9..0000000 --- a/src/main/kotlin/cacheops/cache/definition/encoder/MapTileWriter.kt +++ /dev/null @@ -1,25 +0,0 @@ -package cacheops.cache.definition.encoder - -import Rs2MapEditor - -object MapTileWriter { - - fun replaceValues() { - val region = Rs2MapEditor.region - val baseX = ((region shr 8) shl 6) - val baseY = ((region and 0xFF) shl 6) - val x = (region shr 8) and 0xFF - val y = region and 0xFF - -// val data = MapTileEncoder().write(MapTileParser.definition) -// val combinedData = data.plus(MapTileParser.atmosphereDataTail) -// -// if (data != null) { -// Rs2MapEditor.library.put(Indices.LANDSCAPES, "m${x}_${y}", combinedData) -// Rs2MapEditor.library.update() -// } else { -// System.err.println("Something went VERY wrong!") -// } - } - -} \ 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 7ba087c..0620b86 100644 --- a/src/main/kotlin/cacheops/cache/definition/encoder/NPCSpawnEncoder.kt +++ b/src/main/kotlin/cacheops/cache/definition/encoder/NPCSpawnEncoder.kt @@ -8,7 +8,7 @@ import java.nio.ByteBuffer object NPCSpawnEncoder { fun write(npc: ArrayList) { - val buffer = ByteBuffer.allocate(10000) + val buffer = ByteBuffer.allocate(npc.size * 4) npc.forEach { val formattedCoord = ((it.y or (it.x shl 7)) or (it.plane shl 14)) @@ -16,11 +16,9 @@ object NPCSpawnEncoder { buffer.putShort(it.id.toShort()) } - val dataArray = buffer.array().copyOf(buffer.position()) + val dataArray = buffer.array() val region = Rs2MapEditor.region - val baseX = ((region shr 8) shl 6) - val baseY = ((region and 0xFF) shl 6) val x = (region shr 8) and 0xFF val y = region and 0xFF