From 589ed88a5924a7494e21b95b6bbff5e46ff49ddd Mon Sep 17 00:00:00 2001
From: asmrobot <asmrobot@hotmail.com>
Date: Thu, 21 Nov 2019 01:08:42 +0000
Subject: [PATCH] kalete map

---
 src/RichCreator.Utility/Maps/HouseInfo.cs |  243 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 178 insertions(+), 65 deletions(-)

diff --git a/src/RichCreator.Utility/Maps/HouseInfo.cs b/src/RichCreator.Utility/Maps/HouseInfo.cs
index 3eea125..1cd26b0 100644
--- a/src/RichCreator.Utility/Maps/HouseInfo.cs
+++ b/src/RichCreator.Utility/Maps/HouseInfo.cs
@@ -19,10 +19,10 @@
         public HouseInfo(HousePathInfo houseInfo)
         {
             this.HousePathInfo = houseInfo;
-            InitPathInfo();
+            InitPathInfo(null);
         }
 
-        public HouseInfo(Int32 index,MapType mapType,bool isEnd, HIDCode[] skills)
+        public HouseInfo(Int32 index,MapType mapType,bool isEnd, HIDCode[] skills,Int32[] withoutNumber)
         {
             this.Index = index;
             this.MapType = mapType;
@@ -48,7 +48,7 @@
                 throw e;
             }
 
-            InitPathInfo();
+            InitPathInfo(withoutNumber);
         }
         
 
@@ -57,32 +57,24 @@
         /// </summary>
         public Int32 Index { get; set; }
 
-        ///// <summary>
-        ///// 下一房间编号
-        ///// </summary>
-        //public Int32 NextIndex { get; set; }
-
-        ///// <summary>
-        ///// 判断下一房间是否打开索引
-        ///// </summary>
-        //public Int32 OpenStatusDetectIndex { get; set; }
-
+        private Direction[] doorDirection = null;
         /// <summary>
         /// 门的位置
+        /// todo:cacel
         /// </summary>
-        public Direction[] DoorDirection { get; set; }
+        public Direction[] DoorDirection
+        {
+            get
+            {
+                return doorDirection;
+            }
+        }
 
         /// <summary>
         /// 技能队列
         /// </summary>
         public SkillQueue Skills { get; set; }
-
-        /// <summary>
-        /// 房间的Y轴中间线,为负值,代表从游戏框向上移的像素值
-        /// </summary>
-        public Int32 HouseCenterMoveLine { get; set; }
-
-
+               
         /// <summary>
         /// 是否为结束房间
         /// </summary>
@@ -108,6 +100,11 @@
         /// 定位字典
         /// </summary>
         private Dictionary<Int32, ZTPoint> LocationDic = new Dictionary<int, ZTPoint>();
+
+        /// <summary>
+        /// 排除数字
+        /// </summary>
+        public Dictionary<Int32, bool> WithoutNumber = new Dictionary<int, bool>();
 
         /// <summary>
         /// 屏幕坐标转地图坐标
@@ -150,9 +147,8 @@
         /// </summary>
         /// <param name="start"></param>
         /// <param name="end"></param>
-        public List<ZTPoint> FindPath(ref ZTPoint start, ref ZTPoint end)
+        public List<ZTPoint> FindPath(ZTPoint start, ZTPoint end)
         {
-
             if (start.Equals(end))
             {
                 return new List<ZTPoint>();
@@ -166,38 +162,108 @@
             }
 
             //确保两点不在障碍物里
-            bool inObstacle = EnsureNotInObstacle(ref start);
-            inObstacle = EnsureNotInObstacle(ref end) || inObstacle;
+            ZTPoint startPathGuid = ZTPoint.Empty;
+            ZTPoint endPathGuid = ZTPoint.Empty;
+            bool inObstacle = EnsureNotInObstacle(out startPathGuid, start);
+            inObstacle = EnsureNotInObstacle(out endPathGuid, end) || inObstacle;
 
             //查询两点间是否连通
-            if (inObstacle && Iscross(start, end))
+            if (inObstacle && Iscross(startPathGuid, endPathGuid))
             {
                 //两点直接连通
-                return new List<ZTPoint>() { end };
+                List<ZTPoint> points = new List<ZTPoint>();
+                if (!start.Equals(startPathGuid))
+                {
+                    points.Add(startPathGuid);
+                }
+                if (!end.Equals(endPathGuid))
+                {
+                    points.Add(endPathGuid);
+                }
+                points.Add(end);
+                return points;
             }
 
 
             //把两点添加到寻路网中
-            AddConnectivityEdgeToFinder(start, end);
+            AddConnectivityEdgeToFinder(startPathGuid, endPathGuid);
 
             //寻路,组合路径
-            List<ZTPoint> paths = this.PathFinder.ShortestPath(start, end);
+            List<ZTPoint> paths = this.PathFinder.ShortestPath(startPathGuid, endPathGuid);
 
             //去除寻路网中
-            RemoveStartAndEndVerticeFromFinder(start, end);
+            RemoveStartAndEndVerticeFromFinder(endPathGuid, endPathGuid);
+
+            //生成的路径不包含第一个点,拟如果第一个点是路径引导,则加入路径
+            if (!start.Equals(startPathGuid))
+            {
+                paths.Insert(0, startPathGuid);
+            }
+
+            //如果最后一个点是路径引导点,测加上终点
+            if (!end.Equals(endPathGuid))
+            {
+                paths.Add(end);
+            }
+
             return paths;
+        }
+        
+
+        /// <summary>
+        /// 是否在下一关进门点区域内
+        /// </summary>
+        /// <param name="nextGatePoint"></param>
+        /// <param name="rolePosition"></param>
+        /// <returns></returns>
+        public bool IsInNextGatePoint(out ParametersPoint nextGatePoint, ZTPoint rolePosition)
+        {
+            nextGatePoint = ParametersPoint.Empty;
+            const Int32 X_OFFSET = 5;
+            const Int32 Y_OFFSET = 5;
+            for (Int32 i = 0; i < this.HousePathInfo.NextGates.Count; i++)
+            {
+                ParametersPoint nextGate = this.HousePathInfo.NextGates[i];
+                if (GeoHelper.IsInRect(rolePosition, new ZTRectangle(nextGate.Point.X- X_OFFSET, nextGate.Point.Y- Y_OFFSET, nextGate.Point.X+ X_OFFSET, nextGate.Point.Y+ Y_OFFSET)))
+                {
+                    nextGatePoint = nextGate;
+                    return true;
+                }
+            }
+            return false;
         }
 
         /// <summary>
-        /// 查找到下一关进门点
+        /// 获取指定方向的进门点
         /// </summary>
-        /// <param name="rolePosition"></param>
+        /// <param name="dir"></param>
         /// <returns></returns>
-        public List<ZTPoint> FindDoorPath(out Int32 doorIndex,ZTPoint rolePosition)
+        public ZTPoint GetNextGatePoint(Direction dir)
         {
-            doorIndex = 0;
-            ZTPoint end = this.HousePathInfo.NextGates[0].Point;
-            return FindPath(ref rolePosition, ref end);
+            int dirNumber = 0;
+            switch (dir)
+            {
+                case Direction.Up:
+                    dirNumber = 0;
+                    break;
+                case Direction.Right:
+                    dirNumber = 1;
+                    break;
+                case Direction.Bottom:
+                    dirNumber = 2;
+                    break;
+                case Direction.Left:
+                    dirNumber = 3;
+                    break;
+            }
+            for (int i = 0; i < this.HousePathInfo.NextGates.Count; i++)
+            {
+                if (dirNumber == this.HousePathInfo.NextGates[i].Parameter)
+                {
+                    return this.HousePathInfo.NextGates[i].Point;
+                }
+            }
+            throw new ArgumentOutOfRangeException("house index:" + this.Index.ToString() + ",direction :" + dir.ToString() + " is not exists!~");
         }
 
         /// <summary>
@@ -208,10 +274,9 @@
         /// <returns></returns>
         private bool Iscross(ZTPoint start, ZTPoint end)
         {
-
             for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++)
             {
-                Intersection interSection = GeometryHelper.IntersectionOf(new ZTLinePoint(start, end), this.HousePathInfo.Obstacles[i]);
+                Intersection interSection = GeoHelper.IntersectionOf(new ZTLinePoint(start, end), this.HousePathInfo.Obstacles[i]);
                 if (interSection != Intersection.None)
                 {
                     return false;
@@ -223,16 +288,18 @@
         /// <summary>
         /// 是否在障碍物里,如果在障碍物里则返回最近的不在障碍物点
         /// </summary>
-        /// <param name="point"></param>
+        /// <param name="pathGuidePoint"></param>
         /// <returns>true:在障碍物,false:不在障碍物里</returns>
-        private bool EnsureNotInObstacle(ref ZTPoint point)
+        private bool EnsureNotInObstacle(out ZTPoint pathGuidePoint,ZTPoint source)
         {
-            ZTPoint source = new ZTPoint(point.X, point.Y);
+            pathGuidePoint = ZTPoint.Empty;
+
+            //点是否在障碍物里
             ZTPolygon obstacle = ZTPolygon.Empty;
             for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++)
             {
                 ZTPolygon temp = this.HousePathInfo.Obstacles[i];
-                if (GeometryHelper.IntersectionOf(point, temp) != Intersection.None)
+                if (GeoHelper.IntersectionOf(source, temp) != Intersection.None)
                 {
                     obstacle = this.HousePathInfo.Obstacles[i];
                     break;
@@ -241,8 +308,21 @@
             if (obstacle.Equals(ZTPolygon.Empty))
             {
                 //不在障碍物内
+                pathGuidePoint = source;
                 return false;
             }
+
+            //点是否在路径导引区域
+            for (int i = 0; i < this.HousePathInfo.PathGuides.Count; i++)
+            {
+                ZTTargetPolygon temp = this.HousePathInfo.PathGuides[i];
+                if (GeoHelper.IntersectionOf(source, temp.Polygon) != Intersection.None)
+                {
+                    pathGuidePoint = temp.Target;
+                    return true;
+                }
+            }
+
 
             //计算距离障碍物外最近的距离
             double distance = 0;
@@ -252,9 +332,9 @@
                 if (i == 0)
                 {
                     lastPoint = obstacle.Points[i];
-                    distance = GeometryHelper.GetPointDistance(lastPoint, point);
+                    distance = GeoHelper.GetPointDistance(lastPoint, pathGuidePoint);
                 }
-                double lastDistance = GeometryHelper.GetNearestDistance(new ZTLinePoint(lastPoint, obstacle[i]), point);
+                double lastDistance = GeoHelper.GetNearestDistance(new ZTLinePoint(lastPoint, obstacle[i]), pathGuidePoint);
                 if (lastDistance < distance)
                 {
                     distance = lastDistance;
@@ -267,55 +347,55 @@
             }
 
             //查找最近离开障碍物的点
-            ZTPoint testPoint = new ZTPoint(point.X, point.Y);
-            Int32 maxDistance = Math.Max(Math.Max(point.X, this.HousePathInfo.Width - point.X), Math.Max(point.Y, this.HousePathInfo.Height - point.Y));
+            ZTPoint testPoint = ZTPoint.Empty;
+            Int32 maxDistance = Math.Max(Math.Max(source.X, this.HousePathInfo.Width - source.X), Math.Max(source.Y, this.HousePathInfo.Height - source.Y));
             for (int i = (Int32)distance; i < maxDistance; i++)
             {
                 //下
-                if (point.Y + i <= this.HousePathInfo.Height)
+                if (source.Y + i <= this.HousePathInfo.Height)
                 {
-                    testPoint = new ZTPoint(point.X, point.Y + i);
-                    if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
+                    testPoint = new ZTPoint(source.X, source.Y + i);
+                    if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
                     {
                         testPoint.Y += 10;
-                        point = testPoint;
+                        pathGuidePoint = testPoint;
                         break;
                     }
                 }
 
 
                 //右
-                if (point.X <= this.HousePathInfo.Width)
+                if (source.X <= this.HousePathInfo.Width)
                 {
-                    testPoint = new ZTPoint(point.X + i, point.Y);
-                    if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
+                    testPoint = new ZTPoint(source.X + i, source.Y);
+                    if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
                     {
                         testPoint.X += 10;
-                        point = testPoint;
+                        pathGuidePoint = testPoint;
                         break;
                     }
                 }
 
                 //左
-                if (point.X - i >= 0)
+                if (source.X - i >= 0)
                 {
-                    testPoint = new ZTPoint(point.X - i, point.Y);
-                    if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
+                    testPoint = new ZTPoint(source.X - i, source.Y);
+                    if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
                     {
                         testPoint.X -= 10;
-                        point = testPoint;
+                        pathGuidePoint = testPoint;
                         break;
                     }
                 }
 
                 //上
-                if (point.Y - i >= 0)
+                if (source.Y - i >= 0)
                 {
-                    testPoint = new ZTPoint(point.X, point.Y - i);
-                    if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
+                    testPoint = new ZTPoint(source.X, source.Y - i);
+                    if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None)
                     {
                         testPoint.Y -= 10;
-                        point = testPoint;
+                        pathGuidePoint = testPoint;
                         break;
                     }
                 }
@@ -327,7 +407,7 @@
         /// <summary>
         /// 初始化寻路器
         /// </summary>
-        private void InitPathInfo()
+        private void InitPathInfo(Int32[] withoutNumber)
         {
             this.PathFinder = new Dijkstra<ZTPoint>();
 
@@ -349,6 +429,39 @@
                     this.LocationDic.Add(pp.Parameter, pp.Point);
                 }
             }
+
+            //计算门朝向
+            doorDirection = new Direction[this.HousePathInfo.NextGates.Count];
+            for (Int32 i = 0; i < this.HousePathInfo.NextGates.Count; i++)
+            {
+                switch (this.HousePathInfo.NextGates[i].Parameter)
+                {
+                    case 0:
+                        doorDirection[i] = Direction.Up;
+                        break;
+                    case 1:
+                        doorDirection[i] = Direction.Right;
+                        break;
+                    case 2:
+                        doorDirection[i] = Direction.Bottom;
+                        break;
+                    case 3:
+                        doorDirection[i] = Direction.Left;
+                        break;
+                }
+            }
+
+            if (withoutNumber != null)
+            {
+                for (int i = 0; i < withoutNumber.Length; i++)
+                {
+                    if (!this.WithoutNumber.ContainsKey(withoutNumber[i]))
+                    {
+                        this.WithoutNumber.Add(withoutNumber[i], true);
+                    }
+                }
+            }
+            
         }
 
         /// <summary>
@@ -365,13 +478,13 @@
                 point = this.HousePathInfo.FindPathPoints[i];
                 if (Iscross(start, point))
                 {
-                    distance = (Int32)GeometryHelper.GetPointDistance(start, point);
+                    distance = (Int32)GeoHelper.GetPointDistance(start, point);
                     this.PathFinder.AddEdge(start, point, distance);
                 }
 
                 if (Iscross(end, point))
                 {
-                    distance = (Int32)GeometryHelper.GetPointDistance(end, point);
+                    distance = (Int32)GeoHelper.GetPointDistance(end, point);
                     this.PathFinder.AddEdge(end, point, distance);
                 }
             }

--
Gitblit v1.9.3