private static void SetupCustomAI( TimeInfo timeInfo, RealTimeConfig config, GameConnections <Citizen> gameConnections, RealTimeEventManager eventManager) { var realTimeResidentAI = new RealTimeResidentAI <ResidentAI, Citizen>( config, gameConnections, ResidentAIHook.GetResidentAIConnection(), eventManager); ResidentAIHook.RealTimeAI = realTimeResidentAI; var realTimeTouristAI = new RealTimeTouristAI <TouristAI, Citizen>( config, gameConnections, TouristAIHook.GetTouristAIConnection(), eventManager); TouristAIHook.RealTimeAI = realTimeTouristAI; var realTimePrivateBuildingAI = new RealTimePrivateBuildingAI( config, timeInfo, new ToolManagerConnection()); PrivateBuildingAIHook.RealTimeAI = realTimePrivateBuildingAI; }
private static bool SetupCustomAI( TimeInfo timeInfo, RealTimeConfig config, GameConnections <Citizen> gameConnections, RealTimeEventManager eventManager) { ResidentAIConnection <ResidentAI, Citizen> residentAIConnection = ResidentAIPatch.GetResidentAIConnection(); if (residentAIConnection == null) { return(false); } var spareTimeBehavior = new SpareTimeBehavior(config, timeInfo); var travelBehavior = new TravelBehavior(gameConnections.BuildingManager); var workBehavior = new WorkBehavior(config, gameConnections.Random, gameConnections.BuildingManager, timeInfo, travelBehavior); var realTimePrivateBuildingAI = new RealTimeBuildingAI( config, timeInfo, gameConnections.BuildingManager, new ToolManagerConnection(), workBehavior, travelBehavior); BuildingAIPatches.RealTimeAI = realTimePrivateBuildingAI; BuildingAIPatches.WeatherInfo = gameConnections.WeatherInfo; TransferManagerPatch.RealTimeAI = realTimePrivateBuildingAI; var realTimeResidentAI = new RealTimeResidentAI <ResidentAI, Citizen>( config, gameConnections, residentAIConnection, eventManager, realTimePrivateBuildingAI, workBehavior, spareTimeBehavior, travelBehavior); ResidentAIPatch.RealTimeAI = realTimeResidentAI; SimulationHandler.CitizenProcessor = new CitizenProcessor <ResidentAI, Citizen>( realTimeResidentAI, timeInfo, spareTimeBehavior, travelBehavior); TouristAIConnection <TouristAI, Citizen> touristAIConnection = TouristAIPatch.GetTouristAIConnection(); if (touristAIConnection == null) { return(false); } var realTimeTouristAI = new RealTimeTouristAI <TouristAI, Citizen>( config, gameConnections, touristAIConnection, eventManager, spareTimeBehavior); TouristAIPatch.RealTimeAI = realTimeTouristAI; return(true); }
/// <summary> /// Initializes a new instance of the <see cref="RealTimeResidentAI{TAI, TCitizen}"/> class. /// </summary> /// /// <exception cref="ArgumentNullException">Thrown when any argument is null.</exception> /// /// <param name="config">A <see cref="RealTimeConfig"/> instance containing the mod's configuration.</param> /// <param name="connections">A <see cref="GameConnections{T}"/> instance that provides the game connection implementation.</param> /// <param name="residentAI">A connection to the game's resident AI.</param> /// <param name="eventManager">A <see cref="RealTimeEventManager"/> instance.</param> public RealTimeResidentAI( RealTimeConfig config, GameConnections <TCitizen> connections, ResidentAIConnection <TAI, TCitizen> residentAI, RealTimeEventManager eventManager) : base(config, connections, eventManager) { this.residentAI = residentAI ?? throw new ArgumentNullException(nameof(residentAI)); }
/// <summary> /// Initializes a new instance of the <see cref="RealTimeTouristAI{TAI, TCitizen}"/> class. /// </summary> /// /// <param name="config">The configuration to run with.</param> /// <param name="connections">A <see cref="GameConnections{T}"/> instance that provides the game connection implementation.</param> /// <param name="touristAI">A connection to game's tourist AI.</param> /// <param name="eventManager">The custom event manager.</param> /// /// <exception cref="ArgumentNullException">Thrown when any argument is null.</exception> public RealTimeTouristAI( RealTimeConfig config, GameConnections <TCitizen> connections, TouristAIConnection <TAI, TCitizen> touristAI, RealTimeEventManager eventManager) : base(config, connections, eventManager) { this.touristAI = touristAI ?? throw new ArgumentNullException(nameof(touristAI)); }
/// <summary>Initializes a new instance of the <see cref="RealTimeResidentAI{TAI, TCitizen}"/> class.</summary> /// <exception cref="ArgumentNullException">Thrown when any argument is null.</exception> /// <param name="config">A <see cref="RealTimeConfig"/> instance containing the mod's configuration.</param> /// <param name="connections">A <see cref="GameConnections{T}"/> instance that provides the game connection implementation.</param> /// <param name="residentAI">A connection to the game's resident AI.</param> /// <param name="eventManager">A <see cref="RealTimeEventManager"/> instance.</param> /// <param name="spareTimeBehavior">A behavior that provides simulation info for the citizens spare time.</param> public RealTimeResidentAI( RealTimeConfig config, GameConnections <TCitizen> connections, ResidentAIConnection <TAI, TCitizen> residentAI, RealTimeEventManager eventManager, SpareTimeBehavior spareTimeBehavior) : base(config, connections, eventManager) { this.residentAI = residentAI ?? throw new ArgumentNullException(nameof(residentAI)); this.spareTimeBehavior = spareTimeBehavior ?? throw new ArgumentNullException(nameof(spareTimeBehavior)); residentSchedules = new CitizenSchedule[CitizenMgr.GetMaxCitizensCount()]; workBehavior = new WorkBehavior(config, connections.Random, connections.BuildingManager, connections.TimeInfo, GetEstimatedTravelTime); }
protected RealTimeHumanAIBase(RealTimeConfig config, GameConnections <TCitizen> connections, RealTimeEventManager eventManager) { Config = config ?? throw new ArgumentNullException(nameof(config)); EventMgr = eventManager ?? throw new ArgumentNullException(nameof(eventManager)); if (connections == null) { throw new ArgumentNullException(nameof(connections)); } CitizenMgr = connections.CitizenManager; BuildingMgr = connections.BuildingManager; TransferMgr = connections.TransferManager; CitizenProxy = connections.CitizenConnection; TimeInfo = connections.TimeInfo; randomizer = connections.SimulationManager.GetRandomizer(); }
/// <summary>Initializes a new instance of the <see cref="RealTimeResidentAI{TAI, TCitizen}"/> class.</summary> /// <exception cref="ArgumentNullException">Thrown when any argument is null.</exception> /// <param name="config">A <see cref="RealTimeConfig"/> instance containing the mod's configuration.</param> /// <param name="connections">A <see cref="GameConnections{T}"/> instance that provides the game connection implementation.</param> /// <param name="residentAI">A connection to the game's resident AI.</param> /// <param name="eventManager">A <see cref="RealTimeEventManager"/> instance.</param> /// <param name="workBehavior">A behavior that provides simulation info for the citizens work time.</param> /// <param name="spareTimeBehavior">A behavior that provides simulation info for the citizens spare time.</param> /// <param name="travelBehavior">A behavior that provides simulation info for the citizens traveling.</param> public RealTimeResidentAI( RealTimeConfig config, GameConnections <TCitizen> connections, ResidentAIConnection <TAI, TCitizen> residentAI, RealTimeEventManager eventManager, WorkBehavior workBehavior, SpareTimeBehavior spareTimeBehavior, TravelBehavior travelBehavior) : base(config, connections, eventManager) { this.residentAI = residentAI ?? throw new ArgumentNullException(nameof(residentAI)); this.workBehavior = workBehavior ?? throw new ArgumentNullException(nameof(workBehavior)); this.spareTimeBehavior = spareTimeBehavior ?? throw new ArgumentNullException(nameof(spareTimeBehavior)); this.travelBehavior = travelBehavior ?? throw new ArgumentNullException(nameof(travelBehavior)); residentSchedules = new CitizenSchedule[CitizenMgr.GetMaxCitizensCount()]; }
private static bool SetupCustomAI( TimeInfo timeInfo, RealTimeConfig config, GameConnections <Citizen> gameConnections, RealTimeEventManager eventManager) { ResidentAIConnection <ResidentAI, Citizen> residentAIConnection = ResidentAIPatch.GetResidentAIConnection(); if (residentAIConnection == null) { return(false); } var realTimeResidentAI = new RealTimeResidentAI <ResidentAI, Citizen>( config, gameConnections, residentAIConnection, eventManager); ResidentAIPatch.RealTimeAI = realTimeResidentAI; TouristAIConnection <TouristAI, Citizen> touristAIConnection = TouristAIPatch.GetTouristAIConnection(); if (touristAIConnection == null) { return(false); } var realTimeTouristAI = new RealTimeTouristAI <TouristAI, Citizen>( config, gameConnections, touristAIConnection, eventManager); TouristAIPatch.RealTimeAI = realTimeTouristAI; var realTimePrivateBuildingAI = new RealTimePrivateBuildingAI( config, timeInfo, gameConnections.BuildingManager, new ToolManagerConnection()); BuildingAIPatches.RealTimeAI = realTimePrivateBuildingAI; return(true); }
/// <summary> /// Initializes a new instance of the <see cref="RealTimeHumanAIBase{TCitizen}"/> class. /// </summary> /// /// <exception cref="ArgumentNullException">Thrown when any argument is null.</exception> /// /// <param name="config">A configuration to use with this custom logic.</param> /// <param name="connections">An object providing the proxies that connect the method calls to the game methods.</param> /// <param name="eventManager">A reference to an <see cref="IRealTimeEventManager"/> instance.</param> protected RealTimeHumanAIBase(RealTimeConfig config, GameConnections <TCitizen> connections, IRealTimeEventManager eventManager) { Config = config ?? throw new ArgumentNullException(nameof(config)); EventMgr = eventManager ?? throw new ArgumentNullException(nameof(eventManager)); if (connections == null) { throw new ArgumentNullException(nameof(connections)); } CitizenMgr = connections.CitizenManager; BuildingMgr = connections.BuildingManager; TransferMgr = connections.TransferManager; CitizenProxy = connections.CitizenConnection; TimeInfo = connections.TimeInfo; Random = connections.Random; WeatherInfo = connections.WeatherInfo; CitizenInstancesMaxCount = CitizenMgr.GetMaxInstancesCount(); }
/// <summary>Initializes a new instance of the <see cref="RealTimeResidentAI{TAI, TCitizen}"/> class.</summary> /// <exception cref="ArgumentNullException">Thrown when any argument is null.</exception> /// <param name="config">A <see cref="RealTimeConfig"/> instance containing the mod's configuration.</param> /// <param name="connections">A <see cref="GameConnections{T}"/> instance that provides the game connection implementation.</param> /// <param name="residentAI">A connection to the game's resident AI.</param> /// <param name="eventManager">An <see cref="IRealTimeEventManager"/> instance.</param> /// <param name="buildingAI">The custom building AI.</param> /// <param name="workBehavior">A behavior that provides simulation info for the citizens work time.</param> /// <param name="spareTimeBehavior">A behavior that provides simulation info for the citizens spare time.</param> /// <param name="travelBehavior">A behavior that provides simulation info for the citizens traveling.</param> public RealTimeResidentAI( RealTimeConfig config, GameConnections <TCitizen> connections, ResidentAIConnection <TAI, TCitizen> residentAI, IRealTimeEventManager eventManager, IRealTimeBuildingAI buildingAI, IWorkBehavior workBehavior, ISpareTimeBehavior spareTimeBehavior, ITravelBehavior travelBehavior) : base(config, connections, eventManager) { this.residentAI = residentAI ?? throw new ArgumentNullException(nameof(residentAI)); this.buildingAI = buildingAI ?? throw new ArgumentNullException(nameof(buildingAI)); this.workBehavior = workBehavior ?? throw new ArgumentNullException(nameof(workBehavior)); this.spareTimeBehavior = spareTimeBehavior ?? throw new ArgumentNullException(nameof(spareTimeBehavior)); this.travelBehavior = travelBehavior ?? throw new ArgumentNullException(nameof(travelBehavior)); residentSchedules = new CitizenSchedule[CitizenMgr.GetMaxCitizensCount()]; abandonCarRideDurationThreshold = Constants.MaxTravelTime * 0.8f; abandonCarRideToWorkDurationThreshold = Constants.MaxTravelTime; }
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); }
private static bool SetupCustomAI( TimeInfo timeInfo, RealTimeConfig config, GameConnections <Citizen> gameConnections, RealTimeEventManager eventManager, Compatibility compatibility) { var residentAIConnection = ResidentAIPatch.GetResidentAIConnection(); if (residentAIConnection == null) { return(false); } float travelDistancePerCycle = compatibility.IsAnyModActive(WorkshopMods.RealisticWalkingSpeed) ? Constants.AverageTravelDistancePerCycle * 0.583f : Constants.AverageTravelDistancePerCycle; var spareTimeBehavior = new SpareTimeBehavior(config, timeInfo); var travelBehavior = new TravelBehavior(gameConnections.BuildingManager, travelDistancePerCycle); var workBehavior = new WorkBehavior(config, gameConnections.Random, gameConnections.BuildingManager, timeInfo, travelBehavior); ParkPatch.SpareTimeBehavior = spareTimeBehavior; OutsideConnectionAIPatch.SpareTimeBehavior = spareTimeBehavior; var realTimePrivateBuildingAI = new RealTimeBuildingAI( config, timeInfo, gameConnections.BuildingManager, new ToolManagerConnection(), workBehavior, travelBehavior); BuildingAIPatch.RealTimeAI = realTimePrivateBuildingAI; BuildingAIPatch.WeatherInfo = gameConnections.WeatherInfo; TransferManagerPatch.RealTimeAI = realTimePrivateBuildingAI; var realTimeResidentAI = new RealTimeResidentAI <ResidentAI, Citizen>( config, gameConnections, residentAIConnection, eventManager, realTimePrivateBuildingAI, workBehavior, spareTimeBehavior, travelBehavior); ResidentAIPatch.RealTimeAI = realTimeResidentAI; SimulationHandler.CitizenProcessor = new CitizenProcessor <ResidentAI, Citizen>( realTimeResidentAI, timeInfo, spareTimeBehavior, travelBehavior); var touristAIConnection = TouristAIPatch.GetTouristAIConnection(); if (touristAIConnection == null) { return(false); } var realTimeTouristAI = new RealTimeTouristAI <TouristAI, Citizen>( config, gameConnections, touristAIConnection, eventManager, spareTimeBehavior); TouristAIPatch.RealTimeAI = realTimeTouristAI; return(true); }
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); }