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)); } }
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 } } }
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); } } }
//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); } } }
//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); } }
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)); }
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); }
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)); }
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); } } }
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); }