diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 06379bf..2525b02 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -2,13 +2,8 @@
-
-
-
-
-
-
+
@@ -59,11 +54,47 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -83,12 +114,14 @@
1
+ .add
$PROJECT_DIR$
@@ -106,7 +139,13 @@
+
+
+
+
+
+
@@ -141,6 +180,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -165,6 +234,9 @@
+
+
+
@@ -215,7 +287,7 @@
-
+
1554832667584
@@ -280,11 +352,25 @@
1554901123221
-
+
+ 1554904174549
+
+
+
+ 1554904174549
+
+
+ 1554907968725
+
+
+
+ 1554907968725
+
+
-
+
@@ -299,7 +385,7 @@
-
+
@@ -314,11 +400,11 @@
-
+
-
+
@@ -344,7 +430,9 @@
-
+
+
+
@@ -384,10 +472,40 @@
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/kotlin/net/deliciousreya/minecraftportal/MinecraftPortalPlugin.kt b/src/main/kotlin/net/deliciousreya/minecraftportal/MinecraftPortalPlugin.kt
index 902a786..f27bb5e 100644
--- a/src/main/kotlin/net/deliciousreya/minecraftportal/MinecraftPortalPlugin.kt
+++ b/src/main/kotlin/net/deliciousreya/minecraftportal/MinecraftPortalPlugin.kt
@@ -4,8 +4,6 @@ import org.bukkit.Material
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.block.BlockPlaceEvent
-import org.bukkit.event.player.PlayerJoinEvent
-import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.java.JavaPlugin
class MinecraftPortalPlugin() : JavaPlugin(), Listener
@@ -21,6 +19,12 @@ class MinecraftPortalPlugin() : JavaPlugin(), Listener
logger.info("block placed of type " + e.block.type)
if (e.block.type.equals(Material.GLASS)) {
logger.info("put down glass at " + e.block.location)
+ val portalScanResults = findPortalFrameConnectedTo(e.block)
+ if (portalScanResults.frame != null) {
+ logger.info("found portal frame $portalScanResults")
+ } else {
+ logger.info("no portal frame found, best scan was $portalScanResults")
+ }
}
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/net/deliciousreya/minecraftportal/PortalFrame.kt b/src/main/kotlin/net/deliciousreya/minecraftportal/PortalFrame.kt
new file mode 100644
index 0000000..a86f886
--- /dev/null
+++ b/src/main/kotlin/net/deliciousreya/minecraftportal/PortalFrame.kt
@@ -0,0 +1,96 @@
+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()
+ val nonmatches = ImmutableList.Builder()
+ 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, val nonMatchingBlocks:List) : Comparable {
+ 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 = 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 = ImmutableList.of(
+ Vector(0, 1, 0) + vector,
+ Vector(0, 2, 0) + vector
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/net/deliciousreya/minecraftportal/extensions/Location.kt b/src/main/kotlin/net/deliciousreya/minecraftportal/extensions/Location.kt
new file mode 100644
index 0000000..cb404c5
--- /dev/null
+++ b/src/main/kotlin/net/deliciousreya/minecraftportal/extensions/Location.kt
@@ -0,0 +1,32 @@
+package net.deliciousreya.minecraftportal.extensions
+
+import org.bukkit.Location
+import org.bukkit.util.Vector
+
+operator fun Location.plus(v: Vector):Location {
+ return this.clone().add(v)
+}
+
+operator fun Location.plus(l: Location):Location {
+ return this.clone().add(l)
+}
+
+fun Location.plus(x: Double, y: Double, z: Double):Location {
+ return this.clone().add(x, y, z)
+}
+
+operator fun Location.minus(v:Vector):Location {
+ return this.clone().subtract(v)
+}
+
+operator fun Location.minus(l: Location):Location {
+ return this.clone().subtract(l)
+}
+
+fun Location.minus(x: Double, y: Double, z: Double):Location {
+ return this.clone().subtract(x, y, z)
+}
+
+operator fun Location.times(n:Double):Location {
+ return this.clone().multiply(n)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/net/deliciousreya/minecraftportal/extensions/Vector.kt b/src/main/kotlin/net/deliciousreya/minecraftportal/extensions/Vector.kt
new file mode 100644
index 0000000..3073049
--- /dev/null
+++ b/src/main/kotlin/net/deliciousreya/minecraftportal/extensions/Vector.kt
@@ -0,0 +1,31 @@
+package net.deliciousreya.minecraftportal.extensions
+
+import org.bukkit.util.Vector
+
+operator fun Vector.plus(v:Vector):Vector {
+ return this.clone().add(v)
+}
+
+operator fun Vector.minus(v:Vector):Vector {
+ return this.clone().subtract(v)
+}
+
+operator fun Vector.times(n:Int):Vector {
+ return this.clone().multiply(n)
+}
+
+operator fun Vector.times(n:Float):Vector {
+ return this.clone().multiply(n)
+}
+
+operator fun Vector.times(n:Double):Vector {
+ return this.clone().multiply(n)
+}
+
+operator fun Vector.times(v:Vector):Vector {
+ return this.clone().multiply(v)
+}
+
+operator fun Vector.div(v:Vector):Vector {
+ return this.clone().divide(v)
+}
\ No newline at end of file