Files
KSpigot/src/main/kotlin/net/axay/kspigot/structures/Circle.kt
2020-10-18 18:36:49 +02:00

104 lines
2.8 KiB
Kotlin

@file:Suppress("MemberVisibilityCanBePrivate")
package net.axay.kspigot.structures
import net.axay.kspigot.extensions.geometry.SimpleLocation2D
import net.axay.kspigot.extensions.geometry.SimpleLocation3D
import net.axay.kspigot.particles.KSpigotParticle
import org.bukkit.Material
import org.bukkit.entity.EntityType
private fun circleEdgeLocations(radius: Number) = HashSet<SimpleLocation2D>().apply {
val currentRadius = radius.toDouble()
var d = -currentRadius
var x = currentRadius
var y = 0
while (y <= x) {
addSimpleLoc2D(x, y)
addSimpleLoc2D(x, -y)
addSimpleLoc2D(-x, y)
addSimpleLoc2D(-x, -y)
addSimpleLoc2D(y, x)
addSimpleLoc2D(y, -x)
addSimpleLoc2D(-y, x)
addSimpleLoc2D(-y, -x)
d += 2 * y + 1
y++
if (d > 0) {
d += -2 * x + 2
x--
}
}
}
private fun MutableSet<SimpleLocation2D>.addSimpleLoc2D(first: Number, second: Number) {
this += SimpleLocation2D(first, second)
}
abstract class Circle(val radius: Number) {
protected abstract val data: StructureData
val fillLocations by lazy {
var currentRadius = radius.toDouble()
HashSet<SimpleLocation2D>().apply {
while (currentRadius >= 0) {
this += circleEdgeLocations(currentRadius).mapTo(HashSet()) {
mutableSetOf(it).apply {
this += SimpleLocation2D(
it.x + when {
it.x >= 1 -> -1; it.x <= -1 -> 1; else -> 0
}, it.y
)
this += SimpleLocation2D(
it.x, it.y + when {
it.y >= 1 -> -1; it.y <= -1 -> 1; else -> 0
}
)
}
}.flatten()
currentRadius--
}
}
}
val edgeLocations by lazy {
circleEdgeLocations(radius)
}
val filledStructure by lazy { structure(true) }
val edgeStructure by lazy { structure(false) }
fun structure(filled: Boolean) = Structure(
HashSet<SingleStructureData>().apply {
val locations = if (filled) fillLocations else edgeLocations
for (it in locations)
this += SingleStructureData(SimpleLocation3D(it.x, 0, it.y), data)
}
)
}
class MaterialCircle(radius: Number, material: Material) : Circle(radius) {
override val data = StructureDataMaterial(material)
}
class ParticleCircle(radius: Number, particle: KSpigotParticle) : Circle(radius) {
override val data = StructureDataParticle(particle)
}
class EntityCircle(radius: Number, entityType: EntityType) : Circle(radius) {
override val data = StructureDataEntity(entityType)
}