public static bool AddPawn(WorldPawns __instance, Pawn p)
 {
     lock (__instance)
     {
         __instance.gc.CancelGCPass();
         if (p.Dead || p.Destroyed)
         {
             __instance.pawnsDead.Add(p);
         }
         else
         {
             try
             {
                 int num = 0;
                 while (__instance.ShouldAutoTendTo(p) && num < 30)
                 {
                     TendUtility.DoTend(null, p, null);
                     num++;
                 }
             }
             catch (Exception ex)
             {
                 Log.ErrorOnce("Exception tending to a world pawn " + p.ToStringSafe() + ". Suppressing further errors. " + ex, p.thingIDNumber ^ 0x85C154);
             }
             __instance.pawnsAlive.Add(p);
         }
         p.Notify_PassedToWorld();
     }
     return(false);
 }
        //ThreadSafety: Return a new list, instead of an instance field (allPawnsAliveResult)
        public static bool get_AllPawnsAlive(WorldPawns __instance, ref List <Pawn> __result)
        {
            List <Pawn> newAllPawnsAliveResult;

            newAllPawnsAliveResult = new List <Pawn>(__instance.pawnsAlive);
            newAllPawnsAliveResult.AddRange(__instance.pawnsMothballed);
            __instance.allPawnsAliveResult = newAllPawnsAliveResult;
            __result = newAllPawnsAliveResult;
            return(false);
        }
Exemple #3
0
 public static bool get_AllPawnsAlive(WorldPawns __instance, ref List <Pawn> __result)
 {
     lock (allPawnsAliveResult(__instance))
     {
         allPawnsAliveResult(__instance).Clear();
         allPawnsAliveResult(__instance).AddRange(pawnsAlive(__instance));
         allPawnsAliveResult(__instance).AddRange(pawnsMothballed(__instance));
     }
     __result = allPawnsAliveResult(__instance);
     return(false);
 }
 public static void WorldPawnPostLoadInit(WorldPawns wp)
 {
     if (VersionControl.MajorFromVersionString(ScribeMetaHeaderUtility.loadedGameVersion) == 0 && VersionControl.MajorFromVersionString(ScribeMetaHeaderUtility.loadedGameVersion) <= 17)
     {
         wp.UnpinAllForcefullyKeptPawns();
     }
     if (wp.gc == null)
     {
         wp.gc = new WorldPawnGC();
     }
 }
Exemple #5
0
 public static void Rebuild(WorldPawns instance)
 {
     curCycle = 0;
     curIndex = 0;
     for (int i = 0; i < BucketCount; i++)
     {
         buckets[i].Clear();
     }
     foreach (Pawn pawn in instance.pawnsAlive)
     {
         Register(pawn);
     }
 }
        public static bool WorldPawnsTick(WorldPawns __instance)
        {
            RimThreaded.worldPawnsAlive = pawnsAlive(__instance).ToList();
            RimThreaded.worldPawnsTicks = pawnsAlive(__instance).Count;

            if (Find.TickManager.TicksGame % 15000 == 0)
            {
                DoMothballProcessing(__instance);
            }

            if (tmpPawnsToRemove == null)
            {
                tmpPawnsToRemove = new List <Pawn>();
            }
            else
            {
                tmpPawnsToRemove.Clear();
            }
            foreach (Pawn pawn in pawnsDead(__instance))
            {
                if (pawn == null)
                {
                    Log.ErrorOnce("Dead null world pawn detected, discarding.", 94424128, false);
                    tmpPawnsToRemove.Add(pawn);
                }
                else if (pawn.Discarded)
                {
                    Log.Error("World pawn " + pawn + " has been discarded while still being a world pawn. This should never happen, because discard destroy mode means that the pawn is no longer managed by anything. Pawn should have been removed from the world first.", false);
                    tmpPawnsToRemove.Add(pawn);
                }
            }
            lock (__instance)
            {
                HashSet <Pawn> newSet = new HashSet <Pawn>(pawnsDead(__instance));
                foreach (Pawn p in tmpPawnsToRemove)
                {
                    newSet.Remove(p);
                }
                pawnsDead(__instance) = newSet;
            }
            try
            {
                __instance.gc.WorldPawnGCTick();
            }
            catch (Exception ex)
            {
                Log.Error("Error in WorldPawnGCTick(): " + ex, false);
            }

            return(false);
        }
Exemple #7
0
            private static HashSet <Pawn> GetAlivePawns(HashSet <Pawn> pawns, WorldPawns instance)
            {
                if (!Finder.timeDilation || !Finder.timeDilationWorldPawns || !Finder.enabled)
                {
                    return(pawns);
                }
                var result = WorldPawnsTicker.GetPawns();

                if (Finder.debug && Finder.flashDilatedPawns)
                {
                    Log.Message($"ROCKETMAN: ticker bucket of {result.Count} from {pawns.Count} and index is {WorldPawnsTicker.curIndex}");
                }
                return(result);
            }
Exemple #8
0
        private static void DoMothballProcessing(WorldPawns __instance)
        {
            //List<Pawn> tmpPawnsToTick = new List<Pawn>(pawnsMothballed(__instance));
            //tmpPawnsToTick(__instance).Clear();
            //tmpPawnsToTick(__instance).AddRange((IEnumerable<Pawn>)pawnsMothballed(__instance));
            Pawn[] pawnArray;
            lock (pawnsMothballed(__instance))
            {
                pawnArray = pawnsMothballed(__instance).ToArray();
            }
            Pawn p;

            for (int index = 0; index < pawnArray.Length; index++)
            {
                p = pawnArray[index];
                try
                {
                    p.TickMothballed(15000);
                }
                catch (Exception ex)
                {
                    Log.ErrorOnce("Exception ticking mothballed world pawn. Suppressing further errors. " + (object)ex, p.thingIDNumber ^ 1535437893, false);
                }
            }
            //tmpPawnsToTick(__instance).Clear();
            //tmpPawnsToTick(__instance).AddRange((IEnumerable<Pawn>)pawnsAlive(__instance));
            lock (pawnsAlive(__instance))
            {
                pawnArray = pawnsAlive(__instance).ToArray();
            }
            for (int index = 0; index < pawnArray.Length; index++)
            {
                p = pawnArray[index];
                if (ShouldMothball(p))
                {
                    lock (pawnsAlive(__instance))
                    {
                        pawnsAlive(__instance).Remove(p);
                    }
                    lock (pawnsMothballed(__instance))
                    {
                        pawnsMothballed(__instance).Add(p);
                    }
                }
            }
            //tmpPawnsToTick(__instance).Clear();
        }
        private static void DoMothballProcessing(WorldPawns __instance)
        {
            Pawn[] pawnArray;
            lock (pawnsMothballed(__instance))
            {
                pawnArray = pawnsMothballed(__instance).ToArray();
            }
            Pawn p;

            for (int index = 0; index < pawnArray.Length; index++)
            {
                p = pawnArray[index];
                try
                {
                    p.TickMothballed(15000);
                }
                catch (Exception ex)
                {
                    Log.ErrorOnce("Exception ticking mothballed world pawn. Suppressing further errors. " + ex, p.thingIDNumber ^ 1535437893, false);
                }
            }
            lock (pawnsAlive(__instance))
            {
                pawnArray = pawnsAlive(__instance).ToArray();
            }
            for (int index = 0; index < pawnArray.Length; index++)
            {
                p = pawnArray[index];
                if (funcShouldMothball(__instance, p))
                {
                    lock (__instance)
                    {
                        HashSet <Pawn> newSet = new HashSet <Pawn>(pawnsAlive(__instance));
                        newSet.Remove(p);
                        pawnsAlive(__instance) = newSet;
                    }
                    lock (pawnsMothballed(__instance))
                    {
                        pawnsMothballed(__instance).Add(p);
                    }
                }
            }
        }
        public static bool RemovePawn(WorldPawns __instance, Pawn p)
        {
            lock (__instance)
            {
                if (!__instance.Contains(p))
                {
                    Log.Error("Tried to remove pawn " + (object)p + " from " + (object)__instance.GetType() + ", but it's not here.");
                }
                __instance.gc.CancelGCPass();
                if (__instance.pawnsMothballed.Contains(p))
                {
                    if (Find.TickManager.TicksGame % 15000 != 0)
                    {
                        try
                        {
                            p.TickMothballed(Find.TickManager.TicksGame % 15000);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Exception ticking mothballed world pawn (just before removing): " + (object)ex);
                        }
                    }
                }
                HashSet <Pawn> newPawnsAlive = new HashSet <Pawn>(__instance.pawnsAlive);
                newPawnsAlive.Remove(p);
                __instance.pawnsAlive = newPawnsAlive;

                HashSet <Pawn> newPawnsMothballed = new HashSet <Pawn>(__instance.pawnsMothballed);
                newPawnsMothballed.Remove(p);
                __instance.pawnsMothballed = newPawnsMothballed;

                HashSet <Pawn> newPawnsDead = new HashSet <Pawn>(__instance.pawnsDead);
                newPawnsDead.Remove(p);
                __instance.pawnsDead = newPawnsDead;

                HashSet <Pawn> newPawnsForcefullyKeptAsWorldPawns = new HashSet <Pawn>(__instance.pawnsForcefullyKeptAsWorldPawns);
                newPawnsDead.Remove(p);
                __instance.pawnsForcefullyKeptAsWorldPawns = newPawnsForcefullyKeptAsWorldPawns;

                p.becameWorldPawnTickAbs = -1;
            }
            return(false);
        }
        public static bool Notify_PawnDestroyed(WorldPawns __instance, Pawn p)
        {
            lock (__instance)
            {
                if (!__instance.pawnsAlive.Contains(p) && !__instance.pawnsMothballed.Contains(p))
                {
                    return(false);
                }

                HashSet <Pawn> newPawnsAlive = new HashSet <Pawn>(__instance.pawnsAlive);
                newPawnsAlive.Remove(p);
                __instance.pawnsAlive = newPawnsAlive;

                HashSet <Pawn> newPawnsMothballed = new HashSet <Pawn>(__instance.pawnsMothballed);
                newPawnsMothballed.Remove(p);
                __instance.pawnsMothballed = newPawnsMothballed;

                __instance.pawnsDead.Add(p);
            }
            return(false);
        }
Exemple #12
0
 public static void Postfix(WorldPawns __instance)
 {
     WorldPawnsTicker.Rebuild(__instance);
 }
Exemple #13
0
 public static void SituationSCPEvent(Pawn p, ref WorldPawnSituation __result, WorldPawns __instance)
 {
     if (__result == WorldPawnSituation.Free && p.kindDef == PawnKindDefOf_SCP.SCP_939_PawnKindDef)
     {
         Log.Message("Checking " + p.LabelShort);
         foreach (Map map in Find.Maps)
         {
             if (map.GameConditionManager.ActiveConditions.Any(x => x is GameCondition_SCP939 && (x as GameCondition_SCP939).ActiveSCPInArea.Contains(p)))
             {
                 Log.Message("Result Changed ");
                 __result = WorldPawnSituation.InTravelingTransportPod;
                 return;
             }
         }
     }
 }
Exemple #14
0
        public static bool WorldPawnsTick(WorldPawns __instance)
        {
            //RimThreaded.tmpPawnsToTick.Clear();
            //RimThreaded.tmpPawnsToTick.AddRange(pawnsAlive(__instance));
            //RimThreaded.worldPawns = __instance;
            //RimThreaded.tmpPawnsToTick = new ConcurrentQueue<Pawn>(pawnsAlive(__instance));
            //RimThreaded.worldPawns = __instance;
            RimThreaded.worldPawnsAlive = pawnsAlive(__instance).ToList();
            RimThreaded.worldPawnsTicks = pawnsAlive(__instance).Count;
            //RimThreaded.MainThreadWaitLoop();

            /*
             * for (int index = 0; index < WorldPawns.tmpPawnsToTick.Count; ++index)
             * {
             *  try
             *  {
             *      WorldPawns.tmpPawnsToTick[index].Tick();
             *  }
             *  catch (Exception ex)
             *  {
             *      Log.ErrorOnce("Exception ticking world pawn " + WorldPawns.tmpPawnsToTick[index].ToStringSafe<Pawn>() + ". Suppressing further errors. " + (object)ex, WorldPawns.tmpPawnsToTick[index].thingIDNumber ^ 1148571423, false);
             *  }
             *  try
             *  {
             *      if (this.ShouldAutoTendTo(WorldPawns.tmpPawnsToTick[index]))
             *          TendUtility.DoTend((Pawn)null, WorldPawns.tmpPawnsToTick[index], (Medicine)null);
             *  }
             *  catch (Exception ex)
             *  {
             *      Log.ErrorOnce("Exception tending to a world pawn " + WorldPawns.tmpPawnsToTick[index].ToStringSafe<Pawn>() + ". Suppressing further errors. " + (object)ex, WorldPawns.tmpPawnsToTick[index].thingIDNumber ^ 8765780, false);
             *  }
             * }
             */
            //WorldPawns.tmpPawnsToTick.Clear();
            if (Find.TickManager.TicksGame % 15000 == 0)
            {
                DoMothballProcessing(__instance);
            }
            //tmpPawnsToRemove(__instance).Clear();
            List <Pawn> tmpPawnsToRemove = new List <Pawn>();

            foreach (Pawn pawn in pawnsDead(__instance))
            {
                if (pawn == null)
                {
                    Log.ErrorOnce("Dead null world pawn detected, discarding.", 94424128, false);
                    tmpPawnsToRemove.Add(pawn);
                }
                else if (pawn.Discarded)
                {
                    Log.Error("World pawn " + (object)pawn + " has been discarded while still being a world pawn. This should never happen, because discard destroy mode means that the pawn is no longer managed by anything. Pawn should have been removed from the world first.", false);
                    tmpPawnsToRemove.Add(pawn);
                }
            }
            foreach (Pawn p in tmpPawnsToRemove)
            {
                pawnsDead(__instance).Remove(p);
            }
            //tmpPawnsToRemove(__instance).Clear();
            try
            {
                __instance.gc.WorldPawnGCTick();
            }
            catch (Exception ex)
            {
                Log.Error("Error in WorldPawnGCTick(): " + (object)ex, false);
            }

            return(false);
        }
Exemple #15
0
        public static bool Destroy(Pawn __instance, DestroyMode mode = DestroyMode.Vanish)
        {
            if (mode != 0 && mode != DestroyMode.KillFinalize)
            {
                Log.Error(string.Concat("Destroyed pawn ", __instance, " with unsupported mode ", mode, "."));
            }
            //ThingWithComps twc = __instance;
            //twc.Destroy(mode);
            ThingWithCompsDestroy(__instance, mode);
            Find.WorldPawns.Notify_PawnDestroyed(__instance);
            if (__instance.ownership != null)
            {
                Building_Grave assignedGrave = __instance.ownership.AssignedGrave;
                __instance.ownership.UnclaimAll();
                if (mode == DestroyMode.KillFinalize)
                {
                    assignedGrave?.CompAssignableToPawn.TryAssignPawn(__instance);
                }
            }

            __instance.ClearMind(ifLayingKeepLaying: false, clearInspiration: true);
            Lord lord = __instance.GetLord();

            if (lord != null)
            {
                PawnLostCondition cond = (mode != DestroyMode.KillFinalize) ? PawnLostCondition.Vanished : PawnLostCondition.IncappedOrKilled;
                lord.Notify_PawnLost(__instance, cond);
            }

            if (Current.ProgramState == ProgramState.Playing)
            {
                Find.GameEnder.CheckOrUpdateGameOver();
                Find.TaleManager.Notify_PawnDestroyed(__instance);
            }

            //foreach (Pawn item in PawnsFinder.AllMapsWorldAndTemporary_Alive.Where((Pawn p) => p.playerSettings != null && p.playerSettings.Master == __instance))
            //{
            //item.playerSettings.Master = null;
            //}
            //ClearMatchingMasters(__instance)
            if (Pawn_PlayerSettings_Patch.petsInit == false)
            {
                Pawn_PlayerSettings_Patch.RebuildPetsDictionary();
            }
            if (Pawn_PlayerSettings_Patch.pets.TryGetValue(__instance, out List <Pawn> pawnList))
            {
                for (int i = 0; i < pawnList.Count; i++)
                {
                    Pawn p;
                    try
                    {
                        p = pawnList[i];
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        break;
                    }
                    p.playerSettings.Master = null;
                }
            }

            /*
             * for (int i = 0; i < PawnsFinder.AllMapsWorldAndTemporary_Alive.Count; i++)
             * {
             *  Pawn p;
             *  try
             *  {
             *      p = PawnsFinder.AllMapsWorldAndTemporary_Alive[i];
             *  }
             *  catch (ArgumentOutOfRangeException)
             *  {
             *      break;
             *  }
             *  if (p.playerSettings != null && p.playerSettings.Master == __instance)
             *  {
             *      p.playerSettings.Master = null;
             *  }
             * }
             */
            if (__instance.equipment != null)
            {
                __instance.equipment.Notify_PawnDied();
            }

            if (mode != DestroyMode.KillFinalize)
            {
                if (__instance.equipment != null)
                {
                    __instance.equipment.DestroyAllEquipment();
                }

                __instance.inventory.DestroyAll();
                if (__instance.apparel != null)
                {
                    __instance.apparel.DestroyAll();
                }
            }

            WorldPawns worldPawns = Find.WorldPawns;

            if (!worldPawns.IsBeingDiscarded(__instance) && !worldPawns.Contains(__instance))
            {
                worldPawns.PassToWorld(__instance);
            }
            return(false);
        }
 public override void PostExposeData(object obj)
 {
     if (Scribe.mode == LoadSaveMode.LoadingVars)
     {
         Game game = obj as Game;
         if (game != null && game.battleLog == null)
         {
             game.battleLog = new BattleLog();
         }
         BattleLogEntry_MeleeCombat battleLogEntry_MeleeCombat = obj as BattleLogEntry_MeleeCombat;
         if (battleLogEntry_MeleeCombat != null)
         {
             if (battleLogEntry_MeleeCombat.RuleDef == null)
             {
                 RulePackDef value  = null;
                 RulePackDef value2 = null;
                 Scribe_Defs.Look(ref value, "outcomeRuleDef");
                 Scribe_Defs.Look(ref value2, "maneuverRuleDef");
                 if (value != null && value2 != null)
                 {
                     foreach (RulePackDef item in DefDatabase <RulePackDef> .AllDefsListForReading)
                     {
                         if (!item.include.NullOrEmpty() && item.include.Count == 2 && ((item.include[0] == value && item.include[1] == value2) || (item.include[1] == value && item.include[0] == value2)))
                         {
                             battleLogEntry_MeleeCombat.RuleDef = item;
                             break;
                         }
                     }
                 }
             }
             if (battleLogEntry_MeleeCombat.def == null)
             {
                 battleLogEntry_MeleeCombat.def = LogEntryDefOf.MeleeAttack;
             }
         }
     }
     if (Scribe.mode == LoadSaveMode.PostLoadInit)
     {
         Map map = obj as Map;
         if (map != null && map.pawnDestinationReservationManager == null)
         {
             map.pawnDestinationReservationManager = new PawnDestinationReservationManager();
         }
         Pawn pawn = obj as Pawn;
         if (pawn != null && pawn.Spawned && pawn.rotationTracker == null)
         {
             pawn.rotationTracker = new Pawn_RotationTracker(pawn);
         }
         Pawn_MindState pawn_MindState = obj as Pawn_MindState;
         if (pawn_MindState != null && pawn_MindState.inspirationHandler == null)
         {
             pawn_MindState.inspirationHandler = new InspirationHandler(pawn_MindState.pawn);
         }
         ImportantPawnComp importantPawnComp = obj as ImportantPawnComp;
         if (importantPawnComp != null && importantPawnComp.pawn == null)
         {
             importantPawnComp.pawn = new ThingOwner <Pawn>(importantPawnComp, oneStackOnly: true);
         }
         Pawn_RecordsTracker pawn_RecordsTracker = obj as Pawn_RecordsTracker;
         if (pawn_RecordsTracker != null && Find.TaleManager.AnyTaleConcerns(pawn_RecordsTracker.pawn))
         {
             pawn_RecordsTracker.AccumulateStoryEvent(StoryEventDefOf.TaleCreated);
         }
         WorldPawns worldPawns = obj as WorldPawns;
         if (worldPawns != null && worldPawns.gc == null)
         {
             worldPawns.gc = new WorldPawnGC();
         }
         GameCondition gameCondition = obj as GameCondition;
         if (gameCondition != null && !gameCondition.Permanent && gameCondition.Duration > 1000000000)
         {
             gameCondition.Permanent = true;
         }
         Building_TurretGun building_TurretGun = obj as Building_TurretGun;
         if (building_TurretGun != null && building_TurretGun.gun == null)
         {
             building_TurretGun.MakeGun();
         }
     }
 }