Esempio n. 1
0
        public override void DoAttack(Actor self, Target target, IEnumerable <Armament> armaments = null)
        {
            if (!CanAttack(self, target))
            {
                return;
            }

            var pos       = self.CenterPosition;
            var targetYaw = (target.CenterPosition - self.CenterPosition).Yaw;

            foreach (var a in Armaments)
            {
                var port = SelectFirePort(self, targetYaw);
                if (port == null)
                {
                    return;
                }

                var muzzleFacing = targetYaw.Angle / 4;
                paxFacing[a.Actor].Facing = muzzleFacing;
                paxPos[a.Actor].SetVisualPosition(a.Actor, pos + PortOffset(self, port));

                var barrel = a.CheckFire(a.Actor, facing.Value, target);
                if (barrel == null)
                {
                    return;
                }

                if (a.Info.MuzzleSequence != null)
                {
                    // Muzzle facing is fixed once the firing starts
                    var muzzleAnim = new Animation(self.World, paxRender[a.Actor].GetImage(a.Actor), () => muzzleFacing);
                    var sequence   = a.Info.MuzzleSequence;

                    if (a.Info.MuzzleSplitFacings > 0)
                    {
                        sequence += Util.QuantizeFacing(muzzleFacing, a.Info.MuzzleSplitFacings).ToString();
                    }

                    var muzzleFlash = new AnimationWithOffset(muzzleAnim,
                                                              () => PortOffset(self, port),
                                                              () => false,
                                                              p => RenderUtils.ZOffsetFromCenter(self, p, 1024));

                    muzzles.Add(muzzleFlash);
                    muzzleAnim.PlayThen(sequence, () => muzzles.Remove(muzzleFlash));
                }

                foreach (var npa in self.TraitsImplementing <INotifyAttack>())
                {
                    npa.Attacking(self, target, a, barrel);
                }
            }
        }
Esempio n. 2
0
        public override void DoAttack(Actor self, Target target)
        {
            if (!CanAttack(self, target))
            {
                return;
            }

            var pos = self.CenterPosition;
            var targetedPosition = GetTargetPosition(pos, target);
            var targetYaw        = (targetedPosition - pos).Yaw;

            foreach (var a in Armaments)
            {
                if (a.IsTraitDisabled)
                {
                    continue;
                }

                var port = SelectFirePort(self, targetYaw);
                if (port == null)
                {
                    return;
                }

                paxFacing[a.Actor].Facing = targetYaw;
                paxPos[a.Actor].SetVisualPosition(a.Actor, pos + PortOffset(self, port));

                var barrel = a.CheckFire(a.Actor, facing, target);
                if (barrel == null)
                {
                    continue;
                }

                if (a.Info.MuzzleSequence != null)
                {
                    // Muzzle facing is fixed once the firing starts
                    var muzzleAnim  = new Animation(self.World, paxRender[a.Actor].GetImage(a.Actor), () => targetYaw);
                    var sequence    = a.Info.MuzzleSequence;
                    var muzzleFlash = new AnimationWithOffset(muzzleAnim,
                                                              () => PortOffset(self, port),
                                                              () => false,
                                                              p => RenderUtils.ZOffsetFromCenter(self, p, 1024));

                    muzzles.Add(muzzleFlash);
                    muzzleAnim.PlayThen(sequence, () => muzzles.Remove(muzzleFlash));
                }

                foreach (var npa in self.TraitsImplementing <INotifyAttack>())
                {
                    npa.Attacking(self, target, a, barrel);
                }
            }
        }
Esempio n. 3
0
        public WithMuzzleOverlay(Actor self, WithMuzzleOverlayInfo info)
            : base(info)
        {
            var render = self.Trait <RenderSprites>();
            var facing = self.TraitOrDefault <IFacing>();

            armaments = self.TraitsImplementing <Armament>().ToArray();

            foreach (var arm in armaments)
            {
                var armClosure = arm;                   // closure hazard in AnimationWithOffset

                // Skip armaments that don't define muzzles
                if (arm.Info.MuzzleSequence == null)
                {
                    continue;
                }

                foreach (var b in arm.Barrels)
                {
                    var barrel   = b;
                    var turreted = self.TraitsImplementing <Turreted>()
                                   .FirstOrDefault(t => t.Name == arm.Info.Turret);

                    // Workaround for broken ternary operators in certain versions of mono (3.10 and
                    // certain versions of the 3.8 series): https://bugzilla.xamarin.com/show_bug.cgi?id=23319
                    if (turreted != null)
                    {
                        getFacing = () => turreted.TurretFacing;
                    }
                    else if (facing != null)
                    {
                        getFacing = () => facing.Facing;
                    }
                    else
                    {
                        getFacing = () => 0;
                    }

                    var muzzleFlash = new Animation(self.World, render.GetImage(self), getFacing);
                    visible.Add(barrel, false);
                    anims.Add(barrel,
                              new AnimationWithOffset(muzzleFlash,
                                                      () => info.IgnoreOffset ? WVec.Zero : armClosure.MuzzleOffset(self, barrel),
                                                      () => IsTraitDisabled || !visible[barrel],
                                                      p => RenderUtils.ZOffsetFromCenter(self, p, 2)));
                }
            }
        }
Esempio n. 4
0
        public WithRepairOverlay(Actor self, WithRepairOverlayInfo info)
        {
            var rs   = self.Trait <RenderSprites>();
            var body = self.Trait <BodyOrientation>();

            buildComplete = !self.Info.HasTraitInfo <BuildingInfo>();            // always render instantly for units
            overlay       = new Animation(self.World, rs.GetImage(self),
                                          () => info.PauseOnLowPower && self.IsDisabled());
            overlay.PlayThen(info.Sequence, () => visible = false);

            var anim = new AnimationWithOffset(overlay,
                                               () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
                                               () => !visible || !buildComplete,
                                               p => RenderUtils.ZOffsetFromCenter(self, p, 1));

            rs.Add(anim, info.Palette, info.IsPlayerPalette);
        }
Esempio n. 5
0
        public WithSpriteTurret(Actor self, WithSpriteTurretInfo info)
            : base(info)
        {
            rs     = self.Trait <RenderSprites>();
            body   = self.Trait <BodyOrientation>();
            Attack = self.TraitOrDefault <AttackBase>();
            t      = self.TraitsImplementing <Turreted>()
                     .First(tt => tt.Name == info.Turret);
            arms = self.TraitsImplementing <Armament>()
                   .Where(w => w.Info.Turret == info.Turret).ToArray();
            buildComplete = !self.Info.HasTraitInfo <BuildingInfo>();            // always render instantly for units

            DefaultAnimation = new Animation(self.World, rs.GetImage(self), () => t.TurretFacing);
            DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence));
            rs.Add(new AnimationWithOffset(DefaultAnimation,
                                           () => TurretOffset(self),
                                           () => IsTraitDisabled || !buildComplete,
                                           p => RenderUtils.ZOffsetFromCenter(self, p, 1)));

            // Restrict turret facings to match the sprite
            t.QuantizedFacings = DefaultAnimation.CurrentSequence.Facings;
        }
Esempio n. 6
0
        public WithSpriteBarrel(Actor self, WithSpriteBarrelInfo info)
            : base(info)
        {
            this.self = self;
            body      = self.Trait <BodyOrientation>();
            armament  = self.TraitsImplementing <Armament>()
                        .First(a => a.Info.Name == Info.Armament);
            turreted = self.TraitsImplementing <Turreted>()
                       .First(tt => tt.Name == armament.Info.Turret);

            rs = self.Trait <RenderSprites>();
            DefaultAnimation = new Animation(self.World, rs.GetImage(self), () => turreted.TurretFacing);
            DefaultAnimation.PlayRepeating(NormalizeSequence(self, Info.Sequence));
            rs.Add(new AnimationWithOffset(
                       DefaultAnimation, () => BarrelOffset(), () => IsTraitDisabled, p => RenderUtils.ZOffsetFromCenter(self, p, 0)));

            // Restrict turret facings to match the sprite
            turreted.QuantizedFacings = DefaultAnimation.CurrentSequence.Facings;
        }