summaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt')
-rw-r--r--src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt83
1 files changed, 51 insertions, 32 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt
index 9d9a2aa..9f88fd9 100644
--- a/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt
+++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/Schematic.kt
@@ -6,12 +6,11 @@ import io.dico.parcels2.util.get
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.World
-import org.bukkit.block.Block
+import org.bukkit.block.Sign
import org.bukkit.block.data.BlockData
private val air = Bukkit.createBlockData(Material.AIR)
-// TODO order paste such that attachables are placed after the block they depend on
class Schematic {
val size: Vec3i get() = _size!!
private var _size: Vec3i? = null
@@ -21,7 +20,7 @@ class Schematic {
}
private var blockDatas: Array<BlockData?>? = null
- private val extra = mutableMapOf<Vec3i, (Block) -> Unit>()
+ private val extra = mutableListOf<Pair<Vec3i, ExtraBlockChange>>()
private var isLoaded = false; private set
private val traverser: RegionTraverser = RegionTraverser.upward
@@ -32,7 +31,7 @@ class Schematic {
val blocks = traverser.traverseRegion(region)
val total = region.blockCount.toDouble()
- for ((index, vec) in blocks.withIndex()) {
+ loop@ for ((index, vec) in blocks.withIndex()) {
markSuspensionPoint()
setProgress(index / total)
@@ -40,6 +39,14 @@ class Schematic {
if (block.y > 255) continue
val blockData = block.blockData
data[index] = blockData
+
+ val extraChange = when (blockData.material) {
+ Material.SIGN,
+ Material.WALL_SIGN -> SignStateChange(block.state as Sign)
+ else -> continue@loop
+ }
+
+ extra += (vec - region.origin) to extraChange
}
isLoaded = true
@@ -47,53 +54,65 @@ class Schematic {
suspend fun WorkerScope.paste(world: World, position: Vec3i) {
if (!isLoaded) throw IllegalStateException()
+
val region = Region(position, _size!!)
val blocks = traverser.traverseRegion(region, worldHeight = world.maxHeight)
val blockDatas = blockDatas!!
var postponed = hashMapOf<Vec3i, BlockData>()
- // 90% of the progress of this job is allocated to this code block
- delegateWork(0.9) {
- for ((index, vec) in blocks.withIndex()) {
- markSuspensionPoint()
- val block = world[vec]
- val type = blockDatas[index] ?: air
- if (type !== air && isAttachable(type.material)) {
- val supportingBlock = vec + getSupportingBlock(type)
-
- if (!postponed.containsKey(supportingBlock) && traverser.comesFirst(vec, supportingBlock)) {
- block.blockData = type
- } else {
- postponed[vec] = type
- }
+ val total = region.blockCount.toDouble()
+ var processed = 0
- } else {
+ for ((index, vec) in blocks.withIndex()) {
+ markSuspensionPoint()
+ setProgress(index / total)
+
+ val block = world[vec]
+ val type = blockDatas[index] ?: air
+ if (type !== air && isAttachable(type.material)) {
+ val supportingBlock = vec + getSupportingBlock(type)
+
+ if (!postponed.containsKey(supportingBlock) && traverser.comesFirst(vec, supportingBlock)) {
block.blockData = type
+ setProgress(++processed / total)
+ } else {
+ postponed[vec] = type
}
+
+ } else {
+ block.blockData = type
+ setProgress(++processed / total)
}
}
- delegateWork {
- while (!postponed.isEmpty()) {
- val newMap = hashMapOf<Vec3i, BlockData>()
- for ((vec, type) in postponed) {
- val supportingBlock = vec + getSupportingBlock(type)
- if (supportingBlock in postponed && supportingBlock != vec) {
- newMap[vec] = type
- } else {
- world[vec].blockData = type
- }
+ while (!postponed.isEmpty()) {
+ markSuspensionPoint()
+ val newMap = hashMapOf<Vec3i, BlockData>()
+ for ((vec, type) in postponed) {
+ val supportingBlock = vec + getSupportingBlock(type)
+ if (supportingBlock in postponed && supportingBlock != vec) {
+ newMap[vec] = type
+ } else {
+ world[vec].blockData = type
+ setProgress(++processed / total)
}
- postponed = newMap
}
+ postponed = newMap
+ }
+
+ // Should be negligible so we don't track progress
+ for ((vec, extraChange) in extra) {
+ markSuspensionPoint()
+ val block = world[position + vec]
+ extraChange.update(block)
}
}
- fun getLoadTask(world: World, region: Region): TimeLimitedTask = {
+ fun getLoadTask(world: World, region: Region): WorkerTask = {
load(world, region)
}
- fun getPasteTask(world: World, position: Vec3i): TimeLimitedTask = {
+ fun getPasteTask(world: World, position: Vec3i): WorkerTask = {
paste(world, position)
}