예제 #1
0
        protected void Perform(StoryProgressionObject manager, IScoringGenerator stats, string tag, List <SimDescription> movers, ChildrenMove children, bool ignoreHead)
        {
            if (movers.Count == 0)
            {
                return;
            }

            SimDescription focus = movers[0];

            if (focus.Household == null)
            {
                stats.IncStat(tag + " Break: No Home");

                mGoing.AddRange(movers);
                return;
            }
            else if (SimTypes.IsSpecial(focus))
            {
                stats.IncStat(tag + " Break: Special");

                mGoing.AddRange(movers);
                return;
            }
            else
            {
                bool adult = false;
                foreach (SimDescription sim in movers)
                {
                    if (manager.Households.AllowGuardian(sim))
                    {
                        adult = true;
                        break;
                    }
                }

                if (!adult)
                {
                    stats.IncStat(tag + " Break: Child Transfer");

                    mStaying.AddRange(Households.All(focus.Household));

                    foreach (SimDescription sim in movers)
                    {
                        if (SimTypes.IsSelectable(sim))
                        {
                            continue;
                        }

                        mStaying.Remove(sim);

                        mGoing.Add(sim);
                    }

                    return;
                }

                List <SimDescription> going   = new List <SimDescription>();
                List <SimDescription> staying = new List <SimDescription>();
                List <SimDescription> houseChildrenPetsPlumbots = new List <SimDescription>();

                bool ancestral = manager.GetValue <IsAncestralOption, bool>(focus.Household);

                SimDescription head = null;
                if (!ignoreHead)
                {
                    head = SimTypes.HeadOfFamily(focus.Household);
                }
                else if (ancestral)
                {
                    stats.IncStat(tag + " Break: Ancestral Head Denied");

                    mStaying.AddRange(Households.All(focus.Household));
                    return;
                }

                foreach (SimDescription sim in Households.All(focus.Household))
                {
                    stats.IncStat(sim.FullName, Common.DebugLevel.Logging);

                    SimDescription partner = null;
                    if (SimTypes.IsSelectable(sim))
                    {
                        stats.IncStat(tag + " Break: Active");

                        staying.Add(sim);
                    }
                    else if (!manager.Households.Allow(stats, sim, 0))
                    {
                        stats.IncStat(tag + " Break: User Denied");

                        staying.Add(sim);
                    }
                    else if (IsPartner(sim, staying, out partner))
                    {
                        stats.IncStat(tag + " Break: Partner Stay");

                        staying.Add(sim);
                    }
                    else if ((IsPartner(sim, movers, out partner)) || (IsPartner(sim, going, out partner)))
                    {
                        if ((head == sim) && (Households.NumHumans(focus.Household) != 1))
                        {
                            stats.IncStat(tag + " Break: Partner Go Denied");

                            going.Remove(partner);

                            staying.Add(sim);

                            if (!staying.Contains(partner))
                            {
                                staying.Add(partner);
                            }
                        }
                        else
                        {
                            stats.IncStat(tag + " Break: Partner Go");

                            going.Add(sim);
                        }
                    }
                    else if (movers.Contains(sim))
                    {
                        if ((head == sim) && (Households.NumHumans(focus.Household) != 1))
                        {
                            stats.IncStat(tag + " Break: Go Denied");

                            staying.Add(sim);
                        }
                        else
                        {
                            stats.IncStat(tag + " Break: Go");

                            going.Add(sim);
                        }
                    }
                    else if (head == sim)
                    {
                        stats.IncStat(tag + " Break: Head Stay");

                        staying.Add(sim);
                    }
                    else if ((sim.YoungAdultOrAbove) && (!sim.IsPet) && (!sim.IsEP11Bot))
                    {
                        stats.IncStat(tag + " Break: Stay");

                        staying.Add(sim);
                    }
                    else
                    {
                        houseChildrenPetsPlumbots.Add(sim);
                    }
                }

                List <SimDescription> extraChildrenPets = new List <SimDescription>();
                foreach (SimDescription child in houseChildrenPetsPlumbots)
                {
                    bool bGoing = false;
                    bool bMatch = false;

                    if (child.IsPet)
                    {
                        int goingLiking = int.MinValue;
                        foreach (SimDescription foci in going)
                        {
                            if (child.LastName == foci.LastName)
                            {
                                bMatch = true;

                                int liking = ManagerSim.GetLTR(child, foci);
                                if (goingLiking < liking)
                                {
                                    goingLiking = liking;
                                }
                            }
                        }

                        int stayingLiking = int.MinValue;
                        foreach (SimDescription foci in staying)
                        {
                            if (child.LastName == foci.LastName)
                            {
                                bMatch = true;

                                int liking = ManagerSim.GetLTR(child, foci);
                                if (stayingLiking < liking)
                                {
                                    stayingLiking = liking;
                                }
                            }
                        }

                        if (goingLiking > stayingLiking)
                        {
                            bGoing = true;
                        }
                    }
                    else
                    {
                        // this will handle plumbots that are related to the family (i.e. creation)
                        if (children == ChildrenMove.RelatedStay)
                        {
                            foreach (SimDescription parent in Relationships.GetParents(child))
                            {
                                if (staying.Contains(parent))
                                {
                                    bMatch = true;
                                }
                            }
                        }
                        else if (children == ChildrenMove.RelatedGo)
                        {
                            foreach (SimDescription parent in Relationships.GetParents(child))
                            {
                                if (going.Contains(parent))
                                {
                                    bMatch = true;
                                }
                            }
                        }
                        else if (children != ChildrenMove.Stay)
                        {
                            foreach (SimDescription foci in going)
                            {
                                if (Relationships.GetChildren(foci).Contains(child))
                                {
                                    bMatch = true;
                                    if ((children != ChildrenMove.Scoring) || (ScoreChildMove(stats, tag, child, going)))
                                    {
                                        bGoing = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (child.IsEP11Bot && !bGoing)
                    {
                        // test the liking for Plumbots without the HumanEmotion chip
                        if (!manager.Households.AllowGuardian(child))
                        {
                            bMatch = true;
                            int goingLiking = int.MinValue;
                            foreach (SimDescription foci in going)
                            {
                                int liking = ManagerSim.GetLTR(child, foci);
                                if (goingLiking < liking)
                                {
                                    goingLiking = liking;
                                }
                            }

                            int stayingLiking = int.MinValue;
                            foreach (SimDescription foci in staying)
                            {
                                int liking = ManagerSim.GetLTR(child, foci);
                                if (stayingLiking < liking)
                                {
                                    stayingLiking = liking;
                                }
                            }

                            if (goingLiking > stayingLiking)
                            {
                                bGoing = true;
                            }
                        }
                    }

                    stats.IncStat(child.FullName, Common.DebugLevel.Logging);

                    if ((!bMatch) && (manager.Households.AllowSoloMove(child)))
                    {
                        stats.IncStat(tag + " Break: Teen Stay");

                        staying.Add(child);
                    }
                    else if (bGoing)
                    {
                        if (children == ChildrenMove.Go)
                        {
                            stats.IncStat(tag + " Break: Child Go");
                        }
                        else
                        {
                            stats.IncStat(tag + " Break: Child Scoring Go");
                        }

                        going.Add(child);
                    }
                    else
                    {
                        if (children == ChildrenMove.Stay)
                        {
                            stats.IncStat(tag + " Break: Child Stay");
                        }
                        else if (bMatch)
                        {
                            stats.IncStat(tag + " Break: Child Scoring Stay");
                        }

                        extraChildrenPets.Add(child);
                    }
                }

                bool foundAdult = false, foundBlood = false;
                foreach (SimDescription sim in staying)
                {
                    if (manager.Deaths.IsDying(sim))
                    {
                        continue;
                    }

                    if (!manager.Households.AllowGuardian(sim))
                    {
                        continue;
                    }

                    if (ancestral)
                    {
                        if (Relationships.IsCloselyRelated(head, sim, false))
                        {
                            foundBlood = true;
                        }
                    }

                    foundAdult = true;
                }

                if ((!foundAdult) || ((ancestral) && (!foundBlood)))
                {
                    stats.AddStat(tag + " Break: Extra", extraChildrenPets.Count);

                    going.AddRange(extraChildrenPets);

                    if (ancestral)
                    {
                        stats.IncStat(tag + " Break: Ancestral");

                        mStaying.AddRange(going);
                        return;
                    }
                }

                mStaying.AddRange(staying);

                foreach (SimDescription sim in mStaying)
                {
                    going.Remove(sim);
                }

                mGoing.AddRange(going);
            }
        }