Пример #1
0
        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
            });
        }
Пример #2
0
 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();
             }
         }
     }
 }
Пример #3
0
 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();
         }
     }
 }
Пример #8
0
 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;
 }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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;
        }
Пример #16
0
        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);
        }
Пример #17
0
 public override void Notify_PawnLost(Pawn p, PawnLostCondition condition)
 {
     ReachabilityUtility.ClearCacheFor(p);
 }
Пример #18
0
        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();
            }
        }
Пример #19
0
        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);
        }
Пример #20
0
        /// <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();
            }
        }
Пример #22
0
 public override void Notify_PawnAdded(Pawn p)
 {
     base.Notify_PawnAdded(p);
     ReachabilityUtility.ClearCacheFor(p);
 }
Пример #23
0
        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"));
            }
        }