protected float ReduceDamageToPreserveOutsideParts(float postArmorDamage, DamageInfo dinfo, Pawn pawn) { float result; if (!DamageWorker_AddInjury.ShouldReduceDamageToPreservePart(dinfo.HitPart)) { result = postArmorDamage; } else { float partHealth = pawn.health.hediffSet.GetPartHealth(dinfo.HitPart); if (postArmorDamage < partHealth) { result = postArmorDamage; } else { float maxHealth = dinfo.HitPart.def.GetMaxHealth(pawn); float num = postArmorDamage - partHealth; float x = num / maxHealth; float num2 = DamageWorker_AddInjury.PartBlowOffChancePerOverkillDamagePercent.Evaluate(x); if (Rand.Value < num2) { result = postArmorDamage; } else { postArmorDamage = (result = partHealth - 1f); } } } return(result); }
protected float ReduceDamageToPreserveOutsideParts(float postArmorDamage, DamageInfo dinfo, Pawn pawn) { if (DamageWorker_AddInjury.ShouldReduceDamageToPreservePart(dinfo.HitPart)) { int num = Mathf.FloorToInt(pawn.health.hediffSet.GetPartHealth(dinfo.HitPart)); if ((float)num >= 6.0 && postArmorDamage >= (float)num && postArmorDamage < (float)num * 1.8999999761581421) { postArmorDamage = (float)(num - 1); } } return(postArmorDamage); }
private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, ref DamageResult result) { BodyPartRecord exactPartFromDamageInfo = this.GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo != null) { dinfo.SetHitPart(exactPartFromDamageInfo); int num = dinfo.Amount; if (!dinfo.InstantOldInjury) { num = ArmorUtility.GetPostArmorDamage(pawn, dinfo.Amount, dinfo.HitPart, dinfo.Def); } if (num <= 0) { result.deflected = true; } else { if (DamageWorker_AddInjury.IsHeadshot(dinfo, pawn)) { result.headshot = true; } if (dinfo.InstantOldInjury) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart); if (hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsOld)) == null) { return; } if (dinfo.HitPart.def.oldInjuryBaseChance == 0.0) { return; } if (dinfo.HitPart.def.IsSolid(dinfo.HitPart, pawn.health.hediffSet.hediffs)) { return; } if (pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(dinfo.HitPart)) { return; } } if (!dinfo.AllowDamagePropagation) { this.FinalizeAndAddInjury(pawn, (float)num, dinfo, ref result); } else { this.ApplySpecialEffectsToPart(pawn, (float)num, dinfo, ref result); } } } }
private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, DamageWorker.DamageResult result) { BodyPartRecord exactPartFromDamageInfo = this.GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo != null) { dinfo.SetHitPart(exactPartFromDamageInfo); float num = dinfo.Amount; bool flag = !dinfo.InstantPermanentInjury; bool deflectedByMetalArmor = false; if (flag) { DamageDef def = dinfo.Def; bool diminishedByMetalArmor; num = ArmorUtility.GetPostArmorDamage(pawn, num, dinfo.ArmorPenetrationInt, dinfo.HitPart, ref def, out deflectedByMetalArmor, out diminishedByMetalArmor); dinfo.Def = def; if (num < dinfo.Amount) { result.diminished = true; result.diminishedByMetalArmor = diminishedByMetalArmor; } } if (num <= 0f) { result.AddPart(pawn, dinfo.HitPart); result.deflected = true; result.deflectedByMetalArmor = deflectedByMetalArmor; } else { if (DamageWorker_AddInjury.IsHeadshot(dinfo, pawn)) { result.headshot = true; } if (dinfo.InstantPermanentInjury) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart); if (hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsPermanent)) == null || dinfo.HitPart.def.permanentInjuryBaseChance == 0f || dinfo.HitPart.def.IsSolid(dinfo.HitPart, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(dinfo.HitPart)) { return; } } if (!dinfo.AllowDamagePropagation) { this.FinalizeAndAddInjury(pawn, num, dinfo, result); } else { this.ApplySpecialEffectsToPart(pawn, num, dinfo, result); } } } }
protected float ReduceDamageToPreserveOutsideParts(float postArmorDamage, DamageInfo dinfo, Pawn pawn) { if (!DamageWorker_AddInjury.ShouldReduceDamageToPreservePart(dinfo.HitPart)) { return(postArmorDamage); } float partHealth = pawn.health.hediffSet.GetPartHealth(dinfo.HitPart); if (postArmorDamage < partHealth) { return(postArmorDamage); } float maxHealth = dinfo.HitPart.def.GetMaxHealth(pawn); float num = postArmorDamage - partHealth; float f = num / maxHealth; float chance = this.def.overkillPctToDestroyPart.InverseLerpThroughRange(f); if (Rand.Chance(chance)) { return(postArmorDamage); } return(postArmorDamage = partHealth - 1f); }
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)); }
private DamageWorker.DamageResult ApplyToPawn(DamageInfo dinfo, Pawn pawn) { DamageWorker.DamageResult damageResult = new DamageWorker.DamageResult(); if (dinfo.Amount <= 0f) { return(damageResult); } if (!DebugSettings.enablePlayerDamage && pawn.Faction == Faction.OfPlayer) { return(damageResult); } Map mapHeld = pawn.MapHeld; bool spawnedOrAnyParentSpawned = pawn.SpawnedOrAnyParentSpawned; if (dinfo.AllowDamagePropagation && dinfo.Amount >= (float)dinfo.Def.minDamageToFragment) { int num = Rand.RangeInclusive(2, 4); for (int i = 0; i < num; i++) { DamageInfo dinfo2 = dinfo; dinfo2.SetAmount(dinfo.Amount / (float)num); this.ApplyDamageToPart(dinfo2, pawn, damageResult); } } else { this.ApplyDamageToPart(dinfo, pawn, damageResult); this.ApplySmallPawnDamagePropagation(dinfo, pawn, damageResult); } if (damageResult.wounded) { DamageWorker_AddInjury.PlayWoundedVoiceSound(dinfo, pawn); pawn.Drawer.Notify_DamageApplied(dinfo); } if (damageResult.headshot && pawn.Spawned) { MoteMaker.ThrowText(new Vector3((float)pawn.Position.x + 1f, (float)pawn.Position.y, (float)pawn.Position.z + 1f), pawn.Map, "Headshot".Translate(), Color.white, -1f); if (dinfo.Instigator != null) { Pawn pawn2 = dinfo.Instigator as Pawn; if (pawn2 != null) { pawn2.records.Increment(RecordDefOf.Headshots); } } } if ((damageResult.deflected || damageResult.diminished) && spawnedOrAnyParentSpawned) { EffecterDef effecterDef; if (damageResult.deflected) { if (damageResult.deflectedByMetalArmor && dinfo.Def.canUseDeflectMetalEffect) { if (dinfo.Def == DamageDefOf.Bullet) { effecterDef = EffecterDefOf.Deflect_Metal_Bullet; } else { effecterDef = EffecterDefOf.Deflect_Metal; } } else if (dinfo.Def == DamageDefOf.Bullet) { effecterDef = EffecterDefOf.Deflect_General_Bullet; } else { effecterDef = EffecterDefOf.Deflect_General; } } else if (damageResult.diminishedByMetalArmor) { effecterDef = EffecterDefOf.DamageDiminished_Metal; } else { effecterDef = EffecterDefOf.DamageDiminished_General; } if (pawn.health.deflectionEffecter == null || pawn.health.deflectionEffecter.def != effecterDef) { if (pawn.health.deflectionEffecter != null) { pawn.health.deflectionEffecter.Cleanup(); pawn.health.deflectionEffecter = null; } pawn.health.deflectionEffecter = effecterDef.Spawn(); } pawn.health.deflectionEffecter.Trigger(pawn, dinfo.Instigator ?? pawn); if (damageResult.deflected) { pawn.Drawer.Notify_DamageDeflected(dinfo); } } if (!damageResult.deflected && spawnedOrAnyParentSpawned) { ImpactSoundUtility.PlayImpactSound(pawn, dinfo.Def.impactSoundType, mapHeld); } return(damageResult); }
private DamageResult ApplyToPawn(DamageInfo dinfo, Pawn pawn) { DamageResult result = DamageResult.MakeNew(); if (dinfo.Amount <= 0) { return(result); } if (!DebugSettings.enablePlayerDamage && pawn.Faction == Faction.OfPlayer) { return(result); } Map mapHeld = pawn.MapHeld; bool spawnedOrAnyParentSpawned = pawn.SpawnedOrAnyParentSpawned; if (dinfo.Def.spreadOut) { if (pawn.apparel != null) { List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int num = wornApparel.Count - 1; num >= 0; num--) { this.CheckApplySpreadDamage(dinfo, wornApparel[num]); } } if (pawn.equipment != null && pawn.equipment.Primary != null) { this.CheckApplySpreadDamage(dinfo, pawn.equipment.Primary); } if (pawn.inventory != null) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int num2 = innerContainer.Count - 1; num2 >= 0; num2--) { this.CheckApplySpreadDamage(dinfo, innerContainer[num2]); } } } if (this.ShouldFragmentDamageForDamageType(dinfo)) { int num3 = Rand.RangeInclusive(3, 4); for (int i = 0; i < num3; i++) { DamageInfo dinfo2 = dinfo; dinfo2.SetAmount(dinfo.Amount / num3); this.ApplyDamageToPart(dinfo2, pawn, ref result); } } else { this.ApplyDamageToPart(dinfo, pawn, ref result); this.CheckDuplicateSmallPawnDamageToPartParent(dinfo, pawn, ref result); } if (result.wounded) { DamageWorker_AddInjury.PlayWoundedVoiceSound(dinfo, pawn); pawn.Drawer.Notify_DamageApplied(dinfo); DamageWorker_AddInjury.InformPsychology(dinfo, pawn); } if (result.headshot && pawn.Spawned) { IntVec3 position = pawn.Position; double x = (float)position.x + 1.0; IntVec3 position2 = pawn.Position; float y = (float)position2.y; IntVec3 position3 = pawn.Position; MoteMaker.ThrowText(new Vector3((float)x, y, (float)((float)position3.z + 1.0)), pawn.Map, "Headshot".Translate(), Color.white, -1f); if (dinfo.Instigator != null) { Pawn pawn2 = dinfo.Instigator as Pawn; if (pawn2 != null) { pawn2.records.Increment(RecordDefOf.Headshots); } } } if (result.deflected) { if (pawn.health.deflectionEffecter == null) { pawn.health.deflectionEffecter = EffecterDefOf.ArmorDeflect.Spawn(); } pawn.health.deflectionEffecter.Trigger(pawn, pawn); } else if (spawnedOrAnyParentSpawned) { ImpactSoundUtility.PlayImpactSound(pawn, dinfo.Def.impactSoundType, mapHeld); } return(result); }