public static Thing GetAttacker(Pawn pawn, Thing target, bool attackingHive) { Pawn pawnTarget = target as Pawn; Insect enemyBug = target as Insect; Building_Turret turretTarget = target as Building_Turret; bool recentAttack = false; if (pawnTarget != null) { recentAttack = pawnTarget.mindState.lastAttackTargetTick <= Find.TickManager.TicksGame && pawnTarget.mindState.lastAttackTargetTick > Find.TickManager.TicksGame - ticksInAttackMode; } else if (turretTarget != null) { recentAttack = turretTarget.LastAttackTargetTick <= Find.TickManager.TicksGame && turretTarget.LastAttackTargetTick > Find.TickManager.TicksGame - ticksInAttackMode; } int dist = IntVec3Utility.ManhattanDistanceFlat(pawn.PositionHeld, target.PositionHeld); bool withinHiveAndInVisual = JobGiver_InsectGather.WithinHive(pawn, target, false) && GenSight.LineOfSight(pawn.Position, target.Position, pawn.Map, true, null, 0, 0); bool enemyPawnThreat = (withinHiveAndInVisual || (attackingHive && recentAttack)) && dist < maxAttackDistance; bool enemyInsectThreat = enemyBug != null && enemyBug.Faction != pawn.Faction && GenSight.LineOfSight(pawn.Position, enemyBug.Position, pawn.Map, true, null, 0, 0) && dist < 30; if (enemyPawnThreat || enemyInsectThreat) { if (pawn.CanReach(target, PathEndMode.Touch, Danger.Deadly, true, TraverseMode.PassDoors)) { return(target); } } return(null); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); this.FailOnBurningImmobile(TargetIndex.B); if (!forbiddenInitially) { this.FailOnForbidden(TargetIndex.A); } Toil reserveTargetA = Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null); yield return(reserveTargetA); Toil toilGoto = null; toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A); toilGoto.AddFailCondition(delegate { Pawn actor = toilGoto.actor; Job curJob = actor.jobs.curJob; if (curJob.haulMode == HaulMode.ToCellStorage) { Thing thing = curJob.GetTarget(TargetIndex.A).Thing; IntVec3 cell = actor.jobs.curJob.GetTarget(TargetIndex.B).Cell; if (!cell.IsValidStorageFor(Map, thing)) { return(true); } } return(false); }); yield return(toilGoto); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false)); if (job.haulOpportunisticDuplicates) { yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveTargetA, TargetIndex.A, TargetIndex.B, false, null)); } if (job.expiryInterval != -1) { yield return(CheckExpiry()); } Insect insect = toilGoto.actor as Insect; if (insect != null && insect.targetColonyFood) { yield return(ResetTargetColonyFoodFlag(insect)); } Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); if (insect != null && insect.stealFood) { yield return(ResetStealFoodFlag(insect)); } }
public static Toil ResetTargetColonyFoodFlag(Insect insect) { Toil toil = new Toil(); toil.initAction = delegate { insect.targetColonyFood = false; }; return(toil); }
public override void Tick() { if (Spawned) { sustainer.Maintain(); Vector3 vector = Position.ToVector3Shifted(); IntVec3 c; if (Rand.MTBEventOccurs(FilthSpawnMTB, 1f, 1.TicksToSeconds()) && CellFinder.TryFindRandomReachableCellNear(Position, Map, FilthSpawnRadius, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false), null, null, out c, 999999)) { FilthMaker.MakeFilth(c, Map, filthTypes.RandomElement(), 1); } if (Rand.MTBEventOccurs(DustMoteSpawnMTB, 1f, 1.TicksToSeconds())) { MoteMaker.ThrowDustPuffThick(new Vector3(vector.x, 0f, vector.z) { y = AltitudeLayer.MoteOverhead.AltitudeFor() }, Map, Rand.Range(1.5f, 3f), new Color(1f, 1f, 1f, 2.5f)); } if (secondarySpawnTick <= Find.TickManager.TicksGame) { sustainer.End(); Map map = Map; IntVec3 position = Position; Destroy(DestroyMode.Vanish); if (faction == null) { faction = HiveUtility.GetRandomInsectFaction(); } PawnKindDef kindDef = HiveUtility.GetFactionKindDef(PawnKindDef.Named("BI_Megascarab_Brown"), faction); Insect insect = PawnGenerator.GeneratePawn(kindDef, faction) as Insect; insect.stealFood = true; GenSpawn.Spawn(insect, CellFinder.RandomClosewalkCellNear(position, map, 4, null), map); if (queen != null) { queen.spawnedInsects.Add(insect); Lord lord = queen.Lord; if (lord == null) { lord = queen.CreateNewLord(); } lord.AddPawn(insect); } } } }
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 static bool Patch_GetBuildingCost(ref int __result, ref Building b, ref TraverseParms traverseParms, ref Pawn pawn) { if (pawn != null) { Insect insect = pawn as Insect; if (insect != null && traverseParms != null && traverseParms.mode == TraverseMode.PassAllDestroyableThings) { if (b != null && b.def != null && b.def.passability == Traversability.Impassable && b.def.size == IntVec2.One && b.Faction != null && b.Faction.IsPlayer) { __result = 0; } else { __result = 5000; } return(false); } } return(true); }
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 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 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, "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, "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); }
public void ManageHive() { if (BetterInfestationsMod.settings == null) { return; } if (!spawnedInsects.Any()) { return; } int[] workerCount = new int[3]; List <List <Pawn> > insectList = new List <List <Pawn> >(); for (int i = 0; i < 3; i++) { insectList.Add(new List <Pawn>()); } for (int i = 0; i < spawnedInsects.Count; i++) { if (HiveUtility.megascarabKindDef.Contains(spawnedInsects[i].kindDef)) { insectList[0].Add(spawnedInsects[i]); } else if (HiveUtility.spelopedeKindDef.Contains(spawnedInsects[i].kindDef)) { insectList[1].Add(spawnedInsects[i]); } else if (HiveUtility.megaspiderKindDef.Contains(spawnedInsects[i].kindDef)) { insectList[2].Add(spawnedInsects[i]); } } for (int i = 0; i < 3; i++) { if (!insectList[i].Any()) { continue; } workerCount[i] = (int)Math.Round(insectList[i].Count * BetterInfestationsMod.settings.hiveAggression, MidpointRounding.AwayFromZero); for (int j = 0; j < insectList[i].Count; j++) { Insect insect = insectList[i][j] as Insect; if (insect == null) { continue; } if (insect.worker) { if (workerCount[i] > 0) { if (colonyFoodFound && HiveUtility.TotalHiveInsectCount(this) >= BetterInfestationsMod.settings.maxInsectsHive) { insect.targetColonyFood = true; insect.stealFood = true; } workerCount[i]--; } else { insect.worker = false; insect.targetColonyFood = false; insect.stealFood = false; } } else { if (workerCount[i] > 0) { insect.worker = true; workerCount[i]--; } } } } }
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 }); }