public Pawn GetMaster(Pawn animal, MasterMode mode)
        {
            var master  = animal.playerSettings.Master;
            var options = animal.kindDef.GetMasterOptions(manager, mode);

            Logger.Follow($"Getting master for {animal.LabelShort}:\n\tcurrent: {master?.LabelShort ?? "None"}\n\toptions:\n");
#if DEBUG_FOLLOW
            foreach (var option in options)
            {
                Logger.Follow($"\t\t{option.LabelShort}\n");
            }
#endif

            // cop out if no options
            if (options.NullOrEmpty())
            {
                return(null);
            }

            // if we currently have a master, our current master is a valid option,
            // and all the options have roughly equal amounts of pets following them, we don't need to take action
            if (master != null && options.Contains(master) && RoughlyEquallyDistributed(options))
            {
                return(master);
            }

            // otherwise, assign a master that has the least amount of current followers.
            return(options.MinBy(p => p.GetFollowers().Count));
        }
Пример #2
0
 public static List <Pawn> GetTrainers(this PawnKindDef pawnkind, Map map, MasterMode mode)
 {
     return(pawnkind.GetMasterOptions(map, mode).Where(p =>
                                                       // skill high enough to handle (copied from StatWorker_MinimumHandlingSkill)
                                                       // NOTE: This does NOT apply postprocessing, so scenario and other offsets DO NOT apply.
                                                       // we can't actually use StatRequests because they're hardcoded for either Things or BuildableDefs.
                                                       p.skills.GetSkill(SkillDefOf.Animals).Level >=
                                                       Mathf.Clamp(GenMath.LerpDouble(0.3f, 1f, 0f, 9f, pawnkind.RaceProps.wildness), 0f, 20f))
            .ToList());
 }
Пример #3
0
        public ManagerJob_Livestock(Manager manager) : base(manager)
        {
            // init designations
            _designations = new List <Designation>();

            // start history tracker
            _history = new History(Utilities_Livestock.AgeSexArray.Select(ageSex => ageSex.ToString()).ToArray());

            // set up the trigger, set all target counts to 5
            Trigger = new Trigger_PawnKind(this.manager);

            // set all training to false
            Training = new TrainingTracker();

            // set areas for restriction and taming to unrestricted
            TameArea       = null;
            RestrictToArea = false;
            RestrictArea   = Utilities_Livestock.AgeSexArray.Select(k => (Area)null).ToList();

            // set up sending animals designated for slaughter to an area (freezer)
            SendToSlaughterArea = false;
            SlaughterArea       = null;

            // set up milking area
            SendToMilkingArea = false;
            MilkArea          = null;

            // set up shearing area
            SendToShearingArea = false;
            ShearArea          = null;

            // set up training area
            SendToTrainingArea = false;
            TrainingArea       = null;

            // taming
            TryTameMore = false;
            TameArea    = null;

            // set defaults for butchering
            ButcherExcess   = true;
            ButcherTrained  = false;
            ButcherPregnant = false;
            ButcherBonded   = false;

            // following
            SetFollow       = true;
            FollowDrafted   = true;
            FollowFieldwork = true;
            FollowTraining  = false;
            Masters         = MasterMode.Default;
            Master          = null;
            Trainers        = MasterMode.Default;
            Trainer         = null;
        }
        public void SetMaster(Pawn animal, MasterMode mode, Pawn specificMaster, ref bool actionTaken)
        {
            switch (mode)
            {
            case MasterMode.Default:
                break;

            case MasterMode.Specific:
                SetMaster(animal, specificMaster, ref actionTaken);
                break;

            default:
                var master = GetMaster(animal, mode);
                SetMaster(animal, master, ref actionTaken);
                break;
            }
        }
Пример #5
0
        public Pawn GetMaster(Pawn animal, MasterMode mode)
        {
            var master  = animal.playerSettings.Master;
            var options = animal.kindDef.GetMasterOptions(manager, mode);

            // if the animal is bonded, and we care about bonds, there's no discussion
            if (RespectBonds)
            {
                var bondee = animal.relations.GetFirstDirectRelationPawn(PawnRelationDefOf.Bond, p => !p.Dead);
                if (bondee != null && TrainableUtility.CanBeMaster(bondee, animal))
                {
                    return(bondee);
                }
            }

            Logger.Follow(
                $"Getting master for {animal.LabelShort}:\n\tcurrent: {master?.LabelShort ?? "None"}\n\toptions:\n");
#if DEBUG_FOLLOW
            foreach (var option in options)
            {
                Logger.Follow($"\t\t{option.LabelShort}\n");
            }
#endif

            // cop out if no options
            if (options.NullOrEmpty())
            {
                return(null);
            }

            // if we currently have a master, our current master is a valid option,
            // and all the options have roughly equal amounts of pets following them, we don't need to take action
            if (master != null && options.Contains(master) && RoughlyEquallyDistributed(options))
            {
                return(master);
            }

            // otherwise, assign a master that has the least amount of current followers.
            return(options.MinBy(p => p.GetFollowers().Count));
        }
Пример #6
0
        public static List <Pawn> GetMasterOptions(this PawnKindDef pawnkind, Map map, MasterMode mode)
        {
            // check if we have a cached version
            IEnumerable <Pawn> cached;

            // does it exist at all?
            var  key         = new Triplet <PawnKindDef, Map, MasterMode>(pawnkind, map, mode);
            bool cacheExists = _masterCache.ContainsKey(key);

            // is it up to date?
            if (cacheExists &&
                _masterCache[key].TryGetValue(out cached) && cached != null)
            {
                return(cached.ToList());
            }

            // if not, get a new list.
            cached = map.mapPawns.FreeColonistsSpawned
                     .Where(p => !p.Dead &&

                            // matches mode
                            (p.GetMasterMode() & mode) != MasterMode.Default
                            );

            // update if key exists
            if (cacheExists)
            {
                _masterCache[key].Update(cached);
            }

            // else add it
            else
            {
                // severely limit cache to only apply for one cycle (one job)
                _masterCache.Add(key, new Utilities.CachedValue <IEnumerable <Pawn> >(cached, 2));
            }
            return(cached.ToList());
        }