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