private RoomState AddRoom(RoomProvider roomPrefab, int x, int y, RoomFacing orientation) { var myPosition = new Vector2Int(x, y); var room = GameObject.Instantiate(roomPrefab.GetRoom(), Vector3.zero, RoomFacingUtil.GetRotation(orientation), startingRoomAnchor.transform); var blockers = room.GetBlockers(); foreach (var blocker in blockers) { motorController.AddBlocker(blocker); } var hauntProviders = room.GetHauntProviders(); foreach (var hauntProvider in hauntProviders) { hauntController.AddHauntable(hauntProvider.GetHauntable()); } rooms[x][y] = new RoomState() { orientation = orientation, x = x, y = y, room = room }; room.orientation = orientation; room.gameObject.transform.localPosition = new Vector3(x * unitWorldSize, 0, y * unitWorldSize); pathController.AddLinks(room.path.links); foreach (var anchor in room.anchors) { if (!anchor.allowAttachment) { continue; } var anchorFacingOrientated = RoomFacingUtil.GetOrientated(anchor.facing, orientation); var anchorFacingOrientedOpposite = RoomFacingUtil.GetOpposite(anchorFacingOrientated); var offset = RoomFacingUtil.GetOffset(anchorFacingOrientated); var position = getValidatedPosition(offset.x + x, offset.y + y); if (position == INVALID_POS) { continue; } var roomAtFacing = rooms[position.x][position.y]; if (roomAtFacing == null) { var existingFree = freePositions.FindIndex((item) => item.position == position); if (existingFree >= 0) { continue; } freePositions.Add(new FreePosition() { position = position, from = anchorFacingOrientedOpposite }); } } var myFreeIndex = freePositions.FindIndex((item) => item.position == myPosition); if (myFreeIndex < 0) { return(rooms[x][y]); } freePositions.RemoveAt(myFreeIndex); return(rooms[x][y]); }
public void Generate() { freePositions = new List <FreePosition>(); rooms = new RoomState[maxX][]; for (int x = 0; x < maxX; x++) { rooms[x] = new RoomState[maxY]; } var startingRoom = AddRoom(startingRoomPrefabFront, maxX / 2 + maxX % 2, 0, RoomFacing.South); startingRoom.neverDim = true; var startingRoomComp = startingRoom.room.gameObject.GetComponent <StartingRoom>(); startingPoint = startingRoomComp.startingPoint; entrancePoint = startingRoomComp.entrancePoint; var backStartingRoom = AddRoom(startingRoomPrefabBack, maxX / 2 + maxX % 2, 1, RoomFacing.South); startingRoom.isStarting = true; backStartingRoom.isStarting = true; List <Room> roomShuffle = null; for (var index = 0; index < targetRoomCount; index++) { if (freePositions.Count <= 0) { break; } var positionIndex = UnityEngine.Random.Range(0, freePositions.Count); var orientation = (RoomFacing)UnityEngine.Random.Range(0, (int)RoomFacing.West + 1); var position = freePositions[positionIndex]; if (roomShuffle == null || roomShuffle.Count == 0) { roomShuffle = GetShuffledPrefabs(); } var roomPrefab = roomShuffle[roomShuffle.Count - 1]; roomShuffle.RemoveAt(roomShuffle.Count - 1); var mustRotate = true; while (mustRotate) { var orientatedFrom = RoomFacingUtil.GetInverseOrientated(position.from, orientation); var fromAnchor = roomPrefab.anchors.Find(anchor => anchor.facing == orientatedFrom); if (!fromAnchor.allowAttachment) { orientation = RoomFacingUtil.IncrementWrapped(orientation, 1); continue; } //Debug.Log(position.position + " from " + position.from + " oks anchor " + orientatedFrom + " for " + orientation); mustRotate = false; } AddRoom(roomPrefab, position.position.x, position.position.y, orientation); } for (var x = 0; x < maxX; x++) { for (var y = 0; y < maxY; y++) { var roomState = rooms[x][y]; if (roomState == null) { continue; } foreach (var facing in RoomFacingUtil.ALL) { if (roomState.wallStates[facing] == WallState.Unknown) { var offset = RoomFacingUtil.GetOffset(facing); var position = getValidatedPosition(offset.x + x, offset.y + y); var facingOriented = RoomFacingUtil.GetInverseOrientated(facing, roomState.orientation); var anchorForFacing = roomState.room.anchors.Find((anchor) => anchor.facing == facingOriented); if (position == INVALID_POS) { GenerateWall(x, y, WallState.Solid, roomState, facing, true); anchorForFacing.exitPathPoint.isDeactivated = true; continue; } var oppositeRoom = rooms[position.x][position.y]; if (oppositeRoom == null) { GenerateWall(x, y, WallState.Solid, roomState, facing, true); anchorForFacing.exitPathPoint.isDeactivated = true; continue; } var oppositeFacing = RoomFacingUtil.GetOpposite(facing); var oppositeFacingOriented = RoomFacingUtil.GetInverseOrientated(oppositeFacing, oppositeRoom.orientation); var anchorForOppositeFacing = oppositeRoom.room.anchors.Find((anchor) => anchor.facing == oppositeFacingOriented); if (!anchorForFacing.allowAttachment) { GenerateWall(x, y, WallState.Solid, roomState, facing, false); oppositeRoom.wallStates[oppositeFacing] = WallState.Solid; anchorForFacing.exitPathPoint.isDeactivated = true; anchorForOppositeFacing.exitPathPoint.isDeactivated = true; continue; } if (!anchorForOppositeFacing.allowAttachment) { GenerateWall(x, y, WallState.Solid, roomState, facing, false); oppositeRoom.wallStates[oppositeFacing] = WallState.Solid; anchorForFacing.exitPathPoint.isDeactivated = true; anchorForOppositeFacing.exitPathPoint.isDeactivated = true; continue; } if (anchorForOppositeFacing.allowNoWall && anchorForFacing.allowNoWall) { GenerateWall(x, y, WallState.None, roomState, facing, false); oppositeRoom.wallStates[oppositeFacing] = WallState.None; continue; } GenerateWall(x, y, WallState.Open, roomState, facing, false); var isHorizontal = facing == RoomFacing.North || facing == RoomFacing.South; var barrierPoint = new BarrierPoint() { anchor = anchorForFacing.exitPathPoint.transform, isHorizontal = isHorizontal }; barrierController.AddPoint(barrierPoint); oppositeRoom.wallStates[oppositeFacing] = WallState.Open; } } } } }