Example #1
0
        public void Tick(World world)
        {
            t += 40;

            if (anim != null)
            {
                anim.Tick();
            }

            if (t > TotalTime())
            {
                Explode(world);
            }

            {
                var at       = (float)t / TotalTime();
                var altitude = float2.Lerp(Args.srcAltitude, Args.destAltitude, at);
                var pos      = float2.Lerp(Args.src.ToFloat2(), Args.dest.ToFloat2(), at) - new float2(0, altitude);

                var highPos = (Info.High || Info.Angle > 0)
                                        ? (pos - new float2(0, GetAltitude()))
                                        : pos;

                if (Info.Trail != null && --ticksToNextSmoke < 0)
                {
                    world.AddFrameEndTask(w => w.Add(
                                              new Smoke(w, (PPos)highPos.ToInt2(), Info.Trail)));
                    ticksToNextSmoke = Info.TrailInterval;
                }

                if (Trail != null)
                {
                    var alt = (Info.High || Info.Angle > 0) ? GetAltitude() : 0;
                    Trail.Tick(new PPos((int)pos.X, (int)pos.Y).ToWPos((int)alt));
                }
            }

            if (!Info.High)                     // check for hitting a wall
            {
                var at   = (float)t / TotalTime();
                var pos  = float2.Lerp(Args.src.ToFloat2(), Args.dest.ToFloat2(), at);
                var cell = ((PPos)pos.ToInt2()).ToCPos();

                if (world.ActorMap.GetUnitsAt(cell).Any(
                        a => a.HasTrait <IBlocksBullets>()))
                {
                    Args.dest = (PPos)pos.ToInt2();
                    Explode(world);
                }
            }
        }
Example #2
0
        public void Tick(World world)
        {
            t += 40;

            // In pixels
            var dist = Args.target.CenterLocation + offset - PxPosition;

            var targetAltitude = 0;

            if (Args.target.IsValid && Args.target.IsActor && Args.target.Actor.HasTrait <IMove>())
            {
                targetAltitude = Args.target.Actor.Trait <IMove>().Altitude;
            }

            Altitude += Math.Sign(targetAltitude - Altitude);

            if (Args.target.IsValid)
            {
                Facing = Traits.Util.TickFacing(Facing,
                                                Traits.Util.GetFacing(dist, Facing),
                                                Info.ROT);
            }

            anim.Tick();

            if (dist.LengthSquared < MissileCloseEnough * MissileCloseEnough && Args.target.IsValid)
            {
                Explode(world);
            }

            // TODO: Replace this with a lookup table
            var dir = (-float2.FromAngle((float)(Facing / 128f * Math.PI))).ToPSubVec();

            var move = Info.Speed * dir;

            if (targetAltitude > 0 && Info.TurboBoost)
            {
                move = (move * 3) / 2;
            }
            move = move / 5;

            SubPxPosition += move;

            if (Info.Trail != null)
            {
                var sp = ((SubPxPosition - (move * 3) / 2)).ToPPos() - new PVecInt(0, Altitude);

                if (--ticksToNextSmoke < 0)
                {
                    world.AddFrameEndTask(w => w.Add(new Smoke(w, sp, Info.Trail)));
                    ticksToNextSmoke = Info.TrailInterval;
                }
            }

            if (Info.RangeLimit != 0 && t > Info.RangeLimit * 40)
            {
                Explode(world);
            }

            if (!Info.High)                     // check for hitting a wall
            {
                var cell = PxPosition.ToCPos();
                if (world.ActorMap.GetUnitsAt(cell).Any(a => a.HasTrait <IBlocksBullets>()))
                {
                    Explode(world);
                }
            }

            if (Trail != null)
            {
                Trail.Tick(PxPosition - new PVecInt(0, Altitude));
            }
        }
Example #3
0
        public void Tick(World world)
        {
            t += 40;

            // In pixels
            var dist = Args.target.CenterLocation + offset - PxPosition;

            var targetAltitude = 0;

            if (Args.target.IsValid && Args.target.IsActor && Args.target.Actor.HasTrait <IMove>())
            {
                targetAltitude = Args.target.Actor.Trait <IMove>().Altitude;
            }

            var jammed = Info.Jammable && world.ActorsWithTrait <JamsMissiles>().Any(tp =>
                                                                                     (tp.Actor.CenterLocation - PxPosition).ToCVec().Length <= tp.Trait.Range

                                                                                     && (tp.Actor.Owner.Stances[Args.firedBy.Owner] != Stance.Ally ||
                                                                                         (tp.Actor.Owner.Stances[Args.firedBy.Owner] == Stance.Ally && tp.Trait.AlliedMissiles))

                                                                                     && world.SharedRandom.Next(100 / tp.Trait.Chance) == 0);

            if (!jammed)
            {
                Altitude += Math.Sign(targetAltitude - Altitude);
                if (Args.target.IsValid)
                {
                    Facing = Traits.Util.TickFacing(Facing,
                                                    Traits.Util.GetFacing(dist, Facing),
                                                    Info.ROT);
                }
            }
            else
            {
                Altitude += world.SharedRandom.Next(-1, 2);
                Facing    = Traits.Util.TickFacing(Facing,
                                                   Facing + world.SharedRandom.Next(-20, 21),
                                                   Info.ROT);
            }

            anim.Tick();

            if (dist.LengthSquared < MissileCloseEnough * MissileCloseEnough && Args.target.IsValid)
            {
                Explode(world);
            }

            // TODO: Replace this with a lookup table
            var dir = (-float2.FromAngle((float)(Facing / 128f * Math.PI))).ToPSubVec();

            var move = Info.Speed * dir;

            if (targetAltitude > 0 && Info.TurboBoost)
            {
                move = (move * 3) / 2;
            }
            move = move / 5;

            SubPxPosition += move;

            if (Info.Trail != null)
            {
                var sp = ((SubPxPosition - (move * 3) / 2)).ToPPos() - new PVecInt(0, Altitude);

                if (--ticksToNextSmoke < 0)
                {
                    world.AddFrameEndTask(w => w.Add(new Smoke(w, sp, Info.Trail)));
                    ticksToNextSmoke = Info.TrailInterval;
                }
            }

            if (Info.RangeLimit != 0 && t > Info.RangeLimit * 40)
            {
                Explode(world);
            }

            if (!Info.High)                     // check for hitting a wall
            {
                var cell = PxPosition.ToCPos();
                if (world.ActorMap.GetUnitsAt(cell).Any(a => a.HasTrait <IBlocksBullets>()))
                {
                    Explode(world);
                }
            }

            if (Trail != null)
            {
                Trail.Tick(PxPosition.ToWPos(Altitude));
            }
        }