Fix memory requirements of previous commit :)
This commit is contained in:
parent
e134554879
commit
318b689d2d
@ -16,7 +16,7 @@ import java.io.DataOutputStream
|
||||
|
||||
class ChunkCellsPacket(val pos: ChunkPos, val data: List<ImmutableCell>) : IClientPacket {
|
||||
constructor(stream: DataInputStream, isLegacy: Boolean) : this(stream.readChunkPos(), stream.readCollection { MutableCell().read(stream).immutable() })
|
||||
constructor(chunk: Chunk<*, *, *>) : this(chunk.pos, ArrayList<ImmutableCell>(CHUNK_SIZE * CHUNK_SIZE).also {
|
||||
constructor(chunk: Chunk<*, *>) : this(chunk.pos, ArrayList<ImmutableCell>(CHUNK_SIZE * CHUNK_SIZE).also {
|
||||
for (x in 0 until CHUNK_SIZE) {
|
||||
for (y in 0 until CHUNK_SIZE) {
|
||||
it.add(chunk.getCell(x, y).immutable())
|
||||
|
@ -1,17 +1,12 @@
|
||||
package ru.dbotthepony.kstarbound.client.world
|
||||
|
||||
import ru.dbotthepony.kommons.arrays.Object2DArray
|
||||
import ru.dbotthepony.kstarbound.world.Chunk
|
||||
import ru.dbotthepony.kstarbound.world.ChunkPos
|
||||
import ru.dbotthepony.kstarbound.world.ChunkState
|
||||
import ru.dbotthepony.kstarbound.world.api.AbstractCell
|
||||
import ru.dbotthepony.kstarbound.world.api.ImmutableCell
|
||||
|
||||
class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, ClientChunk, ClientChunk.ChunkCell>(world, pos) {
|
||||
inner class ChunkCell(x: Int, y: Int) : Chunk<ClientWorld, ClientChunk, ClientChunk.ChunkCell>.ChunkCell(x, y)
|
||||
|
||||
override val cells: Object2DArray<ChunkCell> = Object2DArray(width, height, ::ChunkCell)
|
||||
|
||||
class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, ClientChunk>(world, pos) {
|
||||
override val state: ChunkState
|
||||
get() = ChunkState.FULL
|
||||
|
||||
|
@ -62,13 +62,7 @@ import kotlin.coroutines.cancellation.CancellationException
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
||||
class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, ServerChunk, ServerChunk.ChunkCell>(world, pos) {
|
||||
inner class ChunkCell(x: Int, y: Int) : Chunk<ServerWorld, ServerChunk, ServerChunk.ChunkCell>.ChunkCell(x, y) {
|
||||
|
||||
}
|
||||
|
||||
override val cells: Object2DArray<ChunkCell> = Object2DArray(width, height, ::ChunkCell)
|
||||
|
||||
class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, ServerChunk>(world, pos) {
|
||||
override var state: ChunkState = ChunkState.FRESH
|
||||
private set
|
||||
|
||||
@ -156,9 +150,11 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
if (world.template.worldLayout == null || world.template.worldParameters is FloatingDungeonWorldParameters) {
|
||||
// skip since no cells will be generated anyway
|
||||
|
||||
val cells = cells.value
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
cells[x, y].setStateQuiet(AbstractCell.EMPTY)
|
||||
cells[x, y] = AbstractCell.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,6 +187,8 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
if (world.template.worldLayout != null && world.template.worldParameters !is FloatingDungeonWorldParameters) {
|
||||
placeGrass()
|
||||
}
|
||||
|
||||
signalChunkContentsUpdated()
|
||||
}
|
||||
|
||||
ChunkState.FRESH -> throw RuntimeException()
|
||||
@ -401,15 +399,10 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
temporary.forEach { if (it.targetState <= state) it.chunk.complete(this) }
|
||||
}
|
||||
|
||||
fun copyCells(): Object2DArray<ImmutableCell> {
|
||||
return Object2DArray(CHUNK_SIZE, CHUNK_SIZE) { x, y -> cells[x, y].state }
|
||||
}
|
||||
|
||||
data class DamageResult(val result: TileDamageResult, val health: TileHealth? = null, val stateBefore: AbstractCell? = null)
|
||||
|
||||
fun damageTile(pos: Vector2i, isBackground: Boolean, sourcePosition: Vector2d, damage: TileDamage, source: AbstractEntity? = null): DamageResult {
|
||||
val cellState = cells[pos.x, pos.y]
|
||||
val cell = cellState.state
|
||||
val cell = cells.value[pos.x, pos.y]
|
||||
|
||||
if (cell.isIndestructible || cell.tile(isBackground).material.value.isMeta) {
|
||||
return DamageResult(TileDamageResult.NONE)
|
||||
@ -423,7 +416,7 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
result = TileDamageResult.PROTECTED
|
||||
}
|
||||
|
||||
val health = if (isBackground) cellState.backgroundHealth else cellState.foregroundHealth
|
||||
val health = if (isBackground) backgroundHealth.computeIfAbsent(pos) { TileHealth.Tile() } else foregroundHealth.computeIfAbsent(pos) { TileHealth.Tile() }
|
||||
val tile = cell.tile(isBackground)
|
||||
|
||||
val params = if (!damage.type.isPenetrating && tile.modifier.value.breaksWithTile) {
|
||||
@ -436,8 +429,6 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
onTileHealthUpdate(pos.x, pos.y, isBackground, health)
|
||||
|
||||
if (health.isDead) {
|
||||
damagedCells.remove(pos)
|
||||
|
||||
val drops = ArrayList<ItemDescriptor>()
|
||||
|
||||
val copyHealth = health.copy()
|
||||
@ -475,32 +466,24 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
}
|
||||
|
||||
setCell(pos.x, pos.y, mCell.immutable())
|
||||
health.reset()
|
||||
return DamageResult(result, copyHealth, cell)
|
||||
} else {
|
||||
damagedCells.add(pos)
|
||||
return DamageResult(result, health, cell)
|
||||
}
|
||||
}
|
||||
|
||||
private val damagedCells = ObjectArraySet<Vector2i>()
|
||||
|
||||
fun tileDamagePackets(): List<TileDamageUpdatePacket> {
|
||||
val result = ArrayList<TileDamageUpdatePacket>()
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
val health = cells[x, y].backgroundHealth
|
||||
for ((pos, health) in backgroundHealth) {
|
||||
if (!health.isHealthy) {
|
||||
result.add(TileDamageUpdatePacket(this.pos.tileX + pos.x, this.pos.tileY + pos.y, true, health))
|
||||
}
|
||||
}
|
||||
|
||||
if (!health.isHealthy) {
|
||||
result.add(TileDamageUpdatePacket(pos.tileX + x, pos.tileY + y, true, health))
|
||||
}
|
||||
|
||||
val health2 = cells[x, y].foregroundHealth
|
||||
|
||||
if (!health2.isHealthy) {
|
||||
result.add(TileDamageUpdatePacket(pos.tileX + x, pos.tileY + y, false, health2))
|
||||
}
|
||||
for ((pos, health) in foregroundHealth) {
|
||||
if (!health.isHealthy) {
|
||||
result.add(TileDamageUpdatePacket(this.pos.tileX + pos.x, this.pos.tileY + pos.y, false, health))
|
||||
}
|
||||
}
|
||||
|
||||
@ -540,23 +523,18 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
|
||||
super.tick()
|
||||
|
||||
damagedCells.removeIf { (x, y) ->
|
||||
val health = cells[x, y].foregroundHealth
|
||||
val health2 = cells[x, y].backgroundHealth
|
||||
foregroundHealth.entries.removeIf { (pos, health) ->
|
||||
val (x, y) = pos
|
||||
val remove = !health.tick(cells.value[x, y].foreground.material.value.actualDamageTable)
|
||||
onTileHealthUpdate(x, y, false, health)
|
||||
remove
|
||||
}
|
||||
|
||||
var any = false
|
||||
|
||||
if (health.isTicking) {
|
||||
any = health.tick(cells[x, y].state.foreground.material.value.actualDamageTable) || any
|
||||
onTileHealthUpdate(x, y, false, health)
|
||||
}
|
||||
|
||||
if (health2.isTicking) {
|
||||
any = health2.tick(cells[x, y].state.background.material.value.actualDamageTable) || any
|
||||
onTileHealthUpdate(x, y, false, health2)
|
||||
}
|
||||
|
||||
!any
|
||||
backgroundHealth.entries.removeIf { (pos, health) ->
|
||||
val (x, y) = pos
|
||||
val remove = !health.tick(cells.value[x, y].background.material.value.actualDamageTable)
|
||||
onTileHealthUpdate(x, y, true, health)
|
||||
remove
|
||||
}
|
||||
}
|
||||
|
||||
@ -591,15 +569,22 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
}
|
||||
|
||||
fun legacyNetworkCells(): Object2DArray<LegacyNetworkCellState> {
|
||||
return Object2DArray(width, height) { a, b -> cells[a, b].state.toLegacyNet() }
|
||||
if (cells.isInitialized()) {
|
||||
val cells = cells.value
|
||||
return Object2DArray(width, height) { a, b -> cells[a, b].toLegacyNet() }
|
||||
} else {
|
||||
return Object2DArray(width, height, AbstractCell.NULL.toLegacyNet())
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareCells() {
|
||||
val cells = cells.value
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
val info = world.template.cellInfo(pos.tileX + x, pos.tileY + y)
|
||||
|
||||
val state = cells[x, y].state.mutable()
|
||||
val state = cells[x, y].mutable()
|
||||
|
||||
state.blockBiome = info.blockBiomeIndex
|
||||
state.envBiome = info.environmentBiomeIndex
|
||||
@ -643,15 +628,17 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
}
|
||||
}
|
||||
|
||||
cells[x, y].setStateQuiet(state.immutable())
|
||||
cells[x, y] = state.immutable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun finalizeCells() {
|
||||
val cells = cells.value
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
val cell = cells[x, y].state.mutable()
|
||||
val cell = cells[x, y].mutable()
|
||||
val info by lazy { world.template.cellInfo(pos.tileX + x, pos.tileY + y) }
|
||||
|
||||
if (cell.liquid.isInfinite) {
|
||||
@ -676,7 +663,7 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
}
|
||||
|
||||
replaceBiomeBlocks(cell, info)
|
||||
cells[x, y].state = cell.immutable()
|
||||
cells[x, y] = cell.immutable()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -709,11 +696,13 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
}
|
||||
|
||||
private fun replaceBiomeBlocks() {
|
||||
val cells = cells.value
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
val cell = cells[x, y].state.mutable()
|
||||
val cell = cells[x, y].mutable()
|
||||
replaceBiomeBlocks(cell, world.template.cellInfo(pos.tileX + x, pos.tileY + y))
|
||||
cells[x, y].state = cell.immutable()
|
||||
cells[x, y] = cell.immutable()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -789,10 +778,12 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
}
|
||||
|
||||
private fun placeGrass() {
|
||||
val cells = cells.value
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
val biome = world.template.cellInfo(pos.tileX + x, pos.tileY + y).blockBiome ?: continue
|
||||
val cell = cells[x, y].state
|
||||
val cell = cells[x, y]
|
||||
|
||||
// determine layer for grass mod calculation
|
||||
val isBackground = cell.foreground.material.isEmptyTile
|
||||
@ -853,7 +844,7 @@ class ServerChunk(world: ServerWorld, pos: ChunkPos) : Chunk<ServerWorld, Server
|
||||
modify.background.modifierHueShift = biome.hueShift(modify.background.modifier)
|
||||
modify.foreground.modifierHueShift = biome.hueShift(modify.foreground.modifier)
|
||||
|
||||
cells[x, y].state = modify.immutable()
|
||||
cells[x, y] = modify.immutable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ru.dbotthepony.kstarbound.world
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList
|
||||
import ru.dbotthepony.kommons.arrays.Boolean2DArray
|
||||
import ru.dbotthepony.kommons.arrays.Object2DArray
|
||||
import ru.dbotthepony.kommons.util.AABB
|
||||
import ru.dbotthepony.kommons.util.AABBi
|
||||
@ -17,6 +18,7 @@ import ru.dbotthepony.kstarbound.world.physics.CollisionPoly
|
||||
import ru.dbotthepony.kstarbound.world.physics.CollisionType
|
||||
import ru.dbotthepony.kstarbound.world.physics.getBlockPlatforms
|
||||
import ru.dbotthepony.kstarbound.world.physics.getBlocksMarchingSquares
|
||||
import java.util.BitSet
|
||||
import java.util.concurrent.CopyOnWriteArraySet
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
@ -31,7 +33,7 @@ import kotlin.math.min
|
||||
*
|
||||
* Весь игровой мир будет измеряться в Starbound Unit'ах
|
||||
*/
|
||||
abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType, This, CellType>, CellType : Chunk<WorldType, This, CellType>.ChunkCell>(
|
||||
abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType, This>>(
|
||||
val world: WorldType,
|
||||
val pos: ChunkPos,
|
||||
) : ICellAccess {
|
||||
@ -67,12 +69,26 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
||||
val aabb = AABBi(pos.tile, pos.tile + Vector2i(width, height))
|
||||
val aabbd = aabb.toDoubleAABB()
|
||||
|
||||
// TODO: maybe fit them into "width" and "height" variables added recently?
|
||||
protected abstract val cells: Object2DArray<CellType>
|
||||
protected val cells = lazy {
|
||||
Object2DArray(width, height, AbstractCell.NULL)
|
||||
}
|
||||
|
||||
protected val backgroundHealth = HashMap<Vector2i, TileHealth.Tile>()
|
||||
protected val foregroundHealth = HashMap<Vector2i, TileHealth.Tile>()
|
||||
protected val collisionCacheDirty = Boolean2DArray.allocate(width, height)
|
||||
protected val collisionCache by lazy {
|
||||
Object2DArray(width, height) { _, _ -> ObjectArrayList<CollisionPoly>(0) }
|
||||
}
|
||||
|
||||
init {
|
||||
for (x in 0 until width)
|
||||
for (y in 0 until height)
|
||||
collisionCacheDirty[x, y] = true
|
||||
}
|
||||
|
||||
private var hasDirtyCollisions = false
|
||||
|
||||
// bulk mark collision dirty of neighbour chunks
|
||||
// bulk mark collision dirty of neighbour chunks as well as ours
|
||||
protected fun signalChunkContentsUpdated() {
|
||||
val signalPositions = ArrayList<Vector2i>()
|
||||
|
||||
@ -93,7 +109,17 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
||||
val chunk = world.chunkMap[world.geometry.chunkFromCell(actualCellPosition)] ?: continue
|
||||
|
||||
chunk.hasDirtyCollisions = true
|
||||
chunk.cells[actualCellPosition.x - chunk.pos.tileX, actualCellPosition.y - chunk.pos.tileY].collisionCacheDirty = true
|
||||
chunk.collisionCacheDirty[actualCellPosition.x - chunk.pos.tileX, actualCellPosition.y - chunk.pos.tileY] = true
|
||||
}
|
||||
|
||||
hasDirtyCollisions = true
|
||||
backgroundHealth.clear()
|
||||
foregroundHealth.clear()
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
collisionCacheDirty[x, y] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +136,7 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
if (cells[x, y].collisionCacheDirty) {
|
||||
if (collisionCacheDirty[x, y]) {
|
||||
minX = min(minX, x)
|
||||
minY = min(minY, y)
|
||||
maxX = max(maxX, x)
|
||||
@ -121,13 +147,11 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
||||
|
||||
for (x in minX .. maxX) {
|
||||
for (y in minY .. maxY) {
|
||||
val cell = cells[x, y]
|
||||
|
||||
if (cell.collisionCacheDirty) {
|
||||
cell.collisionCache.clear()
|
||||
getBlocksMarchingSquares(pos.tileX + x, pos.tileY + y, world.foreground, CollisionType.DYNAMIC, cell.collisionCache)
|
||||
getBlockPlatforms(pos.tileX + x, pos.tileY + y, world.foreground, CollisionType.PLATFORM, cell.collisionCache)
|
||||
cell.collisionCacheDirty = false
|
||||
if (collisionCacheDirty[x, y]) {
|
||||
collisionCache[x, y].clear()
|
||||
getBlocksMarchingSquares(pos.tileX + x, pos.tileY + y, world.foreground, CollisionType.DYNAMIC, collisionCache[x, y])
|
||||
getBlockPlatforms(pos.tileX + x, pos.tileY + y, world.foreground, CollisionType.PLATFORM, collisionCache[x, y])
|
||||
collisionCacheDirty[x, y] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -137,84 +161,71 @@ abstract class Chunk<WorldType : World<WorldType, This>, This : Chunk<WorldType,
|
||||
hasDirtyCollisions = false
|
||||
}
|
||||
|
||||
target.addAll(cells[x, y].collisionCache)
|
||||
}
|
||||
|
||||
abstract inner class ChunkCell(val x: Int, val y: Int) {
|
||||
private var actualState: ImmutableCell = AbstractCell.NULL
|
||||
|
||||
var state: ImmutableCell
|
||||
get() = actualState
|
||||
set(value) {
|
||||
if (actualState != value) {
|
||||
foregroundHealth.reset()
|
||||
backgroundHealth.reset()
|
||||
hasDirtyCollisions = true
|
||||
collisionCacheDirty = true
|
||||
|
||||
for (xoff in -2 .. 2) {
|
||||
for (yoff in -2 .. 2) {
|
||||
val actualCellPosition = world.geometry.wrap(pos.tile + Vector2i(x + xoff, y + yoff))
|
||||
val chunk = world.chunkMap[world.geometry.chunkFromCell(actualCellPosition)] ?: continue
|
||||
|
||||
chunk.hasDirtyCollisions = true
|
||||
chunk.cells[actualCellPosition.x - chunk.pos.tileX, actualCellPosition.y - chunk.pos.tileY].collisionCacheDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
val old = actualState
|
||||
actualState = value
|
||||
|
||||
if (old.foreground != value.foreground) {
|
||||
foregroundChanges(x, y, value)
|
||||
}
|
||||
|
||||
if (old.background != value.background) {
|
||||
backgroundChanges(x, y, value)
|
||||
}
|
||||
|
||||
if (old.liquid != value.liquid) {
|
||||
liquidChanges(x, y, value)
|
||||
}
|
||||
|
||||
cellChanges(x, y, value)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not trigger any change events
|
||||
*/
|
||||
fun setStateQuiet(state: ImmutableCell) {
|
||||
foregroundHealth.reset()
|
||||
backgroundHealth.reset()
|
||||
hasDirtyCollisions = true
|
||||
collisionCacheDirty = true
|
||||
actualState = state
|
||||
}
|
||||
|
||||
var collisionCacheDirty = true
|
||||
val foregroundHealth = TileHealth.Tile()
|
||||
val backgroundHealth = TileHealth.Tile()
|
||||
val collisionCache = ObjectArrayList<CollisionPoly>(2) // no CME checks
|
||||
target.addAll(collisionCache[x, y])
|
||||
}
|
||||
|
||||
fun loadCells(source: Object2DArray<out AbstractCell>) {
|
||||
val ours = cells
|
||||
val ours = cells.value
|
||||
source.checkSizeEquals(ours)
|
||||
|
||||
for (x in 0 until CHUNK_SIZE) {
|
||||
for (y in 0 until CHUNK_SIZE) {
|
||||
ours[x, y].state = source[x, y].immutable()
|
||||
ours[x, y] = source[x, y].immutable()
|
||||
}
|
||||
}
|
||||
|
||||
signalChunkContentsUpdated()
|
||||
}
|
||||
|
||||
fun copyCells(): Object2DArray<ImmutableCell> {
|
||||
if (cells.isInitialized()) {
|
||||
val cells = cells.value
|
||||
return Object2DArray(CHUNK_SIZE, CHUNK_SIZE) { x, y -> cells[x, y] }
|
||||
} else {
|
||||
return Object2DArray(CHUNK_SIZE, CHUNK_SIZE, AbstractCell.NULL)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCell(x: Int, y: Int): AbstractCell {
|
||||
return cells[x, y].state
|
||||
return if (cells.isInitialized()) cells.value[x, y] else AbstractCell.NULL
|
||||
}
|
||||
|
||||
final override fun setCell(x: Int, y: Int, cell: AbstractCell): Boolean {
|
||||
cells[x, y].state = cell.immutable()
|
||||
val old = if (cells.isInitialized()) cells.value[x, y] else AbstractCell.NULL
|
||||
val new = cell.immutable()
|
||||
|
||||
if (old != new) {
|
||||
cells.value[x, y] = new
|
||||
hasDirtyCollisions = true
|
||||
collisionCacheDirty[x, y] = true
|
||||
|
||||
for (xoff in -2 .. 2) {
|
||||
for (yoff in -2 .. 2) {
|
||||
val actualCellPosition = world.geometry.wrap(pos.tile + Vector2i(x + xoff, y + yoff))
|
||||
val chunk = world.chunkMap[world.geometry.chunkFromCell(actualCellPosition)] ?: continue
|
||||
|
||||
chunk.hasDirtyCollisions = true
|
||||
chunk.collisionCacheDirty[actualCellPosition.x - chunk.pos.tileX, actualCellPosition.y - chunk.pos.tileY] = true
|
||||
}
|
||||
}
|
||||
|
||||
if (old.foreground != new.foreground) {
|
||||
foregroundHealth.remove(Vector2i(x, y))
|
||||
foregroundChanges(x, y, new)
|
||||
}
|
||||
|
||||
if (old.background != new.background) {
|
||||
backgroundHealth.remove(Vector2i(x, y))
|
||||
backgroundChanges(x, y, new)
|
||||
}
|
||||
|
||||
if (old.liquid != new.liquid) {
|
||||
liquidChanges(x, y, new)
|
||||
}
|
||||
|
||||
cellChanges(x, y, new)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ import java.util.random.RandomGenerator
|
||||
import java.util.stream.Stream
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType, *>>(val template: WorldTemplate) : ICellAccess {
|
||||
abstract class World<This : World<This, ChunkType>, ChunkType : Chunk<This, ChunkType>>(val template: WorldTemplate) : ICellAccess {
|
||||
val background = TileView.Background(this)
|
||||
val foreground = TileView.Foreground(this)
|
||||
val sky = Sky(template.skyParameters)
|
||||
|
Loading…
Reference in New Issue
Block a user