/// <summary>
        /// Returns true if a race part was chosen (even if that part is "no part").
        /// </summary>
        public static bool TryAddRacePart(Pawn pawn, SexPartType sexPartType)
        {
            if (!TryGetRaceGroupDef(pawn, out var raceGroupDef))
            {
                // No race, so nothing was chosen.
                return(false);
            }

            if (!RacePartDef_Helper.TryChooseRacePartDef(raceGroupDef, sexPartType, out var racePartDef))
            {
                // Failed to find a part, so nothing was chosen.
                return(false);
            }

            if (racePartDef.IsNone)
            {
                // "no part" was explicitly chosen.
                return(true);
            }

            var target         = sexPartType.GetBodyPartDef();
            var bodyPartRecord = pawn.RaceProps.body.AllParts.Find(bpr => bpr.def == target);

            if (!racePartDef.TryGetHediffDef(out var hediffDef))
            {
                // Failed to find hediffDef.
                return(false);
            }

            var hediff = RacePartDef_Helper.MakePart(hediffDef, pawn, bodyPartRecord, racePartDef);

            pawn.health.AddHediff(hediff, bodyPartRecord);
            // A part was chosen and added.
            return(true);
        }
 public static BodyPartDef GetBodyPartDef(this SexPartType sexPartType)
 {
     return(sexPartType switch
     {
         SexPartType.Anus => xxx.anusDef,
         SexPartType.FemaleBreast => xxx.breastsDef,
         SexPartType.FemaleGenital => xxx.genitalsDef,
         SexPartType.MaleBreast => xxx.breastsDef,
         SexPartType.MaleGenital => xxx.genitalsDef,
         _ => throw new ArgumentException($"Unrecognized sexPartType: {sexPartType}"),
     });
Example #3
0
 public List <string> GetRacePartDefNames(SexPartType sexPartType)
 {
     return(sexPartType switch
     {
         SexPartType.Anus => anuses,
         SexPartType.FemaleBreast => femaleBreasts,
         SexPartType.FemaleGenital => femaleGenitals,
         SexPartType.MaleBreast => maleBreasts,
         SexPartType.MaleGenital => maleGenitals,
         _ => throw new ApplicationException($"Unrecognized sexPartType: {sexPartType}"),
     });
Example #4
0
        public static bool TryChooseRacePartDef(RaceGroupDef raceGroupDef, SexPartType sexPartType, out RacePartDef racePartDef)
        {
            var partNames = raceGroupDef.GetRacePartDefNames(sexPartType);

            if (partNames == null)
            {
                // Missing list, so nothing was chosen.
                racePartDef = null;
                return(false);
            }
            else if (!partNames.Any())
            {
                // Empty list, so "no part" was chosen.
                racePartDef = RacePartDef.None;
                return(true);
            }

            var chances    = raceGroupDef.GetChances(sexPartType);
            var hasChances = chances != null && chances.Count() > 0;

            if (hasChances && chances.Count() != partNames.Count())
            {
                // No need for this to be runtime, should probably be a config error in RaceGroupDef.
                Log.Error($"[RJW] RaceGroupDef named {raceGroupDef.defName} has {partNames.Count()} parts but {chances.Count()} chances for {sexPartType}.");
                racePartDef = null;
                return(false);
            }

            string partName;

            if (hasChances)
            {
                var indexes = partNames.Select((x, i) => i);
                partName = partNames[indexes.RandomElementByWeight(i => chances[i])];
            }
            else
            {
                partName = partNames.RandomElement();
            }

            racePartDef = DefDatabase <RacePartDef> .GetNamedSilentFail(partName);

            if (racePartDef == null)
            {
                Log.Error($"[RJW] Could not find a RacePartDef named {partName} referenced by RaceGroupDef named {raceGroupDef.defName}.");
                return(false);
            }
            else
            {
                return(true);
            }
        }
Example #5
0
        public static bool TryAddSexPart(Pawn pawn, SexPartType sexPartType)
        {
            if (!TryGetRaceGroupDef(pawn, out var raceGroupDef))
            {
                // No race, so nothing was chosen.
                return(false);
            }

            var parts = GetParts(raceGroupDef, sexPartType);

            if (parts == null)
            {
                // Missing list, so nothing was chosen.
                return(false);
            }
            else if (!parts.Any())
            {
                // Empty list, so "no part" was chosen.
                return(true);
            }

            var       target    = BodyPartDefBySexPartType[sexPartType];
            var       part      = pawn.RaceProps.body.AllParts.Find(bpr => bpr.def == target);
            HediffDef hediffDef = parts.RandomElement();

            if (parts.Count() > 1)
            {
                List <float> partschances = GetPartsChances(raceGroupDef, sexPartType);
                if (partschances.Count() > 1)
                {
                    float            chance        = Rand.Value;
                    List <HediffDef> filteredparts = null;
                    for (int i = 0; i < partschances.Count(); i++)
                    {
                        if (chance <= partschances[i])
                        {
                            filteredparts.Add(parts[i]);
                        }
                    }

                    if (filteredparts.Any())
                    {
                        hediffDef = filteredparts.RandomElement();
                    }
                }
            }
            pawn.health.AddHediff(hediffDef, part);
            // A part was chosen and added.
            return(true);
        }
Example #6
0
        public static List <float> GetPartsChances(RaceGroupDef raceGroupDef, SexPartType sexPartType)
        {
            switch (sexPartType)
            {
            case SexPartType.Anus:
                return(raceGroupDef.chanceanuses);

            case SexPartType.FemaleBreast:
                return(raceGroupDef.chancefemaleBreasts);

            case SexPartType.FemaleGenital:
                return(raceGroupDef.chancefemaleGenitals);

            case SexPartType.MaleBreast:
                return(raceGroupDef.chancemaleBreasts);

            case SexPartType.MaleGenital:
                return(raceGroupDef.chancemaleGenitals);

            default:
                throw new ApplicationException($"Unrecognized sexPartType: {sexPartType}");
            }
        }
Example #7
0
 public static bool TryAddRacePart(this Pawn pawn, SexPartType sexPartType)
 {
     return(RaceGroupDef_Helper.TryAddRacePart(pawn, sexPartType));
 }