private static void EnsureGuideUsesBeginTileConnectionPrefab()
        {
            ObjectPlacementPathTileConnectionSettings     tileConnectionSettings      = ObjectPlacement.Get().PathObjectPlacement.PathSettings.TileConnectionSettings;
            ObjectPlacementPathTileConnectionTypeSettings beginTileConnectionSettings = tileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Begin);

            if (CanRefreshGuideToUseBeginTileConnectionPrefab(beginTileConnectionSettings))
            {
                PrefabCategory categoryWhichContainsBeginPrefab = PrefabCategoryDatabase.Get().GetPrefabCategoryWhichContainsPrefab(beginTileConnectionSettings.Prefab);
                if (categoryWhichContainsBeginPrefab == null)
                {
                    return;
                }

                PrefabCategoryDatabase.Get().SetActivePrefabCategory(categoryWhichContainsBeginPrefab);
                categoryWhichContainsBeginPrefab.SetActivePrefab(beginTileConnectionSettings.Prefab);

                ObjectPlacement.Get().DestroyPlacementGuide();
                ObjectPlacementGuide.CreateFromActivePrefabIfNotExists();
            }

            // Note: When using tile connections, we will always use the original prefab scale
            if (ObjectPlacementGuide.ExistsInScene)
            {
                ObjectPlacementGuide.Instance.WorldScale = beginTileConnectionSettings.Prefab.InitialWorldScale;
            }
        }
        private void RenderPathUnderManualConstruction(ObjectPlacementPath path)
        {
            ObjectPlacementPathTileConnectionSettings tileConnectionSettings = path.Settings.TileConnectionSettings;

            if (tileConnectionSettings.UseTileConnections)
            {
                RenderPathUnderManualConstructionWhenUsingTileConnections(path, tileConnectionSettings);
            }
            else
            {
                RenderPathUnderManualConstructionWhenNotUsingTileConnections(path);
            }
        }
Пример #3
0
        private List <Vector3> CalculateOffsetsForAllTileConnectionsExceptAutofill()
        {
            var offsets = new List <Vector3>(ObjectPlacementPathTileConnectionTypes.Count);
            ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings;

            var tileConnectionYOffsetVectorCalculator = new ObjectPlacementPathTileConnectionYOffsetVectorCalculator();
            List <ObjectPlacementPathTileConnectionType> allTileConnectionTypes = ObjectPlacementPathTileConnectionTypes.GetAllExceptAutofill();

            foreach (ObjectPlacementPathTileConnectionType tileConnectionType in allTileConnectionTypes)
            {
                offsets.Add(tileConnectionYOffsetVectorCalculator.Calculate(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionType), _path));
            }

            return(offsets);
        }
        public void ApplyConfigurationDataToSettings(ObjectPlacementPathTileConnectionSettings tileConnectionSettings)
        {
            List <ObjectPlacementPathTileConnectionType> allTileConnectionTypes = ObjectPlacementPathTileConnectionTypes.GetAll();

            foreach (ObjectPlacementPathTileConnectionType tileConnectionType in allTileConnectionTypes)
            {
                int tileConnectionIndex = (int)tileConnectionType;
                ObjectPlacementPathTileConnectionTypeSettings tileConnectionTypeSettings = tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionType);

                tileConnectionTypeSettings.YAxisRotation            = _tileConnectionYAxisRotations[tileConnectionIndex];
                tileConnectionTypeSettings.YOffset                  = _tileConnectionYOffsets[tileConnectionIndex];
                tileConnectionTypeSettings.UpwardsExtrusionAmount   = _tileConnectionUpwardsExtrusionAmount[tileConnectionIndex];
                tileConnectionTypeSettings.DownwardsExtrusionAmount = _tileConnectionDownwardsExtrusionAmount[tileConnectionIndex];
                tileConnectionTypeSettings.Prefab = _tileConnectionPrefabs[tileConnectionIndex];
            }
        }
Пример #5
0
        private bool ValidatePlacementDataCalculationConditions()
        {
            if (_path == null || _path.NumberOfSegments == 0 || !ObjectPlacementGuide.ExistsInScene || _tileConnectionXZSize == 0.0f)
            {
                return(false);
            }

            ObjectPlacementPathTileConnectionSettings tileConnectionSettings = PathObjectPlacement.Get().PathSettings.TileConnectionSettings;

            if (!tileConnectionSettings.DoAllTileConnectionsHavePrefabAssociated(true))
            {
                Debug.LogWarning("Not all tile connections have an associated prefab. Path placement was cancelled.");
                return(false);
            }

            return(true);
        }
Пример #6
0
        public void SetData(ObjectPlacementPathManualConstructionSessionData sessionData)
        {
            if (!_isActive)
            {
                _path                    = sessionData.Path;
                _pathSegments            = sessionData.PathSegments;
                _pathExtensionPlane      = sessionData.PathExtensionPlane;
                _tileConnectionGridCells = sessionData.TileConnectionGridCells;

                _startObject = sessionData.StartObject;
                _startObjectHierarchyWorldOrientedBox = _startObject.GetHierarchyWorldOrientedBox();

                _pathSettings               = _path.Settings;
                _tileConnectionSettings     = _pathSettings.TileConnectionSettings;
                _manualConstructionSettings = _pathSettings.ManualConstructionSettings;
                _heightAdjustmentSettings   = _manualConstructionSettings.HeightAdjustmentSettings;
                _paddingSettings            = _manualConstructionSettings.PaddingSettings;
                _borderSettings             = _manualConstructionSettings.BorderSettings;

                _pathNoTileConnectionsObjectPlacementDataCalculator.Path   = _path;
                _pathWithTileConnectionsObjectPlacementDataCalculator.Path = _path;
            }
        }
 public ObjectPlacementPathTileConnectionSettingsView(ObjectPlacementPathTileConnectionSettings settings)
 {
     _settings = settings;
 }
        public Quaternion Calculate(ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell)
        {
            ObjectPlacementPath path = tileConnectionGridCell.TileConnectionPath;
            ObjectPlacementPathTileConnectionSettings tileConnectionSettings = path.Settings.TileConnectionSettings;
            Plane extensionPlane = path.ExtensionPlane;
            ObjectPlacementBoxStackSegment tileConnectionSegment = tileConnectionGridCell.TileConnectionSegment;
            ObjectPlacementBoxStack        tileConnectionStack   = tileConnectionGridCell.TileConnectionStack;

            bool       usingSprites           = tileConnectionSettings.UsesSprites();
            float      yAxisRotationInDegrees = ObjectPlacementPathTileConnectionYAxisRotations.GetAngleInDegrees(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionGridCell.TileConnectionType).YAxisRotation);
            Quaternion yAxisRotation          = Quaternion.AngleAxis(yAxisRotationInDegrees, extensionPlane.normal);

            Quaternion defaultRotation = Quaternion.LookRotation(path.ExtensionPlaneLookAxis, extensionPlane.normal);

            if (usingSprites)
            {
                defaultRotation = Quaternion.LookRotation(extensionPlane.normal, path.ExtensionPlaneLookAxis);
            }

            ObjectPlacementPathTileConnectionType tileConnectionType = tileConnectionGridCell.TileConnectionType;

            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Autofill)
            {
                return(yAxisRotation * defaultRotation);
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Begin)
            {
                if (tileConnectionGridCell.NumberOfNeighbours == 0)
                {
                    return(yAxisRotation * defaultRotation);
                }
                else
                {
                    ObjectPlacementBoxStack neighbour = tileConnectionGridCell.GetFirstNeighbour().TileConnectionStack;
                    Vector3 toNeighbour = tileConnectionStack.GetNormalizedBasePositionConnectionVectorTo(neighbour);

                    if (usingSprites)
                    {
                        return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toNeighbour));
                    }
                    return(yAxisRotation * Quaternion.LookRotation(toNeighbour, extensionPlane.normal));
                }
            }
            else if (tileConnectionType == ObjectPlacementPathTileConnectionType.End)
            {
                ObjectPlacementBoxStack neighbour = tileConnectionGridCell.GetFirstNeighbour().TileConnectionStack;
                Vector3 toEndTile = neighbour.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack);

                if (usingSprites)
                {
                    return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toEndTile));
                }
                return(yAxisRotation * Quaternion.LookRotation(toEndTile, extensionPlane.normal));
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Cross)
            {
                return(yAxisRotation * defaultRotation);
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.TJunction)
            {
                ObjectPlacementBoxStack baseOfTJunction = null;
                if (tileConnectionGridCell.RightNeighbour != null && tileConnectionGridCell.LeftNeighbour != null)
                {
                    baseOfTJunction = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                }
                else
                {
                    baseOfTJunction = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                }

                Vector3 toTJunction = baseOfTJunction.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack);

                if (usingSprites)
                {
                    return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toTJunction));
                }
                return(yAxisRotation * Quaternion.LookRotation(toTJunction, extensionPlane.normal));
            }
            else
            if (tileConnectionType == ObjectPlacementPathTileConnectionType.Forward)
            {
                if (tileConnectionSegment.NumberOfStacks == 1)
                {
                    if (tileConnectionGridCell.HasForwardAndBackNeightbours())
                    {
                        ObjectPlacementBoxStack forwardNeighbour = tileConnectionGridCell.ForwardNeighbour.TileConnectionStack;
                        ObjectPlacementBoxStack backNeighbour    = tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                        Vector3 toForwardNeighbour = backNeighbour.GetNormalizedBasePositionConnectionVectorTo(forwardNeighbour);

                        if (usingSprites)
                        {
                            return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toForwardNeighbour));
                        }
                        return(yAxisRotation * Quaternion.LookRotation(toForwardNeighbour, extensionPlane.normal));
                    }
                    else
                    {
                        ObjectPlacementBoxStack leftNeighbour  = tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                        ObjectPlacementBoxStack rightNeighbour = tileConnectionGridCell.RightNeighbour.TileConnectionStack;
                        Vector3 toRightNeighbour = leftNeighbour.GetNormalizedBasePositionConnectionVectorTo(rightNeighbour);

                        if (usingSprites)
                        {
                            return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toRightNeighbour));
                        }
                        return(yAxisRotation * Quaternion.LookRotation(toRightNeighbour, extensionPlane.normal));
                    }
                }
                else
                {
                    if (usingSprites)
                    {
                        return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, tileConnectionSegment.ExtensionDirection));
                    }
                    return(yAxisRotation * Quaternion.LookRotation(tileConnectionSegment.ExtensionDirection, extensionPlane.normal));
                }
            }
            else
            {
                ObjectPlacementBoxStack firstNeighbour, secondNeighbour;
                if (tileConnectionGridCell.RightNeighbour != null)
                {
                    firstNeighbour  = tileConnectionGridCell.RightNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                }
                else
                if (tileConnectionGridCell.LeftNeighbour != null)
                {
                    firstNeighbour  = tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                }
                else
                if (tileConnectionGridCell.ForwardNeighbour != null)
                {
                    firstNeighbour  = tileConnectionGridCell.ForwardNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                }
                else
                {
                    firstNeighbour  = tileConnectionGridCell.BackNeighbour.TileConnectionStack;
                    secondNeighbour = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack;
                }

                Vector3 tileLook, tileRight;
                tileLook  = firstNeighbour.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack);
                tileRight = tileConnectionStack.GetNormalizedBasePositionConnectionVectorTo(secondNeighbour);

                Vector3 tileUp = Vector3.Cross(tileLook, tileRight);
                if (Vector3.Dot(tileUp, extensionPlane.normal) < 0.0f)
                {
                    tileLook = -tileRight;
                }

                if (usingSprites)
                {
                    return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, tileLook));
                }
                return(yAxisRotation * Quaternion.LookRotation(tileLook, extensionPlane.normal));
            }
        }
        private void RenderPathUnderManualConstructionWhenUsingTileConnections(ObjectPlacementPath path, ObjectPlacementPathTileConnectionSettings tileConnectionSettings)
        {
            List <ObjectPlacementPathTileConnectionGridCell>    tileConnectionGridCells = path.TileConnectionGridCells;
            ObjectPlacementPathManualConstructionRenderSettings renderSettings          = path.RenderSettings.ManualConstructionRenderSettings;
            var tileConnectionYOffsetVectorCalculator = new ObjectPlacementPathTileConnectionYOffsetVectorCalculator();

            // Loop through all tile connection grid cells. Each cell will give us access to all the information
            // that we need to perform the rendering operation.
            foreach (ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell in tileConnectionGridCells)
            {
                // Use the cell to access the tile connection stack. If the stack is overlapped by another stack
                // or if no boxes exist in the stack, we can move on to the next cell.
                ObjectPlacementBoxStack tileConnectionStack = tileConnectionGridCell.TileConnectionStack;
                if (tileConnectionStack.IsOverlappedByAnotherStack || tileConnectionStack.NumberOfBoxes == 0)
                {
                    continue;
                }

                // Calculate the Y offset vector which applies to all tiles in the current stack and then render each
                // box which resides inside the stack.
                Vector3 tileConnectionYOffsetVector = tileConnectionYOffsetVectorCalculator.Calculate(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionGridCell.TileConnectionType), path);
                for (int boxIndex = 0; boxIndex < tileConnectionStack.NumberOfBoxes; ++boxIndex)
                {
                    // If the box is hidden, we can move on to the next box
                    ObjectPlacementBox placementBox = tileConnectionStack.GetBoxByIndex(boxIndex);
                    if (placementBox.IsHidden)
                    {
                        continue;
                    }

                    // Retrieve the box and apply the Y offset vector. The render the box.
                    OrientedBox orientedBox = placementBox.OrientedBox;
                    orientedBox.Center += tileConnectionYOffsetVector;
                    GizmosEx.RenderOrientedBoxEdges(orientedBox, renderSettings.BoxBorderLineColor);
                }

                // We have to take tile connection extrusion into account, so we will need to retrieve the extrusion
                // boxes and render those too.
                List <OrientedBox> extrusionOrientedBoxes = ObjectPlacementPathTileConnectionExtrusion.GetTileConnectionExtrusionOrientedBoxes(tileConnectionGridCell);
                foreach (OrientedBox extrusionBox in extrusionOrientedBoxes)
                {
                    GizmosEx.RenderOrientedBoxEdges(extrusionBox, renderSettings.BoxBorderLineColor);
                }
            }
        }
Пример #10
0
        public List <ObjectPlacementData> Calculate()
        {
            if (!ValidatePlacementDataCalculationConditions())
            {
                return(new List <ObjectPlacementData>());
            }

            _allowObjectIntersection = ObjectPlacementSettings.Get().ObjectIntersectionSettings.AllowIntersectionForPathPlacement;
            List <ObjectPlacementBoxStackSegment> allPathSegments = _path.GetAllSegments();
            float objectMissChance = _path.Settings.ManualConstructionSettings.ObjectMissChance;
            bool  usingSprites     = _path.Settings.TileConnectionSettings.UsesSprites();

            var tileConnectionDetector           = new ObjectPlacementPathTileConnectionDetector();
            var tileConnectionRotationCalculator = new ObjectPlacementPathTileConnectionRotationCalculator();

            List <ObjectPlacementPathTileConnectionGridCell> tileConnectionGridCells = tileConnectionDetector.Detect(_path, _tileConnectionXZSize);

            if (tileConnectionGridCells.Count == 0)
            {
                return(new List <ObjectPlacementData>());
            }

            List <Prefab>  tileConnectionPrefabsExceptAutofill          = PathObjectPlacement.Get().PathSettings.TileConnectionSettings.GetAllTileConnectionPrefabs(true);
            List <Vector3> tileConnectionWorldScaleValuesExceptAutofill = CalculateWorldScaleForAllTileConnectionPrefabsExceptAutofill(PrefabQueries.GetTransformsForAllPrefabs(tileConnectionPrefabsExceptAutofill), PrefabQueries.GetHierarchyWorldOrientedBoxesForAllPrefabs(tileConnectionPrefabsExceptAutofill));
            List <Vector3> tileConnectionOffsetsExceptAutofill          = CalculateOffsetsForAllTileConnectionsExceptAutofill();

            var objectPlacementDataInstances = new List <ObjectPlacementData>(allPathSegments.Count * 10);

            foreach (ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell in tileConnectionGridCells)
            {
                ObjectPlacementPathTileConnectionType tileConnectionType = tileConnectionGridCell.TileConnectionType;
                ObjectPlacementBoxStack tileConnectionStack = tileConnectionGridCell.TileConnectionStack;
                if (tileConnectionStack.IsOverlappedByAnotherStack)
                {
                    continue;
                }

                Prefab     tileConnectionPrefab     = tileConnectionPrefabsExceptAutofill[(int)tileConnectionType];
                Quaternion tileConnectionRotation   = tileConnectionRotationCalculator.Calculate(tileConnectionGridCell);
                Vector3    tileConnectionWorldScale = tileConnectionWorldScaleValuesExceptAutofill[(int)tileConnectionType];
                Vector3    tileConnectionOffset     = tileConnectionOffsetsExceptAutofill[(int)tileConnectionType];

                for (int stackBoxIndex = 0; stackBoxIndex < tileConnectionStack.NumberOfBoxes; ++stackBoxIndex)
                {
                    ObjectPlacementBox box = tileConnectionStack.GetBoxByIndex(stackBoxIndex);
                    if (box.IsHidden)
                    {
                        continue;
                    }

                    if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance))
                    {
                        continue;
                    }
                    if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(box.OrientedBox, true))
                    {
                        continue;
                    }

                    var objectPlacementData = new ObjectPlacementData();
                    objectPlacementData.WorldPosition  = ObjectPositionCalculator.CalculateObjectHierarchyPosition(tileConnectionPrefab, box.Center, tileConnectionWorldScale, tileConnectionRotation);
                    objectPlacementData.WorldPosition += tileConnectionOffset;

                    objectPlacementData.WorldScale    = tileConnectionWorldScale;
                    objectPlacementData.WorldRotation = tileConnectionRotation;
                    objectPlacementData.Prefab        = tileConnectionPrefab;
                    objectPlacementDataInstances.Add(objectPlacementData);
                }

                // Apply extrusion if necessary
                if (!usingSprites)
                {
                    List <OrientedBox> extrusionOrientedBoxes = ObjectPlacementPathTileConnectionExtrusion.GetTileConnectionExtrusionOrientedBoxes(tileConnectionGridCell);
                    foreach (OrientedBox extrusionBox in extrusionOrientedBoxes)
                    {
                        if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance))
                        {
                            continue;
                        }
                        if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(extrusionBox, true))
                        {
                            continue;
                        }

                        var objectPlacementData = new ObjectPlacementData();
                        objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(tileConnectionPrefab, extrusionBox.Center, tileConnectionWorldScale, tileConnectionRotation);
                        objectPlacementData.WorldScale    = tileConnectionWorldScale;
                        objectPlacementData.WorldRotation = tileConnectionRotation;
                        objectPlacementData.Prefab        = tileConnectionPrefab;
                        objectPlacementDataInstances.Add(objectPlacementData);
                    }
                }
            }

            ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings;

            if (tileConnectionSettings.DoesAutofillTileConnectionHavePrefabAssociated())
            {
                objectPlacementDataInstances.AddRange(GetPlacementDataForAutofillTiles(tileConnectionGridCells[0].ParentGrid));
            }

            return(objectPlacementDataInstances);
        }
Пример #11
0
        public List <ObjectPlacementPathTileConnectionGridCell> CreateAndReturnAutofillTileConnectionCells()
        {
            ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings;

            if (!tileConnectionSettings.DoesAutofillTileConnectionHavePrefabAssociated())
            {
                return(new List <ObjectPlacementPathTileConnectionGridCell>());
            }

            Plane       pathExtensionPlane        = _path.ExtensionPlane;
            OrientedBox autofillPrefabOrientedBox = tileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Autofill).Prefab.UnityPrefab.GetHierarchyWorldOrientedBox();
            Vector3     autofillStackBoxSize      = new Vector3(_cellXZSize, autofillPrefabOrientedBox.ScaledSize.y, _cellXZSize);
            Quaternion  autofillStackRotation     = Quaternion.LookRotation(_path.ExtensionPlaneLookAxis, pathExtensionPlane.normal);

            bool[,] cellAutofillFlags = new bool[NumberOfCellsOnX, NumberOfCellsOnZ];

            // We will first set all occupied cells to true
            foreach (var pair in _occupiedCells)
            {
                cellAutofillFlags[pair.Key.XIndex - MinCellIndexX, pair.Key.ZIndex - MinCellIndexZ] = true;
            }

            var autofillGridCells = new List <ObjectPlacementPathTileConnectionGridCell>(NumberOfCellsOnX * NumberOfCellsOnZ);

            for (int z = MinCellIndexZ; z <= MaxCellIndexZ; ++z)
            {
                for (int x = MinCellIndexX; x <= MaxCellIndexX; ++x)
                {
                    if (cellAutofillFlags[x - MinCellIndexX, z - MinCellIndexZ])
                    {
                        continue;
                    }

                    var traversedIndices = new HashSet <ObjectPlacementPathTileConnectionGridCellIndices>();
                    if (DetectCellsWhichLeadOutsideOfGridRecurse(cellAutofillFlags, x, z, traversedIndices))
                    {
                        foreach (ObjectPlacementPathTileConnectionGridCellIndices indices in traversedIndices)
                        {
                            cellAutofillFlags[indices.XIndex - MinCellIndexX, indices.ZIndex - MinCellIndexZ] = true;
                        }
                    }

                    if (!cellAutofillFlags[x - MinCellIndexX, z - MinCellIndexZ])
                    {
                        var autofillGridCell = new ObjectPlacementPathTileConnectionGridCell(new ObjectPlacementPathTileConnectionGridCellIndices(x, z), this);
                        autofillGridCells.Add(autofillGridCell);

                        AddCell(autofillGridCell);

                        var tileConnectionStack = new ObjectPlacementBoxStack();
                        tileConnectionStack.SetBoxSize(autofillStackBoxSize);
                        tileConnectionStack.SetRotation(autofillStackRotation);
                        tileConnectionStack.SetBasePosition(CalculateCellPosition(x, z));
                        tileConnectionStack.PlaceOnPlane(pathExtensionPlane);
                        tileConnectionStack.GrowUpwards(1);

                        autofillGridCell.TileConnectionStack = tileConnectionStack;
                        autofillGridCell.TileConnectionPath  = _path;
                        autofillGridCell.TileConnectionType  = ObjectPlacementPathTileConnectionType.Autofill;
                    }
                }
            }

            return(autofillGridCells);
        }