void SplitQuadTreeUntilReachMaxDepth(int depth, int planetsCount, Vector2Int topLeftCorner, int size, QuadTreeInfo quadTreeCellInfo, RectInt visibleRectInt, int maxDepthByVisual, int shipValue, List <int> previouslyGeneratedPValues, int previousRestriction) { if (currentMaxDepth < depth) { currentMaxDepth = depth; } // Utils.DebugDrawColoredRectangle(visibleRectInt, Color.green); RectInt cellRectInt = new RectInt(topLeftCorner.x, topLeftCorner.y - size, size, size); // Utils.DebugDrawColoredRectangle(cellRectInt, Color.red); bool isIntersectWithVisibleRectInt = cellRectInt.IntersectOrContains(visibleRectInt); quadTreeCellInfo.random = new System.Random(topLeftCorner.x + topLeftCorner.y + (int)cellRectInt.center.magnitude + cellRectInt.y + size + randomAppendix); var planetsValuesInRange = new List <int>(); var planetsPositionsInRange = new List <Vector2Int>(); int offset = maxDepth + 1 - depth; planetsValuesInRange.AddRange(previouslyGeneratedPValues); int currentRestriction = shipValue / offset; int planetsCountInRange = (depth != maxDepth ? spetialModePlanetsCount : planetsCount); List <Vector2Int> tepmPositionsList = null; Vector2Int posOffset = new Vector2Int(cellRectInt.xMin, cellRectInt.yMax); tepmPositionsList = new List <Vector2Int>(); float multiplicator = size / 7; int tepmPositionsInListCount = 49; int minQuadTreeCellSize_ = 7; if (depth == maxDepth) { multiplicator = 1; tepmPositionsInListCount = minQuadTreeCellSize * minQuadTreeCellSize; minQuadTreeCellSize_ = minQuadTreeCellSize; } for (int i = 0; i < tepmPositionsInListCount; i++) { var index = Utils.XYFromIndex(i, minQuadTreeCellSize); tepmPositionsList.Add(posOffset + new Vector2Int((int)(index.x * multiplicator), -(int)(index.y * multiplicator))); } tepmPositionsList.Shuffle(quadTreeCellInfo.random); for (int i = previouslyGeneratedPValues.Count; i < planetsCountInRange; i++) { var ratingOffset = quadTreeCellInfo.random.Next(previousRestriction, currentRestriction); var ratingValue = shipValue + (ratingOffset * (quadTreeCellInfo.random.Next(0, 1) == 1 ? 1 : -1)); planetsValuesInRange.Add(Mathf.Clamp(ratingValue, minRating, maxRating)); } for (int i = 0; i < planetsCountInRange; i++) { int index = quadTreeCellInfo.random.Next(0, tepmPositionsList.Count - 1); var randomPosition = tepmPositionsList[index]; tepmPositionsList.RemoveAt(index); planetsPositionsInRange.Add(randomPosition); } planetsValuesInRange.Shuffle(quadTreeCellInfo.random); planetsPositionsInRange.Shuffle(quadTreeCellInfo.random); quadTreeCellInfo.planetsValuesInRange = planetsValuesInRange; quadTreeCellInfo.planetsPositionsInRange = planetsPositionsInRange; // _ _ //|A B| //|C D| // ¯ ¯ if (isIntersectWithVisibleRectInt && depth < maxDepthByVisual && depth < maxDepth) { int generatedPlanetsPerRange = spetialModePlanetsCount / 4; int quadAGeneratedPlanetsCount = spetialModePlanetsCount % 4 + generatedPlanetsPerRange; quadTreeCellInfo.nodes = new List <QuadTreeInfo>(); var newSize = size / 2; Vector2Int topLeftCornerA = topLeftCorner; Vector2Int topLeftCornerB = topLeftCorner + new Vector2Int(newSize, 0); Vector2Int topLeftCornerC = topLeftCorner + new Vector2Int(0, -newSize); Vector2Int topLeftCornerD = topLeftCorner + new Vector2Int(newSize, -newSize); int newDepth = depth + 1; int count = quadTreeCellInfo.planetsCount; var cellPlanetsCount = quadTreeCellInfo.planetsCount / 4; //A QuadTreeInfo quadTreeCellInfoA = new QuadTreeInfo(); quadTreeCellInfoA.topLeftCorner = topLeftCornerA; int cellPlanetsCountA = cellPlanetsCount; //+ (int)(quadTreeCellInfo.planetsCount * quadTreeCellInfo.random.GetRandomNumberInRange(-1, 1) * distributionOfPlanetsDelta); count -= cellPlanetsCountA; quadTreeCellInfoA.planetsCount = cellPlanetsCountA; quadTreeCellInfoA.depth = newDepth; quadTreeCellInfoA.size = newSize; quadTreeCellInfo.nodes.Add(quadTreeCellInfoA); //B QuadTreeInfo quadTreeCellInfoB = new QuadTreeInfo(); quadTreeCellInfoB.topLeftCorner = topLeftCornerB; int cellPlanetsCountB = cellPlanetsCount; //+ (int)(quadTreeCellInfo.planetsCount * quadTreeCellInfo.random.GetRandomNumberInRange(-1, 1) * distributionOfPlanetsDelta); count -= cellPlanetsCountB; quadTreeCellInfoB.planetsCount = cellPlanetsCountB; quadTreeCellInfoB.depth = newDepth; quadTreeCellInfoB.size = newSize; quadTreeCellInfo.nodes.Add(quadTreeCellInfoB); //C QuadTreeInfo quadTreeCellInfoC = new QuadTreeInfo(); quadTreeCellInfoC.topLeftCorner = topLeftCornerC; int cellPlanetsCountC = cellPlanetsCount; //+ (int)(quadTreeCellInfo.planetsCount * quadTreeCellInfo.random.GetRandomNumberInRange(-1, 1) * distributionOfPlanetsDelta); count -= cellPlanetsCountC; quadTreeCellInfoC.planetsCount = cellPlanetsCountC; quadTreeCellInfoC.depth = newDepth; quadTreeCellInfoC.size = newSize; quadTreeCellInfo.nodes.Add(quadTreeCellInfoC); //D QuadTreeInfo quadTreeCellInfoD = new QuadTreeInfo(); quadTreeCellInfoD.topLeftCorner = topLeftCornerD; quadTreeCellInfoD.planetsCount = count; quadTreeCellInfoD.depth = newDepth; quadTreeCellInfoD.size = newSize; quadTreeCellInfo.nodes.Add(quadTreeCellInfoD); //split int lastIndex = 0; SplitQuadTreeUntilReachMaxDepth(newDepth, quadTreeCellInfoA.planetsCount, quadTreeCellInfoA.topLeftCorner, quadTreeCellInfoA.size, quadTreeCellInfoA, visibleRectInt, maxDepthByVisual, shipValue, planetsValuesInRange.GetRange(lastIndex, quadAGeneratedPlanetsCount), currentRestriction); lastIndex = quadAGeneratedPlanetsCount; SplitQuadTreeUntilReachMaxDepth(newDepth, quadTreeCellInfoB.planetsCount, quadTreeCellInfoB.topLeftCorner, quadTreeCellInfoB.size, quadTreeCellInfoB, visibleRectInt, maxDepthByVisual, shipValue, planetsValuesInRange.GetRange(lastIndex, generatedPlanetsPerRange), currentRestriction); lastIndex += quadAGeneratedPlanetsCount; SplitQuadTreeUntilReachMaxDepth(newDepth, quadTreeCellInfoC.planetsCount, quadTreeCellInfoC.topLeftCorner, quadTreeCellInfoC.size, quadTreeCellInfoC, visibleRectInt, maxDepthByVisual, shipValue, planetsValuesInRange.GetRange(lastIndex, generatedPlanetsPerRange), currentRestriction); lastIndex += quadAGeneratedPlanetsCount; SplitQuadTreeUntilReachMaxDepth(newDepth, quadTreeCellInfoD.planetsCount, quadTreeCellInfoD.topLeftCorner, quadTreeCellInfoD.size, quadTreeCellInfoD, visibleRectInt, maxDepthByVisual, shipValue, planetsValuesInRange.GetRange(lastIndex, generatedPlanetsPerRange), currentRestriction);; } }