Node Jump(Node testNode, Node currentNode, Node targetNode) { int dx = testNode.gridX - currentNode.gridX; int dy = testNode.gridY - currentNode.gridY; if (grid.BlockingNodeAt(testNode.gridX, testNode.gridY)) // Can't jump to or through a blocker { return(null); } if (testNode == currentNode) { return(null); } if (testNode == targetNode) // If we reach our goal, continue { return(testNode); } if (dx != 0 && dy != 0) // Check for forced neighbours diagonally { Node horizontal = grid.NodeAtPosition(testNode.gridX + dx, testNode.gridY); Node vertical = grid.NodeAtPosition(testNode.gridX, testNode.gridY + dy); if (Jump(horizontal, testNode, targetNode) != null || Jump(vertical, testNode, targetNode) != null) { return(targetNode); } } else { if (dx != 0) // Check for forced neighbours horizontally { if ((!grid.BlockingNodeAt(testNode.gridX, testNode.gridY - 1) && grid.BlockingNodeAt(currentNode.gridX, testNode.gridY - 1)) || (!grid.BlockingNodeAt(testNode.gridX, testNode.gridY + 1) && grid.BlockingNodeAt(currentNode.gridX, testNode.gridY + 1))) { return(testNode); } } else if (dy != 0) // Check for forced neighbours vertically { if ((!grid.BlockingNodeAt(testNode.gridX - 1, testNode.gridY) && grid.BlockingNodeAt(testNode.gridX - 1, currentNode.gridY)) || (!grid.BlockingNodeAt(testNode.gridX + 1, testNode.gridY) && grid.BlockingNodeAt(testNode.gridX + 1, currentNode.gridY))) { return(testNode); } } } if (!grid.BlockingNodeAt(testNode.gridX + dx, testNode.gridY) && !grid.BlockingNodeAt(testNode.gridX, testNode.gridY + dy)) // Only allow diagonal movement if there is space { Node diagonal = grid.NodeAtPosition(testNode.gridX + dx, testNode.gridY + dy); return(Jump(diagonal, testNode, targetNode)); } return(null); }