summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico <dico.karssiens@gmail.com>2018-08-17 10:59:19 +0100
committerDico <dico.karssiens@gmail.com>2018-08-17 10:59:19 +0100
commit48e1d86fcbd2700ab220d64ffa624b6129232832 (patch)
tree71daf095db6554090af9626612216fd3930a8e95
parent5bd0970c54a843c897126116d5eaff88014360fb (diff)
Add interactable api
-rw-r--r--src/main/kotlin/io/dico/parcels2/Interactable.kt106
-rw-r--r--src/main/kotlin/io/dico/parcels2/Parcel.kt6
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt24
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/MaterialExtensions.kt32
4 files changed, 166 insertions, 2 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/Interactable.kt b/src/main/kotlin/io/dico/parcels2/Interactable.kt
new file mode 100644
index 0000000..36a8bdd
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/Interactable.kt
@@ -0,0 +1,106 @@
+package io.dico.parcels2
+
+import io.dico.parcels2.util.findWoodKindPrefixedMaterials
+import org.bukkit.Material
+import java.util.EnumMap
+
+class Interactables
+private constructor(val id: Int,
+ val name: String,
+ val interactableByDefault: Boolean,
+ vararg val materials: Material) {
+
+ companion object {
+ val classesById: List<Interactables>
+ val classesByName: Map<String, Interactables>
+ val listedMaterials: Map<Material, Int>
+
+ init {
+ val array = getClassesArray()
+ classesById = array.asList()
+ classesByName = mapOf(*array.map { it.name to it }.toTypedArray())
+ listedMaterials = EnumMap(mapOf(*array.flatMap { clazz -> clazz.materials.map { it to clazz.id } }.toTypedArray()))
+ }
+
+ private fun getClassesArray() = run {
+ var id = 0
+ @Suppress("UNUSED_CHANGED_VALUE")
+ arrayOf(
+ Interactables(id++, "button", true,
+ Material.STONE_BUTTON,
+ *findWoodKindPrefixedMaterials("BUTTON")),
+
+ Interactables(id++, "lever", true,
+ Material.LEVER),
+
+ Interactables(id++, "pressure_plate", true,
+ Material.STONE_PRESSURE_PLATE,
+ *findWoodKindPrefixedMaterials("PRESSURE_PLATE"),
+ Material.HEAVY_WEIGHTED_PRESSURE_PLATE,
+ Material.LIGHT_WEIGHTED_PRESSURE_PLATE),
+
+ Interactables(id++, "redstone_components", false,
+ Material.COMPARATOR,
+ Material.REPEATER),
+
+ Interactables(id++, "containers", false,
+ Material.CHEST,
+ Material.TRAPPED_CHEST,
+ Material.DISPENSER,
+ Material.DROPPER,
+ Material.HOPPER,
+ Material.FURNACE)
+ )
+ }
+
+ }
+
+}
+
+interface InteractableConfiguration {
+ val interactableClasses: List<Interactables> get() = Interactables.classesById.filter { isInteractable(it) }
+ fun isInteractable(material: Material): Boolean
+ fun isInteractable(clazz: Interactables): Boolean
+ fun setInteractable(clazz: Interactables, interactable: Boolean): Boolean
+ fun clear(): Boolean
+ fun copyFrom(other: InteractableConfiguration) {
+ Interactables.classesById.forEach { setInteractable(it, other.isInteractable(it)) }
+ }
+}
+
+class BitmaskInteractableConfiguration : InteractableConfiguration {
+ val bitmaskArray = IntArray((Interactables.classesById.size + 31) / 32)
+
+ private fun isBitSet(classId: Int): Boolean {
+ val idx = classId.ushr(5)
+ return idx < bitmaskArray.size && bitmaskArray[idx].and(0x1.shl(classId.and(0x1F))) != 0
+ }
+
+ override fun isInteractable(material: Material): Boolean {
+ val classId = Interactables.listedMaterials[material] ?: return false
+ return isBitSet(classId) != Interactables.classesById[classId].interactableByDefault
+ }
+
+ override fun isInteractable(clazz: Interactables): Boolean {
+ return isBitSet(clazz.id) != clazz.interactableByDefault
+ }
+
+ override fun setInteractable(clazz: Interactables, interactable: Boolean): Boolean {
+ val idx = clazz.id.ushr(5)
+ if (idx >= bitmaskArray.size) return false
+ val bit = 0x1.shl(clazz.id.and(0x1F))
+ val oldBitmask = bitmaskArray[idx]
+ bitmaskArray[idx] = if (interactable != clazz.interactableByDefault) oldBitmask.or(bit) else oldBitmask.and(bit.inv())
+ return bitmaskArray[idx] != oldBitmask
+ }
+
+ override fun clear(): Boolean {
+ var change = false
+ for (i in bitmaskArray.indices) {
+ change = change || bitmaskArray[i] != 0
+ bitmaskArray[i] = 0
+ }
+ return change
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/Parcel.kt b/src/main/kotlin/io/dico/parcels2/Parcel.kt
index 3b82d32..6d8a1ca 100644
--- a/src/main/kotlin/io/dico/parcels2/Parcel.kt
+++ b/src/main/kotlin/io/dico/parcels2/Parcel.kt
@@ -39,6 +39,7 @@ interface ParcelData : AddedData {
var owner: PlayerProfile?
val lastClaimTime: DateTime?
var ownerSignOutdated: Boolean
+ var interactableConfig: InteractableConfiguration
fun canBuild(player: OfflinePlayer, checkAdmin: Boolean = true, checkGlobal: Boolean = true): Boolean
@@ -54,8 +55,8 @@ interface ParcelData : AddedData {
}
}
-class ParcelDataHolder(addedMap: MutableAddedDataMap = mutableMapOf()) : AddedDataHolder(addedMap), ParcelData {
-
+class ParcelDataHolder(addedMap: MutableAddedDataMap = mutableMapOf())
+ : ParcelData, AddedDataHolder(addedMap) {
override var owner: PlayerProfile? = null
override var lastClaimTime: DateTime? = null
override var ownerSignOutdated = false
@@ -65,5 +66,6 @@ class ParcelDataHolder(addedMap: MutableAddedDataMap = mutableMapOf()) : AddedDa
override var allowInteractInputs = true
override var allowInteractInventory = true
+ override var interactableConfig: InteractableConfiguration = BitmaskInteractableConfiguration()
}
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
index 7755363..dd3c121 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt
@@ -4,6 +4,7 @@ import io.dico.dicore.Formatting
import io.dico.parcels2.*
import io.dico.parcels2.util.Vec2i
import io.dico.parcels2.util.alsoIfTrue
+import org.bukkit.Material
import org.bukkit.OfflinePlayer
import org.joda.time.DateTime
import kotlin.reflect.KProperty
@@ -90,6 +91,29 @@ class ParcelImpl(override val world: ParcelWorld,
data.allowInteractInventory = value
}
+ private var _interactableConfig: InteractableConfiguration? = null
+ override var interactableConfig: InteractableConfiguration
+ get() {
+ if (_interactableConfig == null) {
+ _interactableConfig = object : InteractableConfiguration {
+ override fun isInteractable(material: Material): Boolean = data.interactableConfig.isInteractable(material)
+ override fun isInteractable(clazz: Interactables): Boolean = data.interactableConfig.isInteractable(clazz)
+
+ override fun setInteractable(clazz: Interactables, interactable: Boolean): Boolean = data.interactableConfig.setInteractable(clazz, interactable).alsoIfTrue {
+ // TODO update storage
+ }
+
+ override fun clear(): Boolean = data.interactableConfig.clear().alsoIfTrue {
+ // TODO update storage
+ }
+ }
+ }
+ return _interactableConfig!!
+ }
+ set(value) {
+ data.interactableConfig.copyFrom(value)
+ // TODO update storage
+ }
}
diff --git a/src/main/kotlin/io/dico/parcels2/util/MaterialExtensions.kt b/src/main/kotlin/io/dico/parcels2/util/MaterialExtensions.kt
index a2aefc8..fadd722 100644
--- a/src/main/kotlin/io/dico/parcels2/util/MaterialExtensions.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/MaterialExtensions.kt
@@ -74,3 +74,35 @@ val Material.isWoodButton
DARK_OAK_BUTTON -> true
else -> false
}
+
+private fun getMaterialPrefixed(prefix: String, name: String): Material {
+ return Material.getMaterial("${prefix}_$name") ?: throw IllegalArgumentException("Material ${prefix}_$name doesn't exist")
+}
+
+fun findWoodKindPrefixedMaterials(name: String) = arrayOf(
+ getMaterialPrefixed("OAK", name),
+ getMaterialPrefixed("BIRCH", name),
+ getMaterialPrefixed("SPRUCE", name),
+ getMaterialPrefixed("JUNGLE", name),
+ getMaterialPrefixed("ACACIA", name),
+ getMaterialPrefixed("DARK_OAK", name)
+)
+
+fun findColorPrefixedMaterials(name: String) = arrayOf(
+ getMaterialPrefixed("WHITE", name),
+ getMaterialPrefixed("ORANGE", name),
+ getMaterialPrefixed("MAGENTA", name),
+ getMaterialPrefixed("LIGHT_BLUE", name),
+ getMaterialPrefixed("YELLOW", name),
+ getMaterialPrefixed("LIME", name),
+ getMaterialPrefixed("PINK", name),
+ getMaterialPrefixed("GRAY", name),
+ getMaterialPrefixed("LIGHT_GRAY", name),
+ getMaterialPrefixed("CYAN", name),
+ getMaterialPrefixed("PURPLE", name),
+ getMaterialPrefixed("BLUE", name),
+ getMaterialPrefixed("BROWN", name),
+ getMaterialPrefixed("GREEN", name),
+ getMaterialPrefixed("RED", name),
+ getMaterialPrefixed("BLACK", name)
+) \ No newline at end of file