1
0
Fork 0
The portal creating plugin for Minecraft.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
3.6 KiB

package net.deliciousreya.minecraftportal
import com.google.common.collect.ImmutableList
import org.bukkit.Location
import org.bukkit.Material.AIR
import org.bukkit.Material.GLASS
import org.bukkit.block.Block
import org.bukkit.util.Vector
import net.deliciousreya.minecraftportal.extensions.*
fun findPortalFrameConnectedTo(block:Block): PortalScanResults {
var bestScan:PortalScanResults? = null
if (block.type == GLASS) {
for (direction in PortalFrame.Direction.values()) {
for (vector in direction.glassOffsets) {
val scanResult = checkPortalFrameAt(block.location.subtract(vector), direction)
if (scanResult.frame != null) {
return scanResult
}
if (bestScan == null || scanResult > bestScan) {
bestScan = scanResult
}
}
}
}
if (block.type == GLASS) {
for (direction in PortalFrame.Direction.values()) {
val scanResult = checkPortalFrameAt(block.location.subtract(direction.mineralOffset), direction)
if (scanResult.frame != null) {
return scanResult
} else if (bestScan == null || scanResult > bestScan) {
bestScan = scanResult
}
}
}
if (bestScan != null) {
return bestScan
} else {
return PortalScanResults(null, ImmutableList.of(), ImmutableList.of())
}
}
/** Detects whether there is a portal frame in the given location, extending in the given direction. */
fun checkPortalFrameAt(location:Location, direction:PortalFrame.Direction): PortalScanResults {
val matches = ImmutableList.Builder<Block>()
val nonmatches = ImmutableList.Builder<Block>()
for (vector in direction.glassOffsets) {
val block = (location + vector).block
(if (block.type == GLASS) matches else nonmatches).add(block)
}
for (vector in direction.airOffsets) {
val block = (location + vector).block
(if (block.type == AIR) matches else nonmatches).add(block)
}
val block = (location + direction.mineralOffset).block
(if (block.type == GLASS) matches else nonmatches).add(block)
val nonmatchesBuilt = nonmatches.build()
return PortalScanResults(if (nonmatchesBuilt.isEmpty()) {PortalFrame(location, direction)} else {null}, matches.build(), nonmatchesBuilt)
}
data class PortalScanResults(val frame: PortalFrame?, val matchingBlocks:List<Block>, val nonMatchingBlocks:List<Block>) : Comparable<PortalScanResults> {
override fun compareTo(other:PortalScanResults): Int {
return matchingBlocks.size - other.matchingBlocks.size
}
}
/** Information about a portal frame. */
data class PortalFrame(val lowerLeftCorner: Location, val direction: Direction) {
val UP = Vector(0, 1, 0)
/** The direction along which a portal frame extends. */
enum class Direction(vector: Vector) {
X_AXIS(Vector(1, 0, 0)),
Z_AXIS(Vector(0, 0, 1));
private val rightSideVector = vector * 2
val glassOffsets: ImmutableList<Vector> = ImmutableList.of(
Vector(0, 0, 0),
Vector(0, 1, 0),
Vector(0, 2, 0),
Vector(0, 3, 0),
vector,
rightSideVector,
Vector(0, 1, 0) + rightSideVector,
Vector(0, 2, 0) + rightSideVector,
Vector(0, 3, 0) + rightSideVector
)
val mineralOffset: Vector = Vector(0, 3, 0) + vector
val airOffsets: ImmutableList<Vector> = ImmutableList.of(
Vector(0, 1, 0) + vector,
Vector(0, 2, 0) + vector
)
}
}