| 812 | |
| 813 | |
| 814 | static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileIndex end) |
| 815 | { |
| 816 | int x = TileX(start); |
| 817 | int y = TileY(start); |
| 818 | int ex = TileX(end); |
| 819 | int ey = TileY(end); |
| 820 | |
| 821 | if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR; |
| 822 | |
| 823 | /* calculate delta x,y from start to end tile */ |
| 824 | int dx = ex - x; |
| 825 | int dy = ey - y; |
| 826 | |
| 827 | /* calculate delta x,y for the first direction */ |
| 828 | int trdx = _trackdelta[*trackdir].x; |
| 829 | int trdy = _trackdelta[*trackdir].y; |
| 830 | |
| 831 | if (!IsDiagonalTrackdir(*trackdir)) { |
| 832 | trdx += _trackdelta[*trackdir ^ 1].x; |
| 833 | trdy += _trackdelta[*trackdir ^ 1].y; |
| 834 | } |
| 835 | |
| 836 | /* validate the direction */ |
| 837 | while ((trdx <= 0 && dx > 0) || |
| 838 | (trdx >= 0 && dx < 0) || |
| 839 | (trdy <= 0 && dy > 0) || |
| 840 | (trdy >= 0 && dy < 0)) { |
| 841 | if (!HasBit(*trackdir, 3)) { // first direction is invalid, try the other |
| 842 | SetBit(*trackdir, 3); // reverse the direction |
| 843 | trdx = -trdx; |
| 844 | trdy = -trdy; |
| 845 | } else { // other direction is invalid too, invalid drag |
| 846 | return CMD_ERROR; |
| 847 | } |
| 848 | } |
| 849 | |
| 850 | /* (for diagonal tracks, this is already made sure of by above test), but: |
| 851 | * for non-diagonal tracks, check if the start and end tile are on 1 line */ |
| 852 | if (!IsDiagonalTrackdir(*trackdir)) { |
| 853 | trdx = _trackdelta[*trackdir].x; |
| 854 | trdy = _trackdelta[*trackdir].y; |
| 855 | if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx)) return CMD_ERROR; |
| 856 | } |
| 857 | |
| 858 | return CommandCost(); |
| 859 | } |
| 860 | |
| 861 | /** |
| 862 | * Build or remove a stretch of railroad tracks. |
no test coverage detected