From cff764e0268598a592e9d38cb5a35cd5ba27d709 Mon Sep 17 00:00:00 2001 From: Norazan Date: Wed, 26 Feb 2025 02:22:56 +0100 Subject: [PATCH 1/2] Introduce depth calculation logic --- .../mineinabyss/deeperworld/DeeperCommands.kt | 36 ++++++++++++++++--- .../deeperworld/world/section/Section.kt | 3 ++ .../deeperworld/world/section/SectionUtils.kt | 2 +- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt index e41b285..6185902 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt @@ -5,9 +5,7 @@ import com.mineinabyss.deeperworld.MinecraftConstants.FULL_DAY_TIME import com.mineinabyss.deeperworld.services.WorldManager import com.mineinabyss.deeperworld.services.canMoveSections import com.mineinabyss.deeperworld.synchronization.sync -import com.mineinabyss.deeperworld.world.section.correspondingSection -import com.mineinabyss.deeperworld.world.section.getCorrespondingLocation -import com.mineinabyss.deeperworld.world.section.section +import com.mineinabyss.deeperworld.world.section.* import com.mineinabyss.idofront.commands.brigadier.Args import com.mineinabyss.idofront.commands.brigadier.commands import com.mineinabyss.idofront.commands.brigadier.executes @@ -29,6 +27,7 @@ import com.sk89q.worldedit.regions.CuboidRegion import com.sk89q.worldedit.session.ClipboardHolder import com.sk89q.worldedit.world.World import io.papermc.paper.command.brigadier.argument.ArgumentTypes +import kotlin.math.floor object DeeperCommands { fun registerCommands() { @@ -166,7 +165,8 @@ object DeeperCommands { ) block.sync { original, corr -> - if (original.type != corr.type) corr.blockData = original.blockData.clone() + if (original.type != corr.type) corr.blockData = + original.blockData.clone() } } } @@ -179,6 +179,34 @@ object DeeperCommands { } } } + "depth" { + playerExecutes() { + val section = WorldManager.getSectionFor(player.location) + if (section == null) { + sender.info("${player.name} is not in a managed section") + return@playerExecutes + } + + var depth = (section.region.max.y - floor(player.location.y)).toInt() + + var currentSection: Section = section + var aboveSection = section.aboveKey.section + + if (aboveSection != null) { + depth += 1 // Account for one unit of depth missing when calculating depth with multiple sections + } + + while (aboveSection != null) { + depth += aboveSection.height + depth += aboveSection.overlapWith(currentSection) ?: 0 + + currentSection = aboveSection + aboveSection = currentSection.aboveKey.section + } + + player.success("Your depth is: $depth") + } + } } } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt b/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt index 09f1f66..d48ecb3 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/world/section/Section.kt @@ -56,5 +56,8 @@ data class Section( @Transient internal var belowKey: SectionKey = SectionKey.TERMINAL + @Transient + val height: Int = this.region.max.y - this.region.min.y + override fun toString() = key.toString() } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/world/section/SectionUtils.kt b/src/main/kotlin/com/mineinabyss/deeperworld/world/section/SectionUtils.kt index f4d180f..dcef325 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/world/section/SectionUtils.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/world/section/SectionUtils.kt @@ -87,7 +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 + 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 From 6ff8e6a07134085d3bcd2672496ce4b7c8afe230 Mon Sep 17 00:00:00 2001 From: Norazan Date: Wed, 26 Feb 2025 03:54:15 +0100 Subject: [PATCH 2/2] Move depth calculation logic to WorldManager methods --- .../mineinabyss/deeperworld/DeeperCommands.kt | 43 +++++++------------ .../deeperworld/services/WorldManager.kt | 19 ++++++++ .../deeperworld/world/WorldManagerImpl.kt | 38 ++++++++++++++++ 3 files changed, 72 insertions(+), 28 deletions(-) diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt index 6185902..0653545 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/DeeperCommands.kt @@ -6,11 +6,7 @@ import com.mineinabyss.deeperworld.services.WorldManager import com.mineinabyss.deeperworld.services.canMoveSections import com.mineinabyss.deeperworld.synchronization.sync import com.mineinabyss.deeperworld.world.section.* -import com.mineinabyss.idofront.commands.brigadier.Args -import com.mineinabyss.idofront.commands.brigadier.commands -import com.mineinabyss.idofront.commands.brigadier.executes -import com.mineinabyss.idofront.commands.brigadier.playerExecutes -import com.mineinabyss.idofront.commands.execution.stopCommand +import com.mineinabyss.idofront.commands.brigadier.* import com.mineinabyss.idofront.messaging.error import com.mineinabyss.idofront.messaging.info import com.mineinabyss.idofront.messaging.success @@ -27,7 +23,7 @@ import com.sk89q.worldedit.regions.CuboidRegion import com.sk89q.worldedit.session.ClipboardHolder import com.sk89q.worldedit.world.World import io.papermc.paper.command.brigadier.argument.ArgumentTypes -import kotlin.math.floor +import org.bukkit.entity.Player object DeeperCommands { fun registerCommands() { @@ -180,31 +176,22 @@ object DeeperCommands { } } "depth" { - playerExecutes() { - val section = WorldManager.getSectionFor(player.location) - if (section == null) { - sender.info("${player.name} is not in a managed section") - return@playerExecutes - } - - var depth = (section.region.max.y - floor(player.location.y)).toInt() - - var currentSection: Section = section - var aboveSection = section.aboveKey.section + val playerArg = ArgumentTypes.player() + .resolve() + .default { listOf(executor as? Player ?: fail("Receiver must be a player or pass a player as argument")) } - if (aboveSection != null) { - depth += 1 // Account for one unit of depth missing when calculating depth with multiple sections - } - - while (aboveSection != null) { - depth += aboveSection.height - depth += aboveSection.overlapWith(currentSection) ?: 0 + executes(playerArg) { players -> + val player = players.single() - currentSection = aboveSection - aboveSection = currentSection.aboveKey.section - } + WorldManager.getDepthFor(player.location)?.let{ + if (sender is Player){ + sender.success("Your depth is $it blocks") + } + else{ + sender.success("Depth of player ${player.name} is $it blocks") + } - player.success("Your depth is: $depth") + } ?: sender.error("${player.name} is not in a managed section") } } } diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/services/WorldManager.kt b/src/main/kotlin/com/mineinabyss/deeperworld/services/WorldManager.kt index 7ecc572..461a030 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/services/WorldManager.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/services/WorldManager.kt @@ -24,6 +24,7 @@ interface WorldManager { * Given x,y coords and a world, return the Section it is within * * @param x The x coordinate + * @param y The y coordinate * @param z The z coordinate * @param world The world * @return The section or null if the location is not within a section. @@ -71,6 +72,24 @@ interface WorldManager { */ fun unregisterSection(key: SectionKey) + /** + * Gets the depth in blocks of the given location, taking sections into account + * + * @param location The location + * @return The depth of the given location in blocks, or null if location is not in a managed section + */ + fun getDepthFor(location: Location): Int? + + /** + * Gets the depth in blocks of the given position, taking sections into account + * @param x The x coordinate + * @param y The y coordinate + * @param z The z coordinate + * @param world The world + * @return The depth of the given position in blocks, or null if position is not in a managed section + */ + fun getDepthFor(x: Double, y: Double, z: Double, world: World): Int? + /** * Gets an immutable copy of the currently loaded sections. */ diff --git a/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt b/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt index b61ccc4..019b9ab 100644 --- a/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt +++ b/src/main/kotlin/com/mineinabyss/deeperworld/world/WorldManagerImpl.kt @@ -5,8 +5,12 @@ import com.mineinabyss.deeperworld.services.WorldManager import com.mineinabyss.deeperworld.world.section.AbstractSectionKey.CustomSectionKey import com.mineinabyss.deeperworld.world.section.Section import com.mineinabyss.deeperworld.world.section.SectionKey +import com.mineinabyss.deeperworld.world.section.overlapWith +import com.mineinabyss.deeperworld.world.section.section +import com.mineinabyss.idofront.messaging.info import org.bukkit.Location import org.bukkit.World +import kotlin.math.floor class WorldManagerImpl : WorldManager { override val sections get() = sectionMap.values.toSet() @@ -28,6 +32,40 @@ class WorldManagerImpl : WorldManager { override fun unregisterSection(key: SectionKey) = TODO() + override fun getDepthFor(location: Location): Int? { + val section = WorldManager.getSectionFor(location) ?: return null + + return this.internalGetDepthFor(floor(location.y).toInt(), section) + } + + override fun getDepthFor(x: Double, y: Double, z: Double, world: World): Int? { + val yFloored = floor(y).toInt() + val section = WorldManager.getSectionFor(floor(x).toInt(), yFloored, floor(z).toInt(), world) ?: return null + + return this.internalGetDepthFor(yFloored, section) + } + + private fun internalGetDepthFor(y: Int, section: Section): Int { + var depth = (section.region.max.y - y) + + var currentSection: Section = section + var aboveSection = section.aboveKey.section + + if (aboveSection != null) { + depth += 1 // Account for one unit of depth missing when calculating depth with multiple sections + } + + while (aboveSection != null) { + depth += aboveSection.height + depth -= aboveSection.overlapWith(currentSection) ?: 0 + + currentSection = aboveSection + aboveSection = currentSection.aboveKey.section + } + + return depth + } + override fun getSectionFor(location: Location): Section? { return getSectionFor(location.blockX, location.blockY, location.blockZ, location.world!!) }