You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
spigot-chunkmaster/src/main/kotlin/net/trivernis/chunkmaster/lib/shapes/Spiral.kt

110 lines
3.7 KiB
Kotlin

package net.trivernis.chunkmaster.lib.shapes
import kotlin.math.abs
import kotlin.math.pow
4 years ago
class Spiral(center: Pair<Int, Int>, start: Pair<Int, Int>, radius: Int) : Shape(center, start, radius) {
private var direction = 0
override fun endReached(): Boolean {
val distances = getDistances(center, currentPos)
Feature/async chunkmaster (#81) * Change generation to be asynchronous At this stage it will most likely crash the server at a certain point. Pausing and resuming isn't stable. Saving the progress isn't stable as well. Chunks are being unloaded in the main thread by an unloader class. * Switch to native threads - Use thread instead of async tasks - Store pending paper chunks in the database - Interrupt the thread when it should be stopped * Fix insertion of pending chunks Fix an error that is thrown when the sql for inserting pending chunks doesn't have any chunks to insert. * Add task states Add states to differentiate between generating and validating tasks as well as a field in the database to store this information. A task will first generate a world until the required radius or the worldborder is reached. Then it validates that each chunk has been generated. * Add object representation of world_properties table * Add DAO for pending_chunks table * Add DAO for generation_tasks table * Add state updating to periodic save * Fix loading of world properties * Add states to tasks and fix completion handling * Fix progress report and spiral shape * Modify the paper generation task so it works with spigot This change is being made because normal chunk generation doesn't allow chunks to be requested from a different thread. With PaperLib this issue can be solved. * Add workarounds for spigot problems * Fix some blocking issues and update README * Add locking to ChunkUnloader class
4 years ago
return radius > 0 && ((direction == 3
&& abs(distances.first) == abs(distances.second)
&& abs(distances.first) == radius)
|| (distances.first > radius || distances.second > radius))
}
override fun total(): Double {
return (radius * 2).toDouble().pow(2)
}
override fun progress(maxRadius: Int?): Double {
return if (maxRadius != null) {
(count / (maxRadius * 2).toDouble().pow(2)).coerceAtMost(1.0)
} else {
(count / (radius * 2).toDouble().pow(2)).coerceAtMost(1.0)
}
}
override fun currentRadius(): Int {
val distances = getDistances(center, currentPos)
return distances.first.coerceAtLeast(distances.second)
}
/**
* Returns the next value in the spiral
*/
override fun next(): Pair<Int, Int> {
Feature/async chunkmaster (#81) * Change generation to be asynchronous At this stage it will most likely crash the server at a certain point. Pausing and resuming isn't stable. Saving the progress isn't stable as well. Chunks are being unloaded in the main thread by an unloader class. * Switch to native threads - Use thread instead of async tasks - Store pending paper chunks in the database - Interrupt the thread when it should be stopped * Fix insertion of pending chunks Fix an error that is thrown when the sql for inserting pending chunks doesn't have any chunks to insert. * Add task states Add states to differentiate between generating and validating tasks as well as a field in the database to store this information. A task will first generate a world until the required radius or the worldborder is reached. Then it validates that each chunk has been generated. * Add object representation of world_properties table * Add DAO for pending_chunks table * Add DAO for generation_tasks table * Add state updating to periodic save * Fix loading of world properties * Add states to tasks and fix completion handling * Fix progress report and spiral shape * Modify the paper generation task so it works with spigot This change is being made because normal chunk generation doesn't allow chunks to be requested from a different thread. With PaperLib this issue can be solved. * Add workarounds for spigot problems * Fix some blocking issues and update README * Add locking to ChunkUnloader class
4 years ago
if (endReached()) {
return currentPos
}
if (count == 0 && currentPos != center) {
// simulate the spiral to get the correct direction and count
val simSpiral = Spiral(center, center, radius)
while (simSpiral.next() != currentPos && !simSpiral.endReached());
direction = simSpiral.direction
count = simSpiral.count
}
if (count == 1) { // because of the center behaviour
4 years ago
count++
return currentPos
}
if (currentPos == center) { // the center has to be handled exclusively
currentPos = Pair(center.first, center.second + 1)
4 years ago
count++
return center
} else {
val distances = getDistances(center, currentPos)
if (abs(distances.first) == abs(distances.second)) {
4 years ago
direction = (direction + 1) % 5
}
4 years ago
}
when (direction) {
0 -> {
currentPos = Pair(currentPos.first + 1, currentPos.second)
}
1 -> {
currentPos = Pair(currentPos.first, currentPos.second - 1)
}
2 -> {
currentPos = Pair(currentPos.first - 1, currentPos.second)
}
3 -> {
currentPos = Pair(currentPos.first, currentPos.second + 1)
}
4 -> {
currentPos = Pair(currentPos.first, currentPos.second + 1)
direction = 0
}
}
4 years ago
count++
return currentPos
}
/**
* Returns the edges to be used with dynmap markers
*/
override fun getShapeEdgeLocations(): List<Pair<Int, Int>> {
val a = Pair(this.radius + center.first, this.radius + center.second)
val b = Pair(this.radius + center.first, -this.radius + center.second)
val c = Pair(-this.radius + center.first, -this.radius + center.second)
val d = Pair(-this.radius + center.first, this.radius + center.second)
return listOf(a, b, c, d, a)
}
/**
* Returns the distances between 2 coordinates
*/
private fun getDistances(pos1: Pair<Int, Int>, pos2: Pair<Int, Int>): Pair<Int, Int> {
return Pair(pos2.first - pos1.first, pos2.second - pos1.second)
}
Feature/async chunkmaster (#81) * Change generation to be asynchronous At this stage it will most likely crash the server at a certain point. Pausing and resuming isn't stable. Saving the progress isn't stable as well. Chunks are being unloaded in the main thread by an unloader class. * Switch to native threads - Use thread instead of async tasks - Store pending paper chunks in the database - Interrupt the thread when it should be stopped * Fix insertion of pending chunks Fix an error that is thrown when the sql for inserting pending chunks doesn't have any chunks to insert. * Add task states Add states to differentiate between generating and validating tasks as well as a field in the database to store this information. A task will first generate a world until the required radius or the worldborder is reached. Then it validates that each chunk has been generated. * Add object representation of world_properties table * Add DAO for pending_chunks table * Add DAO for generation_tasks table * Add state updating to periodic save * Fix loading of world properties * Add states to tasks and fix completion handling * Fix progress report and spiral shape * Modify the paper generation task so it works with spigot This change is being made because normal chunk generation doesn't allow chunks to be requested from a different thread. With PaperLib this issue can be solved. * Add workarounds for spigot problems * Fix some blocking issues and update README * Add locking to ChunkUnloader class
4 years ago
/**
* Resets the shape to its starting parameters
*/
override fun reset() {
this.currentPos = center
this.count = 0
this.direction = 0
}
}