Пример #1
0
 public virtual void Notify_PawnPostApplyDamage(DamageInfo dinfo, float totalDamageDealt)
 {
 }
Пример #2
0
 private static void InformPsychology(DamageInfo dinfo, Pawn pawn)
 {
 }
Пример #3
0
 protected virtual BodyPartRecord ChooseHitPart(DamageInfo dinfo, Pawn pawn)
 {
     return(pawn.health.hediffSet.GetRandomNotMissingPart(dinfo.Def, dinfo.Height, dinfo.Depth));
 }
Пример #4
0
        private DamageResult ApplyToPawn(DamageInfo dinfo, Pawn pawn)
        {
            DamageResult damageResult = new 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);
                    ApplyDamageToPart(dinfo2, pawn, damageResult);
                }
            }
            else
            {
                ApplyDamageToPart(dinfo, pawn, damageResult);
                ApplySmallPawnDamagePropagation(dinfo, pawn, damageResult);
            }
            if (damageResult.wounded)
            {
                PlayWoundedVoiceSound(dinfo, pawn);
                pawn.Drawer.Notify_DamageApplied(dinfo);
                EffecterDef damageEffecter = pawn.RaceProps.FleshType.damageEffecter;
                if (damageEffecter != null)
                {
                    if (pawn.health.woundedEffecter != null && pawn.health.woundedEffecter.def != damageEffecter)
                    {
                        pawn.health.woundedEffecter.Cleanup();
                    }
                    pawn.health.woundedEffecter = damageEffecter.Spawn();
                    pawn.health.woundedEffecter.Trigger(pawn, dinfo.Instigator ?? pawn);
                }
            }
            if (damageResult.headshot && pawn.Spawned)
            {
                MoteMaker.ThrowText(new Vector3((float)pawn.Position.x + 1f, pawn.Position.y, (float)pawn.Position.z + 1f), pawn.Map, "Headshot".Translate(), Color.white);
                if (dinfo.Instigator != null)
                {
                    (dinfo.Instigator as Pawn)?.records.Increment(RecordDefOf.Headshots);
                }
            }
            if ((damageResult.deflected || damageResult.diminished) & spawnedOrAnyParentSpawned)
            {
                EffecterDef effecterDef = damageResult.deflected ? ((damageResult.deflectedByMetalArmor && dinfo.Def.canUseDeflectMetalEffect) ? ((dinfo.Def != DamageDefOf.Bullet) ? EffecterDefOf.Deflect_Metal : EffecterDefOf.Deflect_Metal_Bullet) : ((dinfo.Def != DamageDefOf.Bullet) ? EffecterDefOf.Deflect_General : EffecterDefOf.Deflect_General_Bullet)) : ((!damageResult.diminishedByMetalArmor) ? EffecterDefOf.DamageDiminished_General : EffecterDefOf.DamageDiminished_Metal);
                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);
        }
Пример #5
0
 protected virtual void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, ref DamageWorker.DamageResult result)
 {
     totalDamage = this.ReduceDamageToPreserveOutsideParts(totalDamage, dinfo, pawn);
     this.FinalizeAndAddInjury(pawn, totalDamage, dinfo, ref result);
     this.CheckDuplicateDamageToOuterParts(dinfo, pawn, totalDamage, ref result);
 }
Пример #6
0
 public virtual void PostPostApplyDamage(DamageInfo dinfo, float totalDamageDealt)
 {
 }
        protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, ref DamageResult result)
        {
            totalDamage = base.ReduceDamageToPreserveOutsideParts(totalDamage, dinfo, pawn);
            List <BodyPartRecord> list           = new List <BodyPartRecord>();
            BodyPartRecord        bodyPartRecord = dinfo.HitPart;

            while (bodyPartRecord != null)
            {
                list.Add(bodyPartRecord);
                if (bodyPartRecord.depth != BodyPartDepth.Outside)
                {
                    bodyPartRecord = bodyPartRecord.parent;
                    continue;
                }
                break;
            }
            float totalDamage2 = (float)(totalDamage * (1.0 + base.def.stabPierceBonus) / ((float)list.Count + base.def.stabPierceBonus));

            for (int i = 0; i < list.Count; i++)
            {
                DamageInfo dinfo2 = dinfo;
                dinfo2.SetHitPart(list[i]);
                base.FinalizeAndAddInjury(pawn, totalDamage2, dinfo2, ref result);
            }
        }
        protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, DamageResult result)
        {
            if (dinfo.HitPart.depth == BodyPartDepth.Inside)
            {
                List <BodyPartRecord> list = new List <BodyPartRecord>();
                for (BodyPartRecord bodyPartRecord = dinfo.HitPart; bodyPartRecord != null; bodyPartRecord = bodyPartRecord.parent)
                {
                    list.Add(bodyPartRecord);
                    if (bodyPartRecord.depth == BodyPartDepth.Outside)
                    {
                        break;
                    }
                }
                float num = list.Count;
                for (int i = 0; i < list.Count; i++)
                {
                    DamageInfo dinfo2 = dinfo;
                    dinfo2.SetHitPart(list[i]);
                    FinalizeAndAddInjury(pawn, totalDamage / num, dinfo2, result);
                }
                return;
            }
            IEnumerable <BodyPartRecord> enumerable = dinfo.HitPart.GetDirectChildParts();

            if (dinfo.HitPart.parent != null)
            {
                enumerable = enumerable.Concat(dinfo.HitPart.parent);
                if (dinfo.HitPart.parent.parent != null)
                {
                    enumerable = enumerable.Concat(dinfo.HitPart.parent.GetDirectChildParts());
                }
            }
            enumerable = enumerable.Where((BodyPartRecord target) => target != dinfo.HitPart && !target.def.conceptual && target.depth == BodyPartDepth.Outside && !pawn.health.hediffSet.PartIsMissing(target));
            BodyPartRecord bodyPartRecord2 = enumerable.RandomElementWithFallback();

            if (bodyPartRecord2 == null)
            {
                FinalizeAndAddInjury(pawn, ReduceDamageToPreserveOutsideParts(totalDamage, dinfo, pawn), dinfo, result);
                return;
            }
            FinalizeAndAddInjury(pawn, ReduceDamageToPreserveOutsideParts(totalDamage * def.scratchSplitPercentage, dinfo, pawn), dinfo, result);
            DamageInfo dinfo3 = dinfo;

            dinfo3.SetHitPart(bodyPartRecord2);
            FinalizeAndAddInjury(pawn, ReduceDamageToPreserveOutsideParts(totalDamage * def.scratchSplitPercentage, dinfo3, pawn), dinfo3, result);
        }
        protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, DamageResult result)
        {
            bool       flag     = Rand.Chance(def.bluntInnerHitChance);
            float      num      = (flag ? def.bluntInnerHitDamageFractionToConvert.RandomInRange : 0f);
            float      num2     = totalDamage * (1f - num);
            DamageInfo lastInfo = dinfo;

            while (true)
            {
                num2 -= FinalizeAndAddInjury(pawn, num2, lastInfo, result);
                if (!pawn.health.hediffSet.PartIsMissing(lastInfo.HitPart) || num2 <= 1f)
                {
                    break;
                }
                BodyPartRecord parent = lastInfo.HitPart.parent;
                if (parent == null)
                {
                    break;
                }
                lastInfo.SetHitPart(parent);
            }
            if (flag && !lastInfo.HitPart.def.IsSolid(lastInfo.HitPart, pawn.health.hediffSet.hediffs) && lastInfo.HitPart.depth == BodyPartDepth.Outside && (from x in pawn.health.hediffSet.GetNotMissingParts()
                                                                                                                                                              where x.parent == lastInfo.HitPart && x.def.IsSolid(x, pawn.health.hediffSet.hediffs) && x.depth == BodyPartDepth.Inside
                                                                                                                                                              select x).TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out var result2))
            {
                DamageInfo dinfo2 = lastInfo;
                dinfo2.SetHitPart(result2);
                float totalDamage2 = totalDamage * num + totalDamage * def.bluntInnerHitDamageFractionToAdd.RandomInRange;
                FinalizeAndAddInjury(pawn, totalDamage2, dinfo2, result);
            }
            if (pawn.Dead)
            {
                return;
            }
            SimpleCurve simpleCurve = null;

            if (lastInfo.HitPart.parent == null)
            {
                simpleCurve = def.bluntStunChancePerDamagePctOfCorePartToBodyCurve;
            }
            else
            {
                foreach (BodyPartRecord item in pawn.RaceProps.body.GetPartsWithTag(BodyPartTagDefOf.ConsciousnessSource))
                {
                    if (InSameBranch(item, lastInfo.HitPart))
                    {
                        simpleCurve = def.bluntStunChancePerDamagePctOfCorePartToHeadCurve;
                        break;
                    }
                }
            }
            if (simpleCurve != null)
            {
                float x2 = totalDamage / pawn.def.race.body.corePart.def.GetMaxHealth(pawn);
                if (Rand.Chance(simpleCurve.Evaluate(x2)))
                {
                    DamageInfo dinfo3 = dinfo;
                    dinfo3.Def = DamageDefOf.Stun;
                    dinfo3.SetAmount((float)def.bluntStunDuration.SecondsToTicks() / 30f);
                    pawn.TakeDamage(dinfo3);
                }
            }
        }
        protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, DamageResult result)
        {
            totalDamage = ReduceDamageToPreserveOutsideParts(totalDamage, dinfo, pawn);
            List <BodyPartRecord> list = new List <BodyPartRecord>();

            for (BodyPartRecord bodyPartRecord = dinfo.HitPart; bodyPartRecord != null; bodyPartRecord = bodyPartRecord.parent)
            {
                list.Add(bodyPartRecord);
                if (bodyPartRecord.depth == BodyPartDepth.Outside)
                {
                    break;
                }
            }
            for (int i = 0; i < list.Count; i++)
            {
                BodyPartRecord bodyPartRecord2 = list[i];
                float          totalDamage2    = ((list.Count != 1) ? ((bodyPartRecord2.depth == BodyPartDepth.Outside) ? (totalDamage * 0.75f) : (totalDamage * 0.4f)) : totalDamage);
                DamageInfo     dinfo2          = dinfo;
                dinfo2.SetHitPart(bodyPartRecord2);
                FinalizeAndAddInjury(pawn, totalDamage2, dinfo2, result);
            }
        }
Пример #11
0
        protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, ref DamageWorker.DamageResult result)
        {
            bool  flag = Rand.Chance(this.def.bluntInnerHitFrequency);
            float num  = (!flag) ? 0f : this.def.bluntInnerHitConverted.RandomInRange;
            float num2 = totalDamage * (1f - num);

            while (true)
            {
                num2 -= base.FinalizeAndAddInjury(pawn, num2, dinfo, ref result);
                if (!pawn.health.hediffSet.PartIsMissing(dinfo.HitPart))
                {
                    break;
                }
                if (num2 <= 1f)
                {
                    break;
                }
                BodyPartRecord parent = dinfo.HitPart.parent;
                if (parent == null)
                {
                    break;
                }
                dinfo.SetHitPart(parent);
            }
            if (flag && !dinfo.HitPart.def.IsSolid(dinfo.HitPart, pawn.health.hediffSet.hediffs) && dinfo.HitPart.depth == BodyPartDepth.Outside)
            {
                IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined)
                                                      where x.parent == dinfo.HitPart && x.def.IsSolid(x, pawn.health.hediffSet.hediffs) && x.depth == BodyPartDepth.Inside
                                                      select x;
                BodyPartRecord hitPart;
                if (source.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out hitPart))
                {
                    DamageInfo lastInfo = dinfo;
                    lastInfo.SetHitPart(hitPart);
                    base.FinalizeAndAddInjury(pawn, totalDamage * num + totalDamage * this.def.bluntInnerHitAdded.RandomInRange, lastInfo, ref result);
                }
            }
        }
Пример #12
0
        public void PreApplyDamage(DamageInfo dinfo, out bool absorbed)
        {
            Faction factionOrExtraHomeFaction = this.pawn.FactionOrExtraHomeFaction;

            if (dinfo.Instigator != null && factionOrExtraHomeFaction != null && factionOrExtraHomeFaction.IsPlayer && !this.pawn.InAggroMentalState)
            {
                Pawn pawn = dinfo.Instigator as Pawn;
                if (pawn != null && pawn.guilt != null && pawn.mindState != null)
                {
                    pawn.guilt.Notify_Guilty();
                }
            }
            if (this.pawn.Spawned)
            {
                if (!this.pawn.Position.Fogged(this.pawn.Map))
                {
                    this.pawn.mindState.Active = true;
                }
                this.pawn.GetLord()?.Notify_PawnDamaged(this.pawn, dinfo);
                if (dinfo.Def.ExternalViolenceFor(this.pawn))
                {
                    GenClamor.DoClamor(this.pawn, 18f, ClamorDefOf.Harm);
                }
                this.pawn.jobs.Notify_DamageTaken(dinfo);
            }
            if (factionOrExtraHomeFaction != null)
            {
                factionOrExtraHomeFaction.Notify_MemberTookDamage(this.pawn, dinfo);
                if (Current.ProgramState == ProgramState.Playing && factionOrExtraHomeFaction == Faction.OfPlayer && dinfo.Def.ExternalViolenceFor(this.pawn) && this.pawn.SpawnedOrAnyParentSpawned)
                {
                    this.pawn.MapHeld.dangerWatcher.Notify_ColonistHarmedExternally();
                }
            }
            if (this.pawn.apparel != null && !dinfo.IgnoreArmor)
            {
                List <Apparel> wornApparel = this.pawn.apparel.WornApparel;
                for (int i = 0; i < wornApparel.Count; i++)
                {
                    if (wornApparel[i].CheckPreAbsorbDamage(dinfo))
                    {
                        absorbed = true;
                        return;
                    }
                }
            }
            if (this.pawn.Spawned)
            {
                this.pawn.stances.Notify_DamageTaken(dinfo);
                this.pawn.stances.stunner.Notify_DamageApplied(dinfo, !this.pawn.RaceProps.IsFlesh);
            }
            if (this.pawn.RaceProps.IsFlesh && dinfo.Def.ExternalViolenceFor(this.pawn))
            {
                Pawn pawn2 = dinfo.Instigator as Pawn;
                if (pawn2 != null)
                {
                    if (pawn2.HostileTo(this.pawn))
                    {
                        this.pawn.relations.canGetRescuedThought = true;
                    }
                    if (this.pawn.RaceProps.Humanlike && pawn2.RaceProps.Humanlike && this.pawn.needs.mood != null && (!pawn2.HostileTo(this.pawn) || (pawn2.Faction == factionOrExtraHomeFaction && pawn2.InMentalState)))
                    {
                        this.pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.HarmedMe, pawn2);
                    }
                }
                TaleRecorder.RecordTale(TaleDefOf.Wounded, this.pawn, pawn2, dinfo.Weapon);
            }
            absorbed = false;
        }
Пример #13
0
        private static void DropRoofInCellPhaseOne(IntVec3 c, Map map)
        {
            RoofDef roofDef = map.roofGrid.RoofAt(c);

            if (roofDef != null)
            {
                if (roofDef.collapseLeavingThingDef != null && roofDef.collapseLeavingThingDef.passability == Traversability.Impassable)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        List <Thing> thingList = c.GetThingList(map);
                        for (int num = thingList.Count - 1; num >= 0; num--)
                        {
                            Thing thing = thingList[num];
                            map.roofCollapseBuffer.Notify_Crushed(thing);
                            Pawn       pawn  = thing as Pawn;
                            DamageInfo dinfo = default(DamageInfo);
                            if (pawn != null)
                            {
                                DamageDef      crush  = DamageDefOf.Crush;
                                int            amount = 99999;
                                BodyPartRecord brain  = pawn.health.hediffSet.GetBrain();
                                dinfo = new DamageInfo(crush, amount, -1f, null, brain, null, DamageInfo.SourceCategory.Collapse);
                            }
                            else
                            {
                                dinfo = new DamageInfo(DamageDefOf.Crush, 99999, -1f, null, null, null, DamageInfo.SourceCategory.Collapse);
                                dinfo.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside);
                            }
                            BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = null;
                            if (i == 0 && pawn != null)
                            {
                                battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_Ceiling, null);
                                Find.BattleLog.Add(battleLogEntry_DamageTaken);
                            }
                            thing.TakeDamage(dinfo).InsertIntoLog(battleLogEntry_DamageTaken);
                            if (!thing.Destroyed && thing.def.destroyable)
                            {
                                thing.Destroy(DestroyMode.Vanish);
                            }
                        }
                    }
                }
                else
                {
                    List <Thing> thingList2 = c.GetThingList(map);
                    for (int num2 = thingList2.Count - 1; num2 >= 0; num2--)
                    {
                        Thing thing2 = thingList2[num2];
                        if (thing2.def.category == ThingCategory.Item || thing2.def.category == ThingCategory.Plant || thing2.def.category == ThingCategory.Building || thing2.def.category == ThingCategory.Pawn)
                        {
                            map.roofCollapseBuffer.Notify_Crushed(thing2);
                            float num3 = (float)RoofCollapserImmediate.ThinRoofCrushDamageRange.RandomInRange;
                            if (thing2.def.building != null)
                            {
                                num3 *= thing2.def.building.roofCollapseDamageMultiplier;
                            }
                            BattleLogEntry_DamageTaken battleLogEntry_DamageTaken2 = null;
                            if (thing2 is Pawn)
                            {
                                battleLogEntry_DamageTaken2 = new BattleLogEntry_DamageTaken(thing2 as Pawn, RulePackDefOf.DamageEvent_Ceiling, null);
                                Find.BattleLog.Add(battleLogEntry_DamageTaken2);
                            }
                            DamageInfo dinfo2 = new DamageInfo(DamageDefOf.Crush, GenMath.RoundRandom(num3), -1f, null, null, null, DamageInfo.SourceCategory.Collapse);
                            dinfo2.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside);
                            thing2.TakeDamage(dinfo2).InsertIntoLog(battleLogEntry_DamageTaken2);
                        }
                    }
                }
                if (roofDef.collapseLeavingThingDef != null)
                {
                    Thing thing3 = GenSpawn.Spawn(roofDef.collapseLeavingThingDef, c, map);
                    if (thing3.def.rotatable)
                    {
                        thing3.Rotation = Rot4.Random;
                    }
                }
                for (int j = 0; j < 1; j++)
                {
                    Vector3 a = c.ToVector3Shifted();
                    a += Gen.RandomHorizontalVector(0.6f);
                    MoteMaker.ThrowDustPuff(a, map, 2f);
                }
            }
        }
        protected virtual void ExplosionDamageThing(Explosion explosion, Thing t, List <Thing> damagedThings, IntVec3 cell)
        {
            if (t.def.category == ThingCategory.Mote || t.def.category == ThingCategory.Ethereal)
            {
                return;
            }
            if (damagedThings.Contains(t))
            {
                return;
            }
            damagedThings.Add(t);
            if (this.def == DamageDefOf.Bomb && t.def == ThingDefOf.Fire && !t.Destroyed)
            {
                t.Destroy(DestroyMode.Vanish);
                return;
            }
            float num;

            if (t.Position == explosion.Position)
            {
                num = (float)Rand.RangeInclusive(0, 359);
            }
            else
            {
                num = (t.Position - explosion.Position).AngleFlat;
            }
            DamageDef  damageDef          = this.def;
            float      amount             = (float)explosion.GetDamageAmountAt(cell);
            float      armorPenetrationAt = explosion.GetArmorPenetrationAt(cell);
            float      angle      = num;
            Thing      instigator = explosion.instigator;
            ThingDef   weapon     = explosion.weapon;
            DamageInfo dinfo      = new DamageInfo(damageDef, amount, armorPenetrationAt, angle, instigator, null, weapon, DamageInfo.SourceCategory.ThingOrUnknown, explosion.intendedTarget);

            if (this.def.explosionAffectOutsidePartsOnly)
            {
                dinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
            }
            if (t.def.category == ThingCategory.Building)
            {
                int num2 = Mathf.RoundToInt(dinfo.Amount * this.def.explosionBuildingDamageFactor);
                dinfo.SetAmount((float)num2);
            }
            else if (t.def.category == ThingCategory.Plant)
            {
                int num3 = Mathf.RoundToInt(dinfo.Amount * this.def.explosionPlantDamageFactor);
                dinfo.SetAmount((float)num3);
            }
            BattleLogEntry_ExplosionImpact battleLogEntry_ExplosionImpact = null;
            Pawn pawn = t as Pawn;

            if (pawn != null)
            {
                battleLogEntry_ExplosionImpact = new BattleLogEntry_ExplosionImpact(explosion.instigator, t, explosion.weapon, explosion.projectile, this.def);
                Find.BattleLog.Add(battleLogEntry_ExplosionImpact);
            }
            DamageWorker.DamageResult damageResult = t.TakeDamage(dinfo);
            damageResult.AssociateWithLog(battleLogEntry_ExplosionImpact);
            if (pawn != null && damageResult.wounded && pawn.stances != null)
            {
                pawn.stances.StaggerFor(95);
            }
        }
Пример #15
0
 protected override BodyPartRecord ChooseHitPart(DamageInfo dinfo, Pawn pawn)
 {
     return(pawn.health.hediffSet.GetRandomNotMissingPart(dinfo.Def, dinfo.Height, BodyPartDepth.Outside));
 }
Пример #16
0
        protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, DamageWorker.DamageResult result)
        {
            bool       flag     = Rand.Chance(this.def.bluntInnerHitChance);
            float      num      = (!flag) ? 0f : this.def.bluntInnerHitDamageFractionToConvert.RandomInRange;
            float      num2     = totalDamage * (1f - num);
            DamageInfo lastInfo = dinfo;

            for (;;)
            {
                num2 -= base.FinalizeAndAddInjury(pawn, num2, lastInfo, result);
                if (!pawn.health.hediffSet.PartIsMissing(lastInfo.HitPart))
                {
                    break;
                }
                if (num2 <= 1f)
                {
                    break;
                }
                BodyPartRecord parent = lastInfo.HitPart.parent;
                if (parent == null)
                {
                    break;
                }
                lastInfo.SetHitPart(parent);
            }
            if (flag && !lastInfo.HitPart.def.IsSolid(lastInfo.HitPart, pawn.health.hediffSet.hediffs) && lastInfo.HitPart.depth == BodyPartDepth.Outside)
            {
                IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null)
                                                      where x.parent == lastInfo.HitPart && x.def.IsSolid(x, pawn.health.hediffSet.hediffs) && x.depth == BodyPartDepth.Inside
                                                      select x;
                BodyPartRecord hitPart;
                if (source.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out hitPart))
                {
                    DamageInfo lastInfo2 = lastInfo;
                    lastInfo2.SetHitPart(hitPart);
                    float totalDamage2 = totalDamage * num + totalDamage * this.def.bluntInnerHitDamageFractionToAdd.RandomInRange;
                    base.FinalizeAndAddInjury(pawn, totalDamage2, lastInfo2, result);
                }
            }
            if (!pawn.Dead)
            {
                SimpleCurve simpleCurve = null;
                if (lastInfo.HitPart.parent == null)
                {
                    simpleCurve = this.def.bluntStunChancePerDamagePctOfCorePartToBodyCurve;
                }
                else
                {
                    foreach (BodyPartRecord lhs in pawn.RaceProps.body.GetPartsWithTag(BodyPartTagDefOf.ConsciousnessSource))
                    {
                        if (this.InSameBranch(lhs, lastInfo.HitPart))
                        {
                            simpleCurve = this.def.bluntStunChancePerDamagePctOfCorePartToHeadCurve;
                            break;
                        }
                    }
                }
                if (simpleCurve != null)
                {
                    float x2 = totalDamage / pawn.def.race.body.corePart.def.GetMaxHealth(pawn);
                    if (Rand.Chance(simpleCurve.Evaluate(x2)))
                    {
                        DamageInfo dinfo2 = dinfo;
                        dinfo2.Def = DamageDefOf.Stun;
                        dinfo2.SetAmount((float)this.def.bluntStunDuration.SecondsToTicks() / 30f);
                        pawn.TakeDamage(dinfo2);
                    }
                }
            }
        }
Пример #17
0
 public virtual void PostPreApplyDamage(DamageInfo dinfo, out bool absorbed)
 {
     absorbed = false;
 }
Пример #18
0
        private static void DropRoofInCellPhaseOne(IntVec3 c, Map map, List <Thing> outCrushedThings)
        {
            RoofDef roofDef = map.roofGrid.RoofAt(c);

            if (roofDef == null)
            {
                return;
            }
            if (roofDef.collapseLeavingThingDef != null && roofDef.collapseLeavingThingDef.passability == Traversability.Impassable)
            {
                for (int i = 0; i < 2; i++)
                {
                    List <Thing> thingList = c.GetThingList(map);
                    for (int num = thingList.Count - 1; num >= 0; num--)
                    {
                        Thing thing = thingList[num];
                        TryAddToCrushedThingsList(thing, outCrushedThings);
                        Pawn       pawn = thing as Pawn;
                        DamageInfo dinfo;
                        if (pawn != null)
                        {
                            dinfo = new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, null, pawn.health.hediffSet.GetBrain(), null, DamageInfo.SourceCategory.Collapse);
                        }
                        else
                        {
                            dinfo = new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse);
                            dinfo.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside);
                        }
                        BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = null;
                        if (i == 0 && pawn != null)
                        {
                            battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_Ceiling);
                            Find.BattleLog.Add(battleLogEntry_DamageTaken);
                        }
                        thing.TakeDamage(dinfo).AssociateWithLog(battleLogEntry_DamageTaken);
                        if (!thing.Destroyed && thing.def.destroyable)
                        {
                            thing.Kill(new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse));
                        }
                    }
                }
            }
            else
            {
                List <Thing> thingList2 = c.GetThingList(map);
                for (int num2 = thingList2.Count - 1; num2 >= 0; num2--)
                {
                    Thing thing2 = thingList2[num2];
                    if (thing2.def.category == ThingCategory.Item || thing2.def.category == ThingCategory.Plant || thing2.def.category == ThingCategory.Building || thing2.def.category == ThingCategory.Pawn)
                    {
                        TryAddToCrushedThingsList(thing2, outCrushedThings);
                        float num3 = ThinRoofCrushDamageRange.RandomInRange;
                        if (thing2.def.building != null)
                        {
                            num3 *= thing2.def.building.roofCollapseDamageMultiplier;
                        }
                        BattleLogEntry_DamageTaken battleLogEntry_DamageTaken2 = null;
                        if (thing2 is Pawn)
                        {
                            battleLogEntry_DamageTaken2 = new BattleLogEntry_DamageTaken((Pawn)thing2, RulePackDefOf.DamageEvent_Ceiling);
                            Find.BattleLog.Add(battleLogEntry_DamageTaken2);
                        }
                        DamageInfo dinfo2 = new DamageInfo(DamageDefOf.Crush, GenMath.RoundRandom(num3), 0f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse);
                        dinfo2.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside);
                        thing2.TakeDamage(dinfo2).AssociateWithLog(battleLogEntry_DamageTaken2);
                    }
                }
            }
            if (roofDef.collapseLeavingThingDef != null)
            {
                Thing thing3 = GenSpawn.Spawn(roofDef.collapseLeavingThingDef, c, map);
                if (thing3.def.rotatable)
                {
                    thing3.Rotation = Rot4.Random;
                }
            }
            for (int j = 0; j < 1; j++)
            {
                MoteMaker.ThrowDustPuff(c.ToVector3Shifted() + Gen.RandomHorizontalVector(0.6f), map, 2f);
            }
        }
 public void Notify_DamageTaken(DamageInfo dinfo)
 {
 }
Пример #20
0
 protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, ref DamageWorker.DamageResult result)
 {
     totalDamage *= this.def.biteDamageMultiplier;
     base.FinalizeAndAddInjury(pawn, totalDamage, dinfo, ref result);
 }
 protected override BodyPartRecord ChooseHitPart(DamageInfo dinfo, Pawn pawn)
 {
     return(pawn.health.hediffSet.GetRandomNotMissingPart(dinfo.Def, dinfo.Height, (Rand.Value < base.def.stabChanceOfForcedInternal) ? BodyPartDepth.Inside : dinfo.Depth));
 }
Пример #22
0
 public void Notify_DamageApplied(DamageInfo dam)
 {
     this.graphics.flasher.Notify_DamageApplied(dam);
     this.wiggler.Notify_DamageApplied(dam);
 }
Пример #23
0
 private bool ShouldFragmentDamageForDamageType(DamageInfo dinfo)
 {
     return(dinfo.AllowDamagePropagation && dinfo.Amount >= 9 && dinfo.Def.spreadOut);
 }
Пример #24
0
        private static void DropRoofInCellPhaseOne(IntVec3 c, Map map, List <Thing> outCrushedThings)
        {
            RoofDef roofDef = map.roofGrid.RoofAt(c);

            if (roofDef != null)
            {
                if (roofDef.collapseLeavingThingDef != null && roofDef.collapseLeavingThingDef.passability == Traversability.Impassable)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        List <Thing> thingList = c.GetThingList(map);
                        for (int j = thingList.Count - 1; j >= 0; j--)
                        {
                            Thing thing = thingList[j];
                            RoofCollapserImmediate.TryAddToCrushedThingsList(thing, outCrushedThings);
                            Pawn       pawn = thing as Pawn;
                            DamageInfo dinfo;
                            if (pawn != null)
                            {
                                DamageDef      crush            = DamageDefOf.Crush;
                                float          amount           = 99999f;
                                float          armorPenetration = 999f;
                                BodyPartRecord brain            = pawn.health.hediffSet.GetBrain();
                                dinfo = new DamageInfo(crush, amount, armorPenetration, -1f, null, brain, null, DamageInfo.SourceCategory.Collapse, null);
                            }
                            else
                            {
                                dinfo = new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse, null);
                                dinfo.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside);
                            }
                            BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = null;
                            if (i == 0 && pawn != null)
                            {
                                battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_Ceiling, null);
                                Find.BattleLog.Add(battleLogEntry_DamageTaken);
                            }
                            thing.TakeDamage(dinfo).AssociateWithLog(battleLogEntry_DamageTaken);
                            if (!thing.Destroyed && thing.def.destroyable)
                            {
                                thing.Destroy(DestroyMode.Vanish);
                            }
                        }
                    }
                }
                else
                {
                    List <Thing> thingList2 = c.GetThingList(map);
                    for (int k = thingList2.Count - 1; k >= 0; k--)
                    {
                        Thing thing2 = thingList2[k];
                        if (thing2.def.category == ThingCategory.Item || thing2.def.category == ThingCategory.Plant || thing2.def.category == ThingCategory.Building || thing2.def.category == ThingCategory.Pawn)
                        {
                            RoofCollapserImmediate.TryAddToCrushedThingsList(thing2, outCrushedThings);
                            float num = (float)RoofCollapserImmediate.ThinRoofCrushDamageRange.RandomInRange;
                            if (thing2.def.building != null)
                            {
                                num *= thing2.def.building.roofCollapseDamageMultiplier;
                            }
                            BattleLogEntry_DamageTaken battleLogEntry_DamageTaken2 = null;
                            if (thing2 is Pawn)
                            {
                                battleLogEntry_DamageTaken2 = new BattleLogEntry_DamageTaken((Pawn)thing2, RulePackDefOf.DamageEvent_Ceiling, null);
                                Find.BattleLog.Add(battleLogEntry_DamageTaken2);
                            }
                            DamageInfo dinfo2 = new DamageInfo(DamageDefOf.Crush, (float)GenMath.RoundRandom(num), 0f, -1f, null, null, null, DamageInfo.SourceCategory.Collapse, null);
                            dinfo2.SetBodyRegion(BodyPartHeight.Top, BodyPartDepth.Outside);
                            thing2.TakeDamage(dinfo2).AssociateWithLog(battleLogEntry_DamageTaken2);
                        }
                    }
                }
                if (roofDef.collapseLeavingThingDef != null)
                {
                    Thing thing3 = GenSpawn.Spawn(roofDef.collapseLeavingThingDef, c, map, WipeMode.Vanish);
                    if (thing3.def.rotatable)
                    {
                        thing3.Rotation = Rot4.Random;
                    }
                }
                for (int l = 0; l < 1; l++)
                {
                    Vector3 vector = c.ToVector3Shifted();
                    vector += Gen.RandomHorizontalVector(0.6f);
                    MoteMaker.ThrowDustPuff(vector, map, 2f);
                }
            }
        }
Пример #25
0
        private DamageWorker.DamageResult ApplyToPawn(DamageInfo dinfo, Pawn pawn)
        {
            DamageWorker.DamageResult result = DamageWorker.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 i = wornApparel.Count - 1; i >= 0; i--)
                    {
                        this.CheckApplySpreadDamage(dinfo, wornApparel[i]);
                    }
                }
                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 j = innerContainer.Count - 1; j >= 0; j--)
                    {
                        this.CheckApplySpreadDamage(dinfo, innerContainer[j]);
                    }
                }
            }
            if (this.ShouldFragmentDamageForDamageType(dinfo))
            {
                int num = Rand.RangeInclusive(3, 4);
                for (int k = 0; k < num; k++)
                {
                    DamageInfo dinfo2 = dinfo;
                    dinfo2.SetAmount(dinfo.Amount / num);
                    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)
            {
                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 (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);
        }
 protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, DamageWorker.DamageResult result)
 {
     base.FinalizeAndAddInjury(pawn, totalDamage, dinfo, result);
 }
Пример #27
0
 private static bool IsHeadshot(DamageInfo dinfo, Pawn pawn)
 {
     return(!dinfo.InstantOldInjury && dinfo.HitPart.groups.Contains(BodyPartGroupDefOf.FullHead) && dinfo.Def == DamageDefOf.Bullet);
 }
Пример #28
0
 protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, ref DamageWorker.DamageResult result)
 {
     if (dinfo.HitPart.depth == BodyPartDepth.Inside)
     {
         List <BodyPartRecord> list = new List <BodyPartRecord>();
         for (BodyPartRecord bodyPartRecord = dinfo.HitPart; bodyPartRecord != null; bodyPartRecord = bodyPartRecord.parent)
         {
             list.Add(bodyPartRecord);
             if (bodyPartRecord.depth == BodyPartDepth.Outside)
             {
                 break;
             }
         }
         float num = (float)(list.Count - 1) + 0.5f;
         for (int i = 0; i < list.Count; i++)
         {
             DamageInfo dinfo2 = dinfo;
             dinfo2.SetHitPart(list[i]);
             base.FinalizeAndAddInjury(pawn, totalDamage / num * ((i != 0) ? 1f : 0.5f), dinfo2, ref result);
         }
     }
     else
     {
         int num2 = (this.def.cutExtraTargetsCurve == null) ? 0 : GenMath.RoundRandom(this.def.cutExtraTargetsCurve.Evaluate(Rand.Value));
         List <BodyPartRecord> list2;
         if (num2 != 0)
         {
             IEnumerable <BodyPartRecord> enumerable = dinfo.HitPart.GetDirectChildParts();
             if (dinfo.HitPart.parent != null)
             {
                 enumerable = enumerable.Concat(dinfo.HitPart.parent);
                 enumerable = enumerable.Concat(dinfo.HitPart.parent.GetDirectChildParts());
             }
             list2 = enumerable.Except(dinfo.HitPart).InRandomOrder(null).Take(num2).ToList <BodyPartRecord>();
         }
         else
         {
             list2 = new List <BodyPartRecord>();
         }
         list2.Add(dinfo.HitPart);
         float num3 = totalDamage * (1f + this.def.cutCleaveBonus) / ((float)list2.Count + this.def.cutCleaveBonus);
         if (num2 == 0)
         {
             num3 = base.ReduceDamageToPreserveOutsideParts(num3, dinfo, pawn);
         }
         for (int j = 0; j < list2.Count; j++)
         {
             DamageInfo dinfo3 = dinfo;
             dinfo3.SetHitPart(list2[j]);
             base.FinalizeAndAddInjury(pawn, num3, dinfo3, ref result);
         }
     }
 }
Пример #29
0
        public static void DamageUntilDowned(Pawn p, bool allowBleedingWounds = true)
        {
            if (p.health.Downed)
            {
                return;
            }
            HediffSet hediffSet = p.health.hediffSet;

            p.health.forceIncap = true;
            IEnumerable <BodyPartRecord> source = from x in HealthUtility.HittablePartsViolence(hediffSet)
                                                  where !p.health.hediffSet.hediffs.Any((Hediff y) => y.Part == x && y.CurStage != null && y.CurStage.partEfficiencyOffset < 0f)
                                                  select x;
            int num = 0;

            while (num < 300 && !p.Downed && source.Any <BodyPartRecord>())
            {
                num++;
                BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs);
                int            num2           = Mathf.RoundToInt(hediffSet.GetPartHealth(bodyPartRecord)) - 3;
                if (num2 >= 8)
                {
                    DamageDef damageDef;
                    if (bodyPartRecord.depth == BodyPartDepth.Outside)
                    {
                        if (!allowBleedingWounds && bodyPartRecord.def.bleedRate > 0f)
                        {
                            damageDef = DamageDefOf.Blunt;
                        }
                        else
                        {
                            damageDef = HealthUtility.RandomViolenceDamageType();
                        }
                    }
                    else
                    {
                        damageDef = DamageDefOf.Blunt;
                    }
                    int       num3 = Rand.RangeInclusive(Mathf.RoundToInt((float)num2 * 0.65f), num2);
                    HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(damageDef, p, bodyPartRecord);
                    if (!p.health.WouldDieAfterAddingHediff(hediffDefFromDamage, bodyPartRecord, (float)num3))
                    {
                        DamageDef      def              = damageDef;
                        float          amount           = (float)num3;
                        float          armorPenetration = 999f;
                        BodyPartRecord hitPart          = bodyPartRecord;
                        DamageInfo     dinfo            = new DamageInfo(def, amount, armorPenetration, -1f, null, hitPart, null, DamageInfo.SourceCategory.ThingOrUnknown, null);
                        dinfo.SetAllowDamagePropagation(false);
                        p.TakeDamage(dinfo);
                    }
                }
            }
            if (p.Dead)
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendLine(p + " died during GiveInjuriesToForceDowned");
                for (int i = 0; i < p.health.hediffSet.hediffs.Count; i++)
                {
                    stringBuilder.AppendLine("   -" + p.health.hediffSet.hediffs[i].ToString());
                }
                Log.Error(stringBuilder.ToString(), false);
            }
            p.health.forceIncap = false;
        }
 protected override void ApplySpecialEffectsToPart(Pawn pawn, float totalDamage, DamageInfo dinfo, ref DamageResult result)
 {
     if (dinfo.HitPart.depth == BodyPartDepth.Inside)
     {
         List <BodyPartRecord> list           = new List <BodyPartRecord>();
         BodyPartRecord        bodyPartRecord = dinfo.HitPart;
         while (bodyPartRecord != null)
         {
             list.Add(bodyPartRecord);
             if (bodyPartRecord.depth != BodyPartDepth.Outside)
             {
                 bodyPartRecord = bodyPartRecord.parent;
                 continue;
             }
             break;
         }
         float num = (float)list.Count;
         for (int i = 0; i < list.Count; i++)
         {
             DamageInfo dinfo2 = dinfo;
             dinfo2.SetHitPart(list[i]);
             base.FinalizeAndAddInjury(pawn, totalDamage / num, dinfo2, ref result);
         }
     }
     else
     {
         IEnumerable <BodyPartRecord> enumerable = dinfo.HitPart.GetDirectChildParts();
         if (dinfo.HitPart.parent != null)
         {
             enumerable = enumerable.Concat(dinfo.HitPart.parent.GetDirectChildParts());
             enumerable = enumerable.Concat(dinfo.HitPart.parent);
         }
         enumerable = from target in enumerable
                      where target != dinfo.HitPart && !target.def.isConceptual && target.depth == BodyPartDepth.Outside && !pawn.health.hediffSet.PartIsMissing(target)
                      select target;
         BodyPartRecord bodyPartRecord2 = enumerable.RandomElementWithFallback(null);
         if (bodyPartRecord2 == null)
         {
             base.FinalizeAndAddInjury(pawn, base.ReduceDamageToPreserveOutsideParts(totalDamage, dinfo, pawn), dinfo, ref result);
         }
         else
         {
             base.FinalizeAndAddInjury(pawn, base.ReduceDamageToPreserveOutsideParts(totalDamage * base.def.scratchSplitPercentage, dinfo, pawn), dinfo, ref result);
             DamageInfo dinfo3 = dinfo;
             dinfo3.SetHitPart(bodyPartRecord2);
             base.FinalizeAndAddInjury(pawn, base.ReduceDamageToPreserveOutsideParts(totalDamage * base.def.scratchSplitPercentage, dinfo3, pawn), dinfo3, ref result);
         }
     }
 }