New dynamic region abstraction, consumed in construction

This commit is contained in:
Ceikry
2022-05-03 23:18:11 +00:00
committed by Ryan
parent 8438ecdbd7
commit a5f9c64dbb
26 changed files with 745 additions and 177 deletions
@@ -0,0 +1,34 @@
package api.regionspec
import api.regionspec.contracts.*
import core.game.world.map.Region
import core.game.world.map.RegionChunk
import core.game.world.map.RegionPlane
import core.game.world.map.build.DynamicRegion
class RegionSpecification(val regionContract: RegionSpecContract = EmptyRegionContract(), vararg val chunkContracts: ChunkSpecContract = arrayOf(EmptyChunkContract())) {
constructor(vararg chunkContracts: ChunkSpecContract) : this(EmptyRegionContract(), *chunkContracts)
fun build(): DynamicRegion {
val dyn = regionContract.instantiateRegion()
Region.load(dyn)
chunkContracts.forEach { it.populateChunks(dyn) }
return dyn
}
}
fun fillWith(chunk: RegionChunk?): FillChunkContract {
return FillChunkContract(chunk)
}
fun fillWith(delegate: (Int, Int, Int, Region) -> RegionChunk?) : FillChunkContract {
return FillChunkContract(delegate)
}
fun copyOf(regionId: Int): RegionSpecContract {
return CloneRegionContract(regionId)
}
fun using(region: DynamicRegion) : UseExistingRegionContract {
return UseExistingRegionContract(region)
}
@@ -0,0 +1,7 @@
package api.regionspec.contracts
import core.game.world.map.build.DynamicRegion
interface ChunkSpecContract {
fun populateChunks(dyn: DynamicRegion)
}
@@ -0,0 +1,9 @@
package api.regionspec.contracts
import core.game.world.map.build.DynamicRegion
class CloneRegionContract(val regionId: Int) : RegionSpecContract {
override fun instantiateRegion(): DynamicRegion {
return DynamicRegion.create(regionId)
}
}
@@ -0,0 +1,7 @@
package api.regionspec.contracts
import core.game.world.map.build.DynamicRegion
class EmptyChunkContract : ChunkSpecContract {
override fun populateChunks(dyn: DynamicRegion) {}
}
@@ -0,0 +1,11 @@
package api.regionspec.contracts
import core.game.world.map.build.DynamicRegion
class EmptyRegionContract : RegionSpecContract {
override fun instantiateRegion(): DynamicRegion {
val borders = DynamicRegion.reserveArea(8,8)
val dyn = DynamicRegion(borders)
return dyn
}
}
@@ -0,0 +1,54 @@
package api.regionspec.contracts
import core.game.world.map.BuildRegionChunk
import core.game.world.map.Region
import core.game.world.map.RegionChunk
import core.game.world.map.build.DynamicRegion
open class FillChunkContract(var chunk: RegionChunk? = null) : ChunkSpecContract {
constructor(chunk: (Int, Int, Int, Region) -> RegionChunk?) : this(null) {this.chunkDelegate = chunk}
lateinit var sourceRegion: Region
var planes: IntArray = intArrayOf(0)
var replaceCondition: (Int,Int,Int) -> Boolean = {_,_,_ -> true}
var chunkDelegate: (Int, Int, Int, Region) -> RegionChunk? = {_,_,_,_ -> chunk}
override fun populateChunks(dyn: DynamicRegion) {
for(plane in planes) {
for(x in 0 until 8)
for(y in 0 until 8)
if(replaceCondition.invoke(x,y,plane)) {
val chunk = getChunk(x,y,plane,dyn)
dyn.replaceChunk(
plane,
x,
y,
chunk,
sourceRegion
)
afterSetting(chunk, x, y, plane, dyn)
}
}
}
open fun getChunk(x: Int, y: Int, plane: Int, dyn: DynamicRegion) : BuildRegionChunk? {
return chunkDelegate.invoke(x, y, plane, sourceRegion)?.copy(dyn.planes[plane])
}
open fun afterSetting(chunk: BuildRegionChunk?, x: Int, y: Int, plane: Int, dyn: DynamicRegion) {}
fun from(region: Region): FillChunkContract {
this.sourceRegion = region
return this
}
fun onPlanes(vararg planes: Int) : FillChunkContract {
this.planes = planes
return this
}
fun onCondition(cond: (Int,Int,Int) -> Boolean): FillChunkContract {
this.replaceCondition = cond
return this
}
}
@@ -0,0 +1,7 @@
package api.regionspec.contracts
import core.game.world.map.build.DynamicRegion
interface RegionSpecContract {
fun instantiateRegion(): DynamicRegion
}
@@ -0,0 +1,9 @@
package api.regionspec.contracts
import core.game.world.map.build.DynamicRegion
class UseExistingRegionContract(val region: DynamicRegion) : RegionSpecContract {
override fun instantiateRegion(): DynamicRegion {
return region;
}
}