Пример #1
0
        public static float CalculatePartEfficiency(HediffSet diffSet, BodyPartRecord part, bool ignoreAddedParts = false, List <CapacityImpactor> impactors = null)
        {
            BodyPartRecord rec;

            for (rec = part.parent; rec != null; rec = rec.parent)
            {
                if (diffSet.HasDirectlyAddedPartFor(rec))
                {
                    Hediff_AddedPart hediff_AddedPart = (from x in diffSet.GetHediffs <Hediff_AddedPart>()
                                                         where x.Part == rec
                                                         select x).First();
                    impactors?.Add(new CapacityImpactorHediff
                    {
                        hediff = hediff_AddedPart
                    });
                    return(hediff_AddedPart.def.addedPartProps.partEfficiency);
                }
            }
            if (part.parent != null && diffSet.PartIsMissing(part.parent))
            {
                return(0f);
            }
            float num = 1f;

            if (!ignoreAddedParts)
            {
                for (int i = 0; i < diffSet.hediffs.Count; i++)
                {
                    Hediff_AddedPart hediff_AddedPart2 = diffSet.hediffs[i] as Hediff_AddedPart;
                    if (hediff_AddedPart2 != null && hediff_AddedPart2.Part == part)
                    {
                        num *= hediff_AddedPart2.def.addedPartProps.partEfficiency;
                        if (hediff_AddedPart2.def.addedPartProps.partEfficiency != 1f)
                        {
                            impactors?.Add(new CapacityImpactorHediff
                            {
                                hediff = hediff_AddedPart2
                            });
                        }
                    }
                }
            }
            float b    = -1f;
            float num2 = 0f;
            bool  flag = false;

            for (int j = 0; j < diffSet.hediffs.Count; j++)
            {
                if (diffSet.hediffs[j].Part == part && diffSet.hediffs[j].CurStage != null)
                {
                    HediffStage curStage = diffSet.hediffs[j].CurStage;
                    num2 += curStage.partEfficiencyOffset;
                    flag |= curStage.partIgnoreMissingHP;
                    if (curStage.partEfficiencyOffset != 0f && curStage.becomeVisible)
                    {
                        impactors?.Add(new CapacityImpactorHediff
                        {
                            hediff = diffSet.hediffs[j]
                        });
                    }
                }
            }
            if (!flag)
            {
                float num3 = diffSet.GetPartHealth(part) / part.def.GetMaxHealth(diffSet.pawn);
                if (num3 != 1f)
                {
                    if (DamageWorker_AddInjury.ShouldReduceDamageToPreservePart(part))
                    {
                        num3 = Mathf.InverseLerp(0.1f, 1f, num3);
                    }
                    impactors?.Add(new CapacityImpactorBodyPartHealth
                    {
                        bodyPart = part
                    });
                    num *= num3;
                }
            }
            num += num2;
            if (num > 0.0001f)
            {
                num = Mathf.Max(num, b);
            }
            return(Mathf.Max(num, 0f));
        }
Пример #2
0
 public void HealthTick()
 {
     if (!Dead)
     {
         for (int num = hediffSet.hediffs.Count - 1; num >= 0; num--)
         {
             Hediff hediff = hediffSet.hediffs[num];
             try
             {
                 hediff.Tick();
                 hediff.PostTick();
             }
             catch (Exception ex)
             {
                 Log.Error("Exception ticking hediff " + hediff.ToStringSafe() + " for pawn " + pawn.ToStringSafe() + ". Removing hediff... Exception: " + ex);
                 try
                 {
                     RemoveHediff(hediff);
                 }
                 catch (Exception arg)
                 {
                     Log.Error("Error while removing hediff: " + arg);
                 }
             }
         }
         bool flag = false;
         for (int num2 = hediffSet.hediffs.Count - 1; num2 >= 0; num2--)
         {
             Hediff hediff2 = hediffSet.hediffs[num2];
             if (hediff2.ShouldRemove)
             {
                 hediffSet.hediffs.RemoveAt(num2);
                 hediff2.PostRemoved();
                 flag = true;
             }
         }
         if (flag)
         {
             Notify_HediffChanged(null);
         }
         if (!Dead)
         {
             immunity.ImmunityHandlerTick();
             if (pawn.RaceProps.IsFlesh && pawn.IsHashIntervalTick(600) && (pawn.needs.food == null || !pawn.needs.food.Starving))
             {
                 bool flag2 = false;
                 if (hediffSet.HasNaturallyHealingInjury())
                 {
                     float num3 = 8f;
                     if (pawn.GetPosture() != 0)
                     {
                         num3 += 4f;
                         Building_Bed building_Bed = pawn.CurrentBed();
                         if (building_Bed != null)
                         {
                             num3 += building_Bed.def.building.bed_healPerDay;
                         }
                     }
                     Hediff_Injury hediff_Injury = hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealNaturally).RandomElement();
                     hediff_Injury.Heal(num3 * pawn.HealthScale * 0.01f);
                     flag2 = true;
                 }
                 if (hediffSet.HasTendedAndHealingInjury() && (pawn.needs.food == null || !pawn.needs.food.Starving))
                 {
                     Hediff_Injury hediff_Injury2 = hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealFromTending).RandomElement();
                     float         tendQuality    = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality;
                     float         num4           = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality));
                     hediff_Injury2.Heal(8f * num4 * pawn.HealthScale * 0.01f);
                     flag2 = true;
                 }
                 if (flag2 && !HasHediffsNeedingTendByPlayer() && !HealthAIUtility.ShouldSeekMedicalRest(pawn) && !hediffSet.HasTendedAndHealingInjury() && PawnUtility.ShouldSendNotificationAbout(pawn))
                 {
                     Messages.Message("MessageFullyHealed".Translate(pawn.LabelCap, pawn), pawn, MessageTypeDefOf.PositiveEvent);
                 }
             }
             if (pawn.RaceProps.IsFlesh && hediffSet.BleedRateTotal >= 0.1f)
             {
                 float num5 = hediffSet.BleedRateTotal * pawn.BodySize;
                 num5 = ((pawn.GetPosture() != 0) ? (num5 * 0.0004f) : (num5 * 0.004f));
                 if (Rand.Value < num5)
                 {
                     DropBloodFilth();
                 }
             }
             if (pawn.IsHashIntervalTick(60))
             {
                 List <HediffGiverSetDef> hediffGiverSets = pawn.RaceProps.hediffGiverSets;
                 if (hediffGiverSets != null)
                 {
                     for (int i = 0; i < hediffGiverSets.Count; i++)
                     {
                         List <HediffGiver> hediffGivers = hediffGiverSets[i].hediffGivers;
                         for (int j = 0; j < hediffGivers.Count; j++)
                         {
                             hediffGivers[j].OnIntervalPassed(pawn, null);
                             if (pawn.Dead)
                             {
                                 return;
                             }
                         }
                     }
                 }
                 if (pawn.story != null)
                 {
                     List <Trait> allTraits = pawn.story.traits.allTraits;
                     for (int k = 0; k < allTraits.Count; k++)
                     {
                         TraitDegreeData currentData = allTraits[k].CurrentData;
                         if (currentData.randomDiseaseMtbDays > 0f && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f))
                         {
                             BiomeDef biome;
                             if (pawn.Tile != -1)
                             {
                                 biome = Find.WorldGrid[pawn.Tile].biome;
                             }
                             else
                             {
                                 biome = DefDatabase <BiomeDef> .GetRandom();
                             }
                             IncidentDef incidentDef = (from d in DefDatabase <IncidentDef> .AllDefs
                                                        where d.category == IncidentCategoryDefOf.DiseaseHuman
                                                        select d).RandomElementByWeightWithFallback((IncidentDef d) => biome.CommonalityOfDisease(d));
                             if (incidentDef != null)
                             {
                                 string      blockedInfo;
                                 List <Pawn> list = ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle(pawn), out blockedInfo);
                                 if (PawnUtility.ShouldSendNotificationAbout(pawn))
                                 {
                                     if (list.Contains(pawn))
                                     {
                                         Find.LetterStack.ReceiveLetter("LetterLabelTraitDisease".Translate(incidentDef.diseaseIncident.label), "LetterTraitDisease".Translate(pawn.LabelCap, incidentDef.diseaseIncident.label, pawn.Named("PAWN")).AdjustedFor(pawn), LetterDefOf.NegativeEvent, pawn);
                                     }
                                     else if (!blockedInfo.NullOrEmpty())
                                     {
                                         Messages.Message(blockedInfo, pawn, MessageTypeDefOf.NeutralEvent);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }