Beispiel #1
0
 private RealTimeCore(TimeAdjustment timeAdjustment, CustomTimeBar timeBar, RealTimeEventManager eventManager, MethodPatcher patcher)
 {
     this.timeAdjustment = timeAdjustment;
     this.timeBar        = timeBar;
     this.eventManager   = eventManager;
     this.patcher        = patcher;
     isEnabled           = true;
 }
Beispiel #2
0
        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;
            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, spareTimeBehavior, timeInfo);

            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));
 }
Beispiel #4
0
 /// <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));
 }
Beispiel #5
0
 /// <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);
 }
Beispiel #6
0
        /// <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()];
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        /// <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 an <see cref="RealTimeEventManager"/> instance.</param>
        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;
            Random       = connections.Random;
            WeatherInfo  = connections.WeatherInfo;
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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);
        }