Exemple #1
0
        /// <summary>
        /// Find a target on the aiming line.
        /// Sets LineTaget when a target is aimed at.
        /// </summary>
        public Fixed AimLineAttack(Mobj shooter, Angle angle, Fixed range)
        {
            currentShooter  = shooter;
            currentShooterZ = shooter.Z + (shooter.Height >> 1) + Fixed.FromInt(8);
            currentRange    = range;

            var targetX = shooter.X + range.ToIntFloor() * Trig.Cos(angle);
            var targetY = shooter.Y + range.ToIntFloor() * Trig.Sin(angle);

            // Can't shoot outside view angles.
            topSlope    = Fixed.FromInt(100) / 160;
            bottomSlope = Fixed.FromInt(-100) / 160;

            lineTarget = null;

            world.PathTraversal.PathTraverse(
                shooter.X, shooter.Y,
                targetX, targetY,
                PathTraverseFlags.AddLines | PathTraverseFlags.AddThings,
                aimTraverseFunc);

            if (lineTarget != null)
            {
                return(currentAimSlope);
            }

            return(Fixed.Zero);
        }
Exemple #2
0
        /// <summary>
        /// Looks for special lines in front of the player to activate.
        /// </summary>
        public void UseLines(Player player)
        {
            var pt = world.PathTraversal;

            useThing = player.Mobj;

            var angle = player.Mobj.Angle;

            var x1 = player.Mobj.X;
            var y1 = player.Mobj.Y;
            var x2 = x1 + useRange.ToIntFloor() * Trig.Cos(angle);
            var y2 = y1 + useRange.ToIntFloor() * Trig.Sin(angle);

            pt.PathTraverse(x1, y1, x2, y2, PathTraverseFlags.AddLines, useTraverseFunc);
        }
Exemple #3
0
        /// <summary>
        /// Fire a hitscan bullet.
        /// If damage == 0, it is just a test trace that will leave linetarget set.
        /// </summary>
        public void LineAttack(Mobj shooter, Angle angle, Fixed range, Fixed slope, int damage)
        {
            currentShooter  = shooter;
            currentShooterZ = shooter.Z + (shooter.Height >> 1) + Fixed.FromInt(8);
            currentRange    = range;
            currentAimSlope = slope;
            currentDamage   = damage;

            var targetX = shooter.X + range.ToIntFloor() * Trig.Cos(angle);
            var targetY = shooter.Y + range.ToIntFloor() * Trig.Sin(angle);

            world.PathTraversal.PathTraverse(
                shooter.X, shooter.Y,
                targetX, targetY,
                PathTraverseFlags.AddLines | PathTraverseFlags.AddThings,
                shootTraverseFunc);
        }
        public bool PathTraverse(Fixed x1, Fixed y1, Fixed x2, Fixed y2, PathTraverseFlags flags, Func <Intercept, bool> trav)
        {
            earlyOut = (flags & PathTraverseFlags.EarlyOut) != 0;

            var validCount = world.GetNewValidCount();

            var bm = world.Map.BlockMap;

            interceptCount = 0;

            if (((x1 - bm.OriginX).Data & (BlockMap.MapBlockSize.Data - 1)) == 0)
            {
                // Don't side exactly on a line.
                x1 += Fixed.One;
            }

            if (((y1 - bm.OriginY).Data & (BlockMap.MapBlockSize.Data - 1)) == 0)
            {
                // Don't side exactly on a line.
                y1 += Fixed.One;
            }

            trace.X  = x1;
            trace.Y  = y1;
            trace.Dx = x2 - x1;
            trace.Dy = y2 - y1;

            x1 -= bm.OriginX;
            y1 -= bm.OriginY;

            var blockX1 = x1.Data >> BlockMap.MapBlockShift;
            var blockY1 = y1.Data >> BlockMap.MapBlockShift;

            x2 -= bm.OriginX;
            y2 -= bm.OriginY;

            var blockX2 = x2.Data >> BlockMap.MapBlockShift;
            var blockY2 = y2.Data >> BlockMap.MapBlockShift;

            Fixed stepX;
            Fixed stepY;

            Fixed partial;

            int blockStepX;
            int blockStepY;

            if (blockX2 > blockX1)
            {
                blockStepX = 1;
                partial    = new Fixed(Fixed.FracUnit - ((x1.Data >> BlockMap.MapBToFrac) & (Fixed.FracUnit - 1)));
                stepY      = (y2 - y1) / Fixed.Abs(x2 - x1);
            }
            else if (blockX2 < blockX1)
            {
                blockStepX = -1;
                partial    = new Fixed((x1.Data >> BlockMap.MapBToFrac) & (Fixed.FracUnit - 1));
                stepY      = (y2 - y1) / Fixed.Abs(x2 - x1);
            }
            else
            {
                blockStepX = 0;
                partial    = Fixed.One;
                stepY      = Fixed.FromInt(256);
            }

            var interceptY = new Fixed(y1.Data >> BlockMap.MapBToFrac) + (partial * stepY);


            if (blockY2 > blockY1)
            {
                blockStepY = 1;
                partial    = new Fixed(Fixed.FracUnit - ((y1.Data >> BlockMap.MapBToFrac) & (Fixed.FracUnit - 1)));
                stepX      = (x2 - x1) / Fixed.Abs(y2 - y1);
            }
            else if (blockY2 < blockY1)
            {
                blockStepY = -1;
                partial    = new Fixed((y1.Data >> BlockMap.MapBToFrac) & (Fixed.FracUnit - 1));
                stepX      = (x2 - x1) / Fixed.Abs(y2 - y1);
            }
            else
            {
                blockStepY = 0;
                partial    = Fixed.One;
                stepX      = Fixed.FromInt(256);
            }

            var interceptX = new Fixed(x1.Data >> BlockMap.MapBToFrac) + (partial * stepX);

            // Step through map blocks.
            // Count is present to prevent a round off error from skipping the break.
            var bx = blockX1;
            var by = blockY1;

            for (var count = 0; count < 64; count++)
            {
                if ((flags & PathTraverseFlags.AddLines) != 0)
                {
                    if (!bm.IterateLines(bx, by, lineInterceptFunc, validCount))
                    {
                        // Early out.
                        return(false);
                    }
                }

                if ((flags & PathTraverseFlags.AddThings) != 0)
                {
                    if (!bm.IterateThings(bx, by, thingInterceptFunc))
                    {
                        // Early out.
                        return(false);
                    }
                }

                if (bx == blockX2 && by == blockY2)
                {
                    break;
                }

                if ((interceptY.ToIntFloor()) == by)
                {
                    interceptY += stepY;
                    bx         += blockStepX;
                }
                else if ((interceptX.ToIntFloor()) == bx)
                {
                    interceptX += stepX;
                    by         += blockStepY;
                }
            }

            // Go through the sorted list.
            return(TraverseIntercepts(trav, Fixed.One));
        }