Example #1
0
        public static float2 GetTurretPosition(Actor self, Unit unit, int[] offset, float recoil)
        {
            if( unit == null ) return int2.Zero;	/* things that don't have a rotating base don't need the turrets repositioned */

            var ru = self.traits.GetOrDefault<RenderUnit>();
            var numDirs = (ru != null) ? ru.anim.CurrentSequence.Facings : 8;
            var bodyFacing = unit.Facing;
            var quantizedFacing = QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs);

            return (RotateVectorByFacing(offset.RelOffset(), quantizedFacing, .7f) + GetRecoil(self, recoil))
                + offset.AbsOffset();
        }
Example #2
0
        bool CheckFire(Actor self, Unit unit, string weaponName, ref int fireDelay, int[] offset, ref int burst, int[] localOffset)
        {
            if (fireDelay > 0) return false;

            var limitedAmmo = self.traits.GetOrDefault<LimitedAmmo>();
            if (limitedAmmo != null && !limitedAmmo.HasAmmo())
                return false;

            var weapon = Rules.Weapons[weaponName.ToLowerInvariant()];
            if (weapon.Range * weapon.Range < (target.Location - self.Location).LengthSquared) return false;

            if (!Combat.WeaponValidForTarget(weapon, target)) return false;

            var numOffsets = (localOffset.Length + 2) / 3;
            if (numOffsets == 0) numOffsets = 1;
            var localOffsetForShot = burst % numOffsets;
            var thisLocalOffset = localOffset.Skip(3 * localOffsetForShot).Take(3).ToArray();

            var fireOffset = new[] {
                offset.ElementAtOrDefault(0) + thisLocalOffset.ElementAtOrDefault(0),
                offset.ElementAtOrDefault(1) + thisLocalOffset.ElementAtOrDefault(1),
                offset.ElementAtOrDefault(2),
                offset.ElementAtOrDefault(3) };

            if (--burst > 0)
                fireDelay = 5;
            else
            {
                fireDelay = weapon.ROF;
                burst = weapon.Burst;
            }

            var destUnit = target.traits.GetOrDefault<Unit>();

            var args = new ProjectileArgs
            {
                weapon = Rules.Weapons[weaponName.ToLowerInvariant()],

                firedBy = self,
                target = target,

                src = self.CenterLocation.ToInt2() + Util.GetTurretPosition(self, unit, fireOffset, 0f).ToInt2(),
                srcAltitude = unit != null ? unit.Altitude : 0,
                dest = target.CenterLocation.ToInt2(),
                destAltitude = destUnit != null ? destUnit.Altitude : 0,

                facing = thisLocalOffset.ElementAtOrDefault(2) +
                    (self.traits.Contains<Turreted>() ? self.traits.Get<Turreted>().turretFacing :
                    unit != null ? unit.Facing : Util.GetFacing(target.CenterLocation - self.CenterLocation, 0)),
            };

            ScheduleDelayedAction( FireDelay( self, self.Info.Traits.Get<AttackBaseInfo>() ), () =>
            {
                var projectile = args.weapon.Projectile.Create(args);
                if (projectile != null)
                    self.World.Add(projectile);

                if (!string.IsNullOrEmpty(args.weapon.Report))
                    Sound.Play(args.weapon.Report + ".aud");
            });

            foreach (var na in self.traits.WithInterface<INotifyAttack>())
                na.Attacking(self);

            return true;
        }