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); }
public static bool Replacement(ref string __result, Pawn pawn, Pawn fromPOV) { if (pawn.Dead) { __result = "Dead".Translate(); return(false); } if (pawn.Destroyed) { __result = "Missing".Translate(); return(false); } if (PawnUtility.IsKidnappedPawn(pawn)) { __result = "Kidnapped".Translate(); return(false); } if (pawn.kindDef == PawnKindDefOf.Slave) { __result = "Slave".Translate(); return(false); } if (PawnUtility.IsFactionLeader(pawn)) { __result = "FactionLeader".Translate(); return(false); } Faction faction = pawn.Faction; if (faction == fromPOV.Faction) { __result = string.Empty; return(false); } if (faction == null || fromPOV.Faction == null) { __result = "Neutral".Translate(); return(false); } #region ADDED if (faction == Faction.OfPlayer) { __result = "Colony".Translate(); return(false); } #endregion if (!faction.HostileTo(fromPOV.Faction)) { __result = "Neutral".Translate() + ", " + faction.Name; return(false); } __result = "Hostile".Translate() + ", " + faction.Name; return(false); }
private void DiagnoseMapPawns(out List <Pawn> mapPawnEntryPoints) { List <Pawn> pawnlist = new List <Pawn>(); foreach (Map map in Find.Maps) { foreach (Pawn p in map.mapPawns.AllPawns) { 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.FactionLeader | Flags.RelationLvl1); } if (PawnUtility.IsKidnappedPawn(p)) { addFlag(p, Flags.KeptWorldPawn | Flags.RelationLvl2); } if (p.Corpse != null) { addFlag(p, Flags.CorpseOwner | Flags.RelationLvl1); } /*Outsider caravan member patch*/ if (p.RaceProps.Humanlike) { addFlag(p, Flags.RelationLvl1); } if (allFlags.ContainsKey(p)) { pawnlist.Add(p); if (verbose) { Verse.Log.Message("[mapPawn] " + p.LabelShort + " [flag] " + markedFlagsString(p)); } } ///Unused options //if ((p.records.GetAsInt(RecordDefOf.TimeAsColonistOrColonyAnimal) > 0) && !(p.RaceProps.Humanlike)) addFlag(p, Flags.Animal | Flags.RelationLvl0); //if (allUsedTaleOwner.Contains(p)) addFlag(p, Flags.TaleEntryOwner | Flags.RelationLvl0); //if ((p.Name!=null) &&(!p.Name.Numerical)&&p.Name.ToStringFull.Contains("Serir")) Verse.Log.Message("Pawn:" + p.Name+",flag="+(allFlags.ContainsKey(p)? allFlags[p].ToString():"null")); //if (p.InContainerEnclosed) addFlag(p, Flags.KeptWorldPawn | Flags.RelationLvl0); //if (p.Spawned) addFlag(p, Flags.RelationLvl0); } } mapPawnEntryPoints = pawnlist.ToList <Pawn>(); }
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); }
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); }
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); }