Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion module/bukkit/bukkit-navigation/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
dependencies {
compileOnly(project(":common"))
compileOnly(project(":platform:platform-bukkit"))
compileOnly(project(":platform:platform-bukkit-impl"))
compileOnly(project(":module:bukkit-nms"))
// 服务端
compileOnly("ink.ptms.core:v12101:12101-minimize:mapped")
Expand All @@ -9,4 +11,4 @@ dependencies {
compileOnly("ink.ptms.core:v10900:10900")
compileOnly("ink.ptms:nms-all:1.0.0")
compileOnly("ink.ptms.core:v260100:260100-minimize")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.bukkit.Location
import org.bukkit.World
import org.bukkit.block.BlockFace
import org.bukkit.util.Vector
import taboolib.platform.util.callRegion
import java.util.*

/**
Expand Down Expand Up @@ -69,7 +70,9 @@ open class NodeEntity(
}

fun getWalkTargetValue(pos: Vector): Double {
return this.getWalkTargetValue(pos, location.world!!)
return location.callRegion {
this.getWalkTargetValue(pos, location.world!!)
}
}

/**
Expand All @@ -94,14 +97,18 @@ open class NodeEntity(
}

open fun isInWater(): Boolean {
return location.block.isLiquid
return location.callRegion {
location.block.isLiquid
}
}

open fun isOnGround(): Boolean {
return location.block.getRelative(BlockFace.DOWN).type.isSolid
return location.callRegion {
location.block.getRelative(BlockFace.DOWN).type.isSolid
}
}

open fun getAirSupply(): Int {
return 3
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package taboolib.module.navigation
import org.bukkit.util.NumberConversions
import org.bukkit.util.Vector
import taboolib.module.navigation.Fluid.Companion.getFluid
import taboolib.platform.util.callRegion
import kotlin.math.abs

/**
Expand Down Expand Up @@ -50,6 +51,12 @@ open class NodeReader(val entity: NodeEntity) {
* 获取起点
*/
fun getStart(): Node {
return entity.location.callRegion {
getStartAtRegion()
}
}

private fun getStartAtRegion(): Node {
val position = Vector(0, 0, 0)
var y = entity.location.blockY
var block = world.getBlockAt(position.set(entity.location.blockX, y, entity.location.blockZ))
Expand Down Expand Up @@ -109,9 +116,11 @@ open class NodeReader(val entity: NodeEntity) {
* 指最顶层碰撞箱 maxY > 0 的方块
*/
fun getLandHeight(position: Vector): Double {
val block = position.toBlock(world)
val blockHeight = NMS.instance.getBlockHeight(block)
return if (blockHeight == 0.0) 0.0 else blockHeight + block.y
return position.toLocation(world).callRegion {
val block = position.toBlock(world)
val blockHeight = NMS.instance.getBlockHeight(block)
if (blockHeight == 0.0) 0.0 else blockHeight + block.y
}
}

/**
Expand All @@ -126,6 +135,12 @@ open class NodeReader(val entity: NodeEntity) {
* @param z z
*/
open fun getLandNode(x: Int, y: Int, z: Int): Node? {
return Vector(x, y, z).toLocation(world).callRegion {
getLandNodeAtRegion(x, y, z)
}
}

private fun getLandNodeAtRegion(x: Int, y: Int, z: Int): Node? {
var h = y
var node: Node? = null
// 获取方块类型
Expand Down Expand Up @@ -215,6 +230,12 @@ open class NodeReader(val entity: NodeEntity) {
* 临近合法
*/
open fun isNeighborValid(neighbor: Node?, node: Node): Boolean {
return node.asBlockPos().toLocation(world).callRegion {
isNeighborValidAtRegion(neighbor, node)
}
}

private fun isNeighborValidAtRegion(neighbor: Node?, node: Node): Boolean {
if (neighbor != null && !neighbor.isClosed && (neighbor.costMalus >= 0.0f || node.costMalus < 0.0f)) {
val blockHeight = NMS.instance.getBlockHeight(node.asBlockPos().down().toBlock(world)) + node.y - 1
val neighborHeight = NMS.instance.getBlockHeight(neighbor.asBlockPos().down().toBlock(world)) + neighbor.y - 1
Expand Down Expand Up @@ -247,6 +268,12 @@ open class NodeReader(val entity: NodeEntity) {
}

open fun getNeighbors(nodes: Array<Node?>, node: Node): Int {
return node.asBlockPos().toLocation(world).callRegion {
getNeighborsAtRegion(nodes, node)
}
}

private fun getNeighborsAtRegion(nodes: Array<Node?>, node: Node): Int {
var neighbors = 0
// 北
val north = getLandNode(node.x, node.y, node.z - 1)
Expand Down Expand Up @@ -290,4 +317,4 @@ open class NodeReader(val entity: NodeEntity) {
}
return neighbors
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package taboolib.module.navigation
import com.google.common.collect.Lists
import org.bukkit.Location
import org.bukkit.util.Vector
import taboolib.platform.util.callRegion

/**
* Navigation
Expand All @@ -25,6 +26,12 @@ class PathFinder(val nodeReader: NodeReader, val heuristicWeight: Float = 1.5f)
}

fun findPath(position: Set<Vector>, distance: Float, distanceManhattan: Int = 1, deep: Float = 1f): Path? {
return nodeReader.entity.location.callRegion {
findPathAtRegion(position, distance, distanceManhattan, deep)
}
}

private fun findPathAtRegion(position: Set<Vector>, distance: Float, distanceManhattan: Int, deep: Float): Path? {
openSet.clear()
val start = nodeReader.getStart()
val map = position.map {
Expand Down Expand Up @@ -127,4 +134,4 @@ class PathFinder(val nodeReader: NodeReader, val heuristicWeight: Float = 1.5f)
}
return Path(list, position, flag)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package taboolib.module.navigation

import org.bukkit.Location
import org.bukkit.World
import org.bukkit.util.Vector
import taboolib.platform.util.callRegion
import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.sqrt
Expand All @@ -25,6 +27,12 @@ object PathSmoothing {
* 返回平滑后的世界坐标点列表(方块中心)
*/
fun smooth(path: Path, entity: NodeEntity): List<Vector> {
return entity.location.callRegion {
smoothAtRegion(path, entity)
}
}

private fun smoothAtRegion(path: Path, entity: NodeEntity): List<Vector> {
val nodes = path.nodes
if (nodes.size <= 2) {
return nodes.map { nodeCenter(it) }
Expand All @@ -38,7 +46,7 @@ object PathSmoothing {
for (probe in (current + 2)..last) {
// y 不同时不跨越高度差
if (nodes[probe].y != nodes[current].y) break
if (hasLineOfSight(nodeCenter(nodes[current]), nodeCenter(nodes[probe]), entity, world)) {
if (hasLineOfSightAtRegion(nodeCenter(nodes[current]), nodeCenter(nodes[probe]), entity, world)) {
farthest = probe
}
}
Expand All @@ -52,6 +60,12 @@ object PathSmoothing {
* 检查两点之间是否存在无障碍直线路径
*/
fun hasLineOfSight(from: Vector, to: Vector, entity: NodeEntity, world: World): Boolean {
return Location(world, from.x, from.y, from.z).callRegion {
hasLineOfSightAtRegion(from, to, entity, world)
}
}

private fun hasLineOfSightAtRegion(from: Vector, to: Vector, entity: NodeEntity, world: World): Boolean {
val dx = to.x - from.x
val dz = to.z - from.z
val dist = sqrt(dx * dx + dz * dz)
Expand All @@ -61,7 +75,7 @@ object PathSmoothing {
val t = i.toDouble() / steps
val x = from.x + dx * t
val z = from.z + dz * t
if (!isStandable(x, from.y, z, entity, world)) return false
if (!isStandableAtRegion(x, from.y, z, entity, world)) return false
}
return true
}
Expand All @@ -72,6 +86,12 @@ object PathSmoothing {
* - 实体碰撞箱范围内无不可通行方块
*/
fun isStandable(x: Double, y: Double, z: Double, entity: NodeEntity, world: World): Boolean {
return Location(world, x, y, z).callRegion {
isStandableAtRegion(x, y, z, entity, world)
}
}

private fun isStandableAtRegion(x: Double, y: Double, z: Double, entity: NodeEntity, world: World): Boolean {
val halfWidth = entity.width / 2.0
val halfDepth = entity.depth / 2.0
val minBx = floor(x - halfWidth).toInt()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package taboolib.module.navigation

import org.bukkit.util.Vector
import taboolib.platform.Folia
import taboolib.platform.util.callRegion
import java.util.*
import kotlin.math.*

Expand Down Expand Up @@ -95,8 +97,15 @@ object RandomPositionGenerator {
* @param requireWalkable 依赖可行走的方块
*/
fun generate(nodeEntity: NodeEntity, rX: Int, yY: Int, start: Vector?, onWater: Boolean, aboveLand: Boolean, requireWalkable: Boolean): Vector? {
return nodeEntity.location.callRegion {
generateAtRegion(nodeEntity, rX, yY, start, onWater, aboveLand, requireWalkable)
}
}

private fun generateAtRegion(nodeEntity: NodeEntity, rX: Int, yY: Int, start: Vector?, onWater: Boolean, aboveLand: Boolean, requireWalkable: Boolean): Vector? {
val random: Random = nodeEntity.random
val navigation = PathTypeFactory(nodeEntity)
val world = nodeEntity.location.world!!
val hasRestriction: Boolean = if (nodeEntity.hasRestriction) {
nodeEntity.restrictCenter.closerThan(nodeEntity.location.toCommonVector(), (nodeEntity.restrictRadius + rX.toFloat()).toDouble() + 1.0)
} else {
Expand Down Expand Up @@ -138,11 +147,20 @@ object RandomPositionGenerator {
}
if (aboveLand) {
result = moveUp(result, 0, 256) {
nodeEntity.location.world!!.getBlockAt(it.toLocation(nodeEntity.location.world!!)).type.isSolid
if (Folia.isFolia) {
world.getBlockAtIfLoaded(it)?.type?.isSolid == true
} else {
world.getBlockAt(it.toLocation(world)).type.isSolid
}
}
}
if (onWater || nodeEntity.location.world!!.getBlockAt(result.toLocation(nodeEntity.location.world!!)).type.isWater()) {
val type = navigation.getTypeAsWalkable(nodeEntity.location.world!!, result)
val blockType = if (Folia.isFolia) {
world.getBlockAtIfLoaded(result)?.type
} else {
world.getBlockAt(result.toLocation(world)).type
}
if (onWater || blockType?.isWater() == true) {
val type = navigation.getTypeAsWalkable(world, result)
if (nodeEntity.getPathfindingMalus(type) == 0.0f) {
val walk = nodeEntity.getWalkTargetValue(result)
if (walk > sort) {
Expand Down Expand Up @@ -201,4 +219,4 @@ object RandomPositionGenerator {
Vector(rX, rY, rZ)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.bukkit.block.Block
import org.bukkit.util.NumberConversions
import org.bukkit.util.Vector
import taboolib.module.nms.MinecraftVersion
import taboolib.platform.util.callRegion

fun createPathfinder(nodeEntity: NodeEntity): PathFinder {
return PathFinder(NodeReader(nodeEntity))
Expand All @@ -17,10 +18,15 @@ fun World.getBlockAt(position: Vector): Block {
}

fun World.getBlockAtIfLoaded(position: Vector): Block? {
return if (ChunkAccess.instance.isChunkLoaded(this, position.blockX shr 4, position.blockZ shr 4)) {
getBlockAt(position.blockX, position.blockY, position.blockZ)
} else {
null
val x = position.blockX
val y = position.blockY
val z = position.blockZ
return callRegion(x, y, z) {
if (ChunkAccess.instance.isChunkLoaded(this, x shr 4, z shr 4)) {
getBlockAt(x, y, z)
} else {
null
}
}
}

Expand Down Expand Up @@ -135,4 +141,4 @@ fun Block.isBottomSlab(): Boolean {
} else {
NMS.instance.isBottomSlab(this)
}
}
}
Loading
Loading