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 { 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) { rotatedBlock.blockData = originalBlockData
val rotatedBlock = chunk.getBlock(z, y, x)
val originalBlockData = snapshot.getBlockData(x, y, z)
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()) { recordInvert(chunk)
return
}
val chunk = chunksToInvert.removeAt(0)
plugin.server.scheduler.runTaskLater(plugin, { ->
recordInvert(chunk)
scheduleOne()
}, 5)
} }
scheduleOne()
} }
fun recordInvert(chunk: Chunk) { fun recordInvert(chunk: Chunk) {
@ -60,20 +50,18 @@ 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) { sy++
sy++ ey--
ey-- val targetBlock = chunk.getBlock(x, sy, z)
val targetBlock = chunk.getBlock(x, sy, z) val targetBlockData = targetBlock.blockData.clone()
val targetBlockData = targetBlock.blockData.clone() val nextBlock = chunk.getBlock(x, ey, z)
val nextBlock = chunk.getBlock(x, ey, z) val nextBlockData = nextBlock.blockData.clone()
val nextBlockData = nextBlock.blockData.clone() invertSetBlockData(targetBlock, nextBlockData)
invertSetBlockData(targetBlock, nextBlockData) 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
}
}
}
} }
} }
} }