diff --git a/src/main/kotlin/Rs2MapEditor.kt b/src/main/kotlin/Rs2MapEditor.kt index f5a469f..46d01f4 100644 --- a/src/main/kotlin/Rs2MapEditor.kt +++ b/src/main/kotlin/Rs2MapEditor.kt @@ -1,10 +1,8 @@ import cacheops.cache.definition.data.MapTile +import cacheops.cache.definition.data.OverlayDefinition import cacheops.cache.definition.data.UnderlayDefinition -import cacheops.cache.definition.decoder.FloorUnderlayConfiguration -import cacheops.cache.definition.decoder.MapTileParser -import cacheops.cache.definition.decoder.NPC -import cacheops.cache.definition.decoder.NPCSpawnParser +import cacheops.cache.definition.decoder.* import cacheops.cache.definition.encoder.NPCSpawnEncoder import com.displee.cache.CacheLibrary import com.formdev.flatlaf.FlatDarculaLaf @@ -30,8 +28,10 @@ object Rs2MapEditor { fun main(args: Array) { FlatDarculaLaf.setup() FloorUnderlayConfiguration.init() + FloorOverlayConfiguration.init() MapTileParser.init() underlayMap = FloorUnderlayConfiguration.floorUnderlays + overlayMap = FloorOverlayConfiguration.floorOverlays MainFrame() } @@ -51,6 +51,7 @@ object Rs2MapEditor { // Stores the underlay ID with the Underlay Definition lateinit var underlayMap: HashMap + lateinit var overlayMap: HashMap var selectedUnderlayId: Int? = null diff --git a/src/main/kotlin/cacheops/cache/definition/data/OverlayDefinition.kt b/src/main/kotlin/cacheops/cache/definition/data/OverlayDefinition.kt new file mode 100644 index 0000000..109837b --- /dev/null +++ b/src/main/kotlin/cacheops/cache/definition/data/OverlayDefinition.kt @@ -0,0 +1,20 @@ +package cacheops.cache.definition.data + +data class OverlayDefinition( + var color: Int = 0, + var texture: Int = -1, + var hideUnderlay: Boolean = true, + var blendColor: Int = -1, + var scale: Int = 128, + var blockShadow: Boolean = true, + var aByte0: Int = 8, + var blendTexture: Boolean = false, + var waterColor: Int = 1190717, + var waterScale: Int = 16, + var anInt0: Int = -1, + var waterIntensity: Int = 16 +) { + override fun toString(): String { + return "" + } +} diff --git a/src/main/kotlin/cacheops/cache/definition/decoder/FloorOverlayConfiguration.kt b/src/main/kotlin/cacheops/cache/definition/decoder/FloorOverlayConfiguration.kt new file mode 100644 index 0000000..f55c18e --- /dev/null +++ b/src/main/kotlin/cacheops/cache/definition/decoder/FloorOverlayConfiguration.kt @@ -0,0 +1,32 @@ +package cacheops.cache.definition.decoder + +import Rs2MapEditor +import cacheops.cache.definition.data.OverlayDefinition +import const.Archives +import const.Indices +import java.nio.ByteBuffer + +object FloorOverlayConfiguration { + + val cache = Rs2MapEditor.library.index(Indices.CONFIGURATION).archive(Archives.FLOOR_UNDERLAYS) + + var floorOverlays = hashMapOf() + + @JvmStatic + fun main(args: Array) { + cache!!.files().forEach { + val buffer = ByteBuffer.wrap(it.data) + val definition = FloorOverlayDecoder().decode(buffer) + floorOverlays[it.id] = definition + } + } + + fun init() { + cache!!.files().forEach { + val buffer = ByteBuffer.wrap(it.data) + val definition = FloorOverlayDecoder().decode(buffer) + floorOverlays[it.id] = definition + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/cacheops/cache/definition/decoder/FloorOverlayDecoder.kt b/src/main/kotlin/cacheops/cache/definition/decoder/FloorOverlayDecoder.kt new file mode 100644 index 0000000..26c7be5 --- /dev/null +++ b/src/main/kotlin/cacheops/cache/definition/decoder/FloorOverlayDecoder.kt @@ -0,0 +1,154 @@ +package cacheops.cache.definition.decoder + +import cacheops.cache.definition.data.OverlayDefinition +import ext.medium +import ext.unsignedByte +import ext.unsignedShort +import java.nio.ByteBuffer + +class FloorOverlayDecoder { + + private var color = 0 + private var texture = -1 + private var hideUnderlay = true + private var blendColor = -1 + private var anInt3081 = 0 + private var scale = 128 + private var blockShadow = true + private var aByte0 = 8 + private var blendTexture = false + private var waterColor = 1190717 + private var waterScale = 16 + private var anInt0 = -1 + private var waterIntensity = 16 + + fun decode(buffer: ByteBuffer): OverlayDefinition { + while (true) { + val opcode = buffer.unsignedByte() + if (opcode == 0) { + return OverlayDefinition(color, texture, hideUnderlay, blendColor, scale, blockShadow, aByte0, blendTexture, waterColor, waterScale, anInt0, waterIntensity) + } + decodeOverlayType(opcode, buffer) + } + } + + /** + * Overlay Type Decoder + * + * Takes the standard params for a decoder, [opcode], [rsByteBuffer] and a [ID]. + * + * Currently opcode [10] is unknown. + */ + private fun decodeOverlayType(opcode: Int, buffer: ByteBuffer) { + + when (opcode) { + 1 -> color = rgbToHsl(buffer.medium()) + 2 -> texture = buffer.unsignedByte() + 3 -> { + texture = buffer.unsignedShort() + if (texture == 65535) { + texture = -1 + } + } + 5 -> hideUnderlay = false + 7 -> blendColor = rgbToHsl(buffer.medium()) + 8 -> anInt3081 + 9 -> scale = buffer.unsignedShort() + 10 -> blockShadow = false //Possibly blockShadow? + 11 -> aByte0 = buffer.unsignedByte() + 12 -> blendTexture = true + 13 -> waterColor = buffer.medium() + 14 -> waterScale = buffer.unsignedByte() + 15 -> { + anInt0 = buffer.unsignedShort() + if (anInt0 == 65535) { + anInt0 = -1 + } + } + 16 -> waterIntensity = buffer.unsignedByte() + /* 14 + * Handles how deep into water the player is able to see, + * seems to (but not confirmed) work in jumps of 2, so: "0, 2, 4, 6" etc. + * It seems any number equals to or less than 0, removes any visual + * effect obscuring the depth view. The first increment in order, + * being 2, blocks almost 100% of the view of the underwater map (UM). + */ + else -> println("Unhandled opcode $opcode") + } + } + + private fun rgbToHsl(i_7_: Int): Int { + if (i_7_ == 16711935) { + return -1 + + } else { + + val d = (((0xff80ae and i_7_) shr 16).toDouble() / 256.0) + val d_8_ = (((0xff6a and i_7_) shr 8).toDouble() / 256.0) + val d_9_ = ((i_7_ and 0xff).toDouble() / 256.0) + var d_11_ = d + if (d_11_ > d_8_) { + d_11_ = d_8_ + } + if (d_11_ > d_9_) { + d_11_ = d_9_ + } + var d_12_ = d + if (d_8_ > d_12_) { + d_12_ = d_8_ + } + if (d_12_ < d_9_) { + d_12_ = d_9_ + } + var d_13_ = 0.0 + var d_14_ = 0.0 + val d_15_ = (d_12_ + d_11_) / 2.0 + if (d_11_ != d_12_) { + if (d_15_ < 0.5) { + d_14_ = (-d_11_ + d_12_) / (d_12_ + d_11_) + } + if (d_15_ >= 0.5) { + d_14_ = (d_12_ - d_11_) / (-d_12_ + 2.0 - d_11_) + } + if (d_12_ == d) { + d_13_ = (d_8_ - d_9_) / (d_12_ - d_11_) + } else if (d_12_ == d_8_) { + d_13_ = (-d + d_9_) / (-d_11_ + d_12_) + 2.0 + } else if (d_12_ == d_9_) { + d_13_ = (d - d_8_) / (d_12_ - d_11_) + 4.0 + } + } + d_13_ /= 6.0 + val i_16_ = (d_13_ * 256.0).toInt() + var i_17_ = (d_14_ * 256.0).toInt() + if (i_17_ >= 0) { + if (i_17_ > 255) { + i_17_ = 255 + } + } else { + i_17_ = 0 + } + var i_18_ = (d_15_ * 256.0).toInt() + if (i_18_ >= 0) { + if (i_18_ > 255) { + i_18_ = 255 + } + } else { + i_18_ = 0 + } + if (i_18_ > 243) { + i_17_ = i_17_ shr 4 + } else if (i_18_ <= 217) { + if (i_18_ > 192) { + i_17_ = i_17_ shr 2 + } else if (i_18_ > 179) { + i_17_ = i_17_ shr 1 + } + } else { + i_17_ = i_17_ shr 3 + } + return ((((i_16_ and 0xff) shr 2) shl 10) + ((i_17_ shr 5) shl 7) + (i_18_ shr 1)) + } + } + +} \ No newline at end of file