コード例 #1
0
        private static void DoTendPrefix(Pawn doctor, Pawn patient, ref Medicine medicine, Medicine __state)
        {
            if (QOLTweaksPack.BruiseWalkingOff.Value == false)
            {
                return;
            }

            //Log.Message("tending prefix");
            if (medicine == null || doctor == null || patient == null || doctor.Faction.IsPlayer == false)
            {
                return;
            }



            List <Hediff> tmpHediffsToTend = new List <Hediff>();

            TendUtility.GetOptimalHediffsToTendWithSingleTreatment(patient, true, tmpHediffsToTend, null);

            foreach (Hediff tendable in tmpHediffsToTend)
            {
                //Log.Message("tending " + tendable.GetType().ToString());
                if (!(tendable is Hediff_Injury))
                {
                    return;
                }
                Hediff_Injury injury = (tendable as Hediff_Injury);
                if (injury.Bleeding)
                {
                    //Log.Message("is bleeding");
                    return;
                }
                if (injury.TryGetComp <HediffComp_Infecter>() != null)
                {
                    //Log.Message("has infecter");
                    return;
                }
                if (injury.TryGetComp <HediffComp_GetsOld>() != null)
                {
                    //Log.Message("has scarring");
                    return;
                }
                //Log.Message("match");
            }

            __state  = medicine;
            medicine = null;
        }
コード例 #2
0
        public virtual void Repair(Building_RepairStation repairStation)
        {
            List <Hediff_Injury>      allInjuries     = health.hediffSet.GetHediffs <Hediff_Injury>().ToList();
            List <Hediff_MissingPart> allMissingParts = health.hediffSet.GetHediffs <Hediff_MissingPart>().ToList();


            float num = Rand.Value;

            if ((allInjuries.Count == 0 || num > 0.6) && allMissingParts.Count > 0 && repairStation != null &&
                repairStation.HasEnoughOf(repairStation.Def.repairThingDef, repairStation.Def.repairCostAmount))
            {
                Hediff_MissingPart hediff = allMissingParts.RandomElement();
                if (repairStation.TakeSomeOf(repairStation.Def.repairThingDef, repairStation.Def.repairCostAmount))
                {
                    health.hediffSet.RestorePart(hediff.Part.HighestMissingPart(this));
                }
            }
            else if (allInjuries.Count > 0)
            {
                Hediff_Injury hediff = allInjuries.RandomElement();
                if (hediff.def.injuryProps.fullyHealableOnlyByTreatment)
                {
                    HediffComp_Treatable treatable = hediff.TryGetComp <HediffComp_Treatable>();
                    if (treatable != null && !treatable.treatedWithMedicine)
                    {
                        treatable.NewlyTreated(1f, ThingDefOf.Medicine);
                    }
                }
                hediff.DirectHeal(repairStation.Def.repairAmount);
            }
        }
コード例 #3
0
        // Token: 0x06004B89 RID: 19337 RVA: 0x002347B4 File Offset: 0x00232BB4
        protected float FinalizeAndAddInjury(Pawn pawn, float totalDamage, DamageInfo dinfo, DamageWorker.DamageResult result)
        {
            if (pawn.health.hediffSet.PartIsMissing(dinfo.HitPart))
            {
                return(0f);
            }
            HediffDef     hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart);
            Hediff_Injury hediff_Injury       = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null);

            hediff_Injury.Part   = dinfo.HitPart;
            hediff_Injury.source = dinfo.Weapon;
            hediff_Injury.sourceBodyPartGroup = dinfo.WeaponBodyPartGroup;
            hediff_Injury.sourceHediffDef     = dinfo.WeaponLinkedHediff;
            hediff_Injury.Severity            = totalDamage;
            if (dinfo.InstantPermanentInjury)
            {
                HediffComp_GetsPermanent hediffComp_GetsPermanent = hediff_Injury.TryGetComp <HediffComp_GetsPermanent>();
                if (hediffComp_GetsPermanent != null)
                {
                    hediffComp_GetsPermanent.IsPermanent = true;
                }
                else
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Tried to create instant permanent injury on Hediff without a GetsPermanent comp: ",
                        hediffDefFromDamage,
                        " on ",
                        pawn
                    }), false);
                }
            }
            return(this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, result));
        }
コード例 #4
0
        private void CalculateOldInjuryDamageThreshold(Pawn pawn, Hediff_Injury injury)
        {
            HediffCompProperties hediffCompProperties = injury.def.CompPropsFor(typeof(HediffComp_GetsOld));

            if (hediffCompProperties == null)
            {
                return;
            }
            if (injury.Part.def.IsSolid(injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(injury.Part) || injury.IsOld() || injury.Part.def.oldInjuryBaseChance < 1E-05f)
            {
                return;
            }
            bool isDelicate = injury.Part.def.IsDelicate;

            if ((Rand.Value <= injury.Part.def.oldInjuryBaseChance * hediffCompProperties.becomeOldChance && injury.Severity >= injury.Part.def.GetMaxHealth(pawn) * 0.25f && injury.Severity >= 7f) || isDelicate)
            {
                HediffComp_GetsOld hediffComp_GetsOld = injury.TryGetComp <HediffComp_GetsOld>();
                float num  = 1f;
                float num2 = injury.Severity / 2f;
                if (num <= num2)
                {
                    hediffComp_GetsOld.oldDamageThreshold = Rand.Range(num, num2);
                }
                if (isDelicate)
                {
                    hediffComp_GetsOld.oldDamageThreshold = injury.Severity;
                    hediffComp_GetsOld.IsOld = true;
                }
            }
        }
コード例 #5
0
        private void CalculateOldInjuryDamageThreshold(Pawn pawn, Hediff_Injury injury)
        {
            HediffComp_GetsOld comp = injury.TryGetComp <HediffComp_GetsOld>();

            if (comp == null)
            {
                return;
            }
            // No permanent injuries on solid parts, prosthetics or injuries that are already old
            if (injury.Part.def.IsSolid(injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(injury.Part) || injury.IsOld())
            {
                return;
            }

            // Delicate parts get old instantly
            if (injury.Part.def.IsDelicate)
            {
                comp.oldDamageThreshold = injury.Severity;
                comp.IsOld = true;
            }
            // Check if injury is at least 10% of part health and make a random roll
            else if (injury.Severity >= injury.Part.def.GetMaxHealth(pawn) * 0.1f && injury.Severity > 1)
            {
                float getOldChance = injury.Part.def.oldInjuryBaseChance * comp.Props.becomeOldChance * Mathf.Pow((injury.Severity / injury.Part.def.GetMaxHealth(pawn)), 2);
                if (Rand.Value < getOldChance)
                {
                    comp.oldDamageThreshold = Rand.Range(1, injury.Severity);
                }
            }
        }
コード例 #6
0
        //
        // Static Methods
        //
        public static void GenerateRandomOldAgeInjuries(Pawn pawn, bool tryNotToKillPawn)
        {
            int num = 0;

            for (int i = 10; i < Mathf.Min(pawn.ageTracker.AgeBiologicalYears, 120); i += 10)
            {
                if (Rand.Value < 0.15f)
                {
                    num++;
                }
            }
            for (int j = 0; j < num; j++)
            {
                IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined)
                                                      where x.depth == BodyPartDepth.Outside && !Mathf.Approximately(x.def.oldInjuryBaseChance, 0f) && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x)
                                                      select x;
                if (source.Any <BodyPartRecord>())
                {
                    BodyPartRecord bodyPartRecord      = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs);
                    DamageDef      dam                 = AgeInjuryUtility.RandomOldInjuryDamageType(bodyPartRecord.def.frostbiteVulnerability > 0f && pawn.RaceProps.ToolUser);
                    HediffDef      hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dam, pawn, bodyPartRecord);
                    if (bodyPartRecord.def.oldInjuryBaseChance > 0f && hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsOld)) != null)
                    {
                        if (Rand.Chance(bodyPartRecord.def.amputateIfGeneratedInjuredChance))
                        {
                            Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null);
                            hediff_MissingPart.lastInjury = hediffDefFromDamage;
                            hediff_MissingPart.TryGetComp <HediffComp_GetsOld>().IsOld = true;
                            pawn.health.AddHediff(hediff_MissingPart, bodyPartRecord, null);
                            if (pawn.RaceProps.Humanlike && (bodyPartRecord.def == BodyPartDefOf.LeftLeg || bodyPartRecord.def == BodyPartDefOf.RightLeg) && Rand.Chance(0.5f))
                            {
                                RecipeDefOf.InstallPegLeg.Worker.ApplyOnPawn(pawn, bodyPartRecord, null, AgeInjuryUtility.emptyIngredientsList, null);
                            }
                        }
                        else
                        {
                            Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null);
                            hediff_Injury.Severity = (float)Rand.RangeInclusive(2, 6);
                            hediff_Injury.TryGetComp <HediffComp_GetsOld>().IsOld = true;
                            pawn.health.AddHediff(hediff_Injury, bodyPartRecord, null);
                        }
                    }
                }
            }
            for (int k = 1; k < pawn.ageTracker.AgeBiologicalYears; k++)
            {
                foreach (HediffGiver_Birthday current in AgeInjuryUtility.RandomHediffsToGainOnBirthday(pawn, k))
                {
                    current.TryApplyAndSimulateSeverityChange(pawn, (float)k, tryNotToKillPawn);
                    if (pawn.Dead)
                    {
                        break;
                    }
                }
                if (pawn.Dead)
                {
                    break;
                }
            }
        }
コード例 #7
0
        // Self healing
        //private int timerRepairDamage = 0;
        private void TryHealDamagedBodyPartOfRobot(X2_AIRobot robot)
        {
            //timerRepairDamage--;
            //if (timerRepairDamage > 0)
            //    return;
            //timerRepairDamage = 300;

            if (robot == null || !Verse.Gen.IsHashIntervalTick(robot, 300))
            {
                return;
            }


            IEnumerable <Hediff_Injury> hediff_injuries = (from x in robot.health.hediffSet.GetHediffs <Hediff_Injury>()
                                                           where x.CanHealFromTending() || x.CanHealNaturally()
                                                           select x);


            // Apply Treated, but not healing!
            if (robot.health.HasHediffsNeedingTend(false))
            {
                float quality       = (Rand.Value);
                int   batchPosition = 0;
                foreach (Hediff_Injury injury in from x in robot.health.hediffSet.GetInjuriesTendable()
                         orderby x.Severity descending
                         select x)
                {
                    injury.Tended(quality, batchPosition);
                    batchPosition++;
                    if (batchPosition >= 1)
                    {
                        break;
                    }
                }
            }

            // Apply healing
            if (hediff_injuries != null && hediff_injuries.Count() > 0)
            {
                Hediff_Injury hediff_Injury2 = hediff_injuries.RandomElement();

                float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality;
                float num2        = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality));

                ////hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.01f); -> At quality 0.5 --> 0.066 healed.
                //Log.Error("Calculation: " + (GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)).ToString()));
                //Log.Error("Healing: " + (22f * num2 * robot.HealthScale * 0.1f).ToString());
                //Log.Error("PRE:" + hediff_Injury2.Severity.ToString());

                //hediff_Injury2.Heal(1f);
                hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.1f * 0.5f);

                //Log.Error("POST:" + hediff_Injury2.Severity.ToString());

                // Throw Healing Mote
                MoteMaker.ThrowMetaIcon(this.Position, this.Map, ThingDefOf.Mote_HealingCross);
            }
        }
コード例 #8
0
        // Self healing
        private void DoHealDamagedBodyPart(bool enhancedAI)
        {
            IEnumerable <Hediff> notTendedBodyParts = (from x in this.health.hediffSet.hediffs
                                                       where (x is Hediff_Injury) && x.TendableNow(false)        //!(x is Hediff_MissingPart) && x.CanHealFromTending() && !x.IsTended()
                                                       select x);

            IEnumerable <Hediff_Injury> hediff_injuries = (from x in this.health.hediffSet.GetHediffs <Hediff_Injury>()
                                                           where x.CanHealFromTending() || x.CanHealNaturally()
                                                           select x);

            if (notTendedBodyParts.Count() == 0)  // && hediff_injuries.Count() == 0)
            {
                // Nothing to heal/tend, check for missing body parts next
                DoHealMissingBodyPart(enhancedAI);
                return;
            }


            // Apply Treated, but not healing!
            if (this.health.HasHediffsNeedingTend(false))
            {
                float quality       = (enhancedAI ? 1.0f : Rand.Value);
                int   batchPosition = 0;
                foreach (Hediff_Injury injury in from x in this.health.hediffSet.GetInjuriesTendable()
                         orderby x.Severity descending
                         select x)
                {
                    injury.Tended(quality, 1f, batchPosition);
                    batchPosition++;
                    if (batchPosition >= (IsInBed(Map) ? 3 : 1))
                    {
                        break;
                    }
                }
            }

            // No additional healing while in bed (it heals by itself here)
            if (IsInBed(Map))
            {
                return;
            }


            if (hediff_injuries != null && hediff_injuries.Count() > 0)
            {
                Hediff_Injury hediff_Injury2 = hediff_injuries.RandomElement <Hediff_Injury>();

                float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality;
                float num2        = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality));
                hediff_Injury2.Heal(22f * num2 * this.HealthScale * 0.01f * (enhancedAI ? 2 : 1));
            }
        }
コード例 #9
0
        // Token: 0x06004B8A RID: 19338 RVA: 0x0023489C File Offset: 0x00232C9C
        protected float FinalizeAndAddInjury(Pawn pawn, Hediff_Injury injury, DamageInfo dinfo, DamageWorker.DamageResult result)
        {
            HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>();

            if (hediffComp_GetsPermanent != null)
            {
                hediffComp_GetsPermanent.PreFinalizeInjury();
            }
            pawn.health.AddHediff(injury, null, new DamageInfo?(dinfo), result);
            float num = Mathf.Min(injury.Severity, pawn.health.hediffSet.GetPartHealth(injury.Part));

            result.totalDamageDealt += num;
            result.wounded           = true;
            result.AddPart(pawn, injury.Part);
            result.AddHediff(injury);
            return(num);
        }
コード例 #10
0
        //
        // Static Methods
        //
        public static void GenerateRandomOldAgeInjuries(Pawn pawn, bool tryNotToKillPawn)
        {
            int num = 0;

            for (int i = 10; i < pawn.ageTracker.AgeBiologicalYears; i += 10)
            {
                if (Rand.Value < 0.15)
                {
                    num++;
                }
            }
            for (int j = 0; j < num; j++)
            {
                DamageDef dam  = AgeInjuryUtility.RandomOldInjuryDamageType();
                int       num2 = Rand.RangeInclusive(2, 6);
                IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined)
                                                      where x.depth == BodyPartDepth.Outside && !Mathf.Approximately(x.def.oldInjuryBaseChance, 0) && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x)
                                                      select x;
                if (source.Any <BodyPartRecord>())
                {
                    BodyPartRecord bodyPartRecord      = source.RandomElementByWeight((BodyPartRecord x) => x.absoluteFleshCoverage);
                    HediffDef      hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dam, pawn, bodyPartRecord);
                    if (bodyPartRecord.def.oldInjuryBaseChance > 0 && hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsOld)) != null)
                    {
                        Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null);
                        hediff_Injury.Severity = (float)num2;
                        hediff_Injury.TryGetComp <HediffComp_GetsOld>().IsOld = true;
                        pawn.health.AddHediff(hediff_Injury, bodyPartRecord, null);
                    }
                }
            }
            for (int k = 1; k < pawn.ageTracker.AgeBiologicalYears; k++)
            {
                foreach (HediffGiver_Birthday current in AgeInjuryUtility.RandomHediffsToGainOnBirthday(pawn, k))
                {
                    current.TryApplyAndSimulateSeverityChange(pawn, (float)k, tryNotToKillPawn);
                }
            }
        }
コード例 #11
0
        public bool RegenerateInjury(Pawn pawn, float amount)
        {
            var           injuries = pawn.health.hediffSet.hediffs.OfType <Hediff_Injury>().Where(x => x.Severity > 0 && x.Part != null);
            Hediff_Injury injury   = injuries.RandomElementWithFallback();

            if (injury == null)
            {
                return(false);
            }

            HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>();

            if (hediffComp_GetsPermanent != null)
            {
                hediffComp_GetsPermanent.IsPermanent = false;
            }

            injury.Severity = Mathf.Max(injury.Severity - amount);
            pawn.health.hediffSet.DirtyCache();

            RadiologyEffectSpawnerDef.Spawn(effectRegeneration, pawn);
            return(true);
        }
コード例 #12
0
        public bool RegenerateInjury()
        {
            var           permanentInjuries = pawn.health.hediffSet.hediffs.OfType <Hediff_Injury>().Where(x => x.IsPermanent() && x.Part != null);
            Hediff_Injury injury            = permanentInjuries.RandomElementWithFallback();

            if (injury == null)
            {
                return(false);
            }

            HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>();

            if (hediffComp_GetsPermanent == null)
            {
                return(false);
            }

            hediffComp_GetsPermanent.IsPermanent = false;
            injury.Severity = injury.Part.def.hitPoints - 1;
            pawn.health.hediffSet.DirtyCache();

            RadiologyEffectSpawnerDef.Spawn(def.effectRegeneration, pawn);
            return(true);
        }
コード例 #13
0
        /// <summary>
        /// Handles damage and armor calculations
        /// </summary>
        /// <param name="dinfo"></param>
        /// <param name="pawn"></param>
        /// <param name="result"></param>
        private void ApplyDamagePartial(DamageInfo dinfo, Pawn pawn, ref DamageWorker_AddInjuryCR.LocalInjuryResult result)
        {
            BodyPartRecord exactPartFromDamageInfo = DamageWorker_AddInjuryCR.GetExactPartFromDamageInfo(dinfo, pawn);

            if (exactPartFromDamageInfo == null)
            {
                return;
            }
            bool flag = true;

            if (dinfo.InstantOldInjury)
            {
                flag = false;
            }
            int  damageAmount = dinfo.Amount;
            bool shotAbsorbed = false;

            if (!result.deflected && flag)
            {
                //damageAmount = ArmorUtility.GetAfterArmorDamage(pawn, dinfo.Amount, exactPartFromDamageInfo, dinfo.Def);
                damageAmount = Utility.GetAfterArmorDamage(pawn, dinfo.Amount, exactPartFromDamageInfo, dinfo, true, ref shotAbsorbed);
            }
            if ((double)damageAmount < 0.001)
            {
                result.deflected = true;
                return;
            }

            //Shot absorbed and converted into blunt
            if (shotAbsorbed)
            {
                result.deflected = true;
                if (dinfo.Def != Utility.absorbDamageDef)
                {
                    //Get outer parent of struck part
                    BodyPartRecord parentPart = exactPartFromDamageInfo;
                    while (parentPart != null && parentPart.parent != null && parentPart.depth != BodyPartDepth.Outside)
                    {
                        parentPart = parentPart.parent;
                    }
                    DamageInfo dinfo2 = new DamageInfo(Utility.absorbDamageDef, damageAmount, dinfo.Instigator, new BodyPartDamageInfo(parentPart, false), dinfo.Source);
                    this.ApplyDamagePartial(dinfo2, pawn, ref result);
                    return;
                }
            }

            //Creating the Hediff
            HediffDef     hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, exactPartFromDamageInfo);
            Hediff_Injury hediff_Injury       = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null);

            hediff_Injury.Part   = exactPartFromDamageInfo;
            hediff_Injury.source = dinfo.Source;
            hediff_Injury.sourceBodyPartGroup = dinfo.LinkedBodyPartGroup;
            hediff_Injury.sourceHediffDef     = dinfo.LinkedHediffDef;
            hediff_Injury.Severity            = (float)damageAmount;
            if (dinfo.InstantOldInjury)
            {
                HediffComp_GetsOld hediffComp_GetsOld = hediff_Injury.TryGetComp <HediffComp_GetsOld>();
                if (hediffComp_GetsOld != null)
                {
                    hediffComp_GetsOld.isOld = dinfo.InstantOldInjury;
                }
                else
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Tried to create instant old injury on Hediff without a GetsOld comp: ",
                        hediffDefFromDamage,
                        " on ",
                        pawn
                    }));
                }
            }
            result.wounded     = true;
            result.lastHitPart = hediff_Injury.Part;
            if (DamageWorker_AddInjuryCR.IsHeadshot(dinfo, hediff_Injury, pawn))
            {
                result.headshot = true;
            }
            if (dinfo.InstantOldInjury && (hediff_Injury.def.CompPropsFor(typeof(HediffComp_GetsOld)) == null || hediff_Injury.Part.def.oldInjuryBaseChance == 0f || hediff_Injury.Part.def.IsSolid(hediff_Injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(hediff_Injury.Part)))
            {
                return;
            }
            this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result);
            this.CheckPropagateDamageToInnerSolidParts(dinfo, pawn, hediff_Injury, flag, ref result);
            this.CheckDuplicateDamageToOuterParts(dinfo, pawn, hediff_Injury, flag, ref result);
        }
コード例 #14
0
 private void CalculateOldInjuryDamageThreshold(Pawn pawn, Hediff_Injury injury)
 {
     HediffCompProperties hediffCompProperties = injury.def.CompPropsFor(typeof(HediffComp_GetsOld));
     if (hediffCompProperties == null)
     {
         return;
     }
     if (injury.Part.def.IsSolid(injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(injury.Part) || injury.IsOld() || injury.Part.def.oldInjuryBaseChance < 1E-05f)
     {
         return;
     }
     bool flag = injury.Part.def.oldInjuryBaseChance >= 0.8f;
     if ((Rand.Value <= injury.Part.def.oldInjuryBaseChance * hediffCompProperties.becomeOldChance && injury.Severity >= injury.Part.def.GetMaxHealth(pawn) * 0.25f && injury.Severity >= 7f) || flag)
     {
         HediffComp_GetsOld hediffComp_GetsOld = injury.TryGetComp<HediffComp_GetsOld>();
         float num = 1f;
         float num2 = injury.Severity / 2f;
         if (num <= num2)
         {
             hediffComp_GetsOld.oldDamageThreshold = Rand.Range(num, num2);
         }
         if (flag)
         {
             hediffComp_GetsOld.oldDamageThreshold = injury.Severity;
             hediffComp_GetsOld.isOld = true;
         }
     }
 }
コード例 #15
0
        private void ApplyDamagePartial(DamageInfo dinfo, Pawn pawn, ref DamageWorker_AddInjuryCR.LocalInjuryResult result)
        {
            BodyPartRecord exactPartFromDamageInfo = DamageWorker_AddInjuryCR.GetExactPartFromDamageInfo(dinfo, pawn);

            if (exactPartFromDamageInfo == null)
            {
                return;
            }

            // Only apply armor if we propagate damage to the outside or the body part itself is outside, secondary damage types should directly damage organs, bypassing armor
            bool involveArmor = !dinfo.InstantOldInjury &&
                                !result.deflected &&
                                (dinfo.Def.harmAllLayersUntilOutside || exactPartFromDamageInfo.depth == BodyPartDepth.Outside);
            int damageAmount = dinfo.Amount;

            if (involveArmor)
            {
                damageAmount = Utility.GetAfterArmorDamage(pawn, dinfo.Amount, exactPartFromDamageInfo, dinfo, true, ref result.deflected);
            }
            if ((double)damageAmount < 0.001)
            {
                result.absorbed = true;
                return;
            }

            // Shot absorbed and converted into blunt
            DamageDef_CR damageDefCR = dinfo.Def as DamageDef_CR;

            if (damageDefCR != null &&
                damageDefCR.deflectable &&
                result.deflected &&
                dinfo.Def != Utility.absorbDamageDef)
            {
                // Get outer parent of struck part
                BodyPartRecord currentPart = exactPartFromDamageInfo;
                while (currentPart != null && currentPart.parent != null && currentPart.depth != BodyPartDepth.Outside)
                {
                    currentPart = currentPart.parent;
                }
                DamageInfo dinfo2 = new DamageInfo(Utility.absorbDamageDef, damageAmount, dinfo.Instigator, new BodyPartDamageInfo(currentPart, false), dinfo.Source);
                this.ApplyDamagePartial(dinfo2, pawn, ref result);
                return;
            }

            //Creating the Hediff
            HediffDef     hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, exactPartFromDamageInfo);
            Hediff_Injury hediff_Injury       = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null);

            hediff_Injury.Part   = exactPartFromDamageInfo;
            hediff_Injury.source = dinfo.Source;
            hediff_Injury.sourceBodyPartGroup = dinfo.LinkedBodyPartGroup;
            hediff_Injury.sourceHediffDef     = dinfo.LinkedHediffDef;
            hediff_Injury.Severity            = (float)damageAmount;
            if (dinfo.InstantOldInjury)
            {
                HediffComp_GetsOld hediffComp_GetsOld = hediff_Injury.TryGetComp <HediffComp_GetsOld>();
                if (hediffComp_GetsOld != null)
                {
                    hediffComp_GetsOld.IsOld = true;
                }
                else
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Tried to create instant old injury on Hediff without a GetsOld comp: ",
                        hediffDefFromDamage,
                        " on ",
                        pawn
                    }));
                }
            }
            result.wounded     = true;
            result.lastHitPart = hediff_Injury.Part;
            if (DamageWorker_AddInjuryCR.IsHeadshot(dinfo, hediff_Injury, pawn))
            {
                result.headshot = true;
            }
            if (dinfo.InstantOldInjury && (hediff_Injury.def.CompPropsFor(typeof(HediffComp_GetsOld)) == null || hediff_Injury.Part.def.oldInjuryBaseChance == 0f || hediff_Injury.Part.def.IsSolid(hediff_Injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(hediff_Injury.Part)))
            {
                return;
            }
            this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result);
            this.CheckPropagateDamageToInnerSolidParts(dinfo, pawn, hediff_Injury, !dinfo.InstantOldInjury, damageAmount, ref result);
            this.CheckDuplicateDamageToOuterParts(dinfo, pawn, hediff_Injury, !dinfo.InstantOldInjury, damageAmount, ref result);
        }
コード例 #16
0
        public static void roll_for_syphilis_damage(Pawn p)
        {
            Hediff syp = p.health.hediffSet.GetFirstHediffOfDef(std.syphilis.hediff_def);

            if (syp == null || !(syp.Severity >= 0.60f) || syp.FullyImmune())
            {
                return;
            }

            // A 30% chance per day of getting any permanent damage works out to ~891 in 1 million for each roll
            // The equation is (1-x)^(60000/150)=.7
            // Important Note:
            // this function is called from Need_Sex::NeedInterval(), where it involves a needsex_tick and a std_tick to actually trigger this roll_for_syphilis_damage.
            // j(this is not exactly the same as the value in Need_Sex, that value is 0, but here j should be 1) std_ticks per this function called, k needsex_ticks per std_tick, 150 ticks per needsex_tick, and x is the chance per 150 ticks,
            // The new equation should be .7 = (1-x)^(400/kj)
            // 1-x = .7^(kj/400), x =1-.7^(kj/400)
            // Since k=10,j=1, so kj=10, new x is 1-.7^(10/400)=0.0088772362, let it be 888/100000
            //Rand.PopState();
            //Rand.PushState(RJW_Multiplayer.PredictableSeed());
            if (Rand.RangeInclusive(1, 100000) <= 888)
            {
                BodyPartRecord part;
                float          sev;
                var            parts = p.RaceProps.body.AllParts;

                float rv = Rand.Value;
                if (rv < 0.10f)
                {
                    part = parts.Find(bpr => string.Equals(bpr.def.defName, "Brain"));
                    sev  = 1.0f;
                }
                else if (rv < 0.50f)
                {
                    part = parts.Find(bpr => string.Equals(bpr.def.defName, "Liver"));
                    sev  = Rand.RangeInclusive(1, 3);
                }
                else if (rv < 0.75f)
                {
                    //LeftKidney, probably
                    part = parts.Find(bpr => string.Equals(bpr.def.defName, "Kidney"));
                    sev  = Rand.RangeInclusive(1, 2);
                }
                else
                {
                    //RightKidney, probably
                    part = parts.FindLast(bpr => string.Equals(bpr.def.defName, "Kidney"));
                    sev  = Rand.RangeInclusive(1, 2);
                }

                if (part != null && !p.health.hediffSet.PartIsMissing(part) && !p.health.hediffSet.HasDirectlyAddedPartFor(part))
                {
                    DamageDef vir_dam = DefDatabase <DamageDef> .GetNamed("ViralDamage");

                    HediffDef     dam_def = HealthUtility.GetHediffDefFromDamage(vir_dam, p, part);
                    Hediff_Injury inj     = (Hediff_Injury)HediffMaker.MakeHediff(dam_def, p, null);
                    inj.Severity = sev;
                    inj.TryGetComp <HediffComp_GetsPermanent>().IsPermanent = true;
                    p.health.AddHediff(inj, part, null);
                    string message_title = std.syphilis.label + " Damage";
                    string baby_pronoun  = p.gender == Gender.Male ? "his" : "her";
                    string message_text  = "RJW_Syphilis_Damage_Message".Translate(xxx.get_pawnname(p), baby_pronoun, part.def.label, std.syphilis.label);
                    Find.LetterStack.ReceiveLetter(message_title, message_text, LetterDefOf.ThreatSmall, p);
                }
            }
        }
コード例 #17
0
        public static void GenerateRandomOldAgeInjuries(Pawn pawn, bool tryNotToKillPawn)
        {
            float num    = (!pawn.RaceProps.IsMechanoid) ? pawn.RaceProps.lifeExpectancy : 2500f;
            float num2   = num / 8f;
            float b      = num * 1.5f;
            float chance = (!pawn.RaceProps.Humanlike) ? 0.03f : 0.15f;
            int   num3   = 0;

            for (float num4 = num2; num4 < Mathf.Min((float)pawn.ageTracker.AgeBiologicalYears, b); num4 += num2)
            {
                if (Rand.Chance(chance))
                {
                    num3++;
                }
            }
            for (int i = 0; i < num3; i++)
            {
                IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null)
                                                      where x.depth == BodyPartDepth.Outside && (x.def.permanentInjuryChanceFactor != 0f || x.def.pawnGeneratorCanAmputate) && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x)
                                                      select x;
                if (source.Any <BodyPartRecord>())
                {
                    BodyPartRecord bodyPartRecord      = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs);
                    DamageDef      dam                 = AgeInjuryUtility.RandomPermanentInjuryDamageType(bodyPartRecord.def.frostbiteVulnerability > 0f && pawn.RaceProps.ToolUser);
                    HediffDef      hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dam, pawn, bodyPartRecord);
                    if (bodyPartRecord.def.pawnGeneratorCanAmputate && Rand.Chance(0.3f))
                    {
                        Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null);
                        hediff_MissingPart.lastInjury = hediffDefFromDamage;
                        hediff_MissingPart.Part       = bodyPartRecord;
                        hediff_MissingPart.IsFresh    = false;
                        if (!tryNotToKillPawn || !pawn.health.WouldDieAfterAddingHediff(hediff_MissingPart))
                        {
                            pawn.health.AddHediff(hediff_MissingPart, bodyPartRecord, null, null);
                            if (pawn.RaceProps.Humanlike && bodyPartRecord.def == BodyPartDefOf.Leg && Rand.Chance(0.5f))
                            {
                                RecipeDefOf.InstallPegLeg.Worker.ApplyOnPawn(pawn, bodyPartRecord, null, AgeInjuryUtility.emptyIngredientsList, null);
                            }
                        }
                    }
                    else if (bodyPartRecord.def.permanentInjuryChanceFactor > 0f && hediffDefFromDamage.HasComp(typeof(HediffComp_GetsPermanent)))
                    {
                        Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null);
                        hediff_Injury.Severity = (float)Rand.RangeInclusive(2, 6);
                        hediff_Injury.TryGetComp <HediffComp_GetsPermanent>().IsPermanent = true;
                        hediff_Injury.Part = bodyPartRecord;
                        if (!tryNotToKillPawn || !pawn.health.WouldDieAfterAddingHediff(hediff_Injury))
                        {
                            pawn.health.AddHediff(hediff_Injury, bodyPartRecord, null, null);
                        }
                    }
                }
            }
            for (int j = 1; j < pawn.ageTracker.AgeBiologicalYears; j++)
            {
                foreach (HediffGiver_Birthday hediffGiver_Birthday in AgeInjuryUtility.RandomHediffsToGainOnBirthday(pawn, j))
                {
                    hediffGiver_Birthday.TryApplyAndSimulateSeverityChange(pawn, (float)j, tryNotToKillPawn);
                    if (pawn.Dead)
                    {
                        break;
                    }
                }
                if (pawn.Dead)
                {
                    break;
                }
            }
        }
コード例 #18
0
        public static bool HealthTick(Pawn_HealthTracker __instance)
        {
            if (__instance.Dead)
            {
                return(false);
            }
            for (int index = __instance.hediffSet.hediffs.Count - 1; index >= 0; --index)
            {
                Hediff hediff = __instance.hediffSet.hediffs[index];
                try
                {
                    hediff.Tick();
                    hediff.PostTick();
                }
                catch (Exception ex1)
                {
                    Log.Error("Exception ticking hediff " + hediff.ToStringSafe <Hediff>() + " for pawn " + __instance.pawn.ToStringSafe <Pawn>() + ". Removing hediff... Exception: " + (object)ex1);
                    try
                    {
                        __instance.RemoveHediff(hediff);
                    }
                    catch (Exception ex2)
                    {
                        Log.Error("Error while removing hediff: " + (object)ex2);
                    }
                }
                if (__instance.Dead)
                {
                    return(false);
                }
            }
            bool flag1 = false;

            lock (__instance.hediffSet)                                                     //added
            {
                List <Hediff> newHediffs = new List <Hediff>(__instance.hediffSet.hediffs); //added
                for (int index = newHediffs.Count - 1; index >= 0; --index)                 //changed
                {
                    Hediff hediff = newHediffs[index];
                    if (hediff.ShouldRemove)
                    {
                        newHediffs.RemoveAt(index);                //changed
                        __instance.hediffSet.hediffs = newHediffs; //added
                        hediff.PostRemoved();
                        flag1 = true;
                    }
                }
            }
            if (flag1)
            {
                __instance.Notify_HediffChanged((Hediff)null);
            }
            if (__instance.Dead)
            {
                return(false);
            }
            __instance.immunity.ImmunityHandlerTick();
            if (__instance.pawn.RaceProps.IsFlesh && __instance.pawn.IsHashIntervalTick(600) && (__instance.pawn.needs.food == null || !__instance.pawn.needs.food.Starving))
            {
                bool flag2 = false;
                if (__instance.hediffSet.HasNaturallyHealingInjury())
                {
                    float num = 8f;
                    if (__instance.pawn.GetPosture() != PawnPosture.Standing)
                    {
                        num += 4f;
                        Building_Bed buildingBed = __instance.pawn.CurrentBed();
                        if (buildingBed != null)
                        {
                            num += buildingBed.def.building.bed_healPerDay;
                        }
                    }
                    foreach (Hediff hediff in __instance.hediffSet.hediffs)
                    {
                        HediffStage curStage = hediff.CurStage;
                        if (curStage != null && (double)curStage.naturalHealingFactor != -1.0)
                        {
                            num *= curStage.naturalHealingFactor;
                        }
                    }
                    __instance.hediffSet.GetHediffs <Hediff_Injury>().Where <Hediff_Injury>((Func <Hediff_Injury, bool>)(x => x.CanHealNaturally())).RandomElement <Hediff_Injury>().Heal((float)((double)num * (double)__instance.pawn.HealthScale * 0.00999999977648258) * __instance.pawn.GetStatValue(StatDefOf.InjuryHealingFactor));
                    flag2 = true;
                }
                if (__instance.hediffSet.HasTendedAndHealingInjury() && (__instance.pawn.needs.food == null || !__instance.pawn.needs.food.Starving))
                {
                    Hediff_Injury hd = __instance.hediffSet.GetHediffs <Hediff_Injury>().Where <Hediff_Injury>((Func <Hediff_Injury, bool>)(x => x.CanHealFromTending())).RandomElement <Hediff_Injury>();
                    hd.Heal((float)(8.0 * (double)GenMath.LerpDouble(0.0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(hd.TryGetComp <HediffComp_TendDuration>().tendQuality)) * (double)__instance.pawn.HealthScale * 0.00999999977648258) * __instance.pawn.GetStatValue(StatDefOf.InjuryHealingFactor));
                    flag2 = true;
                }
                if (flag2 && !__instance.HasHediffsNeedingTendByPlayer() && (!HealthAIUtility.ShouldSeekMedicalRest(__instance.pawn) && !__instance.hediffSet.HasTendedAndHealingInjury()) && PawnUtility.ShouldSendNotificationAbout(__instance.pawn))
                {
                    Messages.Message((string)"MessageFullyHealed".Translate((NamedArgument)__instance.pawn.LabelCap, (NamedArgument)(Thing)__instance.pawn), (LookTargets)(Thing)__instance.pawn, MessageTypeDefOf.PositiveEvent);
                }
            }
            if (__instance.pawn.RaceProps.IsFlesh && (double)__instance.hediffSet.BleedRateTotal >= 0.100000001490116)
            {
                float num = __instance.hediffSet.BleedRateTotal * __instance.pawn.BodySize;
                if ((double)Rand.Value < (__instance.pawn.GetPosture() != PawnPosture.Standing ? (double)(num * 0.0004f) : (double)(num * 0.004f)))
                {
                    __instance.DropBloodFilth();
                }
            }
            if (!__instance.pawn.IsHashIntervalTick(60))
            {
                return(false);
            }
            List <HediffGiverSetDef> hediffGiverSets = __instance.pawn.RaceProps.hediffGiverSets;

            if (hediffGiverSets != null)
            {
                for (int index1 = 0; index1 < hediffGiverSets.Count; ++index1)
                {
                    List <HediffGiver> hediffGivers = hediffGiverSets[index1].hediffGivers;
                    for (int index2 = 0; index2 < hediffGivers.Count; ++index2)
                    {
                        hediffGivers[index2].OnIntervalPassed(__instance.pawn, (Hediff)null);
                        if (__instance.pawn.Dead)
                        {
                            return(false);
                        }
                    }
                }
            }
            if (__instance.pawn.story == null)
            {
                return(false);
            }
            List <Trait> allTraits = __instance.pawn.story.traits.allTraits;

            for (int index = 0; index < allTraits.Count; ++index)
            {
                TraitDegreeData currentData = allTraits[index].CurrentData;
                if ((double)currentData.randomDiseaseMtbDays > 0.0 && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f))
                {
                    BiomeDef biome = __instance.pawn.Tile == -1 ? DefDatabase <BiomeDef> .GetRandom() : Find.WorldGrid[__instance.pawn.Tile].biome;

                    IncidentDef incidentDef = DefDatabase <IncidentDef> .AllDefs.Where <IncidentDef>((Func <IncidentDef, bool>)(d => d.category == IncidentCategoryDefOf.DiseaseHuman)).RandomElementByWeightWithFallback <IncidentDef>((Func <IncidentDef, float>)(d => biome.CommonalityOfDisease(d)));

                    if (incidentDef != null)
                    {
                        string      blockedInfo;
                        List <Pawn> pawns = ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle <Pawn>(__instance.pawn), out blockedInfo);
                        if (PawnUtility.ShouldSendNotificationAbout(__instance.pawn))
                        {
                            if (pawns.Contains(__instance.pawn))
                            {
                                Find.LetterStack.ReceiveLetter("LetterLabelTraitDisease".Translate((NamedArgument)incidentDef.diseaseIncident.label), "LetterTraitDisease".Translate((NamedArgument)__instance.pawn.LabelCap, (NamedArgument)incidentDef.diseaseIncident.label, __instance.pawn.Named("PAWN")).AdjustedFor(__instance.pawn), LetterDefOf.NegativeEvent, (LookTargets)(Thing)__instance.pawn);
                            }
                            else if (!blockedInfo.NullOrEmpty())
                            {
                                Messages.Message(blockedInfo, (LookTargets)(Thing)__instance.pawn, MessageTypeDefOf.NeutralEvent);
                            }
                        }
                    }
                }
            }
            return(false);
        }
コード例 #19
0
        private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, ref DamageWorker_AddInjuryCE.LocalInjuryResult result)
        {
            BodyPartRecord exactPartFromDamageInfo = GetExactPartFromDamageInfo(dinfo, pawn);

            if (exactPartFromDamageInfo == null)
            {
                return;
            }
            bool       involveArmor   = !dinfo.InstantOldInjury;
            DamageInfo postArmorDinfo = dinfo;
            bool       shieldAbsorbed = false;

            if (involveArmor)
            {
                postArmorDinfo = ArmorUtilityCE.GetAfterArmorDamage(dinfo, pawn, exactPartFromDamageInfo, out shieldAbsorbed);
                if (dinfo.ForceHitPart == null &&
                    postArmorDinfo.ForceHitPart != null &&
                    exactPartFromDamageInfo != postArmorDinfo.ForceHitPart)
                {
                    exactPartFromDamageInfo = postArmorDinfo.ForceHitPart;   // If the shot was deflected, update our body part
                    if (pawn.Spawned)
                    {
                        LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_ArmorSystem, OpportunityType.Critical);                 // Inform the player about armor deflection
                    }
                }
            }

            // Vanilla code - apply hediff
            if ((double)postArmorDinfo.Amount < 0.001)
            {
                result.deflected = true;
                return;
            }
            HediffDef     hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(postArmorDinfo.Def, pawn, exactPartFromDamageInfo);
            Hediff_Injury hediff_Injury       = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null);

            hediff_Injury.Part   = exactPartFromDamageInfo;
            hediff_Injury.source = postArmorDinfo.WeaponGear;
            hediff_Injury.sourceBodyPartGroup = postArmorDinfo.WeaponBodyPartGroup;
            hediff_Injury.sourceHediffDef     = postArmorDinfo.WeaponLinkedHediff;
            hediff_Injury.Severity            = (float)postArmorDinfo.Amount;
            if (postArmorDinfo.InstantOldInjury)
            {
                HediffComp_GetsOld hediffComp_GetsOld = hediff_Injury.TryGetComp <HediffComp_GetsOld>();
                if (hediffComp_GetsOld != null)
                {
                    hediffComp_GetsOld.IsOld = true;
                }
                else
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Tried to create instant old injury on Hediff without a GetsOld comp: ",
                        hediffDefFromDamage,
                        " on ",
                        pawn
                    }));
                }
            }
            result.wounded     = true;
            result.lastHitPart = hediff_Injury.Part;
            if (DamageWorker_AddInjuryCE.IsHeadshot(postArmorDinfo, hediff_Injury, pawn))
            {
                result.headshot = true;
            }
            if (postArmorDinfo.InstantOldInjury && (hediff_Injury.def.CompPropsFor(typeof(HediffComp_GetsOld)) == null || hediff_Injury.Part.def.oldInjuryBaseChance == 0f || hediff_Injury.Part.def.IsSolid(hediff_Injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(hediff_Injury.Part)))
            {
                return;
            }
            this.FinalizeAndAddInjury(pawn, hediff_Injury, postArmorDinfo, ref result);
            this.CheckPropagateDamageToInnerSolidParts(postArmorDinfo, pawn, hediff_Injury, involveArmor, ref result);
            this.CheckDuplicateDamageToOuterParts(postArmorDinfo, pawn, hediff_Injury, involveArmor, ref result);

            // Apply secondary damage
            if (!shieldAbsorbed)
            {
                var props = dinfo.WeaponGear?.projectile as ProjectilePropertiesCE;
                if (props != null && !props.secondaryDamage.NullOrEmpty() && dinfo.Def == props.damageDef)
                {
                    foreach (SecondaryDamage sec in props.secondaryDamage)
                    {
                        if (pawn.Dead)
                        {
                            return;
                        }
                        var secDinfo = sec.GetDinfo(postArmorDinfo);
                        secDinfo.SetForcedHitPart(exactPartFromDamageInfo);
                        pawn.TakeDamage(secDinfo);
                    }
                }
            }
        }