public void ActionPerform() { int X = 0; int Y = 0; GL.Begin(BeginMode.LineStrip); GL.Color4(Colour.Red, Colour.Green, Colour.Blue, Colour.Alpha); StartTile.Y = (int)(Conversion.Int(StartXY.Y / App.TerrainGridSpacing)); FinishTile.Y = Conversion.Int(FinishXY.Y / App.TerrainGridSpacing); LastXTile = Conversion.Int(StartXY.X / App.TerrainGridSpacing); Horizontal = StartXY; Vertex.X = Horizontal.X; Vertex.Y = (int)(Map.GetTerrainHeight(Horizontal)); Vertex.Z = Convert.ToInt32(- Horizontal.Y); GL.Vertex3(Vertex.X, Vertex.Y, Convert.ToInt32(- Vertex.Z)); if ( StartTile.Y + 1 <= FinishTile.Y ) { for ( Y = StartTile.Y + 1; Y <= FinishTile.Y; Y++ ) { TileEdgeStart.X = 0; TileEdgeStart.Y = Y * App.TerrainGridSpacing; TileEdgeFinish.X = Map.Terrain.TileSize.X * App.TerrainGridSpacing; TileEdgeFinish.Y = Y * App.TerrainGridSpacing; IntersectY = MathUtil.GetLinesIntersectBetween(StartXY, FinishXY, TileEdgeStart, TileEdgeFinish); if ( IntersectY.Exists ) { StartTile.X = LastXTile; FinishTile.X = (int)(Conversion.Int(IntersectY.Pos.X / App.TerrainGridSpacing)); for ( X = StartTile.X + 1; X <= FinishTile.X; X++ ) { TileEdgeStart.X = X * App.TerrainGridSpacing; TileEdgeStart.Y = 0; TileEdgeFinish.X = X * App.TerrainGridSpacing; TileEdgeFinish.Y = Map.Terrain.TileSize.Y * App.TerrainGridSpacing; IntersectX = MathUtil.GetLinesIntersectBetween(StartXY, FinishXY, TileEdgeStart, TileEdgeFinish); if ( IntersectX.Exists ) { Horizontal = IntersectX.Pos; Vertex.X = Horizontal.X; Vertex.Y = (int)(Map.GetTerrainHeight(Horizontal)); Vertex.Z = Convert.ToInt32(- Horizontal.Y); GL.Vertex3(Vertex.X, Vertex.Y, Convert.ToInt32(- Vertex.Z)); } } LastXTile = FinishTile.X; Horizontal = IntersectY.Pos; Vertex.X = Horizontal.X; Vertex.Y = (int)(Map.GetTerrainHeight(Horizontal)); Vertex.Z = Convert.ToInt32(- Horizontal.Y); GL.Vertex3(Vertex.X, Vertex.Y, Convert.ToInt32(- Vertex.Z)); } } } else { StartTile.X = LastXTile; FinishTile.X = Conversion.Int(FinishXY.X / App.TerrainGridSpacing); for ( X = StartTile.X + 1; X <= FinishTile.X; X++ ) { TileEdgeStart.X = X * App.TerrainGridSpacing; TileEdgeStart.Y = 0; TileEdgeFinish.X = X * App.TerrainGridSpacing; TileEdgeFinish.Y = Map.Terrain.TileSize.Y * App.TerrainGridSpacing; IntersectX = MathUtil.GetLinesIntersectBetween(StartXY, FinishXY, TileEdgeStart, TileEdgeFinish); if ( IntersectX.Exists ) { Horizontal = IntersectX.Pos; Vertex.X = Horizontal.X; Vertex.Y = (int)(Map.GetTerrainHeight(Horizontal)); Vertex.Z = Convert.ToInt32(- Horizontal.Y); GL.Vertex3(Vertex.X, Vertex.Y, Convert.ToInt32(- Vertex.Z)); } } } Horizontal = FinishXY; Vertex.X = Horizontal.X; Vertex.Y = (int)(Map.GetTerrainHeight(Horizontal)); Vertex.Z = Convert.ToInt32(- Horizontal.Y); GL.Vertex3(Vertex.X, Vertex.Y, Convert.ToInt32(- Vertex.Z)); GL.End(); }
public clsResult GenerateLayout() { clsResult ReturnResult = new clsResult("Layout"); int X = 0; int Y = 0; int A = 0; int B = 0; int C = 0; int D = 0; int E = 0; int F = 0; int G = 0; int H = 0; TotalPlayerCount = TopLeftPlayerCount * SymmetryBlockCount; sXY_int SymmetrySize = new sXY_int(); SymmetrySize.X = (int)(TileSize.X * App.TerrainGridSpacing / SymmetryBlockCountXY.X); SymmetrySize.Y = (int)(TileSize.Y * App.TerrainGridSpacing / SymmetryBlockCountXY.Y); //create passage nodes int PassageRadius = (int)(128.0F * NodeScale); int MaxLikelyPassageNodeCount = 0; MaxLikelyPassageNodeCount = (int)(Math.Ceiling(Convert.ToDecimal(2.0D * TileSize.X * 128 * TileSize.Y * 128 / (Math.PI * PassageRadius * PassageRadius)))); PassageNodes = new clsPassageNode[SymmetryBlockCount, MaxLikelyPassageNodeCount]; int LoopCount = 0; int EdgeOffset = 0 * 128; bool PointIsValid; sXY_int EdgeSections = new sXY_int(); Position.XY_dbl EdgeSectionSize = default(Position.XY_dbl); sXY_int NewPointPos = new sXY_int(); if ( SymmetryBlockCountXY.X == 1 ) { EdgeSections.X = Convert.ToInt32( Conversion.Int((TileSize.X * App.TerrainGridSpacing - EdgeOffset * 2.0D) / (NodeScale * App.TerrainGridSpacing * 2.0F))); EdgeSectionSize.X = (TileSize.X * App.TerrainGridSpacing - EdgeOffset * 2.0D) / EdgeSections.X; EdgeSections.X--; } else { EdgeSections.X = (int) (Conversion.Int((TileSize.X * App.TerrainGridSpacing / SymmetryBlockCountXY.X - EdgeOffset) / (NodeScale * App.TerrainGridSpacing * 2.0F) - 0.5D)); EdgeSectionSize.X = Convert.ToDouble((TileSize.X * App.TerrainGridSpacing / SymmetryBlockCountXY.X - EdgeOffset) / (Convert.ToDouble( Conversion.Int((TileSize.X * App.TerrainGridSpacing / SymmetryBlockCountXY.X - EdgeOffset) / (NodeScale * App.TerrainGridSpacing * 2.0F) - 0.5D)) + 0.5D)); } if ( SymmetryBlockCountXY.Y == 1 ) { EdgeSections.Y = Convert.ToInt32( Conversion.Int((TileSize.Y * App.TerrainGridSpacing - EdgeOffset * 2.0D) / (NodeScale * App.TerrainGridSpacing * 2.0F))); EdgeSectionSize.Y = (TileSize.Y * App.TerrainGridSpacing - EdgeOffset * 2.0D) / EdgeSections.Y; EdgeSections.Y--; } else { EdgeSections.Y = Convert.ToInt32( Conversion.Int((TileSize.Y * App.TerrainGridSpacing / SymmetryBlockCountXY.Y - EdgeOffset) / (NodeScale * App.TerrainGridSpacing * 2.0F) - 0.5D)); EdgeSectionSize.Y = Convert.ToDouble((TileSize.Y * App.TerrainGridSpacing / SymmetryBlockCountXY.Y - EdgeOffset) / (Convert.ToDouble( Conversion.Int((TileSize.Y * App.TerrainGridSpacing / SymmetryBlockCountXY.Y - EdgeOffset) / (NodeScale * App.TerrainGridSpacing * 2.0F) - 0.5D)) + 0.5D)); } PassageNodeCount = 0; for ( Y = 0; Y <= EdgeSections.Y; Y++ ) { if ( !MakePassageNodes(new sXY_int(EdgeOffset, EdgeOffset + (int)(Y * EdgeSectionSize.Y)), true) ) { ReturnResult.ProblemAdd("Error: Bad border node."); return ReturnResult; } if ( SymmetryBlockCountXY.X == 1 ) { if ( !MakePassageNodes(new sXY_int(TileSize.X * App.TerrainGridSpacing - EdgeOffset, EdgeOffset + (int)(Y * EdgeSectionSize.Y)), true) ) { ReturnResult.ProblemAdd("Error: Bad border node."); return ReturnResult; } } } for ( X = 1; X <= EdgeSections.X; X++ ) { if ( !MakePassageNodes(new sXY_int(EdgeOffset + (int)(X * EdgeSectionSize.X), EdgeOffset), true) ) { ReturnResult.ProblemAdd("Error: Bad border node."); return ReturnResult; } if ( SymmetryBlockCountXY.Y == 1 ) { if ( !MakePassageNodes(new sXY_int(EdgeOffset + (int)(X * EdgeSectionSize.X), TileSize.Y * App.TerrainGridSpacing - EdgeOffset), true) ) { ReturnResult.ProblemAdd("Error: Bad border node."); return ReturnResult; } } } do { LoopCount = 0; do { PointIsValid = true; if ( SymmetryBlockCountXY.X == 1 ) { NewPointPos.X = (int)(EdgeOffset + Conversion.Int(VBMath.Rnd() * (SymmetrySize.X - EdgeOffset * 2 + 1))); } else { NewPointPos.X = EdgeOffset + (int)(Conversion.Int(VBMath.Rnd() * (SymmetrySize.X - EdgeOffset + 1))); } if ( SymmetryBlockCountXY.Y == 1 ) { NewPointPos.Y = EdgeOffset + (int)(Conversion.Int(VBMath.Rnd() * (SymmetrySize.Y - EdgeOffset * 2 + 1))); } else { NewPointPos.Y = EdgeOffset + Convert.ToInt32(Conversion.Int(VBMath.Rnd() * (SymmetrySize.Y - EdgeOffset + 1))); } for ( A = 0; A <= PassageNodeCount - 1; A++ ) { for ( B = 0; B <= SymmetryBlockCount - 1; B++ ) { if ( (PassageNodes[B, A].Pos - NewPointPos).ToDoubles().GetMagnitude() < PassageRadius * 2 ) { goto PointTooClose; } } } PointTooClose: if ( A == PassageNodeCount ) { if ( MakePassageNodes(NewPointPos, false) ) { break; } } LoopCount++; if ( LoopCount >= (int)(64.0F * TileSize.X * TileSize.Y / (NodeScale * NodeScale)) ) { goto PointMakingFinished; } } while ( true ); } while ( true ); PointMakingFinished: PassageNodes = (clsPassageNode[,]) Utils.CopyArray((Array)PassageNodes, new clsPassageNode[SymmetryBlockCount, PassageNodeCount]); //connect until all are connected without intersecting MathUtil.sIntersectPos IntersectPos = new MathUtil.sIntersectPos(); int MaxConDist2 = PassageRadius * 2 * 4; MaxConDist2 *= MaxConDist2; clsNearest NearestA = default(clsNearest); Nearests = new clsNearest[PassageNodeCount * 64]; clsPassageNode tmpPassageNodeA = default(clsPassageNode); clsPassageNode tmpPassageNodeB = default(clsPassageNode); clsTestNearestArgs NearestArgs = new clsTestNearestArgs(); int MinConDist = (int)(NodeScale * 1.25F * 128.0F); NearestArgs.MaxConDist2 = MaxConDist2; NearestArgs.MinConDist = MinConDist; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { NearestArgs.PassageNodeA = PassageNodes[0, A]; for ( B = A; B <= PassageNodeCount - 1; B++ ) { for ( C = 0; C <= SymmetryBlockCount - 1; C++ ) { NearestArgs.PassageNodeB = PassageNodes[C, B]; if ( NearestArgs.PassageNodeA != NearestArgs.PassageNodeB ) { TestNearest(NearestArgs); } } } } clsNearest NearestB = default(clsNearest); bool Flag = default(bool); for ( G = 0; G <= NearestCount - 1; G++ ) { NearestA = Nearests[G]; for ( A = 0; A <= NearestA.NodeCount - 1; A++ ) { tmpPassageNodeA = NearestA.NodeA[A]; tmpPassageNodeB = NearestA.NodeB[A]; for ( H = 0; H <= NearestCount - 1; H++ ) { NearestB = Nearests[H]; if ( NearestB != NearestA ) { if ( NearestB.Dist2 < NearestA.Dist2 ) { Flag = true; } else if ( NearestB.Dist2 == NearestA.Dist2 ) { Flag = NearestA.Num > NearestB.Num; } else { Flag = false; } if ( Flag ) { for ( B = 0; B <= NearestB.NodeCount - 1; B++ ) { if ( !(tmpPassageNodeA == NearestB.NodeA[B] || tmpPassageNodeA == NearestB.NodeB[B] || tmpPassageNodeB == NearestB.NodeA[B] || tmpPassageNodeB == NearestB.NodeB[B]) ) { IntersectPos = MathUtil.GetLinesIntersectBetween(tmpPassageNodeA.Pos, tmpPassageNodeB.Pos, NearestB.NodeA[B].Pos, NearestB.NodeB[B].Pos); if ( IntersectPos.Exists ) { break; } } } if ( B < NearestB.NodeCount ) { NearestA.BlockedCount++; NearestB.BlockedNearests[NearestB.BlockedNearestCount] = NearestA; NearestB.BlockedNearestCount++; } } } } } } int ChangeCount = 0; Connections = new clsConnection[PassageNodeCount * 16]; do { //create valid connections ChangeCount = 0; G = 0; while ( G < NearestCount ) { NearestA = Nearests[G]; Flag = true; if ( NearestA.BlockedCount == 0 && Flag ) { F = ConnectionCount; for ( D = 0; D <= NearestA.NodeCount - 1; D++ ) { Connections[ConnectionCount] = new clsConnection(NearestA.NodeA[D], NearestA.NodeB[D]); ConnectionCount++; } for ( D = 0; D <= NearestA.NodeCount - 1; D++ ) { A = F + D; Connections[A].ReflectionCount = NearestA.NodeCount - 1; Connections[A].Reflections = new clsConnection[Connections[A].ReflectionCount]; B = 0; for ( E = 0; E <= NearestA.NodeCount - 1; E++ ) { if ( E != D ) { Connections[A].Reflections[B] = Connections[F + E]; B++; } } } for ( C = 0; C <= NearestA.BlockedNearestCount - 1; C++ ) { NearestA.BlockedNearests[C].Invalid = true; } NearestCount--; H = NearestA.Num; NearestA.Num = -1; if ( H != NearestCount ) { Nearests[H] = Nearests[NearestCount]; Nearests[H].Num = H; } ChangeCount++; } else { if ( !Flag ) { NearestA.Invalid = true; } G++; } } //remove blocked ones and their blocking effect G = 0; while ( G < NearestCount ) { NearestA = Nearests[G]; if ( NearestA.Invalid ) { NearestA.Num = -1; for ( D = 0; D <= NearestA.BlockedNearestCount - 1; D++ ) { NearestA.BlockedNearests[D].BlockedCount--; } NearestCount--; if ( G != NearestCount ) { Nearests[G] = Nearests[NearestCount]; Nearests[G].Num = G; } } else { G++; } } } while ( ChangeCount > 0 ); //put connections in order of angle for ( A = 0; A <= PassageNodeCount - 1; A++ ) { for ( B = 0; B <= SymmetryBlockCount - 1; B++ ) { PassageNodes[B, A].ReorderConnections(); PassageNodes[B, A].CalcIsNearBorder(); } } //get nodes in random order clsPassageNode[] PassageNodeListOrder = new clsPassageNode[PassageNodeCount]; int PassageNodeListOrderCount = 0; clsPassageNode[] PassageNodeOrder = new clsPassageNode[PassageNodeCount]; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { PassageNodeListOrder[PassageNodeListOrderCount] = PassageNodes[0, A]; PassageNodeListOrderCount++; } B = 0; while ( PassageNodeListOrderCount > 0 ) { A = (int)(Conversion.Int(VBMath.Rnd() * PassageNodeListOrderCount)); PassageNodeOrder[B] = PassageNodeListOrder[A]; B++; PassageNodeListOrderCount--; PassageNodeListOrder[A] = PassageNodeListOrder[PassageNodeListOrderCount]; } //designate height levels LevelHeight = 255.0F / (LevelCount - 1); int BestNum = 0; double Dist = 0; clsPassageNodeHeightLevelArgs HeightsArgs = new clsPassageNodeHeightLevelArgs(); HeightsArgs.PassageNodesMinLevel.Nodes = new int[PassageNodeCount]; HeightsArgs.PassageNodesMaxLevel.Nodes = new int[PassageNodeCount]; HeightsArgs.MapLevelCount = new int[LevelCount]; sXY_int RotatedPos = new sXY_int(); for ( A = 0; A <= PassageNodeCount - 1; A++ ) { HeightsArgs.PassageNodesMinLevel.Nodes[A] = 0; HeightsArgs.PassageNodesMaxLevel.Nodes[A] = LevelCount - 1; } //create bases double[] BestDists = new double[BaseFlatArea]; clsPassageNode[] BestNodes = new clsPassageNode[BaseFlatArea]; int[] BestNodesReflectionNums = new int[BaseFlatArea]; int BestDistCount = 0; PlayerBases = new sPlayerBase[TotalPlayerCount]; for ( B = 0; B <= TopLeftPlayerCount - 1; B++ ) { BestDistCount = 0; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { for ( E = 0; E <= SymmetryBlockCount - 1; E++ ) { tmpPassageNodeA = PassageNodes[E, A]; if ( !tmpPassageNodeA.IsOnBorder ) { Dist = (tmpPassageNodeA.Pos - PlayerBasePos[B]).ToDoubles().GetMagnitude(); for ( C = BestDistCount - 1; C >= 0; C-- ) { if ( Dist > BestDists[C] ) { break; } } C++; for ( D = Math.Min(BestDistCount - 1, BaseFlatArea - 2); D >= C; D-- ) { BestDists[D + 1] = BestDists[D]; BestNodes[D + 1] = BestNodes[D]; } if ( C < BaseFlatArea ) { BestDists[C] = Dist; BestNodes[C] = tmpPassageNodeA; BestDistCount = Math.Max(BestDistCount, C + 1); } } } } if ( BaseLevel < 0 ) { D = Convert.ToInt32(Conversion.Int(VBMath.Rnd() * LevelCount)); } else { D = BaseLevel; } HeightsArgs.MapLevelCount[D] += BestDistCount; for ( A = 0; A <= BestDistCount - 1; A++ ) { if ( BestNodes[A].MirrorNum == 0 ) { BestNodesReflectionNums[A] = -1; } else { for ( C = 0; C <= ((int)(SymmetryBlockCount / 2.0D)) - 1; C++ ) { if ( SymmetryBlocks[0].ReflectToNum[C] == BestNodes[A].MirrorNum ) { break; } } BestNodesReflectionNums[A] = C; } } for ( A = 0; A <= SymmetryBlockCount - 1; A++ ) { E = A * TopLeftPlayerCount + B; PlayerBases[E].NodeCount = BestDistCount; PlayerBases[E].Nodes = new clsPassageNode[PlayerBases[E].NodeCount]; for ( C = 0; C <= BestDistCount - 1; C++ ) { if ( BestNodesReflectionNums[C] < 0 ) { PlayerBases[E].Nodes[C] = PassageNodes[A, BestNodes[C].Num]; } else { PlayerBases[E].Nodes[C] = PassageNodes[SymmetryBlocks[A].ReflectToNum[BestNodesReflectionNums[C]], BestNodes[C].Num]; } PlayerBases[E].Nodes[C].PlayerBaseNum = E; PlayerBases[E].Nodes[C].Level = D; PassageNodesMinLevelSet(PlayerBases[E].Nodes[C], HeightsArgs.PassageNodesMinLevel, D, MaxLevelTransition); PassageNodesMaxLevelSet(PlayerBases[E].Nodes[C], HeightsArgs.PassageNodesMaxLevel, D, MaxLevelTransition); } //PlayerBases(E).CalcPos() RotatedPos = TileUtil.GetRotatedPos(SymmetryBlocks[A].Orientation, PlayerBasePos[B], new sXY_int(SymmetrySize.X - 1, SymmetrySize.Y - 1)); PlayerBases[E].Pos.X = SymmetryBlocks[A].XYNum.X * SymmetrySize.X + RotatedPos.X; PlayerBases[E].Pos.Y = SymmetryBlocks[A].XYNum.Y * SymmetrySize.Y + RotatedPos.Y; } } int WaterCount = 0; bool CanDoFlatsAroundWater = default(bool); int TotalWater = 0; int WaterSpawns = 0; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { tmpPassageNodeA = PassageNodeOrder[A]; if ( tmpPassageNodeA.Level < 0 && !tmpPassageNodeA.IsOnBorder ) { WaterCount = 0; for ( B = 0; B <= tmpPassageNodeA.ConnectionCount - 1; B++ ) { tmpPassageNodeB = tmpPassageNodeA.Connections[B].GetOther(); if ( tmpPassageNodeB.IsWater ) { WaterCount++; } } CanDoFlatsAroundWater = true; for ( B = 0; B <= tmpPassageNodeA.ConnectionCount - 1; B++ ) { if ( HeightsArgs.PassageNodesMinLevel.Nodes[tmpPassageNodeA.Connections[B].GetOther().Num] > 0 ) { CanDoFlatsAroundWater = false; } } if ( CanDoFlatsAroundWater && ((WaterCount == 0 & WaterSpawns < WaterSpawnQuantity) || (WaterCount == 1 & TotalWaterQuantity - TotalWater > WaterSpawnQuantity - WaterSpawns)) && HeightsArgs.PassageNodesMinLevel.Nodes[tmpPassageNodeA.Num] == 0 & TotalWater < TotalWaterQuantity ) { if ( WaterCount == 0 ) { WaterSpawns++; } TotalWater++; C = tmpPassageNodeA.Num; for ( D = 0; D <= SymmetryBlockCount - 1; D++ ) { PassageNodes[D, C].IsWater = true; PassageNodes[D, C].Level = 0; } PassageNodesMinLevelSet(tmpPassageNodeA, HeightsArgs.PassageNodesMinLevel, 0, MaxLevelTransition); PassageNodesMaxLevelSet(tmpPassageNodeA, HeightsArgs.PassageNodesMaxLevel, 0, MaxLevelTransition); HeightsArgs.MapLevelCount[0]++; for ( B = 0; B <= tmpPassageNodeA.ConnectionCount - 1; B++ ) { tmpPassageNodeB = tmpPassageNodeA.Connections[B].GetOther(); PassageNodesMinLevelSet(tmpPassageNodeB, HeightsArgs.PassageNodesMinLevel, 0, MaxLevelTransition); PassageNodesMaxLevelSet(tmpPassageNodeB, HeightsArgs.PassageNodesMaxLevel, 0, MaxLevelTransition); } } } } clsPassageNode tmpPassageNodeC = default(clsPassageNode); App.sResult Result = new App.sResult(); HeightsArgs.FlatsCutoff = 1; HeightsArgs.PassagesCutoff = 1; HeightsArgs.VariationCutoff = 1; HeightsArgs.ActionTotal = 1; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { tmpPassageNodeA = PassageNodeOrder[A]; if ( tmpPassageNodeA.Level < 0 && !tmpPassageNodeA.IsOnBorder && tmpPassageNodeA.IsNearBorder ) { HeightsArgs.PassageNode = tmpPassageNodeA; Result = PassageNodeHeightLevel(HeightsArgs); if ( !Result.Success ) { ReturnResult.ProblemAdd(Result.Problem); return ReturnResult; } } } HeightsArgs.FlatsCutoff = FlatsChance; HeightsArgs.PassagesCutoff = HeightsArgs.FlatsCutoff + PassagesChance; HeightsArgs.VariationCutoff = HeightsArgs.PassagesCutoff + VariationChance; HeightsArgs.ActionTotal = HeightsArgs.VariationCutoff; if ( HeightsArgs.ActionTotal <= 0 ) { ReturnResult.ProblemAdd("All height level behaviors are zero"); return ReturnResult; } for ( A = 0; A <= PassageNodeCount - 1; A++ ) { tmpPassageNodeA = PassageNodeOrder[A]; if ( tmpPassageNodeA.Level < 0 && !tmpPassageNodeA.IsOnBorder ) { HeightsArgs.PassageNode = tmpPassageNodeA; Result = PassageNodeHeightLevel(HeightsArgs); if ( !Result.Success ) { ReturnResult.ProblemAdd(Result.Problem); return ReturnResult; } } } //set edge points to the level of their neighbour for ( A = 0; A <= PassageNodeCount - 1; A++ ) { tmpPassageNodeA = PassageNodes[0, A]; if ( tmpPassageNodeA.IsOnBorder ) { if ( tmpPassageNodeA.Level >= 0 ) { ReturnResult.ProblemAdd("Error: Border has had its height set."); return ReturnResult; } //If tmpPassageNodeA.ConnectionCount <> 1 Then // ReturnResult.Problem = "Error: Border has incorrect connections." // Exit Function //End If tmpPassageNodeC = null; CanDoFlatsAroundWater = true; for ( B = 0; B <= tmpPassageNodeA.ConnectionCount - 1; B++ ) { tmpPassageNodeB = tmpPassageNodeA.Connections[B].GetOther(); if ( tmpPassageNodeB.Level >= 0 && !tmpPassageNodeB.IsOnBorder ) { if ( HeightsArgs.PassageNodesMinLevel.Nodes[tmpPassageNodeA.Num] <= tmpPassageNodeB.Level && HeightsArgs.PassageNodesMaxLevel.Nodes[tmpPassageNodeA.Num] >= tmpPassageNodeB.Level ) { if ( tmpPassageNodeC == null ) { tmpPassageNodeC = tmpPassageNodeB; } } } if ( HeightsArgs.PassageNodesMinLevel.Nodes[tmpPassageNodeB.Num] > 0 ) { CanDoFlatsAroundWater = false; } } //If tmpPassageNodeC Is Nothing Then // ReturnResult.Problem_Add("Error: No connection for border node") // Return ReturnResult //End If if ( tmpPassageNodeC != null ) { BestNum = tmpPassageNodeC.Level; PassageNodesMinLevelSet(tmpPassageNodeA, HeightsArgs.PassageNodesMinLevel, BestNum, MaxLevelTransition); PassageNodesMaxLevelSet(tmpPassageNodeA, HeightsArgs.PassageNodesMaxLevel, BestNum, MaxLevelTransition); for ( D = 0; D <= SymmetryBlockCount - 1; D++ ) { PassageNodes[D, A].IsWater = tmpPassageNodeC.IsWater && CanDoFlatsAroundWater; PassageNodes[D, A].Level = BestNum; } if ( tmpPassageNodeA.IsWater ) { for ( B = 0; B <= tmpPassageNodeA.ConnectionCount - 1; B++ ) { tmpPassageNodeB = tmpPassageNodeA.Connections[B].GetOther(); PassageNodesMinLevelSet(tmpPassageNodeB, HeightsArgs.PassageNodesMinLevel, tmpPassageNodeA.Level, MaxLevelTransition); PassageNodesMaxLevelSet(tmpPassageNodeB, HeightsArgs.PassageNodesMaxLevel, tmpPassageNodeA.Level, MaxLevelTransition); } } } } else if ( tmpPassageNodeA.Level < 0 ) { ReturnResult.ProblemAdd("Error: Node height not set"); return ReturnResult; } } //set level of edge points only connected to another border point for ( A = 0; A <= PassageNodeCount - 1; A++ ) { tmpPassageNodeA = PassageNodes[0, A]; if ( tmpPassageNodeA.IsOnBorder && tmpPassageNodeA.Level < 0 ) { tmpPassageNodeC = null; CanDoFlatsAroundWater = true; for ( B = 0; B <= tmpPassageNodeA.ConnectionCount - 1; B++ ) { tmpPassageNodeB = tmpPassageNodeA.Connections[B].GetOther(); if ( tmpPassageNodeB.Level >= 0 ) { if ( HeightsArgs.PassageNodesMinLevel.Nodes[tmpPassageNodeA.Num] <= tmpPassageNodeB.Level && HeightsArgs.PassageNodesMaxLevel.Nodes[tmpPassageNodeA.Num] >= tmpPassageNodeB.Level ) { if ( tmpPassageNodeC == null ) { tmpPassageNodeC = tmpPassageNodeB; } } } if ( HeightsArgs.PassageNodesMinLevel.Nodes[tmpPassageNodeB.Num] > 0 ) { CanDoFlatsAroundWater = false; } } if ( tmpPassageNodeC == null ) { ReturnResult.ProblemAdd("Error: No connection for border node"); return ReturnResult; } BestNum = tmpPassageNodeC.Level; PassageNodesMinLevelSet(tmpPassageNodeA, HeightsArgs.PassageNodesMinLevel, BestNum, MaxLevelTransition); PassageNodesMaxLevelSet(tmpPassageNodeA, HeightsArgs.PassageNodesMaxLevel, BestNum, MaxLevelTransition); for ( D = 0; D <= SymmetryBlockCount - 1; D++ ) { PassageNodes[D, A].IsWater = tmpPassageNodeC.IsWater && CanDoFlatsAroundWater; PassageNodes[D, A].Level = BestNum; } if ( tmpPassageNodeA.IsWater ) { for ( B = 0; B <= tmpPassageNodeA.ConnectionCount - 1; B++ ) { tmpPassageNodeB = tmpPassageNodeA.Connections[B].GetOther(); PassageNodesMinLevelSet(tmpPassageNodeB, HeightsArgs.PassageNodesMinLevel, tmpPassageNodeA.Level, MaxLevelTransition); PassageNodesMaxLevelSet(tmpPassageNodeB, HeightsArgs.PassageNodesMaxLevel, tmpPassageNodeA.Level, MaxLevelTransition); } } } } RampBase = 1.0D; MaxDisconnectionDist = 99999.0F; clsResult RampResult = GenerateRamps(); ReturnResult.Add(RampResult); return ReturnResult; }