Chaos utilities.

This commit is contained in:
2023-04-04 21:13:27 -07:00
parent 139743a4ba
commit 6a05d5f29f
5 changed files with 97 additions and 51 deletions

View File

@ -0,0 +1,3 @@
package gay.pizza.foundation.common
fun <T> Array<T>.without(value: T): List<T> = filter { it != value }

View File

@ -3,6 +3,7 @@ plugins {
} }
dependencies { dependencies {
implementation(project(":common-all"))
implementation(project(":common-plugin")) implementation(project(":common-plugin"))
compileOnly(project(":foundation-shared")) compileOnly(project(":foundation-shared"))
} }

View File

@ -0,0 +1,71 @@
package gay.pizza.foundation.chaos.modules
import org.bukkit.Chunk
import org.bukkit.ChunkSnapshot
import org.bukkit.World
import org.bukkit.block.Block
import org.bukkit.entity.Player
import org.bukkit.plugin.Plugin
import org.bukkit.scheduler.BukkitScheduler
val World.heightRange
get() = minHeight until maxHeight
inline fun forEachChunkPosition(crossinline each: (Int, Int) -> Unit) {
for (x in 0..15) {
for (z in 0..15) {
each(x, z)
}
}
}
inline fun Chunk.forEachPosition(crossinline each: (Int, Int, Int) -> Unit) {
for (x in 0..15) {
for (z in 0..15) {
for (y in world.heightRange) {
each(x, y, z)
}
}
}
}
inline fun Chunk.forEachBlock(crossinline each: (Int, Int, Int, Block) -> Unit) {
forEachPosition { x, y, z ->
each(x, y, z, getBlock(x, y, z))
}
}
fun Chunk.applyChunkSnapshot(snapshot: ChunkSnapshot) {
forEachPosition { x, y, z ->
val blockData = snapshot.getBlockData(x, y, z)
val block = getBlock(x, y, z)
block.blockData = blockData
}
}
fun Player.teleportHighestLocation() {
teleport(location.toHighestLocation().add(0.0, 1.0, 0.0))
}
fun <T> BukkitScheduler.scheduleUntilEmpty(
plugin: Plugin,
items: MutableList<T>,
ticksBetween: Long,
callback: (T) -> Unit
) {
fun performOne() {
if (items.isEmpty()) {
return
}
val item = items.removeAt(0)
callback(item)
if (items.isNotEmpty()) {
runTaskLater(plugin, { ->
performOne()
}, ticksBetween)
}
}
performOne()
}

View File

@ -23,20 +23,15 @@ class ChunkEnterRotate : ChaosModule {
} }
rotateChunk(currentChunk) rotateChunk(currentChunk)
if (!player.isFlying) { if (!player.isFlying) {
player.teleport(player.location.toHighestLocation().add(0.0, 1.0, 0.0)) player.teleportHighestLocation()
} }
} }
private fun rotateChunk(chunk: Chunk) { private fun rotateChunk(chunk: Chunk) {
val snapshot = chunk.chunkSnapshot val snapshot = chunk.chunkSnapshot
for (x in 0..15) { chunk.forEachBlock { x, y, z, rotatedBlock ->
for (z in 0..15) { val originalBlockData = snapshot.getBlockData(z, y, x)
for (y in chunk.world.minHeight until chunk.world.maxHeight) {
val rotatedBlock = chunk.getBlock(z, y, x)
val originalBlockData = snapshot.getBlockData(x, y, z)
rotatedBlock.blockData = originalBlockData rotatedBlock.blockData = originalBlockData
} }
} }
}
}
} }

View File

@ -1,9 +1,9 @@
package gay.pizza.foundation.chaos.modules package gay.pizza.foundation.chaos.modules
import gay.pizza.foundation.chaos.randomPlayer import gay.pizza.foundation.chaos.randomPlayer
import gay.pizza.foundation.common.without
import org.bukkit.Chunk import org.bukkit.Chunk
import org.bukkit.ChunkSnapshot import org.bukkit.ChunkSnapshot
import org.bukkit.Material
import org.bukkit.block.Block import org.bukkit.block.Block
import org.bukkit.block.data.BlockData import org.bukkit.block.data.BlockData
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
@ -20,22 +20,12 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
val baseChunk = player.chunk val baseChunk = player.chunk
recordInvert(baseChunk) recordInvert(baseChunk)
player.teleport(player.location.toHighestLocation()) player.teleport(player.location.toHighestLocation())
val chunksToInvert = player.world.loadedChunks.filter { it != baseChunk }.toMutableList() val chunksToInvert = player.world.loadedChunks.without(baseChunk).toMutableList()
println("Inverting ${chunksToInvert.size} chunks...") println("Inverting ${chunksToInvert.size} chunks...")
fun scheduleOne() { plugin.server.scheduler.scheduleUntilEmpty(plugin, chunksToInvert, 5) { chunk ->
if (chunksToInvert.isEmpty()) {
return
}
val chunk = chunksToInvert.removeAt(0)
plugin.server.scheduler.runTaskLater(plugin, { ->
recordInvert(chunk) recordInvert(chunk)
scheduleOne()
}, 5)
} }
scheduleOne()
} }
fun recordInvert(chunk: Chunk) { fun recordInvert(chunk: Chunk) {
@ -60,8 +50,7 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
fun invertChunk(chunk: Chunk): ChunkInversion { fun invertChunk(chunk: Chunk): ChunkInversion {
val snapshot = chunk.chunkSnapshot val snapshot = chunk.chunkSnapshot
for (x in 0..15) { forEachChunkPosition { x, z ->
for (z in 0..15) {
var sy = chunk.world.minHeight var sy = chunk.world.minHeight
var ey = chunk.world.maxHeight var ey = chunk.world.maxHeight
while (sy != ey) { while (sy != ey) {
@ -75,7 +64,6 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
invertSetBlockData(nextBlock, targetBlockData) invertSetBlockData(nextBlock, targetBlockData)
} }
} }
}
return ChunkInversion(plugin, snapshot) return ChunkInversion(plugin, snapshot)
} }
@ -83,23 +71,11 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
block.setBlockData(data, false) block.setBlockData(data, false)
} }
class ChunkInversion( class ChunkInversion(val plugin: Plugin, val snapshot: ChunkSnapshot) {
val plugin: Plugin,
val snapshot: ChunkSnapshot
) {
fun revert() { fun revert() {
val world = plugin.server.getWorld(snapshot.worldName) ?: return val world = plugin.server.getWorld(snapshot.worldName) ?: return
val chunk = world.getChunkAt(snapshot.x, snapshot.z) val chunk = world.getChunkAt(snapshot.x, snapshot.z)
chunk.applyChunkSnapshot(snapshot)
for (x in 0..15) {
for (z in 0..15) {
val heightRange = chunk.world.minHeight + 1 until chunk.world.maxHeight
for (y in heightRange) {
val originalBlock = snapshot.getBlockData(x, y, z)
chunk.getBlock(x, y, z).blockData = originalBlock
}
}
}
} }
} }
} }