コード例 #1
0
        public void Tick(World world)
        {
            source = args.CurrentSource();

            if (hasLaunchEffect && ticks == 0)
            {
                world.AddFrameEndTask(w => w.Add(new SpriteEffect(args.CurrentSource, args.CurrentMuzzleFacing, world,
                                                                  info.LaunchEffectImage, info.LaunchEffectSequence, info.LaunchEffectPalette)));
            }

            // Beam tracks target
            if (info.TrackTarget && args.GuidedTarget.IsValidFor(args.SourceActor))
            {
                target = args.Weapon.TargetActorCenter ? args.GuidedTarget.CenterPosition : args.GuidedTarget.Positions.PositionClosestTo(source);
            }

            // Check for blocking actors
            WPos blockedPos;

            if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target,
                                                                             info.Width, out blockedPos))
            {
                target = blockedPos;
            }

            if (ticks < info.DamageDuration && --interval <= 0)
            {
                var warheadArgs = new WarheadArgs(args)
                {
                    ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(source, target), args.CurrentMuzzleFacing()),
                    ImpactPosition    = target,
                };

                args.Weapon.Impact(Target.FromPos(target), warheadArgs);
                interval = info.DamageInterval;
            }

            if (showHitAnim)
            {
                if (ticks == 0)
                {
                    hitanim.PlayThen(info.HitAnimSequence, () => showHitAnim = false);
                }

                hitanim.Tick();
            }

            if (++ticks >= info.Duration && !showHitAnim)
            {
                world.AddFrameEndTask(w => w.Remove(this));
            }
        }
        public void Tick(World world)
        {
            source = args.CurrentSource();

            if (hasLaunchEffect && ticks == 0)
            {
                world.AddFrameEndTask(w => w.Add(new LaunchEffect(world, args.CurrentSource, () => 0,
                                                                  info.LaunchEffectImage, info.LaunchEffectSequence, info.LaunchEffectPalette)));
            }

            // Beam tracks target
            if (info.TrackTarget && args.GuidedTarget.IsValidFor(args.SourceActor))
            {
                target = args.Weapon.TargetActorCenter ? args.GuidedTarget.CenterPosition : args.GuidedTarget.Positions.PositionClosestTo(source);
            }

            // Check for blocking actors
            WPos blockedPos;

            if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, source, target,
                                                                             info.Width, out blockedPos))
            {
                target = blockedPos;
            }

            if (ticks < info.DamageDuration && --interval <= 0)
            {
                args.Weapon.Impact(Target.FromPos(target), args.SourceActor, args.DamageModifiers);
                interval = info.DamageInterval;
            }

            if (showHitAnim)
            {
                if (ticks == 0)
                {
                    hitanim.PlayThen(info.HitAnimSequence, () => showHitAnim = false);
                }

                hitanim.Tick();
            }

            if (++ticks >= info.Duration && !showHitAnim)
            {
                world.AddFrameEndTask(w => w.Remove(this));
            }
        }
コード例 #3
0
ファイル: AreaBeam.cs プロジェクト: anvilvapre/OpenRA-1
        public void Tick(World world)
        {
            if (info.TrackTarget)
            {
                TrackTarget();
            }

            if (++headTicks >= length)
            {
                headPos          = target;
                isHeadTravelling = false;
            }
            else if (isHeadTravelling)
            {
                headPos = WPos.LerpQuadratic(args.Source, target, WAngle.Zero, headTicks, length);
            }

            if (tailTicks <= 0 && args.SourceActor.IsInWorld && !args.SourceActor.IsDead)
            {
                args.Source = args.CurrentSource();
                tailPos     = args.Source;
            }

            // Allow for leniency to avoid edge case stuttering (start firing and immediately stop again).
            var outOfWeaponRange = args.Weapon.Range + info.BeyondTargetRange < new WDist((args.PassiveTarget - args.Source).Length);

            // While the head is travelling, the tail must start to follow Duration ticks later.
            // Alternatively, also stop emitting the beam if source actor dies or is ordered to stop.
            if ((headTicks >= info.Duration && !isTailTravelling) || args.SourceActor.IsDead ||
                !actorAttackBase.IsAttacking || outOfWeaponRange)
            {
                StopTargeting();
            }

            if (isTailTravelling)
            {
                if (++tailTicks >= length)
                {
                    tailPos          = target;
                    isTailTravelling = false;
                }
                else
                {
                    tailPos = WPos.LerpQuadratic(args.Source, target, WAngle.Zero, tailTicks, length);
                }
            }

            // Check for blocking actors
            WPos blockedPos;

            if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, tailPos, headPos,
                                                                             info.Width, info.TargetExtraSearchRadius, out blockedPos))
            {
                headPos = blockedPos;
                target  = headPos;
                length  = Math.Min(headTicks, length);
            }

            // Damage is applied to intersected actors every DamageInterval ticks
            if (headTicks % info.DamageInterval == 0)
            {
                var actors = world.FindActorsOnLine(tailPos, headPos, info.Width, info.TargetExtraSearchRadius);
                foreach (var a in actors)
                {
                    var adjustedModifiers = args.DamageModifiers.Append(GetFalloff((args.Source - a.CenterPosition).Length));
                    args.Weapon.Impact(Target.FromActor(a), args.SourceActor, adjustedModifiers);
                }
            }

            if (IsBeamComplete)
            {
                world.AddFrameEndTask(w => w.Remove(this));
            }
        }
コード例 #4
0
        public void Tick(World world)
        {
            if (info.TrackTarget)
            {
                TrackTarget();
            }

            if (++headTicks >= length)
            {
                headPos          = target;
                isHeadTravelling = false;
            }
            else if (isHeadTravelling)
            {
                headPos = WPos.LerpQuadratic(args.Source, target, WAngle.Zero, headTicks, length);
            }

            if (tailTicks <= 0 && args.SourceActor.IsInWorld && !args.SourceActor.IsDead)
            {
                args.Source = args.CurrentSource();
                tailPos     = args.Source;
            }

            // Allow for leniency to avoid edge case stuttering (start firing and immediately stop again).
            var outOfWeaponRange = args.Weapon.Range + info.BeyondTargetRange < new WDist((args.PassiveTarget - args.Source).Length);

            // While the head is travelling, the tail must start to follow Duration ticks later.
            // Alternatively, also stop emitting the beam if source actor dies or is ordered to stop.
            if ((headTicks >= info.Duration && !isTailTravelling) || args.SourceActor.IsDead ||
                !actorAttackBase.IsAiming || outOfWeaponRange)
            {
                StopTargeting();
            }

            if (isTailTravelling)
            {
                if (++tailTicks >= length)
                {
                    tailPos          = target;
                    isTailTravelling = false;
                }
                else
                {
                    tailPos = WPos.LerpQuadratic(args.Source, target, WAngle.Zero, tailTicks, length);
                }
            }

            // Check for blocking actors
            if (info.Blockable && BlocksProjectiles.AnyBlockingActorsBetween(world, tailPos, headPos, info.Width, out var blockedPos))
            {
                headPos = blockedPos;
                target  = headPos;
                length  = Math.Min(headTicks, length);
            }

            // Damage is applied to intersected actors every DamageInterval ticks
            if (headTicks % info.DamageInterval == 0)
            {
                var actors = world.FindActorsOnLine(tailPos, headPos, info.Width);
                foreach (var a in actors)
                {
                    var adjustedModifiers = args.DamageModifiers.Append(GetFalloff((args.Source - a.CenterPosition).Length));

                    var warheadArgs = new WarheadArgs(args)
                    {
                        ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(args.Source, target), args.CurrentMuzzleFacing()),

                        // Calculating an impact position is bogus for line damage.
                        // FindActorsOnLine guarantees that the beam touches the target's HitShape,
                        // so we just assume a center hit to avoid bogus warhead recalculations.
                        ImpactPosition  = a.CenterPosition,
                        DamageModifiers = adjustedModifiers.ToArray(),
                    };

                    args.Weapon.Impact(Target.FromActor(a), warheadArgs);
                }
            }

            if (IsBeamComplete)
            {
                world.AddFrameEndTask(w => w.Remove(this));
            }
        }