private static Pawn TryGenerateNewPawnInternal(ref PawnGenerationRequest request, out string error, bool ignoreScenarioRequirements, bool ignoreValidator) { error = null; Pawn pawn = (Pawn)ThingMaker.MakeThing(request.KindDef.race); pawnsBeingGenerated.Add(new PawnGenerationStatus(pawn, null)); //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); 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; } GenerateRandomAge(pawn, request); pawn.needs.SetInitialLevels(); if (!request.Newborn && request.CanGeneratePawnRelations) { GeneratePawnRelations(pawn, ref request); } if (pawn.RaceProps.Humanlike) { Faction faction; FactionDef factionType = (request.Faction != null) ? request.Faction.def : ((!Find.FactionManager.TryGetRandomNonColonyHumanlikeFaction(out faction, tryMedievalOrBetter: false, allowDefeated: true)) ? Faction.OfAncients.def : faction.def); pawn.story.melanin = ((!request.FixedMelanin.HasValue) ? PawnSkinColors.RandomMelanin(request.Faction) : request.FixedMelanin.Value); pawn.story.crownType = ((Rand.Value < 0.5f) ? CrownType.Average : CrownType.Narrow); pawn.story.hairColor = PawnHairColors.RandomHairColor(pawn.story.SkinColor, pawn.ageTracker.AgeBiologicalYears); PawnBioAndNameGenerator.GiveAppropriateBioAndNameTo(pawn, request.FixedLastName, factionType); pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(pawn, factionType); GenerateTraits(pawn, request); GenerateBodyType(pawn); GenerateSkills(pawn); } if (pawn.RaceProps.Animal && request.Faction != null && request.Faction.IsPlayer) { pawn.training.SetWantedRecursive(TrainableDefOf.Tameness, checkOn: true); pawn.training.Train(TrainableDefOf.Tameness, null, complete: true); } GenerateInitialHediffs(pawn, request); if (pawn.workSettings != null && request.Faction != null && request.Faction.IsPlayer) { pawn.workSettings.EnableAndInitialize(); } if (request.Faction != null && pawn.RaceProps.Animal) { pawn.GenerateNecessaryName(); } if (Find.Scenario != null) { Find.Scenario.Notify_NewPawnGenerating(pawn, request.Context); } if (!request.AllowDead && (pawn.Dead || pawn.Destroyed)) { DiscardGeneratedPawn(pawn); error = "Generated dead pawn."; return(null); } if (!request.AllowDowned && pawn.Downed) { DiscardGeneratedPawn(pawn); error = "Generated downed pawn."; return(null); } if (request.MustBeCapableOfViolence && ((pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) || (pawn.RaceProps.ToolUser && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)))) { DiscardGeneratedPawn(pawn); error = "Generated pawn incapable of violence."; return(null); } if (!ignoreScenarioRequirements && request.Context == PawnGenerationContext.PlayerStarter && Find.Scenario != null && !Find.Scenario.AllowPlayerStartingPawn(pawn, tryingToRedress: false, request)) { DiscardGeneratedPawn(pawn); error = "Generated pawn doesn't meet scenario requirements."; return(null); } if (!ignoreValidator && request.ValidatorPreGear != null && !request.ValidatorPreGear(pawn)) { DiscardGeneratedPawn(pawn); error = "Generated pawn didn't pass validator check (pre-gear)."; return(null); } if (!request.Newborn) { GenerateGearFor(pawn, request); } if (!ignoreValidator && request.ValidatorPostGear != null && !request.ValidatorPostGear(pawn)) { DiscardGeneratedPawn(pawn); error = "Generated pawn didn't pass validator check (post-gear)."; return(null); } for (int i = 0; i < pawnsBeingGenerated.Count - 1; i++) { if (pawnsBeingGenerated[i].PawnsGeneratedInTheMeantime == null) { pawnsBeingGenerated[i] = new PawnGenerationStatus(pawnsBeingGenerated[i].Pawn, new List <Pawn>()); } pawnsBeingGenerated[i].PawnsGeneratedInTheMeantime.Add(pawn); } return(pawn); } finally { pawnsBeingGenerated.RemoveLast(); } }
private static bool IsValidCandidateToRedress(Pawn pawn, PawnGenerationRequest request) { if (pawn.def != request.KindDef.race) { return(false); } if (!request.WorldPawnFactionDoesntMatter && pawn.Faction != request.Faction) { return(false); } if (!request.AllowDead && (pawn.Dead || pawn.Destroyed)) { return(false); } if (!request.AllowDowned && pawn.Downed) { return(false); } if (pawn.health.hediffSet.BleedRateTotal > 0.001f) { return(false); } if (!request.CanGeneratePawnRelations && pawn.RaceProps.IsFlesh && pawn.relations.RelatedToAnyoneOrAnyoneRelatedToMe) { return(false); } if (!request.AllowGay && pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOf.Gay)) { return(false); } if (request.ValidatorPreGear != null && !request.ValidatorPreGear(pawn)) { return(false); } if (request.ValidatorPostGear != null && !request.ValidatorPostGear(pawn)) { return(false); } if (request.FixedBiologicalAge.HasValue && pawn.ageTracker.AgeBiologicalYearsFloat != request.FixedBiologicalAge) { return(false); } if (request.FixedChronologicalAge.HasValue && (float)pawn.ageTracker.AgeChronologicalYears != request.FixedChronologicalAge) { return(false); } if (request.FixedGender.HasValue && pawn.gender != request.FixedGender) { return(false); } if (request.FixedLastName != null && ((NameTriple)pawn.Name).Last != request.FixedLastName) { return(false); } if (request.FixedMelanin.HasValue && pawn.story != null && pawn.story.melanin != request.FixedMelanin) { return(false); } if (request.Context == PawnGenerationContext.PlayerStarter && Find.Scenario != null && !Find.Scenario.AllowPlayerStartingPawn(pawn, tryingToRedress: true, request)) { return(false); } if (request.MustBeCapableOfViolence) { if (pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) { return(false); } if (pawn.RaceProps.ToolUser && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { return(false); } } return(true); }