Esempio n. 1
0
        private void CalculateShoppingChance(float currentHour)
        {
            float minShoppingChanceEndHour   = Math.Min(config.WakeupHour, EarliestWakeUp);
            float maxShoppingChanceStartHour = Math.Max(config.WorkBegin, config.WakeupHour);

            if (minShoppingChanceEndHour == maxShoppingChanceStartHour)
            {
                minShoppingChanceEndHour = RealTimeMath.Clamp(maxShoppingChanceStartHour - 1f, 2f, maxShoppingChanceStartHour - 1f);
            }

#if DEBUG
            uint oldChance = shoppingChances[(int)Citizen.AgeGroup.Adult];
#endif

            float chance;
            bool  isNight;
            float maxShoppingChanceEndHour = Math.Max(config.GoToSleepUpHour, config.WorkEnd);
            if (currentHour < minShoppingChanceEndHour)
            {
                isNight = true;
                chance  = NightShoppingChance;
            }
            else if (currentHour < maxShoppingChanceStartHour)
            {
                isNight = true;
                chance  = NightShoppingChance +
                          ((100u - NightShoppingChance) * (currentHour - minShoppingChanceEndHour) / (maxShoppingChanceStartHour - minShoppingChanceEndHour));
            }
            else if (currentHour < maxShoppingChanceEndHour)
            {
                isNight = false;
                chance  = 100;
            }
            else
            {
                isNight = true;
                chance  = NightShoppingChance +
                          ((100u - NightShoppingChance) * (24f - currentHour) / (24f - maxShoppingChanceEndHour));
            }

            uint roundedChance = (uint)Math.Round(chance);

            shoppingChances[(int)Citizen.AgeGroup.Child]  = isNight ? 0u : roundedChance;
            shoppingChances[(int)Citizen.AgeGroup.Teen]   = isNight ? 0u : roundedChance;
            shoppingChances[(int)Citizen.AgeGroup.Young]  = roundedChance;
            shoppingChances[(int)Citizen.AgeGroup.Adult]  = roundedChance;
            shoppingChances[(int)Citizen.AgeGroup.Senior] = isNight ? (uint)Math.Round(chance * 0.1f) : roundedChance;

#if DEBUG
            if (oldChance != roundedChance)
            {
                Log.Debug($"SHOPPING CHANCES for {timeInfo.Now}: child = {shoppingChances[0]}, teen = {shoppingChances[1]}, young = {shoppingChances[2]}, adult = {shoppingChances[3]}, senior = {shoppingChances[4]}");
            }
#endif
        }
Esempio n. 2
0
        /// <summary>Gets an estimated travel time (in hours) between two specified buildings.</summary>
        /// <param name="building1">The ID of the first building.</param>
        /// <param name="building2">The ID of the second building.</param>
        /// <returns>An estimated travel time in hours.</returns>
        public float GetEstimatedTravelTime(ushort building1, ushort building2)
        {
            if (building1 == 0 || building2 == 0 || building1 == building2)
            {
                return(0);
            }

            float distance = buildingManager.GetDistanceBetweenBuildings(building1, building2);

            return(RealTimeMath.Clamp(distance / OnTheWayDistancePerHour, MinTravelTime, MaxTravelTime));
        }
Esempio n. 3
0
        /// <summary>Calculates the chances for the citizens to go out based on the current game time.</summary>
        public void RefreshGoOutChances()
        {
            uint weekdayModifier;

            if (config.IsWeekendEnabled)
            {
                weekdayModifier = timeInfo.Now.IsWeekendTime(12f, config.GoToSleepUpHour)
                    ? 11u
                    : 1u;
            }
            else
            {
                weekdayModifier = 1u;
            }

            float currentHour = timeInfo.CurrentHour;

            float latestGoOutHour = config.GoToSleepUpHour - simulationCycle;
            bool  isDayTime       = currentHour >= config.WakeupHour && currentHour < latestGoOutHour;
            float timeModifier;

            if (isDayTime)
            {
                timeModifier = RealTimeMath.Clamp(currentHour - config.WakeupHour, 0, 4f);
            }
            else
            {
                float nightDuration = 24f - (latestGoOutHour - config.WakeupHour);
                float relativeHour  = currentHour - latestGoOutHour;
                if (relativeHour < 0)
                {
                    relativeHour += 24f;
                }

                timeModifier = 3f / nightDuration * (nightDuration - relativeHour);
            }

            uint defaultChance = (uint)((timeModifier + weekdayModifier) * timeModifier);

            bool dump = chances[(int)Citizen.AgeGroup.Young] != defaultChance;

            chances[(int)Citizen.AgeGroup.Child]  = isDayTime ? defaultChance : 0;
            chances[(int)Citizen.AgeGroup.Teen]   = isDayTime ? defaultChance : 0;
            chances[(int)Citizen.AgeGroup.Young]  = defaultChance;
            chances[(int)Citizen.AgeGroup.Adult]  = defaultChance;
            chances[(int)Citizen.AgeGroup.Senior] = isDayTime ? defaultChance : 0;

            if (dump)
            {
                Log.Debug($"GO OUT CHANCES for {timeInfo.Now}: child = {chances[0]}, teen = {chances[1]}, young = {chances[2]}, adult = {chances[3]}, senior = {chances[4]}");
            }
        }
Esempio n. 4
0
        private void CalculateDefaultChances(float currentHour, uint weekdayModifier)
        {
            float latestGoOutHour = config.GoToSleepUpHour - simulationCycle;
            bool  isDayTime       = currentHour >= config.WakeupHour && currentHour < latestGoOutHour;
            float timeModifier;

            if (isDayTime)
            {
                timeModifier = RealTimeMath.Clamp(currentHour - config.WakeupHour, 0, 4f);
            }
            else
            {
                float nightDuration = 24f - (latestGoOutHour - config.WakeupHour);
                float relativeHour  = currentHour - latestGoOutHour;
                if (relativeHour < 0)
                {
                    relativeHour += 24f;
                }

                timeModifier = 3f / nightDuration * (nightDuration - relativeHour);
            }

            float chance        = (timeModifier + weekdayModifier) * timeModifier;
            uint  roundedChance = (uint)Math.Round(chance);

#if DEBUG
            bool dump = defaultChances[(int)Citizen.AgeGroup.Adult] != roundedChance;
#endif

            defaultChances[(int)Citizen.AgeGroup.Child]  = isDayTime ? roundedChance : 0;
            defaultChances[(int)Citizen.AgeGroup.Teen]   = isDayTime ? (uint)Math.Round(chance * 0.9f) : 0;
            defaultChances[(int)Citizen.AgeGroup.Young]  = (uint)Math.Round(chance * 1.3f);
            defaultChances[(int)Citizen.AgeGroup.Adult]  = roundedChance;
            defaultChances[(int)Citizen.AgeGroup.Senior] = isDayTime ? (uint)Math.Round(chance * 0.8f) : 0;

#if DEBUG
            if (dump)
            {
                Log.Debug($"DEFAULT GOING OUT CHANCES for {timeInfo.Now}: child = {defaultChances[0]}, teen = {defaultChances[1]}, young = {defaultChances[2]}, adult = {defaultChances[3]}, senior = {defaultChances[4]}");
            }
#endif
        }
Esempio n. 5
0
        /// <summary>Validates this instance and corrects possible invalid property values.</summary>
        /// <returns>This instance.</returns>
        public RealTimeConfig Validate()
        {
            WakeupHour      = RealTimeMath.Clamp(WakeupHour, 4f, 8f);
            GoToSleepUpHour = RealTimeMath.Clamp(GoToSleepUpHour, 20f, 23.75f);

            DayTimeSpeed   = RealTimeMath.Clamp(DayTimeSpeed, 1u, 7u);
            NightTimeSpeed = RealTimeMath.Clamp(NightTimeSpeed, 1u, 7u);

            VirtualCitizens   = (VirtualCitizensLevel)RealTimeMath.Clamp((int)VirtualCitizens, (int)VirtualCitizensLevel.None, (int)VirtualCitizensLevel.Many);
            ConstructionSpeed = RealTimeMath.Clamp(ConstructionSpeed, 0u, 100u);

            SecondShiftQuota         = RealTimeMath.Clamp(SecondShiftQuota, 1u, 25u);
            NightShiftQuota          = RealTimeMath.Clamp(NightShiftQuota, 1u, 25u);
            LunchQuota               = RealTimeMath.Clamp(LunchQuota, 0u, 100u);
            LocalBuildingSearchQuota = RealTimeMath.Clamp(LocalBuildingSearchQuota, 0u, 100u);
            OnTimeQuota              = RealTimeMath.Clamp(OnTimeQuota, 0u, 100u);

            EarliestHourEventStartWeekday = RealTimeMath.Clamp(EarliestHourEventStartWeekday, 0f, 23.75f);
            LatestHourEventStartWeekday   = RealTimeMath.Clamp(LatestHourEventStartWeekday, 0f, 23.75f);
            if (LatestHourEventStartWeekday < EarliestHourEventStartWeekday)
            {
                LatestHourEventStartWeekday = EarliestHourEventStartWeekday;
            }

            EarliestHourEventStartWeekend = RealTimeMath.Clamp(EarliestHourEventStartWeekend, 0f, 23.75f);
            LatestHourEventStartWeekend   = RealTimeMath.Clamp(LatestHourEventStartWeekend, 0f, 23.75f);
            if (LatestHourEventStartWeekend < EarliestHourEventStartWeekend)
            {
                LatestHourEventStartWeekend = EarliestHourEventStartWeekend;
            }

            WorkBegin   = RealTimeMath.Clamp(WorkBegin, 4f, 11f);
            WorkEnd     = RealTimeMath.Clamp(WorkEnd, 12f, 20f);
            LunchBegin  = RealTimeMath.Clamp(LunchBegin, 11f, 13f);
            LunchEnd    = RealTimeMath.Clamp(LunchEnd, 13f, 15f);
            SchoolBegin = RealTimeMath.Clamp(SchoolBegin, 4f, 10f);
            SchoolEnd   = RealTimeMath.Clamp(SchoolEnd, 11f, 16f);
            MaxOvertime = RealTimeMath.Clamp(MaxOvertime, 0f, 4f);
            return(this);
        }