Skip to content

Commit

Permalink
Rewrite unique rooms
Browse files Browse the repository at this point in the history
  • Loading branch information
Harry282 committed Aug 13, 2024
1 parent 8910fa9 commit 14be639
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/main/kotlin/funnymap/core/RoomData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import funnymap.core.map.RoomType

data class RoomData(
val name: String,
val type: RoomType,
var type: RoomType,
val cores: List<Int>,
val crypts: Int,
val secrets: Int,
Expand Down
17 changes: 1 addition & 16 deletions src/main/kotlin/funnymap/core/map/Room.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package funnymap.core.map

import funnymap.config.Config
import funnymap.core.RoomData
import funnymap.features.dungeon.Dungeon
import funnymap.features.dungeon.DungeonScan
import funnymap.features.dungeon.MapRender
import java.awt.Color

class Room(override val x: Int, override val z: Int, var data: RoomData) : Tile {
var core = 0
var hasMimic = false
var isSeparator = false
var uniqueRoom: UniqueRoom? = null
override var state: RoomState = RoomState.UNDISCOVERED
override val color: Color
get() = if (MapRender.legitRender && state == RoomState.UNOPENED) Config.colorUnopened
Expand All @@ -24,18 +23,4 @@ class Room(override val x: Int, override val z: Int, var data: RoomData) : Tile
RoomType.TRAP -> Config.colorTrap
else -> if (hasMimic) Config.colorRoomMimic else Config.colorRoom
}

fun getArrayPosition(): Pair<Int, Int> {
return Pair((x - DungeonScan.startX) / 16, (z - DungeonScan.startZ) / 16)
}

fun addToUnique(row: Int, column: Int, roomName: String = data.name) {
val unique = Dungeon.Info.uniqueRooms.find { it.name == roomName }

if (unique == null) {
Dungeon.Info.uniqueRooms.add(UniqueRoom(column, row, this))
} else {
unique.addTile(column, row, this)
}
}
}
67 changes: 54 additions & 13 deletions src/main/kotlin/funnymap/core/map/UniqueRoom.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@ import funnymap.features.dungeon.Dungeon
import funnymap.features.dungeon.MapRender

class UniqueRoom(arrX: Int, arrY: Int, room: Room) {
val name = room.data.name
private var topLeft = Pair(arrX, arrY)
var name: String
var topLeft = Pair(arrX, arrY)
private var center = Pair(arrX, arrY)
var mainRoom = room
private val tiles = mutableListOf(room)
get() = Dungeon.Info.dungeonList[topLeft.second * 11 + topLeft.first] as? Room ?: field
val tiles = mutableListOf(room to Pair(arrX, arrY))

init {
if (room.data.name == "Unknown") {
name = "Unknown_${arrX}_${arrY}"
} else {
name = room.data.name
init(arrX, arrY, room)
}
room.uniqueRoom = this
Dungeon.Info.uniqueRooms.add(this)
}

fun init(arrX: Int, arrY: Int, room: Room) {
Dungeon.Info.cryptCount += room.data.crypts
Dungeon.Info.secretCount += room.data.secrets
when (room.data.type) {
Expand All @@ -30,21 +42,54 @@ class UniqueRoom(arrX: Int, arrY: Int, room: Room) {
}

fun addTile(x: Int, y: Int, tile: Room) {
tiles.removeIf { it.x == tile.x && it.z == tile.z }
tiles.add(tile)
addToTiles(x, y, tile)
calculateCenter()
}

fun addTiles(tiles: Iterable<Pair<Int, Int>>) {
tiles.forEach { (x, y) ->
val room = Dungeon.Info.dungeonList[y * 11 + x] as? Room ?: return@forEach
if (room.uniqueRoom !== this) {
Dungeon.Info.uniqueRooms.remove(room.uniqueRoom)
addToTiles(x, y, room)
}
}
calculateCenter()
}

private fun addToTiles(x: Int, y: Int, tile: Room) {
if (mainRoom.data.name == "Unknown") {
if (tile.data.name != "Unknown") {
init(x, y, tile)
name = tile.data.name
mainRoom.data = tile.data
}
} else if (tile.data.name == "Unknown") {
tile.data = mainRoom.data
}

tile.uniqueRoom = this

tiles.removeIf { it.first.x == tile.x && it.first.z == tile.z }
tiles.add(tile to Pair(x, y))

if (x < topLeft.first || (x == topLeft.first && y < topLeft.second)) {
topLeft = Pair(x, y)
mainRoom = tile
if (name.startsWith("Unknown")) {
name = "Unknown_${x}_${y}"
}
}
}

private fun calculateCenter() {
if (tiles.size == 1) {
center = Pair(x, y)
center = tiles.first().second
return
}

val positions = tiles.mapNotNull {
it.getArrayPosition().takeIf { (arrX, arrZ) ->
it.second.takeIf { (arrX, arrZ) ->
arrX % 2 == 0 && arrZ % 2 == 0
}
}
Expand All @@ -67,11 +112,7 @@ class UniqueRoom(arrX: Int, arrY: Int, room: Room) {
}
}

fun getNamePosition(): Pair<Int, Int> {
return if (Config.mapCenterRoomName) center else topLeft
}
fun getNamePosition(): Pair<Int, Int> = if (Config.mapCenterRoomName) center else topLeft

fun getCheckmarkPosition(): Pair<Int, Int> {
return if (Config.mapCenterCheckmark) center else topLeft
}
fun getCheckmarkPosition(): Pair<Int, Int> = if (Config.mapCenterCheckmark) center else topLeft
}
15 changes: 13 additions & 2 deletions src/main/kotlin/funnymap/features/dungeon/DungeonScan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,24 @@ object DungeonScan {
}) continue

scanRoom(xPos, zPos, z, x)?.let {
val prev = Dungeon.Info.dungeonList[z * 11 + x]
if (it is Room) {
if ((prev as? Room)?.uniqueRoom != null) {
prev.uniqueRoom?.addTile(x, z, it)
} else {
UniqueRoom(x, z, it)
}
MapUpdate.roomAdded = true
}
Dungeon.Info.dungeonList[z * 11 + x] = it
}
}
}

if (MapUpdate.roomAdded) {
MapUpdate.updateUniques()
}

if (allChunksLoaded) {
if (Config.scanChatInfo) {
val maxSecrets = ceil(Dungeon.Info.secretCount * ScoreCalculation.getSecretPercent())
Expand Down Expand Up @@ -107,7 +120,6 @@ object DungeonScan {
val roomCore = ScanUtils.getCore(x, z)
Room(x, z, ScanUtils.getRoomData(roomCore) ?: return null).apply {
core = roomCore
addToUnique(row, column)
}
}

Expand All @@ -117,7 +129,6 @@ object DungeonScan {
if (it is Room) {
Room(x, z, it.data).apply {
isSeparator = true
addToUnique(row, column)
}
} else null
}
Expand Down
85 changes: 80 additions & 5 deletions src/main/kotlin/funnymap/features/dungeon/MapUpdate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import net.minecraft.util.StringUtils
import kotlin.math.roundToInt

object MapUpdate {
var roomAdded = false

fun preloadHeads() {
val tabEntries = TabList.getDungeonTabList() ?: return
for (i in listOf(5, 9, 13, 17, 1)) {
Expand Down Expand Up @@ -105,8 +107,10 @@ object MapUpdate {
for (z in 0..10) {
val room = Dungeon.Info.dungeonList[z * 11 + x]
val mapTile = map.getTile(x, z)
if (mapTile is Unknown) continue

if (room is Unknown) {
roomAdded = true
Dungeon.Info.dungeonList[z * 11 + x] = mapTile
continue
}
Expand All @@ -119,6 +123,12 @@ object MapUpdate {
room.state = mapTile.state
}

if (mapTile is Room && room is Room) {
if (room.data.type != mapTile.data.type && mapTile.data.type != RoomType.NORMAL) {
room.data.type = mapTile.data.type
}
}

if (mapTile is Door && room is Door) {
if (mapTile.type == DoorType.WITHER && room.type != DoorType.WITHER) {
room.type = mapTile.type
Expand All @@ -127,15 +137,16 @@ object MapUpdate {

if (room is Door && room.type.equalsOneOf(DoorType.ENTRANCE, DoorType.WITHER, DoorType.BLOOD)) {
if (mapTile is Door && mapTile.type == DoorType.WITHER) {
room.opened = false
if (room.opened) {
room.opened = false
}
} else if (!room.opened && mc.theWorld.getChunkFromChunkCoords(
room.x shr 4,
room.z shr 4
).isLoaded
).isLoaded &&
mc.theWorld.getBlockState(BlockPos(room.x, 69, room.z)).block == Blocks.air
) {
if (mc.theWorld.getBlockState(BlockPos(room.x, 69, room.z)).block == Blocks.air) {
room.opened = true
}
room.opened = true
}

if (!room.opened) {
Expand All @@ -144,5 +155,69 @@ object MapUpdate {
}
}
}

if (roomAdded) {
updateUniques()
}
}

fun updateUniques() {
val visited = BooleanArray(121)
for (x in 0..10) {
for (z in 0..10) {
val index = z * 11 + x
if (visited[index]) continue
visited[index] = true

val room = Dungeon.Info.dungeonList[index]
if (room !is Room) continue

val connected = getConnectedIndices(x, z)
var unique = room.uniqueRoom
if (unique == null || unique.name.startsWith("Unknown")) {
unique = connected.firstOrNull {
(Dungeon.Info.dungeonList[it.second * 11 + it.first] as? Room)?.uniqueRoom?.name?.startsWith("Unknown") == false
}?.let {
(Dungeon.Info.dungeonList[it.second * 11 + it.first] as? Room)?.uniqueRoom
} ?: unique
}

val finalUnique = unique ?: UniqueRoom(x, z, room)

finalUnique.addTiles(connected)

connected.forEach {
visited[it.second * 11 + it.first] = true
}
}
}
roomAdded = false
}

private fun getConnectedIndices(arrayX: Int, arrayY: Int): List<Pair<Int, Int>> {
val tile = Dungeon.Info.dungeonList[arrayY * 11 + arrayX]
if (tile !is Room) return emptyList()
val directions = listOf(
Pair(0, 1),
Pair(1, 0),
Pair(0, -1),
Pair(-1, 0)
)
val connected = mutableListOf<Pair<Int, Int>>()
val queue = mutableListOf(Pair(arrayX, arrayY))
while (queue.isNotEmpty()) {
val current = queue.removeFirst()
if (connected.contains(current)) continue
connected.add(current)
directions.forEach {
val x = current.first + it.first
val y = current.second + it.second
if (x !in 0..10 || y !in 0..10) return@forEach
if (Dungeon.Info.dungeonList[y * 11 + x] is Room) {
queue.add(Pair(x, y))
}
}
}
return connected
}
}

0 comments on commit 14be639

Please sign in to comment.