예제 #1
0
        public WVec MuzzleOffset(Actor self, Barrel b)
        {
            var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation);
            var localOffset     = b.Offset + new WVec(-Recoil, WDist.Zero, WDist.Zero);

            if (turret.Value != null)
            {
                var turretOrientation = coords.Value.QuantizeOrientation(self, turret.Value.LocalOrientation(self));
                localOffset  = localOffset.Rotate(turretOrientation);
                localOffset += turret.Value.Offset;
            }

            return(coords.Value.LocalToWorld(localOffset.Rotate(bodyOrientation)));
        }
예제 #2
0
        void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel)
        {
            if (IsTraitDisabled || IsTraitPaused)
            {
                return;
            }

            if (!Info.ArmamentNames.Contains(a.Info.Name))
            {
                return;
            }

            if (Info.RevokeOnNewTarget)
            {
                if (TargetChanged(lastTarget, target))
                {
                    RevokeInstance(self, Info.RevokeAll);
                }

                lastTarget = target;
            }

            cooldown = Info.RevokeDelay;

            if (!Info.IsCyclic && tokens.Count >= Info.MaximumInstances)
            {
                return;
            }

            shotsFired++;
            var requiredShots = tokens.Count < Info.RequiredShotsPerInstance.Length
                                ? Info.RequiredShotsPerInstance[tokens.Count]
                                : Info.RequiredShotsPerInstance[Info.RequiredShotsPerInstance.Length - 1];

            if (shotsFired >= requiredShots)
            {
                if (Info.IsCyclic && tokens.Count == Info.MaximumInstances)
                {
                    RevokeInstance(self, true);
                }
                else
                {
                    GrantInstance(self, Info.Condition);
                }

                shotsFired = 0;
            }
        }
예제 #3
0
파일: Armament.cs 프로젝트: reaperrr/OpenRA
        protected virtual WVec CalculateMuzzleOffset(Actor self, Barrel b)
        {
            var bodyOrientation = coords.QuantizeOrientation(self, self.Orientation);
            var localOffset     = b.Offset + new WVec(-Recoil, WDist.Zero, WDist.Zero);

            if (turret != null)
            {
                // WorldOrientation is quantized to satisfy the *Fudges.
                // Need to then convert back to a pseudo-local coordinate space, apply offsets,
                // then rotate back at the end
                var turretOrientation = turret.WorldOrientation(self) - bodyOrientation;
                localOffset  = localOffset.Rotate(turretOrientation);
                localOffset += turret.Offset;
            }

            return(coords.LocalToWorld(localOffset.Rotate(bodyOrientation)));
        }
예제 #4
0
        public void Attacking(Actor self, Target target, Armament a, Barrel barrel)
        {
            var sequence = a.Info.MuzzleSequence;

            if (sequence == null)
            {
                return;
            }

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

            visible[barrel] = true;
            anims[barrel].Animation.PlayThen(sequence, () => visible[barrel] = false);
        }
예제 #5
0
        IEnumerable <IRenderable> RenderArmaments(Actor self, AttackBase attack)
        {
            // Fire ports on garrisonable structures
            var garrison = attack as AttackGarrisoned;

            if (garrison != null)
            {
                var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation);
                foreach (var p in garrison.Info.Ports)
                {
                    var pos = self.CenterPosition + coords.Value.LocalToWorld(p.Offset.Rotate(bodyOrientation));
                    var da  = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw + p.Cone)).Rotate(bodyOrientation));
                    var db  = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw - p.Cone)).Rotate(bodyOrientation));

                    yield return(new LineAnnotationRenderable(pos, pos + da * 224 / da.Length, 1, Color.White));

                    yield return(new LineAnnotationRenderable(pos, pos + db * 224 / da.Length, 1, Color.White));
                }

                yield break;
            }

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

                foreach (var b in a.Barrels)
                {
                    var barrelEnd = new Barrel
                    {
                        Offset = b.Offset + new WVec(224, 0, 0),
                        Yaw    = b.Yaw
                    };

                    var muzzle    = self.CenterPosition + a.MuzzleOffset(self, b);
                    var endMuzzle = self.CenterPosition + a.MuzzleOffset(self, barrelEnd);
                    yield return(new LineAnnotationRenderable(muzzle, endMuzzle, 1, Color.White));
                }
            }
        }
예제 #6
0
        protected virtual WVec CalculateMuzzleOffset(Actor self, Barrel b)
        {
            // Weapon offset in turret coordinates
            var localOffset = b.Offset + new WVec(-Recoil, WDist.Zero, WDist.Zero);

            // Turret coordinates to body coordinates
            var bodyOrientation = coords.QuantizeOrientation(self, self.Orientation);

            if (turret != null)
            {
                localOffset = localOffset.Rotate(turret.WorldOrientation) + turret.Offset.Rotate(bodyOrientation);
            }
            else
            {
                localOffset = localOffset.Rotate(bodyOrientation);
            }

            // Body coordinates to world coordinates
            return(coords.LocalToWorld(localOffset));
        }
예제 #7
0
        void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel)
        {
            if (IsTraitDisabled)
            {
                return;
            }

            if (!info.ArmamentNames.Contains(a.Info.Name))
            {
                return;
            }

            var targetPlayer = GetTargetPlayer(target);

            if (targetPlayer != null && targetPlayer.WinState == WinState.Undefined)
            {
                self.World.AddFrameEndTask(w => w.Add(new RevealShroudEffect(self.CenterPosition, info.Radius,
                                                                             info.RevealGeneratedShroud ? Shroud.SourceType.Visibility : Shroud.SourceType.PassiveVisibility,
                                                                             targetPlayer, info.RevealForStancesRelativeToTarget, duration: info.Duration)));
            }
        }
예제 #8
0
 public void Attacking(Actor self, Target target, Armament a, Barrel barrel)
 {
     --charges;
     timeToRecharge = info.ReloadTime;
 }
예제 #9
0
 public void Attacking(Actor self, Target target, Armament a, Barrel barrel)
 {
     if (self.World.SharedRandom.Next(100 / info.AttackPanicChance) == 0)
         Panic();
 }
예제 #10
0
파일: Armament.cs 프로젝트: reaperrr/OpenRA
 public WRot MuzzleOrientation(Actor self, Barrel b)
 {
     return(CalculateMuzzleOrientation(self, b));
 }
예제 #11
0
파일: Armament.cs 프로젝트: reaperrr/OpenRA
 public WVec MuzzleOffset(Actor self, Barrel b)
 {
     return(CalculateMuzzleOffset(self, b));
 }
예제 #12
0
파일: Armament.cs 프로젝트: reaperrr/OpenRA
        protected virtual void FireBarrel(Actor self, IFacing facing, Target target, Barrel barrel)
        {
            foreach (var na in notifyAttacks)
            {
                na.PreparingAttack(self, target, this, barrel);
            }

            Func <WPos> muzzlePosition     = () => self.CenterPosition + MuzzleOffset(self, barrel);
            var         legacyFacing       = MuzzleOrientation(self, barrel).Yaw.Angle / 4;
            Func <int>  legacyMuzzleFacing = () => MuzzleOrientation(self, barrel).Yaw.Angle / 4;

            var passiveTarget = Weapon.TargetActorCenter ? target.CenterPosition : target.Positions.PositionClosestTo(muzzlePosition());
            var initialOffset = Weapon.FirstBurstTargetOffset;

            if (initialOffset != WVec.Zero)
            {
                // We want this to match Armament.LocalOffset, so we need to convert it to forward, right, up
                initialOffset  = new WVec(initialOffset.Y, -initialOffset.X, initialOffset.Z);
                passiveTarget += initialOffset.Rotate(WRot.FromFacing(legacyFacing));
            }

            var followingOffset = Weapon.FollowingBurstTargetOffset;

            if (followingOffset != WVec.Zero)
            {
                // We want this to match Armament.LocalOffset, so we need to convert it to forward, right, up
                followingOffset = new WVec(followingOffset.Y, -followingOffset.X, followingOffset.Z);
                passiveTarget  += ((Weapon.Burst - Burst) * followingOffset).Rotate(WRot.FromFacing(legacyFacing));
            }

            var args = new ProjectileArgs
            {
                Weapon = Weapon,
                Facing = legacyFacing,
                CurrentMuzzleFacing = legacyMuzzleFacing,

                DamageModifiers = damageModifiers.ToArray(),

                InaccuracyModifiers = inaccuracyModifiers.ToArray(),

                RangeModifiers = rangeModifiers.ToArray(),

                Source        = muzzlePosition(),
                CurrentSource = muzzlePosition,
                SourceActor   = self,
                PassiveTarget = passiveTarget,
                GuidedTarget  = target
            };

            ScheduleDelayedAction(Info.FireDelay, () =>
            {
                if (args.Weapon.Projectile != null)
                {
                    var projectile = args.Weapon.Projectile.Create(args);
                    if (projectile != null)
                    {
                        self.World.Add(projectile);
                    }

                    if (args.Weapon.Report != null && args.Weapon.Report.Any())
                    {
                        Game.Sound.Play(SoundType.World, args.Weapon.Report, self.World, self.CenterPosition);
                    }

                    if (Burst == args.Weapon.Burst && args.Weapon.StartBurstReport != null && args.Weapon.StartBurstReport.Any())
                    {
                        Game.Sound.Play(SoundType.World, args.Weapon.StartBurstReport, self.World, self.CenterPosition);
                    }

                    foreach (var na in notifyAttacks)
                    {
                        na.Attacking(self, target, this, barrel);
                    }

                    Recoil = Info.Recoil;
                }
            });
        }
예제 #13
0
 void INotifyAttack.PreparingAttack(Actor self, OpenRA.Traits.Target target, Armament a, Barrel barrel)
 {
 }
예제 #14
0
 void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel)
 {
     ChargeLevel = 0;
 }
예제 #15
0
 void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel)
 {
     --charges;
     timeToRecharge = info.ReloadDelay;
 }
예제 #16
0
 protected virtual WRot CalculateMuzzleOrientation(Actor self, Barrel b)
 {
     return(WRot.FromYaw(b.Yaw).Rotate(turret != null ? turret.WorldOrientation : self.Orientation));
 }
예제 #17
0
 void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel)
 {
 }
예제 #18
0
 public void Attacking(Actor self, Target target, Armament a, Barrel barrel)
 {
     Attacking(self, target);
 }