예제 #1
0
        public WithIdleOverlay(Actor self, WithIdleOverlayInfo info)
            : base(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));
            if (info.StartSequence != null)
            {
                overlay.PlayThen(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.StartSequence),
                                 () => overlay.PlayRepeating(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.Sequence)));
            }
            else
            {
                overlay.PlayRepeating(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.Sequence));
            }

            var anim = new AnimationWithOffset(overlay,
                                               () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
                                               () => IsTraitDisabled || !buildComplete,
                                               () => (info.PauseOnLowPower && self.IsDisabled()) || !buildComplete,
                                               p => WithTurret.ZOffsetFromCenter(self, p, 1));

            rs.Add(anim, info.Palette, info.IsPlayerPalette);
        }
예제 #2
0
        public WithParachute(Actor self, WithParachuteInfo info)
            : base(info)
        {
            this.info = info;

            if (info.ShadowImage != null)
            {
                shadow = new Animation(self.World, info.ShadowImage);
                shadow.PlayRepeating(info.ShadowSequence);
            }

            if (info.Image == null)
            {
                return;
            }

            // For this, info.Image must not be null
            var overlay = new Animation(self.World, info.Image);
            var body    = self.Trait <BodyOrientation>();

            anim = new AnimationWithOffset(overlay,
                                           () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
                                           () => IsTraitDisabled && !renderProlonged,
                                           () => false,
                                           p => WithTurret.ZOffsetFromCenter(self, p, 1));

            var rs = self.Trait <RenderSprites>();

            rs.Add(anim, info.Palette);
        }
예제 #3
0
        public override void DoAttack(Actor self, Target target)
        {
            if (!CanAttack(self, target))
            {
                return;
            }

            var pos       = self.CenterPosition;
            var targetYaw = WAngle.FromFacing(OpenRA.Traits.Util.GetFacing(target.CenterPosition - self.CenterPosition, 0));

            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 && 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 += OpenRA.Traits.Util.QuantizeFacing(muzzleFacing, a.Info.MuzzleSplitFacings).ToString();
                    }

                    var muzzleFlash = new AnimationWithOffset(muzzleAnim,
                                                              () => PortOffset(self, port),
                                                              () => false,
                                                              () => false,
                                                              p => WithTurret.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);
                }
            }
        }
예제 #4
0
        public WithMuzzleFlash(Actor self, WithMuzzleFlashInfo 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 = (Func <int>)(() => 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],
                                                      () => false,
                                                      p => WithTurret.ZOffsetFromCenter(self, p, 2)));
                }
            }
        }
예제 #5
0
        public WithRepairOverlay(Actor self, WithRepairOverlayInfo info)
        {
            var rs   = self.Trait <RenderSprites>();
            var body = self.Trait <IBodyOrientation>();

            buildComplete = !self.HasTrait <Building>();            // always render instantly for units
            overlay       = new Animation(self.World, rs.GetImage(self));
            overlay.Play(info.Sequence);

            var anim = new AnimationWithOffset(overlay,
                                               () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
                                               () => !buildComplete,
                                               () => info.PauseOnLowPower && self.IsDisabled(),
                                               p => WithTurret.ZOffsetFromCenter(self, p, 1));

            rs.Add(anim, info.Palette, info.IsPlayerPalette);
        }
예제 #6
0
        public WithIdleOverlay(Actor self, WithIdleOverlayInfo info)
            : base(info)
        {
            var rs       = self.Trait <RenderSprites>();
            var body     = self.Trait <IBodyOrientation>();
            var disabled = self.TraitsImplementing <IDisable>();

            buildComplete = !self.HasTrait <Building>();            // always render instantly for units
            overlay       = new Animation(self.World, rs.GetImage(self));
            overlay.PlayRepeating(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.Sequence));
            rs.Add("idle_overlay_{0}".F(info.Sequence),
                   new AnimationWithOffset(overlay,
                                           () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
                                           () => IsTraitDisabled || !buildComplete,
                                           () => info.PauseOnLowPower && disabled.Any(d => d.Disabled),
                                           p => WithTurret.ZOffsetFromCenter(self, p, 1)),
                   info.Palette, info.IsPlayerPalette);
        }
예제 #7
0
        public WithBarrel(Actor self, WithBarrelInfo info)
        {
            this.self = self;
            this.info = info;
            body      = self.Trait <IBodyOrientation>();
            armament  = self.TraitsImplementing <Armament>()
                        .First(a => a.Info.Name == info.Armament);
            turreted = self.TraitsImplementing <Turreted>()
                       .First(tt => tt.Name == armament.Info.Turret);

            var rs = self.Trait <RenderSprites>();

            anim = new Animation(self.World, rs.GetImage(self), () => turreted.TurretFacing);
            anim.Play(info.Sequence);
            rs.Add(new AnimationWithOffset(
                       anim, () => BarrelOffset(), null, () => false, p => WithTurret.ZOffsetFromCenter(self, p, 0)));

            // Restrict turret facings to match the sprite
            turreted.QuantizedFacings = anim.CurrentSequence.Facings;
        }
예제 #8
0
        public WithBarrel(Actor self, WithBarrelInfo 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, () => false, p => WithTurret.ZOffsetFromCenter(self, p, 0)));

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