示例#1
0
        public static bool MovePawnToColony(Pawn pawn, Pawn inviter, Map destination)
        {
            Map map = destination;

            if (map.ParentFaction != Faction.OfPlayer)
            {
                if (inviter.IsCaravanMember() || PawnUtility.IsTravelingInTransportPodWorldObject(pawn) || inviter.Map.ParentFaction != Faction.OfPlayer)
                {
                    map = Find.AnyPlayerHomeMap;
                }
                else
                {
                    map = inviter.Map;
                }
            }

            if (!TryFindEntryCell(map, out IntVec3 cell))
            {
                return(false);
            }

            if (pawn.apparel.AnyApparelLocked)
            {
                var req = PawnGenerationRequest.MakeDefault();
                req.Tile = inviter.Map.Tile;
                PawnApparelGenerator.GenerateStartingApparelFor(pawn, req);
            }

            GenSpawn.Spawn(pawn, cell, map, WipeMode.Vanish);

            Letters.SendJoinLetter(pawn, inviter, map);

            return(true);
        }
示例#2
0
 public WorldPawnSituation GetSituation(Pawn p)
 {
     if (!this.Contains(p))
     {
         return(WorldPawnSituation.None);
     }
     if (p.Dead || p.Destroyed)
     {
         return(WorldPawnSituation.Dead);
     }
     if (PawnUtility.IsFactionLeader(p))
     {
         return(WorldPawnSituation.FactionLeader);
     }
     if (PawnUtility.IsKidnappedPawn(p))
     {
         return(WorldPawnSituation.Kidnapped);
     }
     if (p.IsCaravanMember())
     {
         return(WorldPawnSituation.CaravanMember);
     }
     if (PawnUtility.IsTravelingInTransportPodWorldObject(p))
     {
         return(WorldPawnSituation.InTravelingTransportPod);
     }
     if (PawnUtility.ForSaleBySettlement(p))
     {
         return(WorldPawnSituation.ForSaleBySettlement);
     }
     return(WorldPawnSituation.Free);
 }
示例#3
0
 private bool ShouldMothball(Pawn p)
 {
     if (DefPreventingMothball(p) == null && !p.IsCaravanMember())
     {
         return(!PawnUtility.IsTravelingInTransportPodWorldObject(p));
     }
     return(false);
 }
示例#4
0
 private bool ShouldAutoTendTo(Pawn pawn)
 {
     if (!pawn.Dead && !pawn.Destroyed && pawn.IsHashIntervalTick(7500) && !pawn.IsCaravanMember())
     {
         return(!PawnUtility.IsTravelingInTransportPodWorldObject(pawn));
     }
     return(false);
 }
示例#5
0
 public WorldPawnSituation GetSituation(Pawn p)
 {
     if (!Contains(p))
     {
         return(WorldPawnSituation.None);
     }
     if (p.Dead || p.Destroyed)
     {
         return(WorldPawnSituation.Dead);
     }
     if (PawnUtility.IsFactionLeader(p))
     {
         return(WorldPawnSituation.FactionLeader);
     }
     if (PawnUtility.IsKidnappedPawn(p))
     {
         return(WorldPawnSituation.Kidnapped);
     }
     if (p.IsBorrowedByAnyFaction())
     {
         return(WorldPawnSituation.Borrowed);
     }
     if (p.IsCaravanMember())
     {
         return(WorldPawnSituation.CaravanMember);
     }
     if (PawnUtility.IsTravelingInTransportPodWorldObject(p))
     {
         return(WorldPawnSituation.InTravelingTransportPod);
     }
     if (PawnUtility.ForSaleBySettlement(p))
     {
         return(WorldPawnSituation.ForSaleBySettlement);
     }
     if (QuestUtility.IsReservedByQuestOrQuestBeingGenerated(p))
     {
         return(WorldPawnSituation.ReservedByQuest);
     }
     if (p.teleporting)
     {
         return(WorldPawnSituation.Teleporting);
     }
     return(WorldPawnSituation.Free);
 }
示例#6
0
            public static bool Prefix(Pawn member, ref bool free)
            {
                if (member.Faction == Faction.OfPlayer)
                {
                    return(true);
                }
                if (PawnUtility.IsTravelingInTransportPodWorldObject(member))
                {
                    return(false);                                                          // Fired in pod? Don't trigger
                }
                var compGuest = member.CompGuest();

                if (compGuest == null || !compGuest.rescued || member.guest == null || PawnUtility.IsTravelingInTransportPodWorldObject(member))
                {
                    return(true);
                }

                free = true;
                Traverse.Create(member.guest).Field("hostFactionInt").SetValue(Faction.OfPlayer); // Settings this makes the reward work
                compGuest.rescued = false;                                                        // Turn back off

                return(true);
            }
示例#7
0
 private string GetCriticalPawnReason(Pawn pawn)
 {
     if (pawn.Discarded)
     {
         return(null);
     }
     if (PawnUtility.EverBeenColonistOrTameAnimal(pawn) && pawn.RaceProps.Humanlike)
     {
         return("Colonist");
     }
     if (PawnGenerator.IsBeingGenerated(pawn))
     {
         return("Generating");
     }
     if (PawnUtility.IsFactionLeader(pawn))
     {
         return("FactionLeader");
     }
     if (PawnUtility.IsKidnappedPawn(pawn))
     {
         return("Kidnapped");
     }
     if (pawn.IsCaravanMember())
     {
         return("CaravanMember");
     }
     if (PawnUtility.IsTravelingInTransportPodWorldObject(pawn))
     {
         return("TransportPod");
     }
     if (PawnUtility.ForSaleBySettlement(pawn))
     {
         return("ForSale");
     }
     if (Find.WorldPawns.ForcefullyKeptPawns.Contains(pawn))
     {
         return("ForceKept");
     }
     if (pawn.SpawnedOrAnyParentSpawned)
     {
         return("Spawned");
     }
     if (!pawn.Corpse.DestroyedOrNull())
     {
         return("CorpseExists");
     }
     if (pawn.RaceProps.Humanlike && Current.ProgramState == ProgramState.Playing)
     {
         if (Find.PlayLog.AnyEntryConcerns(pawn))
         {
             return("InPlayLog");
         }
         if (Find.BattleLog.AnyEntryConcerns(pawn))
         {
             return("InBattleLog");
         }
     }
     if (Current.ProgramState == ProgramState.Playing && Find.TaleManager.AnyActiveTaleConcerns(pawn))
     {
         return("InActiveTale");
     }
     if (QuestUtility.IsReservedByQuestOrQuestBeingGenerated(pawn))
     {
         return("ReservedByQuest");
     }
     return(null);
 }
示例#8
0
        private static void ExecuteTicks()
        {
            if (mapPreTickComplete && plantMaterialsCount > 0)
            {
                int index = Interlocked.Decrement(ref plantMaterialsCount);
                while (index >= 0)
                {
                    try
                    {
                        WindManager_Patch.plantMaterials[index].SetFloat(ShaderPropertyIDs.SwayHead, plantSwayHead);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Exception ticking " + WindManager_Patch.plantMaterials[index].ToStringSafe() + ": " + ex);
                    }
                    index = Interlocked.Decrement(ref plantMaterialsCount);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }

            else if (tickListNormalComplete && thingListNormalTicks > 0)
            {
                int index = Interlocked.Decrement(ref thingListNormalTicks);
                while (index >= 0)
                {
                    Thing thing = thingListNormal[index];
                    if (!thing.Destroyed)
                    {
                        try
                        {
                            thing.Tick();
                        }
                        catch (Exception ex)
                        {
                            string text = thing.Spawned ? (" (at " + thing.Position + ")") : "";
                            if (Prefs.DevMode)
                            {
                                Log.Error("Exception ticking " + thing.ToStringSafe() + text + ": " + ex);
                            }
                            else
                            {
                                Log.ErrorOnce("Exception ticking " + thing.ToStringSafe() + text + ". Suppressing further errors. Exception: " + ex, thing.thingIDNumber ^ 0x22627165);
                            }
                        }
                    }
                    index = Interlocked.Decrement(ref thingListNormalTicks);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }
            else if (tickListRareComplete && thingListRareTicks > 0)
            {
                int index = Interlocked.Decrement(ref thingListRareTicks);
                while (index >= 0)
                {
                    Thing thing = thingListRare[index];
                    if (!thing.Destroyed)
                    {
                        try
                        {
                            thing.TickRare();
                        }
                        catch (Exception ex)
                        {
                            string text = thing.Spawned ? (" (at " + thing.Position + ")") : "";
                            if (Prefs.DevMode)
                            {
                                Log.Error("Exception ticking " + thing.ToStringSafe() + text + ": " + ex);
                            }
                            else
                            {
                                Log.ErrorOnce("Exception ticking " + thing.ToStringSafe() + text + ". Suppressing further errors. Exception: " + ex, thing.thingIDNumber ^ 0x22627165);
                            }
                        }
                    }
                    index = Interlocked.Decrement(ref thingListRareTicks);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }
            else if (tickListLongComplete && thingListLongTicks > 0)
            {
                int index = Interlocked.Decrement(ref thingListLongTicks);
                while (index >= 0)
                {
                    Thing thing = thingListLong[index];
                    if (!thing.Destroyed)
                    {
                        try
                        {
                            thing.TickLong();
                        }
                        catch (Exception ex)
                        {
                            string text = thing.Spawned ? (" (at " + thing.Position + ")") : "";
                            if (Prefs.DevMode)
                            {
                                Log.Error("Exception ticking " + thing.ToStringSafe() + text + ": " + ex);
                            }
                            else
                            {
                                Log.ErrorOnce("Exception ticking " + thing.ToStringSafe() + text + ". Suppressing further errors. Exception: " + ex, thing.thingIDNumber ^ 0x22627165);
                            }
                        }
                    }
                    index = Interlocked.Decrement(ref thingListLongTicks);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }
            else if (worldTickComplete && worldPawnsTicks > 0)
            {
                int index = Interlocked.Decrement(ref worldPawnsTicks);
                while (index >= 0)
                {
                    Pawn pawn = worldPawnsAlive[index];
                    try
                    {
                        pawn.Tick();
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorOnce("Exception ticking world pawn " + pawn.ToStringSafe() + ". Suppressing further errors. " + (object)ex, pawn.thingIDNumber ^ 1148571423, false);
                    }
                    try
                    {
                        if (!pawn.Dead && !pawn.Destroyed && (pawn.IsHashIntervalTick(7500) && !pawn.IsCaravanMember()) && !PawnUtility.IsTravelingInTransportPodWorldObject(pawn))
                        {
                            TendUtility.DoTend(null, pawn, null);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorOnce("Exception tending to a world pawn " + pawn.ToStringSafe() + ". Suppressing further errors. " + (object)ex, pawn.thingIDNumber ^ 8765780, false);
                    }
                    index = Interlocked.Decrement(ref worldPawnsTicks);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }

            else if (worldTickComplete && worldObjectsTicks > 0)
            {
                int index = Interlocked.Decrement(ref worldObjectsTicks);
                while (index >= 0)
                {
                    try
                    {
                        worldObjects[index].Tick();
                    } catch (Exception ex)
                    {
                        Log.Error("Exception ticking " + worldObjects[index].ToStringSafe() + ": " + ex);
                    }
                    index = Interlocked.Decrement(ref worldObjectsTicks);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }

            else if (worldTickComplete && allFactionsTicks > 0)
            {
                int index = Interlocked.Decrement(ref allFactionsTicks);
                while (index >= 0)
                {
                    try
                    {
                        allFactions[index].FactionTick();
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Exception ticking " + allFactions[index].ToStringSafe() + ": " + ex);
                    }
                    index = Interlocked.Decrement(ref allFactionsTicks);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }

            else if (mapPostTickComplete && steadyEnvironmentEffectsTicksCompleted < totalSteadyEnvironmentEffectsTicks)
            {
                int ticketIndex = Interlocked.Increment(ref steadyEnvironmentEffectsTicksCompleted) - 1;
                int steadyEnvironmentEffectsIndex = 0;
                while (ticketIndex < totalSteadyEnvironmentEffectsTicks)
                {
                    int index = ticketIndex;
                    while (ticketIndex >= steadyEnvironmentEffectsStructures[steadyEnvironmentEffectsIndex].steadyEnvironmentEffectsTicks)
                    {
                        steadyEnvironmentEffectsIndex++;
                    }
                    if (steadyEnvironmentEffectsIndex > 0)
                    {
                        index = ticketIndex - steadyEnvironmentEffectsStructures[steadyEnvironmentEffectsIndex - 1].steadyEnvironmentEffectsTicks;
                    }
                    int cycleIndex = (steadyEnvironmentEffectsStructures[steadyEnvironmentEffectsIndex].steadyEnvironmentEffectsCycleIndexOffset
                                      - index) % steadyEnvironmentEffectsStructures[steadyEnvironmentEffectsIndex].steadyEnvironmentEffectsArea;
                    IntVec3 c = steadyEnvironmentEffectsStructures[steadyEnvironmentEffectsIndex].steadyEnvironmentEffectsCellsInRandomOrder.Get(cycleIndex);
                    try
                    {
                        SteadyEnvironmentEffects_Patch.DoCellSteadyEffects(
                            steadyEnvironmentEffectsStructures[steadyEnvironmentEffectsIndex].steadyEnvironmentEffects, c);
                    } catch (Exception ex)
                    {
                        Log.Error("Exception ticking steadyEnvironmentEffectsCells " + index.ToStringSafe() + ": " + ex);
                    }
                    //Interlocked.Increment(ref SteadyEnvironmentEffects_Patch.cycleIndex(steadyEnvironmentEffectsInstance));
                    ticketIndex = Interlocked.Increment(ref steadyEnvironmentEffectsTicksCompleted) - 1;
                }
                if (ticketIndex == totalSteadyEnvironmentEffectsTicks)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }

            else if (mapPostTickComplete && wildPlantSpawnerTicksCompleted < wildPlantSpawnerTicksCount)
            {
                int ticketIndex           = Interlocked.Increment(ref wildPlantSpawnerTicksCompleted) - 1;
                int wildPlantSpawnerIndex = 0;
                WildPlantSpawnerStructure wildPlantSpawner;
                int index;
                while (ticketIndex < wildPlantSpawnerTicksCount)
                {
                    index = ticketIndex;
                    while (ticketIndex >= wildPlantSpawners[wildPlantSpawnerIndex].WildPlantSpawnerTicks)
                    {
                        wildPlantSpawnerIndex++;
                    }
                    if (wildPlantSpawnerIndex > 0)
                    {
                        index = ticketIndex - wildPlantSpawners[wildPlantSpawnerIndex - 1].WildPlantSpawnerTicks;
                    }
                    try
                    {
                        wildPlantSpawner = wildPlantSpawners[wildPlantSpawnerIndex];
                        int     cycleIndex = (wildPlantSpawner.WildPlantSpawnerCycleIndexOffset - index) % wildPlantSpawner.WildPlantSpawnerArea;
                        IntVec3 intVec     = wildPlantSpawner.WildPlantSpawnerCellsInRandomOrder.Get(cycleIndex);

                        if ((wildPlantSpawner.WildPlantSpawnerCycleIndexOffset - index) > wildPlantSpawner.WildPlantSpawnerArea)
                        {
                            Interlocked.Add(ref wildPlantSpawner.DesiredPlants2Tmp1000,
                                            1000 * (int)WildPlantSpawner_Patch.GetDesiredPlantsCountAt2(
                                                wildPlantSpawner.WildPlantSpawnerMap, intVec, intVec,
                                                wildPlantSpawner.WildPlantSpawnerCurrentPlantDensity));
                            if (intVec.GetTerrain(wildPlantSpawners[wildPlantSpawnerIndex].WildPlantSpawnerMap).fertility > 0f)
                            {
                                Interlocked.Increment(ref wildPlantSpawner.FertilityCells2Tmp);
                            }

                            float mtb = WildPlantSpawner_Patch.GoodRoofForCavePlant2(
                                wildPlantSpawner.WildPlantSpawnerMap, intVec) ? 130f :
                                        wildPlantSpawner.WildPlantSpawnerMap.Biome.wildPlantRegrowDays;
                            if (Rand.Chance(wildPlantSpawner.WildPlantSpawnerChance) && Rand.MTBEventOccurs(mtb, 60000f, 10000) &&
                                WildPlantSpawner_Patch.CanRegrowAt2(wildPlantSpawner.WildPlantSpawnerMap, intVec))
                            {
                                wildPlantSpawner.WildPlantSpawnerInstance.CheckSpawnWildPlantAt(intVec,
                                                                                                wildPlantSpawner.WildPlantSpawnerCurrentPlantDensity, wildPlantSpawner.DesiredPlantsTmp1000 / 1000.0f);
                            }
                        }
                        else
                        {
                            Interlocked.Add(ref wildPlantSpawner.DesiredPlantsTmp1000,
                                            1000 * (int)WildPlantSpawner_Patch.GetDesiredPlantsCountAt2(
                                                wildPlantSpawner.WildPlantSpawnerMap, intVec, intVec,
                                                wildPlantSpawner.WildPlantSpawnerCurrentPlantDensity));
                            if (intVec.GetTerrain(wildPlantSpawner.WildPlantSpawnerMap).fertility > 0f)
                            {
                                Interlocked.Increment(ref wildPlantSpawner.FertilityCellsTmp);
                            }

                            float mtb = WildPlantSpawner_Patch.GoodRoofForCavePlant2(wildPlantSpawner.WildPlantSpawnerMap, intVec) ? 130f :
                                        wildPlantSpawner.WildPlantSpawnerMap.Biome.wildPlantRegrowDays;
                            if (Rand.Chance(wildPlantSpawner.WildPlantSpawnerChance) && Rand.MTBEventOccurs(mtb, 60000f, 10000) &&
                                WildPlantSpawner_Patch.CanRegrowAt2(wildPlantSpawner.WildPlantSpawnerMap, intVec))
                            {
                                wildPlantSpawner.WildPlantSpawnerInstance.CheckSpawnWildPlantAt(intVec,
                                                                                                wildPlantSpawner.WildPlantSpawnerCurrentPlantDensity, wildPlantSpawner.DesiredPlants);
                            }
                        }

                        if (ticketIndex == wildPlantSpawners[wildPlantSpawnerIndex].WildPlantSpawnerTicks - 1)
                        {
                            if ((wildPlantSpawner.WildPlantSpawnerCycleIndexOffset - index) > wildPlantSpawner.WildPlantSpawnerArea)
                            {
                                WildPlantSpawner_Patch.calculatedWholeMapNumDesiredPlants(wildPlantSpawner.WildPlantSpawnerInstance)            = wildPlantSpawner.DesiredPlantsTmp1000 / 1000.0f;
                                WildPlantSpawner_Patch.calculatedWholeMapNumDesiredPlantsTmp(wildPlantSpawner.WildPlantSpawnerInstance)         = wildPlantSpawner.DesiredPlants2Tmp1000 / 1000.0f;
                                WildPlantSpawner_Patch.calculatedWholeMapNumNonZeroFertilityCells(wildPlantSpawner.WildPlantSpawnerInstance)    = wildPlantSpawner.FertilityCellsTmp;
                                WildPlantSpawner_Patch.calculatedWholeMapNumNonZeroFertilityCellsTmp(wildPlantSpawner.WildPlantSpawnerInstance) = wildPlantSpawner.FertilityCells2Tmp;
                            }
                            else
                            {
                                WildPlantSpawner_Patch.calculatedWholeMapNumDesiredPlantsTmp(wildPlantSpawner.WildPlantSpawnerInstance)      = wildPlantSpawner.DesiredPlantsTmp1000 / 1000.0f;
                                WildPlantSpawner_Patch.calculatedWholeMapNumNonZeroFertilityCells(wildPlantSpawner.WildPlantSpawnerInstance) = wildPlantSpawner.FertilityCellsTmp;
                            }
                            if (index == -1)
                            {
                                Interlocked.Increment(ref listsFullyProcessed);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Exception ticking WildPlantSpawner: " + ex);
                    }
                    ticketIndex = Interlocked.Increment(ref wildPlantSpawnerTicksCompleted) - 1;
                }
                if (ticketIndex == wildPlantSpawnerTicksCount)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }
            else if (mapPostTickComplete && totalTradeShipTicksCompleted < totalTradeShipTicks)
            {
                int ticketIndex         = Interlocked.Increment(ref totalTradeShipTicksCompleted) - 1;
                int totalTradeShipIndex = 0;
                while (ticketIndex < totalTradeShipTicks)
                {
                    int index = ticketIndex;
                    while (ticketIndex >= tradeShips[totalTradeShipIndex].TradeShipTicks)
                    {
                        totalTradeShipIndex++;
                    }
                    if (totalTradeShipIndex > 0)
                    {
                        index = ticketIndex - tradeShips[totalTradeShipIndex - 1].TradeShipTicks;
                    }
                    Pawn pawn = tradeShips[totalTradeShipIndex].TradeShipThings[index] as Pawn;
                    if (pawn != null)
                    {
                        try
                        {
                            pawn.Tick();
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Exception ticking Pawn: " + pawn.ToStringSafe() + " " + ex);
                        }
                        if (pawn.Dead)
                        {
                            lock (tradeShips[totalTradeShipIndex].TradeShipThings)
                            {
                                tradeShips[totalTradeShipIndex].TradeShipThings.Remove(pawn);
                            }
                        }
                    }
                    ticketIndex = Interlocked.Increment(ref totalTradeShipTicksCompleted) - 1;
                }
                if (ticketIndex == totalTradeShipTicks)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }
            else if (worldTickComplete && WorldComponentTicks > 0)
            {
                int index = Interlocked.Decrement(ref WorldComponentTicks);
                while (index >= 0)
                {
                    //try
                    //{
                    WorldComponent wc = WorldComponents[index];
                    if (null != wc)
                    {
                        lock (wc)
                        {
                            try
                            {
                                wc.WorldComponentTick();
                            } catch (Exception ex)
                            {
                                Log.Error("Exception ticking World Component: " + wc.ToStringSafe() + ex);
                            }
                        }
                    }
                    //}
                    //catch (Exception ex)
                    //{
                    //    Log.Error(ex.ToString());
                    //}
                    index = Interlocked.Decrement(ref WorldComponentTicks);
                }
                if (index == -1)
                {
                    Interlocked.Increment(ref listsFullyProcessed);
                }
            }

            /*
             * while(drawQueue.TryDequeue(out Thing drawThing))
             * {
             *  IntVec3 position = drawThing.Position;
             *  if ((cellRect.Contains(position) || drawThing.def.drawOffscreen) && (!fogGrid[cellIndices.CellToIndex(position)] || drawThing.def.seeThroughFog) && (drawThing.def.hideAtSnowDepth >= 1.0 || snowGrid.GetDepth(position) <= (double)drawThing.def.hideAtSnowDepth))
             *  {
             *      try
             *      {
             *          drawThing.Draw();
             *      }
             *      catch (Exception ex)
             *      {
             *          Log.Error("Exception drawing " + (object)drawThing + ": " + ex.ToString(), false);
             *      }
             *  }
             * }
             */
        }
        /// <summary>
        /// GC().The best way to shrink Rimworld saves,I think.
        /// </summary>
        /// <param name="verbose">Determine if GC() should log details very very verbosely</param>
        /// <returns>Count of disposed World pawns</returns>
        public int GC(bool verbose = false)
        {
            /*
             * TODO Log
             * 1.talelog by interest             -X
             * 2.animal  - deconstruct relation  -Done
             * 3.deeperclean?remove hediffs      -X
             * 5.correct verbose log             -Done
             * 6.yield return "status"           -X
             * 7.UI compability                  -Done
             * 8.Filth cleaner                   -Done
             * 9.Fix:Faction Leader              -Done
             * 10.Fix:Faction Relations          -Done
             * 12.Warp->Wrap                     -Done
             */

            /*
             * TODO A18
             *  4.adjustable GC depth           -X
             *  11.GC boostup                   -Done
             *  13.remake GC System             -Done
             *  13.Keyed in Float menu items    -Done
             *  14.help contents                -Done
             *  15.Optimize Cleanser frame      -Done
             *  16.Optimize Floatmenu System    -Done
             *  17.Debug only options           -Done
             */

            /*
             * TODO 1.0
             *  18.Clean snow                   -Done
             *  19.whole-map clean              -Done
             *  20.remake log                   -Done
             *  21.Mod framework                -Done
             *  22.settings                     -Done
             *  23.MuteGC                       -Done
             *  24.MuteCL                       -Done
             *  25.remake FloatMenuUtil         -Done
             *  26.timer of gc                  -X
             *  27.toolbox integration          -Done
             *  28.MainButtonDef into xml       -Done
             *  29.try catch                    -Done
             *  30.Find.CurrentMap==null check  -Done
             *  31.MainButtonWorker             -Done
             *  32.Messages.Message(str,historical) settings -Done
             *  33.AvoidGrid rework             -Done
             *  34.Faction rework & cleanup     -Done
             *  35.Close letter stack           -Done
             */

            if (Current.ProgramState != ProgramState.Playing)
            {
                Verse.Log.Error("You must be kidding me...GC a save without loading one?");
                return(0);
            }

            /*Initialization*/
            Verse.Log.Message("[GC Log] Pre-Initializing GC...");
            this.reference = Find.WorldPawns.AllPawnsAliveOrDead.ToList();
            this.allFlags.Clear();
            this.verbose = verbose;
            if (verbose)
            {
                allFlagsCounter.Clear();
                allFlagsCounter.Add(Flags.None, 0);
                for (int j = 0; j < FlagsCountNotNull; j++)
                {
                    allFlagsCounter.Add((Flags)(1 << j), 0);
                }
            }

            /*Generate EntryPoints from Map Pawns*/
            Verse.Log.Message("[GC Log] Generating EntryPoints from Map Pawns...");
            List <Pawn> mapPawnEntryPoints;

            DiagnoseMapPawns(out mapPawnEntryPoints);
            if (verbose)
            {
                Verse.Log.Message("[GC Log][Verbose] " + allPawnsCounter.Count().ToString() + " Map Pawns marked during diagnosis");
            }

            /*Reset counters*/
            allPawnsCounter.Clear();
            if (verbose)
            {
                allFlagsCounter.Clear();
                allFlagsCounter.Add(Flags.None, 0);
                for (int j = 0; j < FlagsCountNotNull; j++)
                {
                    allFlagsCounter.Add((Flags)(1 << j), 0);
                }
            }

            /*Generate a list of pawns concerned by used Tales*/
            Verse.Log.Message("[GC Log] Collecting Pawns concerned by Used Tales...");
            List <Pawn> allUsedTalePawns;

            CleanserUtil.InitUsedTalePawns(out allUsedTalePawns);

            /*Diagnosis:marking entries on WorldPawns.*/
            Verse.Log.Message("[GC Log] Running diagnosis on WorldPawns...");
            foreach (Pawn p in reference)
            {
                if (p.IsColonist)
                {
                    addFlag(p, Flags.Colonist | Flags.RelationLvl2);
                }
                if (p.IsPrisonerOfColony)
                {
                    addFlag(p, Flags.Prisoner | Flags.RelationLvl2);
                }
                if (PawnUtility.IsFactionLeader(p))
                {
                    addFlag(p, Flags.KeptWorldPawn | Flags.FactionLeader | Flags.RelationLvl1);
                }
                if (PawnUtility.IsKidnappedPawn(p))
                {
                    addFlag(p, Flags.KeptWorldPawn | Flags.RelationLvl2);
                }
                if (p.Corpse != null)
                {
                    addFlag(p, Flags.CorpseOwner | Flags.RelationLvl1);
                }
                if (allUsedTalePawns.Contains(p))
                {
                    addFlag(p, Flags.TaleEntryOwner | Flags.RelationLvl0);
                }

                if (p.InContainerEnclosed)
                {
                    addFlag(p, Flags.KeptWorldPawn | Flags.RelationLvl0);
                }
                if (p.Spawned)
                {
                    addFlag(p, Flags.RelationLvl0);
                }
                if (p.IsPlayerControlledCaravanMember())
                {
                    addFlag(p, Flags.KeptWorldPawn | Flags.RelationLvl2);
                }
                if (PawnUtility.IsTravelingInTransportPodWorldObject(p))
                {
                    addFlag(p, Flags.KeptWorldPawn | Flags.RelationLvl2);
                }

                //Patch:A18 new entry
                if (PawnUtility.ForSaleBySettlement(p))
                {
                    addFlag(p, Flags.OnSale | Flags.RelationLvl0);
                }

                if (verbose)
                {
                    Verse.Log.Message("[worldPawn] " + p.LabelShort + " [flag] " + markedFlagsString(p));
                }
            }

            if (verbose)
            {
                Verse.Log.Message("[GC Log][Verbose] " + allPawnsCounter.Count().ToString() + " World Pawns marked during diagnosis");
            }


            int i;

            /*Expansion 1:Expand relation network from map pawns.*/
            Verse.Log.Message("[GC Log] Expanding Relation networks through Map Pawn Entry Points...");
            for (i = mapPawnEntryPoints.Count - 1; i > -1; i--)
            {
                if (containsFlag(mapPawnEntryPoints[i], Flags.RelationLvl2))
                {
                    expandRelation(mapPawnEntryPoints[i], Flags.RelationLvl1);
                    mapPawnEntryPoints.RemoveAt(i);
                }
            }

            for (i = mapPawnEntryPoints.Count - 1; i > -1; i--)
            {
                if (containsFlag(mapPawnEntryPoints[i], Flags.RelationLvl1))
                {
                    expandRelation(mapPawnEntryPoints[i], Flags.RelationLvl0);
                    mapPawnEntryPoints.RemoveAt(i);
                }
            }

            /*Its unnecessary to process RelationLvl0 in mapPawnEntryPoints,
             * for they are not related to any world pawns.
             */

            /*Expansion 2:Expand relation network from world pawns.*/
            Verse.Log.Message("[GC Log] Expanding Relation networks on marked World Pawns...");
            for (i = reference.Count - 1; i > -1; i--)
            {
                if (containsFlag(reference[i], Flags.RelationLvl2))
                {
                    expandRelation(reference[i], Flags.RelationLvl1);
                    reference.RemoveAt(i);
                }
            }

            for (i = reference.Count - 1; i > -1; i--)
            {
                if (containsFlag(reference[i], Flags.RelationLvl1))
                {
                    expandRelation(reference[i], Flags.RelationLvl0);
                    reference.RemoveAt(i);
                }
            }

            for (i = reference.Count - 1; i > -1; i--)
            {
                if (containsFlag(reference[i], Flags.RelationLvl0))
                {
                    reference.RemoveAt(i);
                }
            }


            int a = 0;

            /*VerboseMode:counting addFlag() calls.*/
            if (verbose)
            {
                foreach (KeyValuePair <Pawn, int> p in allPawnsCounter)
                {
                    a += p.Value;
                }
                Verse.Log.Message("[GC Log][Verbose] " + allPawnsCounter.Count().ToString() + " World Pawns marked during Expanding");
                if (debug)
                {
                    Verse.Log.Message("addFlag() called " + a + " times");
                }
            }


            /*Posfix:remove UsedTalePawns.*/
            Verse.Log.Message("[GC Log] Excluding Pawns concerned by Used Tales...");
            foreach (Pawn p in allUsedTalePawns)
            {
                reference.Remove(p);
            }


            /*GC Core:dispose all pawns left in reference list.*/
            Verse.Log.Message("[GC Log] Disposing World Pawns...");
            a = reference.Count;
            Pawn pawn;

            for (i = reference.Count - 1; i > -1; i--)
            {
                pawn = reference[i];
                //Patch:Mysterious WorldPawn.missing
                //Update:This patch is disabled due to safety concerns.
                //if(Find.WorldPawns.Contains(pawn))
                Find.WorldPawns.RemovePawn(pawn);
                if (!pawn.Destroyed)
                {
                    pawn.Destroy(DestroyMode.Vanish);
                }
                if (!pawn.Discarded)
                {
                    pawn.Discard(true);
                }
            }

            /*VerboseMode:Finalize output*/
            if (verbose)
            {
                string s = "[GC Log][Verbose] Flag calls stat:";
                allFlagsCounter.Remove(Flags.None);
                foreach (KeyValuePair <Flags, int> pair in allFlagsCounter)
                {
                    s += "\n  " + pair.Key.ToString() + " : " + pair.Value;
                }
                Verse.Log.Message(s);
            }

            Verse.Log.Message("[GC Log] GC() completed with " + a + " World Pawns disposed");

            return(a);
        }
示例#10
0
        /// <summary>
        /// Manual finalizer for WorldPawnCleaner.GC().
        /// Deconstruct all animal families on map and discard the redundant members.
        /// </summary>
        /// <returns>The count of discarded members.</returns>
        public static int DeconstructAnimalFamily()
        {
            List <Pawn> worldpawns = new List <Pawn>();

            foreach (Pawn p in Find.WorldPawns.AllPawnsAliveOrDead)
            {
                worldpawns.Add(p);
            }

            List <Pawn> queue    = new List <Pawn>();
            List <Pawn> pawnlist = new List <Pawn>();

            foreach (Map map in Find.Maps)
            {
                foreach (Pawn p in map.mapPawns.AllPawns)
                {
                    if ((p.records.GetAsInt(RecordDefOf.TimeAsColonistOrColonyAnimal) > 0) && !(p.RaceProps.Humanlike))
                    {
                        pawnlist.Add(p);
                    }
                }
            }

            foreach (Pawn p in pawnlist)
            {
                //Patch:null relationship on robots.
                if (p.relations != null)
                {
                    foreach (Pawn p2 in expandRelation(p))
                    {
                        if (worldpawns.Contains(p2) && (!p2.Spawned) && (!p2.IsPlayerControlledCaravanMember()) && (!PawnUtility.IsTravelingInTransportPodWorldObject(p2))
                            //Patch:Corpses remained on maps.
                            && (p.Corpse == null)
                            )
                        {
                            queue.Add(p2);
                            worldpawns.Remove(p2);
                        }
                    }
                }
            }


            //Patch:2nd Pawn of a used Tale_DoublePawn will raise Scribe Warnings if discarded
            List <Pawn> allUsedTaleOwner;

            CleanserUtil.InitUsedTalePawns(out allUsedTaleOwner);
            foreach (Pawn pawn in allUsedTaleOwner)
            {
                queue.Remove(pawn);
            }

            int a = queue.Count;

            foreach (Pawn pawn in queue)
            {
                Find.WorldPawns.RemovePawn(pawn);
                if (!pawn.Destroyed)
                {
                    pawn.Destroy(DestroyMode.Vanish);
                }
                if (!pawn.Discarded)
                {
                    pawn.Discard(true);
                }
            }

            Find.WindowStack.WindowOfType <UserInterface>().Notify_PawnsCountDirty();
            return(a);
        }
示例#11
0
 //candidate for reverse patch
 public static void WorldPawnsListTick()
 {
     while (true)
     {
         int index = Interlocked.Decrement(ref worldPawnsTicks);
         if (index < 0)
         {
             return;
         }
         Pawn pawn = worldPawnsAlive[index];
         try
         {
             pawn.Tick();
         }
         catch (Exception ex)
         {
             Log.ErrorOnce("Exception ticking world pawn " + pawn.ToStringSafe() + ". Suppressing further errors. " + ex, pawn.thingIDNumber ^ 1148571423);
         }
         try
         {
             if (!pawn.Dead && !pawn.Destroyed && (pawn.IsHashIntervalTick(7500) && !pawn.IsCaravanMember()) && !PawnUtility.IsTravelingInTransportPodWorldObject(pawn))
             {
                 TendUtility.DoTend(null, pawn, null);
             }
         }
         catch (Exception ex)
         {
             Log.ErrorOnce("Exception tending to a world pawn " + pawn.ToStringSafe() + ". Suppressing further errors. " + ex, pawn.thingIDNumber ^ 8765780);
         }
     }
 }