Пример #1
0
        private float GetEstimatedCost(Int2D End, Map map, float estimateAggression)
        {
            const float scale      = 1f;
            float       multiplier = scale * ((estimateAggression < 0f) ? -estimateAggression : estimateAggression);

            return((Index.x < End.x ? End.x - Index.x : Index.x - End.x) * multiplier + (Index.y < End.y ? End.y - Index.y : Index.y - End.y) * multiplier);
        }
Пример #2
0
        public static Int2D[] IndexesBetween(Map map, Int2D start, Int2D end)         // Start and end both are inclusive
        {
            if (start.x > end.x)
            {
                int StartX = start.x;

                start.x = end.x;
                end.x   = StartX;
            }
            if (start.y > end.y)
            {
                int StartY = start.y;

                start.y = end.y;
                end.y   = StartY;
            }

            start = BringInBounds(map, start);
            end   = BringInBounds(map, end);

            Int2D[] collectedNodes = new Int2D[((end.x - start.x) + 1) * ((end.y - start.y) + 1)];
            int     current        = 0;

            for (int i = start.x; i <= end.x; i++)
            {
                for (int j = start.y; j <= end.y; j++)
                {
                    collectedNodes[current++] = new Int2D(i, j);
                }
            }

            return(collectedNodes);
        }
Пример #3
0
        public void CalculateFGH(Int2D End, Map map, float aggression)
        {
            const float scale      = 1f;
            float       multiplier = scale * ((aggression < 0f) ? -aggression : aggression);

            G = Parent != null ? Parent.G + (Parent.MoveCost * scale * ((Parent.Index.x != Index.x && Parent.Index.y != Index.y) ? 1.414f : 1f)) : 0f;
            H = (Index.x < End.x ? End.x - Index.x : Index.x - End.x) * multiplier + (Index.y < End.y ? End.y - Index.y : Index.y - End.y) * multiplier;
            F = G + H;
        }
Пример #4
0
        public static void UpdateNodeRuntime(Map map, Int2D index, Config config)
        {
            map.MakeBusy();

            UpdateNode(map.GetNode(index), config, false);

            map.MakeFree();

            map.TriggerUpdateEvent();
        }
Пример #5
0
 public Node(Int2D Index, Vector Position, bool Walkable, float MoveCost, Node Parent, bool OnOpenList, bool OnClosedList, float F, float G, float H,
             int BHIndex) : this(Index, Position, Walkable, MoveCost)
 {
     this.Parent       = Parent;
     this.OnOpenList   = OnOpenList;
     this.OnClosedList = OnClosedList;
     this.F            = F;
     this.G            = G;
     this.H            = H;
     this.BHIndex      = BHIndex;
 }
Пример #6
0
 public PathRequest(Int2D Start, Int2D End, Map map, float EstimateAggression, bool MoveDiognal, float MaxDepthDiff, float DepthCostAggression, Int2D[] disallowedIndexes, System.Action <Vector[]> OutputMethod)
 {
     this.Start = Start;
     this.End   = End;
     this.map   = map;
     this.EstimateAggression  = EstimateAggression;
     this.MoveDiognal         = MoveDiognal;
     this.OutputMethod        = OutputMethod;
     this.DepthCostAggression = DepthCostAggression;
     this.MaxDepthDifference  = MaxDepthDiff;
     this.disallowedIndexes   = disallowedIndexes;
 }
Пример #7
0
        /// <summary>
        /// This calculates the difference in the dept (Z or Y axis) as cost too
        /// </summary>
        public void CalculateFGH(Int2D End, Map map, float aggression, float depthAggression, Generator.Config config)
        {
            const float scale      = 1f;
            float       multiplier = scale * ((aggression < 0f) ? -aggression : aggression);

            Vector parentPos      = Parent.Position;
            int    depthDimension = config.XYGrid ? 2 : 1;
            float  depthDiff      = parentPos[depthDimension] < Position[depthDimension] ? Position[depthDimension] - parentPos[depthDimension] : parentPos[depthDimension] - Position[depthDimension];

            G = Parent != null ? (Parent.G + (Parent.MoveCost * scale * ((Parent.Index.x != Index.x && Parent.Index.y != Index.y) ? 1.414f : 1f))) + (depthAggression * depthDiff)  : 0f;
            H = (Index.x < End.x ? End.x - Index.x : Index.x - End.x) * multiplier + (Index.y < End.y ? End.y - Index.y : Index.y - End.y) * multiplier;
            F = G + H;
        }
Пример #8
0
        public Node(Node node, bool deep)
        {
            this.Index    = node.Index;
            this.Position = node.Position;
            this.Walkable = node.Walkable;
            this.MoveCost = node.MoveCost;

            if (deep)
            {
                this.Parent       = node.Parent;
                this.OnOpenList   = node.OnOpenList;
                this.OnClosedList = node.OnClosedList;
                this.F            = node.F;
                this.G            = node.G;
                this.H            = node.H;
                this.BHIndex      = node.BHIndex;
            }
        }
Пример #9
0
        private static PathRequest RequestPath(Int2D Start, Int2D End, Map map, float estimateAggression, bool moveDiognal, float maxDepthDiff, float depthDiffCostMultiplier, Int2D[] disallowedIndexes, System.Action <Vector[]> OutputMethod)
        {
            if (RequestQue == null)
            {
                RequestQue = new System.Collections.Generic.Queue <PathRequest>();
            }

            UtilityMonoBehaviour.CreateInstance();
            PathRequest request = new PathRequest(Start, End, map, estimateAggression, moveDiognal, maxDepthDiff, depthDiffCostMultiplier, disallowedIndexes, OutputMethod);

            RequestQue.Enqueue(request);

            if (RequestProcessThread == null || !RequestProcessThread.IsAlive)
            {
                RequestProcessThread          = new Thread(ProcessRequests);
                RequestProcessThread.Priority = DefaultPriority;
                RequestProcessThread.Start();
            }

            return(request);
        }
Пример #10
0
        public static void UpdateNodesRuntime(Map map, Int2D Start, Int2D End)
        {
            map.MakeBusy();

            Node[,] nodes = map.GetNodeArrayReference();
            Generator.Config config = map.GetConfig();

            if (End.x < Start.x)
            {
                int startX = Start.x;
                Start.x = End.x;
                End.x   = startX;
            }
            if (End.y < Start.y)
            {
                int startY = Start.y;
                Start.y = End.y;
                End.y   = startY;
            }

            if (Start.x < 0 || Start.y < 0 || End.x > map.TilesX || End.y > map.TilesY)
            {
                throw new System.IndexOutOfRangeException("Node index is out of range");
            }

            for (int i = Start.x; i < End.x; i++)
            {
                for (int j = Start.y; j < End.y; j++)
                {
                    UpdateNode(nodes[i, j], config, false);
                }
            }

            map.MakeFree();

            map.TriggerUpdateEvent();
        }
Пример #11
0
        private static Vector[] FindPathImmediate(Int2D Start, Int2D End, Map map, float estimateAggression, bool moveDiognal, float maxDepthDiff, float depthCostAggression, Int2D[] disallowedIndexes)
        {
            Initialise(map);

            Start = map.BringInBounds(Start);
            End   = map.BringInBounds(End);

            if (disallowedIndexes != null)
            {
                for (int i = 0; i < disallowedIndexes.Length; i++)
                {
                    Node node = Nodes[disallowedIndexes[i].x, disallowedIndexes[i].y];
                    ClosedList[ClosedListLength++] = node;
                    node.OnOpenList   = false;
                    node.OnClosedList = true;
                }
            }

            int depthDimension = config.XYGrid ? 1 : 2;

            // We disallowed the target node!  // And starting one too....
            if (!Nodes[Start.x, Start.y].Walkable || !Nodes[End.x, End.y].Walkable || Nodes[End.x, End.y].OnClosedList || Nodes[Start.x, Start.y].OnClosedList)
            {
                Clean();
                return(null);
            }

            Node current = Nodes[Start.x, Start.y];

            current.CalculateFGH(End, map, estimateAggression);
            AddToBH(current);

            while (!Nodes[End.x, End.y].OnClosedList)
            {
                if (OpenListLength < 0)
                {
                    Clean();
                    return(null);
                }

                current = OpenList[1];

                OpenList[1].OnClosedList       = true;
                OpenList[1].OnOpenList         = false;
                ClosedList[ClosedListLength++] = OpenList[1];

                OpenList[1].BHIndex = -1;
                OpenList[1]         = OpenList[OpenListLength--];
                SortFrom(1);

                Int2D currentIndex = current.Index;

                for (int i = 0; i < 8; i++)
                {
                    if (!moveDiognal)
                    {
                        if ((i & 1) != 0)                        // if i is not even
                        {
                            continue;
                        }
                    }

                    Int2D nearbyIndex = currentIndex;

                    switch (i)
                    {
                    case 0:
                        nearbyIndex.x -= 1;
                        break;

                    case 1:
                        nearbyIndex.x -= 1;
                        nearbyIndex.y += 1;
                        break;

                    case 2:
                        nearbyIndex.y += 1;
                        break;

                    case 3:
                        nearbyIndex.y += 1;
                        nearbyIndex.x += 1;
                        break;

                    case 4:
                        nearbyIndex.x += 1;
                        break;

                    case 5:
                        nearbyIndex.x += 1;
                        nearbyIndex.y -= 1;
                        break;

                    case 6:
                        nearbyIndex.y -= 1;
                        break;

                    case 7:
                        nearbyIndex.x -= 1;
                        nearbyIndex.y -= 1;
                        break;
                    }

                    if (nearbyIndex.x < 0 || nearbyIndex.y < 0 || nearbyIndex.x >= TilesX || nearbyIndex.y >= TilesY)
                    {
                        continue;
                    }

                    Node nearbyNode = Nodes[nearbyIndex.x, nearbyIndex.y];

                    float depthDiff = nearbyNode.Position[depthDimension] - current.Position[depthDimension];
                    depthDiff = depthDiff < 0f ? -depthDiff : depthDiff;

                    if (depthDiff > maxDepthDiff)
                    {
                        continue;
                    }

                    if (nearbyNode.OnOpenList)
                    {
                        if (nearbyNode.G < current.G)
                        {
                            nearbyNode.Parent = current;
                            nearbyNode.CalculateFGH(End, map, estimateAggression, depthCostAggression, config);
                            SortFrom(nearbyNode.BHIndex);
                        }
                    }
                    else if (!nearbyNode.OnClosedList && nearbyNode.Walkable)
                    {
                        nearbyNode.Parent = current;
                        nearbyNode.CalculateFGH(End, map, estimateAggression, depthCostAggression, config);

                        nearbyNode.OnOpenList        = true;
                        nearbyNode.BHIndex           = ++OpenListLength;
                        OpenList[nearbyNode.BHIndex] = nearbyNode;
                        SortFrom(OpenListLength);
                    }
                }
            }

            int  len = 0;
            Node n   = Nodes[End.x, End.y];

            while (n != null)
            {
                n    = n.Parent;
                len += 1;
            }

            n = Nodes[End.x, End.y];
            Vector[] path = new Vector[len];
            int      j    = len - 1;

            while (n != null)
            {
                path[j--] = n.Position;
                n         = n.Parent;
            }

            Clean();

            return(path);
        }
Пример #12
0
        public static void Update(Map map, Int2D index)
        {
            index = map.BringInBounds(index);

            Generator.UpdateNodeRuntime(map, index, map.GetConfig());
        }
Пример #13
0
 public Node GetNode(Int2D index)
 {
     return(Nodes[index.x, index.y]);
 }
Пример #14
0
 public Node(Int2D Index, Vector Position, bool Walkable, float MoveCost) : this(Index, Position, Walkable)
 {
     this.MoveCost = MoveCost;
 }
Пример #15
0
 public Node(Int2D Index, Vector Position, bool Walkable) : this(Index, Position)
 {
     this.Walkable = Walkable;
 }
Пример #16
0
 public Node(Int2D Index, Vector Position) : this(Index)
 {
     this.Position = Position;
 }
Пример #17
0
 public Node(Int2D Index)
 {
     this.Index = Index;
 }
Пример #18
0
 public bool InBounds(Int2D start)
 {
     return((start.x >= 0 && start.x < config.TilesX) && (start.y >= 0 && start.y < config.TilesY));
 }
Пример #19
0
 public Int2D BringInBounds(Int2D index)
 {
     return(new Int2D(index.x < 0 ? 0 : index.x >= TilesX ? TilesX - 1 : index.x, index.y < 0 ? 0 : index.y >= TilesY ? TilesY - 1 : index.y));
 }
Пример #20
0
 public static Int2D BringInBounds(Map map, Int2D index)
 {
     return(map.BringInBounds(index));
 }
Пример #21
0
 public Int2D(Int2D int2D)
 {
     this.x = int2D.x;
     this.y = int2D.y;
 }
Пример #22
0
 public static void Update(Map map, Int2D start, Int2D end)
 {
     start = map.BringInBounds(start);
     end   = map.BringInBounds(end);
     Generator.UpdateNodesRuntime(map, start, end);
 }