Skip to content

Commit

Permalink
Start SF structures
Browse files Browse the repository at this point in the history
  • Loading branch information
Seggan committed Sep 18, 2024
1 parent dd550c2 commit 1b77fc4
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import io.github.addoncommunity.galactifun.scripting.PlanetScript
import io.github.addoncommunity.galactifun.scripting.dsl.*
import io.github.addoncommunity.galactifun.scripting.dsl.gen.*
import io.github.addoncommunity.galactifun.scripting.evalScript
import io.github.addoncommunity.galactifun.serial.BlockVectorSerializer
import io.github.addoncommunity.galactifun.units.Angle.Companion.degrees
import io.github.addoncommunity.galactifun.units.Distance.Companion.au
import io.github.addoncommunity.galactifun.units.Distance.Companion.kilometers
import io.github.addoncommunity.galactifun.units.Mass.Companion.kilograms
import io.github.addoncommunity.galactifun.util.bukkit.plus
import io.github.addoncommunity.galactifun.util.general.log
import io.github.seggan.sf4k.AbstractAddon
import io.github.seggan.sf4k.serial.serializers.CustomSerializerRegistry
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun
import io.github.thebusybiscuit.slimefun4.libraries.paperlib.PaperLib
Expand Down Expand Up @@ -58,6 +60,7 @@ open class Galactifun2 : AbstractAddon() {
if (!isTest) {
Bukkit.spigot().config["world-settings.default.verbose"] = false
}
CustomSerializerRegistry.register(BlockVectorSerializer)
}

override suspend fun onEnableAsync() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.github.addoncommunity.galactifun.serial

import io.github.seggan.sf4k.serial.serializers.DelegatingSerializer
import kotlinx.serialization.builtins.IntArraySerializer
import org.bukkit.util.BlockVector

object BlockVectorSerializer : DelegatingSerializer<BlockVector, IntArray>(IntArraySerializer()) {
override fun toData(value: BlockVector): IntArray = intArrayOf(value.blockX, value.blockY, value.blockZ)
override fun fromData(value: IntArray): BlockVector = BlockVector(value[0], value[1], value[2])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package io.github.addoncommunity.galactifun.util

import io.github.addoncommunity.galactifun.util.bukkit.copy
import io.github.addoncommunity.galactifun.util.bukkit.key
import io.github.seggan.sf4k.serial.pdc.get
import io.github.seggan.sf4k.serial.pdc.set
import me.mrCookieSlime.Slimefun.api.BlockStorage
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.RegionAccessor
import org.bukkit.block.structure.Mirror
import org.bukkit.block.structure.StructureRotation
import org.bukkit.structure.Structure
import org.bukkit.util.BlockTransformer
import org.bukkit.util.BlockVector
import org.bukkit.util.EntityTransformer
import org.bukkit.util.Vector
import java.util.*
import kotlin.collections.set

@Suppress("UnstableApiUsage")
class SlimefunStructure(private val delegate: Structure) : Structure by delegate {

private var center: Vector = resetCenter()

companion object {
private val blockStorageKey = "block_storage".key()
}

override fun place(
location: Location,
includeEntities: Boolean,
structureRotation: StructureRotation,
mirror: Mirror,
palette: Int,
integrity: Float,
random: Random,
blockTransformers: MutableCollection<BlockTransformer>,
entityTransformers: MutableCollection<EntityTransformer>
) {
place(
location.world,
location.toVector().toBlockVector(),
includeEntities,
structureRotation,
mirror,
palette,
integrity,
random,
blockTransformers,
entityTransformers
)
}

override fun place(
regionAccessor: RegionAccessor,
location: BlockVector,
includeEntities: Boolean,
structureRotation: StructureRotation,
mirror: Mirror,
palette: Int,
integrity: Float,
random: Random
) {
place(
regionAccessor,
location,
includeEntities,
structureRotation,
mirror,
palette,
integrity,
random,
mutableListOf(),
mutableListOf()
)
}

override fun place(
location: Location,
includeEntities: Boolean,
structureRotation: StructureRotation,
mirror: Mirror,
palette: Int,
integrity: Float,
random: Random
) {
place(
location,
includeEntities,
structureRotation,
mirror,
palette,
integrity,
random,
mutableListOf(),
mutableListOf()
)
}

override fun place(
regionAccessor: RegionAccessor,
location: BlockVector,
includeEntities: Boolean,
structureRotation: StructureRotation,
mirror: Mirror,
palette: Int,
integrity: Float,
random: Random,
blockTransformers: MutableCollection<BlockTransformer>,
entityTransformers: MutableCollection<EntityTransformer>
) {
val data = persistentDataContainer.get<Map<BlockVector, Pair<String, Material>>>(blockStorageKey) ?: emptyMap()
val rotated = data.mapKeys { (vector, _) ->
val newVec = structureRotation.rotateAroundCenter(vector)
when (mirror) {
Mirror.NONE -> newVec
Mirror.FRONT_BACK -> newVec.copy(x = -newVec.x)
Mirror.LEFT_RIGHT -> newVec.copy(z = -newVec.z)
}
}
blockTransformers.add(BlockTransformer { region, x, y, z, current, _ ->
val vector = BlockVector(x, y, z).subtract(location)
val (json, material) = rotated[vector] ?: return@BlockTransformer current
if (current.type != material) return@BlockTransformer current // Block has been changed
val realLocation = Location(region.world, x.toDouble(), y.toDouble(), z.toDouble())
BlockStorage.setBlockInfo(realLocation, json, true)
return@BlockTransformer current
})
delegate.place(
regionAccessor,
location,
includeEntities,
structureRotation,
mirror,
palette,
integrity,
random,
blockTransformers,
entityTransformers
)
}

override fun fill(origin: Location, size: BlockVector, includeEntities: Boolean) {
val data = mutableMapOf<BlockVector, Pair<String, Material>>()
for (x in 0 until size.blockX) {
for (y in 0 until size.blockY) {
for (z in 0 until size.blockZ) {
val vector = BlockVector(x, y, z)
val block = origin.clone().add(vector).block
if (BlockStorage.hasBlockInfo(block)) {
data[vector] = BlockStorage.getBlockInfoAsJson(block) to block.type
}
}
}
}
delegate.fill(origin, size, includeEntities)
persistentDataContainer.set(blockStorageKey, data)
center = resetCenter()
}

override fun fill(corner1: Location, corner2: Location, includeEntities: Boolean) {
fill(corner1, corner2.clone().subtract(corner1).toVector().toBlockVector(), includeEntities)
}

private fun resetCenter(): Vector {
return size.clone().multiply(0.5).setY(0)
}

private fun StructureRotation.rotateAroundCenter(location: Vector): BlockVector {
val centered = location.clone().subtract(center)
val rotated = when (this) {
StructureRotation.NONE -> centered
StructureRotation.CLOCKWISE_90 -> centered.copy(x = -centered.z, z = centered.x)
StructureRotation.CLOCKWISE_180 -> centered.copy(x = -centered.x, z = -centered.z)
StructureRotation.COUNTERCLOCKWISE_90 -> centered.copy(x = centered.z, z = -centered.x)
}
return rotated.add(center).toBlockVector()
}
}

0 comments on commit 1b77fc4

Please sign in to comment.