public static BTStatus AmphibiousMovement(Animal agent, Vector2 generalDirection, float speed, AnimalAnimationState state, float minDistance = 2f, float maxDistance = 20f) { var start = agent.Position.WorldPosition3i; if (!World.World.IsUnderwater(start)) start = RouteManager.NearestWalkableY(agent.Position.WorldPosition3i); if (!start.IsValid) return LandMovement(agent, generalDirection, speed, state, minDistance, maxDistance); if (generalDirection == Vector2.zero) generalDirection = Vector2.right.Rotate(RandomUtil.Range(0f, 360)); else generalDirection = generalDirection.Normalized; var target = (agent.Position + (generalDirection * RandomUtil.Range(minDistance, maxDistance)).X_Z()).WorldPosition3i; if (World.World.IsUnderwater(target)) target.y = World.World.MaxWaterHeight[target]; else target = RouteManager.NearestWalkableXYZ(target, 5); // This is a low-effort search that includes water surface and should occasionally fail, just pick a semi-random node that was visited when it fails var allowWaterSearch = new AStarSearch(RouteCacheData.NeighborsIncludeWater, start, target, 30); if (allowWaterSearch.Status != SearchStatus.PathFound) { target = allowWaterSearch.Nodes.Last().Key; allowWaterSearch.GetPath(target); } if (allowWaterSearch.Path.Count < 2) return BTStatus.Failure; else if (allowWaterSearch.Status == SearchStatus.Unpathable && allowWaterSearch.Nodes.Count < RouteRegions.MinimumRegionSize && !World.World.IsUnderwater(agent.Position.WorldPosition3i)) { // Search region was unexpectedly small and agent is on land, might be trapped by player construction. // Try regular land movement so region checks can apply & the agent can get unstuck (or die) return LandMovement(agent, generalDirection, speed, state, minDistance, maxDistance); } var smoothed = allowWaterSearch.LineOfSightSmooth(agent.Position); PiecewiseLinearFunction route = AIUtilities.ProjectRoute(smoothed, speed); agent.AnimationState = state; agent.NextTick = WorldTime.Seconds + route.EndTime; agent.Target.SetPath(route); return BTStatus.Success; }