Example #1
0
        public virtual void Explode(Thing instigator, Vector3 pos, Map map, float scaleFactor = 1, float?direction = null, List <Thing> ignoredThings = null)
        {
            var posIV = pos.ToIntVec3();

            if (map == null)
            {
                Log.Warning("Tried to do explodeCE in a null map.");
                return;
            }
            if (!posIV.InBounds(map))
            {
                Log.Warning("Tried to explodeCE out of bounds");
                return;
            }

            //Try to throw fragments -- increase count by scaleFactor
            parent.TryGetComp <CompFragments>()?.Throw(pos, map, instigator);//scaleFactor);

            if (Props.explosiveRadius > 0 && //&& Props.damageAmountBase > 0 Disabled to allow flame explosions etc
                parent.def != null)
            {
                //Call GenExplosionCE for main explosion
                GenExplosionCE.DoExplosion(posIV, map, Props.explosiveRadius, Props.explosiveDamageType, instigator,
                                           GenMath.RoundRandom(Props.damageAmountBase), Props.damageAmountBase * 0.1f,
                                           Props.explosionSound, null, parent.def, null,
                                           Props.postExplosionSpawnThingDef, Props.postExplosionSpawnChance, Props.postExplosionSpawnThingCount,
                                           Props.applyDamageToExplosionCellsNeighbors, Props.preExplosionSpawnThingDef, Props.preExplosionSpawnChance,
                                           Props.preExplosionSpawnThingCount, Props.chanceToStartFire, Props.damageFalloff, direction, ignoredThings,
                                           pos.y, scaleFactor);
            }
        }
Example #2
0
        private bool TryDetonate(float stackCountScale = 1)
        {
            if (Find.Maps.IndexOf(Map) < 0)
            {
                return(false);
            }

            CompExplosiveCE comp     = this.TryGetComp <CompExplosiveCE>();
            var             detProps = AmmoDef?.detonateProjectile?.projectile;

            if (comp != null || detProps != null)
            {
                if (Rand.Chance(Mathf.Clamp01(0.75f - Mathf.Pow(HitPoints / MaxHitPoints, 2))))
                {
                    if (comp != null)
                    {
                        comp.Explode(this, Position.ToVector3Shifted(), Map, Mathf.Pow(stackCountScale, 0.333f), null, new List <Thing>()
                        {
                            this
                        });
                    }
                    else
                    {
                        this.TryGetComp <CompFragments>()?.Throw(Position.ToVector3Shifted(), Map, this); //Mathf.Pow(scale, 0.333f));
                    }
                    if (detProps != null)
                    {
                        GenExplosionCE.DoExplosion(Position, Map, detProps.explosionRadius, detProps.damageDef,
                                                   this, detProps.GetDamageAmount(1), GenExplosionCE.GetExplosionAP(detProps),
                                                   detProps.soundExplode,
                                                   null, def, null, detProps.postExplosionSpawnThingDef, detProps.postExplosionSpawnChance,
                                                   detProps.postExplosionSpawnThingCount, detProps.applyDamageToExplosionCellsNeighbors,
                                                   detProps.preExplosionSpawnThingDef, detProps.preExplosionSpawnChance, detProps.preExplosionSpawnThingCount,
                                                   detProps.explosionChanceToStartFire, detProps.explosionDamageFalloff, null, new List <Thing>()
                        {
                            this
                        }, 0f, Mathf.Pow(stackCountScale, 0.333f));
                    }
                }

                return(true);
            }
            return(false);
        }
        protected virtual void Impact(Thing hitThing)
        {
            var ignoredThings = new List <Thing>();

            //Spawn things from preExplosionSpawnThingDef != null
            if (Position.IsValid &&
                def.projectile.preExplosionSpawnChance > 0 &&
                def.projectile.preExplosionSpawnThingDef != null &&
                (Controller.settings.EnableAmmoSystem || !(def.projectile.preExplosionSpawnThingDef is AmmoDef)) &&
                Rand.Value < def.projectile.preExplosionSpawnChance)
            {
                var thingDef = def.projectile.preExplosionSpawnThingDef;

                if (thingDef.IsFilth && Position.Walkable(Map))
                {
                    FilthMaker.TryMakeFilth(Position, Map, thingDef);
                }
                else if (Controller.settings.ReuseNeolithicProjectiles)
                {
                    var reusableAmmo = ThingMaker.MakeThing(thingDef);
                    reusableAmmo.stackCount = 1;
                    reusableAmmo.SetForbidden(true, false);
                    GenPlace.TryPlaceThing(reusableAmmo, Position, Map, ThingPlaceMode.Near);
                    LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_ReusableNeolithicProjectiles, reusableAmmo, OpportunityType.GoodToKnow);
                    ignoredThings.Add(reusableAmmo);
                }
            }

            var explodePos = hitThing?.DrawPos ?? ExactPosition;

            if (!explodePos.ToIntVec3().IsValid)
            {
                Destroy();
                return;
            }

            var explodingComp = this.TryGetComp <CompExplosiveCE>();

            if (explodingComp == null)
            {
                this.TryGetComp <CompFragments>()?.Throw(explodePos, Map, launcher);
            }

            //If the comp exists, it'll already call CompFragments
            if (explodingComp != null || def.projectile.explosionRadius > 0)
            {
                //Handle anything explosive

                if (hitThing is Pawn && (hitThing as Pawn).Dead)
                {
                    ignoredThings.Add((hitThing as Pawn).Corpse);
                }

                var suppressThings = new List <Pawn>();
                var dir            = new float?(origin.AngleTo(Vec2Position()));

                // Opt-out for things without explosionRadius
                if (def.projectile.explosionRadius > 0)
                {
                    GenExplosionCE.DoExplosion(explodePos.ToIntVec3(), Map, def.projectile.explosionRadius,
                                               def.projectile.damageDef, launcher, def.projectile.GetDamageAmount(1), def.projectile.GetDamageAmount(1) * 0.1f,
                                               def.projectile.soundExplode, equipmentDef,
                                               def, null, def.projectile.postExplosionSpawnThingDef, def.projectile.postExplosionSpawnChance, def.projectile.postExplosionSpawnThingCount,
                                               def.projectile.applyDamageToExplosionCellsNeighbors, def.projectile.preExplosionSpawnThingDef, def.projectile.preExplosionSpawnChance,
                                               def.projectile.preExplosionSpawnThingCount, def.projectile.explosionChanceToStartFire, def.projectile.explosionDamageFalloff,
                                               dir, ignoredThings, explodePos.y);

                    // Apply suppression around impact area
                    if (explodePos.y < SuppressionRadius)
                    {
                        suppressThings.AddRange(GenRadial.RadialDistinctThingsAround(explodePos.ToIntVec3(), Map, SuppressionRadius + def.projectile.explosionRadius, true)
                                                .Where(x => x is Pawn).Select(x => x as Pawn));
                    }
                }

                if (explodingComp != null)
                {
                    explodingComp.Explode(this, explodePos, Map, 1f, dir, ignoredThings);

                    if (explodePos.y < SuppressionRadius)
                    {
                        suppressThings.AddRange(GenRadial.RadialDistinctThingsAround(explodePos.ToIntVec3(), Map, SuppressionRadius + (explodingComp.props as CompProperties_ExplosiveCE).explosiveRadius, true)
                                                .Where(x => x is Pawn).Select(x => x as Pawn));
                    }
                }

                foreach (var thing in suppressThings)
                {
                    ApplySuppression(thing as Pawn);
                }
            }

            Destroy();
        }