private static bool ProcessAtHome(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AtHome);

            if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork())
            {
                residentAI.GoToWork(citizenId, ref citizen);

                return(true);
            }
            else if (citizen.Tired())
            {
                residentAI.GoToSleep(citizenId);

                return(true);
            }
            else
            {
                var simulationManager = SimulationManager.instance;
                var happiness         = Citizen.GetHappiness(citizen.m_health, citizen.m_wellbeing);
                var wealth            = citizen.WealthLevel;
                var happinessLevel    = Citizen.GetHappinessLevel(happiness);
                var dayOfWeek         = simulationManager.m_currentGameTime.DayOfWeek;
                var weekend           = !citizen.ValidWorkBuilding() || dayOfWeek == DayOfWeek.Saturday || dayOfWeek == DayOfWeek.Sunday;
                var goSomewhere       = simulationManager.m_randomizer.Int32(16) < ((int)happinessLevel + (int)wealth) * (weekend ? 2 : 1);

                if (goSomewhere)
                {
                    ProcessActivity(ref residentAI, citizenId, ref citizen);
                }

                return(true);
            }
        }
예제 #2
0
        public static bool FindAFunActivity(this ResidentAI residentAI, uint citizenId, ref Citizen citizen, ushort proximityBuilding)
        {
            var visitMonument = SimulationManager.instance.m_randomizer.Int32(10) < 3;

            if (visitMonument && proximityBuilding != 0)
            {
                var proximityBuildingInstance = BuildingManager.instance.m_buildings.m_buffer[proximityBuilding];
                var monument = residentAI.FindSomewhereClose(citizenId, ref citizen, BuildingManager.BUILDINGGRID_RESOLUTION * BuildingManager.BUILDINGGRID_CELL_SIZE, proximityBuildingInstance, new[] { ItemClass.Service.Monument }, new[] { ItemClass.SubService.None });
                if (monument != 0)
                {
                    residentAI.GoToBuilding(citizenId, ref citizen, monument);

                    return(true);
                }
            }

            var entertainmentReason = new Traverse(residentAI).Method("GetEntertainmentReason").GetValue <TransferManager.TransferReason>();

            if (entertainmentReason != TransferManager.TransferReason.None)
            {
                new Traverse(residentAI).Method("FindVisitPlace", citizenId, proximityBuilding, entertainmentReason);

                CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AttemptingToGoForEntertainment);

                return(true);
            }

            return(false);
        }
        private static bool ProcessMoving(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Moving);

            if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork())
            {
                residentAI.GoToWork(citizenId, ref citizen);

                return(true);
            }

            return(false);
        }
예제 #4
0
        public static bool FindAFunActivity(this TouristAI touristAI, uint citizenId, ushort proximityBuilding)
        {
            var entertainmentReason = new Traverse(touristAI).Method("GetEntertainmentReason").GetValue <TransferManager.TransferReason>();

            if (entertainmentReason != TransferManager.TransferReason.None)
            {
                new Traverse(touristAI).Method("FindVisitPlace", citizenId, proximityBuilding, entertainmentReason);

                CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AttemptingToGoForEntertainment);

                return(true);
            }

            return(false);
        }
예제 #5
0
        public static bool LeaveTheCity(this HumanAI humanAI, uint citizenId, ref Citizen citizen)
        {
            var leavingReason = GetLeavingReason(citizenId, ref citizen);

            if (leavingReason != TransferManager.TransferReason.None)
            {
                new Traverse(humanAI).Method("FindVisitPlace", citizenId, citizen.GetBuilding(), leavingReason);

                CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Leaving);

                return(true);
            }

            return(false);
        }
예제 #6
0
        public static bool TryVisit(this HumanAI humanAI, uint citizenId, ref Citizen citizen, ushort buildingId)
        {
            var currentBuilding = citizen.GetBuilding();

            if (buildingId != 0 && currentBuilding != 0 && currentBuilding != buildingId && GlobalLocationHandler.GoodBuildingToVisit(buildingId, ref citizen))
            {
                var moving = humanAI.GoToBuilding(citizenId, ref citizen, buildingId);

                CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.GoingToVisit);

                return(moving);
            }

            return(false);
        }
예제 #7
0
        public static bool FindAShop(this ResidentAI residentAI, uint citizenId, ushort proximityBuilding)
        {
            var shoppingReason = new Traverse(residentAI).Method("GetShoppingReason").GetValue <TransferManager.TransferReason>();

            if (shoppingReason != TransferManager.TransferReason.None)
            {
                new Traverse(residentAI).Method("FindVisitPlace", citizenId, proximityBuilding, shoppingReason);

                CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AttemptingToGoShopping);

                return(true);
            }

            return(false);
        }
        private static bool ProcessVisiting(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, GetBuildingActivity(ref citizen));

            if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork())
            {
                residentAI.GoToWork(citizenId, ref citizen);

                return(true);
            }
            else if (citizen.ShouldGoHome())
            {
                residentAI.GoHome(citizenId, ref citizen);

                return(true);
            }
            else
            {
                var simulationManager = SimulationManager.instance;
                var buildingInstance  = citizen.GetBuildingInstance().Value;
                var shouldStay        = GlobalLocationHandler.GoodBuildingToVisit(ref buildingInstance, ref citizen) && (citizen.AfraidOfGettingWet() || simulationManager.m_randomizer.UInt32(10) < 6);

                if (!shouldStay)
                {
                    var ageGroup           = Citizen.GetAgeGroup(citizen.Age);
                    var happiness          = Citizen.GetHappiness(citizen.m_health, citizen.m_wellbeing);
                    var happinessLevel     = Citizen.GetHappinessLevel(happiness);
                    var visitSomewhereElse = simulationManager.m_randomizer.UInt32(100) < ((int)happinessLevel * 18) / ((int)ageGroup + 1);

                    if (!visitSomewhereElse || !ProcessActivity(ref residentAI, citizenId, ref citizen))
                    {
                        if (!residentAI.GoHome(citizenId, ref citizen))
                        {
                        }
                    }
                }
                else if (citizen.GettingWet())
                {
                    CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.GettingWet);

                    residentAI.GoHome(citizenId, ref citizen);
                }

                return(true);
            }
        }
예제 #9
0
        public static bool Process(ref TouristAI touristAI, uint citizenId, ref Citizen citizen)
        {
            if (!citizen.Arrested && !citizen.Sick && !citizen.Collapsed && !citizen.Dead && !citizen.AtHome() && !citizen.AtWork() && citizen.Exists())
            {
                CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Unknown);

                if (citizen.IsAtABuilding())
                {
                    return(ProcessInBuilding(ref touristAI, citizenId, ref citizen));
                }
                else if (citizen.IsMoving())
                {
                    return(ProcessMoving(ref touristAI, citizenId, ref citizen));
                }

                return(true);
            }

            return(false);
        }
        private static bool ProcessAtHome(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AtHome);

            if (citizen.ValidWorkBuilding() && citizen.ShouldGoToWork())
            {
                residentAI.GoToWork(citizenId, ref citizen);

                return(true);
            }
            else if (citizen.Tired())
            {
                residentAI.GoToSleep(citizenId);

                return(true);
            }
            else if (citizen.NeedsGoods())
            {
                var proximityBuilding = citizen.ValidHomeBuilding() ? citizen.HomeBuilding() : citizen.WorkBuilding(); //Prioritise something close to home, rather than work

                if (residentAI.GoToAShop(citizenId, ref citizen, proximityBuilding, BuildingManager.BUILDINGGRID_CELL_SIZE * 2))
                {
                    return(true);
                }
            }

            var simulationManager = SimulationManager.instance;
            var happiness         = Citizen.GetHappiness(citizen.m_health, citizen.m_wellbeing);
            var wealth            = citizen.WealthLevel;
            var happinessLevel    = Citizen.GetHappinessLevel(happiness);
            var dayOfWeek         = simulationManager.m_currentGameTime.DayOfWeek;
            var weekend           = !citizen.ValidWorkBuilding() || dayOfWeek == DayOfWeek.Saturday || dayOfWeek == DayOfWeek.Sunday;
            var goSomewhere       = simulationManager.m_randomizer.Int32(16) < ((int)happinessLevel + (int)wealth) * (weekend ? 2 : 1);

            if (goSomewhere)
            {
                ProcessActivity(ref residentAI, citizenId, ref citizen);
            }

            return(true);
        }
예제 #11
0
        public void SimulationStep(int subStep)
        {
            var _simulation = SimulationManager.instance;

            if (_simulation.m_enableDayNight)
            {
                if (!_simulation.SimulationPaused && !_simulation.ForcedSimulationPaused)
                {
                    var timeMultiplier = UserModSettings.Settings.Simulation_Speed;

                    if (timeMultiplier >= 1f)
                    {
                        _simulation.m_dayTimeOffsetFrames = (_simulation.m_dayTimeOffsetFrames + (uint)Mathf.RoundToInt(timeMultiplier)) % SimulationManager.DAYTIME_FRAMES;
                    }
                    else
                    {
                        if (_step < Mathf.RoundToInt(1f / timeMultiplier))
                        {
                            ++_step;
                            _simulation.m_dayTimeOffsetFrames = (_simulation.m_dayTimeOffsetFrames - 1u) % SimulationManager.DAYTIME_FRAMES;
                        }
                        else
                        {
                            _step = 0;
                        }
                    }
                }
            }

            if (_nextLogTime < DateTime.Now)
            {
                CitizenActivityMonitor.WriteLog(LoggingWrapper.LogArea.File);

                _nextLogTime = DateTime.Now + CITIZEN_LOG_INTERVAL;
            }
        }
예제 #12
0
        public static bool GoToWork(this HumanAI humanAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.GoingToWork);

            return(humanAI.GoToBuilding(citizenId, ref citizen, citizen.WorkBuilding()));
        }
예제 #13
0
 public static void GoToSleep(this HumanAI humanAI, uint citizenId)
 {
     CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Sleeping);
 }
예제 #14
0
        private static bool ProcessMoving(ref TouristAI touristAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Moving);

            return(citizen.m_vehicle != 0 || citizen.IsVisible());
        }
        private static bool ProcessAtWork(ref ResidentAI residentAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.AtWork);

            if (!citizen.ShouldBeAtWork())
            {
                if (citizen.NeedsGoods())
                {
                    var proximityBuilding = citizen.ValidHomeBuilding() ? citizen.HomeBuilding() : citizen.WorkBuilding(); //Prioritise something close to home, rather than work

                    if (residentAI.GoToAShop(citizenId, ref citizen, proximityBuilding, BuildingManager.BUILDINGGRID_CELL_SIZE * 2))
                    {
                        return(true);
                    }
                }

                if (citizen.ShouldGoHome())
                {
                    residentAI.GoHome(citizenId, ref citizen);

                    return(true);
                }

                var simulationManager = SimulationManager.instance;
                var time           = simulationManager.m_currentGameTime;
                var ageGroup       = Citizen.GetAgeGroup(citizen.Age);
                var happiness      = Citizen.GetHappiness(citizen.m_health, citizen.m_wellbeing);
                var happinessLevel = Citizen.GetHappinessLevel(happiness);

                if (happinessLevel >= Citizen.Happiness.Good)
                {
                    if (UserModSettings.Settings.Citizens_AllowLeisureAfterWork && time.DayOfWeek == DayOfWeek.Friday && (ageGroup == Citizen.AgeGroup.Adult || ageGroup == Citizen.AgeGroup.Young))
                    {
                        var goOut = simulationManager.m_randomizer.Int32(10) <= 6;
                        if (goOut)
                        {
                            var allLeisure         = residentAI.FindAllClosePlaces(citizenId, ref citizen, citizen.WorkBuildingInstance().Value.m_position, new[] { ItemClass.Service.Commercial }, new[] { ItemClass.SubService.CommercialLeisure }, BuildingManager.BUILDINGGRID_CELL_SIZE);
                            var currentBuildingInt = (int)citizen.GetBuilding();
                            var closest            = -1;
                            var chosenBuilding     = (ushort)0;

                            foreach (var leisure in allLeisure)
                            {
                                var leisureInt = (int)leisure;
                                var difference = Math.Abs(leisureInt - currentBuildingInt);
                                if (closest < 0 || difference < closest)
                                {
                                    closest        = difference;
                                    chosenBuilding = leisure;
                                }
                            }

                            if (chosenBuilding != 0 && residentAI.TryVisit(citizenId, ref citizen, chosenBuilding))
                            {
                                return(true);
                            }
                        }
                    }

                    var shouldGoSomewhereElseFirst = simulationManager.m_randomizer.Int32(10) <= 3 + (int)happinessLevel;
                    if (shouldGoSomewhereElseFirst)
                    {
                        if (residentAI.GoToAFunActivity(citizenId, ref citizen, citizen.WorkBuilding(), BuildingManager.BUILDINGGRID_CELL_SIZE))
                        {
                            return(true);
                        }
                    }
                }

                residentAI.GoHome(citizenId, ref citizen);

                return(true);
            }

            return(true);
        }
예제 #16
0
        private static bool ProcessVisiting(ref TouristAI touristAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Visiting);

            if (!citizen.ValidVisitBuilding())
            {
                return(false);
            }

            var touristHotelSearchRadius = BuildingManager.BUILDINGGRID_CELL_SIZE * 4;
            var currentBuildingInstance  = citizen.VisitBuildingInstance().Value;
            var simulationManager        = SimulationManager.instance;

            if (citizen.Tired() || citizen.Tired(TimeSpan.FromHours(6)))
            {
                if (citizen.Tired() && citizen.InHotel())
                {
                    touristAI.GoToSleep(citizenId);

                    return(true);
                }

                var foundHotel = touristAI.FindHotel(citizenId, ref citizen, currentBuildingInstance, touristHotelSearchRadius);
                if (foundHotel != 0 && simulationManager.m_randomizer.Int32(10) < 8)
                {
                    var foundHotelInstance  = BuildingManager.instance.m_buildings.m_buffer[foundHotel];
                    var estimatedTravelTime = TravelTime.EstimateTravelTime(currentBuildingInstance, foundHotelInstance);

                    if (citizen.Tired(estimatedTravelTime))
                    {
                        touristAI.TryVisit(citizenId, ref citizen, foundHotel);

                        return(true);
                    }
                }
                else if (citizen.Tired())
                {
                    touristAI.LeaveTheCity(citizenId, ref citizen);

                    return(true);
                }
            }

            var goSomewhere = (simulationManager.m_randomizer.Int32(10) < 3 || citizen.InHotel()) && !citizen.AfraidOfGettingWet();

            if (goSomewhere)
            {
                var keepItLocal = simulationManager.m_randomizer.Int32(10) < 8;
                if (keepItLocal)
                {
                    var    ventureDistance      = (BuildingManager.BUILDINGGRID_CELL_SIZE * 2) + (simulationManager.m_randomizer.Int32(3) * BuildingManager.BUILDINGGRID_CELL_SIZE);
                    var    randomActivityNumber = simulationManager.m_randomizer.Int32(9);
                    ushort closeActivity        = 0;

                    if (randomActivityNumber < 3 || simulationManager.m_currentGameTime.Hour >= 21)
                    {
                        closeActivity = touristAI.FindLeisure(citizenId, ref citizen, currentBuildingInstance, ventureDistance);
                    }
                    else if (randomActivityNumber < 6)
                    {
                        closeActivity = touristAI.FindPark(citizenId, ref citizen, currentBuildingInstance, ventureDistance);
                    }
                    else
                    {
                        closeActivity = touristAI.FindShop(citizenId, ref citizen, currentBuildingInstance, ventureDistance);
                    }

                    if (closeActivity != 0)
                    {
                        var closeActivityBuilding = BuildingManager.instance.m_buildings.m_buffer[closeActivity];
                        if (!citizen.Tired(TravelTime.EstimateTravelTime(currentBuildingInstance, closeActivityBuilding)))
                        {
                            touristAI.TryVisit(citizenId, ref citizen, closeActivity);
                        }
                    }
                }
                else
                {
                    var goShopping = simulationManager.m_randomizer.Int32(10) < 5;
                    var extendedVentureDistance = BuildingManager.BUILDINGGRID_CELL_SIZE * 6;

                    if (goShopping)
                    {
                        touristAI.GoToAShop(citizenId, ref citizen, extendedVentureDistance);
                    }
                    else
                    {
                        touristAI.GoToAFunActivity(citizenId, ref citizen, citizen.GetBuilding(), extendedVentureDistance);
                    }
                }
            }
            else if (citizen.GettingWet())
            {
                CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.GettingWet);

                var hotel = touristAI.FindHotel(citizenId, ref citizen, currentBuildingInstance, touristHotelSearchRadius);
                if (hotel != 0)
                {
                    touristAI.TryVisit(citizenId, ref citizen, hotel);
                }
            }

            return(true);
        }
예제 #17
0
        private static bool ProcessMoving(ref TouristAI touristAI, uint citizenId, ref Citizen citizen)
        {
            CitizenActivityMonitor.LogActivity(citizenId, CitizenActivityMonitor.Activity.Moving);

            return(false);
        }