diff --git a/src/main/java/com/derongan/minecraft/deeperworld/listeners/MovementListener.kt b/src/main/java/com/derongan/minecraft/deeperworld/listeners/MovementListener.kt index 7e02951..c70338d 100644 --- a/src/main/java/com/derongan/minecraft/deeperworld/listeners/MovementListener.kt +++ b/src/main/java/com/derongan/minecraft/deeperworld/listeners/MovementListener.kt @@ -93,59 +93,55 @@ object MovementListener : Listener { fun tpIfAbleTo( key: SectionKey, - tpFun: (Player, Location, Section, Section) -> Unit, - boundaryCheck: (y: Double, shared: Int) -> Boolean, + tpFun: (Player, Location, Section, Section) -> Unit ) { val toSection = key.section ?: return - val overlap = current.overlapWith(toSection) ?: return val correspondingPos = to.getCorrespondingLocation(current, toSection) ?: return - if (boundaryCheck(to.y, overlap)) { - if (!toSection.region.contains(correspondingPos.blockX, correspondingPos.blockZ) - || !inSpectator && correspondingPos.block.type.isSolid - ) { - if(current.isOnTopOf(toSection)){ - from.block.type = Material.BEDROCK - val spawnedBedrock = from.block - temporaryBedrock.add(spawnedBedrock) - - // Keep bedrock spawned if there are players within a 1.5 radius (regular jump height). - // If no players are in this radius, destroy the bedrock. - deeperWorld.schedule{ - this.repeating(1) - while(spawnedBedrock.location.up(1).getNearbyPlayers(1.5).isNotEmpty()){ - yield() - } - spawnedBedrock.type = Material.AIR - temporaryBedrock.remove(spawnedBedrock) + if (!to.inSectionTransition) return + if (!toSection.region.contains(correspondingPos.blockX, correspondingPos.blockZ) + || !inSpectator && correspondingPos.block.type.isSolid + ) { + if (current.isOnTopOf(toSection)) { + from.block.type = Material.BEDROCK + val spawnedBedrock = from.block + temporaryBedrock.add(spawnedBedrock) + + // Keep bedrock spawned if there are players within a 1.5 radius (regular jump height). + // If no players are in this radius, destroy the bedrock. + deeperWorld.schedule { + this.repeating(1) + while (spawnedBedrock.location.up(1).getNearbyPlayers(1.5).isNotEmpty()) { + yield() } + spawnedBedrock.type = Material.AIR + temporaryBedrock.remove(spawnedBedrock) + } - val oldFallDistance = player.fallDistance - val oldVelocity = player.velocity + val oldFallDistance = player.fallDistance + val oldVelocity = player.velocity - player.teleport(from.up(1)) + player.teleport(from.up(1)) - player.fallDistance = oldFallDistance - player.velocity = oldVelocity - }else{ - player.teleport(from) - } - player.sendMessage("&cThere is no where for you to teleport".color()) + player.fallDistance = oldFallDistance + player.velocity = oldVelocity + } else { + player.teleport(from) } - else - tpFun(player, to, current, toSection) - } + player.sendMessage("&cThere is no where for you to teleport".color()) + } else + tpFun(player, to, current, toSection) } when { changeY > 0.0 -> tpIfAbleTo( current.aboveKey, MovementListener::ascend, - ) { y, shared -> y > player.world.maxHeight - .3 * shared } + ) changeY < 0.0 -> tpIfAbleTo( current.belowKey, MovementListener::descend, - ) { y, shared -> y < player.world.minHeight + .3 * shared } + ) } } diff --git a/src/main/java/com/derongan/minecraft/deeperworld/listeners/PlayerListener.kt b/src/main/java/com/derongan/minecraft/deeperworld/listeners/PlayerListener.kt index 715d924..d290f32 100644 --- a/src/main/java/com/derongan/minecraft/deeperworld/listeners/PlayerListener.kt +++ b/src/main/java/com/derongan/minecraft/deeperworld/listeners/PlayerListener.kt @@ -1,13 +1,10 @@ package com.derongan.minecraft.deeperworld.listeners import com.derongan.minecraft.deeperworld.services.canMoveSections +import com.derongan.minecraft.deeperworld.world.section.inSectionTransition import com.derongan.minecraft.deeperworld.world.section.section -import com.mineinabyss.idofront.destructure.component1 -import com.mineinabyss.idofront.destructure.component2 -import com.mineinabyss.idofront.destructure.component3 import com.mineinabyss.idofront.messaging.error -import org.bukkit.GameMode.ADVENTURE -import org.bukkit.GameMode.SURVIVAL +import org.bukkit.GameMode.CREATIVE import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerTeleportEvent @@ -16,19 +13,21 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.ENDER_PEARL object PlayerListener : Listener { @EventHandler - fun onPlayerTeleport(event: PlayerTeleportEvent) { - val (player, _, to, cause) = event + fun PlayerTeleportEvent.onPlayerTeleport() { + if (player.gameMode == CREATIVE) return + if (cause != ENDER_PEARL && cause != CHORUS_FRUIT) return + if (!player.canMoveSections) return + if ( - (player.gameMode == SURVIVAL || player.gameMode == ADVENTURE) - && (cause == ENDER_PEARL || cause == CHORUS_FRUIT) - && (to.section != player.location.section || to.section == null) - && player.canMoveSections + to.section == null || + to.section != player.location.section || + to.inSectionTransition ) { player.error("Teleportation is disabled between Layers and Sections.") - event.isCancelled = true + isCancelled = true } } } //TODO move into idofront -private operator fun PlayerTeleportEvent.component4() = cause \ No newline at end of file +private operator fun PlayerTeleportEvent.component4() = cause diff --git a/src/main/java/com/derongan/minecraft/deeperworld/synchronization/SectionSyncListener.kt b/src/main/java/com/derongan/minecraft/deeperworld/synchronization/SectionSyncListener.kt index 0dba317..6b583e7 100644 --- a/src/main/java/com/derongan/minecraft/deeperworld/synchronization/SectionSyncListener.kt +++ b/src/main/java/com/derongan/minecraft/deeperworld/synchronization/SectionSyncListener.kt @@ -18,11 +18,13 @@ import org.bukkit.block.data.Waterlogged import org.bukkit.block.data.type.Bed import org.bukkit.block.data.type.Stairs import org.bukkit.block.data.type.TrapDoor +import org.bukkit.entity.EntityType import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.Listener import org.bukkit.event.block.* import org.bukkit.event.entity.EntityExplodeEvent +import org.bukkit.event.entity.EntitySpawnEvent import org.bukkit.event.player.PlayerBucketEmptyEvent import org.bukkit.event.player.PlayerBucketFillEvent @@ -174,4 +176,16 @@ object SectionSyncListener : Listener { fun SignChangeEvent.syncSignText() { block.sync(signUpdater(lines)) } + + /** Disables Iron Golem and Wither summons in section transitions due to duping **/ + @EventHandler + fun EntitySpawnEvent.onEntitySummon() { + if (entity.location.inSectionOverlap && + (entityType == EntityType.WITHER || entityType == EntityType.IRON_GOLEM)) { + isCancelled = true + entity.location.getNearbyPlayers(5.0).forEach { + it.error("Spawning of $entityType is disabled in section overlaps.") + } + } + } } diff --git a/src/main/java/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt b/src/main/java/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt index 99708d4..6c0ac1f 100644 --- a/src/main/java/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt +++ b/src/main/java/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt @@ -69,6 +69,13 @@ val Location.inSectionOverlap: Boolean return sharedBetween(section ?: return false, correspondingSection ?: return false) } +val Location.inSectionTransition: Boolean + get() { + // Get overlap of this section and corresponding section + val shared = section?.overlapWith(correspondingSection ?: return false) ?: return false + return blockY >= world.maxHeight - .3 * shared || blockY <= world.minHeight + .3 * shared + } + fun Location.sharedBetween(section: Section, otherSection: Section): Boolean { val overlap = section.overlapWith(otherSection) ?: return false return when {