1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
package io.dico.parcels2
import io.dico.parcels2.blockvisitor.*
import io.dico.parcels2.util.Region
import io.dico.parcels2.util.Vec2i
import io.dico.parcels2.util.get
import kotlinx.coroutines.CoroutineScope
import org.bukkit.Chunk
import org.bukkit.Location
import org.bukkit.World
import org.bukkit.block.Biome
import org.bukkit.block.Block
import org.bukkit.entity.Entity
import org.bukkit.generator.BlockPopulator
import org.bukkit.generator.ChunkGenerator
import java.util.Random
abstract class ParcelGenerator : ChunkGenerator() {
abstract val worldName: String
abstract val world: World
abstract override fun generateChunkData(world: World?, random: Random?, chunkX: Int, chunkZ: Int, biome: BiomeGrid?): ChunkData
abstract fun populate(world: World?, random: Random?, chunk: Chunk?)
abstract override fun getFixedSpawnLocation(world: World?, random: Random?): Location
override fun getDefaultPopulators(world: World?): MutableList<BlockPopulator> {
return mutableListOf(object : BlockPopulator() {
override fun populate(world: World?, random: Random?, chunk: Chunk?) {
this@ParcelGenerator.populate(world, random, chunk)
}
})
}
abstract fun makeParcelLocatorAndBlockManager(worldId: ParcelWorldId,
container: ParcelContainer,
coroutineScope: CoroutineScope,
worktimeLimiter: WorktimeLimiter): Pair<ParcelLocator, ParcelBlockManager>
}
interface ParcelBlockManager {
val world: World
val worktimeLimiter: WorktimeLimiter
val parcelTraverser: RegionTraverser
// fun getBottomBlock(parcel: ParcelId): Vec2i
fun getHomeLocation(parcel: ParcelId): Location
fun getRegion(parcel: ParcelId): Region
fun getEntities(parcel: ParcelId): Collection<Entity>
fun setOwnerBlock(parcel: ParcelId, owner: PlayerProfile?)
fun setBiome(parcel: ParcelId, biome: Biome): Worker
fun clearParcel(parcel: ParcelId): Worker
fun submitBlockVisitor(parcelId: ParcelId, task: TimeLimitedTask): Worker
/**
* Used to update owner blocks in the corner of the parcel
*/
fun getParcelsWithOwnerBlockIn(chunk: Chunk): Collection<Vec2i>
}
inline fun ParcelBlockManager.doBlockOperation(parcel: ParcelId,
traverser: RegionTraverser,
crossinline operation: suspend WorkerScope.(Block) -> Unit) = submitBlockVisitor(parcel) {
val region = getRegion(parcel)
val blockCount = region.blockCount.toDouble()
val blocks = traverser.traverseRegion(region)
for ((index, vec) in blocks.withIndex()) {
markSuspensionPoint()
operation(world[vec])
setProgress((index + 1) / blockCount)
}
}
abstract class ParcelBlockManagerBase : ParcelBlockManager {
override fun getEntities(parcel: ParcelId): Collection<Entity> {
val region = getRegion(parcel)
val center = region.center
val centerLoc = Location(world, center.x, center.y, center.z)
val centerDist = (center - region.origin).add(0.2, 0.2, 0.2)
return world.getNearbyEntities(centerLoc, centerDist.x, centerDist.y, centerDist.z)
}
}
|