WorldNavigation.gd 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. extends Node
  2. class_name WorldNavigation
  3. # Instance init
  4. static func LoadData(map : WorldMap):
  5. var obj : Object = Instantiate.LoadMapData(map.id, Path.MapNavigationExt)
  6. if obj:
  7. map.navPoly = obj
  8. map.navPoly.cell_size = 0.1
  9. static func CreateInstance(map : WorldMap, mapRID : RID):
  10. if map.navPoly:
  11. map.mapRID = mapRID if mapRID.is_valid() else NavigationServer2D.map_create()
  12. NavigationServer2D.map_set_active(map.mapRID, true)
  13. NavigationServer2D.map_set_cell_size(map.mapRID, map.navPoly.cell_size)
  14. map.regionRID = NavigationServer2D.region_create()
  15. NavigationServer2D.region_set_map(map.regionRID, map.mapRID)
  16. NavigationServer2D.region_set_navigation_polygon(map.regionRID, map.navPoly)
  17. NavigationServer2D.region_set_navigation_layers(map.regionRID, 1)
  18. # Getter
  19. static func GetPathLengthSquared(agent : BaseAgent, pos : Vector2) -> float:
  20. if agent:
  21. var map : WorldMap = WorldAgent.GetMapFromAgent(agent)
  22. if map:
  23. var path : PackedVector2Array = NavigationServer2D.map_get_path(map.mapRID, agent.position, pos, true)
  24. return Util.UnrollPathLength(path)
  25. return INF
  26. static func GetDistanceSquared(agent : BaseAgent, pos : Vector2) -> float:
  27. var pathLengthSquared : float = GetPathLengthSquared(agent, pos)
  28. if pathLengthSquared != INF:
  29. var distLengthSquared : float = agent.position.distance_squared_to(pos)
  30. return INF if (distLengthSquared - pathLengthSquared) > ActorCommons.MismatchPathSquaredThreshold else pathLengthSquared
  31. return pathLengthSquared
  32. # Utils
  33. static func GetRandomPosition(map : WorldMap) -> Vector2i:
  34. assert(map != null && map.navPoly != null && map.navPoly.get_polygon_count() > 0, "No triangulation available")
  35. if map != null && map.navPoly != null && map.navPoly.get_polygon_count() > 0:
  36. return NavigationServer2D.map_get_random_point(map.mapRID, 1, false)
  37. assert(false, "Mob could not be spawned, no available point on the navigation mesh were found")
  38. return Vector2i.ZERO
  39. static func GetRandomPositionAABB(map : WorldMap, pos : Vector2i, offset : Vector2i) -> Vector2i:
  40. assert(map != null, "Could not create a random position for a non-initialized map")
  41. if map != null:
  42. for i in NetworkCommons.NavigationSpawnTry:
  43. var randPoint : Vector2i = Vector2i(randi_range(-offset.x, offset.x), randi_range(-offset.y, offset.y))
  44. randPoint += pos
  45. var closestPoint : Vector2i = NavigationServer2D.map_get_closest_point(map.mapRID, randPoint)
  46. if randPoint == closestPoint:
  47. return randPoint
  48. return GetRandomPosition(map)
  49. return Vector2i.ZERO
  50. static func GetSpawnPosition(map : WorldMap, spawn : SpawnObject, hasNavigation : bool) -> Vector2i:
  51. var position : Vector2i = Vector2i.ZERO
  52. if not spawn.is_global:
  53. if hasNavigation:
  54. position = WorldNavigation.GetRandomPositionAABB(map, spawn.spawn_position, spawn.spawn_offset)
  55. else:
  56. position = spawn.spawn_position
  57. if position == Vector2i.ZERO:
  58. position = WorldNavigation.GetRandomPosition(map)
  59. assert(position != Vector2i.ZERO, "Could not spawn the agent %s, no walkable position found" % spawn.id)
  60. return position