summaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt')
-rw-r--r--src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt133
1 files changed, 71 insertions, 62 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
index c8e64d3..9805f40 100644
--- a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
+++ b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
@@ -1,6 +1,7 @@
package io.dico.parcels2.listener
import gnu.trove.TLongCollection
+import gnu.trove.set.hash.TLongHashSet
import io.dico.dicore.ListenerMarker
import io.dico.dicore.RegistratorListener
import io.dico.parcels2.*
@@ -30,21 +31,23 @@ import org.bukkit.event.world.StructureGrowEvent
import org.bukkit.inventory.InventoryHolder
import java.util.EnumSet
-@Suppress("NOTHING_TO_INLINE")
class ParcelListeners(
val parcelProvider: ParcelProvider,
val entityTracker: ParcelEntityTracker,
val storage: Storage
) {
- private inline fun Parcel?.canBuildN(user: Player) = isPresentAnd { canBuild(user) } || user.hasPermBuildAnywhere
+ private fun canBuildOnArea(user: Player, area: Parcel?) =
+ if (area == null) user.hasPermBuildAnywhere else area.canBuild(user)
+
+ private fun canInteract(user: Player, area: Parcel?, interactClass: String) =
+ canBuildOnArea(user, area) || (area != null && area.interactableConfig(interactClass))
/**
* Get the world and parcel that the block resides in
- * wo is the world, ppa is the parcel
- * ppa for possibly a parcel - it will be null if not in an existing parcel
- * returns null if not in a registered parcel world
+ * the parcel is nullable, and often named area because that means path.
+ * returns null if not in a registered parcel world - should always return in that case to not affect other worlds.
*/
- private fun getWoAndPPa(block: Block): Pair<ParcelWorld, Parcel?>? {
+ private fun getWorldAndArea(block: Block): Pair<ParcelWorld, Parcel?>? {
val world = parcelProvider.getWorld(block.world) ?: return null
return world to world.getParcelAt(block)
}
@@ -57,7 +60,7 @@ class ParcelListeners(
val user = event.player
if (user.hasPermBanBypass) return@l
val parcel = parcelProvider.getParcelAt(event.to) ?: return@l
- if (parcel.isBanned(user.privilegeKey)) {
+ if (!parcel.canEnter(user)) {
parcelProvider.getParcelAt(event.from)?.also {
user.teleport(it.homeLocation)
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
@@ -71,12 +74,12 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onBlockBreakEvent = RegistratorListener<BlockBreakEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
- if (!event.player.hasPermBuildAnywhere && ppa.isNullOr { !canBuild(event.player) }) {
+ val (world, area) = getWorldAndArea(event.block) ?: return@l
+ if (!canBuildOnArea(event.player, area)) {
event.isCancelled = true; return@l
}
- if (!wo.options.dropEntityItems) {
+ if (!world.options.dropEntityItems) {
val state = event.block.state
if (state is InventoryHolder) {
state.inventory.clear()
@@ -90,8 +93,8 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onBlockPlaceEvent = RegistratorListener<BlockPlaceEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
- if (!event.player.hasPermBuildAnywhere && ppa.isNullOr { !canBuild(event.player) }) {
+ val (_, area) = getWorldAndArea(event.block) ?: return@l
+ if (!canBuildOnArea(event.player, area)) {
event.isCancelled = true
}
}
@@ -120,7 +123,7 @@ class ParcelListeners(
private fun checkPistonMovement(event: BlockPistonEvent, blocks: List<Block>) {
val world = parcelProvider.getWorld(event.block.world) ?: return
val direction = event.direction
- val columns = gnu.trove.set.hash.TLongHashSet(blocks.size * 2)
+ val columns = TLongHashSet(blocks.size * 2)
blocks.forEach {
columns.add(Column(it.x, it.z))
@@ -128,8 +131,8 @@ class ParcelListeners(
}
columns.troveForEach {
- val ppa = world.getParcelAt(it.columnX, it.columnZ)
- if (ppa.isNullOr { hasBlockVisitors }) {
+ val area = world.getParcelAt(it.columnX, it.columnZ)
+ if (area == null || area.hasBlockVisitors) {
event.isCancelled = true
return
}
@@ -141,10 +144,10 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onExplosionPrimeEvent = RegistratorListener<ExplosionPrimeEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.entity.location.block) ?: return@l
- if (ppa?.hasBlockVisitors == true) {
+ val (world, area) = getWorldAndArea(event.entity.location.block) ?: return@l
+ if (area != null && area.hasBlockVisitors) {
event.radius = 0F; event.isCancelled = true
- } else if (wo.options.disableExplosions) {
+ } else if (world.options.disableExplosions) {
event.radius = 0F
}
}
@@ -156,18 +159,18 @@ class ParcelListeners(
val onEntityExplodeEvent = RegistratorListener<EntityExplodeEvent> l@{ event ->
entityTracker.untrack(event.entity)
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
- if (world.options.disableExplosions || world.getParcelAt(event.entity).isPresentAnd { hasBlockVisitors }) {
+ if (world.options.disableExplosions || world.getParcelAt(event.entity).let { it != null && it.hasBlockVisitors }) {
event.isCancelled = true
}
}
/*
- * Prevents creepers and tnt minecarts from exploding if explosions are disabled
+ * Prevents liquids from flowing out of plots
*/
@field:ListenerMarker(priority = NORMAL)
val onBlockFromToEvent = RegistratorListener<BlockFromToEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.toBlock) ?: return@l
- if (ppa.isNullOr { hasBlockVisitors }) event.isCancelled = true
+ val (_, area) = getWorldAndArea(event.toBlock) ?: return@l
+ if (area == null || area.hasBlockVisitors) event.isCancelled = true
}
private val bedTypes = EnumSet.copyOf(getMaterialsWithWoolColorPrefix("BED").toList())
@@ -185,7 +188,7 @@ class ParcelListeners(
val clickedBlock = event.clickedBlock
val parcel = clickedBlock?.let { world.getParcelAt(it) }
- if (!user.hasPermBuildAnywhere && parcel.isPresentAnd { isBanned(user.privilegeKey) }) {
+ if (!user.hasPermBuildAnywhere && parcel != null && !parcel.canEnter(user)) {
user.sendParcelMessage(nopermit = true, message = "You cannot interact with parcels you're banned from")
event.isCancelled = true; return@l
}
@@ -193,7 +196,8 @@ class ParcelListeners(
when (event.action) {
Action.RIGHT_CLICK_BLOCK -> run {
val type = clickedBlock.type
- val interactable = parcel.effectiveInteractableConfig.isInteractable(type) || parcel.isPresentAnd { canBuild(user) }
+ val interactable = Interactables.listedMaterials.containsKey(type)
+ && (parcel.effectiveInteractableConfig.isInteractable(type) || (parcel != null && parcel.canBuild(user)))
if (!interactable) {
val interactableClassName = Interactables[type]!!.name
user.sendParcelMessage(nopermit = true, message = "You cannot interact with $interactableClassName in this parcel")
@@ -206,19 +210,24 @@ class ParcelListeners(
val head = if (bed == Bed.Part.FOOT) clickedBlock.getRelative(bed.facing) else clickedBlock
when (head.biome) {
Biome.NETHER, Biome.THE_END -> {
- if (world.options.disableExplosions || parcel.isNullOr { !canBuild(user) }) {
+ if (world.options.disableExplosions) {
user.sendParcelMessage(nopermit = true, message = "You cannot use this bed because it would explode")
event.isCancelled = true; return@l
}
}
}
+
+ if (!canBuildOnArea(user, parcel)) {
+ user.sendParcelMessage(nopermit = true, message = "You may not sleep here")
+ event.isCancelled = true; return@l
+ }
}
onPlayerInteractEvent_RightClick(event, world, parcel)
}
Action.RIGHT_CLICK_AIR -> onPlayerInteractEvent_RightClick(event, world, parcel)
- Action.PHYSICAL -> if (!user.hasPermBuildAnywhere && !parcel.isPresentAnd { canBuild(user) || interactableConfig("pressure_plates") }) {
+ Action.PHYSICAL -> if (!canBuildOnArea(user, parcel) && !(parcel != null && parcel.interactableConfig("pressure_plates"))) {
user.sendParcelMessage(nopermit = true, message = "You cannot use inputs in this parcel")
event.isCancelled = true; return@l
}
@@ -234,7 +243,7 @@ class ParcelListeners(
event.isCancelled = true; return
}
- if (!parcel.canBuildN(event.player)) {
+ if (!canBuildOnArea(event.player, parcel)) {
when (item) {
LAVA_BUCKET, WATER_BUCKET, BUCKET, FLINT_AND_STEEL -> event.isCancelled = true
}
@@ -249,8 +258,8 @@ class ParcelListeners(
@Suppress("NON_EXHAUSTIVE_WHEN")
@field:ListenerMarker(priority = NORMAL)
val onPlayerInteractEntityEvent = RegistratorListener<PlayerInteractEntityEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.rightClicked.location.block) ?: return@l
- if (ppa.canBuildN(event.player)) return@l
+ val (_, area) = getWorldAndArea(event.rightClicked.location.block) ?: return@l
+ if (canBuildOnArea(event.player, area)) return@l
when (event.rightClicked.type) {
EntityType.BOAT,
EntityType.MINECART,
@@ -281,14 +290,14 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onEntityChangeBlockEvent = RegistratorListener<EntityChangeBlockEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.block) ?: return@l
- if (event.entity.type == EntityType.ENDERMAN || ppa.isNullOr { hasBlockVisitors }) {
+ val (_, area) = getWorldAndArea(event.block) ?: return@l
+ if (event.entity.type == EntityType.ENDERMAN || area == null || area.hasBlockVisitors) {
event.isCancelled = true; return@l
}
if (event.entity.type == EntityType.FALLING_BLOCK) {
// a sand block started falling. Track it and delete it if it gets out of this parcel.
- entityTracker.track(event.entity, ppa)
+ entityTracker.track(event.entity, area)
}
}
@@ -306,8 +315,8 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onPlayerDropItemEvent = RegistratorListener<PlayerDropItemEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.itemDrop.location.block) ?: return@l
- if (!ppa.canBuildN(event.player) && !ppa.isPresentAnd { interactableConfig("containers") }) event.isCancelled = true
+ val (_, area) = getWorldAndArea(event.itemDrop.location.block) ?: return@l
+ if (!canInteract(event.player, area, "containers")) event.isCancelled = true
}
/*
@@ -316,8 +325,8 @@ class ParcelListeners(
@field:ListenerMarker(priority = NORMAL)
val onEntityPickupItemEvent = RegistratorListener<EntityPickupItemEvent> l@{ event ->
val user = event.entity as? Player ?: return@l
- val (wo, ppa) = getWoAndPPa(event.item.location.block) ?: return@l
- if (!ppa.canBuildN(user)) event.isCancelled = true
+ val (_, area) = getWorldAndArea(event.item.location.block) ?: return@l
+ if (!canInteract(user, area, "containers")) event.isCancelled = true
}
/*
@@ -327,8 +336,8 @@ class ParcelListeners(
val onInventoryClickEvent = RegistratorListener<InventoryInteractEvent> l@{ event ->
val user = event.whoClicked as? Player ?: return@l
if ((event.inventory ?: return@l).holder === user) return@l // inventory null: hotbar
- val (wo, ppa) = getWoAndPPa(event.inventory.location.block) ?: return@l
- if (ppa.isNullOr { !canBuild(user) && !interactableConfig("containers") }) {
+ val (_, area) = getWorldAndArea(event.inventory.location.block) ?: return@l
+ if (!canInteract(user, area, "containers")) {
event.isCancelled = true
}
}
@@ -358,10 +367,10 @@ class ParcelListeners(
@ListenerMarker(priority = NORMAL)
val onBlockFormEvent = RegistratorListener<BlockFormEvent> l@{ event ->
val block = event.block
- val (wo, ppa) = getWoAndPPa(block) ?: return@l
+ val (world, area) = getWorldAndArea(block) ?: return@l
// prevent any generation whatsoever on paths
- if (ppa == null) {
+ if (area == null) {
event.isCancelled = true; return@l
}
@@ -371,10 +380,10 @@ class ParcelListeners(
val cancel: Boolean = when (event.newState.type) {
// prevent ice generation from Frost Walkers enchantment
- FROSTED_ICE -> player != null && !ppa.canBuild(player)
+ FROSTED_ICE -> player != null && !area.canBuild(player)
// prevent snow generation from weather
- SNOW -> !hasEntity && wo.options.preventWeatherBlockChanges
+ SNOW -> !hasEntity && world.options.preventWeatherBlockChanges
else -> false
}
@@ -392,7 +401,7 @@ class ParcelListeners(
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
if (event.entity is Creature && world.options.blockMobSpawning) {
event.isCancelled = true
- } else if (world.getParcelAt(event.entity).isPresentAnd { hasBlockVisitors }) {
+ } else if (world.getParcelAt(event.entity).let { it != null && it.hasBlockVisitors }) {
event.isCancelled = true
}
}
@@ -402,8 +411,8 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onVehicleMoveEvent = RegistratorListener<VehicleMoveEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.to.block) ?: return@l
- if (ppa == null) {
+ val (_, area) = getWorldAndArea(event.to.block) ?: return@l
+ if (area == null) {
event.vehicle.passengers.forEach {
if (it.type == EntityType.PLAYER) {
(it as Player).sendParcelMessage(except = true, message = "Your ride ends here")
@@ -411,7 +420,7 @@ class ParcelListeners(
}
event.vehicle.eject()
event.vehicle.remove()
- } else if (ppa.hasBlockVisitors) {
+ } else if (area.hasBlockVisitors) {
event.to.subtract(event.to).add(event.from)
}
}
@@ -432,7 +441,7 @@ class ParcelListeners(
?: (event.damager as? Projectile)?.let { it.shooter as? Player }
?: return@l
- if (!world.getParcelAt(event.entity).canBuildN(user)) {
+ if (!canBuildOnArea(user, world.getParcelAt(event.entity))) {
event.isCancelled = true
}
}
@@ -444,7 +453,7 @@ class ParcelListeners(
event.isCancelled = true; return@l
}
- if (world.getParcelAt(event.entity).isPresentAnd { hasBlockVisitors }) {
+ if (world.getParcelAt(event.entity).let { it != null && it.hasBlockVisitors }) {
event.isCancelled = true
}
}
@@ -457,7 +466,7 @@ class ParcelListeners(
val onHangingBreakByEntityEvent = RegistratorListener<HangingBreakByEntityEvent> l@{ event ->
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
val user = event.remover as? Player ?: return@l
- if (!world.getParcelAt(event.entity).canBuildN(user)) {
+ if (!canBuildOnArea(user, world.getParcelAt(event.entity))) {
event.isCancelled = true
}
}
@@ -469,7 +478,7 @@ class ParcelListeners(
val onHangingPlaceEvent = RegistratorListener<HangingPlaceEvent> l@{ event ->
val world = parcelProvider.getWorld(event.entity.world) ?: return@l
val block = event.block.getRelative(event.blockFace)
- if (!world.getParcelAt(block).canBuildN(event.player)) {
+ if (!canBuildOnArea(event.player, world.getParcelAt(block))) {
event.isCancelled = true
}
}
@@ -479,16 +488,16 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onStructureGrowEvent = RegistratorListener<StructureGrowEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.location.block) ?: return@l
- if (ppa == null) {
+ val (world, area) = getWorldAndArea(event.location.block) ?: return@l
+ if (area == null) {
event.isCancelled = true; return@l
}
- if (!event.player.hasPermBuildAnywhere && !ppa.canBuild(event.player)) {
+ if (!event.player.hasPermBuildAnywhere && !area.canBuild(event.player)) {
event.isCancelled = true; return@l
}
- event.blocks.removeIf { wo.getParcelAt(it.block) !== ppa }
+ event.blocks.removeIf { world.getParcelAt(it.block) !== area }
}
/*
@@ -511,9 +520,9 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onItemSpawnEvent = RegistratorListener<ItemSpawnEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.location.block) ?: return@l
- if (ppa == null) event.isCancelled = true
- else entityTracker.track(event.entity, ppa)
+ val (_, area) = getWorldAndArea(event.location.block) ?: return@l
+ if (area == null) event.isCancelled = true
+ else entityTracker.track(event.entity, area)
}
/*
@@ -521,8 +530,8 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onEntityTeleportEvent = RegistratorListener<EntityTeleportEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.from.block) ?: return@l
- if (ppa !== wo.getParcelAt(event.to)) {
+ val (world, area) = getWorldAndArea(event.from.block) ?: return@l
+ if (area !== world.getParcelAt(event.to)) {
event.isCancelled = true
}
}
@@ -533,11 +542,11 @@ class ParcelListeners(
*/
@field:ListenerMarker(priority = NORMAL)
val onProjectileLaunchEvent = RegistratorListener<ProjectileLaunchEvent> l@{ event ->
- val (wo, ppa) = getWoAndPPa(event.entity.location.block) ?: return@l
- if (ppa == null || (event.entity.shooter as? Player)?.let { !ppa.canBuildN(it) } == true) {
+ val (_, area) = getWorldAndArea(event.entity.location.block) ?: return@l
+ if (area == null || (event.entity.shooter as? Player)?.let { !canBuildOnArea(it, area) } == true) {
event.isCancelled = true
} else {
- entityTracker.track(event.entity, ppa)
+ entityTracker.track(event.entity, area)
}
}