Exemple #1
0
        // This is a janky mess and a half, but works!
        protected override Job TryGiveJob(Pawn pawn)
        {
            Pawn_SurvivalToolAssignmentTracker assignmentTracker = pawn.TryGetComp <Pawn_SurvivalToolAssignmentTracker>();

            // Pawn can't use tools, lacks a tool assignment tracker or it isn't yet time to re-optimise tools
            if (!pawn.CanUseSurvivalTools() || assignmentTracker == null || Find.TickManager.TicksGame < assignmentTracker.nextSurvivalToolOptimizeTick)
            {
                return(null);
            }

            if (SurvivalToolsSettings.toolAutoDropExcess)
            {
                assignmentTracker.CheckToolsInUse();

                // Check if current tool assignment allows for each tool, auto-removing those that aren't allowed.
                SurvivalToolAssignment curAssignment = assignmentTracker.CurrentSurvivalToolAssignment;
                List <SurvivalTool>    heldTools     = pawn.GetHeldSurvivalTools();
                foreach (SurvivalTool tool in heldTools)
                {
                    if ((!curAssignment.filter.Allows(tool) || !pawn.NeedsSurvivalTool(tool) || !tool.InUse) && !tool.Forced &&
                        StoreUtility.TryFindBestBetterStoreCellFor(tool, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(tool), pawn.Faction, out IntVec3 c))
                    {
                        return(pawn.DequipAndTryStoreSurvivalTool(tool, true, c));
                    }
                }
            }
            if (SurvivalToolsSettings.toolOptimization)
            {
                SurvivalToolAssignment curAssignment     = assignmentTracker.CurrentSurvivalToolAssignment;
                List <StatDef>         workRelevantStats = pawn.AssignedToolRelevantWorkGiversStatDefs();
                List <Thing>           mapTools          = pawn.MapHeld.listerThings.AllThings.Where(t => t is SurvivalTool).ToList();

                SurvivalTool curTool    = null;
                SurvivalTool newTool    = null;
                float        optimality = 0f;
                foreach (StatDef stat in workRelevantStats)
                {
                    curTool    = pawn.GetBestSurvivalTool(stat);
                    optimality = SurvivalToolScore(curTool, workRelevantStats);
                    foreach (SurvivalTool potentialTool in mapTools)
                    {
                        if (StatUtility.StatListContains(potentialTool.WorkStatFactors.ToList(), stat) && curAssignment.filter.Allows(potentialTool) && potentialTool.BetterThanWorkingToollessFor(stat) &&
                            pawn.CanUseSurvivalTool(potentialTool.def) && potentialTool.IsInAnyStorage() && !potentialTool.IsForbidden(pawn) && !potentialTool.IsBurning())
                        {
                            float potentialOptimality = SurvivalToolScore(potentialTool, workRelevantStats);
                            float delta = potentialOptimality - optimality;
                            if (delta > 0f && pawn.CanReserveAndReach(potentialTool, PathEndMode.OnCell, pawn.NormalMaxDanger()))
                            {
                                newTool    = potentialTool;
                                optimality = potentialOptimality;
                            }
                        }
                    }
                    if (newTool != null)
                    {
                        break;
                    }
                }

                // Return a job based on whether or not a better tool was located

                // Failure
                if (newTool == null)
                {
                    SetNextOptimizeTick(pawn);
                    return(null);
                }

                // Success
                int heldToolOffset = 0;
                if (curTool != null && !curTool.Forced)
                {
                    pawn.jobs.jobQueue.EnqueueFirst(pawn.DequipAndTryStoreSurvivalTool(curTool, false));
                    heldToolOffset = -1;
                }
                if (pawn.CanCarryAnyMoreSurvivalTools(heldToolOffset))
                {
                    Job pickupJob = new Job(JobDefOf.TakeInventory, newTool)
                    {
                        count = 1
                    };
                    return(pickupJob);
                }
            }

            // Final failure state
            SetNextOptimizeTick(pawn);
            return(null);
        }
        // This is a janky mess and a half, but works!
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (SurvivalToolsSettings.toolOptimization)
            {
                Pawn_SurvivalToolAssignmentTracker assignmentTracker = pawn.TryGetComp <Pawn_SurvivalToolAssignmentTracker>();

                // Pawn can't use tools, lacks a tool assignment tracker or it isn't yet time to re-optimise tools
                if (!pawn.CanUseSurvivalTools() || assignmentTracker == null || Find.TickManager.TicksGame < assignmentTracker.nextSurvivalToolOptimizeTick)
                {
                    return(null);
                }

                // Check if current tool assignment allows for each tool, auto-removing those that aren't allowed.
                SurvivalToolAssignment curAssignment = assignmentTracker.CurrentSurvivalToolAssignment;
                List <Thing>           heldTools     = pawn.GetHeldSurvivalTools().ToList();
                foreach (Thing tool in heldTools)
                {
                    if ((!curAssignment.filter.Allows(tool) || !pawn.NeedsSurvivalTool((SurvivalTool)tool)) && assignmentTracker.forcedHandler.AllowedToAutomaticallyDrop(tool))
                    {
                        return(pawn.DequipAndTryStoreSurvivalTool(tool));
                    }
                }

                // Look for better alternative tools to what the colonist currently has, based on what stats are relevant to the work types the colonist is assigned to
                List <Thing>   heldUsableTools   = heldTools.Where(t => heldTools.IndexOf(t).IsUnderSurvivalToolCarryLimitFor(pawn)).ToList();
                List <Thing>   mapTools          = pawn.MapHeld.listerThings.AllThings.Where(t => t is SurvivalTool).ToList();
                List <StatDef> workRelevantStats = pawn.AssignedToolRelevantWorkGiversStatDefs();
                Thing          curTool           = null;
                Thing          newTool           = null;
                float          optimality        = 0f;
                foreach (StatDef stat in workRelevantStats)
                {
                    curTool    = pawn.GetBestSurvivalTool(stat);
                    optimality = SurvivalToolScore(curTool, workRelevantStats);
                    foreach (Thing potentialToolThing in mapTools)
                    {
                        SurvivalTool potentialTool = (SurvivalTool)potentialToolThing;
                        if (StatUtility.StatListContains(potentialTool.WorkStatFactors.ToList(), stat) && curAssignment.filter.Allows(potentialTool) && potentialTool.BetterThanWorkingToollessFor(stat) &&
                            pawn.CanUseSurvivalTool(potentialTool.def) && potentialTool.IsInAnyStorage() && !potentialTool.IsForbidden(pawn) && !potentialTool.IsBurning())
                        {
                            float potentialOptimality = SurvivalToolScore(potentialTool, workRelevantStats);
                            float delta = potentialOptimality - optimality;
                            if (delta > 0f && pawn.CanReserveAndReach(potentialTool, PathEndMode.OnCell, pawn.NormalMaxDanger()))
                            {
                                newTool    = potentialTool;
                                optimality = potentialOptimality;
                            }
                        }
                    }
                    if (newTool != null)
                    {
                        break;
                    }
                }

                // Return a job based on whether or not a better tool was located

                // Failure
                if (newTool == null)
                {
                    SetNextOptimizeTick(pawn);
                    return(null);
                }

                // Success
                int heldToolOffset = 0;
                if (curTool != null && assignmentTracker.forcedHandler.AllowedToAutomaticallyDrop(curTool))
                {
                    pawn.jobs.jobQueue.EnqueueFirst(pawn.DequipAndTryStoreSurvivalTool(curTool, false));
                    heldToolOffset = -1;
                }
                if (pawn.CanCarryAnyMoreSurvivalTools(heldToolOffset))
                {
                    Job pickupJob = new Job(JobDefOf.TakeInventory, newTool)
                    {
                        count = 1
                    };
                    return(pickupJob);
                }

                // Final failure state
                SetNextOptimizeTick(pawn);
            }

            return(null);
        }
Exemple #3
0
        internal static bool _ShouldShowFor(this StatWorker obj, BuildableDef eDef)
        {
            // Need some reflection to access the internals
            StatDef _stat = typeof(StatWorker).GetField("stat", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj) as StatDef;

            if (
                (!_stat.showIfUndefined) &&
                (!StatUtility.StatListContains(eDef.statBases, _stat))
                )
            {
                return(false);
            }
            ThingDef thingDef = eDef as ThingDef;

            if (
                (thingDef != null) &&
                (thingDef.category == ThingCategory.Pawn) &&
                (
                    (!_stat.showOnPawns) ||
                    (
                        (!_stat.showOnHumanlikes) &&
                        (thingDef.race.Humanlike)
                    ) ||
                    (
                        (!_stat.showOnAnimals) &&
                        (thingDef.race.Animal)
                    ) ||
                    (
                        (!_stat.showOnMechanoids) &&
                        (thingDef.race.IsMechanoid)
                    )
                )
                )
            {
                return(false);
            }
            if (
                (_stat.category == StatCategoryDefOf.BasicsPawn) ||
                (_stat.category == StatCategoryDefOf.PawnCombat)
                )
            {
                if (thingDef != null)
                {
                    return(thingDef.category == ThingCategory.Pawn);
                }
                return(false);
            }
            if (
                (_stat.category == StatCategoryDefOf.PawnMisc) ||
                (_stat.category == StatCategoryDefOf.PawnSocial) ||
                (_stat.category == StatCategoryDefOf.PawnWork)
                )
            {
                if (
                    (thingDef != null) &&
                    (thingDef.category == ThingCategory.Pawn)
                    )
                {
                    return(thingDef.race.Humanlike);
                }
                return(false);
            }
            if (_stat.category == StatCategoryDefOf.Building)
            {
                if (thingDef == null)
                {
                    return(false);
                }
                if (_stat == StatDefOf.DoorOpenSpeed)
                {
                    return
                        ((thingDef.thingClass == typeof(Building_Door)) ||
                         (thingDef.thingClass.IsSubclassOf(typeof(Building_Door))));
                }
                return(thingDef.category == ThingCategory.Building);
            }
            if (_stat.category == StatCategoryDefOf.Apparel)
            {
                if (thingDef == null)
                {
                    return(false);
                }
                if (!thingDef.IsApparel)
                {
                    return(thingDef.category == ThingCategory.Pawn);
                }
                return(true);
            }
            if (_stat.category == StatCategoryDefOf.Weapon)
            {
                if (thingDef == null)
                {
                    return(false);
                }
                if (!thingDef.IsMeleeWeapon)
                {
                    return(thingDef.IsRangedWeapon);
                }
                return(true);
            }
            if (_stat.category == StatCategoryDefOf.BasicsNonPawn)
            {
                if (thingDef != null)
                {
                    return(thingDef.category != ThingCategory.Pawn);
                }
                return(true);
            }
            if (_stat.category.displayAllByDefault)
            {
                return(true);
            }
            object[]     objArray     = new object[4];
            string       str1         = "Unhandled case: ";
            StatDef      statDef      = _stat;
            string       str2         = ", ";
            BuildableDef buildableDef = eDef;

            objArray[0] = (object)str1;
            objArray[1] = (object)statDef;
            objArray[2] = (object)str2;
            objArray[3] = (object)buildableDef;
            Verse.Log.Error(string.Concat(objArray));
            return(false);
        }