コード例 #1
0
        /// <summary>Accepts an event attendee with specified properties.</summary>
        /// <param name="age">The attendee age.</param>
        /// <param name="gender">The attendee gender.</param>
        /// <param name="education">The attendee education.</param>
        /// <param name="wealth">The attendee wealth.</param>
        /// <param name="wellbeing">The attendee wellbeing.</param>
        /// <param name="happiness">The attendee happiness.</param>
        /// <param name="randomizer">A reference to the game's randomizer.</param>
        /// <returns>
        /// <c>true</c> if the event attendee with specified properties is accepted and can attend this city event;
        /// otherwise, <c>false</c>.
        /// </returns>
        public override bool TryAcceptAttendee(
            Citizen.AgeGroup age,
            Citizen.Gender gender,
            Citizen.Education education,
            Citizen.Wealth wealth,
            Citizen.Wellbeing wellbeing,
            Citizen.Happiness happiness,
            IRandomizer randomizer)
        {
            if (attendeesCount > eventTemplate.Capacity)
            {
                return(false);
            }

            if (eventTemplate.Costs != null && eventTemplate.Costs.Entry > GetCitizenBudgetForEvent(wealth, randomizer))
            {
                return(false);
            }

            CityEventAttendees attendees = eventTemplate.Attendees;
            float randomPercentage       = randomizer.GetRandomValue(100u);

            if (!CheckAge(age, attendees, randomPercentage))
            {
                return(false);
            }

            randomPercentage = randomizer.GetRandomValue(100u);
            if (!CheckGender(gender, attendees, randomPercentage))
            {
                return(false);
            }

            randomPercentage = randomizer.GetRandomValue(100u);
            if (!CheckEducation(education, attendees, randomPercentage))
            {
                return(false);
            }

            randomPercentage = randomizer.GetRandomValue(100u);
            if (!CheckWealth(wealth, attendees, randomPercentage))
            {
                return(false);
            }

            randomPercentage = randomizer.GetRandomValue(100u);
            if (!CheckWellbeing(wellbeing, attendees, randomPercentage))
            {
                return(false);
            }

            randomPercentage = randomizer.GetRandomValue(100u);
            if (!CheckHappiness(happiness, attendees, randomPercentage))
            {
                return(false);
            }

            attendeesCount++;
            return(true);
        }
コード例 #2
0
ファイル: VanillaEvent.cs プロジェクト: nicwisely/RealTime
 /// <summary>Accepts an event attendee with specified properties.</summary>
 /// <param name="age">The attendee age.</param>
 /// <param name="gender">The attendee gender.</param>
 /// <param name="education">The attendee education.</param>
 /// <param name="wealth">The attendee wealth.</param>
 /// <param name="wellbeing">The attendee wellbeing.</param>
 /// <param name="happiness">The attendee happiness.</param>
 /// <param name="randomizer">A reference to the game's randomizer.</param>
 /// <returns>
 /// <c>true</c> if the event attendee with specified properties is accepted and can attend
 /// this city event; otherwise, <c>false</c>.
 /// </returns>
 public override bool TryAcceptAttendee(
     Citizen.AgeGroup age,
     Citizen.Gender gender,
     Citizen.Education education,
     Citizen.Wealth wealth,
     Citizen.Wellbeing wellbeing,
     Citizen.Happiness happiness,
     IRandomizer randomizer) => ticketPrice <= GetCitizenBudgetForEvent(wealth, randomizer);
コード例 #3
0
 /// <summary>Accepts an event attendee with specified properties.</summary>
 /// <param name="age">The attendee age.</param>
 /// <param name="gender">The attendee gender.</param>
 /// <param name="education">The attendee education.</param>
 /// <param name="wealth">The attendee wealth.</param>
 /// <param name="wellbeing">The attendee wellbeing.</param>
 /// <param name="happiness">The attendee happiness.</param>
 /// <param name="randomizer">A reference to the game's randomizer.</param>
 /// <returns>
 /// <c>true</c> if the event attendee with specified properties is accepted and can attend
 /// this city event; otherwise, <c>false</c>.
 /// </returns>
 public virtual bool TryAcceptAttendee(
     Citizen.AgeGroup age,
     Citizen.Gender gender,
     Citizen.Education education,
     Citizen.Wealth wealth,
     Citizen.Wellbeing wellbeing,
     Citizen.Happiness happiness,
     IRandomizer randomizer) => true;
コード例 #4
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            Citizen.Wealth _citizenWealth = person.WealthLevel;
            Citizen.Education _citizenEducation = person.EducationLevel;
            Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);

            return  _citizenWealth > Citizen.Wealth.Low &&
                    _citizenEducation > Citizen.Education.Uneducated &&
                    _citizenWellbeing > Citizen.Wellbeing.VeryUnhappy;
        }
コード例 #5
0
        private bool CanAttendEvent(uint citizenId, ref TCitizen citizen, ICityEvent cityEvent)
        {
            Citizen.AgeGroup  age       = CitizenProxy.GetAge(ref citizen);
            Citizen.Gender    gender    = CitizenProxy.GetGender(citizenId);
            Citizen.Education education = CitizenProxy.GetEducationLevel(ref citizen);
            Citizen.Wealth    wealth    = CitizenProxy.GetWealthLevel(ref citizen);
            Citizen.Wellbeing wellbeing = CitizenProxy.GetWellbeingLevel(ref citizen);
            Citizen.Happiness happiness = CitizenProxy.GetHappinessLevel(ref citizen);

            return(cityEvent.TryAcceptAttendee(age, gender, education, wealth, wellbeing, happiness, Random));
        }
コード例 #6
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            Citizen.Wealth    _citizenWealth    = person.WealthLevel;
            Citizen.Education _citizenEducation = person.EducationLevel;
            Citizen.Happiness _citizenHappiness = Citizen.GetHappinessLevel(Citizen.GetHappiness(person.m_health, person.m_wellbeing));
            Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);

            return(_citizenWealth > Citizen.Wealth.Low &&
                   _citizenHappiness > Citizen.Happiness.Poor &&
                   _citizenWellbeing > Citizen.Wellbeing.VeryUnhappy);
        }
コード例 #7
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            Citizen.Wealth    _citizenWealth    = person.WealthLevel;
            Citizen.Education _citizenEducation = person.EducationLevel;
            Citizen.Happiness _citizenHappiness = Citizen.GetHappinessLevel(Citizen.GetHappiness(person.m_health, person.m_wellbeing));
            Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);

            return(_citizenWealth > Citizen.Wealth.Low &&
                   _citizenEducation > Citizen.Education.TwoSchools &&
                   _citizenHappiness >= Citizen.Happiness.Good &&
                   _citizenWellbeing >= Citizen.Wellbeing.Satisfied);
        }
コード例 #8
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            Citizen.Wealth    _citizenWealth    = person.WealthLevel;
            Citizen.Education _citizenEducation = person.EducationLevel;
            Citizen.AgeGroup  _citizenAge       = Citizen.GetAgeGroup(person.Age);
            Citizen.Gender    _citizenGender    = Citizen.GetGender(citizenID);
            Citizen.Happiness _citizenHappiness = Citizen.GetHappinessLevel(Citizen.GetHappiness(person.m_health, person.m_wellbeing));
            Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);

            return(_citizenWealth >= Citizen.Wealth.Medium &&
                   _citizenAge == Citizen.AgeGroup.Senior &&
                   _citizenHappiness >= Citizen.Happiness.Good &&
                   _citizenWellbeing > Citizen.Wellbeing.Unhappy);
        }
コード例 #9
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            Citizen.Wealth    _citizenWealth    = person.WealthLevel;
            Citizen.Education _citizenEducation = person.EducationLevel;
            Citizen.AgeGroup  _citizenAge       = Citizen.GetAgeGroup(person.Age);
            Citizen.Happiness _citizenHappiness = Citizen.GetHappinessLevel(Citizen.GetHappiness(person.m_health, person.m_wellbeing));
            Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);

            return(_citizenWealth == Citizen.Wealth.High &&
                   _citizenEducation >= Citizen.Education.TwoSchools &&
                   _citizenAge >= Citizen.AgeGroup.Young &&
                   _citizenHappiness >= Citizen.Happiness.Good &&
                   _citizenWellbeing > Citizen.Wellbeing.Unhappy);
        }
コード例 #10
0
ファイル: RealTimeCityEvent.cs プロジェクト: simog6/RealTime
        private static bool CheckWealth(Citizen.Wealth wealth, CityEventAttendees attendees, float randomPercentage)
        {
            switch (wealth)
            {
            case Citizen.Wealth.Low:
                return(randomPercentage < attendees.LowWealth);

            case Citizen.Wealth.Medium:
                return(randomPercentage < attendees.MediumWealth);

            case Citizen.Wealth.High:
                return(randomPercentage < attendees.HighWealth);
            }

            return(false);
        }
コード例 #11
0
        /// <summary>
        /// Calculates the citizen's maximum budget for visiting a city event. It depends on the
        /// citizen's wealth.
        /// </summary>
        /// ///
        /// <param name="wealth">The citizen's wealth.</param>
        /// <param name="randomizer">A reference to the game's randomizer.</param>
        /// <returns>The citizen's budget for attending an event.</returns>
        protected static float GetCitizenBudgetForEvent(Citizen.Wealth wealth, IRandomizer randomizer)
        {
            switch (wealth)
            {
            case Citizen.Wealth.Low:
                return(30f + randomizer.GetRandomValue(60));

            case Citizen.Wealth.Medium:
                return(80f + randomizer.GetRandomValue(80));

            case Citizen.Wealth.High:
                return(120f + randomizer.GetRandomValue(320));

            default:
                return(0);
            }
        }
コード例 #12
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            Citizen.Wealth    _citizenWealth    = person.WealthLevel;
            Citizen.Education _citizenEducation = person.EducationLevel;
            Citizen.AgeGroup  _citizenAge       = Citizen.GetAgeGroup(person.Age);
            Citizen.Gender    _citizenGender    = Citizen.GetGender(citizenID);
            Citizen.Happiness _citizenHappiness = Citizen.GetHappinessLevel(Citizen.GetHappiness(person.m_health, person.m_wellbeing));
            Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);

            int percentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100);

            return(_citizenWealth >= Citizen.Wealth.Medium &&
                   (_citizenGender == Citizen.Gender.Male || (_citizenGender == Citizen.Gender.Female && percentage < 40)) &&
                   _citizenAge >= Citizen.AgeGroup.Young && _citizenAge < Citizen.AgeGroup.Senior &&
                   _citizenHappiness >= Citizen.Happiness.Good &&
                   _citizenWellbeing > Citizen.Wellbeing.Unhappy);
        }
コード例 #13
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            Citizen.Wealth    _citizenWealth    = person.WealthLevel;
            Citizen.Education _citizenEducation = person.EducationLevel;
            Citizen.Gender    _citizenGender    = Citizen.GetGender(citizenID);
            Citizen.Happiness _citizenHappiness = Citizen.GetHappinessLevel(Citizen.GetHappiness(person.m_health, person.m_wellbeing));
            Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);
            Citizen.AgeGroup  _citizenAgeGroup  = Citizen.GetAgeGroup(person.Age);

            int percentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100);

            return(_citizenWealth < Citizen.Wealth.High &&
                   (_citizenEducation < Citizen.Education.ThreeSchools || _citizenEducation == Citizen.Education.ThreeSchools && percentage < 5) &&
                   (_citizenGender == Citizen.Gender.Male || (_citizenGender == Citizen.Gender.Female && percentage < 20)) &&
                   _citizenHappiness > Citizen.Happiness.Bad &&
                   _citizenWellbeing > Citizen.Wellbeing.Unhappy);
        }
コード例 #14
0
        /// <summary>
        /// Selects the appropriate data array based on parameters.
        /// </summary>
        /// <param name="wealthLevel">Citizen wealth level</param>
        /// <param name="subService">Building subservice</param>
        /// <param name="ageGroup">Citizen age group</param>
        /// <returns></returns>
        public static int[] GetArray(Citizen.Wealth wealthLevel, ItemClass.SubService subService, Citizen.AgeGroup ageGroup)
        {
            int[][] array;
            // TODO - split for eco
            bool eco          = (subService == ItemClass.SubService.ResidentialHighEco) || (subService == ItemClass.SubService.ResidentialLowEco);
            int  densityIndex = (subService == ItemClass.SubService.ResidentialHigh) || (subService == ItemClass.SubService.ResidentialHighEco) ? 1 : 0;

            if (eco)
            {
                switch (wealthLevel)
                {
                case Citizen.Wealth.High:
                    array = DataStore.eco_wealth_high[densityIndex];
                    break;

                case Citizen.Wealth.Medium:
                    array = DataStore.eco_wealth_med[densityIndex];
                    break;

                case Citizen.Wealth.Low:
                default:
                    array = DataStore.eco_wealth_low[densityIndex];
                    break;
                }
            }
            else
            {
                switch (wealthLevel)
                {
                case Citizen.Wealth.High:
                    array = DataStore.wealth_high[densityIndex];
                    break;

                case Citizen.Wealth.Medium:
                    array = DataStore.wealth_med[densityIndex];
                    break;

                case Citizen.Wealth.Low:
                default:
                    array = DataStore.wealth_low[densityIndex];
                    break;
                }
            }
            return(array[(int)ageGroup]);
        }
コード例 #15
0
        }  // copied from original code

        private void CreateMoreTourists_ByMultiplier(uint modelCitizen, ushort sourceBuilding)  // the newly arrived tourist that led to creation of more tourists
        {
            CitizenManager  citizenManager  = Singleton <CitizenManager> .instance;
            BuildingManager buildingManager = Singleton <BuildingManager> .instance;
            Randomizer      randomizer      = Singleton <SimulationManager> .instance.m_randomizer;

            if ((citizenManager.m_citizens.m_buffer[modelCitizen].m_flags & Citizen.Flags.DummyTraffic) == Citizen.Flags.None)  // not dummy traffic
            {
                float         multiplier = DataStorage.instance.multiplier;
                int           i          = (int)Math.Truncate(multiplier);
                System.Random random     = new System.Random();
                i += (float)random.NextDouble() < multiplier - i ? 1 : 0;
                for (int index = 0; index < i; ++index)
                {
                    TransferManager.TransferReason transferReason = GetRandomTransferReason(0);
                    TransferManager.TransferOffer  offer          = Utils.FindOffer(transferReason, true);
                    ushort targetBuilding = offer.Building;
                    uint   unitID         = buildingManager.m_buildings.m_buffer[targetBuilding].GetEmptyCitizenUnit(CitizenUnit.Flags.Visit);
                    int    family         = Singleton <SimulationManager> .instance.m_randomizer.Int32(256U); // no need to keep to same values

                    int age = Singleton <SimulationManager> .instance.m_randomizer.Int32(0, 240);             // this is exactly the original code

                    if (citizenManager.CreateCitizen(out uint citizen, age, family, ref Singleton <SimulationManager> .instance.m_randomizer))
                    {
                        citizenManager.m_citizens.m_buffer[citizen].m_flags |= Citizen.Flags.Tourist;
                        citizenManager.m_citizens.m_buffer[citizen].m_flags |= Citizen.Flags.MovingIn;
                        Citizen.Wealth wealth = citizenManager.m_citizens.m_buffer[modelCitizen].WealthLevel;
                        citizenManager.m_citizens.m_buffer[citizen].WealthLevel = wealth; // same wealth
                        citizenManager.m_citizens.m_buffer[citizen].SetVisitplace(citizen, (ushort)0, unitID);
                        CitizenInfo citizenInfo = citizenManager.m_citizens.m_buffer[citizen].GetCitizenInfo(citizen);
                        if (citizenInfo != null && citizenManager.CreateCitizenInstance(out ushort citizenInstance, ref Singleton <SimulationManager> .instance.m_randomizer, citizenInfo, citizen))
                        {
                            citizenInfo.m_citizenAI.SetSource(citizenInstance, ref citizenManager.m_instances.m_buffer[(int)citizenInstance], sourceBuilding);
                            _SetTarget(citizenInstance, ref citizenManager.m_instances.m_buffer[(int)citizenInstance], targetBuilding, false);
                            citizenManager.m_citizens.m_buffer[citizen].CurrentLocation = Citizen.Location.Moving;
                            Singleton <StatisticsManager> .instance.Acquire <StatisticArray>(StatisticType.IncomingTourists).Acquire <StatisticInt32>((int)wealth, 3).Add(1);
                        }
                    }
                }
            }
        }
コード例 #16
0
 /// <summary>Gets a precise probability (in percent multiplied by 100) for a citizen with specified
 /// wealth to go on vacation on current day.</summary>
 /// <param name="wealth">The citizen's wealth.</param>
 /// <returns>The precise probability (in percent multiplied by 100) for the citizen to go on vacation
 /// on current day.</returns>
 public uint GetPreciseVacationChance(Citizen.Wealth wealth)
 {
     return(vacationChances[(int)wealth]);
 }
コード例 #17
0
        protected override VehicleInfo GetVehicleInfo(ushort instanceID, ref CitizenInstance citizenData, bool forceProbability, out VehicleInfo trailer)
        {
            Randomizer r = new Randomizer(citizenData.m_citizen);

            trailer = (VehicleInfo)null;
            if (citizenData.m_citizen == 0U)
            {
                return((VehicleInfo)null);
            }

            try
            {
                if (!Utils.GetOutsideConnections().Contains(citizenData.m_sourceBuilding))  // tourist is NOT at an outside connection
                {
                    Debug.LogWarning("Spawned only bikes for the toursit");
                    return(Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ItemClass.Level.Level2));  // bikes
                }
            }
            catch (Exception e)
            {
                Debug.Log("error when trying to spawn only bikes" + e);
            }

            // otherwise use original game code, they are just trying to drive to the city
            Citizen.Wealth wealthLevel = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel;
            int            num1;
            int            num2;
            int            num3;

            if (forceProbability || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None)
            {
                num1 = 100;
                num2 = 0;
                num3 = wealthLevel == Citizen.Wealth.Low ? 20 : wealthLevel == Citizen.Wealth.Medium ? 30 : 40;  // camper prob
            }
            else
            {
                num1 = 20;  // car prob
                num2 = 20;  // bike prob
                num3 = 0;
            }
            bool flag1 = r.Int32(100U) < num1;
            bool flag2 = r.Int32(100U) < num2;
            bool flag3 = r.Int32(100U) < num3;
            bool flag4;
            bool flag5;

            if (flag1)
            {
                int electricCarProbability = wealthLevel == Citizen.Wealth.Low ? 10 : wealthLevel == Citizen.Wealth.Medium ? 15 : 20;;
                flag4 = false;
                flag5 = r.Int32(100U) < electricCarProbability;
            }
            else
            {
                int taxiProbability = 20;
                flag4 = r.Int32(100U) < taxiProbability;
                flag5 = false;
            }
            ItemClass.Service    service    = ItemClass.Service.Residential;
            ItemClass.SubService subService = !flag5 ? ItemClass.SubService.ResidentialLow : ItemClass.SubService.ResidentialLowEco;
            if (!flag1 && flag4)
            {
                service    = ItemClass.Service.PublicTransport;
                subService = ItemClass.SubService.PublicTransportTaxi;
            }
            VehicleInfo randomVehicleInfo1;

            if (flag3)
            {
                Randomizer randomizer = r;
                randomVehicleInfo1 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, service, subService, ItemClass.Level.Level2);

                if (randomVehicleInfo1 == null || randomVehicleInfo1.m_vehicleAI is CarTrailerAI)
                {
                    trailer            = randomVehicleInfo1;
                    r                  = randomizer;
                    randomVehicleInfo1 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, service, subService, ItemClass.Level.Level1);
                }
            }
            else
            {
                randomVehicleInfo1 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, service, subService, ItemClass.Level.Level1);
            }
            VehicleInfo randomVehicleInfo2 = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref r, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ItemClass.Level.Level2);

            if (flag2 && randomVehicleInfo2 != null)  // Bikes
            {
                return(randomVehicleInfo2);
            }
            if ((flag1 || flag4) && randomVehicleInfo1 != null)
            {
                return(randomVehicleInfo1);
            }
            return((VehicleInfo)null);
        }
コード例 #18
0
        int failedTimes;         // how many times creation of tourists has failed


        public void Update()  // called every frame by UnityEngine
        {
            // create tourists every minute, perhaps choose at which outside connections to create them
            // PROBABLY NOT spawn vehicles at outside connections more frequently, with reference to in game time?
            // TODO: Space Elevator NOT CONSIDERED!!!!!
            Debug.Log("Update() called by unity engine");

            if (DataStorage.instance.modifierType == TourismIncreaseType.PopulationSizeRelated)
            {
                if (Utils.ComponentActionRequired)
                {
                    ushort[] carConnections   = Utils.GetConnectedOutsideConnections(ItemClass.SubService.None); // ItemClass.Service.Road
                    ushort[] trainConnections = Utils.GetConnectedOutsideConnections(ItemClass.SubService.PublicTransportTrain);
                    ushort[] planeConnections = Utils.GetConnectedOutsideConnections(ItemClass.SubService.PublicTransportPlane);
                    ushort[] shipConnections  = Utils.GetConnectedOutsideConnections(ItemClass.SubService.PublicTransportShip);

                    // use avg land value to calculate the probability (percentage) of different modes of transport
                    int avgLandValue = Singleton <DistrictManager> .instance.m_districts.m_buffer[0].GetLandValue();

                    int planeProb = planeConnections.Length == 0 ? 0 : 100 * avgLandValue / (avgLandValue + 40);
                    int trainProb = trainConnections.Length == 0 ? 0 : planeProb == 0 ? ((100 - planeProb) * avgLandValue / (avgLandValue + 10)) / 2 : ((100 - planeProb) * avgLandValue / (avgLandValue + 15)) / 2;  // ship and train prob, maybe just divide by 2 for each of these
                    int shipProb  = 0;

                    if (trainProb == 0)
                    {
                        if (!(shipConnections.Length == 0))  // no train connections, do have ship connections
                        {
                            shipProb = planeProb == 0 ? ((100 - planeProb) * avgLandValue / (avgLandValue + 10)) : ((100 - planeProb) * avgLandValue / (avgLandValue + 15));
                        }
                    }
                    else
                    {
                        if (!(shipConnections.Length == 0))
                        {
                            shipProb = trainProb;
                        }
                        else  // have train connections but no ship connections
                        {
                            trainProb *= 2;
                        }
                    }

                    int carProb = 100 - (planeProb + trainProb + shipProb);  // would be pretty low even when land value is quite low


                    //int trainProb = trainConnections.Length == 0 ? 0 : 100 - 100 * (avgLandValue / (avgLandValue + 25));  // TODO: maybe customize this
                    //int shipProb = shipConnections.Length == 0 ? 0 : (100 - trainProb) - (100 - trainProb) * (avgLandValue / (avgLandValue + 30));
                    //int planeProb = 100 - (trainProb + shipProb);


                    float amountOfTouristsThisMinute = DataStorage.instance.amountOfTouristsThisMinute;
                    int   amount = (int)Math.Truncate(amountOfTouristsThisMinute);
                    amount += (float)random.NextDouble() < amountOfTouristsThisMinute - amount ? 1 : 0;
                    amount += createTouristFailed;

                    Debug.Log(string.Format("amount of tourists to create decided: {0}", amount));

                    int i;  // for debug purpose
                    for (i = 0; i < amount; ++i)
                    {
                        // decide which type of outside connection they are going to spawn at, hence decide the wealth level accordingly
                        ItemClass.SubService typeOfTransport = ItemClass.SubService.PublicTransportPlane;
                        int prob = randomizer.Int32(1, 100);
                        if (prob < carProb)
                        {
                            typeOfTransport = ItemClass.SubService.None;
                        }
                        else if (prob < trainProb + shipProb)
                        {
                            typeOfTransport = randomizer.Int32(2) < 1 ? ItemClass.SubService.PublicTransportTrain : ItemClass.SubService.PublicTransportShip;
                        }
                        // else it's plane


                        // decide the wealth of the tourist based on which type of outside connection it will come from
                        Citizen.Wealth wealth = Citizen.Wealth.Low;
                        if (typeOfTransport == ItemClass.SubService.PublicTransportPlane)
                        {
                            int rand = randomizer.Int32(100);
                            wealth = rand > 18 ? Citizen.Wealth.High : Citizen.Wealth.Medium;
                        }
                        else if (typeOfTransport == ItemClass.SubService.PublicTransportTrain)
                        {
                            int rand = randomizer.Int32(100);
                            wealth = rand > 80 ? Citizen.Wealth.High : rand > 40 ? Citizen.Wealth.Medium : Citizen.Wealth.Low;
                        }
                        else if (typeOfTransport == ItemClass.SubService.PublicTransportShip)
                        {
                            int rand = randomizer.Int32(100);
                            wealth = rand > 70 ? Citizen.Wealth.High : rand > 25 ? Citizen.Wealth.Medium : Citizen.Wealth.Low;
                        }
                        else  // roads, ItemClass.SubService.None
                        {
                            int rand = randomizer.Int32(100);
                            wealth = rand > 70 ? Citizen.Wealth.High : rand > 30 ? Citizen.Wealth.Medium : Citizen.Wealth.Low;
                        }


                        // randomly choose which sourceBuilding aka the outside connection building the tourist is coming from
                        ushort sourceBuilding = 0;

                        try
                        {
                            switch (typeOfTransport)
                            {
                            case ItemClass.SubService.PublicTransportPlane:
                                sourceBuilding = planeConnections[randomizer.Int32(Convert.ToUInt32(planeConnections.Length))];
                                break;

                            case ItemClass.SubService.PublicTransportTrain:
                                sourceBuilding = trainConnections[randomizer.Int32(Convert.ToUInt32(trainConnections.Length))];
                                break;

                            case ItemClass.SubService.PublicTransportShip:
                                sourceBuilding = shipConnections[randomizer.Int32(Convert.ToUInt32(shipConnections.Length))];
                                break;

                            default:      // road connections
                                sourceBuilding = carConnections[randomizer.Int32(Convert.ToUInt32(carConnections.Length))];
                                break;
                            }
                            Debug.Log("will be spawned at this outside connection: " + sourceBuilding);
                        }
                        catch
                        {
                            Debug.Log("choosing connection building has thrown an exception");
                        }


                        TransferManager.TransferReason transferReason = NewTouristAI.GetRandomTransferReason(0);
                        TransferManager.TransferOffer  offer          = Utils.FindOffer(transferReason, true);
                        ushort targetBuilding = offer.Building;
                        Debug.Log(string.Format("component found building {0} for new tourist", targetBuilding));
                        uint unitID = buildingManager.m_buildings.m_buffer[targetBuilding].GetEmptyCitizenUnit(CitizenUnit.Flags.Visit);
                        int  family = Singleton <SimulationManager> .instance.m_randomizer.Int32(256U);

                        int age = Singleton <SimulationManager> .instance.m_randomizer.Int32(0, 240);

                        if (citizenManager.CreateCitizen(out uint citizen, age, family, ref Singleton <SimulationManager> .instance.m_randomizer))
                        {
                            citizenManager.m_citizens.m_buffer[citizen].m_flags    |= Citizen.Flags.Tourist;
                            citizenManager.m_citizens.m_buffer[citizen].m_flags    |= Citizen.Flags.MovingIn;
                            citizenManager.m_citizens.m_buffer[citizen].WealthLevel = wealth;
                            citizenManager.m_citizens.m_buffer[citizen].SetVisitplace(citizen, (ushort)0, unitID);
                            CitizenInfo citizenInfo = citizenManager.m_citizens.m_buffer[citizen].GetCitizenInfo(citizen);
                            if (citizenInfo != null && citizenManager.CreateCitizenInstance(out ushort citizenInstance, ref Singleton <SimulationManager> .instance.m_randomizer, citizenInfo, citizen))
                            {
                                citizenInfo.m_citizenAI.SetSource(citizenInstance, ref citizenManager.m_instances.m_buffer[(int)citizenInstance], sourceBuilding);
                                citizenInfo.m_citizenAI.SetTarget(citizenInstance, ref citizenManager.m_instances.m_buffer[(int)citizenInstance], targetBuilding, false);
                                citizenManager.m_citizens.m_buffer[citizen].CurrentLocation = Citizen.Location.Moving;
                                Singleton <StatisticsManager> .instance.Acquire <StatisticArray>(StatisticType.IncomingTourists).Acquire <StatisticInt32>((int)wealth, 3).Add(1);
                            }
                            else
                            {
                                failedTimes         += 1;
                                createTouristFailed += amount - i;
                                citizenManager.ReleaseCitizen(citizen);
                                break;
                            }
                        }
                        else
                        {
                            failedTimes         += 1;
                            createTouristFailed += amount - i;
                            break;
                        }
                    }
                    Debug.Log(i + " amount of tourists created in this loop");
                }
            }
        }
コード例 #19
0
        // CitizenAI
        public bool CustomStartPathFind(ushort instanceID, ref CitizenInstance citizenData, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo)
        {
            NetInfo.LaneType        laneType    = NetInfo.LaneType.Pedestrian;
            VehicleInfo.VehicleType vehicleType = VehicleInfo.VehicleType.None;
            if (vehicleInfo != null)
            {
                if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi)
                {
                    if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None && Singleton <DistrictManager> .instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u)
                    {
                        SimulationManager instance = Singleton <SimulationManager> .instance;
                        if (instance.m_isNightTime || instance.m_randomizer.Int32(2u) == 0)
                        {
                            laneType    |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle);
                            vehicleType |= vehicleInfo.m_vehicleType;
                        }
                    }
                }
                else
                {
                    laneType    |= NetInfo.LaneType.Vehicle;
                    vehicleType |= vehicleInfo.m_vehicleType;
                }
            }
            PathUnit.Position vehiclePosition = default(PathUnit.Position);
            ushort            parkedVehicle   = Singleton <CitizenManager> .instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)].m_parkedVehicle;

            if (parkedVehicle != 0)
            {
                Vector3 position = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[(int)parkedVehicle].m_position;
                PathManager.FindPathPosition(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, false, false, 32f, out vehiclePosition);
            }
            bool allowUnderground = (citizenData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None;

            PathUnit.Position startPosA;
            PathUnit.Position endPosA;
            if (this.FindPathPosition(instanceID, ref citizenData, startPos, laneType, vehicleType, allowUnderground, out startPosA) &&
                this.FindPathPosition(instanceID, ref citizenData, endPos, laneType, vehicleType, false, out endPosA))
            {
                // NON-STOCK CODE START //
                Citizen.Wealth wealthLevel = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel;

                byte districtId = Singleton <DistrictManager> .instance.GetDistrict(startPos);

                DistrictPolicies.Services servicePolicies = Singleton <DistrictManager> .instance.m_districts.m_buffer[(int)districtId].m_servicePolicies;
                int transportUsageProb = (servicePolicies & DistrictPolicies.Services.FreeTransport) != DistrictPolicies.Services.None ? FREE_TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel] : TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel];

                //bool mayUseTransport = false;
                if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None)                   // STOCK CODE
                {
                    if (vehicleInfo == null || (instanceID % 100) + 1 <= transportUsageProb)
                    {
                        laneType |= NetInfo.LaneType.PublicTransport;                         // STOCK CODE
                        //mayUseTransport = true;
                        //Log._Debug($"CustomCitizenAI: citizen {instanceID} can use public transport");
                    }
                }
                // NON-STOCK CODE END //
                PathUnit.Position position2 = default(PathUnit.Position);
                uint path;
                // NON-STOCK CODE START //
                ExtVehicleType?extVehicleType = null;
                if (vehicleInfo != null)
                {
                    extVehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicleInfo(vehicleInfo);
                }
                //Log._Debug($"CustomCitizenAI: citizen instance {instanceID}, id {citizenData.m_citizen}. {vehicleType} {extVehicleType} mayUseTransport={mayUseTransport} wealthLevel={wealthLevel}");
                bool res = false;
                if (Options.disableSomething5 || extVehicleType == null)
                {
                    // NON-STOCK CODE END //
                    res = Singleton <CustomPathManager> .instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false, false);
                }
                // NON-STOCK CODE START //
                else
                {
                    res = Singleton <CustomPathManager> .instance.CreatePath((ExtVehicleType)extVehicleType, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false);
                }
                // NON-STOCK CODE END //
                if (res)
                {
                    if (citizenData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(citizenData.m_path);
                    }
                    citizenData.m_path   = path;
                    citizenData.m_flags |= CitizenInstance.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
コード例 #20
0
        public VehicleInfo CustomGetVehicleInfo(ushort instanceID, ref CitizenInstance citizenData, bool forceCar, out VehicleInfo trailer)
        {
#if DEBUG
            bool citDebug  = GlobalConfig.Instance.Debug.CitizenId == 0 || GlobalConfig.Instance.Debug.CitizenId == citizenData.m_citizen;
            bool debug     = GlobalConfig.Instance.Debug.Switches[2] && citDebug;
            bool fineDebug = GlobalConfig.Instance.Debug.Switches[4] && citDebug;
#endif

            trailer = null;

            if (citizenData.m_citizen == 0u)
            {
                return(null);
            }

            // NON-STOCK CODE START
            bool forceTaxi = false;
#if BENCHMARK
            using (var bm = new Benchmark(null, "forceTaxi")) {
#endif
            if (Options.prohibitPocketCars)
            {
                if (ExtCitizenInstanceManager.Instance.ExtInstances[instanceID].pathMode == ExtPathMode.TaxiToTarget)
                {
                    forceTaxi = true;
                }
            }
#if BENCHMARK
        }
#endif
            // NON-STOCK CODE END

            Citizen.Wealth wealthLevel = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel;
            int carProb;
            int bikeProb;
            int taxiProb;
            // NON-STOCK CODE START
            if (forceTaxi)
            {
                carProb  = 0;
                bikeProb = 0;
                taxiProb = 100;
            }
            else
            // NON-STOCK CODE END
            if (forceCar || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None)
            {
                carProb  = 100;
                bikeProb = 0;
                taxiProb = 0;
            }
            else
            {
                carProb  = GetCarProbability();
                bikeProb = GetBikeProbability();
                taxiProb = GetTaxiProbability();
            }
            Randomizer randomizer = new Randomizer(citizenData.m_citizen);
            bool useCar           = randomizer.Int32(100u) < carProb;
            bool useBike          = !useCar && randomizer.Int32(100u) < bikeProb;
            bool useTaxi          = !useCar && !useBike && randomizer.Int32(100u) < taxiProb;
            bool useCamper        = false;
            bool useElectricCar   = false;
            if (useCar)
            {
                int camperProb = this.GetCamperProbability(wealthLevel);
                useCamper = randomizer.Int32(100u) < camperProb;

                if (!useCamper)
                {
                    int electricProb = GetElectricCarProbability(wealthLevel);
                    useElectricCar = randomizer.Int32(100u) < electricProb;
                }
            }

            ItemClass.Service service       = ItemClass.Service.Residential;
            ItemClass.SubService subService = useElectricCar ? ItemClass.SubService.ResidentialLowEco : ItemClass.SubService.ResidentialLow;
            if (useTaxi)
            {
                service    = ItemClass.Service.PublicTransport;
                subService = ItemClass.SubService.PublicTransportTaxi;
            }
            // NON-STOCK CODE START
            VehicleInfo carInfo = null;
#if BENCHMARK
            using (var bm = new Benchmark(null, "find-parked-vehicle")) {
#endif
            if (Options.prohibitPocketCars && useCar && !useTaxi)
            {
                ushort parkedVehicleId = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].m_parkedVehicle;
                if (parkedVehicleId != 0)
                {
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomTouristAI.CustomGetVehicleInfo({instanceID}): Citizen instance {instanceID} owns a parked vehicle {parkedVehicleId}. Reusing vehicle info.");
                    }
#endif
                    carInfo = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info;
                }
            }
#if BENCHMARK
        }
#endif

            if (carInfo == null && (useCar || useTaxi))
            {
                // NON-STOCK CODE END
                if (useCamper)
                {
                    Randomizer randomizer2 = randomizer;
                    carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref randomizer, service, subService, ItemClass.Level.Level2);

                    if (carInfo == null || carInfo.m_vehicleAI is CarTrailerAI)
                    {
                        trailer    = carInfo;
                        randomizer = randomizer2;
                        carInfo    = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref randomizer, service, subService, ItemClass.Level.Level1);
                    }
                }
                else
                {
                    carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref randomizer, service, subService, ItemClass.Level.Level1);
                }
            }

            if (useBike)
            {
                VehicleInfo bikeInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref randomizer, ItemClass.Service.Residential, ItemClass.SubService.ResidentialHigh, ItemClass.Level.Level2);

                if (bikeInfo != null)
                {
                    return(bikeInfo);
                }
            }

            if ((useCar || useTaxi) && carInfo != null)
            {
                return(carInfo);
            }
            return(null);
        }
コード例 #21
0
        private static float getWealthChanceValue(uint[] familyWithStudents, int quality)
        {
            Citizen.Wealth wealth = getFamilyWealth(familyWithStudents);
            float          chance = NO_CHANCE;

            switch (quality)
            {
            case 0:
                // Quality 0 homes are more for jokes, so better chance to move into a 0 quality than a 1 quality
                switch (wealth)
                {
                case Citizen.Wealth.High:
                    chance = QUALITY_MAX_CHANCE_VALUE * -0.5f;
                    break;

                case Citizen.Wealth.Medium:
                    chance = QUALITY_MAX_CHANCE_VALUE * 0.25f;
                    break;

                case Citizen.Wealth.Low:
                    chance = QUALITY_MAX_CHANCE_VALUE * 2f;
                    break;
                }
                break;

            case 1:
                // Quality 1's should be mainly for Low Wealth citizens, but not impossible for medium
                switch (wealth)
                {
                case Citizen.Wealth.High:
                    chance = QUALITY_MAX_CHANCE_VALUE * -1f;
                    break;

                case Citizen.Wealth.Medium:
                    chance = QUALITY_MAX_CHANCE_VALUE * -0.1f;
                    break;

                case Citizen.Wealth.Low:
                    chance = QUALITY_MAX_CHANCE_VALUE * 1.5f;
                    break;
                }
                break;

            case 2:
                // Quality 2's should be for both medium and low wealth citizens
                switch (wealth)
                {
                case Citizen.Wealth.High:
                    chance = QUALITY_MAX_CHANCE_VALUE * -0.5f;
                    break;

                case Citizen.Wealth.Medium:
                    chance = QUALITY_MAX_CHANCE_VALUE * 0.5f;
                    break;

                case Citizen.Wealth.Low:
                    chance = QUALITY_MAX_CHANCE_VALUE * 0.5f;
                    break;
                }
                break;

            case 3:
                // Quality 3 are ideal for medium wealth citizens, but possible for all
                switch (wealth)
                {
                case Citizen.Wealth.High:
                    chance = QUALITY_MAX_CHANCE_VALUE * 0.2f;
                    break;

                case Citizen.Wealth.Medium:
                    chance = QUALITY_MAX_CHANCE_VALUE * 1f;
                    break;

                case Citizen.Wealth.Low:
                    chance = QUALITY_MAX_CHANCE_VALUE * 0.2f;
                    break;
                }
                break;

            case 4:
                // Quality 4's start to become hard for low wealth citizens and more suited for medium to high wealth citizens
                switch (wealth)
                {
                case Citizen.Wealth.High:
                    chance = QUALITY_MAX_CHANCE_VALUE * 0.5f;;
                    break;

                case Citizen.Wealth.Medium:
                    chance = QUALITY_MAX_CHANCE_VALUE * 0.5f;
                    break;

                case Citizen.Wealth.Low:
                    chance = QUALITY_MAX_CHANCE_VALUE * -1f;
                    break;
                }
                break;

            case 5:
                // Quality 5's are best suited for high wealth citizens, but some medium wealth citizens can afford it
                switch (wealth)
                {
                case Citizen.Wealth.High:
                    chance = QUALITY_MAX_CHANCE_VALUE * 1f;
                    break;

                case Citizen.Wealth.Medium:
                    chance = 0.0f;
                    break;

                case Citizen.Wealth.Low:
                    chance = QUALITY_MAX_CHANCE_VALUE * -2f;
                    break;
                }
                break;
            }

            Logger.logInfo(LOG_CHANCES, "MoveInProbabilityHelper.getQualityLevelChanceValue -- Wealth Chance Value: {0} -- Family Wealth: {1} -- Building Quality: {2}", chance, wealth, quality);
            return(chance);
        }
コード例 #22
0
 private int GetCamperProbability(Citizen.Wealth wealth)
 {
     Log._DebugOnlyError("CustomTouristAI.GetCamperProbability called!");
     return(20);
 }
コード例 #23
0
        public VehicleInfo CustomGetVehicleInfo(ushort instanceId,
                                                ref CitizenInstance citizenData,
                                                bool forceCar,
                                                out VehicleInfo trailer)
        {
#if DEBUG
            bool citizenDebug = (DebugSettings.CitizenInstanceId == 0 ||
                                 DebugSettings.CitizenInstanceId == instanceId) &&
                                (DebugSettings.CitizenId == 0 ||
                                 DebugSettings.CitizenId == citizenData.m_citizen) &&
                                (DebugSettings.SourceBuildingId == 0 ||
                                 DebugSettings.SourceBuildingId == citizenData.m_sourceBuilding) &&
                                (DebugSettings.TargetBuildingId == 0 ||
                                 DebugSettings.TargetBuildingId == citizenData.m_targetBuilding);
            bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug;
#else
            var logParkingAi = false;
#endif

            trailer = null;

            if (citizenData.m_citizen == 0u)
            {
                return(null);
            }

            // NON-STOCK CODE START
            bool forceTaxi = false;
            if (Options.parkingAI)
            {
                if (ExtCitizenInstanceManager.Instance.ExtInstances[instanceId].pathMode == ExtPathMode.TaxiToTarget)
                {
                    forceTaxi = true;
                }
            }

            // NON-STOCK CODE END
            Citizen.Wealth wealthLevel = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel;
            int            carProb;
            int            bikeProb;
            int            taxiProb;

            // NON-STOCK CODE START
            if (forceTaxi)
            {
                carProb  = 0;
                bikeProb = 0;
                taxiProb = 100;
            }
            else   // NON-STOCK CODE END
            if (forceCar || (citizenData.m_flags & CitizenInstance.Flags.BorrowCar) != CitizenInstance.Flags.None)
            {
                carProb  = 100;
                bikeProb = 0;
                taxiProb = 0;
            }
            else
            {
                carProb  = GetCarProbability();
                bikeProb = GetBikeProbability();
                taxiProb = GetTaxiProbability();
            }

            Randomizer randomizer     = new Randomizer(citizenData.m_citizen);
            bool       useCar         = randomizer.Int32(100u) < carProb;
            bool       useBike        = !useCar && randomizer.Int32(100u) < bikeProb;
            bool       useTaxi        = !useCar && !useBike && randomizer.Int32(100u) < taxiProb;
            bool       useCamper      = false;
            bool       useElectricCar = false;

            if (useCar)
            {
                int camperProb = GetCamperProbability(wealthLevel);
                useCamper = randomizer.Int32(100u) < camperProb;

                if (!useCamper)
                {
                    int electricProb = GetElectricCarProbability(wealthLevel);
                    useElectricCar = randomizer.Int32(100u) < electricProb;
                }
            }

            ItemClass.Service    service    = ItemClass.Service.Residential;
            ItemClass.SubService subService = useElectricCar
                                 ? ItemClass.SubService.ResidentialLowEco
                                 : ItemClass.SubService.ResidentialLow;
            if (useTaxi)
            {
                service    = ItemClass.Service.PublicTransport;
                subService = ItemClass.SubService.PublicTransportTaxi;
            }

            // NON-STOCK CODE START
            VehicleInfo carInfo = null;
            if (Options.parkingAI && useCar && !useTaxi)
            {
                ushort parkedVehicleId = Singleton <CitizenManager>
                                         .instance.m_citizens.m_buffer[citizenData.m_citizen]
                                         .m_parkedVehicle;
                if (parkedVehicleId != 0)
                {
                    Log._DebugIf(
                        logParkingAi,
                        () => $"CustomTouristAI.CustomGetVehicleInfo({instanceId}): " +
                        $"Citizen instance {instanceId} owns a parked vehicle {parkedVehicleId}. " +
                        $"Reusing vehicle info.");
                    carInfo = Singleton <VehicleManager>
                              .instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info;
                }
            }

            if (carInfo == null && (useCar || useTaxi))
            {
                // NON-STOCK CODE END
                if (useCamper)
                {
                    Randomizer randomizer2 = randomizer;
                    carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(
                        ref randomizer,
                        service,
                        subService,
                        ItemClass.Level.Level2);

                    if (carInfo == null || carInfo.m_vehicleAI is CarTrailerAI)
                    {
                        trailer    = carInfo;
                        randomizer = randomizer2;
                        carInfo    = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(
                            ref randomizer,
                            service,
                            subService,
                            ItemClass.Level.Level1);
                    }
                }
                else
                {
                    carInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(
                        ref randomizer,
                        service,
                        subService,
                        ItemClass.Level.Level1);
                }
            }

            if (useBike)
            {
                VehicleInfo bikeInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(
                    ref randomizer,
                    ItemClass.Service.Residential,
                    ItemClass.SubService.ResidentialHigh,
                    ItemClass.Level.Level2);

                if (bikeInfo != null)
                {
                    return(bikeInfo);
                }
            }

            if ((useCar || useTaxi) && carInfo != null)
            {
                return(carInfo);
            }

            return(null);
        }
 private int GetElectricCarProbability(Citizen.Wealth wealth)
 {
     Log.Error("CustomTouristAI.GetElectricCarProbability called!");
     return(20);
 }
        // CitizenAI
        public bool CustomStartPathFind(ushort instanceID, ref CitizenInstance citizenData, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo)
        {
            CitizenManager citMan = Singleton <CitizenManager> .instance;

            if (citMan.m_citizens.m_buffer[citizenData.m_citizen].CurrentLocation == Citizen.Location.Home)
            {
                currentTransportMode[instanceID] = TransportMode.None;                 // reset currently used transport mode at home
            }
            SimulationManager simManager = Singleton <SimulationManager> .instance;

            Citizen.Wealth wealthLevel  = citMan.m_citizens.m_buffer[citizenData.m_citizen].WealthLevel;
            bool           couldUseTaxi = false;   // could cim use a taxi if it was not forbidden because of randomization?
            bool           couldUseCar  = false;
            bool           couldUseBike = false;
            bool           wouldAffordTaxiVoluntarily = false;

            bool randomParking = false;

            if (vehicleInfo != null)
            {
                if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi)
                {
                    if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None &&
                        Singleton <DistrictManager> .instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u)
                    {
                        couldUseTaxi = true;

                        if (currentTransportMode[instanceID] == TransportMode.Taxi || (currentTransportMode[instanceID] == TransportMode.None &&
                                                                                       ((simManager.m_isNightTime && simManager.m_randomizer.Int32(100) < NIGHT_TAXI_USAGE_PROBABILITY[(int)wealthLevel]) ||
                                                                                        (!simManager.m_isNightTime && simManager.m_randomizer.Int32(100) < DAY_TAXI_USAGE_PROBABILITY[(int)wealthLevel]))))
                        {
                            wouldAffordTaxiVoluntarily = true;                             // NON-STOCK CODE
                        }
                    }
                }
                else
                {
                    // NON-STOCK CODE START
                    if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
                    {
                        couldUseBike = true;
                    }
                    else if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Car)
                    {
                        couldUseCar = true;
                    }
                    // NON-STOCK CODE END

                    if (citizenData.m_targetBuilding != 0 && Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)citizenData.m_targetBuilding].Info.m_class.m_service > ItemClass.Service.Office)
                    {
                        randomParking = true;
                    }
                }
            }

            byte districtId = Singleton <DistrictManager> .instance.GetDistrict(startPos);

            DistrictPolicies.Services servicePolicies = Singleton <DistrictManager> .instance.m_districts.m_buffer[(int)districtId].m_servicePolicies;
            int transportUsageProb = (servicePolicies & DistrictPolicies.Services.FreeTransport) != DistrictPolicies.Services.None ? FREE_TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel] : TRANSPORT_USAGE_PROBABILITY[(int)wealthLevel];

            bool useTaxi            = false;
            bool useBike            = false;
            bool useCar             = false;
            bool usePublicTransport = false;

            if ((citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None)               // STOCK CODE
            {
                if (currentTransportMode[instanceID] == TransportMode.PublicTransport || useTaxi ||
                    (currentTransportMode[instanceID] == TransportMode.None && simManager.m_randomizer.Int32(100) < transportUsageProb))
                {
                    usePublicTransport = true;
                }
            }

            ushort parkedVehicle     = Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenData.m_citizen].m_parkedVehicle;
            bool   couldUseParkedCar = false;           // cims are not allowed to use pocket cars (unless we have no choice)

            PathUnit.Position vehiclePosition = default(PathUnit.Position);
            if (parkedVehicle != 0)
            {
                Vector3 position = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[(int)parkedVehicle].m_position;
                if (PathManager.FindPathPosition(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, false, false, 32f, out vehiclePosition))
                {
                    couldUseParkedCar = true;
                }
            }

            if (couldUseBike)
            {
                // everyone who has a bike may use it
                useBike = true;
            }

            if (!usePublicTransport)
            {
                if (couldUseParkedCar && currentTransportMode[instanceID] == TransportMode.Car)
                {
                    useCar = true;
                }
                else if ((wouldAffordTaxiVoluntarily && currentTransportMode[instanceID] == TransportMode.Taxi) || couldUseTaxi)
                {
                    useTaxi = true;
                }
                else if (couldUseCar)
                {
                    // pocket car fallback
                    useCar = true;
                }
            }

            ExtVehicleType extVehicleType = ExtVehicleType.None;

            NetInfo.LaneType        laneType    = NetInfo.LaneType.Pedestrian;
            VehicleInfo.VehicleType vehicleType = VehicleInfo.VehicleType.None;

            if (usePublicTransport)
            {
                currentTransportMode[instanceID] = TransportMode.PublicTransport;
                laneType       |= NetInfo.LaneType.PublicTransport;
                extVehicleType |= ExtVehicleType.PublicTransport;
            }

            if (useBike && vehicleInfo != null)
            {
                laneType       |= NetInfo.LaneType.Vehicle;
                vehicleType    |= vehicleInfo.m_vehicleType;
                extVehicleType |= ExtVehicleType.Bicycle;
            }

            if (useTaxi && vehicleInfo != null)
            {
                currentTransportMode[instanceID] = TransportMode.Taxi;
                laneType       |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle);
                vehicleType    |= vehicleInfo.m_vehicleType;
                extVehicleType |= ExtVehicleType.Taxi;
            }

            if (useCar && vehicleInfo != null)
            {
                currentTransportMode[instanceID] = TransportMode.Car;
                laneType       |= NetInfo.LaneType.Vehicle;
                vehicleType    |= vehicleInfo.m_vehicleType;
                extVehicleType |= ExtVehicleType.PassengerCar;
            }

            //Log._Debug($"Citizen {instanceID}: usePublicTransport={usePublicTransport} useCar={useCar} useTaxi={useTaxi} useBike={useBike} vehicleInfo.vehicleType={vehicleInfo?.m_vehicleType} laneType={laneType} vehicleType={vehicleType} extVehicleType={extVehicleType}");

            bool allowUnderground = (citizenData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None;

            PathUnit.Position startPosA;
            PathUnit.Position endPosA;
            if (this.FindPathPosition(instanceID, ref citizenData, startPos, laneType, vehicleType, allowUnderground, out startPosA) &&
                this.FindPathPosition(instanceID, ref citizenData, endPos, laneType, vehicleType, false, out endPosA))
            {
                PathUnit.Position position2 = default(PathUnit.Position);
                uint path;
#if DEBUG
                //Log._Debug($"CustomCitizenAI: citizen instance {instanceID}, id {citizenData.m_citizen}. vehicleType={vehicleType} laneType={laneType} extVehicleType={extVehicleType} usePublicTransport={usePublicTransport} useTaxi={useTaxi} useBike={useBike} useCar={useCar} wealthLevel={wealthLevel}");
#endif
                // NON-STOCK CODE END //
                if (Singleton <CustomPathManager> .instance.CreatePath(false, (ExtVehicleType)extVehicleType, null, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, position2, endPosA, position2, vehiclePosition, laneType, vehicleType, 20000f, false, false, false, false, randomParking))
                {
                    if (citizenData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(citizenData.m_path);
                    }
                    citizenData.m_path   = path;
                    citizenData.m_flags |= CitizenInstance.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
コード例 #26
0
        protected override bool CitizenRegistered(uint citizenID, ref Citizen person)
        {
            bool  canAttend = true;
            float maxSpend  = 0f;

            if (m_eventData.m_userEvent)
            {
                SimulationManager simulationManager = Singleton <SimulationManager> .instance;
                Citizen.Wealth    wealth            = person.WealthLevel;

                switch (wealth)
                {
                case Citizen.Wealth.Low:
                    maxSpend = 30f + simulationManager.m_randomizer.Int32(60);
                    break;

                case Citizen.Wealth.Medium:
                    maxSpend = 80f + simulationManager.m_randomizer.Int32(80);
                    break;

                case Citizen.Wealth.High:
                    maxSpend = 120f + simulationManager.m_randomizer.Int32(320);
                    break;
                }

                if (m_eventCosts != null)
                {
                    maxSpend -= m_eventCosts._entry;

                    canAttend = maxSpend > 0;

                    if (m_eventData.m_incentives != null && m_eventData.m_incentives.Length > 0)
                    {
                        int    startFrom = simulationManager.m_randomizer.Int32(0, m_eventData.m_incentives.Length - 1);
                        int    index     = startFrom;
                        string buying    = m_eventData.m_eventName + " ";

                        do
                        {
                            CityEventDataIncentives incentive = m_eventData.m_incentives[index];

                            if (incentive.boughtItems < incentive.itemCount && maxSpend - incentive.returnCost >= 0)
                            {
                                maxSpend -= incentive.returnCost;
                                ++incentive.boughtItems;

                                buying += "[" + incentive.name + " (" + incentive.boughtItems + "/" + incentive.itemCount + ")] ";
                            }

                            if (++index >= m_eventData.m_incentives.Length)
                            {
                                index = 0;
                            }
                        } while (index != startFrom);

                        CimTools.CimToolsHandler.CimToolBase.DetailedLogger.Log(buying);
                    }
                }
            }

            if (!canAttend)
            {
                CimTools.CimToolsHandler.CimToolBase.DetailedLogger.Log("Cim is too poor to attend the event :(");
            }

            return(canAttend);
        }
コード例 #27
0
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            bool canGo = false;

            if (m_eventChances != null && m_eventData.m_registeredCitizens < GetCapacity())
            {
                canGo = true;

                Citizen.Wealth    _citizenWealth    = person.WealthLevel;
                Citizen.Education _citizenEducation = person.EducationLevel;
                Citizen.Gender    _citizenGender    = Citizen.GetGender(citizenID);
                Citizen.Happiness _citizenHappiness = Citizen.GetHappinessLevel(Citizen.GetHappiness(person.m_health, person.m_wellbeing));
                Citizen.Wellbeing _citizenWellbeing = Citizen.GetWellbeingLevel(_citizenEducation, person.m_wellbeing);
                Citizen.AgeGroup  _citizenAgeGroup  = Citizen.GetAgeGroup(person.Age);

                float percentageChange = GetAdjustedChancePercentage();
                int   randomPercentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100U);

                switch (_citizenWealth)
                {
                case Citizen.Wealth.Low:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._lowWealth, percentageChange);
                    break;

                case Citizen.Wealth.Medium:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._mediumWealth, percentageChange);
                    break;

                case Citizen.Wealth.High:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._highWealth, percentageChange);
                    break;
                }

                randomPercentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100U);

                switch (_citizenEducation)
                {
                case Citizen.Education.Uneducated:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._uneducated, percentageChange);
                    break;

                case Citizen.Education.OneSchool:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._oneSchool, percentageChange);
                    break;

                case Citizen.Education.TwoSchools:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._twoSchools, percentageChange);
                    break;

                case Citizen.Education.ThreeSchools:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._threeSchools, percentageChange);
                    break;
                }

                randomPercentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100U);

                switch (_citizenGender)
                {
                case Citizen.Gender.Female:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._females, percentageChange);
                    break;

                case Citizen.Gender.Male:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._males, percentageChange);
                    break;
                }

                randomPercentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100U);

                switch (_citizenHappiness)
                {
                case Citizen.Happiness.Bad:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._badHappiness, percentageChange);
                    break;

                case Citizen.Happiness.Poor:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._poorHappiness, percentageChange);
                    break;

                case Citizen.Happiness.Good:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._goodHappiness, percentageChange);
                    break;

                case Citizen.Happiness.Excellent:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._excellentHappiness, percentageChange);
                    break;

                case Citizen.Happiness.Suberb:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._superbHappiness, percentageChange);
                    break;
                }

                randomPercentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100U);

                switch (_citizenWellbeing)
                {
                case Citizen.Wellbeing.VeryUnhappy:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._veryUnhappyWellbeing, percentageChange);
                    break;

                case Citizen.Wellbeing.Unhappy:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._unhappyWellbeing, percentageChange);
                    break;

                case Citizen.Wellbeing.Satisfied:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._satisfiedWellbeing, percentageChange);
                    break;

                case Citizen.Wellbeing.Happy:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._happyWellbeing, percentageChange);
                    break;

                case Citizen.Wellbeing.VeryHappy:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._veryHappyWellbeing, percentageChange);
                    break;
                }

                randomPercentage = Singleton <SimulationManager> .instance.m_randomizer.Int32(100U);

                switch (_citizenAgeGroup)
                {
                case Citizen.AgeGroup.Child:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._children, percentageChange);
                    break;

                case Citizen.AgeGroup.Teen:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._teens, percentageChange);
                    break;

                case Citizen.AgeGroup.Young:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._youngAdults, percentageChange);
                    break;

                case Citizen.AgeGroup.Adult:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._adults, percentageChange);
                    break;

                case Citizen.AgeGroup.Senior:
                    canGo = canGo && randomPercentage < Adjust(m_eventChances._seniors, percentageChange);
                    break;
                }

                CimTools.CimToolsHandler.CimToolBase.DetailedLogger.Log(
                    (canGo ? "[Can Go]" : "[Ignoring]") +
                    " Citizen " + citizenID + " for " + m_eventData.m_eventName + "\n\t" +
                    _citizenWealth.ToString() + ", " + _citizenEducation.ToString() + ", " + _citizenGender.ToString() + ", " +
                    _citizenHappiness.ToString() + ", " + _citizenWellbeing.ToString() + ", " + _citizenAgeGroup.ToString());
            }

            return(canGo);
        }
コード例 #28
0
        internal static void EnsureCitizenUnits(ref PrivateBuildingAI __instance, ushort buildingID, ref Building data, int homeCount, int workCount, int visitCount, int studentCount)
        {
            int totalWorkCount  = (workCount + 4) / 5;
            int totalVisitCount = (visitCount + 4) / 5;
            int totalHomeCount  = homeCount;

            int[] workersRequired = new int[] { 0, 0, 0, 0 };


            if ((data.m_flags & (Building.Flags.Abandoned | Building.Flags.BurnedDown)) == Building.Flags.None)
            {
                Citizen.Wealth wealthLevel = Citizen.GetWealthLevel(__instance.m_info.m_class.m_level);
                uint           num         = 0u;
                uint           num2        = data.m_citizenUnits;
                int            num3        = 0;
                while (num2 != 0u)
                {
                    CitizenUnit.Flags flags = citizenUnitArray[(int)((UIntPtr)num2)].m_flags;
                    if ((ushort)(flags & CitizenUnit.Flags.Home) != 0)
                    {
                        citizenUnitArray[(int)((UIntPtr)num2)].SetWealthLevel(wealthLevel);
                        homeCount--;
                    }
                    if ((ushort)(flags & CitizenUnit.Flags.Work) != 0)
                    {
                        workCount -= 5;
                        for (int i = 0; i < 5; i++)
                        {
                            uint citizen = citizenUnitArray[(int)((UIntPtr)num2)].GetCitizen(i);
                            if (citizen != 0u)
                            {
                                // Tick off education to see what is there
                                workersRequired[(int)citizenArray[(int)((UIntPtr)citizen)].EducationLevel]--;
                            }
                        }
                    }
                    if ((ushort)(flags & CitizenUnit.Flags.Visit) != 0)
                    {
                        visitCount -= 5;
                    }
                    if ((ushort)(flags & CitizenUnit.Flags.Student) != 0)
                    {
                        studentCount -= 5;
                    }
                    num  = num2;
                    num2 = citizenUnitArray[(int)((UIntPtr)num2)].m_nextUnit;
                    if (++num3 > 524288)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                } // end while

                /*
                 *              homeCount = Mathf.Max(0, homeCount);
                 *              workCount = Mathf.Max(0, workCount);
                 */
                visitCount   = Mathf.Max(0, visitCount);
                studentCount = Mathf.Max(0, studentCount);

                if (homeCount > 0 || workCount > 0 || visitCount > 0 || studentCount > 0)
                {
                    uint num4 = 0u;
                    if (citizenManager.CreateUnits(out num4, ref Singleton <SimulationManager> .instance.m_randomizer, buildingID, 0, homeCount, workCount, visitCount, 0, studentCount))
                    {
                        if (num != 0u)
                        {
                            citizenUnitArray[(int)((UIntPtr)num)].m_nextUnit = num4;
                        }
                        else
                        {
                            data.m_citizenUnits = num4;
                        }
                    }
                }


                // Stop incoming offers to get HandleWorkers() to start fresh
                TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                offer.Building = buildingID;
                Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker0, offer);

                Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker1, offer);

                Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker2, offer);

                Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker3, offer);

                int             worker0 = 0;
                int             worker1 = 0;
                int             worker2 = 0;
                int             worker3 = 0;
                ItemClass.Level level   = ((PrivateBuildingAI)data.Info.GetAI()).m_info.m_class.m_level;
                ((PrivateBuildingAI)data.Info.GetAI()).CalculateWorkplaceCount(level, new Randomizer((int)buildingID), data.Width, data.Length,
                                                                               out worker0, out worker1, out worker2, out worker3);

                // Update the workers required once figuring out how many are needed by the new building
                workersRequired[0] += worker0;
                workersRequired[1] += worker1;
                workersRequired[2] += worker2;
                workersRequired[3] += worker3;

                if (workCount < 0)
                {
                    RemoveWorkerBuilding(buildingID, ref data, totalWorkCount);
                }
                else if (homeCount < 0)
                {
                    RemoveHouseHold(buildingID, ref data, totalHomeCount);
                }

                /*
                 *  if (visitCount < 0)
                 *  {
                 *      RemoveVisitorsBuilding(buildingID, ref data, totalVisitCount);
                 *  }
                 */
                PromoteWorkers(buildingID, ref data, ref workersRequired);
                // Do nothing for students
            } // end if good building
        }     // end EnsureCitizenUnits
コード例 #29
0
 /// <summary>Gets a precise probability (in percent multiplied by 100) for a citizen with specified
 /// wealth to go on vacation on current day.</summary>
 /// <param name="wealth">The citizen's wealth.</param>
 /// <returns>The precise probability (in percent multiplied by 100) for the citizen to go on vacation
 /// on current day.</returns>
 public uint GetPreciseVacationChance(Citizen.Wealth wealth) => vacationChances[(int)wealth];