private bool SynchronizeWithVanillaEvents() { bool result = false; var oneMinuteInterval = TimeSpan.FromMinutes(1); foreach (ushort eventId in eventManager.GetUpcomingEvents(timeInfo.Now.Date, timeInfo.Now.AddDays(1))) { if (!eventManager.TryGetEventInfo(eventId, out ushort buildingId, out DateTime startTime, out float duration, out float ticketPrice)) { continue; } VanillaEvent existingVanillaEvent = CityEvents .OfType <VanillaEvent>() .FirstOrDefault(e => e.BuildingId == buildingId && e.EventId == eventId); if (existingVanillaEvent != null) { if (existingVanillaEvent.StartTime.RoundCeil(oneMinuteInterval) == startTime.RoundCeil(oneMinuteInterval)) { continue; } else { upcomingEvents.Remove(existingVanillaEvent); } } DateTime adjustedStartTime = AdjustEventStartTime(startTime, false); if (adjustedStartTime != startTime) { startTime = adjustedStartTime; eventManager.SetStartTime(eventId, startTime); } var newEvent = new VanillaEvent(eventId, duration, ticketPrice); newEvent.Configure(buildingId, buildingManager.GetBuildingName(buildingId), startTime); result = true; Log.Debug(LogCategory.Events, timeInfo.Now, $"Vanilla event registered for {newEvent.BuildingId}, start time {newEvent.StartTime}, end time {newEvent.EndTime}"); LinkedListNode <ICityEvent> existingEvent = upcomingEvents.FirstOrDefaultNode(e => e.StartTime > startTime); if (existingEvent == null) { upcomingEvents.AddLast(newEvent); } else { upcomingEvents.AddBefore(existingEvent, newEvent); if (existingEvent.Value.StartTime < newEvent.EndTime) { // Avoid multiple events at the same time - vanilla events have priority upcomingEvents.Remove(existingEvent); earliestEvent = newEvent.EndTime.AddHours(12f); } } } return(result); }
private void Update() { if (activeEvent != null && activeEvent.EndTime <= timeInfo.Now) { Log.Debug(timeInfo.Now, $"Event finished in {activeEvent.BuildingId}, started at {activeEvent.StartTime}, end time {activeEvent.EndTime}"); lastActiveEvent = activeEvent; activeEvent = null; } bool eventsChanged = false; foreach (ushort eventId in eventManager.GetUpcomingEvents(timeInfo.Now, timeInfo.Now.AddDays(1))) { eventManager.TryGetEventInfo(eventId, out ushort buildingId, out DateTime startTime, out float duration, out float ticketPrice); if (upcomingEvents.Concat(new[] { activeEvent }) .OfType <VanillaEvent>() .Any(e => e.BuildingId == buildingId && e.StartTime == startTime)) { continue; } var newEvent = new VanillaEvent(duration, ticketPrice); newEvent.Configure(buildingId, buildingManager.GetBuildingName(buildingId), startTime); eventsChanged = true; Log.Debug(timeInfo.Now, $"Vanilla event registered for {newEvent.BuildingId}, start time {newEvent.StartTime}, end time {newEvent.EndTime}"); LinkedListNode <ICityEvent> existingEvent = upcomingEvents.FirstOrDefaultNode(e => e.StartTime > startTime); if (existingEvent == null) { upcomingEvents.AddLast(newEvent); } else { upcomingEvents.AddBefore(existingEvent, newEvent); } } if (upcomingEvents.Count == 0) { return; } ICityEvent upcomingEvent = upcomingEvents.First.Value; if (upcomingEvent.StartTime <= timeInfo.Now) { activeEvent = upcomingEvent; upcomingEvents.RemoveFirst(); eventsChanged = true; Log.Debug(timeInfo.Now, $"Event started! Building {activeEvent.BuildingId}, ends on {activeEvent.EndTime}"); } if (eventsChanged) { OnEventsChanged(); } }
private bool SynchronizeWithVanillaEvents() { bool eventsChanged = false; var today = timeInfo.Now.Date; var upcomingEventIds = eventManager.GetUpcomingEvents(today, today.AddDays(1)); for (int i = 0; i < upcomingEventIds.Count; ++i) { // The evaluation order is important here - avoid short-circuit, we need to call the method on each iteration eventsChanged = SynchronizeWithVanillaEvent(upcomingEventIds[i]) || eventsChanged; } return(eventsChanged); }