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)); }
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()); }
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; } }
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)); }
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()); }