Пример #1
0
        /// <summary>
        /// Produces a secondary explosion on impact using the explosion values from the projectile's projectile def. Requires the projectile's launcher to be passed on due to protection level,
        /// only works when parent can be cast as ProjectileCR. Intended use is for HEAT and similar weapons that spawn secondary explosions while also penetrating, NOT explosive ammo of
        /// anti-materiel rifles as the explosion just spawns on top of the pawn, not inside the hit body part.
        ///
        /// Additionally handles fragmentation effects if defined.
        /// </summary>
        /// <param name="instigator">Launcher of the projectile calling the method</param>
        public virtual void Explode(Thing instigator, IntVec3 pos, Map map)
        {
            if (map == null)
            {
                Log.Warning("Tried to do explodeCR in a null map.");
                return;
            }
            // Regular explosion stuff
            if (Props.explosionRadius > 0 && Props.explosionDamage > 0 && parent.def != null && GenGrid.InBounds(pos, map))
            {
                GenExplosion.DoExplosion
                    (pos,
                    map,
                    Props.explosionRadius,
                    Props.explosionDamageDef,
                    instigator,
                    Props.soundExplode == null ? Props.explosionDamageDef.soundExplosion : Props.soundExplode,
                    parent.def,
                    null,
                    Props.postExplosionSpawnThingDef           = null,
                    Props.postExplosionSpawnChance             = 0f,
                    Props.postExplosionSpawnThingCount         = 1,
                    Props.applyDamageToExplosionCellsNeighbors = false,
                    Props.preExplosionSpawnThingDef            = null,
                    Props.explosionSpawnChance = 0,
                    Props.preExplosionSpawnThingCount);
            }
            // Fragmentation stuff
            if (!Props.fragments.NullOrEmpty() && GenGrid.InBounds(pos, map))
            {
                if (Props.fragRange <= 0)
                {
                    Log.Error(parent.LabelCap + " has fragments but no fragRange");
                }

                else
                {
                    Vector3 exactOrigin = new Vector3(0, 0, 0);
                    exactOrigin.x = parent.DrawPos.x;
                    exactOrigin.z = parent.DrawPos.z;
                    foreach (ThingCountClass fragment in Props.fragments)
                    {
                        for (int i = 0; i < fragment.count; i++)
                        {
                            ProjectileCR projectile = (ProjectileCR)ThingMaker.MakeThing(fragment.thingDef, null);
                            projectile.canFreeIntercept = true;
                            Vector3         exactTarget = exactOrigin + (new Vector3(1, 0, 1) * UnityEngine.Random.Range(0, Props.fragRange)).RotatedBy(UnityEngine.Random.Range(0, 360));
                            LocalTargetInfo targetCell  = exactTarget.ToIntVec3();
                            GenSpawn.Spawn(projectile, parent.Position, map);
                            projectile.Launch(instigator, exactOrigin, targetCell, exactTarget, null);
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Produces a secondary explosion on impact using the explosion values from the projectile's projectile def. Requires the projectile's launcher to be passed on due to protection level,
        /// only works when parent can be cast as ProjectileCR. Intended use is for HEAT and similar weapons that spawn secondary explosions while also penetrating, NOT explosive ammo of
        /// anti-materiel rifles as the explosion just spawns on top of the pawn, not inside the hit body part.
        ///
        /// Additionally handles fragmentation effects if defined.
        /// </summary>
        /// <param name="instigator">Launcher of the projectile calling the method</param>
        public virtual void Explode(Thing instigator, Verse.IntVec3 pos)
        {
            // Regular explosion stuff
            if (this.Props.explosionRadius > 0 && this.Props.explosionDamage > 0)
            {
                Explosion explosion = new Explosion();
                explosion.position   = pos;
                explosion.radius     = Props.explosionRadius;
                explosion.damType    = Props.explosionDamageDef;
                explosion.instigator = instigator;
                explosion.damAmount  = GenMath.RoundRandom(Props.explosionDamage);
                explosion.source     = parent.def;
                explosion.preExplosionSpawnThingDef            = Props.preExplosionSpawnThingDef;
                explosion.preExplosionSpawnChance              = Props.explosionSpawnChance;
                explosion.postExplosionSpawnThingDef           = Props.postExplosionSpawnThingDef;
                explosion.postExplosionSpawnChance             = Props.explosionSpawnChance;
                explosion.applyDamageToExplosionCellsNeighbors = Props.damageAdjacentTiles;
                Find.Map.GetComponent <ExplosionManager>().StartExplosion(explosion, Props.soundExplode == null ? Props.explosionDamageDef.soundExplosion : Props.soundExplode);
            }

            // Fragmentation stuff
            if (!Props.fragments.NullOrEmpty())
            {
                if (Props.fragRange <= 0)
                {
                    Log.Error(this.parent.LabelCap + " has fragments but no fragRange");
                }

                else
                {
                    Vector3 exactOrigin = new Vector3(0, 0, 0);
                    exactOrigin.x = this.parent.DrawPos.x;
                    exactOrigin.z = this.parent.DrawPos.z;

                    foreach (ThingCount fragment in Props.fragments)
                    {
                        for (int i = 0; i < fragment.count; i++)
                        {
                            ProjectileCR projectile = (ProjectileCR)ThingMaker.MakeThing(fragment.thingDef, null);
                            projectile.canFreeIntercept = true;
                            Vector3    exactTarget = exactOrigin + (new Vector3(1, 0, 1) * UnityEngine.Random.Range(0, Props.fragRange)).RotatedBy(UnityEngine.Random.Range(0, 360));
                            TargetInfo targetCell  = exactTarget.ToIntVec3();
                            GenSpawn.Spawn(projectile, this.parent.Position);
                            projectile.Launch(instigator, exactOrigin, targetCell, exactTarget, null);
                        }
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Scatters fragments around
        /// </summary>
        protected virtual void ScatterFragments(ThingDef projectileDef)
        {
            ProjectileCR projectile = (ProjectileCR)ThingMaker.MakeThing(projectileDef, null);

            projectile.canFreeIntercept = true;

            /*
             * projectile.shotAngle = Random.Range(-3.0f, 0.5f);
             * projectile.shotHeight = 0.1f;
             */

            Vector3    exactTarget = this.ExactPosition + (new Vector3(1, 0, 1) * Random.Range(0, this.fragRange)).RotatedBy(Random.Range(0, 360));
            TargetInfo targetCell  = exactTarget.ToIntVec3();

            GenSpawn.Spawn(projectile, this.Position);

            projectile.Launch(this, this.ExactPosition, targetCell, exactTarget, equipment);
        }
        /// <summary>
        /// Fires a projectile using the new aiming system
        /// </summary>
        /// <returns>True for successful shot, false otherwise</returns>
        protected override bool TryCastShot()
        {
            ShootLine shootLine;

            if (!base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine))
            {
                return(false);
            }
            if (this.projectilePropsCR.pelletCount < 1)
            {
                Log.Error(this.ownerEquipment.LabelBaseCap + " tried firing with pelletCount less than 1.");
                return(false);
            }
            for (int i = 0; i < this.projectilePropsCR.pelletCount; i++)
            {
                Vector3      casterExactPosition = this.caster.DrawPos;
                ProjectileCR projectile          = (ProjectileCR)ThingMaker.MakeThing(projectileDef, null);
                GenSpawn.Spawn(projectile, shootLine.Source);
                float lengthHorizontalSquared = (this.currentTarget.Cell - this.caster.Position).LengthHorizontalSquared;

                //New aiming algorithm
                projectile.canFreeIntercept = true;
                ShiftVecReport report     = this.ShiftVecReportFor(this.currentTarget);
                Vector3        targetVec3 = this.ShiftTarget(report);
                projectile.shotAngle  = this.shotAngle;
                projectile.shotHeight = this.shotHeight;
                projectile.shotSpeed  = this.shotSpeed;
                if (this.currentTarget.Thing != null)
                {
                    projectile.Launch(this.caster, casterExactPosition, new TargetInfo(this.currentTarget.Thing), targetVec3, this.ownerEquipment);
                }
                else
                {
                    projectile.Launch(this.caster, casterExactPosition, new TargetInfo(shootLine.Dest), targetVec3, this.ownerEquipment);
                }
            }
            this.numShotsFired++;
            return(true);
        }
Пример #5
0
        /// <summary>
        /// Fires a projectile using the new aiming system
        /// </summary>
        /// <returns>True for successful shot</returns>
        protected override bool TryCastShot()
        {
            ShootLine shootLine;

            if (!base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine))
            {
                return(false);
            }

            /*if (!this.CanHitTargetFrom(this.caster.Position, this.currentTarget))
             * {
             *  return false;
             * }*/
            Vector3      casterExactPosition = this.caster.DrawPos;
            ProjectileCR projectile          = (ProjectileCR)ThingMaker.MakeThing(this.verbProps.projectileDef, null);

            GenSpawn.Spawn(projectile, shootLine.Source);
            float lengthHorizontalSquared = (this.currentTarget.Cell - this.caster.Position).LengthHorizontalSquared;

            //New aiming algorithm
            projectile.canFreeIntercept = true;
            Vector3 targetVec3 = this.ShiftTarget();

            projectile.shotAngle  = this.shotAngle;
            projectile.shotHeight = this.shotHeight;
            projectile.shotSpeed  = this.shotSpeed;
            if (this.currentTarget.Thing != null)
            {
                projectile.Launch(this.caster, casterExactPosition, new TargetInfo(this.currentTarget.Thing), targetVec3, this.ownerEquipment);
            }
            else
            {
                projectile.Launch(this.caster, casterExactPosition, new TargetInfo(shootLine.Dest), targetVec3, this.ownerEquipment);
            }
            return(true);
        }