protected override Job TryGiveJob(Pawn pawn) { pawn.drafter.Drafted = true; IntVec3 cell = pawn.mindState.duty.focus.Cell; if (pawn.IsBoat() && !ShipReachabilityUtility.CanReachShip(pawn, cell, PathEndMode.OnCell, PawnUtility.ResolveMaxDanger(pawn, maxDanger), false, TraverseMode.ByPawn)) { return(null); } else if (!pawn.IsBoat() && pawn is VehiclePawn vehicle && !ReachabilityUtility.CanReach(vehicle, cell, PathEndMode.OnCell, PawnUtility.ResolveMaxDanger(vehicle, maxDanger), false)) { return(null); } if (exactCell && pawn.Position == cell) { return(null); } return(new Job(JobDefOf.Goto, cell) { locomotionUrgency = PawnUtility.ResolveLocomotion(pawn, locomotionUrgency), expiryInterval = jobMaxDuration }); }
public void SetGuestStatus(Faction newHost, bool prisoner = false) { if (newHost != null) { Released = false; } if (newHost != HostFaction || prisoner != IsPrisoner) { if (!prisoner && pawn.Faction.HostileTo(newHost)) { Log.Error("Tried to make " + pawn + " a guest of " + newHost + " but their faction " + pawn.Faction + " is hostile to " + newHost); } else if (newHost != null && newHost == pawn.Faction && !prisoner) { Log.Error("Tried to make " + pawn + " a guest of their own faction " + pawn.Faction); } else { bool flag = prisoner && (!IsPrisoner || HostFaction != newHost); isPrisonerInt = prisoner; hostFactionInt = newHost; pawn.ClearMind(); if (flag) { pawn.DropAndForbidEverything(); pawn.GetLord()?.Notify_PawnLost(pawn, PawnLostCondition.MadePrisoner); if (newHost == Faction.OfPlayer) { Find.StoryWatcher.watcherPopAdaptation.Notify_PawnEvent(pawn, PopAdaptationEvent.GainedPrisoner); } if (pawn.Drafted) { pawn.drafter.Drafted = false; } float x = pawn.RecruitDifficulty(Faction.OfPlayer); resistance = StartingResistancePerRecruitDifficultyCurve.Evaluate(x); resistance *= StartingResistanceFactorFromPopulationIntentCurve.Evaluate(StorytellerUtilityPopulation.PopulationIntent); resistance *= StartingResistanceRandomFactorRange.RandomInRange; resistance = (float)GenMath.RoundRandom(resistance); } PawnComponentsUtility.AddAndRemoveDynamicComponents(pawn); pawn.health.surgeryBills.Clear(); if (pawn.ownership != null) { pawn.ownership.Notify_ChangedGuestStatus(); } ReachabilityUtility.ClearCacheFor(pawn); if (pawn.Spawned) { pawn.Map.mapPawns.UpdateRegistryForPawn(pawn); pawn.Map.attackTargetsCache.UpdateTarget(pawn); } AddictionUtility.CheckDrugAddictionTeachOpportunity(pawn); if (prisoner && pawn.playerSettings != null) { pawn.playerSettings.Notify_MadePrisoner(); } } } }
public override IEnumerable <FloatMenuOption> GetFloatMenuOptions(Pawn myPawn) { if (!ReachabilityUtility.CanReach(myPawn, this, PathEndMode.InteractionCell, Danger.Deadly, false, 0)) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("CannotUseNoPath"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } else if (this.CanLearnFromBook(myPawn)) { string label = "VBE.ReadBook".Translate(); Action action = delegate() { Job job = JobMaker.MakeJob(VBE_DefOf.VBE_ReadBook, null, this); job.count = 1; myPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); }; yield return(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption (label, action, MenuOptionPriority.Default, null, null, 0f, null, null), myPawn, this, "ReservedBy")); } else if (!this.CanLearnFromBook(myPawn)) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("VBE.CantReadSkillBookTooSimple"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } yield break; }
// Token: 0x06000008 RID: 8 RVA: 0x00002298 File Offset: 0x00000498 private static IntVec3 GetNearestBaseItem(Pawn pawn) { IntVec3 position = pawn.Position; float num = 99999f; List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial); if (list.Count > 0) { Thing thing = null; foreach (Thing thing2 in list) { LocalTargetInfo localTargetInfo = thing2; if (ReachabilityUtility.CanReach(pawn, localTargetInfo, PathEndMode.Touch, Danger.Deadly, false, 0)) { float num2 = IntVec3Utility.DistanceTo(pawn.Position, thing2.Position); if (num2 < num) { thing = thing2; num = num2; } } } if (thing != null) { position = thing.Position; } } return(position); }
public static void CheckArrived(Lord lord, List <Pawn> pawnsToCheck, IntVec3 meetingPoint, string memo, Predicate <Pawn> shouldCheckIfArrived, bool waterPathing, Predicate <Pawn> extraValidator = null) { bool flag = true; foreach (Pawn p in pawnsToCheck) { if (shouldCheckIfArrived(p) && !waterPathing) { if (!p.Spawned || !p.Position.InHorDistOf(meetingPoint, 15f) || !ReachabilityUtility.CanReach(p, meetingPoint, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn) || (extraValidator != null && !extraValidator(p))) { flag = false; break; } } else if (waterPathing) { Pawn leadShip = ((LordJob_FormAndSendCaravanShip)lord.LordJob).LeadShip; if (!p.Spawned || !p.Position.InHorDistOf(((LordJob_FormAndSendCaravanShip)lord.LordJob).LeadShip.Position, 5f) || !leadShip.Position.InHorDistOf(meetingPoint, leadShip.def.size.z > 5 ? (float)leadShip.def.size.z / 2 : 3f) || !ShipReachabilityUtility.CanReachShip(p, meetingPoint, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn) || (extraValidator != null && !extraValidator(p))) { flag = false; break; } } } if (flag) { lord.ReceiveMemo(memo); } }
public override void Notify_PawnLost(Pawn p, PawnLostCondition condition) { ReachabilityUtility.ClearCache(); if (!this.caravanSent) { CaravanFormingUtility.RemovePawnFromCaravan(p, this.lord); } }
public void SetGuestStatus(Faction newHost, bool prisoner = false) { if (newHost != null) { this.Released = false; } if (newHost == this.HostFaction && prisoner == this.IsPrisoner) { return; } if (!prisoner && this.pawn.Faction.HostileTo(newHost)) { Log.Error("Tried to make " + this.pawn + " a guest of " + newHost + " but their faction " + this.pawn.Faction + " is hostile to " + newHost); } else if (newHost != null && newHost == this.pawn.Faction && !prisoner) { Log.Error("Tried to make " + this.pawn + " a guest of their own faction " + this.pawn.Faction); } else { bool flag = prisoner && (!this.IsPrisoner || this.HostFaction != newHost); this.isPrisonerInt = prisoner; this.hostFactionInt = newHost; this.pawn.ClearMind(false); if (flag) { this.pawn.DropAndForbidEverything(false); Lord lord = this.pawn.GetLord(); if (lord != null) { lord.Notify_PawnLost(this.pawn, PawnLostCondition.MadePrisoner); } if (this.pawn.Drafted) { this.pawn.drafter.Drafted = false; } } PawnComponentsUtility.AddAndRemoveDynamicComponents(this.pawn, false); this.pawn.health.surgeryBills.Clear(); if (this.pawn.ownership != null) { this.pawn.ownership.Notify_ChangedGuestStatus(); } ReachabilityUtility.ClearCache(); if (this.pawn.Spawned) { this.pawn.Map.mapPawns.UpdateRegistryForPawn(this.pawn); this.pawn.Map.attackTargetsCache.UpdateTarget(this.pawn); } AddictionUtility.CheckDrugAddictionTeachOpportunity(this.pawn); if (prisoner && this.pawn.playerSettings != null) { this.pawn.playerSettings.Notify_MadePrisoner(); } } }
public override void Notify_PawnLost(Pawn p, PawnLostCondition condition) { base.Notify_PawnLost(p, condition); ReachabilityUtility.ClearCacheFor(p); if (!this.caravanSent) { if (condition == PawnLostCondition.IncappedOrKilled && p.Downed) { this.downedPawns.Add(p); } CaravanFormingUtility.RemovePawnFromCaravan(p, this.lord, false); } }
public static bool Prefix(Pawn __instance, PawnKindDef newKindDef) { if (__instance.def is RaceAddonThingDef) { if (__instance.kindDef != newKindDef) { __instance.kindDef = newKindDef; if (__instance.kindDef == PawnKindDefOf.WildMan) { __instance.mindState.WildManEverReachedOutside = false; ReachabilityUtility.ClearCacheFor(__instance); } } } return(true); }
public override IEnumerable <FloatMenuOption> GetFloatMenuOptions(Pawn myPawn) { if (!ReachabilityUtility.CanReach(myPawn, this, PathEndMode.InteractionCell, Danger.Deadly, false, 0)) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("CannotUseNoPath"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } else if (!this.used && !this.researchProject.IsFinished && this.researchProject.PrerequisitesCompleted) { string label = "VBE.ReadBlueprint".Translate(); Action action = delegate() { Job job = JobMaker.MakeJob(VBE_DefOf.VBE_ReadBook, null, this); job.count = 1; myPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); }; yield return(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption (label, action, MenuOptionPriority.Default, null, null, 0f, null, null), myPawn, this, "ReservedBy")); } else if (this.used) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("VBE.CantReadBlueprintUsed"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } else if (this.researchProject.IsFinished) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("VBE.CantReadBlueprintAlreadyResearched"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } else if (!this.researchProject.PrerequisitesCompleted) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("VBE.CantReadBlueprintTooAdvanced"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } yield break; }
public Job TryGiveJob(Pawn pawn, Thing targetThing, bool NoJoyCheck = false) { Verb verb = null; if (pawn != null) { verb = pawn.meleeVerbs.TryGetMeleeVerb(targetThing); } Job result; if (pawn.WorkTagIsDisabled(WorkTags.Violent) || verb == null || verb.verbProps == null) { result = null; } else { List <Thing> list = pawn.Map.listerThings.ThingsOfDef(this.def.thingDefs[0]); Predicate <Thing> predicate = delegate(Thing t) { return(!ForbidUtility.IsForbidden(t, pawn) && ReservationUtility.CanReserve(pawn, t, this.def.jobDef.joyMaxParticipants, -1, null, false) && SocialProperness.IsSociallyProper(t, pawn)); }; Thing thing = null; if (targetThing != null && ReachabilityUtility.CanReach(pawn, targetThing.Position, PathEndMode.InteractionCell, Danger.Deadly, false, 0) && predicate(targetThing)) { thing = targetThing; } else if (targetThing == null) { thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, list, PathEndMode.InteractionCell, TraverseParms.For(pawn, Danger.Deadly, 0, false), 9999f, predicate, null); } if (thing != null) { Job job = JobMaker.MakeJob(this.def.jobDef, thing); return(job); } result = null; } return(result); }
protected override Job TryGiveJob(Pawn pawn) { if (Find.TickManager.TicksGame < PrevTick + 10) { return(null); } PrevTick = Find.TickManager.TicksGame; if (GridsUtility.Fogged(pawn.Position, pawn.Map)) { return(JobMaker.MakeJob(JobDefOf.LayDown)); } Alien alien = pawn as Alien; // Some optimizations here... //if (pawn.TryGetAttackVerb(null, false) == null) //{ // return null; //} if (pawn.CurJob != null) { Log.Message(pawn + " - " + pawn.CurJob.def.defName); } Pawn pawn2 = null; if ((Find.TickManager.TicksGame - alien.lastAttacked) < 1000) { pawn2 = alien.lastInstigator; } else if ((Find.TickManager.TicksGame - pawn.Map.GetComponent <MapComponent_MapEvents>().LastAttacked) < 1000) { pawn2 = FindPawnTargetNearPlants(pawn); } else { pawn2 = FindPawnTarget(pawn); } if (pawn2 == null) { if (pawn.GetRoom() != null && !pawn.GetRoom().PsychologicallyOutdoors) { Predicate <Thing> validator = delegate(Thing t) { return(t.def.defName.ToLower().Contains("door")); }; var door = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.Touch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false) , 5f, validator); if (door != null) { return(PurpleIvyUtils.MeleeAttackJob(pawn, door)); } else { Predicate <Thing> validator2 = delegate(Thing t) { return(t.def.defName.ToLower().Contains("wall")); }; var wall = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.Touch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false) , 5f, validator2); if (wall != null) { return(PurpleIvyUtils.MeleeAttackJob(pawn, wall)); } } } } else if (!pawn2.Downed) { var verb = pawn.VerbTracker.AllVerbs.Where(x => x.IsMeleeAttack != true).FirstOrDefault(); if (pawn.def == PurpleIvyDefOf.Genny_ParasiteOmega && pawn.Position.InHorDistOf(pawn2.Position, 15) && Rand.Chance(0.7f)) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - JUMP"); return(PurpleIvyUtils.JumpOnTargetJob(pawn, pawn2)); } else if (pawn.def == PurpleIvyDefOf.Genny_ParasiteBeta && pawn.Position.InHorDistOf(pawn2.Position, 2) && Rand.Chance(0.1f)) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - SMOKE"); return(PurpleIvyUtils.SmokeAttackJob(pawn, pawn2)); } else if (verb != null && Rand.Chance(0.8f) && pawn.Position.InHorDistOf(pawn2.Position, verb.verbProps.range)) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - SHOOT"); return(PurpleIvyUtils.RangeAttackJob(pawn, pawn2)); } else { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - MELEE"); return(PurpleIvyUtils.MeleeAttackJob(pawn, pawn2)); } } else if (pawn2.Downed) { if (pawn2.BodySize >= 0.5f && pawn.def != PurpleIvyDefOf.Genny_ParasiteOmega && pawn.def != PurpleIvyDefOf.Genny_ParasiteGamma && pawn.kindDef != PurpleIvyDefOf.Genny_Queen && pawn.needs.food.CurCategory < HungerCategory.Hungry) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - Goo"); return(PurpleIvyUtils.EntagleWithGooJob(pawn, pawn2)); } else { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - KILL"); return(PurpleIvyUtils.KillAttackJob(pawn, pawn2)); } } if (alien.canGuard) { if (alien.mindState?.duty?.focus == null || !PurpleIvyUtils.AlienPlantInCell (alien.Map, alien.mindState.duty.focus.Cell)) { alien.SetFocus(); } } if (alien.canHaul) { Predicate <Thing> validator = delegate(Thing t) { List <Thing> list = pawn.Map.thingGrid.ThingsListAt(t.Position); return(!(list.Count > 0 && list.OfType <Plant>().Any(x => x.def == PurpleIvyDefOf.PurpleIvy || x.def == PurpleIvyDefOf.PI_Nest || x.def == PurpleIvyDefOf.PlantVenomousToothwort))); }; Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(PurpleIvyDefOf.PI_StickyGoo), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.None, TraverseMode.NoPassClosedDoors, false), 9999f, validator, null); if (thing == null) { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.Corpse), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.None, TraverseMode.NoPassClosedDoors, false), 50f, validator, null); } if (thing != null && ReservationUtility.CanReserveAndReach(pawn, thing, PathEndMode.ClosestTouch, Danger.None)) { var plants = pawn.Map.listerThings.ThingsOfDef(PurpleIvyDefOf.PurpleIvy); if (plants == null || plants.Count <= 0) { return(null); } var plantToHaul = plants.RandomElement(); if (ReachabilityUtility.CanReach(pawn, plantToHaul, PathEndMode.ClosestTouch, Danger.None, true, TraverseMode.NoPassClosedDoors)) { Job job = JobMaker.MakeJob(PurpleIvyDefOf.PI_HaulToCell, thing, plantToHaul.Position); job.attackDoorIfTargetLost = true; if (job != null && job.TryMakePreToilReservations(pawn, false)) { ReservationUtility.Reserve(pawn, thing, job); return(job); } } } } //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - NULL 1"); //Building building = this.FindTurretTarget(pawn); //if (building != null) //{ // return MeleeAttackJob(pawn, building); //} //if (pawn2 != null) //{ // using (PawnPath pawnPath = pawn.Map.pathFinder.FindPath(pawn.Position, pawn2.Position, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.PassDoors, false), PathEndMode.OnCell)) // { // if (!pawnPath.Found) // { // return null; // } // IntVec3 loc; // if (!pawnPath.TryFindLastCellBeforeBlockingDoor(pawn, out loc)) // { // Log.Error(pawn + " did TryFindLastCellBeforeDoor but found none when it should have been one. Target: " + pawn2.LabelCap, false); // return null; // } // IntVec3 randomCell = CellFinder.RandomRegionNear(loc.GetRegion(pawn.Map, RegionType.Set_Passable), 9, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), null, null, RegionType.Set_Passable).RandomCell; // if (randomCell == pawn.Position) // { // return JobMaker.MakeJob(JobDefOf.Wait, 30, false); // } // return JobMaker.MakeJob(JobDefOf.Goto, randomCell); // } //} return(null); }
public override IEnumerable <FloatMenuOption> GetFloatMenuOptions(Pawn myPawn) { if (!ReachabilityUtility.CanReach(myPawn, this, (PathEndMode)4, (Danger)2, false, 0)) { FloatMenuOption item = new FloatMenuOption(Translator.Translate("CannotUseNoPath"), null, (MenuOptionPriority)4, null, null, 0f, null, null); return(new List <FloatMenuOption> { item }); } if (Spawned && Map.gameConditionManager.ConditionIsActive(GameConditionDefOf.SolarFlare)) { return(new List <FloatMenuOption> { new FloatMenuOption(Translator.Translate("CannotUseSolarFlare"), null, (MenuOptionPriority)4, null, null, 0f, null, null) }); } if (!myPawn.health.capacities.CapableOf(PawnCapacityDefOf.Talking)) { return(new List <FloatMenuOption> { new FloatMenuOption(Translator.Translate("CannotUseReason", new object[] { Translator.Translate("IncapableOfCapacity", new object[] { PawnCapacityDefOf.Talking.label }) }), null, (Verse.MenuOptionPriority) 4, null, null, 0f, null, null) }); } if (!this.CanUseSignalFireNow) { Log.Error(myPawn + " could not use comm console for unknown reason."); return(new List <FloatMenuOption> { new FloatMenuOption("Cannot use now", null, (MenuOptionPriority)4, null, null, 0f, null, null) }); } List <FloatMenuOption> list = new List <FloatMenuOption>(); foreach (ICommunicable commTarget in Find.FactionManager.AllFactionsInViewOrder) { ICommunicable localCommTarget = commTarget; string text = Translator.Translate("CallOnRadio", new object[] { localCommTarget.GetCallLabel() }); if (localCommTarget is Faction faction) { if (faction.IsPlayer) { continue; } if (!LeaderIsAvailableToTalk(faction)) { string str; if (faction.leader != null) { str = Translator.Translate("LeaderUnavailable", new object[] { faction.leader.LabelShort }); } else { str = Translator.Translate("LeaderUnavailableNoLeader"); } list.Add(new FloatMenuOption(text + " (" + str + ")", null, (MenuOptionPriority)4, null, null, 0f, null, null)); continue; } } void action() { if (commTarget is TradeShip && !Building_OrbitalTradeBeacon.AllPowered(Map).Any()) { Messages.Message(Translator.Translate("MessageNeedBeaconToTradeWithShip"), this, MessageTypeDefOf.RejectInput, false); } else { Job job = new Job(DefDatabase <JobDef> .GetNamed("UseSignalFire", true), this) { commTarget = localCommTarget }; myPawn.jobs.TryTakeOrderedJob(job, 0); PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.OpeningComms, (KnowledgeAmount)6); } } list.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, action, (MenuOptionPriority)7, null, null, 0f, null, null), myPawn, this, "ReservedBy")); } return(list); }
public override void Notify_PawnAdded(Pawn p) { ReachabilityUtility.ClearCache(); }
public override IEnumerable <FloatMenuOption> GetFloatMenuOptions(Pawn myPawn) { if (!ReachabilityUtility.CanReach(myPawn, this, PathEndMode.InteractionCell, Danger.Deadly, false, 0)) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("CannotUseNoPath"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } else if (this.def == AlteredCarbonDefOf.AC_FilledCorticalStack && myPawn.skills.GetSkill(SkillDefOf.Intellectual).Level >= 5) { string label = "AlteredCarbon.WipeStack".Translate(); Action action = delegate() { Job job = JobMaker.MakeJob(AlteredCarbonDefOf.AC_WipeStack, this); job.count = 1; myPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); }; yield return(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption (label, action, MenuOptionPriority.Default, null, null, 0f, null, null), myPawn, this, "ReservedBy")); } else if (this.def == AlteredCarbonDefOf.AC_FilledCorticalStack && myPawn.skills.GetSkill(SkillDefOf.Intellectual).Level < 5) { FloatMenuOption floatMenuOption = new FloatMenuOption("AlteredCarbon.CantWipeStackTooDumb".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } if (this.hasPawn) { if (this.Map.listerThings.ThingsOfDef(AlteredCarbonDefOf.AC_EmptyCorticalStack) .Where(x => myPawn.CanReserveAndReach(x, PathEndMode.ClosestTouch, Danger.Deadly)).Any()) { if (myPawn.skills.GetSkill(SkillDefOf.Intellectual).levelInt >= 10) { string label = "AlteredCarbon.DuplicateStack".Translate(); Action action = delegate() { Job job = JobMaker.MakeJob(AlteredCarbonDefOf.AC_CopyStack, this); job.count = 1; myPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); }; yield return(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption (label, action, MenuOptionPriority.Default, null, null, 0f, null, null), myPawn, this, "ReservedBy")); } else if (myPawn.skills.GetSkill(SkillDefOf.Intellectual).levelInt < 10) { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate("AlteredCarbon.CannotCopyNoIntellectual"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } } else { FloatMenuOption floatMenuOption = new FloatMenuOption(Translator.Translate( "AlteredCarbon.CannotCopyNoOtherEmptyStacks"), null, MenuOptionPriority.Default, null, null, 0f, null, null); yield return(floatMenuOption); } } yield break; }
public (PawnPath path, bool found) FindVehiclePath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, CancellationToken token, PathEndMode peMode = PathEndMode.OnCell, bool waterPathing = false) { if (report) { Debug.Message($"{VehicleHarmony.LogLabel} MainPath for {traverseParms.pawn.LabelShort} - ThreadId: [{Thread.CurrentThread.ManagedThreadId}] TaskId: [{Task.CurrentId}]"); } postCalculatedCells.Clear(); VehicleMapping VehicleMapping = map.GetCachedMapComponent <VehicleMapping>(); if (DebugSettings.pathThroughWalls) { traverseParms.mode = TraverseMode.PassAllDestroyableThings; } VehiclePawn pawn = traverseParms.pawn as VehiclePawn; if (!pawn.IsBoat() && waterPathing) { Log.Error($"Set to waterPathing but {pawn.LabelShort} is not registered as a Boat. Self Correcting..."); waterPathing = false; } if (!(pawn is null) && pawn.Map != map) { Log.Error(string.Concat(new object[] { "Tried to FindVehiclePath for pawn which is spawned in another map. Their map PathFinder should have been used, not this one. " + "pawn=", pawn, " pawn.Map=", pawn.Map, " map=", map })); return(PawnPath.NotFound, false); } if (!start.IsValid) { Log.Error(string.Concat(new object[] { "Tried to FindShipPath with invalid start ", start, ", pawn=", pawn })); return(PawnPath.NotFound, false); } if (!dest.IsValid) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid dest ", dest, ", pawn= ", pawn })); return(PawnPath.NotFound, false); } if (traverseParms.mode == TraverseMode.ByPawn) { if (waterPathing) { if (!ShipReachabilityUtility.CanReachShip(pawn, dest, peMode, Danger.Deadly, false, traverseParms.mode)) { return(PawnPath.NotFound, false); } } else { if (!ReachabilityUtility.CanReach(pawn, dest, peMode, Danger.Deadly, false, traverseParms.mode)) { return(PawnPath.NotFound, false); } } } else { if (waterPathing) { if (!VehicleMapping.VehicleReachability.CanReachShip(start, dest, peMode, traverseParms)) { return(PawnPath.NotFound, false); } } else { if (!map.reachability.CanReach(start, dest, peMode, traverseParms)) { return(PawnPath.NotFound, false); } } } cellIndices = map.cellIndices; VehiclePathGrid = VehicleMapping.VehiclePathGrid; pathGrid = map.pathGrid; this.edificeGrid = map.edificeGrid.InnerArray; blueprintGrid = map.blueprintGrid.InnerArray; int x = dest.Cell.x; int z = dest.Cell.z; int num = cellIndices.CellToIndex(start); int num2 = cellIndices.CellToIndex(dest.Cell); ByteGrid byteGrid = (pawn is null) ? null : pawn.GetAvoidGrid(true); bool flag = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater; bool flag2 = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater; bool flag3 = !flag; CellRect cellRect = CalculateDestinationRect(dest, peMode); bool flag4 = cellRect.Width == 1 && cellRect.Height == 1; int[] boatsArray = VehiclePathGrid.pathGrid; int[] vehicleArray = pathGrid.pathGrid; TerrainDef[] topGrid = map.terrainGrid.topGrid; EdificeGrid edificeGrid = map.edificeGrid; int num3 = 0; int num4 = 0; Area allowedArea = GetAllowedArea(pawn); bool flag5 = !(pawn is null) && PawnUtility.ShouldCollideWithPawns(pawn); bool flag6 = true && DebugViewSettings.drawPaths; bool flag7 = !flag && !(VehicleGridsUtility.GetRegion(start, map, RegionType.Set_Passable) is null) && flag2; bool flag8 = !flag || !flag3; bool flag9 = false; bool flag10 = !(pawn is null) && pawn.Drafted; bool flag11 = !(pawn is null) && !(pawn is null); int num5 = (!flag11) ? NodesToOpenBeforeRegionbasedPathing_NonShip : NodesToOpenBeforeRegionBasedPathing_Ship; int num6 = 0; int num7 = 0; float num8 = DetermineHeuristicStrength(pawn, start, dest); int num9 = !(pawn is null) ? pawn.TicksPerMoveCardinal : DefaultMoveTicksCardinal; int num10 = !(pawn is null) ? pawn.TicksPerMoveDiagonal : DefaultMoveTicksDiagonal; CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect); InitStatusesAndPushStartNode(ref num, start); Rot8 rot = pawn.FullRotation; int iterations = 0; for (;;) { if (token.IsCancellationRequested) { return(PawnPath.NotFound, false); } iterations++; if (openList.Count <= 0) { break; } num6 += openList.Count; num7++; CostNode costNode = openList.Pop(); num = costNode.index; if (costNode.cost == calcGrid[num].costNodeCost && calcGrid[num].status != statusClosedValue) { IntVec3 c = cellIndices.IndexToCell(num); IntVec3 prevCell = c; int x2 = c.x; int z2 = c.z; if (flag6) { DebugFlash(c, calcGrid[num].knownCost / 1500f, calcGrid[num].knownCost.ToString()); } if (flag4) { if (num == num2) { goto Block_32; } } else if (cellRect.Contains(c) && !disallowedCornerIndices.Contains(num)) { goto Block_32; } if (num3 > SearchLimit) { goto Block_33; } List <IntVec3> fullRectCells = CellRect.CenteredOn(c, pawn.def.size.x, pawn.def.size.z).Where(cl2 => cl2 != c).ToList(); for (int i = 0; i < 8; i++) { uint num11 = (uint)(x2 + Directions[i]); //x uint num12 = (uint)(z2 + Directions[i + 8]); //y if (num11 < ((ulong)mapSizeX) && num12 < (ulong)(mapSizeZ)) { int num13 = (int)num11; int num14 = (int)num12; int num15 = cellIndices.CellToIndex(num13, num14); IntVec3 cellToCheck = cellIndices.IndexToCell(num15); if (VehicleMod.settings.main.fullVehiclePathing && pawn.LocationRestrictedBySize(cellToCheck)) { goto EndPathing; } if (calcGrid[num15].status != statusClosedValue || flag9) { int num16 = 0; bool flag12 = false; //Extra cost for traversing water if (flag2 || !new IntVec3(num13, 0, num14).GetTerrain(map).HasTag("Water")) { if (waterPathing) { if (!pawn.DrivableFast(num15)) { if (!flag) { if (flag6) { DebugFlash(new IntVec3(num13, 0, num14), 0.22f, "walk"); } goto EndPathing; } num16 += 70; Building building = edificeGrid[num15]; if (building is null) { goto EndPathing; } if (!IsDestroyable(building)) { goto EndPathing; } num16 += (int)(building.HitPoints * 0.2f); } } else { if (!pawn.DrivableFast(num15)) { if (!flag) { if (flag6) { DebugFlash(new IntVec3(num13, 0, num14), 0.22f, "walk"); } goto EndPathing; } flag12 = true; num16 += 70; Building building = edificeGrid[num15]; if (building is null) { goto EndPathing; } if (!IsDestroyable(building)) { goto EndPathing; } num16 += (int)(building.HitPoints * 0.2f); } } if (i > 3) { switch (i) { case 4: if (BlocksDiagonalMovement(pawn, num - mapSizeX)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } if (BlocksDiagonalMovement(pawn, num + 1)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } break; case 5: if (BlocksDiagonalMovement(pawn, num + mapSizeX)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } if (BlocksDiagonalMovement(pawn, num + 1)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } break; case 6: if (BlocksDiagonalMovement(pawn, num + mapSizeX)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } if (BlocksDiagonalMovement(pawn, num - 1)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } break; case 7: if (BlocksDiagonalMovement(pawn, num - mapSizeX)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } if (BlocksDiagonalMovement(pawn, num - 1)) { if (flag8) { if (flag6) { DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "ships"); } goto EndPathing; } num16 += 70; } break; } } int num17 = (i <= 3) ? num9 : num10; num17 += num16; //if (Rot8.DirectionFromCells(prevCell, cellToCheck) != rot) //{ // Log.Message("Additional Cost"); // num17 += ChangeDirectionAdditionalCost; //} if (!flag12 && !waterPathing) { //Extra Terrain costs if (pawn.VehicleDef.properties.customTerrainCosts?.NotNullAndAny() ?? false) { TerrainDef currentTerrain = map.terrainGrid.TerrainAt(num15); if (pawn.VehicleDef.properties.customTerrainCosts.ContainsKey(currentTerrain)) { int customCost = pawn.VehicleDef.properties.customTerrainCosts[currentTerrain]; if (customCost < 0) { goto EndPathing; } num17 += customCost; } else { num17 += vehicleArray[num15]; } } else { num17 += vehicleArray[num15]; } num17 += flag10 ? topGrid[num15].extraDraftedPerceivedPathCost : topGrid[num15].extraNonDraftedPerceivedPathCost; } if (byteGrid != null) { num17 += (byteGrid[num15] * 8); } //Allowed area cost? if (flag5 && MultithreadHelper.AnyVehicleBlockingPathAt(new IntVec3(num13, 0, num14), pawn, false, false, true) != null) { num17 += Cost_PawnCollision; } Building building2 = edificeGrid[num15]; if (!(building2 is null)) { //Building Costs Here } if (blueprintGrid[num15] != null) { List <Blueprint> list = new List <Blueprint>(blueprintGrid[num15]); if (!list.NullOrEmpty()) { int num18 = 0; foreach (Blueprint bp in list) { num18 = Mathf.Max(num18, GetBlueprintCost(bp, pawn)); } if (num18 == int.MaxValue) { goto EndPathing; } num17 += num18; } } int num19 = num17 + calcGrid[num].knownCost; ushort status = calcGrid[num15].status; //if(pawn.Props.useFullHitboxPathing) //{ // foreach(IntVec3 fullRect in fullRectCells) // { // if(fullRect != cellToCheck) // { // num19 += calcGrid[cellIndices.CellToIndex(fullRect)].knownCost; // Log.Message($"Cell: {fullRect} Cost: {num19}"); // if(postCalculatedCells.ContainsKey(fullRect)) // { // postCalculatedCells[fullRect] = num19; // } // else // { // postCalculatedCells.Add(fullRect, num19); // } // } // } //} //Only generate path costs for linear non-reverse pathing check if (report) { if (postCalculatedCells.ContainsKey(cellToCheck)) { postCalculatedCells[cellToCheck] = num19; } else { postCalculatedCells.Add(cellToCheck, num19); } } if (waterPathing && !map.terrainGrid.TerrainAt(num15).IsWater) { num19 += 10000; } if (status == statusClosedValue || status == statusOpenValue) { int num20 = 0; if (status == statusClosedValue) { num20 = num9; } if (calcGrid[num15].knownCost <= num19 + num20) { goto EndPathing; } } if (flag9) { calcGrid[num15].heuristicCost = waterPathing ? Mathf.RoundToInt(regionCostCalculatorSea.GetPathCostFromDestToRegion(num15) * RegionheuristicWeighByNodesOpened.Evaluate(num4)) : Mathf.RoundToInt(regionCostCalculatorLand.GetPathCostFromDestToRegion(num15) * RegionheuristicWeighByNodesOpened.Evaluate(num4)); if (calcGrid[num15].heuristicCost < 0) { Log.ErrorOnce(string.Concat(new object[] { "Heuristic cost overflow for vehicle ", pawn.ToStringSafe <Pawn>(), " pathing from ", start, " to ", dest, "." }), pawn.GetHashCode() ^ 193840009); calcGrid[num15].heuristicCost = 0; } } else if (status != statusClosedValue && status != statusOpenValue) { int dx = Math.Abs(num13 - x); int dz = Math.Abs(num14 - z); int num21 = GenMath.OctileDistance(dx, dz, num9, num10); calcGrid[num15].heuristicCost = Mathf.RoundToInt((float)num21 * num8); } int num22 = num19 + calcGrid[num15].heuristicCost; if (num22 < 0) { Log.ErrorOnce(string.Concat(new object[] { "Node cost overflow for ship ", pawn.ToStringSafe <Pawn>(), " pathing from ", start, " to ", dest, "." }), pawn.GetHashCode() ^ 87865822); num22 = 0; } calcGrid[num15].parentIndex = num; calcGrid[num15].knownCost = num19; calcGrid[num15].status = statusOpenValue; calcGrid[num15].costNodeCost = num22; num4++; rot = Rot8.DirectionFromCells(prevCell, cellToCheck); openList.Push(new CostNode(num15, num22)); } } } EndPathing :; } num3++; calcGrid[num].status = statusClosedValue; if (num4 >= num5 && flag7 && !flag9) { flag9 = true; if (waterPathing) { regionCostCalculatorSea.Init(cellRect, traverseParms, num9, num10, byteGrid, allowedArea, flag10, disallowedCornerIndices); } else { regionCostCalculatorLand.Init(cellRect, traverseParms, num9, num10, byteGrid, allowedArea, flag10, disallowedCornerIndices); } InitStatusesAndPushStartNode(ref num, start); num4 = 0; num3 = 0; } } } string text = ((pawn is null) || pawn.CurJob is null) ? "null" : pawn.CurJob.ToString(); string text2 = ((pawn is null) || pawn.Faction is null) ? "null" : pawn.Faction.ToString(); if (report) { Log.Warning(string.Concat(new object[] { "ship pawn: ", pawn, " pathing from ", start, " to ", dest, " ran out of cells to process.\nJob:", text, "\nFaction: ", text2, "\niterations: ", iterations })); } DebugDrawRichData(); return(PawnPath.NotFound, false); Block_32: PawnPath result = PawnPath.NotFound; if (report) { result = FinalizedPath(num, flag9); } DebugDrawPathCost(); return(result, true); Block_33: Log.Warning(string.Concat(new object[] { "Ship ", pawn, " pathing from ", start, " to ", dest, " hit search limit of ", SearchLimit, " cells." })); DebugDrawRichData(); return(PawnPath.NotFound, false); }
public override void Notify_PawnLost(Pawn p, PawnLostCondition condition) { ReachabilityUtility.ClearCacheFor(p); }
public static void SetFaction(this Pawn pawn, Faction newFaction, Pawn recruiter = null) { if (newFaction == pawn.Faction) { Log.Warning(string.Concat(new object[] { "Used ChangePawnFactionTo to change ", pawn, " to same faction ", newFaction })); return; } if (pawn.guest != null) { pawn.guest.SetGuestStatus(null, false); } if (pawn.Spawned) { pawn.Map.mapPawns.DeRegisterPawn(pawn); pawn.Map.pawnDestinationManager.RemovePawnFromSystem(pawn); pawn.Map.designationManager.RemoveAllDesignationsOn(pawn, false); } if (newFaction == Faction.OfPlayer || pawn.Faction == Faction.OfPlayer) { Find.ColonistBar.MarkColonistsDirty(); } Lord lord = pawn.GetLord(); if (lord != null) { lord.Notify_PawnLost(pawn, PawnLostCondition.ChangedFaction); } if (pawn.Faction != null && pawn.Faction.leader == pawn) { pawn.Faction.Notify_LeaderLost(); } if (newFaction == Faction.OfPlayer && pawn.RaceProps.Humanlike) { pawn.kindDef = newFaction.def.basicMemberKind; } // Call base SetFaction directly - horrible mojo warning MethodInfo method = typeof(Thing).GetMethod("SetFaction", BindingFlags.Public | BindingFlags.Instance); IntPtr fptr = method.MethodHandle.GetFunctionPointer(); ((Action <Faction, Pawn>)Activator.CreateInstance(typeof(Action <Faction, Pawn>), pawn, fptr))(newFaction, null); PawnComponentsUtility.AddAndRemoveDynamicComponents(pawn, false); if (pawn.Faction != null && pawn.Faction.IsPlayer) { if (pawn.workSettings != null) { pawn.workSettings.EnableAndInitialize(); } Find.Storyteller.intenderPopulation.Notify_PopulationGained(); } if (pawn.Drafted) { pawn.drafter.Drafted = false; } ReachabilityUtility.ClearCache(); pawn.health.surgeryBills.Clear(); if (pawn.Spawned) { pawn.Map.mapPawns.RegisterPawn(pawn); } pawn.GenerateNecessaryName(); if (pawn.playerSettings != null) { Pawn_PlayerSettings_Detour.ResetPPSMedicalCare(pawn.playerSettings, pawn); } pawn.ClearMind(true); if (!pawn.Dead && pawn.needs.mood != null) { pawn.needs.mood.thoughts.situational.Notify_SituationalThoughtsDirty(); } if (pawn.Spawned) { pawn.Map.attackTargetsCache.UpdateTarget(pawn); } Find.GameEnder.CheckGameOver(); AddictionUtility.CheckDrugAddictionTeachOpportunity(pawn); if (pawn.needs != null) { pawn.needs.AddOrRemoveNeedsAsAppropriate(); } if (pawn.playerSettings != null) { pawn.playerSettings.Notify_FactionChanged(); } }
private static bool Prefix(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn) { bool flag = !pawn.RaceProps.Animal; bool result; if (flag) { result = true; } else { bool flag2 = false; List <Verb> allVerbs = pawn.verbTracker.AllVerbs; List <Verb> list = new List <Verb>(); for (int i = 0; i < allVerbs.Count; i++) { bool flag3 = allVerbs[i].verbProps.range > 1.1f; if (flag3) { list.Add(allVerbs[i]); flag2 = true; } } bool flag4 = !flag2; if (flag4) { result = true; } else { Verb verb = GenCollection.RandomElementByWeight <Verb>(list, (Verb rangeItem) => rangeItem.verbProps.commonality); bool flag5 = verb == null; if (flag5) { result = true; } else { Thing thing = (Thing)AttackTargetFinder.BestAttackTarget(pawn, TargetScanFlags.NeedThreat, (Thing x) => x is Pawn || x is Building, 0f, verb.verbProps.range, default(IntVec3), float.MaxValue, false, true); bool flag6 = thing == null; if (flag6) { result = true; } else { bool flag7 = IntVec3Utility.DistanceTo(thing.Position, pawn.Position) < verb.verbProps.minRange; if (flag7) { bool flag8 = GenAdj.AdjacentTo8Way(thing.Position, pawn.Position); if (flag8) { __result = new Job(JobDefOf.AttackMelee, thing) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), attackDoorIfTargetLost = false }; return(false); } bool flag9 = pawn.Faction != null && !pawn.Faction.def.isPlayer; if (!flag9) { bool flag10 = ReachabilityUtility.CanReach(pawn, thing, PathEndMode.Touch, Danger.Deadly, false, 0) && pawn.playerSettings.Master.playerSettings.animalsReleased; if (flag10) { __result = new Job(JobDefOf.AttackMelee, thing) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), attackDoorIfTargetLost = false }; return(false); } return(true); } } bool flag11 = (double)CoverUtility.CalculateOverallBlockChance(pawn.Position, thing.Position, pawn.Map) > 0.00999999977648258; bool flag12 = GenGrid.Standable(pawn.Position, pawn.Map); bool flag13 = verb.CanHitTarget(thing); bool flag14 = (pawn.Position - thing.Position).LengthHorizontalSquared < 25; bool flag15 = (flag11 && flag12 && flag13) || (flag14 && flag13); if (flag15) { JobDef named = DefDatabase <JobDef> .GetNamed("PI_AnimalRangeAttack", true); LocalTargetInfo localTargetInfo = thing; IntRange expiryInterval_ShooterSucceeded = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded; __result = new Job(named, localTargetInfo, expiryInterval_ShooterSucceeded.RandomInRange, true) { verbToUse = verb }; result = false; } else { CastPositionRequest castPositionRequest = default(CastPositionRequest); castPositionRequest.caster = pawn; castPositionRequest.target = thing; castPositionRequest.verb = verb; castPositionRequest.maxRangeFromTarget = verb.verbProps.range; castPositionRequest.wantCoverFromTarget = (pawn.training.HasLearned(TrainableDefOf.Release) && (double)verb.verbProps.range > 7.0); castPositionRequest.locus = pawn.playerSettings.Master.Position; castPositionRequest.maxRangeFromLocus = Traverse.Create(__instance).Method("GetFlagRadius", new object[] { pawn }).GetValue <float>(); castPositionRequest.maxRegions = 50; IntVec3 intVec = new IntVec3(); bool flag16 = CastPositionFinder.TryFindCastPosition(castPositionRequest, out intVec); bool flag17 = !flag16; if (flag17) { result = true; } else { bool flag18 = intVec == pawn.Position; if (flag18) { JobDef named2 = DefDatabase <JobDef> .GetNamed("PI_AnimalRangeAttack", true); LocalTargetInfo localTargetInfo2 = thing; IntRange expiryInterval_ShooterSucceeded = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded; __result = new Job(named2, localTargetInfo2, expiryInterval_ShooterSucceeded.RandomInRange, true) { verbToUse = verb }; result = false; } else { Job job = new Job(JobDefOf.Goto, intVec); IntRange expiryInterval_ShooterSucceeded = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded; job.expiryInterval = expiryInterval_ShooterSucceeded.RandomInRange; job.checkOverrideOnExpire = true; __result = job; result = false; } } } } } } } return(result); }
/// <summary> /// Intercepts FloatMenuMakerMap call to restrict by size and call through to custom water based pathing requirements /// </summary> /// <param name="clickCell"></param> /// <param name="pawn"></param> /// <param name="__result"></param> /// <returns></returns> public static bool GotoLocationShips(IntVec3 clickCell, Pawn pawn, ref FloatMenuOption __result) { if (pawn is VehiclePawn vehicle) { if (vehicle.Faction != Faction.OfPlayer || !vehicle.CanMoveFinal) { return(false); } if (VehicleMod.settings.main.fullVehiclePathing && vehicle.LocationRestrictedBySize(clickCell)) { Messages.Message("VehicleCannotFit".Translate(), MessageTypeDefOf.RejectInput); return(false); } if (vehicle.CompFueledTravel != null && vehicle.CompFueledTravel.EmptyTank) { Messages.Message("VehicleOutOfFuel".Translate(), MessageTypeDefOf.RejectInput); return(false); } Debug.Message("-> " + clickCell + " | " + vehicle.Map.terrainGrid.TerrainAt(clickCell).LabelCap + " | " + vehicle.Map.GetCachedMapComponent <VehicleMapping>().VehiclePathGrid.CalculatedCostAt(clickCell) + " - " + vehicle.Map.GetCachedMapComponent <VehicleMapping>().VehiclePathGrid.pathGrid[vehicle.Map.cellIndices.CellToIndex(clickCell)]); if (vehicle.IsBoat() && !VehicleMod.settings.debug.debugDisableWaterPathing) { int num = GenRadial.NumCellsInRadius(2.9f); int i = 0; IntVec3 curLoc; while (i < num) { curLoc = GenRadial.RadialPattern[i] + clickCell; if (GenGridVehicles.Standable(curLoc, vehicle.Map)) { if (curLoc == vehicle.Position || vehicle.beached) { __result = null; return(false); } if (!ShipReachabilityUtility.CanReachShip(vehicle, curLoc, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { Debug.Message($"Cant Reach {curLoc} with {vehicle.Label}"); __result = new FloatMenuOption("CannotSailToCell".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null); return(false); } Action action = delegate() { Job job = new Job(JobDefOf.Goto, curLoc); if (vehicle.Map.exitMapGrid.IsExitCell(Verse.UI.MouseCell())) { job.exitMapOnArrival = true; } else if (!vehicle.Map.IsPlayerHome && !vehicle.Map.exitMapGrid.MapUsesExitGrid && CellRect.WholeMap(vehicle.Map).IsOnEdge(Verse.UI.MouseCell(), 3) && vehicle.Map.Parent.GetComponent <FormCaravanComp>() != null && MessagesRepeatAvoider.MessageShowAllowed("MessagePlayerTriedToLeaveMapViaExitGrid-" + vehicle.Map.uniqueID, 60f)) { FormCaravanComp component = vehicle.Map.Parent.GetComponent <FormCaravanComp>(); if (component.CanFormOrReformCaravanNow) { Messages.Message("MessagePlayerTriedToLeaveMapViaExitGrid_CanReform".Translate(), vehicle.Map.Parent, MessageTypeDefOf.RejectInput, false); } else { Messages.Message("MessagePlayerTriedToLeaveMapViaExitGrid_CantReform".Translate(), vehicle.Map.Parent, MessageTypeDefOf.RejectInput, false); } } if (vehicle.jobs.TryTakeOrderedJob(job, JobTag.Misc)) { MoteMaker.MakeStaticMote(curLoc, vehicle.Map, ThingDefOf.Mote_FeedbackGoto, 1f); } }; __result = new FloatMenuOption("GoHere".Translate(), action, MenuOptionPriority.GoHere, null, null, 0f, null, null) { autoTakeable = true, autoTakeablePriority = 10f }; return(false); } else { i++; } } } else { int num = GenRadial.NumCellsInRadius(2.9f); int i = 0; IntVec3 curLoc; while (i < num) { curLoc = GenRadial.RadialPattern[i] + clickCell; if (GenGrid.Standable(curLoc, pawn.Map)) { if (curLoc == pawn.Position) { __result = null; return(false); } if (!ReachabilityUtility.CanReach(pawn, curLoc, PathEndMode.OnCell, Danger.Deadly, false)) { Debug.Message($"Cant Reach {curLoc} with {vehicle.Label}"); __result = new FloatMenuOption("CannotSailToCell".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null); return(false); } Action action = delegate() { Job job = new Job(JobDefOf.Goto, curLoc); if (pawn.Map.exitMapGrid.IsExitCell(Verse.UI.MouseCell())) { job.exitMapOnArrival = true; } else if (!pawn.Map.IsPlayerHome && !pawn.Map.exitMapGrid.MapUsesExitGrid && CellRect.WholeMap(pawn.Map).IsOnEdge(Verse.UI.MouseCell(), 3) && pawn.Map.Parent.GetComponent <FormCaravanComp>() != null && MessagesRepeatAvoider.MessageShowAllowed("MessagePlayerTriedToLeaveMapViaExitGrid-" + pawn.Map.uniqueID, 60f)) { FormCaravanComp component = pawn.Map.Parent.GetComponent <FormCaravanComp>(); if (component.CanFormOrReformCaravanNow) { Messages.Message("MessagePlayerTriedToLeaveMapViaExitGrid_CanReform".Translate(), pawn.Map.Parent, MessageTypeDefOf.RejectInput, false); } else { Messages.Message("MessagePlayerTriedToLeaveMapViaExitGrid_CantReform".Translate(), pawn.Map.Parent, MessageTypeDefOf.RejectInput, false); } } if (pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc)) { MoteMaker.MakeStaticMote(curLoc, pawn.Map, ThingDefOf.Mote_FeedbackGoto, 1f); } }; __result = new FloatMenuOption("GoHere".Translate(), action, MenuOptionPriority.GoHere, null, null, 0f, null, null) { autoTakeable = true, autoTakeablePriority = 10f }; return(false); } else { i++; } } } __result = null; return(false); } else { if (PathingHelper.VehicleInCell(pawn.Map, clickCell)) { __result = new FloatMenuOption("CannotGoNoPath".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null); return(false); } } return(true); }
public void SetGuestStatus(Faction newHost, bool prisoner = false) { if (newHost != null) { this.Released = false; } if (newHost == this.HostFaction && prisoner == this.IsPrisoner) { return; } if (!prisoner && this.pawn.Faction.HostileTo(newHost)) { Log.Error(string.Concat(new object[] { "Tried to make ", this.pawn, " a guest of ", newHost, " but their faction ", this.pawn.Faction, " is hostile to ", newHost }), false); return; } if (newHost != null && newHost == this.pawn.Faction && !prisoner) { Log.Error(string.Concat(new object[] { "Tried to make ", this.pawn, " a guest of their own faction ", this.pawn.Faction }), false); return; } bool flag = prisoner && (!this.IsPrisoner || this.HostFaction != newHost); this.isPrisonerInt = prisoner; this.hostFactionInt = newHost; this.pawn.ClearMind(false); if (flag) { this.pawn.DropAndForbidEverything(false); Lord lord = this.pawn.GetLord(); if (lord != null) { lord.Notify_PawnLost(this.pawn, PawnLostCondition.MadePrisoner, null); } if (newHost == Faction.OfPlayer) { Find.StoryWatcher.watcherPopAdaptation.Notify_PawnEvent(this.pawn, PopAdaptationEvent.GainedPrisoner); } if (this.pawn.Drafted) { this.pawn.drafter.Drafted = false; } float x = this.pawn.RecruitDifficulty(Faction.OfPlayer); this.resistance = Pawn_GuestTracker.StartingResistancePerRecruitDifficultyCurve.Evaluate(x); this.resistance *= Pawn_GuestTracker.StartingResistanceFactorFromPopulationIntentCurve.Evaluate(StorytellerUtilityPopulation.PopulationIntent); this.resistance *= Pawn_GuestTracker.StartingResistanceRandomFactorRange.RandomInRange; this.resistance = (float)GenMath.RoundRandom(this.resistance); } PawnComponentsUtility.AddAndRemoveDynamicComponents(this.pawn, false); this.pawn.health.surgeryBills.Clear(); if (this.pawn.ownership != null) { this.pawn.ownership.Notify_ChangedGuestStatus(); } ReachabilityUtility.ClearCacheFor(this.pawn); if (this.pawn.Spawned) { this.pawn.Map.mapPawns.UpdateRegistryForPawn(this.pawn); this.pawn.Map.attackTargetsCache.UpdateTarget(this.pawn); } AddictionUtility.CheckDrugAddictionTeachOpportunity(this.pawn); if (prisoner && this.pawn.playerSettings != null) { this.pawn.playerSettings.Notify_MadePrisoner(); } }
public override void Notify_PawnAdded(Pawn p) { base.Notify_PawnAdded(p); ReachabilityUtility.ClearCacheFor(p); }
public void SetGuestStatus(Faction newHost, bool prisoner = false) { if (newHost != null) { Released = false; } if (newHost == HostFaction && prisoner == IsPrisoner) { return; } if (!prisoner && pawn.Faction.HostileTo(newHost)) { Log.Error("Tried to make " + pawn + " a guest of " + newHost + " but their faction " + pawn.Faction + " is hostile to " + newHost); return; } if (newHost != null && newHost == pawn.Faction && !prisoner) { Log.Error("Tried to make " + pawn + " a guest of their own faction " + pawn.Faction); return; } bool num = prisoner && (!IsPrisoner || HostFaction != newHost); isPrisonerInt = prisoner; Faction faction = hostFactionInt; hostFactionInt = newHost; Pawn obj = pawn; bool clearMentalState = prisoner; obj.ClearMind(newHost != null, clearInspiration: false, clearMentalState); if (num) { pawn.DropAndForbidEverything(); pawn.GetLord()?.Notify_PawnLost(pawn, PawnLostCondition.MadePrisoner); if (pawn.Drafted) { pawn.drafter.Drafted = false; } float x = pawn.RecruitDifficulty(Faction.OfPlayer); resistance = StartingResistancePerRecruitDifficultyCurve.Evaluate(x); resistance *= StartingResistanceFactorFromPopulationIntentCurve.Evaluate(StorytellerUtilityPopulation.PopulationIntent); resistance *= StartingResistanceRandomFactorRange.RandomInRange; if (pawn.royalty != null) { RoyalTitle mostSeniorTitle = pawn.royalty.MostSeniorTitle; if (mostSeniorTitle != null) { resistance *= mostSeniorTitle.def.recruitmentResistanceFactor; resistance += mostSeniorTitle.def.recruitmentResistanceOffset; } } resistance = GenMath.RoundRandom(resistance); } PawnComponentsUtility.AddAndRemoveDynamicComponents(pawn); pawn.health.surgeryBills.Clear(); if (pawn.ownership != null) { pawn.ownership.Notify_ChangedGuestStatus(); } ReachabilityUtility.ClearCacheFor(pawn); if (pawn.Spawned) { pawn.Map.mapPawns.UpdateRegistryForPawn(pawn); pawn.Map.attackTargetsCache.UpdateTarget(pawn); } AddictionUtility.CheckDrugAddictionTeachOpportunity(pawn); if (prisoner && pawn.playerSettings != null) { pawn.playerSettings.Notify_MadePrisoner(); } if (faction != hostFactionInt) { QuestUtility.SendQuestTargetSignals(pawn.questTags, "ChangedHostFaction", pawn.Named("SUBJECT"), hostFactionInt.Named("FACTION")); } }