Even better tele pos determination logic
This commit is contained in:
parent
5586404512
commit
6738921e8a
@ -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<BlockPos>): TraceResult? {
|
||||
phasedBlocks.clear()
|
||||
private fun tryToPhaseThroughWall(blockPos: BlockPos, normal: Vec3i): TraceResult? {
|
||||
val phasedBlocks = ArrayList<BlockPos>(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<TraceResult>()
|
||||
|
||||
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<BlockPos>(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<BlockPos>()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user