示例#1
0
        IntVector3 FindStartLoc(Random r, SideEdge edge)
        {
            int side = m_terrain.Width;

            int yo = r.Next(0, side);
            int zo = m_terrain.GetSurfaceLevel(MapCoord(yo, edge));

            int yu = yo;
            int zu = zo;

            for (int y = yo - 1; y >= 0; --y)
            {
                int z = m_terrain.GetSurfaceLevel(MapCoord(y, edge));
                if (z < zu)
                {
                    zu = z;
                    yu = y;
                }

                if (z - 2 > zu)
                {
                    break;
                }
            }

            int yd = yo;
            int zd = zo;

            for (int y = yo + 1; y < side; ++y)
            {
                int z = m_terrain.GetSurfaceLevel(MapCoord(y, edge));
                if (z < zd)
                {
                    zd = z;
                    yd = y;
                }

                if (z - 2 > zd)
                {
                    break;
                }
            }

            int yf = zd < zu ? yd : yu;
            var p2 = MapCoord(yf, edge);

            return(m_terrain.GetSurfaceLocation(p2));
        }
示例#2
0
        public bool CreateRiverPath()
        {
            int offset = m_random.Next();

            m_riverPath = null;

            for (int i = 0; i < 8; ++i)
            {
                SideEdge edge = (SideEdge)((i + offset) % 4);

                var startLoc = FindStartLoc(m_random, edge);

                var target       = new MyTarget(m_terrain, startLoc, edge);
                int maxNodeCount = 500000;                 // XXX this should reflect the map size
                var res          = AStar.Find(new IntVector3[] { startLoc }, target, maxNodeCount);

                if (res.Status != AStarStatus.Found)
                {
                    continue;
                }

                var riverPath = res.GetPathLocationsReverse().Select(p => p.ToIntVector2()).ToArray();

                if (riverPath.Length < 100)
                {
                    Trace.TraceInformation("retry, too short");
                    continue;
                }

                int tot = riverPath.Aggregate(0, (a, p) =>
                                              a + MyMath.Min(p.X, p.Y, m_terrain.Width - p.X - 1, m_terrain.Height - p.Y - 1));

                int avg = tot / riverPath.Length;

                if (avg < 20)
                {
                    Trace.TraceInformation("too close to edge, avg {0}", avg);
                    continue;
                }

                m_riverPath = riverPath;

                return(true);
            }

            return(false);
        }
示例#3
0
        IntVector2 MapCoord(int c, SideEdge edge)
        {
            switch (edge)
            {
            case SideEdge.Left:
                return(new IntVector2(0, c));

            case SideEdge.Top:
                return(new IntVector2(c, 0));

            case SideEdge.Right:
                return(new IntVector2(m_terrain.Width - 1, c));

            case SideEdge.Bottom:
                return(new IntVector2(c, m_terrain.Height - 1));

            default:
                throw new Exception();
            }
        }
示例#4
0
 public MyTarget(TerrainData terrain, IntVector3 origin, SideEdge sourceSide)
 {
     m_terrain = terrain;
     m_origin = origin;
     m_sourceSide = sourceSide;
 }
示例#5
0
 IntVector2 MapCoord(int c, SideEdge edge)
 {
     switch (edge)
     {
         case SideEdge.Left:
             return new IntVector2(0, c);
         case SideEdge.Top:
             return new IntVector2(c, 0);
         case SideEdge.Right:
             return new IntVector2(m_terrain.Width - 1, c);
         case SideEdge.Bottom:
             return new IntVector2(c, m_terrain.Height - 1);
         default:
             throw new Exception();
     }
 }
示例#6
0
        IntVector3 FindStartLoc(Random r, SideEdge edge)
        {
            int side = m_terrain.Width;

            int yo = r.Next(0, side);
            int zo = m_terrain.GetSurfaceLevel(MapCoord(yo, edge));

            int yu = yo;
            int zu = zo;

            for (int y = yo - 1; y >= 0; --y)
            {
                int z = m_terrain.GetSurfaceLevel(MapCoord(y, edge));
                if (z < zu)
                {
                    zu = z;
                    yu = y;
                }

                if (z - 2 > zu)
                    break;
            }

            int yd = yo;
            int zd = zo;

            for (int y = yo + 1; y < side; ++y)
            {
                int z = m_terrain.GetSurfaceLevel(MapCoord(y, edge));
                if (z < zd)
                {
                    zd = z;
                    yd = y;
                }

                if (z - 2 > zd)
                    break;
            }

            int yf = zd < zu ? yd : yu;
            var p2 = MapCoord(yf, edge);
            return m_terrain.GetSurfaceLocation(p2);
        }
示例#7
0
 public MyTarget(TerrainData terrain, IntVector3 origin, SideEdge sourceSide)
 {
     m_terrain    = terrain;
     m_origin     = origin;
     m_sourceSide = sourceSide;
 }