From c5637a0f3548f7d451c24b9e175140a1ea8d9efe Mon Sep 17 00:00:00 2001 From: 0ffz Date: Fri, 5 Nov 2021 17:59:26 -0400 Subject: [PATCH] Improve overlap logic when two sections are not actually across a transition and call transition event when moving between them --- .../deeperworld/movement/MovementHandler.kt | 13 +++++++--- .../transition/ConfigSectionChecker.kt | 26 ++++++++++++------- .../movement/transition/SectionTransition.kt | 5 ++-- .../minecraft/deeperworld/world/Region.kt | 3 +++ .../deeperworld/world/section/SectionUtils.kt | 4 ++- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/MovementHandler.kt b/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/MovementHandler.kt index e49177a..7f3dcd7 100644 --- a/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/MovementHandler.kt +++ b/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/MovementHandler.kt @@ -16,8 +16,7 @@ object MovementHandler { private val sectionCheckers = listOf(ConfigSectionChecker) fun handleMovement(player: Player, from: Location, to: Location) { - - if (sectionCheckers.any { it.inSection(player) }) + if (sectionCheckers.any { it.inSection(player) }) { sectionCheckers.firstNotNullOfOrNull { it.checkForTransition(player, from, to) }?.let { with(getTeleportHandler(player, it)) { if (this.isValidTeleport()) { @@ -28,7 +27,8 @@ object MovementHandler { this.handleTeleport() } } - } else { + } + } else { applyOutOfBoundsDamage(player) } } @@ -59,6 +59,11 @@ object MovementHandler { player: Player, sectionTransition: SectionTransition ): TeleportHandler { + if (sectionTransition.teleportUnnecessary) return object : TeleportHandler { + override fun handleTeleport() {} + + override fun isValidTeleport() = true + } if (player.gameMode != GameMode.SPECTATOR && sectionTransition.to.block.isSolid) { return if (sectionTransition.kind == TransitionKind.ASCEND) { UndoMovementInvalidTeleportHandler( @@ -77,4 +82,4 @@ object MovementHandler { return TransitionTeleportHandler(player, sectionTransition.from, sectionTransition.to); } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/ConfigSectionChecker.kt b/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/ConfigSectionChecker.kt index 80b50c5..74dec91 100644 --- a/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/ConfigSectionChecker.kt +++ b/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/ConfigSectionChecker.kt @@ -16,15 +16,21 @@ object ConfigSectionChecker : SectionChecker { from: Location, to: Location ): SectionTransition? { - return to.takeIf { to.inSectionTransition }?.correspondingLocation?.let { - SectionTransition( - from, - it, - from.section!!, // If inSectionTransition, must be non-null - it.section!!, - if (to.y < from.y) TransitionKind.DESCEND else TransitionKind.ASCEND - ) - } + val fromSection = from.section ?: return null + val toSection = to.section ?: return null + val corrLoc = when { + to.inSectionTransition -> to.correspondingLocation + fromSection != toSection -> to + else -> null + } ?: return null + return SectionTransition( + from, + corrLoc, + fromSection, + corrLoc.section!!, // If inSectionTransition, must be non-null + if (to.y < from.y) TransitionKind.DESCEND else TransitionKind.ASCEND, + teleportUnnecessary = fromSection != toSection + ) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/SectionTransition.kt b/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/SectionTransition.kt index e06a1a6..f9f5618 100644 --- a/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/SectionTransition.kt +++ b/src/main/kotlin/com/derongan/minecraft/deeperworld/movement/transition/SectionTransition.kt @@ -12,7 +12,8 @@ data class SectionTransition( val to: Location, val fromSection: Section, val toSection: Section, - val kind: TransitionKind + val kind: TransitionKind, + val teleportUnnecessary: Boolean, ) enum class TransitionKind { @@ -26,4 +27,4 @@ internal fun SectionTransition.toEvent(player: Player): PlayerChangeSectionEvent } else { PlayerDescendEvent(player, fromSection, toSection) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/derongan/minecraft/deeperworld/world/Region.kt b/src/main/kotlin/com/derongan/minecraft/deeperworld/world/Region.kt index df7970a..57b9049 100644 --- a/src/main/kotlin/com/derongan/minecraft/deeperworld/world/Region.kt +++ b/src/main/kotlin/com/derongan/minecraft/deeperworld/world/Region.kt @@ -15,6 +15,9 @@ import kotlin.math.min */ @Serializable(with = RegionSerializer::class) class Region(val a: CubePoint, val b: CubePoint) { + val min = CubePoint(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)) + val max = CubePoint(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)) + constructor(ax: Int, ay: Int, az: Int, bx: Int, by: Int, bz: Int) : this( CubePoint(ax, ay, az), CubePoint(bx, by, bz) diff --git a/src/main/kotlin/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt b/src/main/kotlin/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt index 6c0ac1f..4f1a378 100644 --- a/src/main/kotlin/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt +++ b/src/main/kotlin/com/derongan/minecraft/deeperworld/world/section/SectionUtils.kt @@ -87,6 +87,7 @@ fun Location.sharedBetween(section: Section, otherSection: Section): Boolean { fun Section.overlapWith(other: Section): Int? { if (!isAdjacentTo(other)) return null + if(min(this.region.max.y, other.region.max.y) <= max(this.region.min.y, other.region.min.y)) return null // We decide which two points we are translating between. val (locA, locB) = when (isOnTopOf(other)) { true -> referenceBottom to other.referenceTop @@ -94,7 +95,8 @@ fun Section.overlapWith(other: Section): Int? { } val yA = locA.blockY val yB = locB.blockY - return (world.maxHeight - max(yA, yB)) + (min(yA, yB) - world.minHeight) + return max(this.region.max.y, other.region.max.y) - max(yA, yB) + + (min(yA, yB) - min(this.region.min.y, other.region.min.y)) } fun Section.isOnTopOf(other: Section) = key == other.aboveKey