private static void TurnRiverToLand(GraphConnection c) { c.River = null; c.StartNode.River = null; c.EndNode.River = null; c.RiverWidth = 0; foreach (GraphPolygon p in c.Polygons) { p.FindRivers(); } }
private static void TurnConnectionToRiver(GraphConnection c, GraphPath river, float width) { c.River = river; c.StartNode.River = river; c.EndNode.River = river; c.RiverWidth = width; foreach (GraphPolygon p in c.Polygons) { p.FindRivers(); } }
public static void DoCreateRiver(PolygonMapGenerator PMG) { List <GraphConnection> candidateStartConnections = PMG.InGraphConnections.Where(x => x.River == null && x.Type == BorderType.Inland && x.StartNode.Type != BorderPointType.Shore && x.EndNode.Type != BorderPointType.Shore && x.StartNode.River == null && x.EndNode.River == null).ToList(); if (candidateStartConnections.Count == 0) { return; } GraphPath river = new GraphPath(); float riverWidth = START_RIVER_SIZE; List <GraphConnection> forbiddenConnections = new List <GraphConnection>(); GraphConnection lastSegment = candidateStartConnections[UnityEngine.Random.Range(0, candidateStartConnections.Count)]; GraphNode currentEndPoint; GraphNode lastEndPoint; if (UnityEngine.Random.Range(0, 2) == 0) { currentEndPoint = lastSegment.StartNode; lastEndPoint = lastSegment.EndNode; } else { currentEndPoint = lastSegment.EndNode; lastEndPoint = lastSegment.StartNode; } lastEndPoint.RiverWidth = riverWidth; currentEndPoint.RiverWidth = riverWidth; forbiddenConnections.AddRange(lastEndPoint.Connections); river.Nodes.Add(lastEndPoint); river.Nodes.Add(currentEndPoint); river.Connections.Add(lastSegment); bool endRiver = (currentEndPoint.Type == BorderPointType.Shore || currentEndPoint.River != null); float expansionRate = UnityEngine.Random.Range(MIN_RIVER_EXPANSION_RATE, MAX_RIVER_EXPANSION_RATE); float maxWidth = UnityEngine.Random.Range(MIN_RIVER_MAX_WIDTH, MAX_RIVER_MAX_WIDTH); TurnConnectionToRiver(lastSegment, river, riverWidth); while (!endRiver) { riverWidth += expansionRate; if (riverWidth > maxWidth) { riverWidth = maxWidth; } // Find candidates for next node of river List <GraphConnection> candidates = currentEndPoint.Connections.Where(x => x.River == null && x.Type == BorderType.Inland && !forbiddenConnections.Contains(x) && (x.StartNode.River == null || x.EndNode.River == null) && (x.StartNode.DistanceFromNearestOcean <= currentEndPoint.DistanceFromNearestOcean) && (x.EndNode.DistanceFromNearestOcean <= currentEndPoint.DistanceFromNearestOcean)).ToList(); if (candidates.Count == 0) { TurnRiverToLand(lastSegment); river.Connections.Remove(lastSegment); river.Nodes.Remove(currentEndPoint); currentEndPoint = lastSegment.EndNode == currentEndPoint ? lastSegment.StartNode : lastSegment.EndNode; foreach (GraphConnection c in currentEndPoint.Connections) { if (forbiddenConnections.Contains(c)) { forbiddenConnections.Remove(c); } } forbiddenConnections.Add(lastSegment); lastSegment = currentEndPoint.Connections.FirstOrDefault(x => x.River != null); if (lastSegment == null) { return; } } else { lastSegment = candidates[UnityEngine.Random.Range(0, candidates.Count)]; river.Connections.Add(lastSegment); lastEndPoint = currentEndPoint; forbiddenConnections.AddRange(lastEndPoint.Connections); currentEndPoint = lastSegment.StartNode == currentEndPoint ? lastSegment.EndNode : lastSegment.StartNode; currentEndPoint.RiverWidth = riverWidth; river.Nodes.Add(currentEndPoint); endRiver = (currentEndPoint.Type == BorderPointType.Shore || (currentEndPoint.River != null && currentEndPoint.Connections.Where(x => x.River != null).Min(x => x.RiverWidth) > riverWidth)); TurnConnectionToRiver(lastSegment, river, riverWidth); } } // Add polygons to river foreach (GraphConnection c in river.Connections) { foreach (GraphPolygon p in c.Polygons) { if (!river.Polygons.Contains(p)) { river.Polygons.Add(p); } p.Rivers.Add(river); } } PMG.RiverPaths.Add(river); }