void MarkPrimary() { for (int y = 0; y < Height; ++y) { for (int x = 0; x < Width; ++x) { Int2 p = new Int2(x, y); if (IsWalkable(p)) { continue; } for (int d = 0b10000000; d > 0b00001111; d >>= 1) { EDirFlags dir = (EDirFlags)d; var primaryP = p.Foward(dir); var primaryB = GetBlockOrNull(primaryP); if (primaryB == null) { continue; } switch (dir) { case EDirFlags.NORTHEAST: { var p1 = p.Foward(EDirFlags.NORTH); var p2 = p.Foward(EDirFlags.EAST); if (IsWalkable(p1) && IsWalkable(p2)) { primaryB.JumpDirFlags |= EDirFlags.SOUTH | EDirFlags.WEST; } break; } case EDirFlags.SOUTHEAST: { var p1 = p.Foward(EDirFlags.SOUTH); var p2 = p.Foward(EDirFlags.EAST); if (IsWalkable(p1) && IsWalkable(p2)) { primaryB.JumpDirFlags |= EDirFlags.NORTH | EDirFlags.WEST; } break; } case EDirFlags.NORTHWEST: { var p1 = p.Foward(EDirFlags.NORTH); var p2 = p.Foward(EDirFlags.WEST); if (IsWalkable(p1) && IsWalkable(p2)) { primaryB.JumpDirFlags |= EDirFlags.SOUTH | EDirFlags.EAST; } break; } case EDirFlags.SOUTHWEST: { var p1 = p.Foward(EDirFlags.SOUTH); var p2 = p.Foward(EDirFlags.WEST); if (IsWalkable(p1) && IsWalkable(p2)) { primaryB.JumpDirFlags |= EDirFlags.NORTH | EDirFlags.EAST; } break; } default: throw new ArgumentException(); } } } } }
void MarkDiagonal() { // * N . // W . . // . . . for (int y = 0; y < Height; ++y) { // NORTH & WEST for (int x = 0; x < Width; ++x) { Int2 p = new Int2(x, y); JPSPlusMapBakerBlock block = GetBlockOrNull(p); if (block == null) { continue; } if (x == 0 || y == 0) { block.SetDistance(EDirFlags.NORTHWEST, 0); // Diagonal-Wall Distance continue; } Int2 p1 = p.Foward(EDirFlags.NORTH); Int2 p2 = p.Foward(EDirFlags.NORTHWEST); Int2 p3 = p.Foward(EDirFlags.WEST); bool p1Walkable = IsWalkable(p1); bool p3Walkable = IsWalkable(p3); if (!p1Walkable || !IsWalkable(p2) || !p3Walkable) { block.SetDistance(EDirFlags.NORTHWEST, 0); // Diagonal-Wall Distance continue; } JPSPlusMapBakerBlock prevBlock = GetBlockOrNull(p2); if (p1Walkable && p3Walkable && (prevBlock.GetDistance(EDirFlags.NORTH) > 0 || prevBlock.GetDistance(EDirFlags.WEST) > 0)) { block.SetDistance(EDirFlags.NORTHWEST, 1); // Initial Diagonal Distance continue; } int distanceFromPrev = prevBlock.GetDistance(EDirFlags.NORTHWEST); if (distanceFromPrev > 0) { block.SetDistance(EDirFlags.NORTHWEST, distanceFromPrev + 1); // Diagonal Distance } else { block.SetDistance(EDirFlags.NORTHWEST, distanceFromPrev - 1); // Diagonal-Wall Distance } } } // NORTH & WEST // . N * // . . E // . . . for (int y = 0; y < Height; ++y) { // NORTH & EAST for (int x = Width - 1; x >= 0; --x) { Int2 p = new Int2(x, y); JPSPlusMapBakerBlock block = GetBlockOrNull(p); if (block == null) { continue; } if (x == Width - 1 || y == 0) { block.SetDistance(EDirFlags.NORTHEAST, 0); // Diagonal-Wall Distance continue; } Int2 p1 = p.Foward(EDirFlags.NORTH); Int2 p2 = p.Foward(EDirFlags.NORTHEAST); Int2 p3 = p.Foward(EDirFlags.EAST); bool p1Walkable = IsWalkable(p1); bool p3Walkable = IsWalkable(p3); if (!p1Walkable || !IsWalkable(p2) || !p3Walkable) { block.SetDistance(EDirFlags.NORTHEAST, 0); // Diagonal-Wall Distance continue; } JPSPlusMapBakerBlock prevBlock = GetBlockOrNull(p2); if (p1Walkable && p3Walkable && (prevBlock.GetDistance(EDirFlags.NORTH) > 0 || prevBlock.GetDistance(EDirFlags.EAST) > 0)) { block.SetDistance(EDirFlags.NORTHEAST, 1); // Initial Diagonal Distance continue; } int distanceFromPrev = prevBlock.GetDistance(EDirFlags.NORTHEAST); if (distanceFromPrev > 0) { block.SetDistance(EDirFlags.NORTHEAST, distanceFromPrev + 1); // Diagonal Distance } else { block.SetDistance(EDirFlags.NORTHEAST, distanceFromPrev - 1); // Diagonal-Wall Distance } } } // NORTH & EAST // . . . // W . . // * S . for (int y = Height - 1; y >= 0; --y) { // SOUTH & WEST for (int x = 0; x < Width; ++x) { Int2 p = new Int2(x, y); JPSPlusMapBakerBlock block = GetBlockOrNull(p); if (block == null) { continue; } if (x == 0 || y == Height - 1) { block.SetDistance(EDirFlags.SOUTHWEST, 0); // Diagonal-Wall Distance continue; } Int2 p1 = p.Foward(EDirFlags.SOUTH); Int2 p2 = p.Foward(EDirFlags.SOUTHWEST); Int2 p3 = p.Foward(EDirFlags.WEST); bool p1Walkable = IsWalkable(p1); bool p3Walkable = IsWalkable(p3); if (!p1Walkable || !IsWalkable(p2) || !p3Walkable) { block.SetDistance(EDirFlags.SOUTHWEST, 0); // Diagonal-Wall Distance continue; } JPSPlusMapBakerBlock prevBlock = GetBlockOrNull(p2); if (p1Walkable && p3Walkable && (prevBlock.GetDistance(EDirFlags.SOUTH) > 0 || prevBlock.GetDistance(EDirFlags.WEST) > 0)) { block.SetDistance(EDirFlags.SOUTHWEST, 1); // Initial Diagonal Distance continue; } int distanceFromPrev = prevBlock.GetDistance(EDirFlags.SOUTHWEST); if (distanceFromPrev > 0) { block.SetDistance(EDirFlags.SOUTHWEST, distanceFromPrev + 1); // Diagonal Distance } else { block.SetDistance(EDirFlags.SOUTHWEST, distanceFromPrev - 1); // Diagonal-Wall Distance } } } // SOUTH & WEST // . . . // . . E // . S * for (int y = Height - 1; y >= 0; --y) { // SOUTH & EAST for (int x = Width - 1; x >= 0; --x) { Int2 p = new Int2(x, y); JPSPlusMapBakerBlock block = GetBlockOrNull(p); if (block == null) { continue; } if (x == Width - 1 || y == Height - 1) { block.SetDistance(EDirFlags.SOUTHEAST, 0); // Diagonal-Wall Distance continue; } Int2 p1 = p.Foward(EDirFlags.SOUTH); Int2 p2 = p.Foward(EDirFlags.SOUTHEAST); Int2 p3 = p.Foward(EDirFlags.EAST); bool p1Walkable = IsWalkable(p1); bool p3Walkable = IsWalkable(p3); if (!p1Walkable || !IsWalkable(p2) || !p3Walkable) { block.SetDistance(EDirFlags.SOUTHEAST, 0); // Diagonal-Wall Distance continue; } JPSPlusMapBakerBlock prevBlock = GetBlockOrNull(p2); if (p1Walkable && p3Walkable && (prevBlock.GetDistance(EDirFlags.SOUTH) > 0 || prevBlock.GetDistance(EDirFlags.EAST) > 0)) { block.SetDistance(EDirFlags.SOUTHEAST, 1); // Initial Diagonal Distance continue; } int distanceFromPrev = prevBlock.GetDistance(EDirFlags.SOUTHEAST); if (distanceFromPrev > 0) { block.SetDistance(EDirFlags.SOUTHEAST, distanceFromPrev + 1); // Diagonal Distance } else { block.SetDistance(EDirFlags.SOUTHEAST, distanceFromPrev - 1); // Diagonal-Wall Distance } } } // SOUTH & EAST }