Esempio n. 1
0
        /// <summary>
        /// operation - move part data from thing to hediff
        /// </summary>
        public static Hediff recipePartAdder(RecipeDef recipe, Pawn pawn, BodyPartRecord part, List <Thing> ingredients)
        {
            Hediff hd    = HediffMaker.MakeHediff(recipe.addsHediff, pawn, part);
            Thing  thing = ingredients.Find(x => x.def.defName == recipe.addsHediff.defName);

            CompThingBodyPart  CompThing  = thing.TryGetComp <rjw.CompThingBodyPart>();
            CompHediffBodyPart CompHediff = hd.TryGetComp <rjw.CompHediffBodyPart>();

            if (CompHediff != null && CompThing != null)
            {
                if (CompThing.SizeBase > 0)
                {
                    CompHediff.FluidType     = CompThing.FluidType;
                    CompHediff.FluidAmmount  = CompThing.FluidAmmount;
                    CompHediff.FluidModifier = CompThing.FluidModifier;
                    CompHediff.SizeBase      = CompThing.SizeBase;
                    CompHediff.SizeOwner     = CompThing.SizeOwner;
                    CompHediff.RaceOwner     = CompThing.RaceOwner;
                    CompHediff.PreviousOwner = CompThing.PreviousOwner;
                    CompHediff.Eggs          = CompThing.Eggs;
                    CompHediff.updatesize();
                }
                else                  //not initialised things, drop pods, trader?  //TODO: figure out how to populate rjw parts at gen
                {
                    hd = MakePart(hd.def, pawn, part);
                }
            }

            return(hd);
        }
        public void InitComp(Pawn pawn = null)
        {
            var def = DefDatabase <HediffDef> .GetNamed(parent.def.defName);

            //pick random pawn to create temp hediff
            pawn = PawnsFinder.AllMaps_FreeColonistsAndPrisonersSpawned.RandomElement();
            //pawn = PawnsFinder.All_AliveOrDead.RandomElement(); //TODO: maybe some day add immobilizing size?

            Hediff hd = HediffMaker.MakeHediff(def, pawn);

            CompHediffBodyPart CompHediff = hd.TryGetComp <CompHediffBodyPart>();

            if (CompHediff != null)
            {
                CompHediff.initComp(pawn);
                CompHediff.updatesize();

                FluidType     = CompHediff.FluidType;
                FluidAmmount  = CompHediff.FluidAmmount;
                FluidModifier = CompHediff.FluidModifier;
                Size          = CompHediff.Size;
                SizeBase      = CompHediff.SizeBase;
                SizeOwner     = CompHediff.SizeOwner;
                RaceOwner     = "Unknown";
                PreviousOwner = "Unknown";
                Eggs          = CompHediff.Eggs;
            }
        }
 public override void PostAdd(DamageInfo?dinfo)
 {
     foreach (Hediff hed in pawn.health.hediffSet.hediffs.Where(x => x.Part != null && x.Part == Part && (x is Hediff_PartBaseNatural || x is Hediff_PartBaseArtifical)).ToList())
     {
         CompHediffBodyPart CompHediff = hed.TryGetComp <rjw.CompHediffBodyPart>();
         if (CompHediff != null)
         {
             CompHediff.SizeBase = this.def.initialSeverity;
             CompHediff.initComp(reroll: true);
             CompHediff.updatesize();
         }
     }
     pawn.health.RemoveHediff(this);
 }
Esempio n. 4
0
        /// <summary>
        /// generate part hediff
        /// </summary>
        public static Hediff MakePart(HediffDef def, Pawn pawn, BodyPartRecord bpr)
        {
            //Log.Message("SexPartAdder::PartMaker ( " + xxx.get_pawnname(pawn) + " ) " + def.defName);
            Hediff hd = HediffMaker.MakeHediff(def, pawn, bpr);
            //Log.Message("SexPartAdder::PartMaker ( " + xxx.get_pawnname(pawn) + " ) " + hd.def.defName);
            CompHediffBodyPart compHediff = hd.TryGetComp <CompHediffBodyPart>();

            if (compHediff != null)
            {
                //Log.Message("SexPartAdder::PartMaker init comps");
                compHediff.initComp(pawn);
                compHediff.updatesize();
            }
            return(hd);
        }
Esempio n. 5
0
        /// <summary>
        /// operation - move part data from hediff to thing
        /// </summary>
        public static Thing recipePartRemover(Hediff hd)
        {
            Thing thing = ThingMaker.MakeThing(hd.def.spawnThingOnRemoved);

            CompThingBodyPart  CompThing  = thing.TryGetComp <rjw.CompThingBodyPart>();
            CompHediffBodyPart CompHediff = hd.TryGetComp <rjw.CompHediffBodyPart>();

            if (CompThing != null && CompHediff != null)
            {
                CompThing.FluidType     = CompHediff.FluidType;
                CompThing.FluidAmmount  = CompHediff.FluidAmmount;
                CompThing.FluidModifier = CompHediff.FluidModifier;
                CompThing.Size          = CompHediff.Size;
                CompThing.SizeBase      = CompHediff.SizeBase;
                CompThing.SizeOwner     = CompHediff.SizeOwner;
                CompThing.RaceOwner     = CompHediff.RaceOwner;
                CompThing.PreviousOwner = xxx.get_pawnname(CompHediff.Pawn);
                CompThing.Eggs          = CompHediff.Eggs;
            }
            return(thing);
        }
 public override void PostAdd(DamageInfo?dinfo)
 {
     foreach (Hediff hed in pawn.health.hediffSet.hediffs.Where(x => x.Part != null && x.Part == Part && (x is Hediff_PartBaseNatural || x is Hediff_PartBaseArtifical)).ToList())
     {
         CompHediffBodyPart CompHediff = hed.TryGetComp <rjw.CompHediffBodyPart>();
         if (CompHediff != null)
         {
             //Log.Message("  Hediff_PartsSizeChanger: " + hed.Label);
             //Log.Message("  Hediff_PartsSizeChanger: " + hed.Severity);
             //Log.Message("  Hediff_PartsSizeChanger: " + CompHediff.SizeBase);
             //Log.Message("  Hediff_PartsSizeChanger: " + "-----");
             //Log.Message("  Hediff_PartsSizeChanger: " + this.Label);
             //Log.Message("  Hediff_PartsSizeChanger: " + this.Severity);
             CompHediff.SizeBase = this.CurStage.minSeverity;
             CompHediff.initComp(reroll: true);
             CompHediff.updatesize();
             //Log.Message("  Hediff_PartsSizeChanger: " + "-----");
             //Log.Message("  Hediff_PartsSizeChanger: " + hed.Label);
             //Log.Message("  Hediff_PartsSizeChanger: " + hed.Severity);
             //Log.Message("  Hediff_PartsSizeChanger: " + CompHediff.SizeBase);
         }
     }
     pawn.health.RemoveHediff(this);
 }
        public static void calculateAndApplySemen(Pawn pawn, Pawn partner, xxx.rjwSextype sextype)
        {
            if (!RJWSettings.cum_on_body)
            {
                return;
            }

            Pawn giver, receiver;
            //Rand.PopState();
            //Rand.PushState(RJW_Multiplayer.PredictableSeed());

            List <Hediff> giverparts;
            var           pawnparts    = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn));
            var           partnerparts = Genital_Helper.get_PartsHediffList(partner, Genital_Helper.get_genitalsBPR(partner));

            //dispenser of the seed
            if (Genital_Helper.has_penis_fertile(pawn, pawnparts) || xxx.is_mechanoid(pawn) || xxx.is_insect(pawn))
            {
                giver      = pawn;
                giverparts = pawnparts;
                receiver   = partner;
            }
            else if (partner != null && (Genital_Helper.has_penis_fertile(partner, partnerparts) || xxx.is_mechanoid(partner) || xxx.is_insect(partner)))
            {
                giver      = partner;
                giverparts = partnerparts;
                receiver   = pawn;
            }
            else            //female on female or genderless - no s***n dispensed; maybe add futa support?
            {
                return;
            }

            //slimes do not waste fluids?
            //if (xxx.is_slime(giver)) return;

            //determine entity:
            int entityType = SemenHelper.CUM_NORMAL;

            if (xxx.is_mechanoid(giver))
            {
                entityType = SemenHelper.CUM_MECHA;
            }
            else if (xxx.is_insect(giver))
            {
                entityType = SemenHelper.CUM_INSECT;
            }

            //get pawn genitalia:
            BodyPartRecord genitals;

            if (xxx.is_mechanoid(giver))
            {
                genitals = giver.RaceProps.body.AllParts.Find(x => string.Equals(x.def.defName, "MechGenitals"));
            }
            else            //insects, animals, humans
            {
                genitals = giver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.genitalsDef);
            }
            //no cum without genitals
            if (genitals == null)
            {
                return;
            }

            float cumAmount = giver.BodySize;                                         //fallback for mechanoinds and w/e without hediffs
            float horniness = 1f;
            float ageScale  = Math.Min(80 / SexUtility.ScaleToHumanAge(giver), 1.0f); //calculation lifted from rjw

            if (xxx.is_mechanoid(giver) && giverparts.NullOrEmpty())
            {
                //use default above
            }
            else if (giverparts.NullOrEmpty())
            {
                return;
            }
            else
            {
                var penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("penis")).InRandomOrder().FirstOrDefault();

                if (penisHediff == null)
                {
                    penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("ovipositorf")).InRandomOrder().FirstOrDefault();
                }
                if (penisHediff == null)
                {
                    penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("ovipositorm")).InRandomOrder().FirstOrDefault();
                }
                if (penisHediff == null)
                {
                    penisHediff = giverparts.FindAll((Hediff hed) => hed.def.defName.ToLower().Contains("tentacle")).InRandomOrder().FirstOrDefault();
                }

                if (penisHediff != null)
                {
                    cumAmount = penisHediff.Severity * giver.BodySize;

                    CompHediffBodyPart chdf = penisHediff.TryGetComp <rjw.CompHediffBodyPart>();
                    if (chdf != null)
                    {
                        cumAmount = chdf.FluidAmmount * chdf.FluidModifier;
                    }

                    Need sexNeed = giver?.needs?.AllNeeds.Find(x => string.Equals(x.def.defName, "Sex"));
                    if (sexNeed != null)                    //non-humans don't have it - therefore just use the default value
                    {
                        horniness = 1f - sexNeed.CurLevel;
                    }
                }
                else
                {
                    //something is wrong... v****a?
                    return;
                }
            }

            cumAmount  = cumAmount * horniness * ageScale * RJWSettings.cum_on_body_amount_adjust;
            cumAmount /= 100;

            //TODO: SemenHelper Autofellatio
            //if no partner -> masturbation, apply some cum on self:
            //if (partner == null && sextype == xxx.rjwSextype.Autofellatio)
            //{
            //	if (!xxx.is_slime(giver))
            //		SemenHelper.cumOn(giver, BodyPartDefOf.Jaw, cumAmount, giver);
            //	return;
            //}
            if (partner == null && sextype == xxx.rjwSextype.Masturbation)
            {
                if (!xxx.is_slime(giver))
                {
                    SemenHelper.cumOn(giver, genitals, cumAmount * 0.3f, giver);                    //pawns are usually not super-messy -> only apply 30%
                }
                return;
            }
            else if (partner != null)
            {
                List <BodyPartRecord>        targetParts    = new List <BodyPartRecord>(); //which to apply s***n on
                IEnumerable <BodyPartRecord> availableParts = SemenHelper.getAvailableBodyParts(receiver);
                BodyPartRecord randomPart;                                                 //not always needed

                switch (sextype)
                {
                case rjw.xxx.rjwSextype.Anal:
                    targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.anusDef));
                    break;

                case rjw.xxx.rjwSextype.Boobjob:
                    targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.chestDef));
                    break;

                case rjw.xxx.rjwSextype.DoublePenetration:
                    targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.anusDef));
                    targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.genitalsDef));
                    break;

                case rjw.xxx.rjwSextype.Fingering:
                    cumAmount = 0;
                    break;

                case rjw.xxx.rjwSextype.Fisting:
                    cumAmount = 0;
                    break;

                case rjw.xxx.rjwSextype.Footjob:
                    //random part:
                    availableParts.TryRandomElement <BodyPartRecord>(out randomPart);
                    targetParts.Add(randomPart);
                    break;

                case rjw.xxx.rjwSextype.Handjob:
                    //random part:
                    availableParts.TryRandomElement <BodyPartRecord>(out randomPart);
                    targetParts.Add(randomPart);
                    break;

                case rjw.xxx.rjwSextype.Masturbation:
                    cumAmount *= 2f;
                    break;

                case rjw.xxx.rjwSextype.MechImplant:
                    //one of the openings:
                    int random = Rand.Range(0, 3);
                    if (random == 0)
                    {
                        targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.genitalsDef));
                    }
                    else if (random == 1)
                    {
                        targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.anusDef));
                    }
                    else if (random == 2)
                    {
                        targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == BodyPartDefOf.Jaw));
                    }
                    break;

                case rjw.xxx.rjwSextype.MutualMasturbation:
                    //random
                    availableParts.TryRandomElement <BodyPartRecord>(out randomPart);
                    targetParts.Add(randomPart);
                    break;

                case rjw.xxx.rjwSextype.None:
                    cumAmount = 0;
                    break;

                case rjw.xxx.rjwSextype.Oral:
                    targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == BodyPartDefOf.Jaw));
                    break;

                case rjw.xxx.rjwSextype.Scissoring:
                    //I guess if it came to here, a male must be involved?
                    targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.genitalsDef));
                    break;

                case rjw.xxx.rjwSextype.Vaginal:
                    targetParts.Add(receiver.RaceProps.body.AllParts.Find(x => x.def == SemenHelper.genitalsDef));
                    break;
                }

                if (cumAmount > 0)
                {
                    if (xxx.is_slime(receiver))
                    {
                        //slime absorb cum
                        //this needs balancing, since cumamount ranges 0-10(?) which is fine for cum/hentai but not very realistic for feeding
                        //using TransferNutrition for now
                        //Log.Message("cumAmount " + cumAmount);
                        //float nutrition_amount = cumAmount/10;

                        Need_Food need = need = giver.needs.TryGetNeed <Need_Food>();
                        if (need == null)
                        {
                            //Log.Message("xxx::TransferNutrition() " + xxx.get_pawnname(pawn) + " doesn't track nutrition in itself, probably shouldn't feed the others");
                            return;
                        }

                        if (receiver?.needs?.TryGetNeed <Need_Food>() != null)
                        {
                            //Log.Message("xxx::TransferNutrition() " +  xxx.get_pawnname(partner) + " can receive");
                            float nutrition_amount = Math.Min(need.MaxLevel / 15f, need.CurLevel);                             //body size is taken into account implicitly by need.MaxLevel
                            receiver.needs.food.CurLevel += nutrition_amount;
                        }
                    }
                    else
                    {
                        SemenHelper.cumOn(giver, genitals, cumAmount * 0.3f, giver, entityType);                        //cum on self - smaller amount
                        foreach (BodyPartRecord bpr in targetParts)
                        {
                            if (bpr != null)
                            {
                                SemenHelper.cumOn(receiver, bpr, cumAmount, giver, entityType);                                //cum on partner
                            }
                        }
                    }
                }
            }
        }