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, p => RenderUtils.ZOffsetFromCenter(self, p, 1)); var rs = self.Trait <RenderSprites>(); rs.Add(anim, info.Palette); }
public override void DoAttack(Actor self, Target target, IEnumerable <Armament> armaments = null) { 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; } 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, 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), () => 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); } } }
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), () => (info.PauseOnLowPower && self.IsDisabled()) || !buildComplete); 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, p => RenderUtils.ZOffsetFromCenter(self, p, 1)); rs.Add(anim, info.Palette, info.IsPlayerPalette); }
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))); } } }
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); }
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; }
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; }