public static Thing GetClosest(Pawn pawn, List <Thing> list)
        {
            Thing result = null;
            int   best   = int.MaxValue;

            if (list != null && list.Any())
            {
                Queen queen = HiveUtility.FindQueen(pawn);
                if (queen == null)
                {
                    return(null);
                }
                if (list.Contains(queen as Thing) && !pawn.CanReach(queen, PathEndMode.OnCell, Danger.Deadly, true, TraverseMode.PassDoors))
                {
                    return(queen);
                }
                else
                {
                    IntVec3 pos    = pawn.Position;
                    Insect  insect = pawn as Insect;
                    if (insect != null && insect.targetColonyFood)
                    {
                        pos = queen.colonyFoodLoc;
                    }

                    foreach (Thing thing in list)
                    {
                        int dist = IntVec3Utility.ManhattanDistanceFlat(pos, thing.Position);
                        if (dist < best && dist <= JobGiver_InsectHunt.MaxDistance(pawn))
                        {
                            if (!pawn.CanReach(thing, PathEndMode.OnCell, Danger.Deadly, true, TraverseMode.PassDoors))
                            {
                                best   = dist;
                                result = thing;
                            }
                        }
                    }
                }
            }
            return(result);
        }
        public static Thing GetClosest(Pawn pawn, List <Thing> things)
        {
            if (things == null || !things.Any())
            {
                return(null);
            }

            Thing result = null;
            int   best   = int.MaxValue;

            IntVec3 pos    = pawn.Position;
            Insect  insect = pawn as Insect;

            if (insect != null && insect.targetColonyFood)
            {
                Queen queen = HiveUtility.FindQueen(pawn);
                if (queen != null)
                {
                    pos = queen.colonyFoodLoc;
                }
            }

            foreach (Thing thing in things)
            {
                int dist = IntVec3Utility.ManhattanDistanceFlat(pos, thing.Position);
                if (dist < best && dist <= JobGiver_InsectHunt.MaxDistance(pawn))
                {
                    if (pawn.CanReserve(thing) && pawn.CanReach(thing, PathEndMode.Touch, Danger.Deadly, true, TraverseMode.PassDoors))
                    {
                        best   = dist;
                        result = thing;
                    }
                }
            }
            return(result);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (HiveUtility.JobGivenRecentTick(pawn, "BI_InsectHarvest"))
            {
                return(null);
            }
            if (BetterInfestationsMod.settings == null)
            {
                return(null);
            }
            if (!BetterInfestationsMod.settings.allowHarvestJob)
            {
                return(null);
            }
            if (pawn.GetRoom() != null && pawn.GetRoom().Fogged)
            {
                return(null);
            }
            Queen queen = HiveUtility.FindQueen(pawn);

            if (queen == null)
            {
                return(null);
            }
            Insect insect = pawn as Insect;

            if (insect == null)
            {
                return(null);
            }
            int foodAmount = HiveUtility.HiveFoodCount(queen);

            if (foodAmount >= BetterInfestationsMod.settings.foodStorage && !insect.stealFood)
            {
                return(null);
            }
            Region region = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                return(null);
            }
            Thing target = FindTarget(pawn);

            if (target != null)
            {
                Thing gatherTarget = JobGiver_InsectGather.FindTarget(pawn, false);
                if (gatherTarget != null)
                {
                    if (JobGiver_InsectGather.FindCloserTarget(pawn, target, gatherTarget))
                    {
                        return(JobGiver_InsectGather.ForceJob(pawn, gatherTarget));
                    }
                }
                if (JobGiver_InsectHunt.CanHunt(pawn) && BetterInfestationsMod.settings.allowHuntingJob)
                {
                    Thing huntTarget = JobGiver_InsectHunt.FindTarget(pawn);
                    if (huntTarget != null)
                    {
                        if (JobGiver_InsectGather.FindCloserTarget(pawn, target, huntTarget))
                        {
                            return(JobGiver_InsectHunt.ForceJob(pawn, huntTarget));
                        }
                    }
                }
                if (Rand.Range(1, 25) == 1 && BetterInfestationsMod.settings.allowSapperJob)
                {
                    Thing sapperTarget = JobGiver_InsectSapper.FindTarget(pawn);
                    if (sapperTarget != null && sapperTarget != queen as Thing)
                    {
                        if (JobGiver_InsectGather.FindCloserTarget(pawn, target, sapperTarget))
                        {
                            return(JobGiver_InsectSapper.ForceJob(pawn, sapperTarget));
                        }
                    }
                }
            }
            if (target == null)
            {
                return(null);
            }
            Job job = new Job(DefDatabase <JobDef> .GetNamed("BI_InsectHarvest"), target)
            {
                canBash        = true,
                expiryInterval = 480,
                count          = 1
            };

            return(job);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (HiveUtility.JobGivenRecentTick(pawn, "Mine"))
            {
                return(null);
            }
            if (BetterInfestationsMod.settings == null)
            {
                return(null);
            }
            if (!BetterInfestationsMod.settings.allowSapperJob)
            {
                return(null);
            }
            if (pawn.GetRoom() != null && pawn.GetRoom().Fogged)
            {
                return(null);
            }
            Queen queen = HiveUtility.FindQueen(pawn);

            if (queen == null)
            {
                return(null);
            }
            Insect insect = pawn as Insect;

            if (insect == null && queen != null && queen.spawnedInsects != null && queen.spawnedInsects.Count > 1)
            {
                return(null);
            }
            int foodAmount = HiveUtility.HiveFoodCount(queen);

            if (foodAmount >= BetterInfestationsMod.settings.foodStorage && insect != null && !insect.stealFood)
            {
                return(null);
            }
            Region region = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                return(null);
            }
            Thing target = FindTarget(pawn);

            if (target != null && target != queen as Thing)
            {
                Thing gatherTarget = JobGiver_InsectGather.FindTarget(pawn, false);
                if (gatherTarget != null)
                {
                    if (JobGiver_InsectGather.FindCloserTarget(pawn, target, gatherTarget))
                    {
                        return(JobGiver_InsectGather.ForceJob(pawn, gatherTarget));
                    }
                }
                if (JobGiver_InsectHunt.CanHunt(pawn) && BetterInfestationsMod.settings.allowHuntingJob)
                {
                    Thing huntTarget = JobGiver_InsectHunt.FindTarget(pawn);
                    if (huntTarget != null)
                    {
                        if (JobGiver_InsectGather.FindCloserTarget(pawn, target, huntTarget))
                        {
                            return(JobGiver_InsectHunt.ForceJob(pawn, huntTarget));
                        }
                    }
                }
                if (JobGiver_InsectHarvest.CanHarvest(pawn) && BetterInfestationsMod.settings.allowHarvestJob)
                {
                    Thing harvestTarget = JobGiver_InsectHarvest.FindTarget(pawn);
                    if (harvestTarget != null)
                    {
                        if (JobGiver_InsectGather.FindCloserTarget(pawn, target, harvestTarget))
                        {
                            return(JobGiver_InsectHarvest.ForceJob(pawn, harvestTarget));
                        }
                    }
                }
            }
            if (target == null)
            {
                return(null);
            }
            if (!pawn.CanReach(target, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.PassAllDestroyableThings))
            {
                return(null);
            }
            using (PawnPath pawnPath = pawn.Map.pathFinder.FindPath(pawn.Position, target, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.PassAllDestroyableThings, false), PathEndMode.OnCell))
            {
                List <IntVec3> cells = pawnPath.NodesReversed;
                if (cells != null && cells.Any())
                {
                    foreach (IntVec3 cell in cells)
                    {
                        Building b = cell.GetEdifice(pawn.Map);
                        if (b != null && b.def != null)
                        {
                            if (b.def.passability != Traversability.Impassable)
                            {
                                return(null);
                            }
                            if (b.def.size != IntVec2.One)
                            {
                                return(null);
                            }
                            if (b.Faction == null || (b.Faction != null && !b.Faction.IsPlayer))
                            {
                                return(null);
                            }
                        }
                    }
                }
                IntVec3 cellBeforeBlocker;
                Thing   thing = pawnPath.FirstBlockingBuilding(out cellBeforeBlocker, pawn);
                if (thing != null && pawn.CanReserve(thing) && pawn.CanReach(thing, PathEndMode.Touch, Danger.Deadly, true, TraverseMode.PassDoors))
                {
                    return(new Job(JobDefOf.Mine, thing)
                    {
                        ignoreDesignations = true,
                        expiryInterval = 6000
                    });
                }
            }
            return(null);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (HiveUtility.JobGivenRecentTick(pawn, "BI_HaulToCell"))
            {
                return(null);
            }
            if (BetterInfestationsMod.settings == null)
            {
                return(null);
            }
            if (pawn.GetRoom() != null && pawn.GetRoom().Fogged)
            {
                return(null);
            }
            Queen queen = HiveUtility.FindQueen(pawn);

            if (queen == null)
            {
                return(null);
            }
            Insect insect = pawn as Insect;

            if (insect == null && queen != null && queen.spawnedInsects != null && queen.spawnedInsects.Count > 1)
            {
                return(null);
            }
            int foodAmount = HiveUtility.HiveFoodCount(queen);

            if (foodAmount >= BetterInfestationsMod.settings.foodStorage && insect != null && !insect.stealFood)
            {
                return(null);
            }
            Region region = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                return(null);
            }
            Thing target = FindTarget(pawn, false);

            if (target != null)
            {
                if (JobGiver_InsectHunt.CanHunt(pawn) && BetterInfestationsMod.settings.allowHuntingJob)
                {
                    Thing huntTarget = JobGiver_InsectHunt.FindTarget(pawn);
                    if (huntTarget != null)
                    {
                        if (FindCloserTarget(pawn, target, huntTarget))
                        {
                            return(JobGiver_InsectHunt.ForceJob(pawn, huntTarget));
                        }
                    }
                }
                if (JobGiver_InsectHarvest.CanHarvest(pawn) && BetterInfestationsMod.settings.allowHarvestJob)
                {
                    Thing harvestTarget = JobGiver_InsectHarvest.FindTarget(pawn);
                    if (harvestTarget != null)
                    {
                        if (FindCloserTarget(pawn, target, harvestTarget))
                        {
                            return(JobGiver_InsectHarvest.ForceJob(pawn, harvestTarget));
                        }
                    }
                }
                if (Rand.Range(1, 25) == 1 && BetterInfestationsMod.settings.allowSapperJob)
                {
                    Thing sapperTarget = JobGiver_InsectSapper.FindTarget(pawn);
                    if (sapperTarget != null && sapperTarget != queen as Thing)
                    {
                        if (FindCloserTarget(pawn, target, sapperTarget))
                        {
                            return(JobGiver_InsectSapper.ForceJob(pawn, sapperTarget));
                        }
                    }
                }
            }
            if (target == null)
            {
                return(null);
            }
            IntVec3 cell = FindCell(pawn);

            if (cell == IntVec3.Invalid)
            {
                return(null);
            }
            return(new Job(DefDatabase <JobDef> .GetNamed("BI_HaulToCell"), target, cell)
            {
                canBash = true,
                haulOpportunisticDuplicates = false,
                haulMode = HaulMode.ToCellNonStorage,
                expiryInterval = 480,
                ignoreForbidden = true,
                count = 99999
            });
        }