Chaos utilities.

This commit is contained in:
Alex Zenla 2023-04-04 21:13:27 -07:00
parent 139743a4ba
commit 6a05d5f29f
Signed by: alex
GPG Key ID: C0780728420EBFE5
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 {
implementation(project(":common-all"))
implementation(project(":common-plugin"))
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)
if (!player.isFlying) {
player.teleport(player.location.toHighestLocation().add(0.0, 1.0, 0.0))
player.teleportHighestLocation()
}
}
private fun rotateChunk(chunk: Chunk) {
val snapshot = chunk.chunkSnapshot
for (x in 0..15) {
for (z in 0..15) {
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
}
}
chunk.forEachBlock { x, y, z, rotatedBlock ->
val originalBlockData = snapshot.getBlockData(z, y, x)
rotatedBlock.blockData = originalBlockData
}
}
}

View File

@ -1,9 +1,9 @@
package gay.pizza.foundation.chaos.modules
import gay.pizza.foundation.chaos.randomPlayer
import gay.pizza.foundation.common.without
import org.bukkit.Chunk
import org.bukkit.ChunkSnapshot
import org.bukkit.Material
import org.bukkit.block.Block
import org.bukkit.block.data.BlockData
import org.bukkit.plugin.Plugin
@ -20,22 +20,12 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
val baseChunk = player.chunk
recordInvert(baseChunk)
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...")
fun scheduleOne() {
if (chunksToInvert.isEmpty()) {
return
}
val chunk = chunksToInvert.removeAt(0)
plugin.server.scheduler.runTaskLater(plugin, { ->
recordInvert(chunk)
scheduleOne()
}, 5)
plugin.server.scheduler.scheduleUntilEmpty(plugin, chunksToInvert, 5) { chunk ->
recordInvert(chunk)
}
scheduleOne()
}
fun recordInvert(chunk: Chunk) {
@ -60,20 +50,18 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
fun invertChunk(chunk: Chunk): ChunkInversion {
val snapshot = chunk.chunkSnapshot
for (x in 0..15) {
for (z in 0..15) {
var sy = chunk.world.minHeight
var ey = chunk.world.maxHeight
while (sy != ey) {
sy++
ey--
val targetBlock = chunk.getBlock(x, sy, z)
val targetBlockData = targetBlock.blockData.clone()
val nextBlock = chunk.getBlock(x, ey, z)
val nextBlockData = nextBlock.blockData.clone()
invertSetBlockData(targetBlock, nextBlockData)
invertSetBlockData(nextBlock, targetBlockData)
}
forEachChunkPosition { x, z ->
var sy = chunk.world.minHeight
var ey = chunk.world.maxHeight
while (sy != ey) {
sy++
ey--
val targetBlock = chunk.getBlock(x, sy, z)
val targetBlockData = targetBlock.blockData.clone()
val nextBlock = chunk.getBlock(x, ey, z)
val nextBlockData = nextBlock.blockData.clone()
invertSetBlockData(targetBlock, nextBlockData)
invertSetBlockData(nextBlock, targetBlockData)
}
}
return ChunkInversion(plugin, snapshot)
@ -83,23 +71,11 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
block.setBlockData(data, false)
}
class ChunkInversion(
val plugin: Plugin,
val snapshot: ChunkSnapshot
) {
class ChunkInversion(val plugin: Plugin, val snapshot: ChunkSnapshot) {
fun revert() {
val world = plugin.server.getWorld(snapshot.worldName) ?: return
val chunk = world.getChunkAt(snapshot.x, snapshot.z)
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
}
}
}
chunk.applyChunkSnapshot(snapshot)
}
}
}