From 6738921e8abd2a02f17056b7fe47a07b0cf1f544 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 13 Oct 2022 16:57:27 +0700 Subject: [PATCH] Even better tele pos determination logic --- .../android/feature/EnderTeleporterFeature.kt | 75 +++++++++++++++---- 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt index 6cae8a748..d594ef14d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt @@ -48,10 +48,12 @@ import ru.dbotthepony.mc.otm.core.plus import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.shortestDistanceBetween import ru.dbotthepony.mc.otm.core.times +import ru.dbotthepony.mc.otm.core.toDoubleVector import ru.dbotthepony.mc.otm.registry.AndroidFeatures import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.triggers.EnderTeleporterFallDeathTrigger import java.util.LinkedList +import kotlin.math.roundToInt import kotlin.math.sin class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiveFeature(AndroidFeatures.ENDER_TELEPORTER, capability) { @@ -122,8 +124,8 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv } } - private fun tryToPhaseThroughWall(blockPos: BlockPos, normal: Vec3i, phasedBlocks: MutableList): TraceResult? { - phasedBlocks.clear() + private fun tryToPhaseThroughWall(blockPos: BlockPos, normal: Vec3i): TraceResult? { + val phasedBlocks = ArrayList(ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) phasedBlocks.add(blockPos) for (extend in 1 .. ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) { @@ -175,21 +177,26 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv val candidates = LinkedList() - if (result.direction != Direction.UP && result.direction != Direction.DOWN && !isAirGap(result.blockPos) && ply.xRot in -15f .. 15f) { + if ( + result.direction != Direction.UP && + result.direction != Direction.DOWN && + !isAirGap(result.blockPos) && + ply.xRot in -15f .. 15f && + ply.eyePosition.distanceTo(result.blockPos.asVector()) <= 3.5 + ) { val (vx, vy, vz) = ply.getViewVector(1f) val nearest = Direction.getNearest(vx, vy, vz) if (nearest != Direction.UP && nearest != Direction.DOWN) { // attempt one - val phasedBlocks = ArrayList(ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) - var phaseResult = tryToPhaseThroughWall(result.blockPos, nearest.normal, phasedBlocks) + var phaseResult = tryToPhaseThroughWall(result.blockPos, nearest.normal) if (phaseResult != null) { candidates.add(phaseResult) } // attempt two - phaseResult = tryToPhaseThroughWall(result.blockPos, result.direction.opposite.normal, phasedBlocks) + phaseResult = tryToPhaseThroughWall(result.blockPos, result.direction.opposite.normal) if (phaseResult != null) { candidates.add(phaseResult) @@ -197,16 +204,34 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv } } - for (y in (if (ply.level.getBlockState(result.blockPos).`is`(BlockTags.CLIMBABLE)) -1 else 0) .. ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) { - val pos = BlockPos(result.blockPos.x, result.blockPos.y + y + 1, result.blockPos.z) + var phasedBlocks = 0 + val phasedBlocksList = ArrayList() - if (ply.level.getBlockState(pos).`is`(Blocks.BEDROCK)) { + for (y in (if (ply.level.getBlockState(result.blockPos).`is`(BlockTags.CLIMBABLE)) -1 else 0) .. ply.level.maxBuildHeight - ply.level.minBuildHeight) { + val pos = BlockPos(result.blockPos.x, result.blockPos.y + y + 1, result.blockPos.z) + val state = ply.level.getBlockState(pos) + + if (state.`is`(Blocks.BEDROCK)) { // Can't phase through bedrock break } - if (isValidPosition(pos) && shortestDistanceBetween(testPositions, pos.asVector()) <= ServerConfig.EnderTeleporter.MAX_DISTANCE) { - candidates.add(TraceResult(pos, if (y != 0) ImmutableList(y + 1) { result.blockPos + BlockPos(0, it, 0) } else listOf())) + if (!isAirGap(pos)) { + phasedBlocks++ + + if (phasedBlocks >= ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) { + break + } + + phasedBlocksList.add(pos) + } + + if (shortestDistanceBetween(testPositions, pos.asVector()) > ServerConfig.EnderTeleporter.MAX_DISTANCE) { + break + } + + if (isValidPosition(pos)) { + candidates.add(TraceResult(pos, phasedBlocksList)) break } } @@ -233,16 +258,34 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv // no valid positions... if (isAirGap(result.blockPos)) { // try to find ground below... - for (y in 0 downTo -ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) { - val pos = BlockPos(result.blockPos.x, result.blockPos.y + y, result.blockPos.z) + phasedBlocks = 0 + phasedBlocksList.clear() - if (ply.level.getBlockState(pos).`is`(Blocks.BEDROCK)) { + for (y in 0 downTo ply.level.maxBuildHeight - ply.level.minBuildHeight) { + val pos = BlockPos(result.blockPos.x, result.blockPos.y + y, result.blockPos.z) + val state = ply.level.getBlockState(pos) + + if (state.`is`(Blocks.BEDROCK)) { // Can't phase through bedrock break } - if (isValidPosition(pos) && shortestDistanceBetween(testPositions, pos.asVector()) <= ServerConfig.EnderTeleporter.MAX_DISTANCE) { - return TraceResult(pos, if (y != 0) ImmutableList(-y + 1) { result.blockPos - BlockPos(0, it, 0) } else listOf()) + if (!isAirGap(pos)) { + phasedBlocks++ + + if (phasedBlocks >= ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) { + break + } + + phasedBlocksList.add(pos) + } + + if (shortestDistanceBetween(testPositions, pos.asVector()) > ServerConfig.EnderTeleporter.MAX_DISTANCE) { + break + } + + if (isValidPosition(pos)) { + return TraceResult(pos, phasedBlocksList) } } }