mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-28 05:45:10 -06:00
Fixed combat movement pathing past SmartPathfinder limit
Adventure bots could enter combat with NPCs near the edge of the SmartPathfinder truncation window, causing combat movement to try attack tiles at distance 50+ and spam pathfinding exceptions. Skip SMART combat movement destinations that SmartPathfinder cannot attempt, and make the pathfinder cutoff follow max_pathfind_dist instead of a hard-coded 50. Added a regression test for the reported coordinate boundary.
This commit is contained in:
parent
1fe520836b
commit
c52de9464d
3 changed files with 34 additions and 13 deletions
|
|
@ -14,6 +14,7 @@ import core.game.world.map.Point
|
|||
import core.game.world.map.RegionManager
|
||||
import core.game.world.map.path.Path
|
||||
import core.game.world.map.path.Pathfinder
|
||||
import core.game.world.map.path.SmartPathfinder
|
||||
import core.game.world.repository.Repository
|
||||
import java.util.LinkedHashMap
|
||||
|
||||
|
|
@ -405,6 +406,11 @@ object CombatMovementIntents {
|
|||
if (attacker.location == destination.location) {
|
||||
return null
|
||||
}
|
||||
if (destination.pathfinder === Pathfinder.SMART &&
|
||||
!SmartPathfinder.canAttempt(attacker.location, destination.location)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
val path = Pathfinder.find(attacker, destination.node, destination.allowPartialPath, destination.pathfinder)
|
||||
if (!path.reaches(destination.location) && (!destination.allowPartialPath || path.points.isEmpty())) {
|
||||
|
|
|
|||
|
|
@ -71,6 +71,13 @@ internal constructor() : Pathfinder() {
|
|||
*/
|
||||
private var foundPath = false
|
||||
|
||||
companion object {
|
||||
fun canAttempt(start: Location, dest: Location): Boolean {
|
||||
val distance = kotlin.math.floor(Vector.betweenLocs(start, dest).magnitude())
|
||||
return distance < ServerConstants.MAX_PATHFIND_DISTANCE * 2.0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the pathfinder.
|
||||
*/
|
||||
|
|
@ -101,16 +108,16 @@ internal constructor() : Pathfinder() {
|
|||
|
||||
override fun find(start: Location?, moverSize: Int, dest: Location?, sizeX: Int, sizeY: Int, rotation: Int, type: Int, walkingFlag: Int, near: Boolean, clipMaskSupplier: ClipMaskSupplier?): Path {
|
||||
reset()
|
||||
assert(start != null && dest != null)
|
||||
var vec = Vector.betweenLocs(start!!, dest!!)
|
||||
val startLoc = requireNotNull(start)
|
||||
var end = requireNotNull(dest)
|
||||
var vec = Vector.betweenLocs(startLoc, end)
|
||||
var mag = kotlin.math.floor(vec.magnitude())
|
||||
var end = dest!!
|
||||
if (mag > ServerConstants.MAX_PATHFIND_DISTANCE) {
|
||||
try {
|
||||
if (mag < 50.0) { //truncate the path if it's realistically long
|
||||
if (canAttempt(startLoc, end)) { //truncate the path if it's realistically long
|
||||
vec = vec.normalized() * (ServerConstants.MAX_PATHFIND_DISTANCE - 1)
|
||||
end = start!!.transform(vec)
|
||||
} else throw Exception("Pathfinding distance exceeds server max! -> " + mag.toString() + " {" + start + "->" + end + "}")
|
||||
end = startLoc.transform(vec)
|
||||
} else throw Exception("Pathfinding distance exceeds server max! -> " + mag.toString() + " {" + startLoc + "->" + end + "}")
|
||||
} catch (e: Exception) {
|
||||
val sw = StringWriter()
|
||||
val pw = PrintWriter(sw)
|
||||
|
|
@ -129,12 +136,12 @@ internal constructor() : Pathfinder() {
|
|||
cost[x][y] = 99999999
|
||||
}
|
||||
}
|
||||
val z = start!!.z
|
||||
val location = Location.create(start.regionX - 6 shl 3, start.regionY - 6 shl 3, z)
|
||||
curX = start.sceneX
|
||||
curY = start.sceneY
|
||||
dstX = end!!.getSceneX(start)
|
||||
dstY = end.getSceneY(start)
|
||||
val z = startLoc.z
|
||||
val location = Location.create(startLoc.regionX - 6 shl 3, startLoc.regionY - 6 shl 3, z)
|
||||
curX = startLoc.sceneX
|
||||
curY = startLoc.sceneY
|
||||
dstX = end.getSceneX(startLoc)
|
||||
dstY = end.getSceneY(startLoc)
|
||||
var attempts: Int
|
||||
var readPosition: Int
|
||||
check(curX, curY, 99, 0)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import core.game.node.entity.npc.NPC
|
|||
import core.game.node.entity.player.Player
|
||||
import core.game.world.GameWorld
|
||||
import core.game.world.map.Region
|
||||
import core.game.world.map.path.SmartPathfinder
|
||||
import core.net.packet.PacketProcessor
|
||||
import core.plugin.ClassScanner
|
||||
import core.plugin.Plugin
|
||||
|
|
@ -26,6 +27,13 @@ import org.rs09.consts.NPCs
|
|||
class PathfinderTests {
|
||||
companion object {init {TestUtils.preTestSetup(); GatheringSkillOptionListeners().defineListeners(); WoodcuttingListener().defineListeners() }; val NPC_TEST_LOC = ServerConstants.HOME_LOCATION!!.transform(2, 10, 0)}
|
||||
|
||||
@Test fun smartPathfinderShouldRejectDestinationsAtTheTruncationLimit() {
|
||||
val start = Location.create(3165, 3218, 0)
|
||||
|
||||
Assertions.assertTrue(SmartPathfinder.canAttempt(start, Location.create(3203, 3186, 0)))
|
||||
Assertions.assertFalse(SmartPathfinder.canAttempt(start, Location.create(3203, 3185, 0)))
|
||||
}
|
||||
|
||||
@Test fun getOccupiedTilesShouldReturnCorrectSetOfTilesThatAnObjectOccupiesAtAllRotations() {
|
||||
//clay fireplace - 13609 - sizex: 1, sizey: 2
|
||||
val scenery = Scenery(13609, Location.create(50, 50, 0))
|
||||
|
|
@ -257,4 +265,4 @@ class PathfinderTests {
|
|||
Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION!!) <= 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue