public static Pawn GeneratePawn(PawnGenerationRequest request) { Log.Message("Alien Pawn generated."); request.EnsureNonNullFaction(); Pawn pawn = null; if (!request.Newborn && !request.ForceGenerateNewPawn && Rand.Value < AlienPawnGenerator.ChanceToRedressAnyWorldPawn()) { IEnumerable <Pawn> enumerable = Find.WorldPawns.GetPawnsBySituation(WorldPawnSituation.Free); if (request.KindDef.factionLeader) { enumerable = enumerable.Concat(Find.WorldPawns.GetPawnsBySituation(WorldPawnSituation.FactionLeader)); } enumerable = from x in enumerable where AlienPawnGenerator.IsValidCandidateToRedress(x, request) select x; if (enumerable.TryRandomElementByWeight((Pawn x) => AlienPawnGenerator.WorldPawnSelectionWeight(x), out pawn)) { Verse.PawnGenerator.RedressPawn(pawn, request); Find.WorldPawns.RemovePawn(pawn); } } if (pawn == null) { pawn = AlienPawnGenerator.GenerateNewNakedPawn(ref request); if (pawn == null) { return(null); } if (!request.Newborn) { AlienPawnGenerator.GenerateGearFor(pawn, request); } } if (Find.Scenario != null) { Find.Scenario.Notify_PawnGenerated(pawn, request.Context); } if (pawn.kindDef.race.ToString().Contains("Alien_")) { AlienPawn alienpawn = new AlienPawn(); return(alienpawn); } else { return(pawn); } }
private static Pawn GenerateNewNakedPawn(ref PawnGenerationRequest request) { Pawn pawn = null; string text = null; bool ignoreScenarioRequirements = false; for (int i = 0; i < 100; i++) { if (i == 70) { Log.Error(string.Concat(new object[] { "Could not generate a pawn after ", 70, " tries. Last error: ", text, " Ignoring scenario requirements." })); ignoreScenarioRequirements = true; } PawnGenerationRequest pawnGenerationRequest = request; pawn = AlienPawnGenerator.DoGenerateNewNakedPawn(ref pawnGenerationRequest, out text, ignoreScenarioRequirements); if (pawn != null) { request = pawnGenerationRequest; break; } } if (pawn == null) { Log.Error(string.Concat(new object[] { "Pawn generation error: ", text, " Too many tries (", 100, "), returning null. Generation request: ", request })); return(null); } return(pawn); }
private static void GiveRandomTraits(Pawn pawn, bool allowGay) { if (pawn.story == null) { return; } if (pawn.story.childhood.forcedTraits != null) { List <TraitEntry> forcedTraits = pawn.story.childhood.forcedTraits; for (int i = 0; i < forcedTraits.Count; i++) { TraitEntry traitEntry = forcedTraits[i]; if (traitEntry.def == null) { Log.Error("Null forced trait def on " + pawn.story.childhood); } else if (!pawn.story.traits.HasTrait(traitEntry.def)) { pawn.story.traits.GainTrait(new Trait(traitEntry.def, traitEntry.degree)); } } } if (pawn.story.adulthood.forcedTraits != null) { List <TraitEntry> forcedTraits2 = pawn.story.adulthood.forcedTraits; for (int j = 0; j < forcedTraits2.Count; j++) { TraitEntry traitEntry2 = forcedTraits2[j]; if (traitEntry2.def == null) { Log.Error("Null forced trait def on " + pawn.story.adulthood); } else if (!pawn.story.traits.HasTrait(traitEntry2.def)) { pawn.story.traits.GainTrait(new Trait(traitEntry2.def, traitEntry2.degree)); } } } int num = Rand.RangeInclusive(2, 3); if (allowGay && (LovePartnerRelationUtility.HasAnyLovePartnerOfTheSameGender(pawn) || LovePartnerRelationUtility.HasAnyExLovePartnerOfTheSameGender(pawn))) { Trait trait = new Trait(TraitDefOf.Gay, AlienPawnGenerator.RandomTraitDegree(TraitDefOf.Gay)); pawn.story.traits.GainTrait(trait); } while (pawn.story.traits.allTraits.Count < num) { TraitDef newTraitDef = DefDatabase <TraitDef> .AllDefsListForReading.RandomElementByWeight((TraitDef tr) => tr.GetGenderSpecificCommonality(pawn)); if (!pawn.story.traits.HasTrait(newTraitDef)) { if (newTraitDef == TraitDefOf.Gay) { if (!allowGay) { continue; } if (LovePartnerRelationUtility.HasAnyLovePartnerOfTheOppositeGender(pawn) || LovePartnerRelationUtility.HasAnyExLovePartnerOfTheOppositeGender(pawn)) { continue; } } if (!pawn.story.traits.allTraits.Any((Trait tr) => newTraitDef.ConflictsWith(tr)) && (newTraitDef.conflictingTraits == null || !newTraitDef.conflictingTraits.Any((TraitDef tr) => pawn.story.traits.HasTrait(tr)))) { if (newTraitDef.requiredWorkTypes == null || !pawn.story.OneOfWorkTypesIsDisabled(newTraitDef.requiredWorkTypes)) { if (!pawn.story.WorkTagIsDisabled(newTraitDef.requiredWorkTags)) { int degree = AlienPawnGenerator.RandomTraitDegree(newTraitDef); if (!pawn.story.childhood.DisallowsTrait(newTraitDef, degree) && !pawn.story.adulthood.DisallowsTrait(newTraitDef, degree)) { Trait trait2 = new Trait(newTraitDef, degree); if (pawn.mindState == null || pawn.mindState.mentalBreaker == null || pawn.mindState.mentalBreaker.BreakThresholdExtreme + trait2.OffsetOfStat(StatDefOf.MentalBreakThreshold) <= 40f) { pawn.story.traits.GainTrait(trait2); } } } } } } } }
public static Pawn GeneratePawn(PawnKindDef kindDef, Faction faction = null) { return(AlienPawnGenerator.GeneratePawn(new PawnGenerationRequest(kindDef, faction, PawnGenerationContext.NonPlayer, false, false, false, false, true, false, 1f, false, true, true, null, null, null, null, null, null))); }
private static Pawn DoGenerateNewNakedPawn(ref PawnGenerationRequest request, out string error, bool ignoreScenarioRequirements) { error = null; Pawn pawn = (Pawn)ThingMaker.MakeThing(request.KindDef.race, null); AlienPawnGenerator.pawnsBeingGenerated.Add(new AlienPawnGenerator.PawnGenerationStatus(pawn, null)); Pawn result; try { pawn.kindDef = request.KindDef; pawn.SetFactionDirect(request.Faction); PawnComponentsUtility.CreateInitialComponents(pawn); if (request.FixedGender.HasValue) { pawn.gender = request.FixedGender.Value; } else if (pawn.RaceProps.hasGenders) { if (Rand.Value < 0.5f) { pawn.gender = Gender.Male; } else { pawn.gender = Gender.Female; } } else { pawn.gender = Gender.None; } AlienPawnGenerator.GenerateRandomAge(pawn, request); pawn.needs.SetInitialLevels(); if (!request.Newborn && request.CanGeneratePawnRelations) { AlienPawnGenerator.GeneratePawnRelations(pawn, ref request); } if (pawn.RaceProps.Humanlike) { pawn.story.skinWhiteness = ((!request.FixedSkinWhiteness.HasValue) ? PawnSkinColors.RandomSkinWhiteness() : request.FixedSkinWhiteness.Value); pawn.story.crownType = ((Rand.Value >= 0.5f) ? CrownType.Narrow : CrownType.Average); pawn.story.hairColor = PawnHairColors.RandomHairColor(pawn.story.SkinColor, pawn.ageTracker.AgeBiologicalYears); PawnBioGenerator.GiveAppropriateBioTo(pawn, request.FixedLastName); pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(pawn, request.Faction.def); AlienPawnGenerator.GiveRandomTraits(pawn, request.AllowGay); pawn.story.GenerateSkillsFromBackstory(); } if (pawn.workSettings != null && request.Faction.IsPlayer) { pawn.workSettings.EnableAndInitialize(); } if (request.Faction != null && pawn.RaceProps.Animal) { pawn.GenerateNecessaryName(); } if (!request.AllowDead && (pawn.Dead || pawn.Destroyed)) { AlienPawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated dead pawn."; result = null; } else if (!request.AllowDowned && pawn.Downed) { AlienPawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated downed pawn."; result = null; } else if (request.MustBeCapableOfViolence && pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) { AlienPawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated pawn incapable of violence."; result = null; } else if (!ignoreScenarioRequirements && request.Context == PawnGenerationContext.PlayerStarter && !Find.Scenario.AllowPlayerStartingPawn(pawn)) { AlienPawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated pawn doesn't meet scenario requirements."; result = null; } else if (request.Validator != null && !request.Validator(pawn)) { AlienPawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated pawn didn't pass validator check."; result = null; } else { for (int i = 0; i < AlienPawnGenerator.pawnsBeingGenerated.Count - 1; i++) { if (AlienPawnGenerator.pawnsBeingGenerated[i].PawnsGeneratedInTheMeantime == null) { AlienPawnGenerator.pawnsBeingGenerated[i] = new AlienPawnGenerator.PawnGenerationStatus(AlienPawnGenerator.pawnsBeingGenerated[i].Pawn, new List <Pawn>()); } AlienPawnGenerator.pawnsBeingGenerated[i].PawnsGeneratedInTheMeantime.Add(pawn); } result = pawn; } } finally { AlienPawnGenerator.pawnsBeingGenerated.RemoveLast <AlienPawnGenerator.PawnGenerationStatus>(); } return(result); }
public static void RedressPawn(Pawn pawn, PawnGenerationRequest request) { pawn.kindDef = request.KindDef; AlienPawnGenerator.GenerateGearFor(pawn, request); }