private static Pawn TryGenerateNewPawnInternal(ref PawnGenerationRequest request, out string error, bool ignoreScenarioRequirements, bool ignoreValidator) { error = null; Pawn pawn = (Pawn)ThingMaker.MakeThing(request.KindDef.race, null); PawnGenerator.pawnsBeingGenerated.Add(new PawnGenerator.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; } PawnGenerator.GenerateRandomAge(pawn, request); pawn.needs.SetInitialLevels(); if (!request.Newborn && request.CanGeneratePawnRelations) { PawnGenerator.GeneratePawnRelations(pawn, ref request); } if (pawn.RaceProps.Humanlike) { FactionDef def; Faction faction; if (request.Faction != null) { def = request.Faction.def; } else if (Find.FactionManager.TryGetRandomNonColonyHumanlikeFaction(out faction, false, true, TechLevel.Undefined)) { def = faction.def; } else { def = Faction.OfAncients.def; } pawn.story.melanin = ((!request.FixedMelanin.HasValue) ? PawnSkinColors.RandomMelanin(request.Faction) : request.FixedMelanin.Value); pawn.story.crownType = ((Rand.Value >= 0.5f) ? CrownType.Narrow : CrownType.Average); pawn.story.hairColor = PawnHairColors.RandomHairColor(pawn.story.SkinColor, pawn.ageTracker.AgeBiologicalYears); PawnBioAndNameGenerator.GiveAppropriateBioAndNameTo(pawn, request.FixedLastName, def); pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(pawn, def); PawnGenerator.GenerateTraits(pawn, request); PawnGenerator.GenerateBodyType(pawn); PawnGenerator.GenerateSkills(pawn); } if (pawn.RaceProps.Animal && request.Faction != null && request.Faction.IsPlayer) { pawn.training.SetWantedRecursive(TrainableDefOf.Tameness, true); pawn.training.Train(TrainableDefOf.Tameness, null, true); } PawnGenerator.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)) { PawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated dead pawn."; result = null; } else if (!request.AllowDowned && pawn.Downed) { PawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated downed pawn."; result = null; } else if (request.MustBeCapableOfViolence && ((pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) || (pawn.RaceProps.ToolUser && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)))) { PawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated pawn incapable of violence."; result = null; } else if (!ignoreScenarioRequirements && request.Context == PawnGenerationContext.PlayerStarter && Find.Scenario != null && !Find.Scenario.AllowPlayerStartingPawn(pawn, false, request)) { PawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated pawn doesn't meet scenario requirements."; result = null; } else if (!ignoreValidator && request.ValidatorPreGear != null && !request.ValidatorPreGear(pawn)) { PawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated pawn didn't pass validator check (pre-gear)."; result = null; } else { if (!request.Newborn) { PawnGenerator.GenerateGearFor(pawn, request); } if (!ignoreValidator && request.ValidatorPostGear != null && !request.ValidatorPostGear(pawn)) { PawnGenerator.DiscardGeneratedPawn(pawn); error = "Generated pawn didn't pass validator check (post-gear)."; result = null; } else { for (int i = 0; i < PawnGenerator.pawnsBeingGenerated.Count - 1; i++) { if (PawnGenerator.pawnsBeingGenerated[i].PawnsGeneratedInTheMeantime == null) { PawnGenerator.pawnsBeingGenerated[i] = new PawnGenerator.PawnGenerationStatus(PawnGenerator.pawnsBeingGenerated[i].Pawn, new List <Pawn>()); } PawnGenerator.pawnsBeingGenerated[i].PawnsGeneratedInTheMeantime.Add(pawn); } result = pawn; } } } finally { PawnGenerator.pawnsBeingGenerated.RemoveLast <PawnGenerator.PawnGenerationStatus>(); } return(result); }
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)); 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_NewTemp(out faction, tryMedievalOrBetter: false, allowDefeated: true)) ? Faction.OfAncients.def : faction.def)); pawn.story.melanin = (request.FixedMelanin.HasValue ? request.FixedMelanin.Value : PawnSkinColors.RandomMelanin(request.Faction)); 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); if (pawn.story != null) { if (request.FixedBirthName != null) { pawn.story.birthLastName = request.FixedBirthName; } else if (pawn.Name is NameTriple) { pawn.story.birthLastName = ((NameTriple)pawn.Name).Last; } } pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(pawn, factionType); GenerateTraits(pawn, request); GenerateBodyType_NewTemp(pawn, request); 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 (!request.ForbidAnyTitle) { RoyalTitleDef royalTitleDef = request.FixedTitle; if (royalTitleDef == null) { if (request.KindDef.titleRequired != null) { royalTitleDef = request.KindDef.titleRequired; } else if (!request.KindDef.titleSelectOne.NullOrEmpty() && Rand.Chance(request.KindDef.royalTitleChance)) { royalTitleDef = request.KindDef.titleSelectOne.RandomElementByWeight((RoyalTitleDef t) => t.commonality); } } if (request.KindDef.minTitleRequired != null && (royalTitleDef == null || royalTitleDef.seniority < request.KindDef.minTitleRequired.seniority)) { royalTitleDef = request.KindDef.minTitleRequired; } if (royalTitleDef != null) { Faction faction2 = ((request.Faction != null && request.Faction.def.HasRoyalTitles) ? request.Faction : Find.FactionManager.RandomRoyalFaction()); pawn.royalty.SetTitle(faction2, royalTitleDef, grantRewards: false); if (request.Faction != null && !request.Faction.IsPlayer) { PurchasePermits(pawn, faction2); } int amount = 0; if (royalTitleDef.GetNextTitle(faction2) != null) { amount = Rand.Range(0, royalTitleDef.GetNextTitle(faction2).favorCost - 1); } pawn.royalty.SetFavor_NewTemp(faction2, amount); if (royalTitleDef.maxPsylinkLevel > 0) { Hediff_ImplantWithLevel hediff_ImplantWithLevel = HediffMaker.MakeHediff(HediffDefOf.PsychicAmplifier, pawn, pawn.health.hediffSet.GetBrain()) as Hediff_ImplantWithLevel; pawn.health.AddHediff(hediff_ImplantWithLevel); hediff_ImplantWithLevel.SetLevelTo(royalTitleDef.maxPsylinkLevel); } } } if (pawn.royalty != null) { pawn.royalty.allowRoomRequirements = request.KindDef.allowRoyalRoomRequirements; pawn.royalty.allowApparelRequirements = request.KindDef.allowRoyalApparelRequirements; } 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.WorkTagIsDisabled(WorkTags.Violent)) || (pawn.RaceProps.ToolUser && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)))) { DiscardGeneratedPawn(pawn); error = "Generated pawn incapable of violence."; return(null); } if (request.KindDef != null && !request.KindDef.skills.NullOrEmpty()) { List <SkillRange> skills = request.KindDef.skills; for (int i = 0; i < skills.Count; i++) { if (pawn.skills.GetSkill(skills[i].Skill).TotallyDisabled) { error = "Generated pawn incapable of required skill: " + skills[i].Skill.defName; return(null); } } } if (request.KindDef.requiredWorkTags != 0 && (pawn.CombinedDisabledWorkTags & request.KindDef.requiredWorkTags) != 0) { DiscardGeneratedPawn(pawn); error = "Generated pawn with disabled requiredWorkTags."; 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 j = 0; j < pawnsBeingGenerated.Count - 1; j++) { if (pawnsBeingGenerated[j].PawnsGeneratedInTheMeantime == null) { pawnsBeingGenerated[j] = new PawnGenerationStatus(pawnsBeingGenerated[j].Pawn, new List <Pawn>()); } pawnsBeingGenerated[j].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, 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); }
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) { if (pawn.Dead || pawn.Destroyed) { return(false); } if (pawn.health.hediffSet.GetBrain() == null) { 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.AllowAddictions && AddictionUtility.AddictedToAnything(pawn)) { return(false); } if (request.ProhibitedTraits != null && request.ProhibitedTraits.Any((TraitDef t) => pawn.story.traits.HasTrait(t))) { return(false); } List <SkillRange> skills = request.KindDef.skills; if (skills != null) { for (int i = 0; i < skills.Count; i++) { SkillRecord skill = pawn.skills.GetSkill(skills[i].Skill); if (skill.TotallyDisabled) { return(false); } if (skill.Level < skills[i].Range.min || skill.Level > skills[i].Range.max) { return(false); } } } if (request.ForcedTraits != null) { foreach (TraitDef forcedTrait in request.ForcedTraits) { if (!pawn.story.traits.HasTrait(forcedTrait)) { 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 && (!(pawn.Name is NameTriple) || ((NameTriple)pawn.Name).Last != request.FixedLastName)) { return(false); } if (request.FixedMelanin.HasValue && pawn.story != null && pawn.story.melanin != request.FixedMelanin) { return(false); } if (request.FixedTitle != null && (pawn.royalty == null || !pawn.royalty.HasTitle(request.FixedTitle))) { return(false); } if (request.KindDef.minTitleRequired != null) { if (pawn.royalty == null) { return(false); } RoyalTitleDef royalTitleDef = pawn.royalty.MainTitle(); if (royalTitleDef == null || royalTitleDef.seniority < request.KindDef.minTitleRequired.seniority) { return(false); } } if (request.Context == PawnGenerationContext.PlayerStarter && Find.Scenario != null && !Find.Scenario.AllowPlayerStartingPawn(pawn, tryingToRedress: true, request)) { return(false); } if (request.MustBeCapableOfViolence) { if (pawn.WorkTagIsDisabled(WorkTags.Violent)) { return(false); } if (pawn.RaceProps.ToolUser && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { return(false); } } if (request.RedressValidator != null && !request.RedressValidator(pawn)) { return(false); } if (request.KindDef.requiredWorkTags != 0 && pawn.kindDef != request.KindDef && (pawn.CombinedDisabledWorkTags & request.KindDef.requiredWorkTags) != 0) { return(false); } return(true); }