private IntVec3 FindGroundSleepSpotFor(Pawn pawn) { Queen queen = HiveUtility.FindQueen(pawn); if (queen != null) { IntVec3 pos; pos = queen.hiveLocation; List <Egg> eggs = queen.spawnedEggs; if (eggs != null && eggs.Any()) { Egg egg = eggs.RandomElement(); if (egg != null) { pos = egg.Position; } } if (!pawn.CanReach(pos, PathEndMode.OnCell, Danger.Deadly, true, TraverseMode.PassDoors)) { pos = pawn.Position; } for (int i = 0; i < 2; i++) { int radius = (i != 0) ? 12 : 4; IntVec3 result; if (CellFinder.TryRandomClosewalkCellNear(pos, pawn.Map, radius, out result, (IntVec3 x) => !x.IsForbidden(pawn) && !x.GetTerrain(pawn.Map).avoidWander)) { return(result); } } } return(CellFinder.RandomClosewalkCellNearNotForbidden(pawn.Position, pawn.Map, 4, pawn)); }
protected override Job TryGiveJob(Pawn pawn) { if (HiveUtility.JobGivenRecentTick(pawn, "BI_Maintain")) { return(null); } Queen queen = HiveUtility.FindQueen(pawn); if (queen != null && JobGiver_InsectGather.WithinHive(pawn, pawn, true)) { List <Egg> eggs = queen.spawnedEggs; if (eggs != null && eggs.Any()) { foreach (Egg egg in eggs) { if (egg != null && pawn.CanReserve(egg)) { CompMaintainable compMaintainable = egg.TryGetComp <CompMaintainable>(); if (compMaintainable != null && compMaintainable.CurStage != MaintainableStage.Healthy) { return(new Job(DefDatabase <JobDef> .GetNamed("BI_Maintain"), egg)); } } } } } return(null); }
public static Egg FindEgg(Pawn pawn) { Queen queen = HiveUtility.FindQueen(pawn); if (queen != null) { List <Egg> eggs = queen.spawnedEggs; if (eggs != null && eggs.Any()) { foreach (Egg egg in eggs) { CompInsectSpawner comp = egg.TryGetComp <CompInsectSpawner>(); if (comp != null) { if (comp.jellyMax > comp.jellyStores) { if (pawn.CanReserve(egg.Position) && pawn.CanReach(egg.Position, PathEndMode.Touch, Danger.Deadly, true, TraverseMode.PassDoors)) { return(egg); } } } } } } return(null); }
public override void UpdateAllDuties() { List <Pawn> pawns = lord.ownedPawns; if (pawns != null && pawns.Any()) { Queen queen = HiveUtility.FindQueen(pawns.RandomElement()); foreach (Pawn pawn in pawns) { if (queen != null) { if (HiveUtility.queenKindDef.Contains(pawn.kindDef)) { pawn.mindState.duty = new PawnDuty(DefDatabase <DutyDef> .GetNamed("BI_QueenDuty"), queen, distToQueenToAttack); } else if (HiveUtility.megaspiderKindDef.Contains(pawn.kindDef)) { pawn.mindState.duty = new PawnDuty(DefDatabase <DutyDef> .GetNamed("BI_MegaspiderDuty"), queen, distToQueenToAttack); } else if (HiveUtility.spelopedeKindDef.Contains(pawn.kindDef)) { pawn.mindState.duty = new PawnDuty(DefDatabase <DutyDef> .GetNamed("BI_SpelopedeDuty"), queen, distToQueenToAttack); } else if (HiveUtility.megascarabKindDef.Contains(pawn.kindDef)) { pawn.mindState.duty = new PawnDuty(DefDatabase <DutyDef> .GetNamed("BI_MegascarabDuty"), queen, distToQueenToAttack); } } } } }
public static bool ButcherCheck(Pawn pawn) { bool canButcher = true; Queen queen = HiveUtility.FindQueen(pawn); if (queen != null) { List <Pawn> spawnedInsects = queen.spawnedInsects; List <ThingDef> defList = new List <ThingDef>(); List <string> list = spawnedInsects?.Select(x => x.def.defName).ToList() ?? new List <string>(); defList = list.Select(s => DefDatabase <ThingDef> .GetNamedSilentFail(s)).OfType <ThingDef>().ToList(); if (HiveUtility.megaspiderKindDef.Contains(pawn.kindDef)) { if (defList.Contains(ThingDef.Named("Spelopede")) || defList.Contains(ThingDef.Named("Megascarab"))) { canButcher = false; } } else if (HiveUtility.spelopedeKindDef.Contains(pawn.kindDef)) { if (!defList.Contains(ThingDef.Named("Megaspider")) && defList.Contains(ThingDef.Named("Megascarab"))) { canButcher = false; } } } return(canButcher); }
public static IntVec3 FindCell(Pawn pawn) { Queen queen = HiveUtility.FindQueen(pawn); if (queen != null) { IntVec3 cell = IntVec3.Invalid; List <Egg> eggs = queen.spawnedEggs; if (eggs != null && eggs.Any()) { cell = eggs.RandomElement().Position; } else { cell = queen.hiveLocation; } IntVec3 pos = IntVec3.Invalid; pos = CellFinder.RandomClosewalkCellNear(cell, pawn.Map, 5); if (pos != IntVec3.Invalid && pawn.CanReserve(pos) && pawn.CanReach(pos, PathEndMode.Touch, Danger.Deadly, true, TraverseMode.PassDoors)) { return(pos); } } return(IntVec3.Invalid); }
protected override Job TryGiveJob(Pawn pawn) { if (HiveUtility.JobGivenRecentTick(pawn, "Mine")) { return(null); } Region region = pawn.GetRegion(RegionType.Set_Passable); if (region == null) { return(null); } Queen queen = HiveUtility.FindQueen(pawn); if (queen == null) { return(null); } IntVec3 pos = IntVec3.Invalid; List <Egg> eggs = queen.spawnedEggs; if (eggs != null && eggs.Any()) { pos = eggs.RandomElement().Position; } else { pos = queen.hiveLocation; } for (int i = 0; i < 40; i++) { IntVec3 randomCell = region.RandomCell; for (int j = 0; j < 4; j++) { IntVec3 c = randomCell + GenAdj.CardinalDirections[j]; int dist = IntVec3Utility.ManhattanDistanceFlat(c, pos); if (dist > 3) { continue; } if (!c.InBounds(pawn.Map)) { continue; } Building edifice = c.GetEdifice(pawn.Map); if (edifice != null && (edifice.def.passability == Traversability.Impassable || edifice.def.IsDoor) && edifice.def.size == IntVec2.One && edifice.def != ThingDefOf.CollapsedRocks && pawn.CanReserve(edifice, 1, -1, null, false)) { return(new Job(JobDefOf.Mine, edifice) { ignoreDesignations = true }); } } } return(null); }
protected override IntVec3 GetWanderRoot(Pawn pawn) { Queen queen = HiveUtility.FindQueen(pawn); if (queen != null) { return(queen.Position); } return(pawn.Position); }
protected override IntVec3 GetWanderRoot(Pawn pawn) { Queen queen = HiveUtility.FindQueen(pawn); if (queen != null) { List <Egg> eggs = queen.spawnedEggs; if (eggs != null && eggs.Any()) { return(eggs.RandomElement().Position); } else { return(queen.hiveLocation); } } return(pawn.Position); }
public static int MaxDistance(Pawn pawn) { int maxDistance = 99999; int foodAmount = HiveUtility.HiveFoodCount(HiveUtility.FindQueen(pawn)); if (foodAmount <= 0) { return maxDistance; } Insect insect = pawn as Insect; if (insect != null) { if (!insect.worker && !insect.stealFood) { return Rand.Range(12, 20); } } return maxDistance; }
public override void UpdateAllDuties() { Queen queen = HiveUtility.FindQueen(lord.ownedPawns.RandomElement()); for (int i = 0; i < lord.ownedPawns.Count; i++) { if (queen != null) { if (!HiveUtility.queenKindDef.Contains(lord.ownedPawns[i].kindDef)) { lord.ownedPawns[i].mindState.duty = new PawnDuty(DefDatabase <DutyDef> .GetNamed("BI_HiveDefenseDuty"), queen, distToQueenToAttack); } else { lord.ownedPawns[i].mindState.duty = new PawnDuty(DefDatabase <DutyDef> .GetNamed("BI_QueenDuty"), queen, distToQueenToAttack); } } } }
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 bool WithinHive(Pawn pawn, Thing thing, bool NearAllyEggs) { List <Thing> things = HiveUtility.ListQueens(pawn.Map); if (things == null || !things.Any()) { return(false); } foreach (Thing t in things) { Queen queen = t as Queen; if (queen != null) { if (queen == HiveUtility.FindQueen(pawn) || (NearAllyEggs && queen.Faction == pawn.Faction)) { int dist = IntVec3Utility.ManhattanDistanceFlat(queen.hiveLocation, thing.Position); if (dist <= 12) { return(true); } List <Egg> eggs = queen.spawnedEggs; if (eggs != null && eggs.Any()) { foreach (Egg egg in eggs) { if (egg != null) { dist = IntVec3Utility.ManhattanDistanceFlat(egg.Position, thing.Position); if (dist <= 5) { return(true); } } } } } } } return(false); }
public static bool FindCloserTarget(Pawn pawn, Thing targetA, Thing targetB) { 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; } } float dist = IntVec3Utility.ManhattanDistanceFlat(targetA.Position, pos); float dist2 = IntVec3Utility.ManhattanDistanceFlat(targetB.Position, pos); if (dist2 < dist) { return(true); } return(false); }
public static Thing FindTarget(Pawn pawn) { List <Thing> allThings = pawn.Map.listerThings.AllThings; if (allThings == null || !allThings.Any()) { return(null); } List <Thing> targetList = new List <Thing>(); foreach (Thing thing in allThings) { if (thing != null) { Corpse corpse = thing as Corpse; Pawn p = thing as Pawn; Queen q = thing as Queen; if (thing.def.category == ThingCategory.Item && !thing.def.IsCorpse && (thing.IngestibleNow || thing.def.defName == "WoodLog") && !JobGiver_InsectGather.WithinHive(pawn, thing, true)) { targetList.Add(thing); } else if (corpse != null && corpse.InnerPawn != null && corpse.InnerPawn.RaceProps.IsFlesh && corpse.GetRotStage() != RotStage.Dessicated && !JobGiver_InsectGather.WithinHive(pawn, thing, true)) { targetList.Add(thing); } else if (p != null && p.RaceProps.IsFlesh && (p.Faction == null || (p.Faction != null && p.Faction != pawn.Faction)) && !JobGiver_InsectGather.WithinHive(pawn, thing, true)) { targetList.Add(thing); } else if (q != null && HiveUtility.FindQueen(pawn) == q) { targetList.Add(thing); } } } return(GetClosest(pawn, targetList)); }
public static Toil ResetStealFoodFlag(Insect insect) { if (BetterInfestationsMod.settings == null) { return(null); } Toil toil = new Toil(); toil.initAction = delegate { insect.stealFood = false; Queen queen = HiveUtility.FindQueen(insect); if (queen != null && !queen.colonyFoodFound) { queen.colonyFoodFound = true; if (BetterInfestationsMod.settings.showNotifications) { Find.LetterStack.ReceiveLetter("letterlabelfoodinfestationsiege".Translate(), "lettertextfoodinfestationsiege".Translate(), LetterDefOf.ThreatBig, queen); Find.TickManager.slower.SignalForceNormalSpeedShort(); } } }; return(toil); }
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, "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_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, "AttackMelee")) { return null; } if (BetterInfestationsMod.settings == null) { return null; } if (!BetterInfestationsMod.settings.allowHuntingJob) { 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) { 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_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 (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; } return MeleeAttackJob(pawn, target); }
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 }); }