feat: データ形式の修正とvisualize
This commit is contained in:
parent
c33cd859fe
commit
8fcacf37ff
1
hcu-core
Submodule
1
hcu-core
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 520a378cd5c3da6321305d07cc0b402b73292add
|
||||
|
|
@ -4,6 +4,7 @@ import io.papermc.paper.math.Position
|
|||
import net.hareworks.hcu.lands.App
|
||||
import net.hareworks.hcu.lands.model.Land
|
||||
import net.hareworks.hcu.lands.model.Shape
|
||||
import net.hareworks.hcu.lands.model.normalizeToBlockInt
|
||||
import net.hareworks.hcu.lands.task.LandsVisualizer
|
||||
import net.hareworks.kommand_lib.kommand
|
||||
import net.kyori.adventure.text.Component
|
||||
|
|
@ -88,7 +89,14 @@ class LandsCommand(
|
|||
executes {
|
||||
val p1: Position = argument("pos1")
|
||||
val p2: Position = argument("pos2")
|
||||
val shape = Shape.Cuboid(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z())
|
||||
val shape = Shape.Cuboid(
|
||||
normalizeToBlockInt(p1.x()),
|
||||
normalizeToBlockInt(p1.y()),
|
||||
normalizeToBlockInt(p1.z()),
|
||||
normalizeToBlockInt(p2.x()),
|
||||
normalizeToBlockInt(p2.y()),
|
||||
normalizeToBlockInt(p2.z())
|
||||
)
|
||||
val name: String = argument("name")
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
|
|
@ -102,14 +110,26 @@ class LandsCommand(
|
|||
literal("cylinder") {
|
||||
blockCoordinates("center") {
|
||||
float("radius") {
|
||||
float("height") {
|
||||
literal("center") {
|
||||
integer("totalHeight", min = 1) {
|
||||
executes {
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val h: Double = argument("height")
|
||||
val shape = Shape.Cylinder(c.x(), c.y(), c.z(), r, h)
|
||||
val total: Int = argument("totalHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
// Subtract 1 for center block, distribute remaining
|
||||
val remaining = total - 1
|
||||
val topH = (remaining + 1) / 2 // Prefer top
|
||||
val bottomH = remaining - topH
|
||||
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, bottomH, topH
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
parts.add(shape)
|
||||
sender.sendMessage(Component.text("Shape added.", NamedTextColor.GREEN))
|
||||
|
|
@ -117,6 +137,76 @@ class LandsCommand(
|
|||
}
|
||||
}
|
||||
}
|
||||
literal("top") {
|
||||
integer("topHeight", min = 1) {
|
||||
literal("bottom") {
|
||||
integer("bottomHeight", min = 0) {
|
||||
executes {
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val topH: Int = argument("topHeight")
|
||||
val bottomH: Int = argument("bottomHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, bottomH, topH
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
parts.add(shape)
|
||||
sender.sendMessage(Component.text("Shape added.", NamedTextColor.GREEN))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
executes {
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val total: Int = argument("topHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
// total - 1 goes to top, 0 to bottom
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, 0, total - 1
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
parts.add(shape)
|
||||
sender.sendMessage(Component.text("Shape added.", NamedTextColor.GREEN))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
literal("bottom") {
|
||||
integer("bottomHeight", min = 1) {
|
||||
executes {
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val total: Int = argument("bottomHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
// total - 1 goes to bottom, 0 to top
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, total - 1, 0
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
parts.add(shape)
|
||||
sender.sendMessage(Component.text("Shape added.", NamedTextColor.GREEN))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -130,7 +220,14 @@ class LandsCommand(
|
|||
val index: Int = argument("index")
|
||||
val p1: Position = argument("pos1")
|
||||
val p2: Position = argument("pos2")
|
||||
val shape = Shape.Cuboid(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z())
|
||||
val shape = Shape.Cuboid(
|
||||
normalizeToBlockInt(p1.x()),
|
||||
normalizeToBlockInt(p1.y()),
|
||||
normalizeToBlockInt(p1.z()),
|
||||
normalizeToBlockInt(p2.x()),
|
||||
normalizeToBlockInt(p2.y()),
|
||||
normalizeToBlockInt(p2.z())
|
||||
)
|
||||
val name: String = argument("name")
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
|
|
@ -148,15 +245,26 @@ class LandsCommand(
|
|||
literal("cylinder") {
|
||||
blockCoordinates("center") {
|
||||
float("radius") {
|
||||
float("height") {
|
||||
literal("center") {
|
||||
integer("totalHeight", min = 1) {
|
||||
executes {
|
||||
val index: Int = argument("index")
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val h: Double = argument("height")
|
||||
val shape = Shape.Cylinder(c.x(), c.y(), c.z(), r, h)
|
||||
val total: Int = argument("totalHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
val remaining = total - 1
|
||||
val topH = (remaining + 1) / 2
|
||||
val bottomH = remaining - topH
|
||||
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, bottomH, topH
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
if (index in parts.indices) {
|
||||
parts[index] = shape
|
||||
|
|
@ -168,6 +276,89 @@ class LandsCommand(
|
|||
}
|
||||
}
|
||||
}
|
||||
literal("top") {
|
||||
integer("topHeight", min = 1) {
|
||||
literal("bottom") {
|
||||
integer("bottomHeight", min = 0) {
|
||||
executes {
|
||||
val index: Int = argument("index")
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val topH: Int = argument("topHeight")
|
||||
val bottomH: Int = argument("bottomHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, bottomH, topH
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
if (index in parts.indices) {
|
||||
parts[index] = shape
|
||||
sender.sendMessage(Component.text("Shape modified at index $index.", NamedTextColor.GREEN))
|
||||
} else {
|
||||
sender.sendMessage(Component.text("Index out of bounds.", NamedTextColor.RED))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
executes {
|
||||
val index: Int = argument("index")
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val total: Int = argument("topHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, 0, total - 1
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
if (index in parts.indices) {
|
||||
parts[index] = shape
|
||||
sender.sendMessage(Component.text("Shape modified at index $index.", NamedTextColor.GREEN))
|
||||
} else {
|
||||
sender.sendMessage(Component.text("Index out of bounds.", NamedTextColor.RED))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
literal("bottom") {
|
||||
integer("bottomHeight", min = 1) {
|
||||
executes {
|
||||
val index: Int = argument("index")
|
||||
val c: Position = argument("center")
|
||||
val r: Double = argument("radius")
|
||||
val total: Int = argument("bottomHeight")
|
||||
val name: String = argument("name")
|
||||
|
||||
val shape = Shape.Cylinder(
|
||||
normalizeToBlockInt(c.x()),
|
||||
normalizeToBlockInt(c.y()),
|
||||
normalizeToBlockInt(c.z()),
|
||||
r, total - 1, 0
|
||||
)
|
||||
|
||||
updateLandData(sender, name) { parts ->
|
||||
if (index in parts.indices) {
|
||||
parts[index] = shape
|
||||
sender.sendMessage(Component.text("Shape modified at index $index.", NamedTextColor.GREEN))
|
||||
} else {
|
||||
sender.sendMessage(Component.text("Index out of bounds.", NamedTextColor.RED))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ sealed class Shape {
|
|||
@Serializable
|
||||
@SerialName("cuboid")
|
||||
data class Cuboid(
|
||||
val x1: Double, val y1: Double, val z1: Double,
|
||||
val x2: Double, val y2: Double, val z2: Double
|
||||
val x1: Int, val y1: Int, val z1: Int,
|
||||
val x2: Int, val y2: Int, val z2: Int
|
||||
) : Shape() {
|
||||
fun minX() = minOf(x1, x2)
|
||||
fun maxX() = maxOf(x1, x2)
|
||||
|
|
@ -32,24 +32,63 @@ sealed class Shape {
|
|||
fun maxZ() = maxOf(z1, z2)
|
||||
|
||||
fun contains(x: Double, y: Double, z: Double): Boolean {
|
||||
return x >= minX() && x <= maxX() &&
|
||||
y >= minY() && y <= maxY() &&
|
||||
z >= minZ() && z <= maxZ()
|
||||
// Add 0.5 to block coordinates for center-based comparison
|
||||
return x >= minX() + 0.5 && x <= maxX() + 0.5 &&
|
||||
y >= minY() + 0.5 && y <= maxY() + 0.5 &&
|
||||
z >= minZ() + 0.5 && z <= maxZ() + 0.5
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the two corner blocks (min and max corners) for visualization
|
||||
*/
|
||||
fun getCornerBlocks(): Pair<Triple<Int, Int, Int>, Triple<Int, Int, Int>> {
|
||||
val minCorner = Triple(minX(), minY(), minZ())
|
||||
val maxCorner = Triple(maxX(), maxY(), maxZ())
|
||||
return minCorner to maxCorner
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@SerialName("cylinder")
|
||||
data class Cylinder(
|
||||
val x: Double, val y: Double, val z: Double,
|
||||
val x: Int, val y: Int, val z: Int,
|
||||
val radius: Double,
|
||||
val height: Double // Assuming vertical cylinder
|
||||
val bottomHeight: Int, // Height extending downward from center block
|
||||
val topHeight: Int // Height extending upward from center block
|
||||
) : Shape() {
|
||||
fun contains(tx: Double, ty: Double, tz: Double): Boolean {
|
||||
if (ty < y || ty > y + height) return false
|
||||
val dx = tx - x
|
||||
val dz = tz - z
|
||||
// Add 0.5 to block coordinates for center-based comparison
|
||||
val centerX = x + 0.5
|
||||
val centerY = y + 0.5
|
||||
val centerZ = z + 0.5
|
||||
|
||||
// Total height includes center block (1) + bottomHeight + topHeight
|
||||
val minY = centerY - bottomHeight
|
||||
val maxY = centerY + 1.0 + topHeight
|
||||
|
||||
if (ty < minY || ty > maxY) return false
|
||||
val dx = tx - centerX
|
||||
val dz = tz - centerZ
|
||||
return (dx * dx + dz * dz) <= (radius * radius)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the center block for visualization
|
||||
*/
|
||||
fun getCenterBlock(): Triple<Int, Int, Int> {
|
||||
return Triple(x, y, z)
|
||||
}
|
||||
|
||||
/**
|
||||
* Total height of the cylinder including center block
|
||||
*/
|
||||
fun totalHeight(): Int = 1 + bottomHeight + topHeight
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a coordinate to block integer (floor)
|
||||
*/
|
||||
fun normalizeToBlockInt(coord: Double): Int {
|
||||
return kotlin.math.floor(coord).toInt()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,40 +51,149 @@ class VisualizerTask(private val landService: LandService) : Runnable {
|
|||
}
|
||||
|
||||
private fun drawCuboid(player: Player, cuboid: Shape.Cuboid) {
|
||||
// Draw edges
|
||||
val minX = cuboid.minX()
|
||||
val maxX = cuboid.maxX()
|
||||
val minY = cuboid.minY()
|
||||
val maxY = cuboid.maxY()
|
||||
val minZ = cuboid.minZ()
|
||||
val maxZ = cuboid.maxZ()
|
||||
val (minCorner, maxCorner) = cuboid.getCornerBlocks()
|
||||
|
||||
// Just corners for now or simple lines
|
||||
// A simple way to visualize is to spawn particles at corners and periodically along edges
|
||||
// Doing full wireframe every tick is heavy.
|
||||
// Let's do corners.
|
||||
val corners = listOf(
|
||||
Triple(minX, minY, minZ), Triple(maxX, minY, minZ),
|
||||
Triple(minX, maxY, minZ), Triple(maxX, maxY, minZ),
|
||||
Triple(minX, minY, maxZ), Triple(maxX, minY, maxZ),
|
||||
Triple(minX, maxY, maxZ), Triple(maxX, maxY, maxZ)
|
||||
)
|
||||
corners.forEach { (x, y, z) ->
|
||||
player.spawnParticle(Particle.DUST, x, y, z, 1, 0.0, 0.0, 0.0, Particle.DustOptions(Color.LIME, 1.0f))
|
||||
}
|
||||
// Draw outline of min corner block
|
||||
drawBlockOutline(player, minCorner.first, minCorner.second, minCorner.third, Color.LIME)
|
||||
|
||||
// Draw outline of max corner block
|
||||
drawBlockOutline(player, maxCorner.first, maxCorner.second, maxCorner.third, Color.YELLOW)
|
||||
|
||||
// Draw edges of the cuboid using outer corners
|
||||
// Min corner is at block position, max corner extends to outer edge (+1.0)
|
||||
val minX = cuboid.minX().toDouble()
|
||||
val maxX = cuboid.maxX() + 1.0
|
||||
val minY = cuboid.minY().toDouble()
|
||||
val maxY = cuboid.maxY() + 1.0
|
||||
val minZ = cuboid.minZ().toDouble()
|
||||
val maxZ = cuboid.maxZ() + 1.0
|
||||
|
||||
val edgeColor = Particle.DustOptions(Color.fromRGB(100, 255, 100), 0.75f)
|
||||
val step = 0.5
|
||||
|
||||
// Bottom face edges
|
||||
drawLine(player, minX, minY, minZ, maxX, minY, minZ, edgeColor, step)
|
||||
drawLine(player, maxX, minY, minZ, maxX, minY, maxZ, edgeColor, step)
|
||||
drawLine(player, maxX, minY, maxZ, minX, minY, maxZ, edgeColor, step)
|
||||
drawLine(player, minX, minY, maxZ, minX, minY, minZ, edgeColor, step)
|
||||
|
||||
// Top face edges
|
||||
drawLine(player, minX, maxY, minZ, maxX, maxY, minZ, edgeColor, step)
|
||||
drawLine(player, maxX, maxY, minZ, maxX, maxY, maxZ, edgeColor, step)
|
||||
drawLine(player, maxX, maxY, maxZ, minX, maxY, maxZ, edgeColor, step)
|
||||
drawLine(player, minX, maxY, maxZ, minX, maxY, minZ, edgeColor, step)
|
||||
|
||||
// Vertical edges
|
||||
drawLine(player, minX, minY, minZ, minX, maxY, minZ, edgeColor, step)
|
||||
drawLine(player, maxX, minY, minZ, maxX, maxY, minZ, edgeColor, step)
|
||||
drawLine(player, maxX, minY, maxZ, maxX, maxY, maxZ, edgeColor, step)
|
||||
drawLine(player, minX, minY, maxZ, minX, maxY, maxZ, edgeColor, step)
|
||||
}
|
||||
|
||||
private fun drawCylinder(player: Player, cylinder: Shape.Cylinder) {
|
||||
val segments = 20
|
||||
val step = (Math.PI * 2) / segments
|
||||
// Top and Bottom circles
|
||||
for (i in 0 until segments) {
|
||||
val angle = i * step
|
||||
val dx = cos(angle) * cylinder.radius
|
||||
val dz = sin(angle) * cylinder.radius
|
||||
val center = cylinder.getCenterBlock()
|
||||
|
||||
player.spawnParticle(Particle.DUST, cylinder.x + dx, cylinder.y, cylinder.z + dz, 1, 0.0, 0.0, 0.0, Particle.DustOptions(Color.AQUA, 1.0f))
|
||||
player.spawnParticle(Particle.DUST, cylinder.x + dx, cylinder.y + cylinder.height, cylinder.z + dz, 1, 0.0, 0.0, 0.0, Particle.DustOptions(Color.AQUA, 1.0f))
|
||||
// Draw outline of center block
|
||||
drawBlockOutline(player, center.first, center.second, center.third, Color.AQUA)
|
||||
|
||||
// Draw cylinder edges (top and bottom circles + vertical lines)
|
||||
// Add 0.5 to block coordinates for center on X/Z axis
|
||||
val centerX = cylinder.x + 0.5
|
||||
val centerZ = cylinder.z + 0.5
|
||||
|
||||
// Y coordinates use block boundaries (no +0.5 offset)
|
||||
val bottomY = cylinder.y.toDouble() - cylinder.bottomHeight
|
||||
val topY = cylinder.y.toDouble() + 1.0 + cylinder.topHeight
|
||||
|
||||
val segments = 32
|
||||
val step = (Math.PI * 2) / segments
|
||||
val edgeColor = Particle.DustOptions(Color.fromRGB(100, 200, 255), 0.75f)
|
||||
|
||||
// Bottom circle
|
||||
for (i in 0 until segments) {
|
||||
val angle1 = i * step
|
||||
val angle2 = (i + 1) * step
|
||||
val x1 = centerX + cos(angle1) * cylinder.radius
|
||||
val z1 = centerZ + sin(angle1) * cylinder.radius
|
||||
val x2 = centerX + cos(angle2) * cylinder.radius
|
||||
val z2 = centerZ + sin(angle2) * cylinder.radius
|
||||
|
||||
drawLine(player, x1, bottomY, z1, x2, bottomY, z2, edgeColor, 0.25)
|
||||
}
|
||||
|
||||
// Top circle
|
||||
for (i in 0 until segments) {
|
||||
val angle1 = i * step
|
||||
val angle2 = (i + 1) * step
|
||||
val x1 = centerX + cos(angle1) * cylinder.radius
|
||||
val z1 = centerZ + sin(angle1) * cylinder.radius
|
||||
val x2 = centerX + cos(angle2) * cylinder.radius
|
||||
val z2 = centerZ + sin(angle2) * cylinder.radius
|
||||
|
||||
drawLine(player, x1, topY, z1, x2, topY, z2, edgeColor, 0.25)
|
||||
}
|
||||
|
||||
// Vertical lines (8 cardinal directions)
|
||||
val verticalSegments = 8
|
||||
for (i in 0 until verticalSegments) {
|
||||
val angle = i * (Math.PI * 2) / verticalSegments
|
||||
val x = centerX + cos(angle) * cylinder.radius
|
||||
val z = centerZ + sin(angle) * cylinder.radius
|
||||
|
||||
drawLine(player, x, bottomY, z, x, topY, z, edgeColor, 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an outline of a block using particles
|
||||
*/
|
||||
private fun drawBlockOutline(player: Player, x: Int, y: Int, z: Int, color: Color) {
|
||||
val dustOptions = Particle.DustOptions(color, 1.0f)
|
||||
val step = 0.25 // Particle spacing along edges
|
||||
|
||||
// Bottom face edges
|
||||
drawLine(player, x.toDouble(), y.toDouble(), z.toDouble(), x + 1.0, y.toDouble(), z.toDouble(), dustOptions, step)
|
||||
drawLine(player, x + 1.0, y.toDouble(), z.toDouble(), x + 1.0, y.toDouble(), z + 1.0, dustOptions, step)
|
||||
drawLine(player, x + 1.0, y.toDouble(), z + 1.0, x.toDouble(), y.toDouble(), z + 1.0, dustOptions, step)
|
||||
drawLine(player, x.toDouble(), y.toDouble(), z + 1.0, x.toDouble(), y.toDouble(), z.toDouble(), dustOptions, step)
|
||||
|
||||
// Top face edges
|
||||
drawLine(player, x.toDouble(), y + 1.0, z.toDouble(), x + 1.0, y + 1.0, z.toDouble(), dustOptions, step)
|
||||
drawLine(player, x + 1.0, y + 1.0, z.toDouble(), x + 1.0, y + 1.0, z + 1.0, dustOptions, step)
|
||||
drawLine(player, x + 1.0, y + 1.0, z + 1.0, x.toDouble(), y + 1.0, z + 1.0, dustOptions, step)
|
||||
drawLine(player, x.toDouble(), y + 1.0, z + 1.0, x.toDouble(), y + 1.0, z.toDouble(), dustOptions, step)
|
||||
|
||||
// Vertical edges
|
||||
drawLine(player, x.toDouble(), y.toDouble(), z.toDouble(), x.toDouble(), y + 1.0, z.toDouble(), dustOptions, step)
|
||||
drawLine(player, x + 1.0, y.toDouble(), z.toDouble(), x + 1.0, y + 1.0, z.toDouble(), dustOptions, step)
|
||||
drawLine(player, x + 1.0, y.toDouble(), z + 1.0, x + 1.0, y + 1.0, z + 1.0, dustOptions, step)
|
||||
drawLine(player, x.toDouble(), y.toDouble(), z + 1.0, x.toDouble(), y + 1.0, z + 1.0, dustOptions, step)
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a line of particles between two points
|
||||
*/
|
||||
private fun drawLine(
|
||||
player: Player,
|
||||
x1: Double, y1: Double, z1: Double,
|
||||
x2: Double, y2: Double, z2: Double,
|
||||
dustOptions: Particle.DustOptions,
|
||||
step: Double
|
||||
) {
|
||||
val dx = x2 - x1
|
||||
val dy = y2 - y1
|
||||
val dz = z2 - z1
|
||||
val distance = kotlin.math.sqrt(dx * dx + dy * dy + dz * dz)
|
||||
val steps = (distance / step).toInt()
|
||||
|
||||
if (steps == 0) return
|
||||
|
||||
for (i in 0..steps) {
|
||||
val t = i.toDouble() / steps
|
||||
val x = x1 + dx * t
|
||||
val y = y1 + dy * t
|
||||
val z = z1 + dz * t
|
||||
player.spawnParticle(Particle.DUST, x, y, z, 1, 0.0, 0.0, 0.0, dustOptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user