private void MakeDowned(DamageInfo?dinfo, Hediff hediff) { if (this.Downed) { Log.Error(this.pawn + " tried to do MakeDowned while already downed.", false); return; } if (this.pawn.guilt != null && this.pawn.GetLord() != null && this.pawn.GetLord().LordJob != null && this.pawn.GetLord().LordJob.GuiltyOnDowned) { this.pawn.guilt.Notify_Guilty(); } this.healthState = PawnHealthState.Down; PawnDiedOrDownedThoughtsUtility.TryGiveThoughts(this.pawn, dinfo, PawnDiedOrDownedThoughtsKind.Downed); if (this.pawn.InMentalState) { this.pawn.mindState.mentalStateHandler.CurState.RecoverFromState(); } if (this.pawn.Spawned) { this.pawn.DropAndForbidEverything(true); this.pawn.stances.CancelBusyStanceSoft(); } this.pawn.ClearMind(true); if (Current.ProgramState == ProgramState.Playing) { Lord lord = this.pawn.GetLord(); if (lord != null) { lord.Notify_PawnLost(this.pawn, PawnLostCondition.IncappedOrKilled, dinfo); } } if (this.pawn.Drafted) { this.pawn.drafter.Drafted = false; } PortraitsCache.SetDirty(this.pawn); if (this.pawn.SpawnedOrAnyParentSpawned) { GenHostility.Notify_PawnLostForTutor(this.pawn, this.pawn.MapHeld); } if (this.pawn.RaceProps.Humanlike && Current.ProgramState == ProgramState.Playing && this.pawn.SpawnedOrAnyParentSpawned) { if (this.pawn.HostileTo(Faction.OfPlayer)) { LessonAutoActivator.TeachOpportunity(ConceptDefOf.Capturing, this.pawn, OpportunityType.Important); } if (this.pawn.Faction == Faction.OfPlayer) { LessonAutoActivator.TeachOpportunity(ConceptDefOf.Rescuing, this.pawn, OpportunityType.Critical); } } if (dinfo != null && dinfo.Value.Instigator != null) { Pawn pawn = dinfo.Value.Instigator as Pawn; if (pawn != null) { RecordsUtility.Notify_PawnDowned(this.pawn, pawn); } } if (this.pawn.Spawned) { TaleRecorder.RecordTale(TaleDefOf.Downed, new object[] { this.pawn, (dinfo == null) ? null : (dinfo.Value.Instigator as Pawn), (dinfo == null) ? null : dinfo.Value.Weapon }); Find.BattleLog.Add(new BattleLogEntry_StateTransition(this.pawn, RulePackDefOf.Transition_Downed, (dinfo == null) ? null : (dinfo.Value.Instigator as Pawn), hediff, (dinfo == null) ? null : dinfo.Value.HitPart)); } Find.Storyteller.Notify_PawnEvent(this.pawn, AdaptationEvent.Downed, dinfo); }
protected override Job TryGiveJob(Pawn pawn) { bool flag = forceCanDig || (pawn.mindState.duty != null && pawn.mindState.duty.canDig && !pawn.CanReachMapEdge()) || (forceCanDigIfCantReachMapEdge && !pawn.CanReachMapEdge()) || (forceCanDigIfAnyHostileActiveThreat && pawn.Faction != null && GenHostility.AnyHostileActiveThreatTo(pawn.Map, pawn.Faction, countDormantPawnsAsHostile: true)); if (!TryFindGoodExitDest(pawn, flag, out var dest)) { return(null); } if (flag) { using PawnPath path = pawn.Map.pathFinder.FindPath(pawn.Position, dest, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.PassAllDestroyableThings)); IntVec3 cellBefore; Thing thing = path.FirstBlockingBuilding(out cellBefore, pawn); if (thing != null) { Job job = DigUtility.PassBlockerJob(pawn, thing, cellBefore, canMineMineables: true, canMineNonMineables: true); if (job != null) { return(job); } } } Job job2 = JobMaker.MakeJob(JobDefOf.Goto, dest); job2.exitMapOnArrival = true; job2.failIfCantJoinOrCreateCaravan = failIfCantJoinOrCreateCaravan; job2.locomotionUrgency = PawnUtility.ResolveLocomotion(pawn, defaultLocomotion, LocomotionUrgency.Jog); job2.expiryInterval = jobMaxDuration; job2.canBash = canBash; return(job2); }
public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = float.MaxValue, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true) { Thing searcherThing = searcher.Thing; Pawn searcherPawn = searcher as Pawn; Verb verb = searcher.CurrentEffectiveVerb; if (verb == null) { Log.Error("BestAttackTarget with " + searcher.ToStringSafe() + " who has no attack verb."); return(null); } bool onlyTargetMachines = verb.IsEMP(); float minDistSquared = minDist * minDist; float num = maxTravelRadiusFromLocus + verb.verbProps.range; float maxLocusDistSquared = num * num; Func <IntVec3, bool> losValidator = null; if ((flags & TargetScanFlags.LOSBlockableByGas) != 0) { losValidator = delegate(IntVec3 vec3) { Gas gas = vec3.GetGas(searcherThing.Map); return(gas == null || !gas.def.gas.blockTurretTracking); }; } Predicate <IAttackTarget> innerValidator = delegate(IAttackTarget t) { Thing thing = t.Thing; if (t == searcher) { return(false); } if (minDistSquared > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistSquared) { return(false); } if (!canTakeTargetsCloserThanEffectiveMinRange) { float num2 = verb.verbProps.EffectiveMinRange(thing, searcherThing); if (num2 > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < num2 * num2) { return(false); } } if (maxTravelRadiusFromLocus < 9999f && (float)(thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared) { return(false); } if (!searcherThing.HostileTo(thing)) { return(false); } if (validator != null && !validator(thing)) { return(false); } if (searcherPawn != null) { Lord lord = searcherPawn.GetLord(); if (lord != null && !lord.LordJob.ValidateAttackTarget(searcherPawn, thing)) { // Log.Messageage(thing + " lord ValidateAttackTarget: false"); return(false); } } if ((flags & TargetScanFlags.NeedNotUnderThickRoof) != 0) { RoofDef roof = thing.Position.GetRoof(thing.Map); if (roof != null && roof.isThickRoof) { // Log.Messageage(thing + " isThickRoof: false"); return(false); } } if ((flags & TargetScanFlags.NeedLOSToAll) != 0) { if (losValidator != null && (!losValidator(searcherThing.Position) || !losValidator(thing.Position))) { // Log.Messageage(thing + " LOSToAll: false"); return(false); } if (!searcherThing.CanSee(thing, losValidator)) { if (t is Pawn) { if ((flags & TargetScanFlags.NeedLOSToPawns) != 0) { // Log.Messageage(thing + " LOSToPawns: false"); return(false); } } else if ((flags & TargetScanFlags.NeedLOSToNonPawns) != 0) { // Log.Messageage(thing + " LOSToNonPawns: false"); return(false); } } } if (((flags & TargetScanFlags.NeedThreat) != 0 || (flags & TargetScanFlags.NeedAutoTargetable) != 0) && t.ThreatDisabled(searcher)) { // Log.Messageage(thing + " NeedThreat: false"); return(false); } if ((flags & TargetScanFlags.NeedAutoTargetable) != 0 && !IsAutoTargetable(t)) { // Log.Messageage(thing + " NeedAutoTargetable: false"); return(false); } if ((flags & TargetScanFlags.NeedActiveThreat) != 0 && !GenHostility.IsActiveThreatTo(t, searcher.Thing.Faction)) { // Log.Messageage(thing + " NeedActiveThreat: false"); return(false); } Pawn pawn = t as Pawn; if (onlyTargetMachines && pawn != null && pawn.RaceProps.IsFlesh) { // Log.Messageage(thing + " onlyTargetMachines: false"); return(false); } if ((flags & TargetScanFlags.NeedNonBurning) != 0 && thing.IsBurning()) { // Log.Messageage(thing + " NeedNonBurning: false"); return(false); } if (searcherThing.def.race != null && (int)searcherThing.def.race.intelligence >= 2) { CompExplosive compExplosive = thing.TryGetCompFast <CompExplosive>(); if (compExplosive != null && compExplosive.wickStarted) { // Log.Messageage(thing + " wickStarted: false"); return(false); } } if (thing.def.size.x == 1 && thing.def.size.z == 1) { if (thing.Position.Fogged(thing.Map)) { // Log.Messageage(thing + " Fogged: false"); return(false); } } else { bool flag2 = false; foreach (IntVec3 item in thing.OccupiedRect()) { if (!item.Fogged(thing.Map)) { flag2 = true; break; } } if (!flag2) { // Log.Messageage(thing + " Fogged: false"); return(false); } } // Log.Messageage(thing + " valid: true"); return(true); }; if (HasRangedAttack(searcher) && (searcherPawn == null || !searcherPawn.InAggroMentalState)) { // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack 0"); tmpTargets.Clear(); // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack 1"); tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher)); // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack 2 tmpTargets: " + tmpTargets.Count); if ((flags & TargetScanFlags.NeedReachable) != 0) { Predicate <IAttackTarget> oldValidator2 = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator2(t) && CanReach(searcherThing, t.Thing, canBash)); } // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack 3"); bool flag = false; for (int i = 0; i < tmpTargets.Count; i++) { IAttackTarget attackTarget = tmpTargets[i]; if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && CanShootAtFromCurrentPosition(attackTarget, searcher, verb)) { flag = true; break; } } // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack 4 "); IAttackTarget attackTarget2; if (flag) { tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x)); attackTarget2 = GetRandomShootingTargetByScore(tmpTargets, searcher, verb); } else { attackTarget2 = (IAttackTarget)GenClosest.ClosestThing_Global(validator: ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) == 0 || (flags & TargetScanFlags.NeedReachable) != 0) ? ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t))) : ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t) && (CanReach(searcherThing, t, canBash) || CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)))), center: searcherThing.Position, searchSet: tmpTargets, maxDistance: maxDist); } // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack 5"); tmpTargets.Clear(); // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack tgt found: " + (attackTarget2 != null).ToString()); return(attackTarget2); } // Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack no ranged attack found"); if (searcherPawn != null && searcherPawn.mindState.duty != null && searcherPawn.mindState.duty.radius > 0f && !searcherPawn.InMentalState) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator(t) && t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius)); } IAttackTarget attackTarget3 = (IAttackTarget)GenClosest.ClosestThingReachable(searcherThing.Position, searcherThing.Map, ThingRequest.ForGroup(ThingRequestGroup.AttackTarget), PathEndMode.Touch, TraverseParms.For(searcherPawn, Danger.Deadly, TraverseMode.ByPawn, canBash), maxDist, (Thing x) => innerValidator((IAttackTarget)x), null, 0, (maxDist > 800f) ? (-1) : 40); if (attackTarget3 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn)) { IAttackTarget attackTarget4 = FindBestReachableMeleeTarget(innerValidator, searcherPawn, maxDist, canBash); if (attackTarget4 != null) { float lengthHorizontal = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal; float lengthHorizontal2 = (searcherPawn.Position - attackTarget4.Thing.Position).LengthHorizontal; if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50f) { attackTarget3 = attackTarget4; } } } return(attackTarget3); }
public static bool BestAttackTarget(ref IAttackTarget __result, IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.40282347E+38f, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true) { Thing searcherThing = searcher.Thing; Pawn searcherPawn = searcher as Pawn; Verb verb = searcher.CurrentEffectiveVerb; if (verb == null) { Log.Error("BestAttackTarget with " + searcher.ToStringSafe <IAttackTargetSearcher>() + " who has no attack verb.", false); __result = null; return(false); } bool onlyTargetMachines = verb.IsEMP(); float minDistSquared = minDist * minDist; float num = maxTravelRadiusFromLocus + verb.verbProps.range; float maxLocusDistSquared = num * num; Func <IntVec3, bool> losValidator = null; if ((flags & TargetScanFlags.LOSBlockableByGas) != TargetScanFlags.None) { losValidator = delegate(IntVec3 vec3) { Gas gas = vec3.GetGas(searcherThing.Map); return(gas == null || !gas.def.gas.blockTurretTracking); }; } Predicate <IAttackTarget> innerValidator = delegate(IAttackTarget t) { Thing thing = t.Thing; if (t == searcher) { return(false); } if (minDistSquared > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistSquared) { return(false); } if (!canTakeTargetsCloserThanEffectiveMinRange) { float num2 = verb.verbProps.EffectiveMinRange(thing, searcherThing); if (num2 > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < num2 * num2) { return(false); } } if (maxTravelRadiusFromLocus < 9999f && (float)(thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared) { return(false); } if (!searcherThing.HostileTo(thing)) { return(false); } if (validator != null && !validator(thing)) { return(false); } if (searcherPawn != null) { Lord lord = searcherPawn.GetLord(); if (lord != null && !lord.LordJob.ValidateAttackTarget(searcherPawn, thing)) { return(false); } } if ((flags & TargetScanFlags.NeedNotUnderThickRoof) != TargetScanFlags.None) { RoofDef roof = thing.Position.GetRoof(thing.Map); if (roof != null && roof.isThickRoof) { return(false); } } if ((flags & TargetScanFlags.NeedLOSToAll) != TargetScanFlags.None) { if (losValidator != null && (!losValidator(searcherThing.Position) || !losValidator(thing.Position))) { return(false); } if (!searcherThing.CanSee(thing, losValidator)) { if (t is Pawn) { if ((flags & TargetScanFlags.NeedLOSToPawns) != TargetScanFlags.None) { return(false); } } else if ((flags & TargetScanFlags.NeedLOSToNonPawns) != TargetScanFlags.None) { return(false); } } } if (((flags & TargetScanFlags.NeedThreat) != TargetScanFlags.None || (flags & TargetScanFlags.NeedAutoTargetable) != TargetScanFlags.None) && t.ThreatDisabled(searcher)) { return(false); } if ((flags & TargetScanFlags.NeedAutoTargetable) != TargetScanFlags.None && !AttackTargetFinder.IsAutoTargetable(t)) { return(false); } if ((flags & TargetScanFlags.NeedActiveThreat) != TargetScanFlags.None && !GenHostility.IsActiveThreatTo(t, searcher.Thing.Faction)) { return(false); } Pawn pawn = t as Pawn; if (onlyTargetMachines && pawn != null && pawn.RaceProps.IsFlesh) { return(false); } if ((flags & TargetScanFlags.NeedNonBurning) != TargetScanFlags.None && thing.IsBurning()) { return(false); } if (searcherThing.def.race != null && searcherThing.def.race.intelligence >= Intelligence.Humanlike) { CompExplosive compExplosive = thing.TryGetComp <CompExplosive>(); if (compExplosive != null && compExplosive.wickStarted) { return(false); } } if (thing.def.size.x == 1 && thing.def.size.z == 1) { if (thing.Position.Fogged(thing.Map)) { return(false); } } else { bool flag2 = false; using (CellRect.Enumerator enumerator = thing.OccupiedRect().GetEnumerator()) { while (enumerator.MoveNext()) { if (!enumerator.Current.Fogged(thing.Map)) { flag2 = true; break; } } } if (!flag2) { return(false); } } return(true); }; if (HasRangedAttack(searcher) && (searcherPawn == null || !searcherPawn.InAggroMentalState)) { List <IAttackTarget> tmpTargets = new List <IAttackTarget>(); //AttackTargetFinder.tmpTargets.Clear(); tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher)); if ((flags & TargetScanFlags.NeedReachable) != TargetScanFlags.None) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator(t) && CanReach(searcherThing, t.Thing, canBash)); } bool flag = false; for (int i = 0; i < tmpTargets.Count; i++) { IAttackTarget attackTarget = tmpTargets[i]; if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && CanShootAtFromCurrentPosition(attackTarget, searcher, verb)) { flag = true; break; } } IAttackTarget result = null; if (flag) { tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x)); _ = GetRandomShootingTargetByScore(ref result, tmpTargets, searcher, verb); } else { Predicate <Thing> validator2; if ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) != TargetScanFlags.None && (flags & TargetScanFlags.NeedReachable) == TargetScanFlags.None) { validator2 = ((Thing t) => innerValidator((IAttackTarget)t) && (CanReach(searcherThing, t, canBash) || CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb))); } else { validator2 = ((Thing t) => innerValidator((IAttackTarget)t)); } result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, tmpTargets, maxDist, validator2, null); } tmpTargets.Clear(); __result = result; return(false); } if (searcherPawn != null && searcherPawn.mindState.duty != null && searcherPawn.mindState.duty.radius > 0f && !searcherPawn.InMentalState) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator(t) && t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius)); } IAttackTarget attackTarget2 = (IAttackTarget)GenClosest.ClosestThingReachable(searcherThing.Position, searcherThing.Map, ThingRequest.ForGroup(ThingRequestGroup.AttackTarget), PathEndMode.Touch, TraverseParms.For(searcherPawn, Danger.Deadly, TraverseMode.ByPawn, canBash), maxDist, (Thing x) => innerValidator((IAttackTarget)x), null, 0, (maxDist > 800f) ? -1 : 40, false, RegionType.Set_Passable, false); if (attackTarget2 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn)) { IAttackTarget attackTarget3 = FindBestReachableMeleeTarget(innerValidator, searcherPawn, maxDist, canBash); if (attackTarget3 != null) { float lengthHorizontal = (searcherPawn.Position - attackTarget2.Thing.Position).LengthHorizontal; float lengthHorizontal2 = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal; if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50f) { attackTarget2 = attackTarget3; } } } __result = attackTarget2; return(false); }
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); }
protected override Job TryGiveJob(Pawn pawn) { bool flag = false; if (this.forceCanDig || (pawn.mindState.duty != null && pawn.mindState.duty.canDig) || (this.forceCanDigIfCantReachMapEdge && !pawn.CanReachMapEdge()) || (this.forceCanDigIfAnyHostileActiveThreat && pawn.Faction != null && GenHostility.AnyHostileActiveThreatTo(pawn.Map, pawn.Faction))) { flag = true; } IntVec3 c; if (!this.TryFindGoodExitDest(pawn, flag, out c)) { return(null); } if (flag) { using (PawnPath pawnPath = pawn.Map.pathFinder.FindPath(pawn.Position, c, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.PassAllDestroyableThings, false), PathEndMode.OnCell)) { IntVec3 cellBeforeBlocker; Thing thing = pawnPath.FirstBlockingBuilding(out cellBeforeBlocker, pawn); if (thing != null) { Job job = DigUtility.PassBlockerJob(pawn, thing, cellBeforeBlocker, true, true); if (job != null) { return(job); } } } } return(new Job(JobDefOf.Goto, c) { exitMapOnArrival = true, failIfCantJoinOrCreateCaravan = this.failIfCantJoinOrCreateCaravan, locomotionUrgency = PawnUtility.ResolveLocomotion(pawn, this.defaultLocomotion, LocomotionUrgency.Jog), expiryInterval = this.jobMaxDuration, canBash = this.canBash }); }
private void FriendliesDead() { // All friendlies dead if (survivors && ((MapParent)parent).Map.mapPawns.FreeHumanlikesSpawnedOfFaction(parent.Faction).Count(p => GenHostility.IsActiveThreatTo(p, enemy)) == 0) { survivors = false; } }
private void CheckForAutoAttack() { if (base.pawn.Downed || base.pawn.stances.FullBodyBusy) { return; } collideWithPawns = false; bool flag = !base.pawn.WorkTagIsDisabled(WorkTags.Violent); bool flag2 = base.pawn.RaceProps.ToolUser && base.pawn.Faction == Faction.OfPlayer && !base.pawn.WorkTagIsDisabled(WorkTags.Firefighting); if (!(flag || flag2)) { return; } Fire fire = null; for (int i = 0; i < 9; i++) { IntVec3 c = base.pawn.Position + GenAdj.AdjacentCellsAndInside[i]; if (!c.InBounds(base.pawn.Map)) { continue; } List <Thing> thingList = c.GetThingList(base.Map); for (int j = 0; j < thingList.Count; j++) { if (flag) { Pawn pawn = thingList[j] as Pawn; if (pawn != null && !pawn.Downed && base.pawn.HostileTo(pawn) && GenHostility.IsActiveThreatTo(pawn, base.pawn.Faction)) { base.pawn.meleeVerbs.TryMeleeAttack(pawn); collideWithPawns = true; return; } } if (flag2) { Fire fire2 = thingList[j] as Fire; if (fire2 != null && (fire == null || fire2.fireSize < fire.fireSize || i == 8) && (fire2.parent == null || fire2.parent != base.pawn)) { fire = fire2; } } } } if (fire != null && (!base.pawn.InMentalState || base.pawn.MentalState.def.allowBeatfire)) { base.pawn.natives.TryBeatFire(fire); } else { if (!flag || !job.canUseRangedWeapon || base.pawn.Faction == null || job.def != JobDefOf.Wait_Combat || (base.pawn.drafter != null && !base.pawn.drafter.FireAtWill)) { return; } Verb currentEffectiveVerb = base.pawn.CurrentEffectiveVerb; if (currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToAll | TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; if (currentEffectiveVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(base.pawn, targetScanFlags); if (thing != null) { base.pawn.TryStartAttack(thing); collideWithPawns = true; } } } }
public bool BuildingClaimableBy(Building building, Pawn by, CellRect cellRect) { //Log.Warning($"[ZzZomboRW.CompClaimable] Check: pawn={by}, int.={by.RaceProps.intelligence}, building={building}, claimable = {building.def.Claimable}, `by.faction`={by.Faction}, tooluser={by.RaceProps.ToolUser}, is wild={by.IsWildMan()}."); //Log.Warning($"[ZzZomboRW.CompClaimable] Condition: factions={building.Faction == by.Faction || building.Faction == Faction.OfMechanoids}."); //Log.Warning($"[ZzZomboRW.CompClaimable] Condition: enemies={!building.Faction.HostileTo(by.Faction)}."); //Log.Warning($"[ZzZomboRW.CompClaimable] Condition: hives={HiveUtility.AnyHivePreventsClaiming(building)}."); if (by == null || building == null || !building.Spawned || !building.def.Claimable || by.Faction == null || !by.RaceProps.ToolUser || by.IsWildMan()) { return(false); } if (building.Faction == by.Faction || building.Faction == Faction.OfMechanoids) { return(false); } if (!building.Faction.HostileTo(by.Faction)) { return(false); } if (by.Faction != Faction.OfPlayer) { if (!this.Props.byEnemies) { //Log.Warning("[ZzZomboRW.CompClaimable] Check: by enemies=false."); return(false); } } else { if (!this.Props.byPlayer || building.Fogged()) { //Log.Warning($"[ZzZomboRW.CompClaimable] Check: by player={this.Props.byPlayer}."); //Log.Warning($"[ZzZomboRW.CompClaimable] Check: fogged={building.Fogged()}."); return(false); } } if (!GenHostility.IsActiveThreatTo(by, building.Faction)) { //Log.Warning("[ZzZomboRW.CompClaimable] Check: not a threat."); return(false); } foreach (var pawn in building.Map.mapPawns.SpawnedPawnsInFaction(by.Faction)) { if (pawn.mindState?.enemyTarget == building) { //Log.Warning("[ZzZomboRW.CompClaimable] Check: target."); return(false); } } if (HiveUtility.AnyHivePreventsClaiming(building)) { return(false); } var dest = new LocalTargetInfo(building); foreach (var c in cellRect) { foreach (var t in c.GetThingList(building.Map)) { if (t is Pawn pawn && pawn.RaceProps.ToolUser && GenHostility.IsActiveThreatTo(pawn, by.Faction) && GenSight.LineOfSightToThing(pawn.Position, building, building.Map) && pawn.CanReach(dest, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { //Log.Warning($"[ZzZomboRW.CompClaimable] Check: {pawn} prevents capture."); return(false); } } } //Log.Warning($"[ZzZomboRW.CompClaimable] Condition: reachable={GenSight.LineOfSightToThing(by.Position, building, building.Map) && by.CanReach(dest, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)}!"); return(GenSight.LineOfSightToThing(by.Position, building, building.Map) && by.CanReach(dest, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)); }
public override void PostMapGenerate() { base.PostMapGenerate(); Map map = base.Map; this.core.def.Worker.PostMapGenerate(map); for (int i = 0; i < this.parts.Count; i++) { this.parts[i].def.Worker.PostMapGenerate(map); } this.anyEnemiesInitially = GenHostility.AnyHostileActiveThreatToPlayer(base.Map); LookTargets lookTargets = new LookTargets(); StringBuilder stringBuilder = new StringBuilder(); Site.tmpUsedDefs.Clear(); Site.tmpDefs.Clear(); Site.tmpDefs.Add(this.core.def); for (int j = 0; j < this.parts.Count; j++) { Site.tmpDefs.Add(this.parts[j].def); } LetterDef letterDef = null; string text = null; for (int k = 0; k < Site.tmpDefs.Count; k++) { string text2; LetterDef letterDef2; LookTargets lookTargets2; string arrivedLetterPart = Site.tmpDefs[k].Worker.GetArrivedLetterPart(map, out text2, out letterDef2, out lookTargets2); if (arrivedLetterPart != null) { if (!Site.tmpUsedDefs.Contains(Site.tmpDefs[k])) { Site.tmpUsedDefs.Add(Site.tmpDefs[k]); if (stringBuilder.Length > 0) { stringBuilder.AppendLine(); stringBuilder.AppendLine(); } stringBuilder.Append(arrivedLetterPart); } if (text == null) { text = text2; } if (letterDef == null) { letterDef = letterDef2; } if (lookTargets2.IsValid()) { lookTargets = new LookTargets(lookTargets.targets.Concat(lookTargets2.targets)); } } } if (stringBuilder.Length > 0) { Find.LetterStack.ReceiveLetter(text ?? "LetterLabelPlayerEnteredNewSiteGeneric".Translate(), stringBuilder.ToString(), letterDef ?? LetterDefOf.NeutralEvent, (!lookTargets.IsValid()) ? this : lookTargets, null, null); } }
public bool TryExecute(Pawn p) { return((p.RaceProps.Humanlike && !GenHostility.HostileTo(p, Faction.OfPlayer) && !p.IsColonist) || p.IsPrisonerOfColony); }