예제 #1
0
    public Color GetMapColor()
    {
        Color biomeCol = Biome.GetColor();

        if (ChunkFeature != null)
        {
            if (ChunkFeature is ChunkRiverNode)
            {
                ChunkRiverNode rn = ChunkFeature as ChunkRiverNode;
                if (rn.HasBridge)
                {
                    return(Color.grey);
                }
                return(new Color(0, 0, 0.4f));
            }
            else if (ChunkFeature is ChunkRoad)
            {
                ChunkRoad r = ChunkFeature as ChunkRoad;
                if (r.Type == ChunkRoad.RoadType.Dirt)
                {
                    return(new Color(165f / 255f, 42f / 255f, 42f / 255f));
                }
                //Debug.Log("road at " + Pos);
                return(Color.grey);
            }
            else if (ChunkFeature is ChunkLake)
            {
                return(Color.blue);
            }
        }
        return(biomeCol);
    }
예제 #2
0
    private void ModifyRiverHeight(ChunkRiverNode crn)
    {
        float height = ChunkBases[crn.Pos.x, crn.Pos.z].Height;

        foreach (ChunkRiverNode crn1 in crn.FlowOut)
        {
            ChunkBase2 cb = ChunkBases[crn1.Pos.x, crn1.Pos.z];
            if (cb.Height < height)
            {
                height = cb.Height;
                ModifyRiverValleyHeight(crn1.Pos, height);
            }
        }
    }
예제 #3
0
    private void FromRiverSource(Vec2i source, Vec2i end, float startHeight = -1, int distSinceFork = 0, bool riverRaySearch = true)
    {
        int i = 0;

        if (startHeight < 0)
        {
            startHeight = ChunkBases[source.x, source.z].Height;
        }

        i = 0;

        Vec2i last    = source;
        Vec2i mainDir = CalcDir(source, end);



        Vec2i current = source + mainDir;
        bool  isDone  = false;

        Vector2 exactCurrent = current.AsVector2();

        List <RiverPoint> river        = new List <RiverPoint>();
        ChunkRiverNode    previousNode = null;

        while (!isDone)
        {
            int distToEnd = end.QuickDistance(current);

            i++;

            /*
             * if(i%16 == 0 && riverRaySearch)
             * {
             *  bool success = false;
             *  //search up to 16 chunks away
             *  for(int j=1; j<16; j++)
             *  {
             *      if (success)
             *          break;
             *      //search all 8 directions
             *      foreach(Vec2i v in Vec2i.OCT_DIRDIR)
             *      {
             *          Vec2i p = current + v * j;
             *
             *          if(ChunkBases[p.x,p.z].Biome == ChunkBiome.ocean || ChunkBases[p.x, p.z].ChunkFeature is ChunkRiverNode)
             *          {
             *              end = p;
             *              success = true;
             *              break;
             *          }
             *      }
             *  }
             * }*/


            // Vector2 currentFlow = FlowField[current.x, current.z];

            float   fx         = PerlinNoise(current.x, current.z, 36) * 2 - 1;
            float   fz         = PerlinNoise(current.x, current.z, 37) * 2 - 1;
            Vector2 noiseFlow  = new Vector2(fx, fz);
            Vector2 flowField  = FlowField[current.x, current.z];
            Vector2 targetFlow = (end - current).AsVector2().normalized;


            float targetFlowMult = distToEnd < 400 ? 4 * Mathf.Exp((400f - distToEnd) / 200f) : 4;

            Vector2 flow = (noiseFlow + targetFlowMult * targetFlow + 3.5f * flowField).normalized;
            exactCurrent += flow;
            current       = Vec2i.FromVector2(exactCurrent);
            int  check   = Mathf.Min(river.Count, 5);
            bool isValid = true;
            for (int j = 0; j < check; j++)
            {
                if (river[river.Count - j - 1].Pos == current)
                {
                    isValid = false;
                }
            }
            if (!isValid)
            {
                current     += mainDir;
                exactCurrent = current.AsVector2();
            }


            if (ChunkBases[current.x, current.z].Biome == ChunkBiome.ocean)
            {
                isDone = true;
            }
            if (ChunkBases[current.x, current.z].ChunkFeature is ChunkRiverNode)
            {
                isDone = true;
                //Shouldn't be null, but lets do a check anyway
                if (previousNode != null)
                {
                    //Get the river node
                    ChunkRiverNode endNode = ChunkBases[current.x, current.z].ChunkFeature as ChunkRiverNode;
                    //Inform river nodes of flow
                    endNode.FlowIn.Add(previousNode);
                    previousNode.FlowOut.Add(endNode);
                    ModifyRiverHeight(endNode);
                }
                if (GenRan.Random() < 0.5f)
                {
                    PlaceLake(current, 8);
                }
            }
            if (current == end)
            {
                isDone = true;
            }
            ChunkRiverNode nextNode = new ChunkRiverNode(current);
            ChunkBases[current.x, current.z].SetChunkFeature(nextNode);
            if (previousNode != null)
            {
                nextNode.FlowIn.Add(previousNode);
                previousNode.FlowOut.Add(nextNode);
            }
            previousNode = nextNode;
            //If this chunk is too high, we modify it and the surrounding area
            if (ChunkBases[current.x, current.z].Height > startHeight)
            {
                ModifyRiverValleyHeight(current, startHeight);
            }
            else if (ChunkBases[current.x, current.z].Height < startHeight)
            {
                startHeight = ChunkBases[current.x, current.z].Height;
            }
            RiverPoint rp = new RiverPoint();
            rp.Pos  = current;
            rp.Flow = flow;

            river.Add(rp);
            if (i > 4096)
            {
                PlaceLake(current, 12);
                return;
            }


            /*
             * distSinceFork++;
             *
             * if(distSinceFork > 256)
             * {
             *
             *  float p = Mathf.Exp(-distSinceFork/200f);
             *  if(p < GenRan.Random())
             *  {
             *
             *      Vec2i delta = GenRan.RandomVec2i(-64, 64);
             *
             *      FromRiverSource(current + delta, current);
             *      distSinceFork = 0;
             *  }
             *
             * }*/
            mainDir = CalcDir(current, end);
        }
        return;

        if (river.Count > 128)
        {
            int forkCount = Mathf.CeilToInt(river.Count / 128f);
            int jump      = (int)(((float)river.Count) / forkCount);
            int index     = GenRan.RandomInt(0, jump);
            for (int j = 0; j < forkCount; j++)
            {
                if (index > river.Count - 30)
                {
                    return;
                }
                RiverPoint rp      = river[index];
                Vec2i      forkEnd = rp.Pos;
                Vec2i      delta   = GenRan.RandomVec2i(-32, 32);

                Vector2 endToForkDir = (forkEnd - end).AsVector2().normalized;

                Vec2i forkStart = Vec2i.FromVector2(forkEnd.AsVector2() + endToForkDir * GenRan.Random(64, 128)) + delta;


                FromRiverSource(forkStart, forkEnd);



                index += jump + GenRan.RandomInt(-32, 32);
            }
        }
    }