示例#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
 /// <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;
示例#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 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);
示例#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);
        }
        public override bool CitizenCanGo(uint citizenID, ref Citizen person)
        {
            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(_citizenAge >= Citizen.AgeGroup.Teen &&
                   _citizenHappiness >= Citizen.Happiness.Good &&
                   _citizenWellbeing >= Citizen.Wellbeing.Unhappy);
        }
        /// <summary>
        /// 以教育背景计算对政党的兴趣度
        /// </summary>
        /// <param name="education"></param>
        /// <returns></returns>
        private ushort GetFromEducationLevel(Citizen.Education education)
        {
            /*
             * 根据ResidentAICitizenUnitSimulationStepPatch.GetVoteTickets()方法
             * 似乎所有政党的WinChance加起来应该是800
             * 而同一个类里的GetVoteChance()也曾把Politics.education[i,j]的参数乘2
             * 这地方要问一下作者...
             */
            ushort val = (ushort)(this.partyInterestData.EducationLevel[(int)education] << 1);

            return(val);
        }
示例#9
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);
        }
示例#10
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);
        }
示例#11
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);
        }
        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);
        }
示例#13
0
        private static bool CheckEducation(Citizen.Education education, CityEventAttendees attendees, float randomPercentage)
        {
            switch (education)
            {
            case Citizen.Education.Uneducated:
                return(randomPercentage < attendees.Uneducated);

            case Citizen.Education.OneSchool:
                return(randomPercentage < attendees.OneSchool);

            case Citizen.Education.TwoSchools:
                return(randomPercentage < attendees.TwoSchools);

            case Citizen.Education.ThreeSchools:
                return(randomPercentage < attendees.ThreeSchools);
            }

            return(false);
        }
示例#14
0
        public static string GetEducationText(Citizen.Education education)
        {
            switch (education)
            {
            case Citizen.Education.OneSchool:
                return("Elementary");

            case Citizen.Education.TwoSchools:
                return("High School");

            case Citizen.Education.ThreeSchools:
                return("University");

            case Citizen.Education.Uneducated:
                return("Uneducated");

            default:
                return("Error");
            }
        }
示例#15
0
        public void GetCitizenIncome(Citizen citizen, int level, ref int income, ref int tourists)
        {
            if ((citizen.m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None && !citizen.Dead)
            {
                bool tourist = ((citizen.m_flags & Citizen.Flags.Tourist) != Citizen.Flags.None);
                int  age     = citizen.Age;
                Citizen.Education educationLevel = citizen.EducationLevel;
                Citizen.AgePhase  agePhase       = Citizen.GetAgePhase(educationLevel, age);
                int unemployed = citizen.Unemployed;
                var result     = 0;

                if (citizen.Sick && level < 3 && !tourist)
                {
                    result -= 50;
                }
                if (unemployed == 0 || tourist)
                {
                    switch (agePhase)
                    {
                    case Citizen.AgePhase.Child:
                        result += 20;
                        break;

                    case Citizen.AgePhase.Teen0:
                        result += 30;
                        break;

                    case Citizen.AgePhase.Teen1:
                        result += 40;
                        break;

                    case Citizen.AgePhase.Young0:
                        result += 50;
                        break;

                    case Citizen.AgePhase.Young1:
                        result += 60;
                        break;

                    case Citizen.AgePhase.Young2:
                        result += 70;
                        break;

                    case Citizen.AgePhase.Adult0:
                        result += 50;
                        break;

                    case Citizen.AgePhase.Adult1:
                        result += 60;
                        break;

                    case Citizen.AgePhase.Adult2:
                        result += 70;
                        break;

                    case Citizen.AgePhase.Adult3:
                        result += 80;
                        break;

                    case Citizen.AgePhase.Senior0:
                        result += 50;
                        break;

                    case Citizen.AgePhase.Senior1:
                        result += 60;
                        break;

                    case Citizen.AgePhase.Senior2:
                        result += 70;
                        break;

                    case Citizen.AgePhase.Senior3:
                        result += 80;
                        break;
                    }
                }

                if (tourist || level > 2)
                {
                }
                else if (level == 2)
                {
                    result += Math.Max(-10, citizen.m_health + citizen.m_wellbeing - 140);
                }
                else if (level == 1)
                {
                    result += Math.Max(-20, citizen.m_health + citizen.m_wellbeing - 145);
                }
                else
                {
                    result += Math.Max(-44, citizen.m_health + citizen.m_wellbeing - 155);
                }

                if (tourist)
                {
                    tourists += result;
                }
                else
                {
                    income += result;
                }
            }
        }
示例#16
0
        /// <summary>
        /// Gets the education level of the new citizen based on their <paramref name="age" />.
        /// </summary>
        /// <param name="age">The citizen's age as raw value (0-255).</param>
        /// <param name="currentEducation">The current value of the citizen's education.</param>
        /// <returns>The education level of the new citizen with the specified age.</returns>
        public Citizen.Education GetEducation(int age, Citizen.Education currentEducation)
        {
            if (!config.UseSlowAging)
            {
                return(currentEducation);
            }

            var randomValue = randomizer.GetRandomValue(100u);

            // Age:
            // 0-14    -> child
            // 15-44   -> teen
            // 45-89   -> young
            // 90-179  -> adult
            // 180-255 -> senior
            if (age < 10)
            {
                // little children
                return(Citizen.Education.Uneducated);
            }
            else if (age < 40)
            {
                // children and most of the teens
                return(randomValue <= 25 ? Citizen.Education.Uneducated : Citizen.Education.OneSchool);
            }
            else if (age < 80)
            {
                // few teens and most of the young adults
                if (randomValue < 50)
                {
                    return(Citizen.Education.Uneducated);
                }
                else if (randomValue < 90)
                {
                    return(Citizen.Education.OneSchool);
                }
                else
                {
                    return(Citizen.Education.TwoSchools);
                }
            }
            else
            {
                // few young adults, adults and seniors
                if (randomValue < 50)
                {
                    return(Citizen.Education.Uneducated);
                }
                else if (randomValue < 80)
                {
                    return(Citizen.Education.OneSchool);
                }
                else if (randomValue < 90)
                {
                    return(Citizen.Education.TwoSchools);
                }
                else
                {
                    return(Citizen.Education.ThreeSchools);
                }
            }
        }
示例#17
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);
        }
        /// <summary>
        /// Method called by OutsideConnectionAI.StartConnectionTransferImpl Transpiler insertion.
        /// Randomises (within parameters) age and education levels of immigrants.
        /// All variables are local variables within OutsideConnectionAI.StartConnectionTransferImpl.
        /// </summary>
        /// <param name="i">Loop counter (for loop containing method call)</param>
        /// <param name="education">Education level input (StartConnectionTransferImpl local variable)</param>
        /// <param name="ageArray">Array of acceptible ages (from mod DataStore); placed on stack in advance via Transpiler insertion</param>
        /// <param name="childrenAgeMax">Maximum child immigrant age; placed on stack in advance via Transpiler insertion </param>
        /// <param name="childrenAgeMin">Minimum child immigrant age; placed on stack in advance via Transpiler insertion</param>
        /// <param name="minAdultAge">Minimum adult immigrant age; placed on stack in advance via Transpiler insertion</param>
        /// <param name="resultEducation">Resultant education level for immigrant after mod calculations (StartConnectionTransferImpl local variable 'education2')</param>
        /// <param name="resultAge">Resultant age level for immigrant after mod calculations (StartConnectionTransferImpl local variable 'age')</param>
        public static void RandomizeImmigrants(int i, Citizen.Education education, int[] ageArray, ref int childrenAgeMax, ref int childrenAgeMin, ref int minAdultAge, out Citizen.Education resultEducation, out int resultAge)
        {
            // Minimum and maximum ages.
            int min = ageArray[0];
            int max = ageArray[1];

            // We start inside an i loop.
            // i is is the family member number for this incoming family.  0 is primary adult, 1 is secondary adults, and after that are children.
            if (i == 1)
            {
                // Age of second adult - shouldn't be too far from the first. Just because.
                min = Math.Max(minAdultAge - 20, DataStore.incomingAdultAge[0]);
                max = Math.Min(minAdultAge + 20, DataStore.incomingAdultAge[1]);
            }
            else if (i >= 2)
            {
                // Children.
                min = childrenAgeMin;
                max = childrenAgeMax;
            }

            // Calculate actual age randomly between minumum and maxiumum.
            resultAge = Singleton <SimulationManager> .instance.m_randomizer.Int32(min, max);

            // Adust age brackets for subsequent family members.
            if (i == 0)
            {
                minAdultAge = resultAge;
            }
            else if (i == 1)
            {
                // Restrict to adult age. Young adult is 18 according to National Institutes of Health... even if the young adult section in a library isn't that range.
                minAdultAge = Math.Min(resultAge, minAdultAge);

                // Children should be between 80 and 180 younger than the youngest adult.
                childrenAgeMax = Math.Max(minAdultAge - 80, 0);  // Allow people 10 ticks from 'adulthood' to have kids
                childrenAgeMin = Math.Max(minAdultAge - 178, 0); // Accounting gestation, which isn't simulated yet (2 ticks)
            }

            // Set default eductation output to what the game has already determined.
            resultEducation = education;

            // Apply education level randomisation if that option is selected.
            if (ModSettings.randomImmigrantEd)
            {
                if (i < 2)
                {
                    // Adults.
                    // 24% different education levels
                    int eduModifier = Singleton <SimulationManager> .instance.m_randomizer.Int32(-12, 12) / 10;

                    resultEducation += eduModifier;
                    if (resultEducation < Citizen.Education.Uneducated)
                    {
                        resultEducation = Citizen.Education.Uneducated;
                    }
                    else if (resultEducation > Citizen.Education.ThreeSchools)
                    {
                        resultEducation = Citizen.Education.ThreeSchools;
                    }
                }
                else
                {
                    // Children.
                    switch (Citizen.GetAgeGroup(resultAge))
                    {
                    case Citizen.AgeGroup.Child:
                        resultEducation = Citizen.Education.Uneducated;
                        break;

                    case Citizen.AgeGroup.Teen:
                        resultEducation = Citizen.Education.OneSchool;
                        break;

                    default:
                        // Make it that 80% graduate from high school
                        resultEducation = (Singleton <SimulationManager> .instance.m_randomizer.Int32(0, 100) < 80) ? Citizen.Education.TwoSchools : Citizen.Education.OneSchool;
                        break;
                    }
                }
            }

            // Write to immigration log if that option is selected.
            if (Debugging.UseImmigrationLog)
            {
                Debugging.WriteToLog(Debugging.ImmigrationLogName, "Family member " + i + " immigrating with age " + resultAge + " (" + (int)(resultAge / 3.5) + " years old) and education level " + education + ".");
            }
        }
        /// <summary>
        /// increment the appropriate citizen temp count based on the citizen's demographics
        /// </summary>
        /// <param name="citizen">citizen instance</param>
        private void IncrementCitizenTempCount(Citizen citizen)
        {
            // get the age group and education level
            Citizen.AgeGroup ageGroup = Citizen.GetAgeGroup(citizen.Age);
            Citizen.Education educationLevel = citizen.EducationLevel;

            // check if deceased
            if (citizen.Dead)
            {
                // increment deceased count for age group
                switch (ageGroup)
                {
                    case Citizen.AgeGroup.Child:  _tempCount.children.deceased++; break;
                    case Citizen.AgeGroup.Teen:   _tempCount.teens.deceased++;    break;
                    case Citizen.AgeGroup.Young:  _tempCount.youngs.deceased++;   break;
                    case Citizen.AgeGroup.Adult:  _tempCount.adults.deceased++;   break;
                    case Citizen.AgeGroup.Senior: _tempCount.seniors.deceased++;  break;
                }

                // increment deceased count for education level
                switch (educationLevel)
                {
                    case Citizen.Education.Uneducated:   _tempCount.deceased.eduLevel0++; break;
                    case Citizen.Education.OneSchool:    _tempCount.deceased.eduLevel1++; break;
                    case Citizen.Education.TwoSchools:   _tempCount.deceased.eduLevel2++; break;
                    case Citizen.Education.ThreeSchools: _tempCount.deceased.eduLevel3++; break;
                }
            }
            else
            {
                // check if moving in
                if ((citizen.m_flags & Citizen.Flags.MovingIn) != 0)
                {
                    // increment moving in count for age group
                    switch (ageGroup)
                    {
                        case Citizen.AgeGroup.Child:  _tempCount.children.movingIn++; break;
                        case Citizen.AgeGroup.Teen:   _tempCount.teens.movingIn++;    break;
                        case Citizen.AgeGroup.Young:  _tempCount.youngs.movingIn++;   break;
                        case Citizen.AgeGroup.Adult:  _tempCount.adults.movingIn++;   break;
                        case Citizen.AgeGroup.Senior: _tempCount.seniors.movingIn++;  break;
                    }

                    // increment moving in count for education level
                    switch (educationLevel)
                    {
                        case Citizen.Education.Uneducated:   _tempCount.movingIn.eduLevel0++; break;
                        case Citizen.Education.OneSchool:    _tempCount.movingIn.eduLevel1++; break;
                        case Citizen.Education.TwoSchools:   _tempCount.movingIn.eduLevel2++; break;
                        case Citizen.Education.ThreeSchools: _tempCount.movingIn.eduLevel3++; break;
                    }
                }
                else
                {
                    // normal citizen (i.e. not deceased and not moving in)

                    // get the data row for the age group
                    DataRow drAgeGroup = null;
                    switch (ageGroup)
                    {
                        case Citizen.AgeGroup.Child:  drAgeGroup = _tempCount.children; break;
                        case Citizen.AgeGroup.Teen:   drAgeGroup = _tempCount.teens;    break;
                        case Citizen.AgeGroup.Young:  drAgeGroup = _tempCount.youngs;   break;
                        case Citizen.AgeGroup.Adult:  drAgeGroup = _tempCount.adults;   break;
                        case Citizen.AgeGroup.Senior: drAgeGroup = _tempCount.seniors;  break;
                    }

                    // increment count for age group and education level
                    switch (educationLevel)
                    {
                        case Citizen.Education.Uneducated:   drAgeGroup.eduLevel0++; break;
                        case Citizen.Education.OneSchool:    drAgeGroup.eduLevel1++; break;
                        case Citizen.Education.TwoSchools:   drAgeGroup.eduLevel2++; break;
                        case Citizen.Education.ThreeSchools: drAgeGroup.eduLevel3++; break;
                    }
                }
            }
        }