Example #1
0
 public void Rotate(Dir8 dir, int n, Dir8 expected, bool exception = false)
 {
     if (exception)
     {
         Assert.Throws <ArgumentOutOfRangeException>(() => { dir.Rotate(n); });
     }
     else
     {
         Assert.That(dir.Rotate(n), Is.EqualTo(expected));
     }
 }
Example #2
0
        private void ChooseActionFromDirection(PlayerTurnEvent e, Dir8 dir, bool shift)
        {
            Point    targetPoint    = Player.Position.PointInDir(dir);
            Creature targetCreature = CreatureAt(targetPoint);

            if (targetCreature != null)
            {
                e.ChosenAction = new MeleeAttackAction(Player, targetCreature);
                return;
            }
            // Check for wall sliding:
            bool wallSliding = false;

            if (!TileDefinition.IsPassable(TileTypeAt(targetPoint)))
            {
                Point cwPoint  = Player.Position.PointInDir(dir.Rotate(true));
                Point ccwPoint = Player.Position.PointInDir(dir.Rotate(false));
                if (TileDefinition.IsPassable(TileTypeAt(cwPoint)) && !TileDefinition.IsPassable(TileTypeAt(ccwPoint)))
                {
                    wallSliding    = true;
                    dir            = dir.Rotate(true);
                    targetPoint    = Player.Position.PointInDir(dir);
                    targetCreature = CreatureAt(targetPoint);
                }
                else if (!TileDefinition.IsPassable(TileTypeAt(cwPoint)) && TileDefinition.IsPassable(TileTypeAt(ccwPoint)))
                {
                    wallSliding    = true;
                    dir            = dir.Rotate(false);
                    targetPoint    = Player.Position.PointInDir(dir);
                    targetCreature = CreatureAt(targetPoint);
                }
            }
            if (targetCreature != null)
            {
                e.ChosenAction = new MeleeAttackAction(Player, targetCreature);
            }
            else
            {
                e.ChosenAction = new WalkAction(Player, targetPoint);
                if (shift && !wallSliding)
                {
                    walkDir = dir;                                       // Don't set walkDir for attacks or wall slides
                }
            }
        }
Example #3
0
        private static IEnumerable <Point> PointsAtChebyshevDistanceInternal(
            this Point source, int distance, bool clockwise, bool orderByEuclideanDistance, Dir8 startDir)
        {
            if (distance == 0)
            {
                yield return(source);

                yield break;
            }
            if (orderByEuclideanDistance)
            {
                Dir4 orthoDir = (Dir4)startDir;                 // If this bool is true, startDir must be orthogonal
                foreach (Point p in source.StartingPointsAtChebyshevDistance(distance, clockwise, orthoDir))
                {
                    yield return(p);
                }
                if (distance > 1)
                {
                    var  enumerators = new IEnumerator <Point> [4];
                    Dir4 currentDir  = orthoDir;
                    for (int i = 0; i < 4; ++i)
                    {
                        enumerators[i] = source.MiddlePointsAtChebyshevDistance(distance, clockwise, currentDir).GetEnumerator();
                        currentDir     = currentDir.Rotate(clockwise);
                    }
                    // MiddlePointsAtChebyshevDistance *must* provide pairs, so 2 points are yielded for each, per iteration:
                    while (enumerators[0].MoveNext() && enumerators[1].MoveNext() && enumerators[2].MoveNext() && enumerators[3].MoveNext())
                    {
                        for (int i = 0; i < 4; ++i)
                        {
                            yield return(enumerators[i].Current);

                            enumerators[i].MoveNext();
                            yield return(enumerators[i].Current);
                        }
                    }
                }
                foreach (Point p in source.FinalPointsAtChebyshevDistance(distance, clockwise, orthoDir))
                {
                    yield return(p);
                }
            }
            else
            {
                Dir8 currentDir = startDir;
                for (int i = 0; i < 8; ++i)
                {
                    foreach (Point p in source.PointsInOctantAtChebyshevDistance(distance, clockwise, currentDir))
                    {
                        yield return(p);
                    }
                    currentDir = currentDir.Rotate(clockwise);
                }
            }
        }
Example #4
0
        //todo, old code had pairs...not sure what to do with these yet. add only if needed:
        //public static int[][] FourDirectionPairs = { new int[] { 8, 2 }, new int[] { 6, 4 } };
        //public static int[][] EightDirectionPairs = { new int[] { 8, 2 }, new int[] { 9, 1 }, new int[] { 6, 4 }, new int[] { 3, 7 } };

        public static IEnumerable <Dir8> Enumerate(bool clockwise, bool includeNeutral, bool orthogonalsFirst, Dir8 startDir = Dir8.N)
        {
            if (includeNeutral)
            {
                yield return(Dir8.Neutral);
            }
            if (orthogonalsFirst)
            {
                Dir4 orthoDir, diagDir;
                if (startDir.IsOrthogonal())
                {
                    orthoDir = (Dir4)startDir;
                    diagDir  = (Dir4)startDir.Rotate(clockwise);
                }
                else
                {
                    orthoDir = (Dir4)startDir.Rotate(clockwise);
                    diagDir  = (Dir4)startDir;
                }
                for (int i = 0; i < 4; ++i)
                {
                    yield return((Dir8)orthoDir);

                    orthoDir = orthoDir.Rotate(clockwise);
                }
                for (int i = 0; i < 4; ++i)
                {
                    yield return((Dir8)diagDir);

                    diagDir = diagDir.Rotate(clockwise);
                }
            }
            else
            {
                for (int i = 0; i < 8; ++i)
                {
                    yield return(startDir);

                    startDir = startDir.Rotate(clockwise);
                }
            }
        }
Example #5
0
        //todo needs xml notes
        public static IEnumerable <Dir8> GetDirectionsInArc(this Dir8 dir, int distance, bool clockwise, bool extendArcInBothDirections)
        {
            int startIdx;

            if (extendArcInBothDirections)
            {
                dir      = dir.Rotate(!clockwise, distance);
                startIdx = -distance;
            }
            else
            {
                startIdx = 0;
            }

            for (int i = startIdx; i <= distance; ++i)
            {
                yield return(dir);

                dir = dir.Rotate(clockwise);
            }
        }
Example #6
0
 public static Dir8 AddAngles(Dir8 dir1, Dir8 dir2)
 {
     // dir1 is validated by Dir8.Rotate
     if (!dir2.Validate())
     {
         throw new ArgumentOutOfRangeException(nameof(dir2), dir2, "Invalid enum value.");
     }
     if (dir1 == Dir8.None || dir2 == Dir8.None)
     {
         return(Dir8.None);
     }
     return(dir1.Rotate((int)dir2));
 }
Example #7
0
 public static Dir8 Rotate(this Dir8 dir, bool clockwise, int times)
 {
     if (dir == Dir8.Neutral)
     {
         return(Dir8.Neutral);
     }
     if (times < 0)
     {
         times     = -times;
         clockwise = !clockwise;
     }
     for (int i = 0; i < times; ++i)
     {
         dir = dir.Rotate(clockwise);
     }
     return(dir);
 }
Example #8
0
 public static IEnumerable <Point> EnumeratePointsAtChebyshevDistance(
     this Point source, int distance, bool clockwise, bool orderByEuclideanDistance, Dir8 startDir = Dir8.N)
 {
     if (distance < 0)
     {
         throw new ArgumentException("distance must be nonnegative");
     }
     if (!startDir.IsValid(false))
     {
         throw new ArgumentException("startDir must be an orthogonal or diagonal");
     }
     if (orderByEuclideanDistance && startDir.IsDiagonal())
     {
         // If ordering by Euclidean distance, we'll be starting at an orthogonal direction anyway:
         startDir = startDir.Rotate(clockwise);
     }
     return(source.PointsAtChebyshevDistanceInternal(distance, clockwise, orderByEuclideanDistance, startDir));
 }
Example #9
0
 public static IEnumerable <Point> EnumeratePointsByChebyshevDistance(
     this Point source, bool clockwise, bool orderByEuclideanDistance, Dir8 startDir = Dir8.N)
 {
     if (!startDir.IsValid(false))
     {
         throw new ArgumentException("startDir must be an orthogonal or diagonal");
     }
     if (orderByEuclideanDistance && startDir.IsDiagonal())
     {
         // If ordering by Euclidean distance, we'll be starting at an orthogonal direction anyway:
         startDir = startDir.Rotate(clockwise);
     }
     for (int distance = 0; ; ++distance)
     {
         foreach (Point p in source.PointsAtChebyshevDistanceInternal(distance, clockwise, orderByEuclideanDistance, startDir))
         {
             yield return(p);
         }
     }
 }
Example #10
0
        public static List <Dir8> GetForkDirs(Loc point, LocTest checkBlock, LocTest checkDiagBlock)
        {
            List <Dir8> forks       = new List <Dir8>();
            bool        prevBlocked = IsDirBlocked(point, Dir8.Down, checkBlock, checkDiagBlock);
            Dir8        dir         = Dir8.DownLeft;

            do
            {
                bool newBlock = IsDirBlocked(point, dir, checkBlock, checkDiagBlock);
                if (newBlock != prevBlocked)
                {
                    if (!newBlock)
                    {
                        forks.Add(dir);
                    }
                    prevBlocked = newBlock;
                }

                dir = dir.Rotate(1);
            }while (dir != Dir8.DownLeft);

            return(forks);
        }