mirror of
				https://github.com/GayPizzaSpecifications/foundation.git
				synced 2025-11-03 19:29:38 +00:00 
			
		
		
		
	Implement chunk inversion system.
This commit is contained in:
		@ -1,7 +1,11 @@
 | 
			
		||||
package gay.pizza.foundation.chaos.modules
 | 
			
		||||
 | 
			
		||||
import gay.pizza.foundation.chaos.randomPlayer
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
class WorldSwapper(val plugin: Plugin) : ChaosModule {
 | 
			
		||||
@ -9,38 +13,91 @@ class WorldSwapper(val plugin: Plugin) : ChaosModule {
 | 
			
		||||
  override fun name(): String = "World Swapper"
 | 
			
		||||
  override fun what(): String = "Swaps the world vertically on activation, and un-swaps it on deactivation."
 | 
			
		||||
 | 
			
		||||
  var snapshot: ChunkSnapshot? = null
 | 
			
		||||
  var chunkInversions = mutableListOf<ChunkInversion>()
 | 
			
		||||
 | 
			
		||||
  override fun activate() {
 | 
			
		||||
    val player = plugin.server.randomPlayer() ?: return
 | 
			
		||||
    val chunk = player.world.getChunkAt(player.location)
 | 
			
		||||
    val localSnapshot = chunk.chunkSnapshot
 | 
			
		||||
    val baseChunk = player.chunk
 | 
			
		||||
    recordInvert(baseChunk)
 | 
			
		||||
    player.teleport(player.location.toHighestLocation())
 | 
			
		||||
    val chunksToInvert = player.world.loadedChunks.filter { it != baseChunk }.toMutableList()
 | 
			
		||||
 | 
			
		||||
    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 targetBlock = chunk.getBlock(x, y, z)
 | 
			
		||||
          val inverseY = heightRange.random()
 | 
			
		||||
          val nextBlock = localSnapshot.getBlockData(x, inverseY, z)
 | 
			
		||||
          targetBlock.setBlockData(nextBlock, true)
 | 
			
		||||
        }
 | 
			
		||||
    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)
 | 
			
		||||
    }
 | 
			
		||||
    snapshot = localSnapshot
 | 
			
		||||
 | 
			
		||||
    scheduleOne()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fun recordInvert(chunk: Chunk) {
 | 
			
		||||
    chunkInversions.add(invertChunk(chunk))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  override fun deactivate() {
 | 
			
		||||
    val localSnapshot = snapshot ?: return
 | 
			
		||||
    val world = plugin.server.getWorld(localSnapshot.worldName) ?: return
 | 
			
		||||
    val chunk = world.getChunkAt(localSnapshot.x, localSnapshot.z)
 | 
			
		||||
    fun scheduleOne() {
 | 
			
		||||
      if (chunkInversions.isEmpty()) {
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      val inversion = chunkInversions.removeAt(0)
 | 
			
		||||
      plugin.server.scheduler.runTaskLater(plugin, { ->
 | 
			
		||||
        inversion.revert()
 | 
			
		||||
        scheduleOne()
 | 
			
		||||
      }, 5)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    scheduleOne()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fun invertChunk(chunk: Chunk): ChunkInversion {
 | 
			
		||||
    val snapshot = chunk.chunkSnapshot
 | 
			
		||||
    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 = localSnapshot.getBlockData(x, y, z)
 | 
			
		||||
          chunk.getBlock(x, y, z).blockData = originalBlock
 | 
			
		||||
        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)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private fun invertSetBlockData(block: Block, data: BlockData) {
 | 
			
		||||
    block.setBlockData(data, false)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user