示例#1
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);
 }
示例#2
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);
 }
示例#3
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);
 }
示例#4
0
        IEnumerable <Thing> GenerateThingEnumer(int forTile, Faction forFaction)
        {
            int numKinds             = kindCountRange.RandomInRange;
            int count                = countRange.RandomInRange;
            List <PawnKindDef> kinds = new List <PawnKindDef>();

            for (int j = 0; j < numKinds; j++)
            {
                if (!(from k in DefDatabase <PawnKindDef> .AllDefs
                      where !kinds.Contains(k) && PawnKindAllowed(k, forTile)
                      select k).TryRandomElementByWeight((PawnKindDef k) => SelectionChance(k), out PawnKindDef result))
                {
                    break;
                }
                kinds.Add(result);
            }
            for (int i = 0; i < count; i++)
            {
                if (!kinds.TryRandomElement(out PawnKindDef kind))
                {
                    break;
                }
                PawnKindDef kind2 = kind;
                int         tile  = forTile;

                Pawn pawnOriginal = Find.WorldPawns.AllPawnsAlive.Where(p => !p.IsPlayerControlledCaravanMember() && (PawnUtility.ForSaleBySettlement(p) || p.kindDef == PawnKindDefOf.Slave || (PawnUtility.IsKidnappedPawn(p) && p.RaceProps.Humanlike) && !PawnUtility.IsFactionLeader(p))).RandomElement();

                PawnGenerationRequest request = new PawnGenerationRequest(kind2, null, PawnGenerationContext.NonPlayer, tile);
                Pawn pawn = PawnGenerator.GeneratePawn(request); //Generate the animal!



                if (pawnOriginal == null)
                {
                    Gender newGender = pawn.gender;

                    if (Rand.RangeInclusive(0, 100) <= 25)
                    {
                        switch (pawn.gender)
                        {
                        case (Gender.Male):
                            newGender = Gender.Female;
                            break;

                        case (Gender.Female):
                            newGender = Gender.Male;
                            break;

                        default:
                            break;
                        }
                    }

                    float animalAge            = pawn.ageTracker.AgeBiologicalYearsFloat;
                    float animalLifeExpectancy = pawn.def.race.lifeExpectancy;
                    float humanLifeExpectancy  = 80f;


                    float age = animalAge * humanLifeExpectancy / animalLifeExpectancy;
                    age = Mathf.Max(age, 17); //make sure the human is at least 17 years old
                    float chronoAge = pawn.ageTracker.AgeChronologicalYears * age / animalAge;
                    var   pkds      = new List <PawnKindDef>
                    {
                        PawnKindDefOf.Slave,
                        PawnKindDefOf.Colonist,
                        PawnKindDefOf.SpaceRefugee,
                        PawnKindDefOf.Villager,
                        PawnKindDefOf.Drifter,
                        PawnKindDefOf.AncientSoldier
                    };


                    PawnKindDef rKind = pkds.RandElement();

                    var hRequest = new PawnGenerationRequest(rKind, Faction.OfPlayer,
                                                             PawnGenerationContext.NonPlayer, fixedBiologicalAge: age,
                                                             fixedChronologicalAge: chronoAge, fixedGender: newGender);


                    pawnOriginal = PawnGenerator.GeneratePawn(hRequest);


                    pawn.Name = pawnOriginal.Name;
                }
                else
                {
                    pawn.Name = pawnOriginal.Name;
                    Find.WorldPawns.RemovePawn(pawnOriginal);
                }

                var pm = TfSys.TransformedPawn.Create(pawnOriginal, pawn); //pawnOriginal is human, pawn is animal
                FormerHumanUtilities.MakeAnimalSapient(pawnOriginal, pawn, Rand.Range(0.5f, 1f));
                Find.World.GetComponent <PawnmorphGameComp>().AddTransformedPawn(pm);

                yield return(pawn);
            }
        }
        /// <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);
        }