/// <summary> /// Called when a game level is loaded. If applicable, activates the Real Time mod /// for the loaded level. /// </summary> /// /// <param name="mode">The <see cref="LoadMode"/> a game level is loaded in.</param> public override void OnLevelLoaded(LoadMode mode) { switch (mode) { case LoadMode.LoadGame: case LoadMode.NewGame: case LoadMode.LoadScenario: case LoadMode.NewGameFromScenario: break; default: return; } Log.Info($"The 'Real Time' mod starts, game mode {mode}."); if (core != null) { core.Stop(); } core = RealTimeCore.Run(config, modPath, localizationProvider); if (core == null) { Log.Warning("Showing a warning message to user because the mod isn't working"); MessageBox.Show( localizationProvider.Translate(TranslationKeys.Warning), localizationProvider.Translate(TranslationKeys.ModNotWorkingMessage)); } }
public override void OnLevelUnloading() { if (core != null) { core.Stop(); core = null; } ConfigurationProvider.SaveConfiguration(config); }
/// <summary> /// Called when a game level is about to be unloaded. If the Real Time mod was activated /// for this level, deactivates the mod for this level. /// </summary> public override void OnLevelUnloading() { if (core != null) { Log.Info($"The 'Real Time' mod stops."); core.Stop(); core = null; } ConfigurationProvider.SaveConfiguration(config); }
/// <summary> /// Called when a game level is loaded. If applicable, activates the Real Time mod for the loaded level. /// </summary> /// <param name="mode">The <see cref="LoadMode"/> a game level is loaded in.</param> public override void OnLevelLoaded(LoadMode mode) { if (string.IsNullOrEmpty(modPath)) { MessageBox.Show("Sorry", NoWorkshopMessage); return; } switch (mode) { case LoadMode.LoadGame: case LoadMode.NewGame: case LoadMode.LoadScenario: case LoadMode.NewGameFromScenario: break; default: return; } Log.Info($"The 'Real Time' mod starts, game mode {mode}."); if (core != null) { core.Stop(); } core = RealTimeCore.Run(configProvider, modPath, localizationProvider); if (core == null) { Log.Warning("Showing a warning message to user because the mod isn't working"); MessageBox.Show( localizationProvider.Translate(TranslationKeys.Warning), localizationProvider.Translate(TranslationKeys.ModNotWorkingMessage)); } else { string restricted = core.IsRestrictedMode ? localizationProvider.Translate(TranslationKeys.RestrictedMode) : null; bool showMessage = core.IsRestrictedMode; if (configProvider.Configuration.ShowIncompatibilityNotifications) { showMessage = Compatibility.CheckAndNotify(Name, localizationProvider, restricted) && core.IsRestrictedMode; } if (showMessage) { Compatibility.Notify(Name + " - " + localizationProvider.Translate(TranslationKeys.Warning), restricted); } } }
/// <summary> /// Called when a game level is about to be unloaded. If the Real Time mod was activated for this level, /// deactivates the mod for this level. /// </summary> public override void OnLevelUnloading() { if (string.IsNullOrEmpty(modPath)) { return; } if (core != null) { Log.Info($"The 'Real Time' mod stops."); core.Stop(); core = null; } configProvider.LoadDefaultConfiguration(); }
public override void OnLevelLoaded(LoadMode mode) { switch (mode) { case LoadMode.LoadGame: case LoadMode.NewGame: case LoadMode.LoadScenario: case LoadMode.NewGameFromScenario: break; default: return; } core = RealTimeCore.Run(config, modPath, localizationProvider); }
/// <summary> /// Called when a game level is loaded. If applicable, activates the Real Time mod for the loaded level. /// </summary> /// <param name="mode">The <see cref="LoadMode"/> a game level is loaded in.</param> public override void OnLevelLoaded(LoadMode mode) { if (string.IsNullOrEmpty(modPath)) { MessageBox.Show("Sorry", NoWorkshopMessage); return; } switch (mode) { case LoadMode.LoadGame: case LoadMode.NewGame: case LoadMode.LoadScenario: case LoadMode.NewGameFromScenario: break; default: return; } Log.Info($"The 'Real Time' mod starts, game mode {mode}."); if (core != null) { core.Stop(); } bool isNewGame = mode == LoadMode.NewGame || mode == LoadMode.NewGameFromScenario; core = RealTimeCore.Run(configProvider, modPath, localizationProvider, isNewGame); if (core == null) { Log.Warning("Showing a warning message to user because the mod isn't working"); MessageBox.Show( localizationProvider.Translate(TranslationKeys.Warning), localizationProvider.Translate(TranslationKeys.ModNotWorkingMessage)); } else { CheckCompatibility(); } }
public static RealTimeCore Run( ConfigurationProvider <RealTimeConfig> configProvider, string rootPath, ILocalizationProvider localizationProvider, bool setDefaultTime, Compatibility compatibility) { if (configProvider == null) { throw new ArgumentNullException(nameof(configProvider)); } if (string.IsNullOrEmpty(rootPath)) { throw new ArgumentException("The root path cannot be null or empty string", nameof(rootPath)); } if (localizationProvider == null) { throw new ArgumentNullException(nameof(localizationProvider)); } if (compatibility == null) { throw new ArgumentNullException(nameof(compatibility)); } var patches = GetMethodPatches(compatibility); var patcher = new MethodPatcher(HarmonyId, patches); var appliedPatches = patcher.Apply(); if (!CheckRequiredMethodPatches(appliedPatches)) { Log.Error("The 'Real Time' mod failed to perform method redirections for required methods"); patcher.Revert(); return(null); } if (StorageBase.CurrentLevelStorage != null) { LoadStorageData(new[] { configProvider }, StorageBase.CurrentLevelStorage); } localizationProvider.SetEnglishUSFormatsState(configProvider.Configuration.UseEnglishUSFormats); var timeInfo = new TimeInfo(configProvider.Configuration); var buildingManager = new BuildingManagerConnection(); var randomizer = new GameRandomizer(); var weatherInfo = new WeatherInfo(new WeatherManagerConnection(), randomizer); var gameConnections = new GameConnections <Citizen>( timeInfo, new CitizenConnection(), new CitizenManagerConnection(), buildingManager, randomizer, new TransferManagerConnection(), weatherInfo); var eventManager = new RealTimeEventManager( configProvider.Configuration, CityEventsLoader.Instance, new EventManagerConnection(), buildingManager, randomizer, timeInfo, Constants.MaxTravelTime); if (!SetupCustomAI(timeInfo, configProvider.Configuration, gameConnections, eventManager, compatibility)) { Log.Error("The 'Real Time' mod failed to setup the customized AI and will now be deactivated."); patcher.Revert(); return(null); } var timeAdjustment = new TimeAdjustment(configProvider.Configuration); var gameDate = timeAdjustment.Enable(setDefaultTime); SimulationHandler.CitizenProcessor.UpdateFrameDuration(); CityEventsLoader.Instance.ReloadEvents(rootPath); var customTimeBar = new CustomTimeBar(); customTimeBar.Enable(gameDate); customTimeBar.CityEventClick += CustomTimeBarCityEventClick; var vanillaEvents = VanillaEvents.Customize(); var result = new RealTimeCore(timeAdjustment, customTimeBar, eventManager, patcher, vanillaEvents); eventManager.EventsChanged += result.CityEventsChanged; var statistics = new Statistics(timeInfo, localizationProvider); if (statistics.Initialize()) { statistics.RefreshUnits(); } else { statistics = null; } SimulationHandler.NewDay += result.CityEventsChanged; SimulationHandler.TimeAdjustment = timeAdjustment; SimulationHandler.DayTimeSimulation = new DayTimeSimulation(configProvider.Configuration); SimulationHandler.EventManager = eventManager; SimulationHandler.WeatherInfo = weatherInfo; SimulationHandler.Buildings = BuildingAIPatch.RealTimeAI; SimulationHandler.Buildings.UpdateFrameDuration(); if (appliedPatches.Contains(CitizenManagerPatch.CreateCitizenPatch1)) { CitizenManagerPatch.NewCitizenBehavior = new NewCitizenBehavior(randomizer, configProvider.Configuration); } if (appliedPatches.Contains(BuildingAIPatch.GetColor)) { SimulationHandler.Buildings.InitializeLightState(); } SimulationHandler.Statistics = statistics; if (appliedPatches.Contains(WorldInfoPanelPatch.UpdateBindings)) { WorldInfoPanelPatch.CitizenInfoPanel = CustomCitizenInfoPanel.Enable(ResidentAIPatch.RealTimeAI, localizationProvider); WorldInfoPanelPatch.VehicleInfoPanel = CustomVehicleInfoPanel.Enable(ResidentAIPatch.RealTimeAI, localizationProvider); WorldInfoPanelPatch.CampusWorldInfoPanel = CustomCampusWorldInfoPanel.Enable(localizationProvider); } AwakeSleepSimulation.Install(configProvider.Configuration); var schedulesStorage = ResidentAIPatch.RealTimeAI.GetStorageService( schedules => new CitizenScheduleStorage(schedules, gameConnections.CitizenManager.GetCitizensArray, timeInfo)); result.storageData.Add(schedulesStorage); result.storageData.Add(eventManager); if (StorageBase.CurrentLevelStorage != null) { StorageBase.CurrentLevelStorage.GameSaving += result.GameSaving; LoadStorageData(result.storageData, StorageBase.CurrentLevelStorage); } result.storageData.Add(configProvider); result.Translate(localizationProvider); result.IsRestrictedMode = appliedPatches.Count != patches.Count; return(result); }
public static RealTimeCore Run(RealTimeConfig config, string rootPath, LocalizationProvider localizationProvider) { if (config == null) { throw new ArgumentNullException(nameof(config)); } if (string.IsNullOrEmpty(rootPath)) { throw new ArgumentException("The root path cannot be null or empty string", nameof(rootPath)); } if (localizationProvider == null) { throw new ArgumentNullException(nameof(localizationProvider)); } try { int redirectedCount = Redirector.PerformRedirections(); Log.Info($"Successfully redirected {redirectedCount} methods."); } catch (Exception ex) { Log.Error("Failed to perform method redirections: " + ex.Message); return(null); } var timeAdjustment = new TimeAdjustment(); DateTime gameDate = timeAdjustment.Enable(); var timeInfo = new TimeInfo(); var buildingManager = new BuildingManagerConnection(); var simulationManager = new SimulationManagerConnection(); var gameConnections = new GameConnections <Citizen>( timeInfo, new CitizenConnection(), new CitizenManagerConnection(), buildingManager, simulationManager, new TransferManagerConnection()); var eventManager = new RealTimeEventManager( config, CityEventsLoader.Istance, new EventManagerConnection(), buildingManager, simulationManager, timeInfo); SetupCustomAI(timeInfo, config, gameConnections, eventManager); CityEventsLoader.Istance.ReloadEvents(rootPath); var customTimeBar = new CustomTimeBar(); customTimeBar.Enable(gameDate); customTimeBar.CityEventClick += CustomTimeBarCityEventClick; var result = new RealTimeCore(timeAdjustment, customTimeBar, eventManager); eventManager.EventsChanged += result.CityEventsChanged; SimulationHandler.NewDay += result.CityEventsChanged; SimulationHandler.DayTimeSimulation = new DayTimeSimulation(); SimulationHandler.EventManager = eventManager; SimulationHandler.CommercialAI = new CommercialAI(timeInfo, buildingManager); RealTimeStorage.Instance.GameSaving += result.GameSaving; result.storageData.Add(eventManager); result.LoadStorageData(); result.Translate(localizationProvider); return(result); }
public static RealTimeCore Run(RealTimeConfig config, string rootPath, ILocalizationProvider localizationProvider) { if (config == null) { throw new ArgumentNullException(nameof(config)); } if (string.IsNullOrEmpty(rootPath)) { throw new ArgumentException("The root path cannot be null or empty string", nameof(rootPath)); } if (localizationProvider == null) { throw new ArgumentNullException(nameof(localizationProvider)); } var patcher = new MethodPatcher( BuildingAIPatches.PrivateConstructionTime, BuildingAIPatches.PrivateHandleWorkers, BuildingAIPatches.CommercialSimulation, ResidentAIPatch.Location, ResidentAIPatch.ArriveAtDestination, TouristAIPatch.Location, UIGraphPatches.MinDataPoints, UIGraphPatches.VisibleEndTime, UIGraphPatches.BuildLabels); try { patcher.Apply(); Log.Info("The 'Real Time' successfully performed the methods redirections"); } catch (Exception ex) { Log.Error("The 'Real Time' mod failed to perform method redirections: " + ex); patcher.Revert(); return(null); } var timeInfo = new TimeInfo(config); var buildingManager = new BuildingManagerConnection(); var randomizer = new GameRandomizer(); var weatherInfo = new WeatherInfo(new WeatherManagerConnection()); var gameConnections = new GameConnections <Citizen>( timeInfo, new CitizenConnection(), new CitizenManagerConnection(), buildingManager, randomizer, new TransferManagerConnection(), weatherInfo); var eventManager = new RealTimeEventManager( config, CityEventsLoader.Instance, new EventManagerConnection(), buildingManager, randomizer, timeInfo); if (!SetupCustomAI(timeInfo, config, gameConnections, eventManager)) { Log.Error("The 'Real Time' mod failed to setup the customized AI and will now be deactivated."); patcher.Revert(); return(null); } var timeAdjustment = new TimeAdjustment(config); DateTime gameDate = timeAdjustment.Enable(); SimulationHandler.CitizenProcessor.SetFrameDuration(timeAdjustment.HoursPerFrame); CityEventsLoader.Instance.ReloadEvents(rootPath); var customTimeBar = new CustomTimeBar(); customTimeBar.Enable(gameDate); customTimeBar.CityEventClick += CustomTimeBarCityEventClick; var result = new RealTimeCore(timeAdjustment, customTimeBar, eventManager, patcher); eventManager.EventsChanged += result.CityEventsChanged; SimulationHandler.NewDay += result.CityEventsChanged; SimulationHandler.TimeAdjustment = timeAdjustment; SimulationHandler.DayTimeSimulation = new DayTimeSimulation(config); SimulationHandler.EventManager = eventManager; SimulationHandler.WeatherInfo = weatherInfo; SimulationHandler.Buildings = BuildingAIPatches.RealTimeAI; AwakeSleepSimulation.Install(config); RealTimeStorage.CurrentLevelStorage.GameSaving += result.GameSaving; result.storageData.Add(eventManager); result.storageData.Add(ResidentAIPatch.RealTimeAI.GetStorageService()); result.LoadStorageData(); result.Translate(localizationProvider); return(result); }