mirror of
				https://github.com/GayPizzaSpecifications/foundation.git
				synced 2025-11-04 11:39:39 +00:00 
			
		
		
		
	Chaos utilities.
This commit is contained in:
		@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					package gay.pizza.foundation.common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun <T> Array<T>.without(value: T): List<T> = filter { it != value }
 | 
				
			||||||
@ -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"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user