Ejemplo n.º 1
0
        /*
         * public static void DoExplosion(
         *      IntVec3 center, Map map, float radius, DamageDef damType, Thing instigator,
         *      int damAmount = -1, float armorPenetration = -1, SoundDef explosionSound = null, ThingDef weapon = null, ThingDef projectile = null, Thing intendedTarget = null,
         *      ThingDef postExplosionSpawnThingDef = null, float postExplosionSpawnChance = 0, int postExplosionSpawnThingCount = 1,
         *      bool applyDamageToExplosionCellsNeighbors = false,
         *      ThingDef preExplosionSpawnThingDef = null, float preExplosionSpawnChance = 0, int preExplosionSpawnThingCount = 1,
         *      float chanceToStartFire = 0, bool damageFalloff = false, float? direction = null, List<Thing> ignoredThings = null
         * );*/
        public static bool TryExplode(this DamageWorker_ExplosionOnImpact DWEOI, PickedParams pp)
        {
            GenExplosion.DoExplosion(
                center: pp.Origin, map: pp.Map, radius: pp.Radius, damType: pp.DamageType, instigator: pp.Instigator,
                damAmount: (int)pp.DamageAmount, explosionSound: pp.ExplosionSound, weapon: pp.Weapon, intendedTarget: pp.IntendedTarget,
                postExplosionSpawnThingDef: pp.PostExplosionSpawnThingDef, postExplosionSpawnChance: pp.PostExplosionSpawnChance, postExplosionSpawnThingCount: pp.PostExplosionSpawnThingCount,

                preExplosionSpawnThingDef: pp.PreExplosionSpawnThingDef, preExplosionSpawnChance: pp.PreExplosionSpawnChance, preExplosionSpawnThingCount: pp.PreExplosionSpawnThingCount,
                chanceToStartFire: pp.ChanceToStartFire, damageFalloff: pp.DamageFallOff, ignoredThings: pp.IgnoredByExplosion
                );

            return(true);
        }
        public override DamageResult Apply(DamageInfo dinfo, Thing victim)
        {
            string debugStr = MyDebug ? $"{victim.def.defName} Apply - " : "";

            Pawn pVictim   = victim as Pawn;
            Pawn pAgressor = dinfo.Instigator as Pawn;

            IntVec3 IntVec3Origin = pVictim.Position;
            //IntVec3Origin.ToVector3Shifted();
            Vector3 Vector3Origin = pVictim.DrawPos;

            bool DidSomething       = false;
            bool DidApplyEffect     = false;
            bool DidExplosionEffect = false;
            Map  map = victim.Map;

            DamageResult damageResult = base.Apply(dinfo, victim);

            DidSomething |= DidApplyEffect = this.TryApplyEffect(pVictim);
            if (DidApplyEffect && HasDecoration && ExplosionDecoration.HasPawnEffectMote)
            {
                MoteThrower.ThrowPawnEffectMote(pVictim.DrawPos, map, ExplosionDecoration.pawnEffectMote);
            }

            Tools.Warn($"{debugStr}DidApplyEffect: {DidApplyEffect}", MyDebug);

            float ExplosionChance = this.ChanceToTriggerExplosion(pAgressor);

            Tools.Warn($"{debugStr}ExplosionChance: {ExplosionChance}", MyDebug);

            if (Rand.Chance(ExplosionChance))
            {
                Tools.Warn($"{debugStr}Trying to explode", MyDebug);

                ExplosionSpawnItem preExplosionSpawnItem  = HasPreExplosionSpawn ? PreExplosionSpawn.PickRandomWeightedItem() : null;
                ExplosionSpawnItem postExplosionSpawnItem = HasPostExplosionSpawn ? PostExplosionSpawn.PickRandomWeightedItem() : null;

                List <Thing> explosionImmuneThings = null;
                if (HasImmunity)
                {
                    explosionImmuneThings = new List <Thing>();
                    explosionImmuneThings = this.GenerateThingsToIgnore(map, dinfo.Instigator, this.GenerateThingDefsToIgnore(pAgressor), Immunity.limit);

                    Tools.Warn($"{debugStr}explosionImmuneThings: {explosionImmuneThings?.Count}", MyDebug);
                    if (!explosionImmuneThings.NullOrEmpty() && MyDebug)
                    {
                        foreach (Thing t in explosionImmuneThings)
                        {
                            Tools.Warn(t.def.defName, MyDebug);
                        }
                    }
                }

                Tools.Warn($"{debugStr}trying to construct pp", MyDebug);
                PickedParams pp = new PickedParams()
                {
                    Instigator = dinfo.Instigator,

                    Origin = IntVec3Origin,
                    Map    = map,
                    Radius = this.PawnWeightedExplosionRadius(pAgressor),

                    DamageType   = Nature.damageType,
                    DamageAmount = this.PawnWeightedExplosionDamage(pAgressor, damageResult.totalDamageDealt),

                    ExplosionSound = (!HasDecoration || !ExplosionDecoration.HasSoundOnImpact)?null: ExplosionDecoration.soundOnImpact,
                    Weapon         = dinfo.Weapon,

                    IntendedTarget = victim,

                    PreExplosionSpawnChance     = preExplosionSpawnItem != null ? preExplosionSpawnItem.chance.RandomInRange : 0,
                    PreExplosionSpawnThingCount = preExplosionSpawnItem != null ? preExplosionSpawnItem.stack.RandomInRange : 0,
                    PreExplosionSpawnThingDef   = preExplosionSpawnItem != null ? preExplosionSpawnItem.thingDef : null,

                    PostExplosionSpawnChance     = postExplosionSpawnItem != null ? postExplosionSpawnItem.chance.RandomInRange : 0,
                    PostExplosionSpawnThingCount = postExplosionSpawnItem != null ? postExplosionSpawnItem.stack.RandomInRange : 0,
                    PostExplosionSpawnThingDef   = postExplosionSpawnItem != null ? postExplosionSpawnItem.thingDef : null,

                    ChanceToStartFire = Nature.chanceToStartFire.RandomInRange,
                    DamageFallOff     = Nature.damageFallOff,

                    IgnoredByExplosion = explosionImmuneThings
                };

                Tools.Warn($"{debugStr}constructed pp", MyDebug);

                DidSomething |= DidExplosionEffect = this.TryExplode(pp);

                Tools.Warn($"{debugStr}DidExplosionEffect : {DidExplosionEffect}", MyDebug);
                if (DidExplosionEffect && HasDecoration)
                {
                    float myRadius = pp.Radius;

                    if (ExplosionDecoration.HasSmokeExplosionMote)
                    {
                        int smokeNum = ExplosionDecoration.smokeNum.RandomInRange;
                        for (int i = 0; i < smokeNum; i++)
                        {
                            MoteThrower.ThrowSmokeCustom(Vector3Origin + Gen.RandomHorizontalVector(myRadius * 0.7f), map, myRadius * 0.6f, ExplosionDecoration.smokeExplosionMote);
                        }
                    }
                    if (ExplosionDecoration.HasBlastExplosionMote)
                    {
                        int num = Mathf.RoundToInt((float)Math.PI * myRadius * myRadius / ExplosionDecoration.blastNumLimiter.RandomInRange);
                        for (int j = 0; j < num; j++)
                        {
                            MoteMaker.ThrowExplosionInteriorMote(Vector3Origin + Gen.RandomHorizontalVector(myRadius * 0.7f), map, ExplosionDecoration.blastExplosionMote);
                        }
                    }
                }
            }

            if (HasDestroyProcedure && victim.Destroyed && map != null)
            {
                if (DestroyedProcedure.HasNonTree)
                {
                    foreach (IntVec3 item in victim.OccupiedRect())
                    {
                        FilthMaker.TryMakeFilth(item, map, DestroyedProcedure.filthLeft);
                    }
                }

                if (DestroyedProcedure.HasTree && victim is Plant plant && victim.def.plant.IsTree && plant.LifeStage != 0 && victim.def != DestroyedProcedure.thingSpawnedForTrees)
                {
                    ((DeadPlant)GenSpawn.Spawn(DestroyedProcedure.thingSpawnedForTrees, IntVec3Origin, map)).Growth = plant.Growth;
                }
            }

            if (DidSomething && Nature.forceNormalSpeedIfTriggered)
            {
                if (pVictim != null && pVictim.Faction == Faction.OfPlayer)
                {
                    Find.TickManager.slower.SignalForceNormalSpeedShort();
                }
            }

            return(damageResult);
        }