Beispiel #1
0
 protected virtual void defaultDamageThing(Explosion explosion, Thing t, List <Thing> damagedThings, IntVec3 cell)
 {
     if (t.def.category != ThingCategory.Mote && t.def.category != ThingCategory.Ethereal)
     {
         if (!damagedThings.Contains(t))
         {
             damagedThings.Add(t);
             if (this.def == DamageDefOf.Bomb && t.def == ThingDefOf.Fire && !t.Destroyed)
             {
                 t.Destroy(DestroyMode.Vanish);
             }
             else
             {
                 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);
                 }
             }
         }
     }
 }
        // Token: 0x06004BA7 RID: 19367 RVA: 0x002357D4 File Offset: 0x00233BD4
        public override DamageWorker.DamageResult Apply(DamageInfo dinfo, Thing victim)
        {
            Pawn pawn = victim as Pawn;

            if (pawn != null && pawn.Faction == Faction.OfPlayer)
            {
                Find.TickManager.slower.SignalForceNormalSpeedShort();
            }
            Map map = victim.Map;

            dinfo.SetAmount((dinfo.Amount * (1 - victim.GetStatValue(DefDatabase <StatDef> .GetNamed("RRY_AcidResistance")))));
            DamageWorker.DamageResult damageResult = base.Apply(dinfo, victim);
            if (!damageResult.deflected && !dinfo.InstantPermanentInjury)
            {
                //   victim.TryAttachFire(Rand.Range(0.15f, 0.25f));
            }
            if (victim.Destroyed && map != null && pawn == null)
            {
                foreach (IntVec3 c in victim.OccupiedRect())
                {
                    FilthMaker.TryMakeFilth(c, map, ThingDefOf.Filth_Ash, 1);
                }
                if (victim is Plant plant && victim.def.plant.IsTree && plant.LifeStage != PlantLifeStage.Sowing && victim.def != ThingDefOf.BurnedTree)
                {
                    DeadPlant deadPlant = (DeadPlant)GenSpawn.Spawn(ThingDefOf.BurnedTree, victim.Position, map, WipeMode.Vanish);
                    deadPlant.Growth = plant.Growth;
                }
            }
            return(damageResult);
        }
Beispiel #3
0
 private void CheckApplySpreadDamage(DamageInfo dinfo, Thing t)
 {
     if ((dinfo.Def != DamageDefOf.Flame || t.FlammableNow) && Rand.Chance(0.5f))
     {
         dinfo.SetAmount((float)Mathf.CeilToInt(dinfo.Amount * Rand.Range(0.35f, 0.7f)));
         t.TakeDamage(dinfo);
     }
 }
 // Token: 0x06004B85 RID: 19333 RVA: 0x002344F0 File Offset: 0x002328F0
 private void CheckApplySpreadDamage(DamageInfo dinfo, Thing t)
 {
     if (Rand.Chance(0.5f))
     {
         dinfo.SetAmount((float)Mathf.CeilToInt(dinfo.Amount * Rand.Range(0.35f, 0.7f)));
         t.TakeDamage(dinfo);
     }
 }
Beispiel #5
0
 private void CheckApplySpreadDamage(DamageInfo dinfo, Thing t)
 {
     if (dinfo.Def == DamageDefOf.Flame && !t.FlammableNow)
     {
         return;
     }
     if (Random.value < 0.5)
     {
         dinfo.SetAmount(Mathf.CeilToInt((float)dinfo.Amount * Rand.Range(0.35f, 0.7f)));
         t.TakeDamage(dinfo);
     }
 }
Beispiel #6
0
        public DamageWorker.DamageResult TakeDamage(DamageInfo dinfo)
        {
            if (this.Destroyed)
            {
                return(DamageWorker.DamageResult.MakeNew());
            }
            if (dinfo.Amount == 0)
            {
                return(DamageWorker.DamageResult.MakeNew());
            }
            if (this.def.damageMultipliers != null)
            {
                for (int i = 0; i < this.def.damageMultipliers.Count; i++)
                {
                    if (this.def.damageMultipliers[i].damageDef == dinfo.Def)
                    {
                        int amount = Mathf.RoundToInt((float)dinfo.Amount * this.def.damageMultipliers[i].multiplier);
                        dinfo.SetAmount(amount);
                    }
                }
            }
            bool flag = default(bool);

            this.PreApplyDamage(dinfo, out flag);
            if (flag)
            {
                return(DamageWorker.DamageResult.MakeNew());
            }
            bool spawnedOrAnyParentSpawned = this.SpawnedOrAnyParentSpawned;
            Map  mapHeld = this.MapHeld;

            DamageWorker.DamageResult result = dinfo.Def.Worker.Apply(dinfo, this);
            if (dinfo.Def.harmsHealth && spawnedOrAnyParentSpawned)
            {
                mapHeld.damageWatcher.Notify_DamageTaken(this, result.totalDamageDealt);
            }
            if (dinfo.Def.externalViolence)
            {
                GenLeaving.DropFilthDueToDamage(this, result.totalDamageDealt);
                if (dinfo.Instigator != null)
                {
                    Pawn pawn = dinfo.Instigator as Pawn;
                    if (pawn != null)
                    {
                        pawn.records.AddTo(RecordDefOf.DamageDealt, result.totalDamageDealt);
                        pawn.records.AccumulateStoryEvent(StoryEventDefOf.DamageDealt);
                    }
                }
            }
            this.PostApplyDamage(dinfo, result.totalDamageDealt);
            return(result);
        }
Beispiel #7
0
        public DamageWorker.DamageResult TakeDamage(DamageInfo dinfo)
        {
            if (Destroyed)
            {
                return(new DamageWorker.DamageResult());
            }
            if (dinfo.Amount == 0f)
            {
                return(new DamageWorker.DamageResult());
            }
            if (def.damageMultipliers != null)
            {
                for (int i = 0; i < def.damageMultipliers.Count; i++)
                {
                    if (def.damageMultipliers[i].damageDef == dinfo.Def)
                    {
                        int num = Mathf.RoundToInt(dinfo.Amount * def.damageMultipliers[i].multiplier);
                        dinfo.SetAmount(num);
                    }
                }
            }
            PreApplyDamage(ref dinfo, out var absorbed);
            if (absorbed)
            {
                return(new DamageWorker.DamageResult());
            }
            bool spawnedOrAnyParentSpawned = SpawnedOrAnyParentSpawned;
            Map  mapHeld = MapHeld;

            DamageWorker.DamageResult damageResult = dinfo.Def.Worker.Apply(dinfo, this);
            if (dinfo.Def.harmsHealth && spawnedOrAnyParentSpawned)
            {
                mapHeld.damageWatcher.Notify_DamageTaken(this, damageResult.totalDamageDealt);
            }
            if (dinfo.Def.ExternalViolenceFor(this))
            {
                GenLeaving.DropFilthDueToDamage(this, damageResult.totalDamageDealt);
                if (dinfo.Instigator != null)
                {
                    Pawn pawn = dinfo.Instigator as Pawn;
                    if (pawn != null)
                    {
                        pawn.records.AddTo(RecordDefOf.DamageDealt, damageResult.totalDamageDealt);
                        pawn.records.AccumulateStoryEvent(StoryEventDefOf.DamageDealt);
                    }
                }
            }
            PostApplyDamage(dinfo, damageResult.totalDamageDealt);
            return(damageResult);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
        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)
                                                      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)3.5f.SecondsToTicks() / 30f);
                        pawn.TakeDamage(dinfo2);
                    }
                }
            }
        }
        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);
                }
            }
        }