public static List <Cell> Project(Cell root, ref List <Cell> cellsLeftToClaim, int claimAmount, float claimChance) { var successfulProjection = new List <Cell>(); foreach (var direction in Directionf.Directions()) { var secondaryDirections = new List <Direction>() { direction.Left(), direction.Right() }; foreach (var subDirection in secondaryDirections) { var cellsLefttoClaimCopy = cellsLeftToClaim.ToList(); var attemptedProjection = ProjectionAttempt(root, ref cellsLefttoClaimCopy, claimAmount, claimChance, direction, subDirection); if (attemptedProjection.Count > successfulProjection.Count) { successfulProjection = attemptedProjection; } if (successfulProjection.Count >= claimAmount) { break; } } } //Fetched cells, now claim them foreach (var cell in successfulProjection) { cellsLeftToClaim.Remove(cell); } return(successfulProjection); }
private static void DrawCell(Vector4 position) { position = ProjectToCellSpace(position); var normals = ((int)position.w).GetDirectionsFromByte(); foreach (var direction in Directionf.Directions()) { DrawWall(position, direction, normals.Contains(direction) ? Color.red : Color.cyan); } }
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); }
//private bool VerifyProjectionFitsRoomConfiguration(SuiteProjection projection, SuiteEntity entity, LevelRoom room, Direction direction) //{ // var wallScaffolds = Level.roomScaffolds[room.roomId].wall.main .Where(x => projection.spacesAsVec3.Contains(x.root.position)); // foreach (var wallScaffold in wallScaffolds) // { // var root = projection.spacesAsVec3.FirstOrDefault(x => // wallScaffolds.Select(s => s.root.position).Contains(x)); // if (root != null) // { // } // } //} private bool IsBlockedPath(Vector3 root, Vector3 direction) { var root_Vec4Rep = nextContainerInstance.spaces.FirstOrDefault(x => x.x == root.x && x.y == root.y && x.z == root.z); var direction_Vec4Rep = nextContainerInstance.spaces.FirstOrDefault(x => x.x == direction.x && x.y == direction.y && x.z == direction.z); var normal = Directionf.GetNormalTowards(root, direction); return(root_Vec4Rep != null && ((int)root.z).GetDirectionsFromByte().Contains(normal) || direction_Vec4Rep != null && ((int)root.z).GetDirectionsFromByte().Contains(normal.Opposite())); }
public static List <Direction> NeighborOpenings(this Cell cell) { var result = new List <Direction>(); foreach (var direction in Directionf.Directions()) { if (!CellCollection.cells.Any(x => x.Key == cell.Step(direction))) { result.Add(direction); } } return(result); }
private static void Wall_ParseConnector(Room room, ref Scaffold scaffold) { foreach (var connector in scaffold.floor.connectors) { var rootNormal = connector.rootCells.First().DirectionToNeighbor(connector.rootCells.Last()); var directionsToTry = Directionf.Directions(); directionsToTry.Remove(rootNormal); directionsToTry.Remove(rootNormal.Opposite()); foreach (var direction in directionsToTry) { RenderWallConnectorNode(connector, direction, ref scaffold); } } }
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); }
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); }
public static List <Cell> Project(Cell root, ref List <Cell> cellsLeftToClaim) { var result = new List <Cell>(); foreach (var direction in Directionf.Directions()) //Largest result is returned { var attempt = ProjectCascade(root, cellsLeftToClaim, direction); if (attempt.Count > result.Count) { result = attempt; //Get the biggest result } } //Fetched cells, now claim them foreach (var cell in result) { cellsLeftToClaim.Remove(cell); } return(result); }
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); } } } }
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); }
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); }
//Connector Parse private static void Floor_ParseConnectors(Room room, ref Scaffold scaffold) { foreach (var cell in room.GetCells()) { var neighborsInRoom = cell.NeighborCellsInRoom(); foreach (var neighbor in neighborsInRoom) { if (!scaffold.floor.connectors.Any(x => x.position == cell.PositionBetween(neighbor))) { var node = new Node_FloorConnector(); node.position = cell.PositionBetween(neighbor); node.rootCells.Add(cell); node.rootCells.Add(neighbor); node.normal = Directionf.GetNormalTowards(node.position, node.rootCells.First().position); node.rootCells = new List <Cell>() { cell, neighbor }; scaffold.floor.connectors.Add(node); } } } }
//Column Parse private static void Floor_ParseColumns(Room room, ref Scaffold scaffold) { var cells = room.GetCells(); if (cells.Count < 4) { return; //Columns cannot show up in rooms with less than 4 cells } foreach (var cell in cells) { foreach (var direction in Directionf.Directions()) { var cellGrouping = new List <Cell>(); if (ColumnScan(cell, ref cellGrouping, direction)) { var node = new Node_FloorColumn(); node.position = Cellf.PositionBetween(cellGrouping); node.rootCells = cellGrouping; scaffold.floor.columns.Add(node); } } } }
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); }
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; } } }
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); }