/// <summary> /// Connects two rooms together. /// </summary> /// <param name="departureRoom">The departure room.</param> /// <param name="arrivalRoom">The arrival room.</param> /// <param name="createDoorwayForArrival">If set to <c>true</c>, a new doorway will be created for the arrival room that is linked back to the originating departure room. /// Otherwise, a one-way door will be created.</param> /// <exception cref="System.NullReferenceException"> /// Neither the departure room or arrival room can be null /// or /// Can not connect rooms when the DepartureDirection is null. /// or /// Can not connect rooms when the doorways collection is null. /// </exception> public virtual void ConnectRooms(DefaultRoom departureRoom, DefaultRoom arrivalRoom, bool createDoorwayForArrival = true) { ExceptionFactory .ThrowIf <ArgumentNullException>( departureRoom == null || arrivalRoom == null, "Neither the departure room or arrival room can be null") .Or <NullReferenceException>( this.DepartureDirection == null, "Can not connect rooms when the DepartureDirection is null.") .Or( departureRoom.Doorways == null, "Can not connect rooms when the doorways collection is null."); // Set up the departure room first. this.ArrivalRoom = arrivalRoom; this.DepartureRoom = departureRoom; departureRoom.Doorways.Add(this); // The opposite rooms arrival needs to be the departing room that this doorway is connected to. if (createDoorwayForArrival) { // Create a new doorway for the arrival room, so that you can leave the room once you are in it. ITravelDirection oppositeDirection = this.DepartureDirection.GetOppositeDirection(); // TODO: Create the doorway from a factory call. DefaultDoorway arrivalDoorway = new DefaultDoorway(oppositeDirection); arrivalDoorway.ConnectRooms(arrivalRoom, departureRoom, false); } }
/// <summary> /// Disconnects the two connected rooms. /// </summary> public virtual void DisconnectRoom() { // If this doorway isn't set up, then there is nothing to disconnect. if (this.DepartureDirection == null || this.ArrivalRoom == null) { return; } // This doorway always belongs to the departing room. We can get the departing room // by walking through the arrival rooms doorways and finding the opposite doorway. string oppositeDirection = this.DepartureDirection.GetOppositeDirection().Direction; DefaultDoorway oppositeDoorway = this.ArrivalRoom.Doorways .FirstOrDefault(d => d.DepartureDirection.Direction == oppositeDirection); ExceptionFactory.ThrowIf <InvalidOperationException>( oppositeDoorway == null, "Opposite direction does not have a connected room."); DefaultRoom departureRoom = oppositeDoorway.ArrivalRoom; // Remove the doorway from the opposite room. oppositeDoorway.ArrivalRoom.Doorways.Remove(oppositeDoorway); // Remove this door from the arrival room this.ArrivalRoom.Doorways.Remove(oppositeDoorway); departureRoom.Doorways.Remove(this); }
/// <summary> /// Adds the occupant to this instance. /// </summary> /// <param name="character">The character.</param> /// <exception cref="System.NullReferenceException">Attempted to add a null character to the Room.</exception> public void MoveOccupantToRoom(ICharacter character, DefaultRoom departingRoom) { // We don't allow the user to enter a disabled room. if (!this.IsEnabled) { // TODO: Need to do some kind of communication back to the caller that this can't be traveled to. throw new InvalidOperationException("The room is disabled and can not be traveled to."); } if (character == null) { throw new NullReferenceException("Attempted to add a null character to the Room."); } // Remove the character from their previous room. //Find the doorway that the character traveled through DefaultDoorway doorwayTraveledThrough = departingRoom?.Doorways.FirstOrDefault(door => door.ArrivalRoom == this); // Get the opposite direction of the doorways travel direction. This will be the direction that they entered from // within this instance's available entry points. ITravelDirection enteredDirection = doorwayTraveledThrough?.DepartureDirection.GetOppositeDirection(); // Handle removing the occupant from the previous room. The character might handle this for us // so our RemoveOccupantFromRoom implementation will try to remove safely. departingRoom?.TryRemoveOccupantFromRoom(character, doorwayTraveledThrough.DepartureDirection, this); this.Occupants.Add(character); character.Deleted += this.OnCharacterDeletingStarting; // Notify our event handles that the character has entered the room. this.OnEnteringRoom(character, enteredDirection, departingRoom); character.Move(enteredDirection, this); }
/// <summary> /// Initializes a new instance of the <see cref="OccupancyChangedEventArgs"/> class. /// </summary> /// <param name="occupant">The occupant.</param> /// <param name="departureRoom">The departure room.</param> /// <param name="arrivalRoom">The arrival room.</param> public OccupancyChangedEventArgs(ICharacter occupant, ITravelDirection travelDirection, DefaultRoom departureRoom, DefaultRoom arrivalRoom) { this.Occupant = occupant; this.DepartureRoom = departureRoom; this.ArrivalRoom = arrivalRoom; this.TravelDirection = travelDirection; }
/// <summary> /// Removes the room from zone. /// </summary> /// <param name="room">The room.</param> public void RemoveRoomFromZone(DefaultRoom room) { if (!this.rooms.Contains(room)) { return; } this.rooms.Remove(room); room.EnteredRoom -= this.RoomOccupancyChanged; room.LeftRoom -= this.RoomOccupancyChanged; }
/// <summary> /// Constructs the world. /// </summary> /// <param name="game">The game.</param> private async Task ConstructWorld(IGame game) { // Set up the Room var bedroom = new DefaultRoom { IsEnabled = true }; var hallway = new DefaultRoom { IsEnabled = true }; // Set up the Zone var weatherStates = new List<IWeatherState> { new ClearWeather(), new RainyWeather(), new ThunderstormWeather() }; DefaultZone zone = new DefaultZone(); zone.Name = "Country Side"; zone.Rooms = new List<DefaultRoom>() { bedroom }; zone.WeatherStates = weatherStates; zone.WeatherUpdateFrequency = 6; zone.WeatherChanged += (sender, weatherArgs) => Console.WriteLine($"{zone.Name} zone weather has changed to {weatherArgs.CurrentState.Name}"); DefaultZone zone2 = new DefaultZone(); zone2.Name = "Castle Rock"; zone2.Rooms = new List<DefaultRoom> { hallway }; zone2.WeatherStates = weatherStates; zone2.WeatherUpdateFrequency = 2; zone2.WeatherChanged += (sender, weatherArgs) => Console.WriteLine($"{zone2.Name} zone weather has changed to {weatherArgs.CurrentState.Name}"); // Set up the World. IWorld world = new DefaultWorld(); world.GameDayToRealHourRatio = 0.4; world.HoursPerDay = 10; world.Name = "Sample World"; world.SetNotificationManager(game.NotificationCenter); var morningState = new TimeOfDayState { Name = "Morning", StateStartTime = new TimeOfDay { Hour = 2 } }; var afternoonState = new TimeOfDayState { Name = "Afternoon", StateStartTime = new TimeOfDay { Hour = 5 } }; var nightState = new TimeOfDayState { Name = "Night", StateStartTime = new TimeOfDay { Hour = 8 } }; world.AddTimeOfDayState(morningState); world.AddTimeOfDayState(afternoonState); world.AddTimeOfDayState(nightState); world.TimeOfDayChanged += World_TimeOfDayChanged; // Set up the Realm. DefaultRealm realm = new DefaultRealm(world, new TimeOfDay { Hour = 3, HoursPerDay = 10 }); realm.TimeZoneOffset = new TimeOfDay { Hour = 3, Minute = 10, HoursPerDay = world.HoursPerDay }; realm.Name = "Realm 1"; realm.SetNotificationManager(game.NotificationCenter); // Initialize the environment. Task task = world.Initialize(); task.Wait(); await world.AddRealmToWorld(realm); realm.AddZoneToRealm(zone); realm.AddZoneToRealm(zone2); await game.AddWorld(world); }
/// <summary> /// Add and initializes the given room. /// </summary> /// <param name="room">The room.</param> /// <exception cref="System.NullReferenceException">Attempted to add a null Zone to the Realm.</exception> public void AddRoomToZone(DefaultRoom room) { if (room == null) { throw new NullReferenceException("Attempted to add a null Zone to the Realm."); } room.Initialize(this); this.rooms.Add(room); room.EnteredRoom += this.RoomOccupancyChanged; room.LeftRoom += this.RoomOccupancyChanged; }
/// <summary> /// Called when a character leaves this room. /// </summary> /// <param name="character">The character.</param> /// <param name="arrivalRoom">The arrival room.</param> protected virtual void OnLeavingRoom(ICharacter character, ITravelDirection enteringDirection, DefaultRoom arrivalRoom) { EventHandler <OccupancyChangedEventArgs> handler = this.LeftRoom; if (handler == null) { return; } handler(this, new OccupancyChangedEventArgs(character, enteringDirection, this, arrivalRoom)); }
public bool HasRoom(DefaultRoom room) { throw new NotImplementedException(); }
/// <summary> /// Called when a character leaves this room. /// </summary> /// <param name="character">The character.</param> /// <param name="arrivalRoom">The arrival room.</param> protected virtual void OnLeavingRoom(ICharacter character, ITravelDirection enteringDirection, DefaultRoom arrivalRoom) { EventHandler<OccupancyChangedEventArgs> handler = this.LeftRoom; if (handler == null) { return; } handler(this, new OccupancyChangedEventArgs(character, enteringDirection, this, arrivalRoom)); }
/// <summary> /// Called when the character changes rooms. /// </summary> /// <param name="departingRoom">The departing room.</param> /// <param name="arrivalRoom">The arrival room.</param> protected virtual void OnRoomChanged(ITravelDirection direction, DefaultRoom departingRoom, DefaultRoom arrivalRoom) { EventHandler<OccupancyChangedEventArgs> handler = this.RoomChanged; if (handler == null) { return; } handler(this, new OccupancyChangedEventArgs(this, direction, departingRoom, arrivalRoom)); }
/// <summary> /// Moves this character to the given room going in the specified direction. /// </summary> /// <param name="directionEnteringFrom">The direction.</param> /// <param name="newRoom">The new room.</param> public void Move(ITravelDirection directionEnteringFrom, DefaultRoom newRoom) { this.CurrentRoom = newRoom; this.OnRoomChanged(directionEnteringFrom, this.CurrentRoom, newRoom); }
/// <summary> /// Called when a character enters this room. /// </summary> /// <param name="character">The character.</param> /// <param name="departingRoom">The departing room.</param> protected virtual void OnEnteringRoom(ICharacter character, ITravelDirection enteringDirection, DefaultRoom departingRoom) { EventHandler<OccupancyChangedEventArgs> handler = this.EnteredRoom; if (handler == null) { return; } handler(this, new OccupancyChangedEventArgs(character, enteringDirection, departingRoom, this)); }
/// <summary> /// Removes the occupant from room. /// </summary> /// <param name="character">The character.</param> /// <param name="arrivalRoom">The arrival room.</param> protected void TryRemoveOccupantFromRoom(ICharacter character, ITravelDirection leavingDirection, DefaultRoom arrivalRoom) { if (character == null) { return; } this.Occupants.Remove(character); this.OnLeavingRoom(character, leavingDirection, arrivalRoom); }
/// <summary> /// Called when a character enters this room. /// </summary> /// <param name="character">The character.</param> /// <param name="departingRoom">The departing room.</param> protected virtual void OnEnteringRoom(ICharacter character, ITravelDirection enteringDirection, DefaultRoom departingRoom) { EventHandler <OccupancyChangedEventArgs> handler = this.EnteredRoom; if (handler == null) { return; } handler(this, new OccupancyChangedEventArgs(character, enteringDirection, departingRoom, this)); }
/// <summary> /// Connects two rooms together. /// </summary> /// <param name="departureRoom">The departure room.</param> /// <param name="arrivalRoom">The arrival room.</param> /// <param name="createDoorwayForArrival">If set to <c>true</c>, a new doorway will be created for the arrival room that is linked back to the originating departure room. /// Otherwise, a one-way door will be created.</param> /// <exception cref="System.NullReferenceException"> /// Neither the departure room or arrival room can be null /// or /// Can not connect rooms when the DepartureDirection is null. /// or /// Can not connect rooms when the doorways collection is null. /// </exception> public virtual void ConnectRooms(DefaultRoom departureRoom, DefaultRoom arrivalRoom, bool createDoorwayForArrival = true) { ExceptionFactory .ThrowIf<ArgumentNullException>( departureRoom == null || arrivalRoom == null, "Neither the departure room or arrival room can be null") .Or<NullReferenceException>( this.DepartureDirection == null, "Can not connect rooms when the DepartureDirection is null.") .Or( departureRoom.Doorways == null, "Can not connect rooms when the doorways collection is null."); // Set up the departure room first. this.ArrivalRoom = arrivalRoom; this.DepartureRoom = departureRoom; departureRoom.Doorways.Add(this); // The opposite rooms arrival needs to be the departing room that this doorway is connected to. if (createDoorwayForArrival) { // Create a new doorway for the arrival room, so that you can leave the room once you are in it. ITravelDirection oppositeDirection = this.DepartureDirection.GetOppositeDirection(); // TODO: Create the doorway from a factory call. DefaultDoorway arrivalDoorway = new DefaultDoorway(oppositeDirection); arrivalDoorway.ConnectRooms(arrivalRoom, departureRoom, false); } }