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); }
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(); } }
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); }
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); }
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); }
public static void Postfix(WorldPawns __instance) { WorldPawnsTicker.Rebuild(__instance); }
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; } } } }
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); }
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(); } } }