public static void Postfix(Pawn_MindState __instance) { if (__instance.pawn.NoOverlapAdjustedIsHashIntervalTick(100)) { if (__instance.pawn.Spawned) { int regionsToScan = __instance.anyCloseHostilesRecently ? 24 : 18; __instance.anyCloseHostilesRecently = PawnUtility.EnemiesAreNearby(__instance.pawn, regionsToScan, true); } else { __instance.anyCloseHostilesRecently = false; } } if (TickUtility.NoOverlapTickMod(123) && __instance.pawn.Spawned && __instance.pawn.RaceProps.IsFlesh && __instance.pawn.needs.mood != null) { TerrainDef terrain = __instance.pawn.Position.GetTerrain(__instance.pawn.Map); if (terrain.traversedThought != null) { __instance.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(terrain.traversedThought); } WeatherDef curWeatherLerped = __instance.pawn.Map.weatherManager.CurWeatherLerped; if (curWeatherLerped.exposedThought != null && !__instance.pawn.Position.Roofed(__instance.pawn.Map)) { __instance.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(curWeatherLerped.exposedThought); } } }
private bool DoesTargetPawnAcceptAdvance() { //if (xxx.config.always_accept_whores) // return true; //Log.Message("[RJW]JobDriver_InvitingVisitors::DoesTargetPawnAcceptAdvance() is called"); if (PawnUtility.EnemiesAreNearby(TargetPawn)) { //Log.Message("[RJW]JobDriver_InvitingVisitors::DoesTargetPawnAcceptAdvance() fail - enemy near"); return(false); } if (!allowedJobs.Contains(TargetPawn.jobs.curJob.def)) { //Log.Message("[RJW]JobDriver_InvitingVisitors::DoesTargetPawnAcceptAdvance() fail - not allowed job"); return(false); } //Log.Message("Will try " + WhoringHelper.WillPawnTryHookup(TargetPawn)); //Log.Message("Appeal " + WhoringHelper.IsHookupAppealing(TargetPawn, W***e)); //Log.Message("Afford " + WhoringHelper.CanAfford(TargetPawn, W***e)); //Log.Message("Need sex " + (xxx.need_some_sex(TargetPawn) >= 1)); W***e.skills.Learn(SkillDefOf.Social, 1.2f); return(WhoringHelper.WillPawnTryHookup(TargetPawn) && WhoringHelper.IsHookupAppealing(TargetPawn, W***e) && WhoringHelper.CanAfford(TargetPawn, W***e) && xxx.need_some_sex(TargetPawn) >= 1f); }
public virtual void JobTrackerTick() { jobsGivenThisTick = 0; jobsGivenThisTickTextual = ""; if (pawn.IsHashIntervalTick(30)) { ThinkResult thinkResult = DetermineNextConstantThinkTreeJob(); if (thinkResult.IsValid) { if (ShouldStartJobFromThinkTree(thinkResult)) { CheckLeaveJoinableLordBecauseJobIssued(thinkResult); StartJob(thinkResult.Job, JobCondition.InterruptForced, thinkResult.SourceNode, resumeCurJobAfterwards: false, cancelBusyStances: false, pawn.thinker.ConstantThinkTree, thinkResult.Tag); } else if (thinkResult.Job != curJob && !jobQueue.Contains(thinkResult.Job)) { JobMaker.ReturnToPool(thinkResult.Job); } } } if (curDriver != null) { if (curJob.expiryInterval > 0 && (Find.TickManager.TicksGame - curJob.startTick) % curJob.expiryInterval == 0 && Find.TickManager.TicksGame != curJob.startTick) { if (!curJob.expireRequiresEnemiesNearby || PawnUtility.EnemiesAreNearby(pawn, 25)) { if (debugLog) { DebugLogEvent("Job expire"); } if (!curJob.checkOverrideOnExpire) { EndCurrentJob(JobCondition.Succeeded); } else { CheckForJobOverride(); } FinalizeTick(); return; } if (debugLog) { DebugLogEvent("Job expire skipped because there are no enemies nearby"); } } curDriver.DriverTick(); } if (curJob == null && !pawn.Dead && pawn.mindState.Active && CanDoAnyJob()) { if (debugLog) { DebugLogEvent("Starting job from Tick because curJob == null."); } TryFindAndStartJob(); } FinalizeTick(); }
public void MindStateTick() { if (wantsToTradeWithColony) { TradeUtility.CheckInteractWithTradersTeachOpportunity(pawn); } if (meleeThreat != null && !MeleeThreatStillThreat) { meleeThreat = null; } mentalStateHandler.MentalStateHandlerTick(); mentalBreaker.MentalBreakerTick(); inspirationHandler.InspirationHandlerTick(); if (!pawn.GetPosture().Laying()) { applyBedThoughtsTick = 0; } if (pawn.IsHashIntervalTick(100)) { if (pawn.Spawned) { int regionsToScan = (!anyCloseHostilesRecently) ? 18 : 24; anyCloseHostilesRecently = PawnUtility.EnemiesAreNearby(pawn, regionsToScan, passDoors: true); } else { anyCloseHostilesRecently = false; } } if (WillJoinColonyIfRescued && AnythingPreventsJoiningColonyIfRescued) { WillJoinColonyIfRescued = false; } if (pawn.Spawned && pawn.IsWildMan() && !WildManEverReachedOutside && pawn.GetRoom() != null && pawn.GetRoom().TouchesMapEdge) { WildManEverReachedOutside = true; } if (Find.TickManager.TicksGame % 123 == 0 && pawn.Spawned && pawn.RaceProps.IsFlesh && pawn.needs.mood != null) { TerrainDef terrain = pawn.Position.GetTerrain(pawn.Map); if (terrain.traversedThought != null) { pawn.needs.mood.thoughts.memories.TryGainMemoryFast(terrain.traversedThought); } WeatherDef curWeatherLerped = pawn.Map.weatherManager.CurWeatherLerped; if (curWeatherLerped.exposedThought != null && !pawn.Position.Roofed(pawn.Map)) { pawn.needs.mood.thoughts.memories.TryGainMemoryFast(curWeatherLerped.exposedThought); } } if (GenLocalDate.DayTick(pawn) == 0) { interactionsToday = 0; } }
public virtual void JobTrackerTick() { this.jobsGivenThisTick = 0; this.jobsGivenThisTickTextual = ""; if (this.pawn.IsHashIntervalTick(30)) { ThinkResult thinkResult = this.DetermineNextConstantThinkTreeJob(); if (thinkResult.IsValid && this.ShouldStartJobFromThinkTree(thinkResult)) { this.CheckLeaveJoinableLordBecauseJobIssued(thinkResult); this.StartJob(thinkResult.Job, JobCondition.InterruptForced, thinkResult.SourceNode, false, false, this.pawn.thinker.ConstantThinkTree, thinkResult.Tag, false); } } if (this.curDriver != null) { if (this.curJob.expiryInterval > 0 && (Find.TickManager.TicksGame - this.curJob.startTick) % this.curJob.expiryInterval == 0 && Find.TickManager.TicksGame != this.curJob.startTick) { if (!this.curJob.expireRequiresEnemiesNearby || PawnUtility.EnemiesAreNearby(this.pawn, 25, false)) { if (this.debugLog) { this.DebugLogEvent("Job expire"); } if (!this.curJob.checkOverrideOnExpire) { this.EndCurrentJob(JobCondition.Succeeded, true); } else { this.CheckForJobOverride(); } this.FinalizeTick(); return; } if (this.debugLog) { this.DebugLogEvent("Job expire skipped because there are no enemies nearby"); } } this.curDriver.DriverTick(); } if (this.curJob == null && !this.pawn.Dead && this.pawn.mindState.Active && this.CanDoAnyJob()) { if (this.debugLog) { this.DebugLogEvent("Starting job from Tick because curJob == null."); } this.TryFindAndStartJob(); } this.FinalizeTick(); }
public static bool MindStateTick(Pawn_MindState __instance) { if (__instance.wantsToTradeWithColony) { TradeUtility.CheckInteractWithTradersTeachOpportunity(__instance.pawn); } if (__instance.meleeThreat != null && !__instance.MeleeThreatStillThreat) { __instance.meleeThreat = null; } __instance.mentalStateHandler.MentalStateHandlerTick(); __instance.mentalBreaker.MentalBreakerTick(); __instance.inspirationHandler.InspirationHandlerTick(); if (!__instance.pawn.GetPosture().Laying()) { __instance.applyBedThoughtsTick = 0; } if (__instance.pawn.IsHashIntervalTick(100)) { __instance.anyCloseHostilesRecently = __instance.pawn.Spawned && PawnUtility.EnemiesAreNearby(__instance.pawn, __instance.anyCloseHostilesRecently ? 24 : 18, true); } if (__instance.WillJoinColonyIfRescued && __instance.AnythingPreventsJoiningColonyIfRescued) { __instance.WillJoinColonyIfRescued = false; } if (__instance.pawn.Spawned && __instance.pawn.IsWildMan() && (!__instance.WildManEverReachedOutside && __instance.pawn.GetRoom(RegionType.Set_Passable) != null) && __instance.pawn.GetRoom(RegionType.Set_Passable).TouchesMapEdge) { __instance.WildManEverReachedOutside = true; } if (Find.TickManager.TicksGame % 123 == 0 && __instance.pawn.Spawned && (__instance.pawn.RaceProps.IsFlesh && __instance.pawn.needs.mood != null)) { TerrainDef terrain = __instance.pawn.Position.GetTerrain(__instance.pawn.Map); if (terrain.traversedThought != null) { __instance.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(terrain.traversedThought); } WeatherDef curWeatherLerped = __instance.pawn.Map.weatherManager.CurWeatherLerped; if (curWeatherLerped.exposedThought != null && !__instance.pawn.Position.Roofed(__instance.pawn.Map)) { __instance.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(curWeatherLerped.exposedThought); } } //dirty hack for easy speedup - i'm sure this breaks things like pawn conversation interval. //if (GenLocalDate.DayTick((Thing)__instance.pawn) != 0) // return; __instance.interactionsToday = 0; return(false); }
protected override Job TryGiveJob(Pawn pawn) { if (pawn.mindState.meleeThreat is null && !PawnUtility.EnemiesAreNearby(pawn)) { return(null); } if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { return(null); } if (pawn.GetRegion() == null) { return(null); } if (pawn.equipment != null && !AlreadySatisfiedWithCurrentWeapon(pawn)) { Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.Weapon), PathEndMode.OnCell, TraverseParms.For(pawn), 8f, (Thing x) => pawn.CanReserve(x) && !x.IsBurning() && ShouldEquipWeapon(x, pawn), null, 0, 15); if (thing != null) { return(JobMaker.MakeJob(JobDefOf.Equip, thing)); } } Pawn_EquipmentTracker equipment = pawn.equipment; if (equipment != null && equipment.Primary?.def?.IsRangedWeapon == true) { foreach (Apparel item in pawn.apparel.WornApparel) { if (item.def == ThingDefOf.Apparel_ShieldBelt) { return(JobMaker.MakeJob(JobDefOf.RemoveApparel, item)); } } } if (pickUpUtilityItems && pawn.apparel != null && WouldPickupUtilityItem(pawn)) { Thing thing2 = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.Apparel), PathEndMode.OnCell, TraverseParms.For(pawn), 8f, (Thing x) => pawn.CanReserve(x) && !x.IsBurning() && ShouldEquipUtilityItem(x, pawn), null, 0, 15); if (thing2 != null) { return(JobMaker.MakeJob(JobDefOf.Wear, thing2)); } } return(null); }
private bool DoesTargetPawnAcceptAdvance() { if (RJWSettings.DebugWhoring) { Log.Message($"JobDriver_InvitingVisitors::DoesTargetPawnAcceptAdvance() - {xxx.get_pawnname(TargetPawn)}"); } //if (RJWSettings.WildMode) return true; if (PawnUtility.EnemiesAreNearby(TargetPawn)) { if (RJWSettings.DebugWhoring) { Log.Message($" fail - enemy near"); } return(false); } if (!allowedJobs.Contains(TargetPawn.jobs.curJob.def)) { if (RJWSettings.DebugWhoring) { Log.Message($" fail - not allowed job"); } return(false); } if (RJWSettings.DebugWhoring) { Log.Message("Will try hookup " + WhoringHelper.WillPawnTryHookup(TargetPawn)); Log.Message("Is w***e appealing " + WhoringHelper.IsHookupAppealing(TargetPawn, W***e)); Log.Message("Can afford w***e " + WhoringHelper.CanAfford(TargetPawn, W***e)); Log.Message("Need sex " + (xxx.need_some_sex(TargetPawn) >= 1)); } if (WhoringHelper.WillPawnTryHookup(TargetPawn) && WhoringHelper.IsHookupAppealing(TargetPawn, W***e) && WhoringHelper.CanAfford(TargetPawn, W***e) && xxx.need_some_sex(TargetPawn) >= 1f) { W***e.skills.Learn(SkillDefOf.Social, 1.2f); return(true); } return(false); }
private WorkPriority GetPriorityWork(Pawn pawn) { CompAmmoUser primaryammouser = pawn.equipment.Primary.TryGetComp <CompAmmoUser>(); CompInventory compammo = pawn.TryGetComp <CompInventory>(); if (pawn.Faction.IsPlayer && pawn.equipment.Primary != null && pawn.equipment.Primary.TryGetComp <CompAmmoUser>() != null) { Loadout loadout = pawn.GetLoadout(); // if (loadout != null && !loadout.Slots.NullOrEmpty()) if (loadout != null && loadout.SlotCount > 0) { return(WorkPriority.None); } } if (pawn.kindDef.trader) { return(WorkPriority.None); } if (pawn.CurJob != null && pawn.CurJob.def == JobDefOf.Tame) { return(WorkPriority.None); } if (pawn.equipment.Primary == null) { if (Unload(pawn)) { return(WorkPriority.Unloading); } else { return(WorkPriority.Weapon); } } if (pawn.equipment.Primary != null && primaryammouser != null) { int ammocount = 0; foreach (AmmoLink link in primaryammouser.Props.ammoSet.ammoTypes) { Thing ammoThing; ammoThing = compammo.ammoList.Find(thing => thing.def == link.ammo); if (ammoThing != null) { ammocount += ammoThing.stackCount; } } // current ammo bulk float currentAmmoBulk = primaryammouser.CurrentAmmo.GetStatValueAbstract(CE_StatDefOf.Bulk); // weapon magazine size float stackSize = primaryammouser.Props.magazineSize; // weight projectile ratio to free bulk with x1.5 reserve float weightProjectileRatio = Mathf.RoundToInt(((compammo.capacityBulk - compammo.currentBulk) / 1.5f) / currentAmmoBulk); if (ammocount < stackSize * 1 && (ammocount < weightProjectileRatio)) { if (Unload(pawn)) { return(WorkPriority.Unloading); } else { return(WorkPriority.LowAmmo); } } if (!PawnUtility.EnemiesAreNearby(pawn, 30, true)) { if (ammocount < stackSize * 2 && (ammocount < weightProjectileRatio)) { if (Unload(pawn)) { return(WorkPriority.Unloading); } else { return(WorkPriority.Ammo); } } } } /* * if (!pawn.Faction.IsPlayer && pawn.equipment.Primary != null * && !PawnUtility.EnemiesAreNearby(pawn, 30, true) || (!pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.Torso) || !pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.Legs))) ||{ || return WorkPriority.Apparel; ||} */ return(WorkPriority.None); }
private static void Detour(Pawn_JobTracker __instance) { Profiler pro = null; __instance.jobsGivenThisTick = 0; __instance.jobsGivenThisTickTextual = ""; if (__instance.pawn.IsHashIntervalTick(30)) { pro = ProfileController.Start("DetermineNextConstantThinkTreeJob"); var thinkResult = __instance.DetermineNextConstantThinkTreeJob(); pro.Stop(); if (thinkResult.IsValid) { pro = ProfileController.Start("ShouldStartJobFromThinkTree"); if (__instance.ShouldStartJobFromThinkTree(thinkResult)) { __instance.CheckLeaveJoinableLordBecauseJobIssued(thinkResult); __instance.StartJob(thinkResult.Job, JobCondition.InterruptForced, thinkResult.SourceNode, false, false, __instance.pawn.thinker.ConstantThinkTree, thinkResult.Tag); } else if (thinkResult.Job != __instance.curJob && !__instance.jobQueue.Contains(thinkResult.Job)) { JobMaker.ReturnToPool(thinkResult.Job); } pro.Stop(); } } if (__instance.curDriver != null) { if (__instance.curJob.expiryInterval > 0 && (Find.TickManager.TicksGame - __instance.curJob.startTick) % __instance.curJob.expiryInterval == 0 && Find.TickManager.TicksGame != __instance.curJob.startTick) { pro = ProfileController.Start("EnemiesAreNearby"); var enemies = !__instance.curJob.expireRequiresEnemiesNearby || PawnUtility.EnemiesAreNearby(__instance.pawn, 25); pro.Stop(); if (enemies) { if (__instance.debugLog) { __instance.DebugLogEvent("Job expire"); } if (!__instance.curJob.checkOverrideOnExpire) { pro = ProfileController.Start("EndCurrentJob"); __instance.EndCurrentJob(JobCondition.Succeeded); pro.Stop(); } else { pro = ProfileController.Start("CheckForJobOverride"); __instance.CheckForJobOverride(); pro.Stop(); } pro = ProfileController.Start("FinalizeTick"); __instance.FinalizeTick(); pro.Stop(); return; } if (__instance.debugLog) { __instance.DebugLogEvent("Job expire skipped because there are no enemies nearby"); } } var key = string.Empty; if (PerPawn) { key = __instance.pawn.LabelShort + __instance.curDriver.job?.def.defName; } else { key = __instance.curDriver.job?.def.defName; } string label() { var daffy = string.Empty; if (PerPawn) { daffy = $"{__instance.pawn.LabelShort} {__instance.curDriver.job?.def?.defName} - {__instance.curDriver.job?.def?.driverClass} - {__instance.curDriver.job?.def?.modContentPack?.Name}"; } else { daffy = $"{__instance.curDriver.job?.def?.defName} - {__instance.curDriver.job?.def?.driverClass} - {__instance.curDriver.job?.def?.modContentPack?.Name}"; } return(daffy); } var meth = AccessTools.Method(__instance.curDriver.job?.def?.driverClass, "DriverTick"); pro = ProfileController.Start(key, label, __instance.curDriver.job?.def?.driverClass, __instance.curDriver.job?.def, __instance.pawn, meth); __instance.curDriver.DriverTick(); pro.Stop(); } if (__instance.curJob == null && !__instance.pawn.Dead && __instance.pawn.mindState.Active) { pro = ProfileController.Start("CanDoAnyJob"); var doit = __instance.CanDoAnyJob(); pro.Stop(); if (doit) { if (__instance.debugLog) { __instance.DebugLogEvent("Starting job from Tick because curJob == null."); } pro = ProfileController.Start("FinalizeTick"); __instance.TryFindAndStartJob(); pro.Stop(); } } pro = ProfileController.Start("FinalizeTick"); __instance.FinalizeTick(); pro.Stop(); }
public void MindStateTick() { if (this.wantsToTradeWithColony) { TradeUtility.CheckInteractWithTradersTeachOpportunity(this.pawn); } if (this.meleeThreat != null && !this.MeleeThreatStillThreat) { this.meleeThreat = null; } this.mentalStateHandler.MentalStateHandlerTick(); this.mentalBreaker.MentalBreakerTick(); this.inspirationHandler.InspirationHandlerTick(); if (this.pawn.CurJob == null || this.pawn.jobs.curDriver.layingDown == LayingDownState.NotLaying) { this.applyBedThoughtsTick = 0; } if (this.pawn.IsHashIntervalTick(100)) { if (this.pawn.Spawned) { int regionsToScan = (!this.anyCloseHostilesRecently) ? 18 : 24; this.anyCloseHostilesRecently = PawnUtility.EnemiesAreNearby(this.pawn, regionsToScan, true); } else { this.anyCloseHostilesRecently = false; } } if (this.willJoinColonyIfRescued && this.pawn.Spawned && this.pawn.IsHashIntervalTick(30)) { if (this.pawn.Faction == Faction.OfPlayer) { this.willJoinColonyIfRescued = false; } else if (this.pawn.CanReachMapEdge()) { foreach (Pawn current in this.pawn.Map.mapPawns.FreeColonistsSpawned) { if (current.IsColonistPlayerControlled) { this.PrisonerRescued(current); break; } } } else { Room room = this.pawn.GetRoom(RegionType.Set_Passable); if (room != null) { List <Thing> containedAndAdjacentThings = room.ContainedAndAdjacentThings; for (int i = 0; i < containedAndAdjacentThings.Count; i++) { Pawn pawn = containedAndAdjacentThings[i] as Pawn; if (pawn != null && pawn.IsColonistPlayerControlled) { this.PrisonerRescued(pawn); break; } } } } } if (this.pawn.Spawned && this.pawn.IsWildMan() && !this.wildManEverReachedOutside && this.pawn.GetRoom(RegionType.Set_Passable) != null && this.pawn.GetRoom(RegionType.Set_Passable).TouchesMapEdge) { this.wildManEverReachedOutside = true; this.pawn.Map.reachability.ClearCache(); } }
private WorkPriority GetPriorityWork(Pawn pawn) { #region Traders have no work priority if (pawn.kindDef.trader) { return(WorkPriority.None); } #endregion //#region Pawns with non-idle jobs have no work priority //bool hasCurJob = pawn.CurJob != null; //JobDef jobDef = hasCurJob ? pawn.CurJob.def : null; //if (hasCurJob && !jobDef.isIdle) //{ // return WorkPriority.None; //} //#endregion bool hasPrimary = (pawn.equipment != null && pawn.equipment.Primary != null); CompAmmoUser primaryAmmoUser = hasPrimary ? pawn.equipment.Primary.TryGetComp <CompAmmoUser>() : hasWeaponInInventory(pawn) ? weaponInInventory(pawn) : null; #region Colonists with primary ammo-user and a loadout have no work priority if (pawn.Faction.IsPlayer && primaryAmmoUser != null) { Loadout loadout = pawn.GetLoadout(); // if (loadout != null && !loadout.Slots.NullOrEmpty()) if (loadout != null && loadout.SlotCount > 0) { return(WorkPriority.None); } } #endregion // Pawns without weapon.. if (!hasPrimary) { // With inventory && non-colonist && not stealing && little space left if (Unload(pawn)) { return(WorkPriority.Unloading); } // Without inventory || colonist || stealing || lots of space left if (!hasWeaponInInventory(pawn)) { return(WorkPriority.Weapon); } } CompInventory compInventory = pawn.TryGetComp <CompInventory>(); // Pawn with ammo-using weapon.. if (primaryAmmoUser != null && primaryAmmoUser.UseAmmo) { // Magazine size FloatRange magazineSize = new FloatRange(1f, 2f); LoadoutPropertiesExtension loadoutPropertiesExtension = (LoadoutPropertiesExtension)(pawn.kindDef.modExtensions?.FirstOrDefault(x => x is LoadoutPropertiesExtension)); bool hasWeaponTags = pawn.kindDef.weaponTags?.Any() ?? false; if (hasWeaponTags && primaryAmmoUser.parent.def.weaponTags.Any(pawn.kindDef.weaponTags.Contains) && loadoutPropertiesExtension != null && loadoutPropertiesExtension.primaryMagazineCount != FloatRange.Zero) { magazineSize.min = loadoutPropertiesExtension.primaryMagazineCount.min; magazineSize.max = loadoutPropertiesExtension.primaryMagazineCount.max; } magazineSize.min *= primaryAmmoUser.Props.magazineSize; magazineSize.max *= primaryAmmoUser.Props.magazineSize; // Number of things in inventory that could be put in the weapon int viableAmmoCarried = 0; float viableAmmoBulk = 0; foreach (AmmoLink link in primaryAmmoUser.Props.ammoSet.ammoTypes) { var count = compInventory.AmmoCountOfDef(link.ammo); viableAmmoCarried += count; viableAmmoBulk += count * link.ammo.GetStatValueAbstract(CE_StatDefOf.Bulk); } // ~2/3rds of the inventory bulk minus non-usable and non-ammo bulk could be filled with ammo float potentialAmmoBulk = ammoFractionOfNonAmmoInventory * (compInventory.capacityBulk - compInventory.currentBulk + viableAmmoBulk); // There's less ammo [bulk] than fits the potential ammo bulk [bulk] if (viableAmmoBulk < potentialAmmoBulk) { // There's less ammo [nr] than fits a clip [nr] if (primaryAmmoUser.Props.magazineSize == 0 || viableAmmoCarried < magazineSize.min) { return(Unload(pawn) ? WorkPriority.Unloading : WorkPriority.LowAmmo); } // There's less ammo [nr] than fits two clips [nr] && no enemies are close if (viableAmmoCarried < magazineSize.max && !PawnUtility.EnemiesAreNearby(pawn, 20, true)) { return(Unload(pawn) ? WorkPriority.Unloading : WorkPriority.Ammo); } } } return(WorkPriority.None); }
public void MindStateTick() { if (this.wantsToTradeWithColony) { TradeUtility.CheckInteractWithTradersTeachOpportunity(this.pawn); } if (this.meleeThreat != null && !this.MeleeThreatStillThreat) { this.meleeThreat = null; } this.mentalStateHandler.MentalStateHandlerTick(); this.mentalBreaker.MentalBreakerTick(); this.inspirationHandler.InspirationHandlerTick(); if (!this.pawn.GetPosture().Laying()) { this.applyBedThoughtsTick = 0; } if (this.pawn.IsHashIntervalTick(100)) { if (this.pawn.Spawned) { int regionsToScan = (!this.anyCloseHostilesRecently) ? 18 : 24; this.anyCloseHostilesRecently = PawnUtility.EnemiesAreNearby(this.pawn, regionsToScan, true); } else { this.anyCloseHostilesRecently = false; } } if (this.WillJoinColonyIfRescued && this.pawn.Spawned && this.pawn.IsHashIntervalTick(30)) { if (this.pawn.Faction == Faction.OfPlayer) { this.WillJoinColonyIfRescued = false; } else if (this.pawn.IsPrisoner && !this.pawn.HostFaction.HostileTo(Faction.OfPlayer)) { this.WillJoinColonyIfRescued = false; } else if (!this.pawn.IsPrisoner && this.pawn.Faction != null && this.pawn.Faction.HostileTo(Faction.OfPlayer) && !this.pawn.Downed) { this.WillJoinColonyIfRescued = false; } else { foreach (Pawn pawn in this.pawn.Map.mapPawns.FreeColonistsSpawned) { if (pawn.IsColonistPlayerControlled && pawn.Position.InHorDistOf(this.pawn.Position, 4f) && GenSight.LineOfSight(this.pawn.Position, pawn.Position, this.pawn.Map, false, null, 0, 0)) { this.JoinColonyBecauseRescuedBy(pawn); break; } } } } if (this.pawn.Spawned && this.pawn.IsWildMan() && !this.WildManEverReachedOutside && this.pawn.GetRoom(RegionType.Set_Passable) != null && this.pawn.GetRoom(RegionType.Set_Passable).TouchesMapEdge) { this.WildManEverReachedOutside = true; } if (Find.TickManager.TicksGame % 123 == 0 && this.pawn.Spawned && this.pawn.RaceProps.IsFlesh && this.pawn.needs.mood != null) { TerrainDef terrain = this.pawn.Position.GetTerrain(this.pawn.Map); if (terrain.traversedThought != null) { this.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(terrain.traversedThought); } WeatherDef curWeatherLerped = this.pawn.Map.weatherManager.CurWeatherLerped; if (curWeatherLerped.exposedThought != null && !this.pawn.Position.Roofed(this.pawn.Map)) { this.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(curWeatherLerped.exposedThought); } } if (GenLocalDate.DayTick(this.pawn) == 0) { this.interactionsToday = 0; } }
static bool Prefix(Pawn_MindState __instance) { if (!__instance.pawn.NonHumanlikeOrWildMan() && (UmbrellaDefMethods.HasUmbrella(__instance.pawn) || (RimbrellasMod.settings.cowboyHatsPreventSoakingWet && UmbrellaDefMethods.HasCowboyHat(__instance.pawn)))) { if (__instance.wantsToTradeWithColony) { TradeUtility.CheckInteractWithTradersTeachOpportunity(__instance.pawn); } if (__instance.meleeThreat != null && !__instance.MeleeThreatStillThreat) { __instance.meleeThreat = null; } __instance.mentalStateHandler.MentalStateHandlerTick(); __instance.mentalBreaker.MentalBreakerTick(); __instance.inspirationHandler.InspirationHandlerTick(); if (!__instance.pawn.GetPosture().Laying()) { __instance.applyBedThoughtsTick = 0; } if (__instance.pawn.IsHashIntervalTick(100)) { if (__instance.pawn.Spawned) { int regionsToScan = __instance.anyCloseHostilesRecently ? 24 : 18; __instance.anyCloseHostilesRecently = PawnUtility.EnemiesAreNearby(__instance.pawn, regionsToScan, passDoors: true); } else { __instance.anyCloseHostilesRecently = false; } } if (__instance.WillJoinColonyIfRescued && __instance.AnythingPreventsJoiningColonyIfRescued) { __instance.WillJoinColonyIfRescued = false; } if (__instance.pawn.Spawned && __instance.pawn.IsWildMan() && !__instance.WildManEverReachedOutside && __instance.pawn.GetRoom() != null && __instance.pawn.GetRoom().TouchesMapEdge) { __instance.WildManEverReachedOutside = true; } if (Find.TickManager.TicksGame % 123 == 0 && __instance.pawn.Spawned && __instance.pawn.RaceProps.IsFlesh && __instance.pawn.needs.mood != null) { __instance.pawn.Drawer.renderer.graphics.ResolveAllGraphics(); TerrainDef terrain = __instance.pawn.Position.GetTerrain(__instance.pawn.Map); if (terrain.traversedThought != null) { __instance.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(terrain.traversedThought); } /*WeatherDef curWeatherLerped = __instance.pawn.Map.weatherManager.CurWeatherLerped; * if (curWeatherLerped.exposedThought != null && !__instance.pawn.Position.Roofed(__instance.pawn.Map)) { * __instance.pawn.needs.mood.thoughts.memories.TryGainMemoryFast(curWeatherLerped.exposedThought); * }*///this code would assign the Soaking Wet thought to a pawn outside in the rain, but we've already checked that the pawn has an umbrella } if (GenLocalDate.DayTick(__instance.pawn) == 0) { __instance.interactionsToday = 0; } return(false); } return(true); }
protected override Job TryGiveJob(Pawn pawn) { if (!Controller.settings.EnableAmmoSystem || !Controller.settings.AutoTakeAmmo) { return(null); } if (!pawn.RaceProps.Humanlike || (pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent))) { return(null); } if (pawn.Faction.IsPlayer && pawn.Drafted) { return(null); } if (!Rand.MTBEventOccurs(60, 1, 30)) { return(null); } // Log.Message(pawn.ToString() + " - priority:" + (GetPriorityWork(pawn)).ToString() + " capacityWeight: " + pawn.TryGetComp<CompInventory>().capacityWeight.ToString() + " currentWeight: " + pawn.TryGetComp<CompInventory>().currentWeight.ToString() + " capacityBulk: " + pawn.TryGetComp<CompInventory>().capacityBulk.ToString() + " currentBulk: " + pawn.TryGetComp<CompInventory>().currentBulk.ToString()); var brawler = (pawn.story != null && pawn.story.traits != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler)); CompInventory inventory = pawn.TryGetComp <CompInventory>(); bool hasPrimary = (pawn.equipment != null && pawn.equipment.Primary != null); CompAmmoUser primaryammouser = hasPrimary ? pawn.equipment.Primary.TryGetComp <CompAmmoUser>() : null; if (inventory != null) { // Prefer ranged weapon in inventory if (!pawn.Faction.IsPlayer && hasPrimary && pawn.equipment.Primary.def.IsMeleeWeapon && !brawler) { if ((pawn.skills.GetSkill(SkillDefOf.Shooting).Level >= pawn.skills.GetSkill(SkillDefOf.Melee).Level || pawn.skills.GetSkill(SkillDefOf.Shooting).Level >= 6)) { ThingWithComps InvListGun3 = inventory.rangedWeaponList.Find(thing => thing.TryGetComp <CompAmmoUser>() != null && thing.TryGetComp <CompAmmoUser>().HasAmmoOrMagazine); if (InvListGun3 != null) { inventory.TrySwitchToWeapon(InvListGun3); } } } // Drop excess ranged weapon if (!pawn.Faction.IsPlayer && primaryammouser != null && GetPriorityWork(pawn) == WorkPriority.Unloading && inventory.rangedWeaponList.Count >= 1) { Thing ListGun = inventory.rangedWeaponList.Find(thing => thing.TryGetComp <CompAmmoUser>() != null && thing.def != pawn.equipment.Primary.def); if (ListGun != null) { Thing ammoListGun = null; if (!ListGun.TryGetComp <CompAmmoUser>().HasAmmoOrMagazine) { foreach (AmmoLink link in ListGun.TryGetComp <CompAmmoUser>().Props.ammoSet.ammoTypes) { if (inventory.ammoList.Find(thing => thing.def == link.ammo) == null) { ammoListGun = ListGun; break; } } } if (ammoListGun != null) { Thing droppedWeapon; if (inventory.container.TryDrop(ListGun, pawn.Position, pawn.Map, ThingPlaceMode.Near, ListGun.stackCount, out droppedWeapon)) { pawn.jobs.EndCurrentJob(JobCondition.None, true); pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.DropEquipment, droppedWeapon, 30, true)); } } } } // Find and drop not need ammo from inventory if (!pawn.Faction.IsPlayer && hasPrimary && inventory.ammoList.Count > 1 && GetPriorityWork(pawn) == WorkPriority.Unloading) { Thing WrongammoThing = null; WrongammoThing = primaryammouser != null ? inventory.ammoList.Find(thing => !primaryammouser.Props.ammoSet.ammoTypes.Any(a => a.ammo == thing.def)) : inventory.ammoList.RandomElement <Thing>(); if (WrongammoThing != null) { Thing InvListGun = inventory.rangedWeaponList.Find(thing => hasPrimary && thing.TryGetComp <CompAmmoUser>() != null && thing.def != pawn.equipment.Primary.def); if (InvListGun != null) { Thing ammoInvListGun = null; foreach (AmmoLink link in InvListGun.TryGetComp <CompAmmoUser>().Props.ammoSet.ammoTypes) { ammoInvListGun = inventory.ammoList.Find(thing => thing.def == link.ammo); break; } if (ammoInvListGun != null && ammoInvListGun != WrongammoThing) { Thing droppedThingAmmo; if (inventory.container.TryDrop(ammoInvListGun, pawn.Position, pawn.Map, ThingPlaceMode.Near, ammoInvListGun.stackCount, out droppedThingAmmo)) { pawn.jobs.EndCurrentJob(JobCondition.None, true); pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.DropEquipment, 30, true)); } } } else { Thing droppedThing; if (inventory.container.TryDrop(WrongammoThing, pawn.Position, pawn.Map, ThingPlaceMode.Near, WrongammoThing.stackCount, out droppedThing)) { pawn.jobs.EndCurrentJob(JobCondition.None, true); pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.DropEquipment, 30, true)); } } } } Room room = RegionAndRoomQuery.RoomAtFast(pawn.Position, pawn.Map); // Find weapon in inventory and try to switch if any ammo in inventory. if (GetPriorityWork(pawn) == WorkPriority.Weapon && !hasPrimary) { ThingWithComps InvListGun2 = inventory.rangedWeaponList.Find(thing => thing.TryGetComp <CompAmmoUser>() != null); if (InvListGun2 != null) { Thing ammoInvListGun2 = null; foreach (AmmoLink link in InvListGun2.TryGetComp <CompAmmoUser>().Props.ammoSet.ammoTypes) { ammoInvListGun2 = inventory.ammoList.Find(thing => thing.def == link.ammo); break; } if (ammoInvListGun2 != null) { inventory.TrySwitchToWeapon(InvListGun2); } } // Find weapon with near ammo for ai. if (!pawn.Faction.IsPlayer) { Predicate <Thing> validatorWS = (Thing w) => w.def.IsWeapon && w.MarketValue > 5 && pawn.CanReserve(w, 1) && pawn.Position.InHorDistOf(w.Position, fixedsearchrange(pawn, w, 30f)) && pawn.CanReach(w, PathEndMode.Touch, Danger.Deadly, true) && (pawn.Faction.HostileTo(Faction.OfPlayer) || pawn.Faction == Faction.OfPlayer || (!pawn.Faction.HostileTo(Faction.OfPlayer) && !pawn.Map.areaManager.Home[w.Position])); // generate a list of all weapons (this includes melee weapons) List <Thing> allWeapons = ( from w in pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.HaulableAlways) where validatorWS(w) orderby w.MarketValue - w.Position.DistanceToSquared(pawn.Position) * 2f descending select w ).ToList(); // now just get the ranged weapons out... List <Thing> rangedWeapons = allWeapons.Where(w => w.def.IsRangedWeapon).ToList(); if (!rangedWeapons.NullOrEmpty()) { foreach (Thing thing in rangedWeapons) { if (thing.TryGetComp <CompAmmoUser>() == null) { // pickup a non-CE ranged weapon... int numToThing = 0; if (inventory.CanFitInInventory(thing, out numToThing)) { return(new Job(JobDefOf.Equip, thing) { checkOverrideOnExpire = true, expiryInterval = 100 }); } } else { // pickup a CE ranged weapon... List <ThingDef> thingDefAmmoList = thing.TryGetComp <CompAmmoUser>().Props.ammoSet.ammoTypes.Select(g => g.ammo as ThingDef).ToList(); Predicate <Thing> validatorA = (Thing t) => t.def.category == ThingCategory.Item && t is AmmoThing && pawn.CanReserve(t, 1) && pawn.Position.InHorDistOf(t.Position, fixedsearchrange(pawn, t, 30f)) && pawn.CanReach(t, PathEndMode.Touch, Danger.Deadly, true) && (pawn.Faction.HostileTo(Faction.OfPlayer) || pawn.Faction == Faction.OfPlayer || (!pawn.Faction.HostileTo(Faction.OfPlayer) && !pawn.Map.areaManager.Home[t.Position])); List <Thing> thingAmmoList = ( from t in pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.HaulableAlways) where validatorA(t) select t ).ToList(); if (thingAmmoList.Count > 0 && thingDefAmmoList.Count > 0) { int desiredStackSize = thing.TryGetComp <CompAmmoUser>().Props.magazineSize * 2; Thing th = thingAmmoList.FirstOrDefault(x => thingDefAmmoList.Contains(x.def) && x.stackCount > desiredStackSize); if (th != null) { int numToThing = 0; if (inventory.CanFitInInventory(thing, out numToThing)) { return(new Job(JobDefOf.Equip, thing) { checkOverrideOnExpire = true, expiryInterval = 100 }); } } } else if (isGrenade(thing) && grenadeCountInInventory(pawn, inventory) < 5) { int numToThing = thing.stackCount > 7 ? 7 : thing.stackCount; if (inventory.CanFitInInventory(thing, out numToThing)) { return(new Job(JobDefOf.TakeInventory, thing) { count = Mathf.RoundToInt(numToThing * 0.8f), checkOverrideOnExpire = true, expiryInterval = 150 }); } } } } } // else if no ranged weapons with nearby ammo was found, lets consider a melee weapon. if (allWeapons != null && allWeapons.Count > 0) { // since we don't need to worry about ammo, just pick one. Thing meleeWeapon = allWeapons.FirstOrDefault(w => !w.def.IsRangedWeapon && w.def.IsMeleeWeapon); if (meleeWeapon != null) { return(new Job(JobDefOf.Equip, meleeWeapon) { checkOverrideOnExpire = true, expiryInterval = 100 }); } } } } // Find ammo if ((GetPriorityWork(pawn) == WorkPriority.Ammo || GetPriorityWork(pawn) == WorkPriority.LowAmmo) && primaryammouser != null) { List <ThingDef> curAmmoList = (from AmmoLink g in primaryammouser.Props.ammoSet.ammoTypes select g.ammo as ThingDef).ToList(); if (curAmmoList.Count > 0) { Predicate <Thing> validator = (Thing t) => t is AmmoThing && pawn.CanReserve(t, 1) && pawn.CanReach(t, PathEndMode.Touch, Danger.Deadly, true) && ((pawn.Faction.IsPlayer && !ForbidUtility.IsForbidden(t, pawn)) || (!pawn.Faction.IsPlayer && pawn.Position.InHorDistOf(t.Position, fixedsearchrange(pawn, t, 30f)))) && (pawn.Faction.HostileTo(Faction.OfPlayer) || pawn.Faction == Faction.OfPlayer || (!pawn.Faction.HostileTo(Faction.OfPlayer) && !pawn.Map.areaManager.Home[t.Position])); List <Thing> curThingList = ( from t in pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.HaulableAlways) where validator(t) select t ).ToList(); foreach (Thing th in curThingList) { foreach (ThingDef thd in curAmmoList) { if (thd == th.def) { //Defence from low count loot spam float thw = (th.GetStatValue(CE_StatDefOf.Bulk)) * th.stackCount; if (thw > 0.5f) { if (pawn.Faction.IsPlayer) { int SearchRadius = 0; if (GetPriorityWork(pawn) == WorkPriority.LowAmmo) { SearchRadius = 70; } else { SearchRadius = 30; } Thing closestThing = GenClosest.ClosestThingReachable( pawn.Position, pawn.Map, ThingRequest.ForDef(th.def), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.None, TraverseMode.ByPawn), SearchRadius, x => !x.IsForbidden(pawn) && pawn.CanReserve(x)); if (closestThing != null) { int numToCarry = 0; if (inventory.CanFitInInventory(th, out numToCarry)) { return(new Job(JobDefOf.TakeInventory, th) { count = numToCarry }); } } } else { int numToCarry = 0; if (inventory.CanFitInInventory(th, out numToCarry)) { return(new Job(JobDefOf.TakeInventory, th) { count = numToCarry, expiryInterval = 150, checkOverrideOnExpire = true }); } } } } } } } } // postfind grenade and ammos. if (!pawn.Faction.IsPlayer) { int minrange = 2; int maxrange = 14; float rangevariation = hasPrimary ? minrange : maxrange / 2; Predicate <Thing> validatorPost = (Thing w) => (isGrenade(w) || w is AmmoThing) && pawn.Position.InHorDistOf(w.Position, fixedsearchrange(pawn, w, maxrange, Mathf.RoundToInt(rangevariation + (maxrange / 2)), Mathf.RoundToInt(rangevariation + minrange))) && pawn.CanReach(w, PathEndMode.Touch, Danger.Deadly, true) && (pawn.Faction.HostileTo(Faction.OfPlayer) || (!pawn.Faction.HostileTo(Faction.OfPlayer) && !pawn.Map.areaManager.Home[w.Position])); List <Thing> allPostThings = ( from w in pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.HaulableAlways) where validatorPost(w) select w ).ToList(); // Look for grenades List <Thing> grenadelist = ( from g in allPostThings where g.def.IsWeapon && pawn.CanReserve(g, 1) orderby g.Position.DistanceToSquared(pawn.Position) * 2f descending select g ).ToList(); if (!grenadelist.NullOrEmpty() && grenadeCountInInventory(pawn, inventory) < 5) { foreach (Thing grenade in grenadelist) { int numToThing = grenade.stackCount > 7 ? 7 : grenade.stackCount; if (inventory.CanFitInInventory(grenade, out numToThing)) { return(new Job(JobDefOf.TakeInventory, grenade) { count = Mathf.RoundToInt(numToThing * 0.8f), expiryInterval = 150, checkOverrideOnExpire = true }); } } } if (hasPrimary && primaryammouser != null) { List <ThingDef> curAmmoList = (from AmmoLink g in primaryammouser.Props.ammoSet.ammoTypes select g.ammo as ThingDef).ToList(); if (curAmmoList.Count > 0) { List <Thing> ammolist = ( from p in allPostThings where p is AmmoThing && curAmmoList.Contains(p.def) && pawn.CanReserve(p, 1) orderby p.Position.DistanceToSquared(pawn.Position) * 2f descending select p ).ToList(); if (ammolist.Count > 0) { for (var i = 0; i < ammolist.Count; i++) { //try to take more ammo if it really nearby. int numToThing2 = 0; if (!inventory.CanFitInInventory(ammolist[i], out numToThing2)) { break; } if (PawnUtility.EnemiesAreNearby(pawn, 25, true)) { break; } if (pawn.Position.InHorDistOf(ammolist[i].Position, 4f)) { return(new Job(JobDefOf.TakeInventory, ammolist[i]) { count = numToThing2, expiryInterval = 150, checkOverrideOnExpire = true }); } } } } } } /* * if (!pawn.Faction.IsPlayer && pawn.apparel != null && GetPriorityWork(pawn) == WorkPriority.Apparel) * { * if (!pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.Torso)) * { * Apparel apparel = this.FindGarmentCoveringPart(pawn, BodyPartGroupDefOf.Torso); * if (apparel != null) * { * int numToapparel = 0; * if (inventory.CanFitInInventory(apparel, out numToapparel)) * { * return new Job(JobDefOf.Wear, apparel) * { * ignoreForbidden = true * }; * } * } * } * if (!pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.Legs)) * { * Apparel apparel2 = this.FindGarmentCoveringPart(pawn, BodyPartGroupDefOf.Legs); * if (apparel2 != null) * { * int numToapparel2 = 0; * if (inventory.CanFitInInventory(apparel2, out numToapparel2)) * { * return new Job(JobDefOf.Wear, apparel2) * { * ignoreForbidden = true * }; * } * } * } * if (!pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.FullHead)) * { * Apparel apparel3 = this.FindGarmentCoveringPart(pawn, BodyPartGroupDefOf.FullHead); * if (apparel3 != null) * { * int numToapparel3 = 0; * if (inventory.CanFitInInventory(apparel3, out numToapparel3)) * { * return new Job(JobDefOf.Wear, apparel3) * { * ignoreForbidden = true, * locomotionUrgency = LocomotionUrgency.Sprint * }; * } * } * } * } */ return(null); } return(null); }
private WorkPriority GetPriorityWork(Pawn pawn) { CompAmmoUser primaryammouser = pawn.equipment.Primary.TryGetComp <CompAmmoUser>(); if (pawn.Faction.IsPlayer && pawn.equipment.Primary != null && pawn.equipment.Primary.TryGetComp <CompAmmoUser>() != null) { Loadout loadout = pawn.GetLoadout(); // if (loadout != null && !loadout.Slots.NullOrEmpty()) if (loadout != null && loadout.SlotCount > 0) { return(WorkPriority.None); } } if (pawn.kindDef.trader) { return(WorkPriority.None); } if (pawn.jobs.curJob != null && pawn.jobs.curJob.def == JobDefOf.Tame) { return(WorkPriority.None); } if (pawn.equipment.Primary == null) { if (Unload(pawn)) { return(WorkPriority.Unloading); } else { return(WorkPriority.Weapon); } } if (pawn.equipment.Primary != null && primaryammouser != null) { int ammocount = 0; foreach (ThingDef ammoDef in primaryammouser.Props.ammoSet.ammoTypes) { Thing ammoThing; ammoThing = pawn.TryGetComp <CompInventory>().ammoList.Find(thing => thing.def == ammoDef); if (ammoThing != null) { ammocount += ammoThing.stackCount; } } float atw = primaryammouser.currentAmmo.GetStatValueAbstract(CR_StatDefOf.Bulk); if ((ammocount < (1.5f / atw)) && ((1.5f / atw) > 3)) { if (Unload(pawn)) { return(WorkPriority.Unloading); } else { return(WorkPriority.LowAmmo); } } if (!PawnUtility.EnemiesAreNearby(pawn, 30, true)) { if ((ammocount < (3.5f / atw)) && ((3.5f / atw) > 4)) { if (Unload(pawn)) { return(WorkPriority.Unloading); } else { return(WorkPriority.Ammo); } } } } if (!pawn.Faction.IsPlayer && pawn.equipment.Primary != null && !PawnUtility.EnemiesAreNearby(pawn, 30, true) || (!pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.Torso) || !pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.Legs))) { return(WorkPriority.Apparel); } else { return(WorkPriority.None); } }
public static bool CheckForAutoAttack(Verse.AI.JobDriver_Wait __instance) { Pawn this_pawn = __instance.pawn; if (this_pawn.Downed || this_pawn.stances.FullBodyBusy) { return(false); } Map map = this_pawn.Map; List <Thing> fireList = map.listerThings.ThingsOfDef(ThingDefOf.Fire); bool flag = PawnUtility.EnemiesAreNearby(this_pawn, 1) && !this_pawn.WorkTagIsDisabled(WorkTags.Violent); bool flag2 = this_pawn.RaceProps.ToolUser && this_pawn.Faction == Faction.OfPlayer && !this_pawn.WorkTagIsDisabled(WorkTags.Firefighting) && (!this_pawn.InMentalState || this_pawn.MentalState.def.allowBeatfire); if (!flag && !flag2) { return(false); } __instance.collideWithPawns = false; Fire fire = null; for (int i = 0; i < 9; i++) { IntVec3 c = this_pawn.Position + GenAdj.AdjacentCellsAndInside[i]; if (c.InBounds(map)) { Thing[] thingList; List <Thing> thingList1 = c.GetThingList(map); lock (thingList1) { thingList = thingList1.ToArray(); } for (int j = 0; j < thingList.Length; j++) { if (flag) { Pawn pawn = thingList[j] as Pawn; if (pawn != null && !pawn.Downed && this_pawn.HostileTo(pawn) && GenHostility.IsActiveThreatTo(pawn, this_pawn.Faction)) { this_pawn.meleeVerbs.TryMeleeAttack(pawn, null, false); __instance.collideWithPawns = true; return(false); } } if (flag2) { Fire fire2 = thingList[j] as Fire; if (fire2 != null && (fire == null || fire2.fireSize < fire.fireSize || i == 8) && (fire2.parent == null || fire2.parent != this_pawn)) { fire = fire2; } } } } } if (fire != null) { this_pawn.natives.TryBeatFire(fire); return(false); } if (flag && __instance.job.canUseRangedWeapon && this_pawn.Faction != null && __instance.job.def == JobDefOf.Wait_Combat && (this_pawn.drafter == null || this_pawn.drafter.FireAtWill)) { Verb currentEffectiveVerb = this_pawn.CurrentEffectiveVerb; if (currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; if (currentEffectiveVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(this_pawn, targetScanFlags, null, 0f, 9999f); if (thing != null) { this_pawn.TryStartAttack(thing); __instance.collideWithPawns = true; return(false); } } } return(false); }