Esempio n. 1
0
        private static bool ColumnScan(Cell root, ref List <Cell> cellGrouping, Direction startingDirection)
        {
            var currentDirection = startingDirection;
            var currentCell      = root;
            var result           = new List <Cell>();

            //A circle has 4 steps of scanning
            for (int i = 0; i < 4; i++)
            {
                if (CellCollection.HasCellAt(currentCell.Step(currentDirection)))
                {
                    var nextCell = CellCollection.cells[currentCell.Step(currentDirection)];
                    if (!nextCell.HasSameRoom(root))
                    {
                        break;
                    }
                    currentDirection = currentDirection.Right();
                    result.Add(currentCell);
                    currentCell = nextCell;
                }
                else
                {
                    break;
                }
            }

            if (result.Count == 4)
            {
                cellGrouping = result;
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        public static Direction DirectionToNeighbor(this Cell cell, Cell targetCell)
        {
            foreach (var direction in Directionf.Directions())
            {
                if (CellCollection.HasCellAt(cell.Step(direction)) && CellCollection.cells[cell.Step(direction)] == targetCell)
                {
                    return(direction);
                }
            }

            return(Direction.Up);
        }
Esempio n. 3
0
        private static List <Cell> ProjectRoom_PartialBloom(Cell root, ref List <Cell> cellsLeftToClaim, int claimAmount, float claimChance)
        {
            var result = new List <Cell>()
            {
                root
            };
            var claimedAmount = result.Count;

            var currentRoots = new List <Cell> {
                root
            };

            while (claimedAmount < claimAmount)
            {
                var nextRoots = new List <Cell>();
                foreach (var currentRoot in currentRoots.ToList())
                {
                    foreach (var direction in Directionf.Directions().Shuffle())
                    {
                        var target = currentRoot.Step(direction);
                        if (CellCollection.HasCellAt(target) && cellsLeftToClaim.Any(x => x.position == target))
                        {
                            var chanceRoll = Random.Range(0.0f, 1.0f);
                            if (chanceRoll <= claimChance)
                            {
                                nextRoots.Add(CellCollection.cells[target]);
                                cellsLeftToClaim.Remove(CellCollection.cells[target]);
                                claimedAmount++;
                                result.Add(CellCollection.cells[target]);
                            }
                            else
                            {
                                claimedAmount--;
                            }
                        }
                    }
                    if (!nextRoots.Any()) //Ran out of cells to claim, just take what we got
                    {
                        return(result);
                    }
                }
                currentRoots = nextRoots;
            }

            return(result);
        }
Esempio n. 4
0
        public static List <Cell> NeighborCellsInRegion(this Cell cell)
        {
            var result = new List <Cell>();

            if (cell.regionId == "")
            {
                return(result);
            }

            foreach (var direction in Directionf.Directions())
            {
                if (CellCollection.HasCellAt(cell.Step(direction)) &&
                    CellCollection.cells[cell.Step(direction)].regionId == cell.regionId)
                {
                    result.Add(CellCollection.cells[cell.Step(direction)]);
                }
            }

            return(result);
        }
Esempio n. 5
0
 private static void Wall_ParseMain(Room room, ref Scaffold scaffold)
 {
     foreach (var cell in room.GetCells())
     {
         foreach (var direction in Directionf.Directions())
         {
             if (CellCollection.HasCellAt(cell.Step(direction)))
             {
                 var neighbor = CellCollection.cells[cell.Step(direction)];
                 if (neighbor.roomId != cell.roomId)
                 {
                     RenderWallNode(cell, direction, ref scaffold);
                 }
             }
             else
             {
                 RenderWallNode(cell, direction, ref scaffold);
             }
         }
     }
 }
Esempio n. 6
0
        public static List <Cell> NeighborCellsOutOfRoom(this Cell cell, bool includeElevation = false)
        {
            var result = new List <Cell>();

            foreach (var direction in Directionf.Directions())
            {
                if (CellCollection.HasCellAt(cell.Step(direction)) &&
                    CellCollection.cells[cell.Step(direction)].roomId != cell.roomId)
                {
                    if (!includeElevation && CellCollection.cells[cell.Step(direction)].type == CellType.Elevation)
                    {
                        continue;
                    }
                    else
                    {
                        result.Add(CellCollection.cells[cell.Step(direction)]);
                    }
                }
            }

            return(result);
        }
Esempio n. 7
0
        public static List <Cell> Project(Cell root, ref List <Cell> cellsLeftToClaim, int claimAmount)
        {
            var result = new List <Cell>()
            {
                root
            };
            var claimedAmount = result.Count;

            var currentRoots = new List <Cell> {
                root
            };

            while (claimedAmount < claimAmount)
            {
                var nextRoots = new List <Cell>();
                foreach (var currentRoot in currentRoots.ToList())
                {
                    foreach (var direction in Directionf.Directions().Shuffle())
                    {
                        var target = currentRoot.Step(direction);
                        if (CellCollection.HasCellAt(target) && cellsLeftToClaim.Any(x => x.position == target))
                        {
                            nextRoots.Add(CellCollection.cells[target]);
                            cellsLeftToClaim.Remove(CellCollection.cells[target]);
                            claimedAmount++;
                            result.Add(CellCollection.cells[target]);
                        }
                    }
                    if (!nextRoots.Any()) //Ran out of cells to claim, just take what we got
                    {
                        return(result);
                    }
                }
                currentRoots = nextRoots;
            }

            return(result);
        }
Esempio n. 8
0
 private static void Elevation_Parse(Room room, ref Scaffold scaffold)
 {
     foreach (var cell in room.GetCells().Where(x => x.type == CellType.Elevation))
     {
         //Upper Scan
         if (CellCollection.HasCellAt(cell.Step(Direction.Up)))
         {
             var upper = CellCollection.cells[cell.Step(Direction.Up)];
             if (!scaffold.elevation.Any(x => x.lower == cell))
             {
                 var node = new Node_Elevation();
                 node.lower    = cell;
                 node.upper    = upper;
                 node.position = upper.position;
                 node.rootCells.Add(upper);
                 node.rootCells.Add(cell);
                 cell.elevationOverride_Lower  = true;
                 upper.elevationOverride_Upper = true;
                 scaffold.elevation.Add(node);
             }
         }
     }
 }
Esempio n. 9
0
        public static void Proliferate(ref Region region)
        {
            var cellsWithOpenings = region.GetCells().Where(x => x.NeighborOpenings().Any() && x.type == CellType.Cell).ToList();
            var cellsToAdd        = new List <Cell>();

            foreach (var cell in cellsWithOpenings)
            {
                //Recheck for openings
                var openings = cell.NeighborOpenings();
                if (!openings.Any())
                {
                    continue;
                }
                foreach (var opening in openings)
                {
                    var currentCell = cell;
                    for (int i = 0; i < region.proliferationAmount; i++)
                    {
                        if (CellCollection.HasCellAt(currentCell.Step(opening)))
                        {
                            break;
                        }
                        else
                        {
                            var nextCell = new Cell(CellType.Cell, currentCell.Step(opening));
                            nextCell.parent   = currentCell;
                            nextCell.regionId = region.id;
                            cellsToAdd.Add(nextCell);
                            currentCell = cell;
                        }
                    }
                }
            }

            CellCollection.Add(cellsToAdd);
        }
Esempio n. 10
0
        public static List <Cell> NeighborCellsInRoom(this Cell cell, bool includeDiagonal = false)
        {
            var result = new List <Cell>();

            foreach (var direction in Directionf.Directions())
            {
                if (CellCollection.HasCellAt(cell.Step(direction)) &&
                    CellCollection.cells[cell.Step(direction)].roomId == cell.roomId)
                {
                    result.Add(CellCollection.cells[cell.Step(direction)]);
                }

                if (includeDiagonal)
                {
                    if (CellCollection.HasCellAt(cell.Step(direction).Step(direction.Right())) &&
                        CellCollection.cells[cell.Step(direction).Step(direction.Right())].roomId == cell.roomId)
                    {
                        result.Add(CellCollection.cells[cell.Step(direction).Step(direction.Right())]);
                    }
                }
            }

            return(result);
        }
Esempio n. 11
0
        public static void Expand(ref Region region)
        {
            var cellsToAdd = new List <Cell>();

            var cells = region.GetCells();

            var sequenceLength = cells.Last().sequence;
            var sequenceMiddle = cells.Sum(s => s.sequence) / cells.Where(x => x.sequence > 0).Count();

            var pathwayCells = cells.Where(x => x.type == CellType.Pathway).ToArray();

            foreach (var pathwayCell in pathwayCells) //Ignore elevation cells, those cannot expand
            {
                cellsToAdd = new List <Cell>();
                var expansionAmount = 0;
                foreach (var direction in Directionf.Directions())
                {
                    if (region.cellExpansionConstant)
                    {
                        expansionAmount = region.cellExpansionAmount;
                        var currentCell = pathwayCell;
                        for (int i = 0; i < expansionAmount; i++)
                        {
                            if (CellCollection.HasCellAt(currentCell.position.Step(direction)))
                            {
                                break;
                            }
                            else
                            {
                                var cell = new Cell(CellType.Cell, currentCell.position.Step(direction));
                                cell.parent   = currentCell;
                                cell.regionId = region.id;
                                cellsToAdd.Add(cell);
                                currentCell = cell;
                            }
                        }
                    }
                    else
                    {
                        if (pathwayCell.sequence <= sequenceMiddle)
                        {
                            expansionAmount = Mathf.FloorToInt(
                                Mathf.Lerp(region.cellExpansionStart,
                                           region.cellExpansionMiddle,
                                           pathwayCell.sequence / (sequenceLength - sequenceMiddle)));
                        }
                        else
                        {
                            expansionAmount = Mathf.FloorToInt(
                                Mathf.Lerp(region.cellExpansionMiddle,
                                           region.cellExpansionEnd,
                                           (pathwayCell.sequence - sequenceMiddle) / (sequenceLength - sequenceMiddle)));
                        }
                        var currentCell = pathwayCell;
                        for (int i = 0; i < expansionAmount; i++)
                        {
                            if (CellCollection.HasCellAt(currentCell.position.Step(direction)))
                            {
                                break;
                            }
                            else
                            {
                                var cell = new Cell(CellType.Cell, currentCell.position.Step(direction));
                                cell.parent   = currentCell;
                                cell.regionId = region.id;
                                cellsToAdd.Add(cell);
                                currentCell = cell;
                            }
                        }
                    }
                }
                try
                {
                    CellCollection.Add(cellsToAdd);
                }
                catch (Exception e) {
                    continue;
                }
            }
        }
Esempio n. 12
0
        public static bool BuildPath(ref Region region)
        {
            //Get direction of pathway
            var directions = FindDirectionVector(region.startPosition, region.endPosition);

            var xDistance = GetDistance(region.startPosition.x, region.endPosition.x, Cellf.CELL_STEP_OFFSET);
            var yDistance = GetDistance(region.startPosition.y, region.endPosition.y, Cellf.CELL_STEP_OFFSET / 2);
            var zDistance = GetDistance(region.startPosition.z, region.endPosition.z, Cellf.CELL_STEP_OFFSET);

            var retries = RETRIES;
            var success = false;

            while (retries > 0)
            {
                retries--;

                #region Reset Values
                var finishEndCellMetadata = false;
                var cellsToAdd            = new List <Cell>();
                var xTemp = xDistance;
                var yTemp = yDistance;
                var zTemp = zDistance;

                Cell currentCell    = null;
                Cell lastCell       = null;
                Cell secondLastCell = null; //Used to prevent the end of a path from being an elevation cell
                #endregion

                #region Init
                //Start cell
                if (CellCollection.HasCellAt(region.startPosition)) //If starting from an existing path
                {
                    currentCell = CellCollection.cells[region.startPosition];
                }
                else
                {
                    var cell = new Cell(CellType.Pathway, region.startPosition);
                    cell.sequence = sequence++;
                    cell.regionId = region.id;
                    cell.parent   = currentCell;
                    cellsToAdd.Add(cell);
                    currentCell = cell;
                }

                //Force horizontal start
                if (xTemp > 0 || zTemp > 0)
                {
                    var directionsToTry = new List <Direction>();
                    if (xTemp > 0)
                    {
                        directionsToTry.Add(directions.xDirection);
                    }
                    if (zTemp > 0)
                    {
                        directionsToTry.Add(directions.zDirection);
                    }

                    var directionToGo = directionsToTry[Random.Range(0, directionsToTry.Count)];

                    if (directionToGo == directions.xDirection)
                    {
                        xTemp--;
                    }
                    else
                    {
                        zTemp--;
                    }

                    if (CellCollection.HasCellAt(currentCell.Step(directionToGo)))
                    {
                        success = false; retries--; continue;
                    }

                    var cell = new Cell(CellType.Pathway, currentCell.Step(directionToGo));
                    cell.sequence = sequence++;
                    cell.regionId = region.id;
                    cell.parent   = currentCell;
                    currentCell.children.Add(cell);
                    cellsToAdd.Add(cell);
                    currentCell = cell;
                }

                //End cell
                if (CellCollection.HasCellAt(region.endPosition)) //If connecting to an existing path
                {
                    lastCell = CellCollection.cells[region.endPosition];
                }
                else
                {
                    var cell = new Cell(CellType.Pathway, region.endPosition);
                    //Sequence and parents will have to be added later
                    finishEndCellMetadata = true;
                    cell.regionId         = region.id;
                    cellsToAdd.Add(cell);
                    lastCell = cell;
                }

                //Remove a temp increment for the end cell
                var directionsForEnd = new List <Direction>();
                if (xTemp > 0)
                {
                    directionsForEnd.Add(directions.xDirection);
                }
                if (zTemp > 0)
                {
                    directionsForEnd.Add(directions.zDirection);
                }
                var directionToRemoveFrom = directionsForEnd[Random.Range(0, directionsForEnd.Count)];
                if (directionToRemoveFrom == directions.xDirection)
                {
                    xTemp--;
                }
                else
                {
                    zTemp--;
                }

                //Force horizontal end
                if (xTemp > 0 || zTemp > 0)
                {
                    var directionsToTry = new List <Direction>();
                    if (xTemp > 0)
                    {
                        directionsToTry.Add(directions.xDirection.Opposite());
                    }
                    if (zTemp > 0)
                    {
                        directionsToTry.Add(directions.zDirection.Opposite());
                    }

                    var directionToGo = directionsToTry[Random.Range(0, directionsToTry.Count)];

                    if (directionToGo == directions.xDirection.Opposite())
                    {
                        xTemp--;
                    }
                    else
                    {
                        zTemp--;
                    }

                    if (CellCollection.HasCellAt(lastCell.Step(directionToGo)))
                    {
                        success = false; retries--; continue;
                    }

                    var cell = new Cell(CellType.Pathway, lastCell.Step(directionToGo));
                    //Sequence and parent will have to be added later
                    cell.children.Add(lastCell);
                    cell.regionId = region.id;
                    cellsToAdd.Add(cell);

                    lastCell.parent = cell; //End cell parent finalized
                    secondLastCell  = cell; //Save this for metadata finalization at the end
                }
                #endregion

                #region Generate

                bool elevationMode = false;

                while (xTemp + zTemp + yTemp > 0)
                {
                    var directionsLeft = new List <Direction>();

                    //Force elevation to all generate at once, don't let it scatter because it is weird and non-sense
                    if (elevationMode)
                    {
                        directionsLeft = GetDirectionsLeft(0, yTemp, 0, directions);
                        if (!directionsLeft.Any())
                        {
                            elevationMode  = false;
                            directionsLeft = GetDirectionsLeft(xTemp, yTemp, zTemp, directions);
                        }
                    }
                    else
                    {
                        directionsLeft = GetDirectionsLeft(xTemp, yTemp, zTemp, directions);
                    }

                    var currentDirection = directionsLeft[Random.Range(0, directionsLeft.Count)];

                    if (currentDirection == Direction.Up || currentDirection == Direction.Down)
                    {
                        elevationMode = true;
                    }

                    var type = (currentDirection == Direction.Up || currentDirection == Direction.Down) ? CellType.Elevation : CellType.Pathway;
                    if (type == CellType.Elevation) //Retroactivly change the previous generated cell to be an elevation cell as well
                    {
                        cellsToAdd.First(x => x == currentCell).type = type;
                    }

                    if (CellCollection.HasCellAt(currentCell.position.Step(currentDirection)))
                    {
                        success = false; retries--; continue;
                    }

                    var cell = new Cell(type, currentCell.position.Step(currentDirection));
                    cell.parent = currentCell;
                    currentCell.children.Add(cell);
                    cell.regionId = region.id;
                    cell.sequence = sequence++;
                    cellsToAdd.Add(cell);
                    currentCell = cell;

                    switch (currentDirection)
                    {
                    case Direction.North:
                    case Direction.South:
                        zTemp--;
                        break;

                    case Direction.East:
                    case Direction.West:
                        xTemp--;
                        break;

                    case Direction.Up:
                    case Direction.Down:
                        yTemp--;
                        break;

                    default:
                        success = false;
                        break;
                    }

                    if (xTemp + yTemp + zTemp == 0)
                    {
                        success = true;
                    }
                }
                #endregion

                //The last cell generated in the above loop should be the one right before the forced horizontal cell, if that exists
                if (secondLastCell != null)
                {
                    cellsToAdd.First(x => x == secondLastCell).sequence = sequence++;
                    cellsToAdd.First(x => x == secondLastCell).parent   = currentCell;
                    currentCell.children.Add(secondLastCell);
                }

                cellsToAdd.First(x => x == lastCell).sequence = sequence++;

                if (success)
                {
                    CellCollection.Add(cellsToAdd.OrderBy(o => o.sequence).ToList());
                    break;
                }
            }

            return(success);
        }
Esempio n. 13
0
        public bool RenderEntity(LevelRoom room, SuiteEntity entity)
        {
            if (renderContainer == null)
            {
                ResetRenderContainer(room);
            }

            var projectionScaffolds = new List <Scaffold_Node>();

            var success = false;

            //Shortcut to prevent expensive calculations if something obvious can prevent more computation
            if (!ValidateRoom(room))
            {
                return(false);
            }

            foreach (var cell in CellCollection.GetByRoom(room.roomId).ToList().Shuffle())
            {
                foreach (var direction in Directionf.Directions())
                {
                    var projection = entity.BuildProjection(cell.position, direction);
                    //Projection cannot clip room cell space
                    if (projection.spaces.Any(x => !CellCollection.HasCellAt(x) || CellCollection.cells[x].roomId != room.roomId))
                    {
                        continue;
                    }

                    //Projection cannot intersect existing projections
                    if (nextContainerInstance.cellPositionsTaken.Any(a => projection.spaces.Contains(a)))
                    {
                        continue;
                    }

                    //Project cannot intersect with existing scaffold claims
                    if (!VerifyProjectionScaffoldDoesntIntersect(projection, entity, room, cell.position, direction, out projectionScaffolds))
                    {
                        continue;
                    }

                    //Projection cannot block navigation through room
                    if (!VerifyProjectionDoesNotBlockRoomPathways(projection))
                    {
                        continue;
                    }

                    //If we made it this far, this projection is valid, we will claim it
                    ClaimProjection(projection, projectionScaffolds, cell, direction, entity);
                    success = true;
                    break;
                }

                if (success)
                {
                    renderContainer = nextContainerInstance;
                    renderContainer.claimedScaffolds.ForEach(x => Level.roomScaffolds[room.roomId].SetNodeClaimed(x.id));
                    RollbackRenderContainer();
                    break; //A claim was found
                }
            }

            return(success);
        }
        //This projection type will attempt to claim the most successful projection that claims the most cells possible
        private static List <Cell> ProjectionAttempt(Cell root, ref List <Cell> cellsLeftToClaim, int claimAmount, float claimChance, Direction primaryDirection, Direction secondaryDirection)
        {
            bool terminate = false;

            #region Step 1
            var result = new List <Cell>()
            {
                root
            };
            var claimedAmount = result.Count;
            cellsLeftToClaim.Remove(root);

            if (claimedAmount >= claimAmount)
            {
                return(result);
            }
            #endregion

            #region Step 2

            var steps = new List <Vector3>()
            {
                root.Step(primaryDirection),    //2_1
                root.Step(secondaryDirection)   //2_2
            };

            foreach (var step in steps)
            {
                if (CellCollection.HasCellAt(step) && cellsLeftToClaim.Contains(CellCollection.cells[step]))
                {
                    var cell = CellCollection.cells[step];
                    result.Add(cell);
                    cellsLeftToClaim.Remove(cell);
                    claimedAmount = result.Count;
                }
                else
                {
                    terminate = true;
                }
            }

            if (terminate || result.Count >= claimAmount)
            {
                return(result);
            }

            #endregion

            #region Step 3

            steps = new List <Vector3>()
            {
                root.Step(primaryDirection).Step(secondaryDirection),            //3_1
                root.Step(primaryDirection.Opposite()).Step(secondaryDirection), //3_2
                root.Step(primaryDirection).Step(secondaryDirection.Opposite()), //3_3
            };

            foreach (var step in steps)
            {
                if (CellCollection.HasCellAt(step) && cellsLeftToClaim.Contains(CellCollection.cells[step]))
                {
                    var cell = CellCollection.cells[step];
                    result.Add(cell);
                    cellsLeftToClaim.Remove(cell);
                    claimedAmount = result.Count;
                }
                else
                {
                    terminate = true;
                }
            }

            if (terminate || result.Count >= claimAmount)
            {
                return(result);
            }

            #endregion

            #region Step 4

            steps = new List <Vector3>()
            {
                root.Step(primaryDirection.Opposite()),  //4_1
                root.Step(secondaryDirection.Opposite()) //4_2
            };

            foreach (var step in steps)
            {
                if (CellCollection.HasCellAt(step) && cellsLeftToClaim.Contains(CellCollection.cells[step]))
                {
                    var cell = CellCollection.cells[step];
                    result.Add(cell);
                    cellsLeftToClaim.Remove(cell);
                    claimedAmount = result.Count;
                }
                else
                {
                    terminate = true;
                }
            }

            if (terminate || result.Count >= claimAmount)
            {
                return(result);
            }

            #endregion

            #region Step 5

            steps = new List <Vector3>()
            {
                root.Step(primaryDirection.Opposite()).Step(secondaryDirection.Opposite())//5_1
            };

            foreach (var step in steps)
            {
                if (CellCollection.HasCellAt(step) && cellsLeftToClaim.Contains(CellCollection.cells[step]))
                {
                    var cell = CellCollection.cells[step];
                    result.Add(cell);
                    cellsLeftToClaim.Remove(cell);
                    claimedAmount = result.Count;
                }
                else
                {
                    terminate = true;
                }
            }

            if (terminate || result.Count >= claimAmount)
            {
                return(result);
            }

            #endregion

            #region Step 6

            steps = new List <Vector3>()
            {
                root.Step(primaryDirection, 2),                                     //6_1
                root.Step(secondaryDirection, 2),                                   //6_2
                root.Step(primaryDirection, 2).Step(secondaryDirection),            //6_3
                root.Step(primaryDirection).Step(secondaryDirection, 2),            //6_4
                root.Step(primaryDirection.Opposite()).Step(secondaryDirection, 2), //6_5
                root.Step(primaryDirection, 2).Step(secondaryDirection.Opposite()), //6_6
            };

            foreach (var step in steps)
            {
                if (CellCollection.HasCellAt(step) && cellsLeftToClaim.Contains(CellCollection.cells[step]))
                {
                    var cell = CellCollection.cells[step];
                    result.Add(cell);
                    cellsLeftToClaim.Remove(cell);
                    claimedAmount = result.Count;
                }
                else
                {
                    terminate = true;
                }
            }

            if (terminate || result.Count >= claimAmount)
            {
                return(result);
            }

            #endregion

            #region Step 7

            steps = new List <Vector3>()
            {
                root.Step(primaryDirection, 2).Step(secondaryDirection, 2) //7_1
            };

            foreach (var step in steps)
            {
                if (CellCollection.HasCellAt(step) && cellsLeftToClaim.Contains(CellCollection.cells[step]))
                {
                    var cell = CellCollection.cells[step];
                    result.Add(cell);
                    cellsLeftToClaim.Remove(cell);
                    claimedAmount = result.Count;
                }
                else
                {
                    terminate = true;
                }
            }

            if (terminate || result.Count >= claimAmount)
            {
                return(result);
            }

            #endregion

            return(result);
        }