protected override void ResolveParmsPoints(IncidentParms parms) { if (!(parms.points >= 0f)) { parms.points = Rand.ByCurve(PointsCurve); } }
private static int FinalLevelOfSkill(Pawn pawn, SkillDef sk) { //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); float num = (!sk.usuallyDefinedInBackstories) ? Rand.ByCurve(LevelRandomCurve) : ((float)Rand.RangeInclusive(0, 4)); foreach (Backstory item in from bs in pawn.story.AllBackstories where bs != null select bs) { foreach (KeyValuePair <SkillDef, int> item2 in item.skillGainsResolved) { if (item2.Key == sk) { num += (float)item2.Value * Rand.Range(1f, 1.4f); } } } for (int i = 0; i < pawn.story.traits.allTraits.Count; i++) { int value = 0; if (pawn.story.traits.allTraits[i].CurrentData.skillGains.TryGetValue(sk, out value)) { num += (float)value; } } float num2 = Rand.Range(1f, AgeSkillMaxFactorCurve.Evaluate((float)pawn.ageTracker.AgeBiologicalYears)); num *= num2; num = LevelFinalAdjustmentCurve.Evaluate(num); return(Mathf.Clamp(Mathf.RoundToInt(num), 0, 20)); }
protected override void ResolveParmsPoints(IncidentParms parms) { if (parms.points < 0f) { parms.points = Rand.ByCurve(IncidentWorker_VisitorGroup.PointsCurve); } }
protected override void ResolveParmsPoints(IncidentParms parms) { if (parms.points >= 0f) { return; } parms.points = Rand.ByCurve(IncidentWorker_TravelerGroup.PointsCurve); }
public static MechClusterSketch GenerateClusterSketch_NewTemp(float points, Map map, bool startDormant = true, bool forceNoConditionCauser = false) { if (!ModLister.RoyaltyInstalled) { Log.ErrorOnce("Mech clusters are a Royalty-specific game system. If you want to use this code please check ModLister.RoyaltyInstalled before calling it. See rules on the Ludeon forum for more info.", 657122); return(new MechClusterSketch(new Sketch(), new List <MechClusterSketch.Mech>(), startDormant)); } points = Mathf.Min(points, 10000f); float num = points; List <MechClusterSketch.Mech> list = null; if (Rand.Chance(PointsToPawnsChanceCurve.Evaluate(points))) { List <PawnKindDef> source = DefDatabase <PawnKindDef> .AllDefsListForReading.Where((PawnKindDef def) => def.RaceProps.IsMechanoid).ToList(); list = new List <MechClusterSketch.Mech>(); float a = Rand.ByCurve(PawnPointsRandomPercentOfTotalCurve) * num; float pawnPointsLeft; a = (pawnPointsLeft = Mathf.Max(a, source.Min((PawnKindDef x) => x.combatPower))); PawnKindDef result; while (pawnPointsLeft > 0f && source.Where((PawnKindDef def) => def.combatPower <= pawnPointsLeft).TryRandomElement(out result)) { pawnPointsLeft -= result.combatPower; list.Add(new MechClusterSketch.Mech(result)); } num -= a - pawnPointsLeft; } Sketch buildingsSketch = RimWorld.SketchGen.SketchGen.Generate(SketchResolverDefOf.MechCluster, new ResolveParams { points = num, totalPoints = points, mechClusterDormant = startDormant, sketch = new Sketch(), mechClusterForMap = map, forceNoConditionCauser = forceNoConditionCauser }); if (list != null) { List <IntVec3> pawnUsedSpots = new List <IntVec3>(); for (int i = 0; i < list.Count; i++) { MechClusterSketch.Mech pawn = list[i]; if (!buildingsSketch.OccupiedRect.Where((IntVec3 c) => !buildingsSketch.ThingsAt(c).Any() && !pawnUsedSpots.Contains(c)).TryRandomElement(out var result2)) { CellRect cellRect = buildingsSketch.OccupiedRect; do { cellRect = cellRect.ExpandedBy(1); }while (!cellRect.Where((IntVec3 x) => !buildingsSketch.WouldCollide(pawn.kindDef.race, x, Rot4.North) && !pawnUsedSpots.Contains(x)).TryRandomElement(out result2)); } pawnUsedSpots.Add(result2); pawn.position = result2; list[i] = pawn; } } return(new MechClusterSketch(buildingsSketch, list, startDormant)); }
private static int GetLitterCount(Pawn pawn) { var raceProps = pawn.RaceProps; if (raceProps.litterSizeCurve is null) { return(1); } var n = Mathf.RoundToInt(Rand.ByCurve(pawn.RaceProps.litterSizeCurve)); return(n > 1 ? n : 1); }
private static VehiclePawn GenerateVehicleInternal(VehicleGenerationRequest request) { VehiclePawn result = (VehiclePawn)ThingMaker.MakeThing(request.VehicleDef); PawnComponentsUtility.CreateInitialComponents(result); result.kindDef = request.VehicleDef.VehicleKindDef; result.SetFactionDirect(request.Faction); string defaultMask = VehicleMod.settings.vehicles.defaultMasks.TryGetValue(result.VehicleDef.defName, "Default"); PatternDef pattern = DefDatabase <PatternDef> .GetNamed(defaultMask); if (pattern is null) { Log.Error($"Unable to retrieve saved default pattern {defaultMask}. Defaulting to original Default mask."); pattern = PatternDefOf.Default; } result.pattern = request.RandomizeMask ? result.VehicleGraphic.maskMatPatterns.RandomElement().Key : pattern; if (result.VehicleGraphic.MatSingle.shader.SupportsRGBMaskTex()) { result.DrawColor = request.ColorOne; result.DrawColorTwo = request.ColorTwo; result.DrawColorThree = request.ColorThree; } result.PostGenerationSetup(); foreach (VehicleComp comp in result.AllComps.Where(c => c is VehicleComp)) { comp.PostGenerationSetup(); } //REDO - Allow other modders to add setup for non clean-slate items if (!request.CleanSlate) { UpgradeAtRandom(result, request.Upgrades); DistributeAmmunition(result); } float num = Rand.ByCurve(DefaultAgeGenerationCurve); result.ageTracker.AgeBiologicalTicks = (long)(num * BiologicalAgeTicksMultiplier) + Rand.Range(0, 3600000); result.needs.SetInitialLevels(); if (Find.Scenario != null) { Find.Scenario.Notify_NewPawnGenerating(result, PawnGenerationContext.NonPlayer); } return(result); }
private void SetVars(Slate slate) { float x = slate.Get("points", 0f); float num = pointsCurve.GetValue(slate).Evaluate(x); if (roundRandom.GetValue(slate)) { num = GenMath.RoundRandom(num); } if (challengeRating.TryGetValue(slate, out int value)) { switch (value) { case 1: num = Mathf.Min(num, maxCountOneStar.GetValue(slate)); break; case 2: num = Mathf.Min(num, maxCountTwoStar.GetValue(slate)); break; default: num = Mathf.Min(num, maxCountThreeStar.GetValue(slate)); break; } } SimpleCurve value2 = chancesCurve.GetValue(slate); int num2 = value2.Points.Count - 1; while (num2 >= 0) { if (value2.Points[num2].x > num) { value2.Points[num2] = new CurvePoint(0f, 0f); num2--; continue; } value2.Points.Insert(num2 + 1, new CurvePoint(num + 1f, 0f)); break; } float num3 = Rand.ByCurve(value2); if (roundRandom.GetValue(slate)) { num3 = GenMath.RoundRandom(num3); } slate.Set(storeAs.GetValue(slate), Mathf.Clamp(num3, 1f, num)); }
private void SetVars(Slate slate) { float num = Rand.ByCurve(curve.GetValue(slate)); if (roundRandom.GetValue(slate)) { num = GenMath.RoundRandom(num); } if (min.GetValue(slate).HasValue) { num = Mathf.Max(num, min.GetValue(slate).Value); } if (max.GetValue(slate).HasValue) { num = Mathf.Min(num, max.GetValue(slate).Value); } slate.Set(storeAs.GetValue(slate), num); }
public static int FinalLevelOfSkill(Pawn pawn, SkillDef sk) { float num; if (sk.usuallyDefinedInBackstories) { num = (float)Rand.RangeInclusive(0, 4); } else { num = Rand.ByCurve(LevelRandomCurve); } foreach (Backstory backstory in from bs in pawn.story.AllBackstories where bs != null select bs) { foreach (KeyValuePair <SkillDef, int> keyValuePair in backstory.skillGainsResolved) { if (keyValuePair.Key == sk) { num += (float)keyValuePair.Value * Rand.Range(1f, 1.4f); } } } for (int i = 0; i < pawn.story.traits.allTraits.Count; i++) { int num2 = 0; if (pawn.story.traits.allTraits[i].CurrentData.skillGains.TryGetValue(sk, out num2)) { num += (float)num2; } } float num3 = Rand.Range(1f, AgeSkillMaxFactorCurve.Evaluate((float)pawn.ageTracker.AgeBiologicalYears)); num *= num3; num = LevelFinalAdjustmentCurve.Evaluate(num); return(Mathf.Clamp(Mathf.RoundToInt(num), 0, 20)); }
// Token: 0x06000034 RID: 52 RVA: 0x00003B50 File Offset: 0x00001D50 protected virtual int FinalLevelOfSkill(Pawn pawn, SkillDef sk) { float num; if (sk.usuallyDefinedInBackstories) { num = Rand.RangeInclusive(0, 4); } else { num = Rand.ByCurve(LevelRandomCurve); } foreach (var backstory in from bs in pawn.story.AllBackstories where bs != null select bs) { foreach (var keyValuePair in backstory.skillGainsResolved) { if (keyValuePair.Key == sk) { num += keyValuePair.Value * Rand.Range(1f, 1.4f); } } } foreach (var trait in pawn.story.traits.allTraits) { if (trait.CurrentData.skillGains.TryGetValue(sk, out var num2)) { num += num2; } } num = LevelFinalAdjustmentCurve.Evaluate(num); return(Mathf.Clamp(Mathf.RoundToInt(num), 0, 20)); }
static public void GenerateRandomAge(Pawn pawn, Map map) { int num = 0; int num2; do { if (pawn.RaceProps.ageGenerationCurve != null) { num2 = Mathf.RoundToInt(Rand.ByCurve(pawn.RaceProps.ageGenerationCurve, 200)); } else if (pawn.RaceProps.IsMechanoid) { num2 = Rand.Range(0, 2500); } else { if (!pawn.RaceProps.Animal) { goto IL_84; } num2 = Rand.Range(1, 10); } num++; if (num > 100) { goto IL_95; } }while (num2 > pawn.kindDef.maxGenerationAge || num2 < pawn.kindDef.minGenerationAge); goto IL_A5; IL_84: Log.Warning("Didn't get age for " + pawn); return; IL_95: Log.Error("Tried 100 times to generate age for " + pawn); IL_A5: pawn.ageTracker.AgeBiologicalTicks = ((long)(num2 * 3600000f) + Rand.Range(0, 3600000)); int num3; if (Rand.Value < pawn.kindDef.backstoryCryptosleepCommonality) { float value = Rand.Value; if (value < 0.7f) { num3 = Rand.Range(0, 100); } else if (value < 0.95f) { num3 = Rand.Range(100, 1000); } else { int num4 = GenLocalDate.Year(map) - 2026 - pawn.ageTracker.AgeBiologicalYears; num3 = Rand.Range(1000, num4); } } else { num3 = 0; } long num5 = GenTicks.TicksAbs - pawn.ageTracker.AgeBiologicalTicks; num5 -= num3 * 3600000L; pawn.ageTracker.BirthAbsTicks = num5; if (pawn.ageTracker.AgeBiologicalTicks > pawn.ageTracker.AgeChronologicalTicks) { pawn.ageTracker.AgeChronologicalTicks = (pawn.ageTracker.AgeBiologicalTicks); } }
public static bool GeneratePawn_GenerateRandomAge_Postfix(Pawn pawn, PawnGenerationRequest request) { if (true) { if (request.FixedBiologicalAge != null && request.FixedChronologicalAge != null) { float?fixedBiologicalAge = request.FixedBiologicalAge; bool flag = fixedBiologicalAge != null; float?fixedChronologicalAge = request.FixedChronologicalAge; if ((flag & fixedChronologicalAge != null) && fixedBiologicalAge.GetValueOrDefault() > fixedChronologicalAge.GetValueOrDefault()) { Log.Warning(string.Concat(new object[] { "Tried to generate age for pawn ", pawn, ", but pawn generation request demands biological age (", request.FixedBiologicalAge, ") to be greater than chronological age (", request.FixedChronologicalAge, ")." }), false); } } if (request.Newborn) { pawn.ageTracker.AgeBiologicalTicks = 0L; } else if (request.FixedBiologicalAge != null) { pawn.ageTracker.AgeBiologicalTicks = (long)(request.FixedBiologicalAge.Value * 3600000f); } else { int num = 0; float num2; for (; ;) { if (pawn.RaceProps.ageGenerationCurve != null) { num2 = (float)Mathf.RoundToInt(Rand.ByCurve(pawn.RaceProps.ageGenerationCurve)); } else if (pawn.RaceProps.IsMechanoid) { num2 = Rand.Range(0f, 2500f); } else { num2 = Rand.ByCurve(AM_PawnGenerator_GenerateRandomAge_test_Patch.DefaultAgeGenerationCurve) * pawn.RaceProps.lifeExpectancy; } num++; if (num > 300) { break; } if (num2 <= (float)pawn.kindDef.maxGenerationAge && num2 >= (float)pawn.kindDef.minGenerationAge) { goto IL_1D4; } } Log.Error("Tried 300 times to generate age for " + pawn, false); IL_1D4: pawn.ageTracker.AgeBiologicalTicks = (long)(num2 * 3600000f) + (long)Rand.Range(0, 3600000); } if (request.Newborn) { pawn.ageTracker.AgeChronologicalTicks = 0L; } else if (request.FixedChronologicalAge != null) { pawn.ageTracker.AgeChronologicalTicks = (long)(request.FixedChronologicalAge.Value * 3600000f); } else { int num3; if (request.CertainlyBeenInCryptosleep || Rand.Value < pawn.kindDef.backstoryCryptosleepCommonality) { float value = Rand.Value; if (value < 0.7f) { num3 = Rand.Range(0, 100); } else if (value < 0.95f) { num3 = Rand.Range(100, 1000); } else { int max = GenDate.Year((long)GenTicks.TicksAbs, 0f) - 2026 - pawn.ageTracker.AgeBiologicalYears; num3 = Rand.Range(1000, max); } } else { num3 = 0; } int ticksAbs = GenTicks.TicksAbs; long num4 = (long)ticksAbs - pawn.ageTracker.AgeBiologicalTicks; num4 -= (long)num3 * 3600000L; pawn.ageTracker.BirthAbsTicks = num4; } if (pawn.ageTracker.AgeBiologicalTicks > pawn.ageTracker.AgeChronologicalTicks) { pawn.ageTracker.AgeChronologicalTicks = pawn.ageTracker.AgeBiologicalTicks; } return(false); } return(true); }
new public static void DoBirthSpawn(Pawn mother, Pawn father) { //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); int num = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve)); if (num < 1) { num = 1; } PawnGenerationRequest request = new PawnGenerationRequest(father.kindDef, father.Faction, PawnGenerationContext.NonPlayer, -1, false, true, false, false, true, false, 1f, false, true, true, false, false, false, false, null, null, null, null); Pawn pawn = null; for (int i = 0; i < num; i++) { pawn = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(pawn, mother)) { if (pawn.playerSettings != null && mother.playerSettings != null) { pawn.playerSettings.AreaRestriction = father.playerSettings.AreaRestriction; } if (pawn.RaceProps.IsFlesh) { pawn.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { pawn.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } } } else { Find.WorldPawns.PassToWorld(pawn, PawnDiscardDecideMode.Discard); } } if (mother.Spawned) { FilthMaker.MakeFilth(mother.Position, mother.Map, ThingDefOf.Filth_AmnioticFluid, mother.LabelIndefinite(), 5); if (mother.caller != null) { mother.caller.DoCall(); } if (pawn.caller != null) { pawn.caller.DoCall(); } } }
private static void GenerateRandomAge(Pawn pawn, PawnGenerationRequest request) { if (request.FixedBiologicalAge.HasValue && request.FixedChronologicalAge.HasValue) { float?fixedBiologicalAge = request.FixedBiologicalAge; bool arg_67_0; if (fixedBiologicalAge.HasValue) { float?fixedChronologicalAge = request.FixedChronologicalAge; if (fixedChronologicalAge.HasValue) { arg_67_0 = (fixedBiologicalAge.Value > fixedChronologicalAge.Value); goto IL_67; } } arg_67_0 = false; IL_67: if (arg_67_0) { Log.Warning(string.Concat(new object[] { "Tried to generate age for pawn ", pawn, ", but pawn generation request demands biological age (", request.FixedBiologicalAge, ") to be greater than chronological age (", request.FixedChronologicalAge, ")." })); } } if (request.Newborn) { pawn.ageTracker.AgeBiologicalTicks = 0L; } else if (request.FixedBiologicalAge.HasValue) { pawn.ageTracker.AgeBiologicalTicks = (long)(request.FixedBiologicalAge.Value * 3600000f); } else { int num = 0; float num2; while (true) { if (pawn.RaceProps.ageGenerationCurve != null) { num2 = (float)Mathf.RoundToInt(Rand.ByCurve(pawn.RaceProps.ageGenerationCurve, 200)); } else if (pawn.RaceProps.IsMechanoid) { num2 = (float)Rand.Range(0, 2500); } else { num2 = Rand.ByCurve(AlienPawnGenerator.DefaultAgeGenerationCurve, 200) * pawn.RaceProps.lifeExpectancy; } num++; if (num > 300) { break; } if (num2 <= (float)pawn.kindDef.maxGenerationAge && num2 >= (float)pawn.kindDef.minGenerationAge) { goto IL_1D7; } } Log.Error("Tried 300 times to generate age for " + pawn); IL_1D7: pawn.ageTracker.AgeBiologicalTicks = (long)(num2 * 3600000f) + (long)Rand.Range(0, 3600000); } if (request.Newborn) { pawn.ageTracker.AgeChronologicalTicks = 0L; } else if (request.FixedChronologicalAge.HasValue) { pawn.ageTracker.AgeChronologicalTicks = (long)(request.FixedChronologicalAge.Value * 3600000f); } else { int num3; if (Rand.Value < pawn.kindDef.backstoryCryptosleepCommonality) { float value = Rand.Value; if (value < 0.7f) { num3 = Rand.Range(0, 100); } else if (value < 0.95f) { num3 = Rand.Range(100, 1000); } else { int max = GenDate.CurrentYear - 2026 - pawn.ageTracker.AgeBiologicalYears; num3 = Rand.Range(1000, max); } } else { num3 = 0; } int ticksAbs = GenTicks.TicksAbs; long num4 = (long)ticksAbs - pawn.ageTracker.AgeBiologicalTicks; num4 -= (long)num3 * 3600000L; pawn.ageTracker.BirthAbsTicks = num4; } if (pawn.ageTracker.AgeBiologicalTicks > pawn.ageTracker.AgeChronologicalTicks) { pawn.ageTracker.AgeChronologicalTicks = pawn.ageTracker.AgeBiologicalTicks; } }
private static void GenerateRandomAge(Pawn pawn, PawnGenerationRequest request) { //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); if (request.FixedBiologicalAge.HasValue && request.FixedChronologicalAge.HasValue) { float?fixedBiologicalAge = request.FixedBiologicalAge; bool hasValue = fixedBiologicalAge.HasValue; float?fixedChronologicalAge = request.FixedChronologicalAge; if ((hasValue & fixedChronologicalAge.HasValue) && fixedBiologicalAge.GetValueOrDefault() > fixedChronologicalAge.GetValueOrDefault()) { Log.Warning("Tried to generate age for pawn " + pawn + ", but pawn generation request demands biological age (" + request.FixedBiologicalAge + ") to be greater than chronological age (" + request.FixedChronologicalAge + ")."); } } if (request.Newborn) { pawn.ageTracker.AgeBiologicalTicks = 0L; } else if (request.FixedBiologicalAge.HasValue) { pawn.ageTracker.AgeBiologicalTicks = (long)(request.FixedBiologicalAge.Value * 3600000f); } else { float num = 0f; int num2 = 0; do { num = ((pawn.RaceProps.ageGenerationCurve != null) ? ((float)Mathf.RoundToInt(Rand.ByCurve(pawn.RaceProps.ageGenerationCurve))) : ((!pawn.RaceProps.IsMechanoid) ? (Rand.ByCurve(DefaultAgeGenerationCurve) * pawn.RaceProps.lifeExpectancy) : Rand.Range(0f, 2500f))); num2++; if (num2 > 300) { Log.Error("Tried 300 times to generate age for " + pawn); break; } }while (num > (float)pawn.kindDef.maxGenerationAge || num < (float)pawn.kindDef.minGenerationAge); pawn.ageTracker.AgeBiologicalTicks = (long)(num * 3600000f) + Rand.Range(0, 3600000); } if (request.Newborn) { pawn.ageTracker.AgeChronologicalTicks = 0L; } else if (request.FixedChronologicalAge.HasValue) { pawn.ageTracker.AgeChronologicalTicks = (long)(request.FixedChronologicalAge.Value * 3600000f); } else { int num3; if (request.CertainlyBeenInCryptosleep || Rand.Value < pawn.kindDef.backstoryCryptosleepCommonality) { float value = Rand.Value; if (value < 0.7f) { num3 = Rand.Range(0, 100); } else if (value < 0.95f) { num3 = Rand.Range(100, 1000); } else { int max = GenDate.Year(GenTicks.TicksAbs, 0f) - 2026 - pawn.ageTracker.AgeBiologicalYears; num3 = Rand.Range(1000, max); } } else { num3 = 0; } int ticksAbs = GenTicks.TicksAbs; long num4 = ticksAbs - pawn.ageTracker.AgeBiologicalTicks; num4 -= (long)num3 * 3600000L; pawn.ageTracker.BirthAbsTicks = num4; } if (pawn.ageTracker.AgeBiologicalTicks > pawn.ageTracker.AgeChronologicalTicks) { pawn.ageTracker.AgeChronologicalTicks = pawn.ageTracker.AgeBiologicalTicks; } }
protected override bool TryFindScatterCell(Map map, out IntVec3 result) { randomSize = Mathf.RoundToInt(Rand.ByCurve(RuinSizeChanceCurve)); return(base.TryFindScatterCell(map, out result)); }
private static void DoDebugOptions(Rect rightRect, Pawn pawn) { Widgets.CheckboxLabeled(new Rect(rightRect.x, rightRect.y - 25f, 110f, 30f), "Dev: AllDiffs", ref showAllHediffs); Widgets.CheckboxLabeled(new Rect(rightRect.x + 115f, rightRect.y - 25f, 120f, 30f), "DiffsDebugInfo", ref showHediffsDebugInfo); if (Widgets.ButtonText(new Rect(rightRect.x + 240f, rightRect.y - 27f, 115f, 25f), "Debug info")) { List <FloatMenuOption> list = new List <FloatMenuOption>(); list.Add(new FloatMenuOption("Parts hit chance (this part or any child node)", delegate { StringBuilder stringBuilder13 = new StringBuilder(); foreach (BodyPartRecord item2 in from x in pawn.RaceProps.body.AllParts orderby x.coverageAbsWithChildren descending select x) { stringBuilder13.AppendLine(item2.LabelCap + " " + item2.coverageAbsWithChildren.ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder13.ToString())); })); list.Add(new FloatMenuOption("Parts hit chance (exactly this part)", delegate { StringBuilder stringBuilder12 = new StringBuilder(); float num8 = 0f; foreach (BodyPartRecord item3 in from x in pawn.RaceProps.body.AllParts orderby x.coverageAbs descending select x) { stringBuilder12.AppendLine(item3.LabelCap + " " + item3.coverageAbs.ToStringPercent()); num8 += item3.coverageAbs; } stringBuilder12.AppendLine(); stringBuilder12.AppendLine("Total " + num8.ToStringPercent()); Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder12.ToString())); })); list.Add(new FloatMenuOption("Per-part efficiency", delegate { StringBuilder stringBuilder11 = new StringBuilder(); foreach (BodyPartRecord allPart in pawn.RaceProps.body.AllParts) { stringBuilder11.AppendLine(allPart.LabelCap + " " + PawnCapacityUtility.CalculatePartEfficiency(pawn.health.hediffSet, allPart).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder11.ToString())); })); list.Add(new FloatMenuOption("BodyPartGroup efficiency (of only natural parts)", delegate { StringBuilder stringBuilder10 = new StringBuilder(); foreach (BodyPartGroupDef item4 in from x in DefDatabase <BodyPartGroupDef> .AllDefs where pawn.RaceProps.body.AllParts.Any((BodyPartRecord y) => y.groups.Contains(x)) select x) { stringBuilder10.AppendLine(item4.LabelCap + " " + PawnCapacityUtility.CalculateNaturalPartsAverageEfficiency(pawn.health.hediffSet, item4).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder10.ToString())); })); list.Add(new FloatMenuOption("IsSolid", delegate { StringBuilder stringBuilder9 = new StringBuilder(); foreach (BodyPartRecord notMissingPart in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder9.AppendLine(notMissingPart.LabelCap + " " + notMissingPart.def.IsSolid(notMissingPart, pawn.health.hediffSet.hediffs)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder9.ToString())); })); list.Add(new FloatMenuOption("IsSkinCovered", delegate { StringBuilder stringBuilder8 = new StringBuilder(); foreach (BodyPartRecord notMissingPart2 in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder8.AppendLine(notMissingPart2.LabelCap + " " + notMissingPart2.def.IsSkinCovered(notMissingPart2, pawn.health.hediffSet)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder8.ToString())); })); list.Add(new FloatMenuOption("does have added parts", delegate { StringBuilder stringBuilder7 = new StringBuilder(); foreach (BodyPartRecord notMissingPart3 in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder7.AppendLine(notMissingPart3.LabelCap + " " + pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(notMissingPart3)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder7.ToString())); })); list.Add(new FloatMenuOption("GetNotMissingParts", delegate { StringBuilder stringBuilder6 = new StringBuilder(); foreach (BodyPartRecord notMissingPart4 in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder6.AppendLine(notMissingPart4.LabelCap); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder6.ToString())); })); list.Add(new FloatMenuOption("GetCoverageOfNotMissingNaturalParts", delegate { StringBuilder stringBuilder5 = new StringBuilder(); foreach (BodyPartRecord item5 in from x in pawn.RaceProps.body.AllParts orderby pawn.health.hediffSet.GetCoverageOfNotMissingNaturalParts(x) descending select x) { stringBuilder5.AppendLine(item5.LabelCap + ": " + pawn.health.hediffSet.GetCoverageOfNotMissingNaturalParts(item5).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder5.ToString())); })); list.Add(new FloatMenuOption("parts nutrition (assuming adult)", delegate { StringBuilder stringBuilder4 = new StringBuilder(); float totalCorpseNutrition = StatDefOf.Nutrition.Worker.GetValueAbstract(pawn.RaceProps.corpseDef); foreach (BodyPartRecord item6 in from x in pawn.RaceProps.body.AllParts orderby FoodUtility.GetBodyPartNutrition(totalCorpseNutrition, pawn, x) descending select x) { stringBuilder4.AppendLine(item6.LabelCap + ": " + FoodUtility.GetBodyPartNutrition(totalCorpseNutrition, pawn, item6)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder4.ToString())); })); list.Add(new FloatMenuOption("test permanent injury pain factor probability", delegate { StringBuilder stringBuilder3 = new StringBuilder(); int num2 = 0; int num3 = 0; int num4 = 0; float num5 = 0f; int num6 = 10000; for (int k = 0; k < num6; k++) { float num7 = Mathf.Max(0f, Rand.ByCurve(HealthTuning.PermanentInjuryPainFactorRandomCurve)); if (num7 < 0f) { Log.Error("Pain factor < 0"); } if (num7 == 0f) { num2++; } if (num7 < 1f) { num3++; } if (num7 < 5f) { num4++; } if (num7 > num5) { num5 = num7; } } stringBuilder3.AppendLine("total: " + num6); stringBuilder3.AppendLine("0: " + num2 + " (" + ((float)num2 / (float)num6).ToStringPercent() + ")"); stringBuilder3.AppendLine("< 1: " + num3 + " (" + ((float)num3 / (float)num6).ToStringPercent() + ")"); stringBuilder3.AppendLine("< 5: " + num4 + " (" + ((float)num4 / (float)num6).ToStringPercent() + ")"); stringBuilder3.AppendLine("max: " + num5); Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder3.ToString())); })); HediffGiver_Birthday hLocal; list.Add(new FloatMenuOption("HediffGiver_Birthday chance at age", delegate { List <FloatMenuOption> list2 = new List <FloatMenuOption>(); foreach (HediffGiverSetDef hediffGiverSet in pawn.RaceProps.hediffGiverSets) { foreach (HediffGiver_Birthday item7 in hediffGiverSet.hediffGivers.OfType <HediffGiver_Birthday>()) { hLocal = item7; FloatMenuOption item = new FloatMenuOption(hediffGiverSet.defName + " - " + item7.hediff.defName, delegate { StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.AppendLine("% of pawns which will have at least 1 " + hLocal.hediff.label + " at age X:"); stringBuilder2.AppendLine(); for (int j = 1; (float)j < pawn.RaceProps.lifeExpectancy + 20f; j++) { stringBuilder2.AppendLine(j + ": " + hLocal.DebugChanceToHaveAtAge(pawn, j).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder2.ToString())); }); list2.Add(item); } } Find.WindowStack.Add(new FloatMenu(list2)); })); list.Add(new FloatMenuOption("HediffGiver_Birthday count at age", delegate { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Average hediffs count (from HediffGiver_Birthday) at age X:"); stringBuilder.AppendLine(); for (int i = 1; (float)i < pawn.RaceProps.lifeExpectancy + 20f; i++) { float num = 0f; foreach (HediffGiverSetDef hediffGiverSet2 in pawn.RaceProps.hediffGiverSets) { foreach (HediffGiver_Birthday item8 in hediffGiverSet2.hediffGivers.OfType <HediffGiver_Birthday>()) { num += item8.DebugChanceToHaveAtAge(pawn, i); } } stringBuilder.AppendLine(i + ": " + num.ToStringDecimalIfSmall()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder.ToString())); })); Find.WindowStack.Add(new FloatMenu(list)); } }
private static bool on_begin_DoBirthSpawn(ref Pawn mother, ref Pawn father) { //TODO: Set pregnant hediff to torso //--Log.Message("patches_pregnancy::PATCH_Hediff_Pregnant::DoBirthSpawn() called"); var mother_name = (mother != null) ? mother.NameStringShort : "NULL"; var father_name = (father != null) ? father.NameStringShort : "NULL"; if (mother == null) { Log.Error("Hediff_Pregnant::DoBirthSpawn() - no mother defined"); return(false); } if (father == null) { Log.Warning("Hediff_Pregnant::DoBirthSpawn() - no father defined"); } // get a reference to the hediff we are applying Hediff_Pregnant self = (Hediff_Pregnant)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Pregnant")); // determine litter size int litter_size = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve, 300)); if (litter_size < 1) { litter_size = 1; } float skin_whiteness = Rand.Range(0, 1); string last_name = null; // send a message about giving birth ////--Log.Message("Hediff_Pregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - generating baby pawns"); if (self.Visible && PawnUtility.ShouldSendNotificationAbout(mother)) { Messages.Message("GivingBirth".Translate(new object[] { mother.LabelIndefinite() }).CapitalizeFirst(), mother, MessageTypeDefOf.NeutralEvent); } ////--Log.Message("Hediff_Pregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - creating spawn request"); List <Pawn> siblings = new List <Pawn>(); for (int i = 0; i < litter_size; i++) { Pawn spawn_parent = mother; if (father != null && Mod_Settings.pregnancy_use_parent_method && (100 * Rand.Value) > Mod_Settings.pregnancy_weight_parent) { spawn_parent = father; } PawnGenerationRequest request = new PawnGenerationRequest(spawn_parent.kindDef, spawn_parent.Faction, PawnGenerationContext.NonPlayer, spawn_parent.Map.Tile, false, true, false, false, false, false, 1, false, true, true, false, false, false, false, null, null, 0, 0, null, skin_whiteness, last_name); ////--Log.Message("Hediff_GenericPregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - spawning baby"); Pawn baby = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother)) { if (baby.playerSettings != null && mother.playerSettings != null) { baby.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction; } if (baby.RaceProps.IsFlesh) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } foreach (Pawn sibling in siblings) { baby.relations.AddDirectRelation(PawnRelationDefOf.Sibling, sibling); } siblings.Add(baby); //inject RJW_BabyState to the newborn if RimWorldChildren is not active if (!xxx.RimWorldChildrenIsActive && baby.kindDef.race == ThingDefOf.Human && baby.ageTracker.CurLifeStageIndex <= 1 && baby.ageTracker.AgeBiologicalYears < 1 && !baby.Dead) { // Clean out drug randomly generated drug addictions baby.health.hediffSet.Clear(); baby.health.AddHediff(HediffDef.Named("RJW_BabyState"), null, null); Hediff_SimpleBaby babystate = (Hediff_SimpleBaby)baby.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_BabyState")); if (babystate != null) { babystate.GrowUpTo(0, true); } } } } else { Find.WorldPawns.PassToWorld(baby, PawnDiscardDecideMode.Discard); } } ////--Log.Message("Hediff_Pregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - removing pregnancy"); mother.health.RemoveHediff(self); return(false); }
public override void Initialize(CompProperties props) { base.Initialize(props); signalTag = Props.signalTag; ticksLeft = Mathf.CeilToInt(Rand.ByCurve(Props.countdownCurveTicks)); }
private static bool on_begin_DoBirthSpawn(ref Pawn mother, ref Pawn father) { //--Log.Message("patches_pregnancy::PATCH_Hediff_Pregnant::DoBirthSpawn() called"); if (mother == null) { Log.Error("Hediff_Pregnant::DoBirthSpawn() - no mother defined -> exit"); return(false); } //vanilla debug? if (mother.gender == Gender.Male) { Log.Error("Hediff_Pregnant::DoBirthSpawn() - mother is male -> exit"); return(false); } //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); // get a reference to the hediff we are applying //do birth for vanilla pregnancy Hediff //if using rjw pregnancies - add RJW pregnancy Hediff and birth it instead Hediff_Pregnant self = (Hediff_Pregnant)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Pregnant")); if (self != null) { if (father == null) { father = Hediff_BasePregnancy.Trytogetfather(ref mother); } Log.Message("patches_pregnancy::PATCH_Hediff_Pregnant::DoBirthSpawn():Vanilla_pregnancy birthing:" + xxx.get_pawnname(mother)); if (RJWPregnancySettings.animal_pregnancy_enabled && ((father == null || xxx.is_animal(father)) && xxx.is_animal(mother))) { //RJW Bestial pregnancy animal-animal Log.Message(" override as Bestial birthing(animal-animal): Father-" + xxx.get_pawnname(father) + " Mother-" + xxx.get_pawnname(mother)); Hediff_BestialPregnancy.Create(mother, father); Hediff_BestialPregnancy hediff = (Hediff_BestialPregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy_beast")); hediff.Initialize(mother, father); hediff.GiveBirth(); if (self != null) { mother.health.RemoveHediff(self); } return(false); } else if (RJWPregnancySettings.bestial_pregnancy_enabled && ((xxx.is_animal(father) && xxx.is_human(mother)) || (xxx.is_human(father) && xxx.is_animal(mother)))) { //RJW Bestial pregnancy human-animal Log.Message(" override as Bestial birthing(human-animal): Father-" + xxx.get_pawnname(father) + " Mother-" + xxx.get_pawnname(mother)); Hediff_BestialPregnancy.Create(mother, father); Hediff_BestialPregnancy hediff = (Hediff_BestialPregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy_beast")); hediff.Initialize(mother, father); hediff.GiveBirth(); if (self != null) { mother.health.RemoveHediff(self); } return(false); } else if (RJWPregnancySettings.humanlike_pregnancy_enabled && (xxx.is_human(father) && xxx.is_human(mother))) { //RJW Humanlike pregnancy Log.Message(" override as Humanlike birthing: Father-" + xxx.get_pawnname(father) + " Mother-" + xxx.get_pawnname(mother)); Hediff_HumanlikePregnancy.Create(mother, father); Hediff_HumanlikePregnancy hediff = (Hediff_HumanlikePregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy")); hediff.Initialize(mother, father); hediff.GiveBirth(); if (self != null) { mother.health.RemoveHediff(self); } return(false); } else { Log.Warning("Hediff_Pregnant::DoBirthSpawn() - rjw checks failed, vanilla pregnancy birth"); Log.Warning("Hediff_Pregnant::DoBirthSpawn(): Father-" + xxx.get_pawnname(father) + " Mother-" + xxx.get_pawnname(mother)); //vanilla pregnancy code, no effects on rjw int num = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve)); if (num < 1) { num = 1; } PawnGenerationRequest request = new PawnGenerationRequest(mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, -1, forceGenerateNewPawn: false, newborn: true); Pawn pawn = null; for (int i = 0; i < num; i++) { pawn = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(pawn, mother)) { if (pawn.playerSettings != null && mother.playerSettings != null) { pawn.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction; } if (pawn.RaceProps.IsFlesh) { pawn.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { pawn.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } } } else { Find.WorldPawns.PassToWorld(pawn, PawnDiscardDecideMode.Discard); } TaleRecorder.RecordTale(TaleDefOf.GaveBirth, mother, pawn); } if (mother.Spawned) { FilthMaker.MakeFilth(mother.Position, mother.Map, ThingDefOf.Filth_AmnioticFluid, mother.LabelIndefinite(), 5); if (mother.caller != null) { mother.caller.DoCall(); } if (pawn.caller != null) { pawn.caller.DoCall(); } } if (self != null) { mother.health.RemoveHediff(self); } return(false); } } // do birth for existing RJW pregnancies Hediff_HumanlikePregnancy rjwH = (Hediff_HumanlikePregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy")); if (rjwH != null) { //RJW Bestial pregnancy Log.Message("patches_pregnancy::PATCH_Hediff_Pregnant::DoBirthSpawn():RJW_pregnancy birthing:" + xxx.get_pawnname(mother)); rjwH.GiveBirth(); if (self == null) { return(false); } } Hediff_BestialPregnancy rjwB = (Hediff_BestialPregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy_beast")); if (rjwB != null) { //RJW Humanlike pregnancy Log.Message("patches_pregnancy::PATCH_Hediff_Pregnant::DoBirthSpawn():RJW_pregnancy_beast birthing:" + xxx.get_pawnname(mother)); rjwB.GiveBirth(); if (self == null) { return(false); } } //debug, add RJW pregnancy and birth it Log.Message("patches_pregnancy::PATCH_Hediff_Pregnant::DoBirthSpawn():Debug_pregnancy birthing:" + xxx.get_pawnname(mother)); if (father == null) { father = Hediff_BasePregnancy.Trytogetfather(ref mother); } /* * if (true) * { * //RJW Mech pregnancy * Log.Message(" override as mech birthing:" + xxx.get_pawnname(mother)); * Hediff_MechanoidPregnancy.Create(mother, father); * Hediff_MechanoidPregnancy hediff = (Hediff_MechanoidPregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy_mech")); * hediff.GiveBirth(); * return false; * } */ if (RJWPregnancySettings.bestial_pregnancy_enabled && ((xxx.is_animal(father) || xxx.is_animal(mother))) || (xxx.is_animal(mother) && RJWPregnancySettings.animal_pregnancy_enabled)) { //RJW Bestial pregnancy Log.Message(" override as Bestial birthing, mother: " + xxx.get_pawnname(mother)); Hediff_BestialPregnancy.Create(mother, father); Hediff_BestialPregnancy hediff = (Hediff_BestialPregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy_beast")); hediff.GiveBirth(); } else if (RJWPregnancySettings.humanlike_pregnancy_enabled && ((father == null || xxx.is_human(father)) && xxx.is_human(mother))) { //RJW Humanlike pregnancy Log.Message(" override as Humanlike birthing, mother: " + xxx.get_pawnname(mother)); Hediff_HumanlikePregnancy.Create(mother, father); Hediff_HumanlikePregnancy hediff = (Hediff_HumanlikePregnancy)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy")); hediff.GiveBirth(); } else { Log.Warning("Hediff_Pregnant::DoBirthSpawn() - debug vanilla pregnancy birth"); //vanilla code int num = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve)); if (num < 1) { num = 1; } PawnGenerationRequest request = new PawnGenerationRequest(mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, -1, forceGenerateNewPawn: false, newborn: true); Pawn pawn = null; for (int i = 0; i < num; i++) { pawn = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(pawn, mother)) { if (pawn.playerSettings != null && mother.playerSettings != null) { pawn.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction; } if (pawn.RaceProps.IsFlesh) { pawn.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { pawn.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } } } else { Find.WorldPawns.PassToWorld(pawn, PawnDiscardDecideMode.Discard); } TaleRecorder.RecordTale(TaleDefOf.GaveBirth, mother, pawn); } if (mother.Spawned) { FilthMaker.MakeFilth(mother.Position, mother.Map, ThingDefOf.Filth_AmnioticFluid, mother.LabelIndefinite(), 5); if (mother.caller != null) { mother.caller.DoCall(); } if (pawn.caller != null) { pawn.caller.DoCall(); } } if (self != null) { mother.health.RemoveHediff(self); } } return(false); }
// // Methods // public void DoBirthSpawn(Pawn mother, Pawn father, float chance_successful = 1.0f) { if (mother == null) { Log.Error("No mother defined"); return; } if (father == null) { Log.Warning("No father defined"); } float birthing_quality = mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).TryGetComp <HediffComp_TendDuration> ().tendQuality; mother.health.AddHediff(HediffDef.Named("PostPregnancy"), null, null); mother.health.AddHediff(HediffDef.Named("Lactating"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null); int num = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve, 300)); if (num < 1) { num = 1; } // Make sure the pawn looks like mommy and daddy float skin_whiteness = Rand.Range(0, 1); // Pool of "genetic traits" the baby can inherit List <Trait> traitpool = new List <Trait>(); if (mother.RaceProps.Humanlike) { // Add mom's traits to the pool foreach (Trait momtrait in mother.story.traits.allTraits) { traitpool.Add(momtrait); } if (father != null) { // Add dad's traits to the pool foreach (Trait dadtrait in father.story.traits.allTraits) { traitpool.Add(dadtrait); } // Blend skin colour between mom and dad skin_whiteness = Rand.Range(mother.story.melanin, father.story.melanin); } else { // If dad doesn't exist, just use mom's skin colour skin_whiteness = mother.story.melanin; } // Clear out any traits that aren't genetic from the list if (traitpool.Count > 0) { foreach (Trait trait in traitpool.ToArray()) { bool is_genetic = false; foreach (TraitDef gentrait in genetic_traits) { if (gentrait.defName == trait.def.defName) { is_genetic = true; } } if (!is_genetic) { traitpool.Remove(trait); } } } } // Todo: Perhaps add a way to pass on the parent's body build // Best way to do it might be to represent thin/fat/normal/hulk // as a pair of two values, strength and weight // For example, if the mother has an average body type, she would // have a strength of .5f and a weight of .5f. A fat pawn would have // a strength of .5f and a weight of .75f. A thin pawn would have a // strength of .25f and a weight of .25f. A hulk pawn would have // strength of .75f and weight of .75f //List<float> strength_pool = new List<float>(); //List<float> weight_pool = new List<float>(); //// Get mother and fathers info here if possible //float avg_strength = strength_pool.Average(); //float avg_weight = weight_pool.Average(); // Surname passing string last_name = null; if (mother.RaceProps.Humanlike) { if (father == null) { last_name = NameTriple.FromString(mother.Name.ToStringFull).Last; } else { last_name = NameTriple.FromString(father.Name.ToStringFull).Last; } //Log.Message ("Debug: Newborn is born to the " + last_name + " family."); } //PawnGenerationRequest request = new PawnGenerationRequest (mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map, false, true, false, false, true, false, 1, false, true, true, null, 0, 0, null, skin_whiteness, last_name); PawnGenerationRequest request = new PawnGenerationRequest(mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map.Tile, false, true, false, false, false, false, 1, false, true, true, false, false, null, 0, 0, null, skin_whiteness, last_name); Pawn baby = null; for (int i = 0; i < num; i++) { baby = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother)) { if (baby.playerSettings != null && mother.playerSettings != null) { baby.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction; } if (baby.RaceProps.IsFlesh) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } } // Good until otherwise proven bad bool successful_birth = true; var disabledBaby = BackstoryDatabase.allBackstories ["CustomBackstory_NA_Childhood_Disabled"]; if (disabledBaby != null) { baby.story.childhood = disabledBaby; } else { Log.Error("Couldn't find the required Backstory: CustomBackstory_NA_Childhood_Disabled!"); baby.story.childhood = null; } baby.story.adulthood = null; baby.workSettings.Disable(WorkTypeDefOf.Hunting); //hushes up the "has no ranged weapon" alert // remove all traits baby.story.traits.allTraits.Clear(); // Add some genetic traits if (traitpool.Count > 0) { for (int j = 0; j != 2; j++) { Trait gentrait = traitpool.RandomElement(); if (!baby.story.traits.HasTrait(gentrait.def)) { baby.story.traits.GainTrait(gentrait); } } } // Move the baby in front of the mother, rather than on top if (mother.CurrentBed() != null) { baby.Position = baby.Position + new IntVec3(0, 0, 1).RotatedBy(mother.CurrentBed().Rotation); } // else { // baby.Position = baby.Position + new IntVec3 (0, 0, 1).RotatedBy (mother.Rotation); // } // The baby died from bad chance of success if (Rand.Value > chance_successful || chance_successful == 0) { successful_birth = false; } // Birth defects via drugs or alcohol if (mother.health.hediffSet.HasHediff(HediffDef.Named("BirthDefectTracker"))) { Hediff_BirthDefectTracker tracker = (Hediff_BirthDefectTracker)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("BirthDefectTracker")); // The baby died in utero from chemical affect if (tracker.stillbirth) { successful_birth = false; } // The baby lived! So far, anyways else { // Should the baby get fetal alcohol syndrome? if (tracker.fetal_alcohol) { baby.health.AddHediff(HediffDef.Named("FetalAlcoholSyndrome")); } // If the mother got high while pregnant, crongrats retard // now your baby is addicted to crack if (tracker.drug_addictions.Count > 0) { foreach (HediffDef addiction in tracker.drug_addictions) { baby.health.AddHediff(addiction, null, null); } } } } // Inbred? if (father != null && mother.relations.FamilyByBlood.Contains <Pawn> (father)) { // 50% chance to get a birth defect from inbreeding if (Rand.Range(0, 1) == 1) { GiveRandomBirthDefect(baby); if (baby.health.hediffSet.HasHediff(HediffDef.Named("DefectStillborn"))) { successful_birth = false; } } } // The baby was born! Yay! if (successful_birth == true) { // Give father a happy memory if the birth was successful and he's not dead if (father != null && !father.health.Dead) { // The father is happy the baby was born father.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PartnerGaveBirth")); } // Send a message that the baby was born if (mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("HumanPregnancy")).Visible&& PawnUtility.ShouldSendNotificationAbout(mother)) { //Messages.Message ("MessageGaveBirth".Translate (new object[] {mother.LabelIndefinite ()}).CapitalizeFirst (), mother, MessageSound.Benefit); Find.LetterStack.ReceiveLetter("LabelGaveBirth".Translate(new object[] { baby.LabelIndefinite() }), "MessageHumanBirth".Translate(new object[] { mother.LabelIndefinite(), baby.Name.ToStringShort }), LetterDefOf.Good, baby, null); } // Try to give PPD. If not, give "New baby" thought float chance = 0.2f; if (mother.story.traits.HasTrait(TraitDefOf.Psychopath)) { chance -= 1; } if (mother.story.traits.HasTrait(TraitDef.Named("Nerves"))) { chance -= 0.2f * mother.story.traits.GetTrait(TraitDef.Named("Nerves")).Degree; } else if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood"))) { if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == 2) { chance -= 1; } if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2) { chance += 0.6f; } // For some reason this is broken /*} else if (mother.story.traits.HasTrait (TraitDef.Named ("Neurotic"))) { * if (mother.story.traits.GetTrait (TraitDef.Named ("Neurotic")).Degree == 1) { * chance += 0.2f; * } else * chance += 0.4f;*/ } // Because for whatever dumb reason the Math class doesn't have a Clamp method if (chance < 0) { chance = 0; } if (chance > 1) { chance = 1; } Log.Message("Debugging: Chance of PPD is " + chance * 100 + "%"); // Try to give PPD if (Rand.Value < chance) { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PostPartumDepression"), null); bool verybad = false; if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood"))) { if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2) { verybad = true; } } else if (mother.story.traits.HasTrait(TraitDef.Named("Neurotic"))) { if (mother.story.traits.GetTrait(TraitDef.Named("Neurotic")).Degree == 2) { verybad = true; } } // This pawn gets an exceptionally bad case of PPD if (verybad) { foreach (Thought_Memory thought in mother.needs.mood.thoughts.memories.Memories) { if (thought.def.defName == "PostPartumDepression") { thought.SetForcedStage(thought.CurStageIndex + 1); } } } } else { // If we didn't get PPD, then the pawn gets a mood buff if (mother.health.hediffSet.HasHediff(HediffDef.Named("GaveBirthFlag")) == false) { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirthFirstTime")); } else { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirth")); } } } else { bool aborted = false; if (chance_successful < 0f) { aborted = true; } if (baby != null) { Miscarry(baby, aborted); } } } else { Find.WorldPawns.PassToWorld(baby, PawnDiscardDecideMode.Discard); } } // Post birth if (mother.Spawned) { // Spawn guck FilthMaker.MakeFilth(mother.Position, mother.Map, ThingDefOf.FilthAmnioticFluid, mother.LabelIndefinite(), 5); if (mother.caller != null) { mother.caller.DoCall(); } if (baby != null) { if (baby.caller != null) { baby.caller.DoCall(); } } Log.Message("Birth quality = " + birthing_quality); // Possible tearing from pregnancy if (birthing_quality < 0.75f) { if (birthing_quality < Rand.Value) { // Add a tear from giving birth if (birthing_quality < Rand.Value) { mother.health.AddHediff(HediffDef.Named("PregnancyTearMajor"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null); } else { mother.health.AddHediff(HediffDef.Named("PregnancyTear"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null); } } } } pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth"))); pawn.health.RemoveHediff(this); }