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;
        }