| author | celestar |
| Sun, 03 Apr 2005 06:26:31 +0000 | |
| changeset 1634 | 473f8efef832 |
| parent 1617 | 55878ca5ada9 |
| child 1643 | d38655053062 |
| permissions | -rw-r--r-- |
| 1247 | 1 |
#include "stdafx.h" |
2 |
#include "ttd.h" |
|
|
1299
0a6510cc889b
(svn r1803) Move debugging stuff into files of it's own
tron
parents:
1248
diff
changeset
|
3 |
#include "debug.h" |
| 1247 | 4 |
#include "npf.h" |
5 |
#include "aystar.h" |
|
6 |
#include "macros.h" |
|
7 |
#include "pathfind.h" |
|
8 |
#include "station.h" |
|
9 |
#include "tile.h" |
|
|
1313
bba6afb8a995
(svn r1817) -Codechange: Moved depot-functions to depot.c
truelight
parents:
1299
diff
changeset
|
10 |
#include "depot.h" |
| 1247 | 11 |
|
12 |
AyStar _train_find_station; |
|
13 |
AyStar _train_find_depot; |
|
14 |
AyStar _road_find_station; |
|
15 |
AyStar _road_find_depot; |
|
16 |
AyStar _npf_aystar; |
|
17 |
||
18 |
/* Maps a trackdir to the bit that stores its status in the map arrays, in the |
|
19 |
* direction along with the trackdir */ |
|
20 |
const byte _signal_along_trackdir[14] = {
|
|
21 |
0x80, 0x80, 0x80, 0x20, 0x40, 0x10, 0, 0, |
|
22 |
0x40, 0x40, 0x40, 0x10, 0x80, 0x20 |
|
23 |
}; |
|
24 |
||
25 |
/* Maps a trackdir to the bit that stores its status in the map arrays, in the |
|
26 |
* direction against the trackdir */ |
|
27 |
const byte _signal_against_trackdir[14] = {
|
|
28 |
0x40, 0x40, 0x40, 0x10, 0x80, 0x20, 0, 0, |
|
29 |
0x80, 0x80, 0x80, 0x20, 0x40, 0x10 |
|
30 |
}; |
|
31 |
||
32 |
/* Maps a trackdir to the trackdirs that can be reached from it (ie, when |
|
33 |
* entering the next tile */ |
|
34 |
const uint16 _trackdir_reaches_trackdirs[14] = {
|
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
35 |
0x1009, 0x0016, 0x1009, 0x0016, 0x0520, 0x0016, 0, 0, |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
36 |
0x0520, 0x2A00, 0x2A00, 0x0520, 0x2A00, 0x1009 |
| 1247 | 37 |
}; |
38 |
||
39 |
/* Maps a trackdir to all trackdirs that make 90 deg turns with it. */ |
|
40 |
const uint16 _trackdir_crosses_trackdirs[14] = {
|
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
41 |
0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C, 0, 0, |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
42 |
0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C |
| 1247 | 43 |
}; |
44 |
||
45 |
/* Maps a track to all tracks that make 90 deg turns with it. */ |
|
46 |
const byte _track_crosses_tracks[6] = {
|
|
47 |
0x2, /* Track 1 -> Track 2 */ |
|
48 |
0x1, /* Track 2 -> Track 1 */ |
|
49 |
0x30, /* Upper -> Left | Right */ |
|
50 |
0x30, /* Lower -> Left | Right */ |
|
51 |
0x0C, /* Left -> Upper | Lower */ |
|
52 |
0x0C, /* Right -> Upper | Lower */ |
|
53 |
}; |
|
54 |
||
55 |
/* Maps a trackdir to the (4-way) direction the tile is exited when following |
|
56 |
* that trackdir */ |
|
57 |
const byte _trackdir_to_exitdir[14] = {
|
|
58 |
0,1,0,1,2,1, 0,0, |
|
59 |
2,3,3,2,3,0, |
|
60 |
}; |
|
61 |
||
62 |
const byte _track_exitdir_to_trackdir[6][4] = {
|
|
63 |
{0, 0xff, 8, 0xff},
|
|
64 |
{0xff, 1, 0xff, 9},
|
|
65 |
{2, 0xff, 0xff, 10},
|
|
66 |
{0xff, 3, 11, 0xf},
|
|
67 |
{0xff, 0xff, 4, 12},
|
|
68 |
{13, 5, 0xff, 0xff}
|
|
69 |
}; |
|
70 |
||
71 |
const byte _track_direction_to_trackdir[6][8] = {
|
|
72 |
{0xff, 0, 0xff, 0xff, 0xff, 8, 0xff, 0xff},
|
|
73 |
{0xff, 0xff, 0xff, 1, 0xff, 0xff, 0xff, 9},
|
|
74 |
{0xff, 0xff, 2, 0xff, 0xff, 0xff, 10, 0xff},
|
|
75 |
{0xff, 0xff, 3, 0xff, 0xff, 0xff, 11, 0xff},
|
|
76 |
{12, 0xff, 0xff, 0xff, 4, 0xff, 0xff, 0xff},
|
|
77 |
{13, 0xff, 0xff, 0xff, 5, 0xff, 0xff, 0xff}
|
|
78 |
}; |
|
79 |
||
80 |
const byte _dir_to_diag_trackdir[4] = {
|
|
81 |
0, 1, 8, 9, |
|
82 |
}; |
|
83 |
||
84 |
const byte _reverse_dir[4] = {
|
|
85 |
2, 3, 0, 1 |
|
86 |
}; |
|
87 |
||
88 |
const byte _reverse_trackdir[14] = {
|
|
89 |
8, 9, 10, 11, 12, 13, 0xFF, 0xFF, |
|
90 |
0, 1, 2, 3, 4, 5 |
|
91 |
}; |
|
92 |
||
93 |
/* The cost of each trackdir. A diagonal piece is the full NPF_TILE_LENGTH, |
|
94 |
* the shorter piece is sqrt(2)/2*NPF_TILE_LENGTH =~ 0.7071 |
|
95 |
*/ |
|
96 |
#define NPF_STRAIGHT_LENGTH (uint)(NPF_TILE_LENGTH * 0.7071) |
|
97 |
static const uint _trackdir_length[14] = {
|
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
98 |
NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
99 |
0, 0, |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
100 |
NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH |
| 1247 | 101 |
}; |
102 |
||
103 |
uint NTPHash(uint key1, uint key2) |
|
104 |
{
|
|
105 |
return PATHFIND_HASH_TILE(key1); |
|
106 |
} |
|
107 |
||
108 |
int32 NPFCalcZero(AyStar* as, AyStarNode* current, OpenListNode* parent) {
|
|
109 |
return 0; |
|
110 |
} |
|
111 |
||
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
112 |
/* Calcs the tile of given station that is closest to a given tile |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
113 |
* for this we assume the station is a rectangle, |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
114 |
* as defined by its top tile (st->train_tile) and its width/height (st->trainst_w, st->trainst_h) |
| 1247 | 115 |
*/ |
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
116 |
TileIndex CalcClosestStationTile(int station, TileIndex tile) {
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
117 |
const Station* st = GetStation(station); |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
118 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
119 |
int x1,x2,x3,tx; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
120 |
int y1,y2,y3,ty; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
121 |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
122 |
x1 = TileX(st->train_tile); y1 = TileY(st->train_tile); // topmost corner of station |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
123 |
x2 = x1 + st->trainst_w - 1; y2 = y1 + st->trainst_h - 1; // lowermost corner of station |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
124 |
x3 = TileX(tile); y3 = TileY(tile); // tile we take the distance from |
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
125 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
126 |
// we are going the aim for the x coordinate of the closest corner |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
127 |
// but if we are between those coordinates, we will aim for our own x coordinate |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
128 |
if (x3 < x1) |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
129 |
tx = x1; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
130 |
else if (x3 > x2) |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
131 |
tx = x2; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
132 |
else |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
133 |
tx = x3; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
134 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
135 |
// same for y coordinate, see above comment |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
136 |
if (y3 < y1) |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
137 |
ty = y1; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
138 |
else if (y3 > y2) |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
139 |
ty = y2; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
140 |
else |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
141 |
ty = y3; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
142 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
143 |
// return the tile of our target coordinates |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
144 |
return TILE_XY(tx,ty); |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
145 |
}; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
146 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
147 |
/* Calcs the heuristic to the target tile (using NPFFindStationOrTileData). |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
148 |
* If the target is a station, the heuristic is probably "wrong"! Normally |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
149 |
* this shouldn't matter, but if it turns out to be a problem, we could use |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
150 |
* the heuristic below? |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
151 |
* Afterthis will save the heuristic into NPFFoundTargetData if it is the |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
152 |
* smallest until now. It will then also save |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
153 |
* AyStarNode.user_data[NPF_TRACKDIR_CHOICE] in best_trackdir |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
154 |
*/ |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
155 |
int32 NPFCalcTileHeuristic(AyStar* as, AyStarNode* current, OpenListNode* parent) {
|
| 1247 | 156 |
NPFFindStationOrTileData* fstd = (NPFFindStationOrTileData*)as->user_target; |
157 |
NPFFoundTargetData* ftd = (NPFFoundTargetData*)as->user_path; |
|
158 |
TileIndex from = current->tile; |
|
159 |
TileIndex to = fstd->dest_coords; |
|
160 |
uint dist = DistanceManhattan(from, to) * NPF_TILE_LENGTH; |
|
161 |
||
162 |
if (dist < ftd->best_bird_dist) {
|
|
163 |
ftd->best_bird_dist = dist; |
|
164 |
ftd->best_trackdir = current->user_data[NPF_TRACKDIR_CHOICE]; |
|
165 |
} |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
166 |
#ifdef NPF_DEBUG |
| 1247 | 167 |
debug("Calculating H for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), dist);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
168 |
#endif |
| 1247 | 169 |
return dist; |
170 |
} |
|
171 |
||
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
172 |
/* Calcs the heuristic to the target station or tile. Almost the same as above |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
173 |
* function, but calculates the distance to train stations with |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
174 |
* CalcClosestStationTile instead. So is somewhat more correct for stations |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
175 |
* (truly optimistic), but this added correctness is not really required we |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
176 |
* believe (matthijs & Hackykid) |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
177 |
*/ |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
178 |
int32 NPFCalcStationOrTileHeuristic(AyStar* as, AyStarNode* current, OpenListNode* parent) {
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
179 |
NPFFindStationOrTileData* fstd = (NPFFindStationOrTileData*)as->user_target; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
180 |
NPFFoundTargetData* ftd = (NPFFoundTargetData*)as->user_path; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
181 |
TileIndex from = current->tile; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
182 |
TileIndex to = fstd->dest_coords; |
| 1453 | 183 |
uint dist; |
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
184 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
185 |
// for train-stations, we are going to aim for the closest station tile |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
186 |
if ((as->user_data[NPF_TYPE] == TRANSPORT_RAIL) && (fstd->station_index != -1)) |
| 1453 | 187 |
to = CalcClosestStationTile(fstd->station_index, from); |
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
188 |
|
| 1453 | 189 |
dist = DistanceManhattan(from, to) * NPF_TILE_LENGTH; |
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
190 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
191 |
if (dist < ftd->best_bird_dist) {
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
192 |
ftd->best_bird_dist = dist; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
193 |
ftd->best_trackdir = current->user_data[NPF_TRACKDIR_CHOICE]; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
194 |
} |
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
195 |
#ifdef NPF_DEBUG |
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
196 |
debug("Calculating H for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), dist);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
197 |
#endif |
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
198 |
return dist; |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
199 |
} |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
200 |
|
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
201 |
|
| 1247 | 202 |
/* Fills AyStarNode.user_data[NPF_TRACKDIRCHOICE] with the chosen direction to |
203 |
* get here, either getting it from the current choice or from the parent's |
|
204 |
* choice */ |
|
205 |
void NPFFillTrackdirChoice(AyStarNode* current, OpenListNode* parent) |
|
206 |
{
|
|
207 |
if (parent->path.parent == NULL) {
|
|
208 |
byte trackdir = current->direction; |
|
209 |
/* This is a first order decision, so we'd better save the |
|
210 |
* direction we chose */ |
|
211 |
current->user_data[NPF_TRACKDIR_CHOICE] = trackdir; |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
212 |
#ifdef NPF_DEBUG |
| 1247 | 213 |
debug("Saving trackdir: %#x", trackdir);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
214 |
#endif |
| 1247 | 215 |
} else {
|
216 |
/* We've already made the decision, so just save our parent's |
|
217 |
* decision */ |
|
218 |
current->user_data[NPF_TRACKDIR_CHOICE] = parent->path.node.user_data[NPF_TRACKDIR_CHOICE]; |
|
219 |
} |
|
220 |
||
221 |
} |
|
222 |
||
223 |
/* Will return the cost of the tunnel. If it is an entry, it will return the |
|
224 |
* cost of that tile. If the tile is an exit, it will return the tunnel length |
|
225 |
* including the exit tile. Requires that this is a Tunnel tile */ |
|
226 |
uint NPFTunnelCost(AyStarNode* current) {
|
|
227 |
byte exitdir = _trackdir_to_exitdir[current->direction]; |
|
228 |
TileIndex tile = current->tile; |
|
229 |
if ( (uint)(_map5[tile] & 3) == _reverse_dir[exitdir]) {
|
|
230 |
/* We just popped out if this tunnel, since were |
|
231 |
* facing the tunnel exit */ |
|
232 |
FindLengthOfTunnelResult flotr; |
|
233 |
flotr = FindLengthOfTunnel(tile, _reverse_dir[exitdir]); |
|
234 |
return flotr.length * NPF_TILE_LENGTH; |
|
235 |
//TODO: Penalty for tunnels? |
|
236 |
} else {
|
|
237 |
/* We are entering the tunnel, the enter tile is just a |
|
238 |
* straight track */ |
|
239 |
return NPF_TILE_LENGTH; |
|
240 |
} |
|
241 |
} |
|
242 |
||
243 |
uint NPFSlopeCost(AyStarNode* current) {
|
|
244 |
TileIndex next = current->tile + TileOffsByDir(_trackdir_to_exitdir[current->direction]); |
|
|
1503
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
245 |
int x,y; |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
246 |
int8 z1,z2; |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
247 |
|
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
248 |
x = TileX(current->tile) * 16; |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
249 |
y = TileY(current->tile) * 16; |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
250 |
z1 = GetSlopeZ(x+8, y+8); |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
251 |
|
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
252 |
x = TileX(next) * 16; |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
253 |
y = TileY(next) * 16; |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
254 |
z2 = GetSlopeZ(x+8, y+8); |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
255 |
|
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
256 |
if ((z2 - z1) > 1) {
|
| 1247 | 257 |
/* Slope up */ |
258 |
return _patches.npf_rail_slope_penalty; |
|
259 |
} |
|
260 |
return 0; |
|
261 |
/* Should we give a bonus for slope down? Probably not, we |
|
262 |
* could just substract that bonus from the penalty, because |
|
263 |
* there is only one level of steepness... */ |
|
264 |
} |
|
265 |
||
266 |
void NPFMarkTile(TileIndex tile) {
|
|
267 |
switch(GetTileType(tile)) {
|
|
268 |
case MP_RAILWAY: |
|
269 |
case MP_STREET: |
|
270 |
/* DEBUG: mark visited tiles by mowing the grass under them |
|
271 |
* ;-) */ |
|
272 |
_map2[tile] &= ~15; |
|
273 |
MarkTileDirtyByTile(tile); |
|
274 |
break; |
|
275 |
default: |
|
276 |
break; |
|
277 |
} |
|
278 |
} |
|
279 |
||
280 |
int32 NPFWaterPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent) {
|
|
281 |
//TileIndex tile = current->tile; |
|
282 |
int32 cost = 0; |
|
283 |
byte trackdir = current->direction; |
|
284 |
||
285 |
cost = _trackdir_length[trackdir]; /* Should be different for diagonal tracks */ |
|
286 |
||
287 |
/* TODO Penalties? */ |
|
288 |
||
289 |
return cost; |
|
290 |
} |
|
291 |
||
292 |
/* Determine the cost of this node, for road tracks */ |
|
293 |
int32 NPFRoadPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent) {
|
|
294 |
TileIndex tile = current->tile; |
|
295 |
int32 cost = 0; |
|
296 |
/* Determine base length */ |
|
297 |
switch (GetTileType(tile)) {
|
|
298 |
case MP_TUNNELBRIDGE: |
|
299 |
if ((_map5[tile] & 0xF0)==0) {
|
|
300 |
cost = NPFTunnelCost(current); |
|
301 |
break; |
|
302 |
} |
|
303 |
/* Fall through if above if is false, it is a bridge |
|
304 |
* then. We treat that as ordinary rail */ |
|
305 |
case MP_STREET: |
|
306 |
cost = NPF_TILE_LENGTH; |
|
307 |
break; |
|
308 |
default: |
|
309 |
break; |
|
310 |
} |
|
311 |
||
312 |
/* Determine extra costs */ |
|
313 |
||
314 |
/* Check for slope */ |
|
315 |
cost += NPFSlopeCost(current); |
|
316 |
||
317 |
/* Check for turns */ |
|
318 |
//TODO |
|
319 |
||
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
320 |
#ifdef NPF_MARKROUTE |
| 1247 | 321 |
NPFMarkTile(tile); |
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
322 |
#endif |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
323 |
#ifdef NPF_DEBUG |
| 1247 | 324 |
debug("Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
325 |
#endif |
| 1247 | 326 |
return cost; |
327 |
} |
|
328 |
||
329 |
||
330 |
/* Determine the cost of this node, for railway tracks */ |
|
331 |
int32 NPFRailPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent) {
|
|
332 |
TileIndex tile = current->tile; |
|
333 |
byte trackdir = current->direction; |
|
334 |
int32 cost = 0; |
|
|
1617
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
335 |
OpenListNode new_node; |
|
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
336 |
|
| 1247 | 337 |
/* Determine base length */ |
338 |
switch (GetTileType(tile)) {
|
|
339 |
case MP_TUNNELBRIDGE: |
|
340 |
if ((_map5[tile] & 0xF0)==0) {
|
|
341 |
cost = NPFTunnelCost(current); |
|
342 |
break; |
|
343 |
} |
|
344 |
/* Fall through if above if is false, it is a bridge |
|
345 |
* then. We treat that as ordinary rail */ |
|
346 |
case MP_RAILWAY: |
|
347 |
cost = _trackdir_length[trackdir]; /* Should be different for diagonal tracks */ |
|
348 |
break; |
|
349 |
case MP_STREET: /* Railway crossing */ |
|
350 |
cost = NPF_TILE_LENGTH; |
|
351 |
break; |
|
|
1503
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
352 |
case MP_STATION: |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
353 |
/* We give a station tile a penalty. Logically we would only |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
354 |
* want to give station tiles that are not our destination |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
355 |
* this penalty. This would discourage trains to drive through |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
356 |
* busy stations. But, we can just give any station tile a |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
357 |
* penalty, because every possible route will get this penalty |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
358 |
* exactly once, on its end tile (if it's a station) and it |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
359 |
* will therefore not make a difference. */ |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
360 |
cost = NPF_TILE_LENGTH + _patches.npf_rail_station_penalty; |
|
be35a76c7555
(svn r2007) - Fix: [NPF] Slope penalties did not work correctly with foundations. (HackyKid)
matthijs
parents:
1502
diff
changeset
|
361 |
break; |
| 1247 | 362 |
default: |
363 |
break; |
|
364 |
} |
|
365 |
||
366 |
/* Determine extra costs */ |
|
367 |
||
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
368 |
/* Check for signals */ |
|
1502
e84925444095
(svn r2006) - Fix: [NPF] Wrong signal detection for last signal red detection. Multiple tracks per tile with only one signal were detected wrong. (HackyKid)
matthijs
parents:
1464
diff
changeset
|
369 |
if (IsTileType(tile, MP_RAILWAY) && (_map5[tile] & 0xC0) == 0x40 && (_map3_lo[tile] & _signal_along_trackdir[trackdir]) != 0) {
|
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
370 |
/* Ordinary track with signals */ |
| 1247 | 371 |
if ((_map2[tile] & _signal_along_trackdir[trackdir]) == 0) {
|
372 |
/* Signal facing us is red */ |
|
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
373 |
if (!NPFGetFlag(current, NPF_FLAG_SEEN_SIGNAL)) {
|
| 1247 | 374 |
/* Penalize the first signal we |
375 |
* encounter, if it is red */ |
|
376 |
cost += _patches.npf_rail_firstred_penalty; |
|
377 |
} |
|
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
378 |
/* Record the state of this signal */ |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
379 |
NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, true); |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
380 |
} else {
|
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
381 |
/* Record the state of this signal */ |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
382 |
NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, false); |
| 1247 | 383 |
} |
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
384 |
NPFSetFlag(current, NPF_FLAG_SEEN_SIGNAL, true); |
| 1247 | 385 |
} |
386 |
||
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
387 |
/* Penalise the tile if it is a target tile and the last signal was |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
388 |
* red */ |
|
1617
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
389 |
new_node.path.node = *current; |
|
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
390 |
if (as->EndNodeCheck(as, &new_node)==AYSTAR_FOUND_END_NODE && NPFGetFlag(current, NPF_FLAG_LAST_SIGNAL_RED)) |
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
391 |
cost += _patches.npf_rail_lastred_penalty; |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
392 |
|
| 1247 | 393 |
/* Check for slope */ |
394 |
cost += NPFSlopeCost(current); |
|
395 |
||
396 |
/* Check for turns */ |
|
| 1460 | 397 |
if (current->direction != parent->path.node.direction) |
398 |
cost += _patches.npf_rail_curve_penalty; |
|
399 |
//TODO, with realistic acceleration, also the amount of straight track between |
|
400 |
// curves should be taken into account, as this affects the speed limit. |
|
| 1247 | 401 |
|
402 |
/* Check for occupied track */ |
|
403 |
//TODO |
|
404 |
||
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
405 |
#ifdef NPF_MARKROUTE |
| 1247 | 406 |
NPFMarkTile(tile); |
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
407 |
#endif |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
408 |
#ifdef NPF_DEBUG |
| 1247 | 409 |
debug("Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
410 |
#endif |
| 1247 | 411 |
return cost; |
412 |
} |
|
413 |
||
414 |
/* Will find any depot */ |
|
|
1617
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
415 |
int32 NPFFindDepot(AyStar* as, OpenListNode *current) {
|
|
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
416 |
TileIndex tile = current->path.node.tile; |
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
417 |
if (IsTileDepotType(tile, as->user_data[NPF_TYPE])) |
| 1247 | 418 |
return AYSTAR_FOUND_END_NODE; |
419 |
else |
|
420 |
return AYSTAR_DONE; |
|
421 |
} |
|
422 |
||
423 |
/* Will find a station identified using the NPFFindStationOrTileData */ |
|
|
1617
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
424 |
int32 NPFFindStationOrTile(AyStar* as, OpenListNode *current) {
|
|
1464
266d3b0ee2c8
(svn r1968) - Fix: [NPF] Mixed declarations and statements
matthijs
parents:
1463
diff
changeset
|
425 |
NPFFindStationOrTileData* fstd = (NPFFindStationOrTileData*)as->user_target; |
|
1617
55878ca5ada9
(svn r2121) -Fix: changed the 2nd param of AyStar_EndNodeCheck back to what it should be
truelight
parents:
1503
diff
changeset
|
426 |
AyStarNode *node = ¤t->path.node; |
|
1464
266d3b0ee2c8
(svn r1968) - Fix: [NPF] Mixed declarations and statements
matthijs
parents:
1463
diff
changeset
|
427 |
TileIndex tile = node->tile; |
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
428 |
|
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
429 |
/* See if we checked this before */ |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
430 |
if (NPFGetFlag(node, NPF_FLAG_TARGET_CHECKED)) |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
431 |
return NPFGetFlag(node, NPF_FLAG_IS_TARGET); |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
432 |
/* We're gonna check this now and store the result, let's mark that */ |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
433 |
NPFSetFlag(node, NPF_FLAG_TARGET_CHECKED, true); |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
434 |
|
| 1247 | 435 |
/* If GetNeighbours said we could get here, we assume the station type |
436 |
* is correct */ |
|
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
437 |
if ( |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
438 |
(fstd->station_index == -1 && tile == fstd->dest_coords) || /* We've found the tile, or */ |
| 1247 | 439 |
(IsTileType(tile, MP_STATION) && _map2[tile] == fstd->station_index) /* the station */ |
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
440 |
) {
|
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
441 |
NPFSetFlag(node, NPF_FLAG_TARGET_CHECKED, true); |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
442 |
return AYSTAR_FOUND_END_NODE; |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
443 |
} else {
|
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
444 |
NPFSetFlag(node, NPF_FLAG_TARGET_CHECKED, false); |
| 1247 | 445 |
return AYSTAR_DONE; |
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
446 |
} |
| 1247 | 447 |
} |
448 |
||
449 |
/* To be called when current contains the (shortest route to) the target node. |
|
450 |
* Will fill the contents of the NPFFoundTargetData using |
|
451 |
* AyStarNode[NPF_TRACKDIR_CHOICE]. |
|
452 |
*/ |
|
453 |
void NPFSaveTargetData(AyStar* as, OpenListNode* current) {
|
|
454 |
NPFFoundTargetData* ftd = (NPFFoundTargetData*)as->user_path; |
|
455 |
ftd->best_trackdir = current->path.node.user_data[NPF_TRACKDIR_CHOICE]; |
|
456 |
ftd->best_path_dist = current->g; |
|
457 |
ftd->best_bird_dist = 0; |
|
458 |
ftd->node = current->path.node; |
|
459 |
} |
|
460 |
||
461 |
/* Will just follow the results of GetTileTrackStatus concerning where we can |
|
462 |
* go and where not. Uses AyStar.user_data[NPF_TYPE] as the transport type and |
|
463 |
* an argument to GetTileTrackStatus. Will skip tunnels, meaning that the |
|
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
464 |
* entry and exit are neighbours. Will fill |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
465 |
* AyStarNode.user_data[NPF_TRACKDIR_CHOICE] with an appropriate value, and |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
466 |
* copy AyStarNode.user_data[NPF_NODE_FLAGS] from the parent */ |
| 1247 | 467 |
void NPFFollowTrack(AyStar* aystar, OpenListNode* current) {
|
468 |
byte src_trackdir = current->path.node.direction; |
|
469 |
TileIndex src_tile = current->path.node.tile; |
|
470 |
byte src_exitdir = _trackdir_to_exitdir[src_trackdir]; |
|
471 |
FindLengthOfTunnelResult flotr; |
|
472 |
TileIndex dst_tile; |
|
473 |
int i = 0; |
|
474 |
uint trackdirs, ts; |
|
475 |
TransportType type = aystar->user_data[NPF_TYPE]; |
|
476 |
/* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */ |
|
477 |
aystar->num_neighbours = 0; |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
478 |
#ifdef NPF_DEBUG |
| 1247 | 479 |
debug("Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
480 |
#endif |
| 1247 | 481 |
|
482 |
/* Find dest tile */ |
|
483 |
if (IsTileType(src_tile, MP_TUNNELBRIDGE) && (_map5[src_tile] & 0xF0)==0 && (_map5[src_tile] & 3) == src_exitdir) {
|
|
484 |
/* This is a tunnel. We know this tunnel is our type, |
|
485 |
* otherwise we wouldn't have got here. It is also facing us, |
|
486 |
* so we should skip it's body */ |
|
487 |
flotr = FindLengthOfTunnel(src_tile, src_exitdir); |
|
488 |
dst_tile = flotr.tile; |
|
489 |
} else {
|
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
490 |
if (IsTileDepotType(src_tile, type)){
|
| 1247 | 491 |
/* This is a road station or a train or road depot. We can enter and exit |
492 |
* those from one side only. Trackdirs don't support that (yet), so we'll |
|
493 |
* do this here. */ |
|
494 |
||
495 |
byte exitdir; |
|
496 |
/* Find out the exit direction first */ |
|
497 |
if (IsRoadStationTile(src_tile)) |
|
498 |
exitdir = GetRoadStationDir(src_tile); |
|
499 |
else /* Train or road depot. Direction is stored the same for both, in map5 */ |
|
500 |
exitdir = _map5[src_tile] & 3; /* Extract the direction from the map */ |
|
501 |
||
502 |
/* Let's see if were headed the right way */ |
|
503 |
if (src_trackdir != _dir_to_diag_trackdir[exitdir]) |
|
504 |
/* Not going out of the station/depot through the exit, but the back. No |
|
505 |
* neighbours then. */ |
|
506 |
return; |
|
507 |
} |
|
508 |
/* This a normal tile, a bridge, a tunnel exit, etc. */ |
|
509 |
dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDir(_trackdir_to_exitdir[src_trackdir])); |
|
510 |
if (dst_tile == INVALID_TILE) {
|
|
511 |
/* We reached the border of the map */ |
|
512 |
/* TODO Nicer control flow for this */ |
|
513 |
return; |
|
514 |
} |
|
515 |
} |
|
516 |
||
517 |
// TODO: check correct rail type (mono, maglev, etc) |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
518 |
|
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
519 |
/* Check the owner of the tile */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
520 |
if ( |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
521 |
IsTileType(dst_tile, MP_RAILWAY) /* Rail tile */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
522 |
|| IsTileDepotType(dst_tile, TRANSPORT_ROAD) /* Road depot tile */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
523 |
|| IsTileType(dst_tile, MP_STATION) /* Station tile */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
524 |
|| IsTileDepotType(dst_tile, TRANSPORT_WATER) /* Water depot tile */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
525 |
) /* TODO: Crossings, tunnels and bridges are "public" now */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
526 |
/* The above cases are "private" tiles, we need to check the owner */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
527 |
if (!IsTileOwner(dst_tile, aystar->user_data[NPF_OWNER])) |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
528 |
return; |
| 1247 | 529 |
|
530 |
/* Determine available tracks */ |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
531 |
if (type == TRANSPORT_ROAD && (IsRoadStationTile(dst_tile) || IsTileDepotType(dst_tile, TRANSPORT_ROAD))){
|
| 1247 | 532 |
/* Road stations and depots return 0 on GTTS, so we have to do this by hand... */ |
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
533 |
byte exitdir; |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
534 |
if (IsRoadStationTile(dst_tile)) |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
535 |
exitdir = GetRoadStationDir(dst_tile); |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
536 |
else /* Road depot */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
537 |
/* Find the trackdirs that are available for a depot with this orientation. They are in both directions */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
538 |
exitdir = _map5[dst_tile] & 3; /* Extract the direction from the map */ |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
539 |
ts = (1 << _dir_to_diag_trackdir[exitdir]) |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
540 |
| (1 << _dir_to_diag_trackdir[_reverse_dir[exitdir]]); |
| 1247 | 541 |
} else {
|
542 |
ts = GetTileTrackStatus(dst_tile, type); |
|
543 |
} |
|
544 |
trackdirs = ts & 0x3F3F; /* Filter out signal status and the unused bits */ |
|
545 |
||
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
546 |
#ifdef NPF_DEBUG |
| 1247 | 547 |
debug("Next node: (%d, %d) [%d], possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirs);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
548 |
#endif |
| 1247 | 549 |
/* Select only trackdirs we can reach from our current trackdir */ |
550 |
trackdirs &= _trackdir_reaches_trackdirs[src_trackdir]; |
|
551 |
if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) /* Filter out trackdirs that would make 90 deg turns for trains */ |
|
552 |
trackdirs &= ~_trackdir_crosses_trackdirs[src_trackdir]; |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
553 |
#ifdef NPF_DEBUG |
| 1247 | 554 |
debug("After filtering: (%d, %d), possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), trackdirs);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
555 |
#endif |
| 1247 | 556 |
|
557 |
/* Enumerate possible track */ |
|
558 |
while (trackdirs != 0) {
|
|
559 |
byte dst_trackdir; |
|
560 |
dst_trackdir = FindFirstBit2x64(trackdirs); |
|
561 |
trackdirs = KillFirstBit2x64(trackdirs); |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
562 |
#ifdef NPF_DEBUG |
| 1247 | 563 |
debug("Expanded into trackdir: %d, remaining trackdirs: %#x", dst_trackdir, trackdirs);
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
564 |
#endif |
| 1247 | 565 |
|
566 |
/* Check for oneway signal against us */ |
|
567 |
if (IsTileType(dst_tile, MP_RAILWAY) && (_map5[dst_tile]&0xC0) == 0x40) {
|
|
568 |
// the tile has a signal |
|
569 |
byte signal_present = _map3_lo[dst_tile]; |
|
570 |
if (!(signal_present & _signal_along_trackdir[dst_trackdir])) {
|
|
571 |
// if one way signal not pointing towards us, stop going in this direction. |
|
572 |
if (signal_present & _signal_against_trackdir[dst_trackdir]) |
|
573 |
break; |
|
574 |
} |
|
575 |
} |
|
576 |
{
|
|
577 |
/* We've found ourselves a neighbour :-) */ |
|
578 |
AyStarNode* neighbour = &aystar->neighbours[i]; |
|
579 |
neighbour->tile = dst_tile; |
|
580 |
neighbour->direction = dst_trackdir; |
|
581 |
/* Save user data */ |
|
582 |
neighbour->user_data[NPF_NODE_FLAGS] = current->path.node.user_data[NPF_NODE_FLAGS]; |
|
583 |
NPFFillTrackdirChoice(neighbour, current); |
|
584 |
} |
|
585 |
i++; |
|
586 |
} |
|
587 |
aystar->num_neighbours = i; |
|
588 |
} |
|
589 |
||
590 |
/* |
|
591 |
* Plan a route to the specified target (which is checked by target_proc), |
|
592 |
* from start1 and if not NULL, from start2 as well. The type of transport we |
|
593 |
* are checking is in type. |
|
594 |
* When we are looking for one specific target (optionally multiple tiles), we |
|
595 |
* should use a good heuristic to perform aystar search. When we search for |
|
596 |
* multiple targets that are spread around, we should perform a breadth first |
|
597 |
* search by specifiying CalcZero as our heuristic. |
|
598 |
*/ |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
599 |
NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner) {
|
| 1247 | 600 |
int r; |
601 |
NPFFoundTargetData result; |
|
602 |
||
603 |
/* Initialize procs */ |
|
604 |
_npf_aystar.CalculateH = heuristic_proc; |
|
605 |
_npf_aystar.EndNodeCheck = target_proc; |
|
606 |
_npf_aystar.FoundEndNode = NPFSaveTargetData; |
|
607 |
_npf_aystar.GetNeighbours = NPFFollowTrack; |
|
608 |
if (type == TRANSPORT_RAIL) |
|
609 |
_npf_aystar.CalculateG = NPFRailPathCost; |
|
610 |
else if (type == TRANSPORT_ROAD) |
|
611 |
_npf_aystar.CalculateG = NPFRoadPathCost; |
|
612 |
else if (type == TRANSPORT_WATER) |
|
613 |
_npf_aystar.CalculateG = NPFWaterPathCost; |
|
614 |
else |
|
615 |
assert(0); |
|
616 |
||
617 |
/* Initialize Start Node(s) */ |
|
618 |
start1->user_data[NPF_TRACKDIR_CHOICE] = 0xff; |
|
619 |
start1->user_data[NPF_NODE_FLAGS] = 0; |
|
620 |
_npf_aystar.addstart(&_npf_aystar, start1); |
|
621 |
if (start2) {
|
|
622 |
start2->user_data[NPF_TRACKDIR_CHOICE] = 0xff; |
|
|
1459
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
623 |
start2->user_data[NPF_NODE_FLAGS] = 0; |
|
6c1f01803928
(svn r1963) - Add: [NPF] Penalty for a red signal that is the last signal on the path.
matthijs
parents:
1453
diff
changeset
|
624 |
NPFSetFlag(start2, NPF_FLAG_REVERSE, true); |
| 1247 | 625 |
_npf_aystar.addstart(&_npf_aystar, start2); |
626 |
} |
|
627 |
||
628 |
/* Initialize result */ |
|
629 |
result.best_bird_dist = (uint)-1; |
|
630 |
result.best_path_dist = (uint)-1; |
|
631 |
result.best_trackdir = 0xff; |
|
632 |
_npf_aystar.user_path = &result; |
|
633 |
||
634 |
/* Initialize target */ |
|
635 |
_npf_aystar.user_target = target; |
|
636 |
||
637 |
/* Initialize user_data */ |
|
638 |
_npf_aystar.user_data[NPF_TYPE] = type; |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
639 |
_npf_aystar.user_data[NPF_OWNER] = owner; |
| 1247 | 640 |
|
641 |
/* GO! */ |
|
642 |
r = AyStarMain_Main(&_npf_aystar); |
|
643 |
assert(r != AYSTAR_STILL_BUSY); |
|
644 |
||
645 |
if (result.best_bird_dist != 0) {
|
|
646 |
if (target) {
|
|
647 |
DEBUG(misc, 1) ("NPF: Could not find route to 0x%x from 0x%x.", target->dest_coords, start1->tile);
|
|
648 |
} else {
|
|
649 |
/* Assumption: target == NULL, so we are looking for a depot */ |
|
650 |
DEBUG(misc, 1) ("NPF: Could not find route to a depot from 0x%x.", start1->tile);
|
|
651 |
} |
|
652 |
||
653 |
} |
|
654 |
return result; |
|
655 |
} |
|
656 |
||
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
657 |
NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, byte trackdir1, TileIndex tile2, byte trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner) {
|
| 1247 | 658 |
AyStarNode start1; |
659 |
AyStarNode start2; |
|
660 |
||
661 |
start1.tile = tile1; |
|
662 |
start2.tile = tile2; |
|
663 |
start1.direction = trackdir1; |
|
664 |
start2.direction = trackdir2; |
|
665 |
||
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
666 |
return NPFRouteInternal(&start1, &start2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner); |
| 1247 | 667 |
} |
668 |
||
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
669 |
NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, byte trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner) {
|
| 1247 | 670 |
AyStarNode start; |
671 |
||
672 |
assert(tile != 0); |
|
673 |
||
674 |
start.tile = tile; |
|
675 |
start.direction = trackdir; |
|
676 |
/* We set this in case the target is also the start tile, we will just |
|
677 |
* return a not found then */ |
|
678 |
start.user_data[NPF_TRACKDIR_CHOICE] = 0xff; |
|
679 |
||
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
680 |
return NPFRouteInternal(&start, NULL, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner); |
| 1247 | 681 |
} |
682 |
||
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
683 |
NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, byte trackdir, TransportType type, Owner owner) {
|
| 1247 | 684 |
AyStarNode start; |
685 |
||
686 |
start.tile = tile; |
|
687 |
start.direction = trackdir; |
|
688 |
/* We set this in case the target is also the start tile, we will just |
|
689 |
* return a not found then */ |
|
690 |
start.user_data[NPF_TRACKDIR_CHOICE] = 0xff; |
|
691 |
||
692 |
/* perform a breadth first search. Target is NULL, |
|
693 |
* since we are just looking for any depot...*/ |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
694 |
return NPFRouteInternal(&start, NULL, NULL, NPFFindDepot, NPFCalcZero, type, owner); |
| 1247 | 695 |
} |
696 |
||
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
697 |
NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, TransportType type, Owner owner) {
|
| 1247 | 698 |
/* Okay, what we're gonna do. First, we look at all depots, calculate |
699 |
* the manhatten distance to get to each depot. We then sort them by |
|
700 |
* distance. We start by trying to plan a route to the closest, then |
|
701 |
* the next closest, etc. We stop when the best route we have found so |
|
702 |
* far, is shorter than the manhattan distance. This will obviously |
|
703 |
* always find the closest depot. It will probably be most efficient |
|
704 |
* for ships, since the heuristic will not be to far off then. I hope. |
|
705 |
*/ |
|
706 |
Queue depots; |
|
707 |
int r; |
|
708 |
NPFFoundTargetData best_result; |
|
709 |
NPFFoundTargetData result; |
|
710 |
NPFFindStationOrTileData target; |
|
711 |
AyStarNode start; |
|
712 |
Depot* current; |
|
|
1313
bba6afb8a995
(svn r1817) -Codechange: Moved depot-functions to depot.c
truelight
parents:
1299
diff
changeset
|
713 |
Depot *depot; |
| 1247 | 714 |
|
715 |
init_InsSort(&depots); |
|
716 |
/* Okay, let's find all depots that we can use first */ |
|
|
1313
bba6afb8a995
(svn r1817) -Codechange: Moved depot-functions to depot.c
truelight
parents:
1299
diff
changeset
|
717 |
FOR_ALL_DEPOTS(depot) {
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
718 |
/* Check if this is really a valid depot, it is of the needed type and |
|
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
719 |
* owner */ |
| 1338 | 720 |
if (IsValidDepot(depot) && IsTileDepotType(depot->xy, type) && IsTileOwner(depot->xy, owner)) |
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
721 |
/* If so, let's add it to the queue, sorted by distance */ |
|
1313
bba6afb8a995
(svn r1817) -Codechange: Moved depot-functions to depot.c
truelight
parents:
1299
diff
changeset
|
722 |
depots.push(&depots, depot, DistanceManhattan(tile, depot->xy)); |
| 1247 | 723 |
} |
724 |
||
725 |
/* Now, let's initialise the aystar */ |
|
726 |
||
727 |
/* Initialize procs */ |
|
728 |
_npf_aystar.CalculateH = NPFCalcStationOrTileHeuristic; |
|
729 |
_npf_aystar.EndNodeCheck = NPFFindStationOrTile; |
|
730 |
_npf_aystar.FoundEndNode = NPFSaveTargetData; |
|
731 |
_npf_aystar.GetNeighbours = NPFFollowTrack; |
|
732 |
if (type == TRANSPORT_RAIL) |
|
733 |
_npf_aystar.CalculateG = NPFRailPathCost; |
|
734 |
else if (type == TRANSPORT_ROAD) |
|
735 |
_npf_aystar.CalculateG = NPFRoadPathCost; |
|
736 |
else if (type == TRANSPORT_WATER) |
|
737 |
_npf_aystar.CalculateG = NPFWaterPathCost; |
|
738 |
else |
|
739 |
assert(0); |
|
740 |
||
741 |
/* Initialize target */ |
|
742 |
target.station_index = -1; /* We will initialize dest_coords inside the loop below */ |
|
743 |
_npf_aystar.user_target = ⌖ |
|
744 |
||
745 |
/* Initialize user_data */ |
|
746 |
_npf_aystar.user_data[NPF_TYPE] = type; |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
747 |
_npf_aystar.user_data[NPF_OWNER] = owner; |
| 1247 | 748 |
|
749 |
/* Initialize Start Node */ |
|
750 |
start.tile = tile; |
|
751 |
start.direction = trackdir; /* We will initialize user_data inside the loop below */ |
|
752 |
||
753 |
/* Initialize Result */ |
|
754 |
_npf_aystar.user_path = &result; |
|
755 |
best_result.best_path_dist = (uint)-1; |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
756 |
best_result.best_bird_dist = (uint)-1; |
| 1247 | 757 |
|
758 |
/* Just iterate the depots in order of increasing distance */ |
|
759 |
while ((current = depots.pop(&depots))) {
|
|
760 |
/* Check to see if we already have a path shorter than this |
|
|
1330
8a67d04016ce
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
matthijs
parents:
1313
diff
changeset
|
761 |
* depot's manhattan distance. HACK: We call DistanceManhattan |
| 1247 | 762 |
* again, we should probably modify the queue to give us that |
763 |
* value... */ |
|
764 |
if ( DistanceManhattan(tile, current->xy * NPF_TILE_LENGTH) > best_result.best_path_dist) |
|
765 |
break; |
|
766 |
||
767 |
/* Initialize Start Node */ |
|
768 |
/* We set this in case the target is also the start tile, we will just |
|
769 |
* return a not found then */ |
|
770 |
start.user_data[NPF_TRACKDIR_CHOICE] = 0xff; |
|
771 |
start.user_data[NPF_NODE_FLAGS] = 0; |
|
772 |
_npf_aystar.addstart(&_npf_aystar, &start); |
|
773 |
||
774 |
/* Initialize result */ |
|
775 |
result.best_bird_dist = (uint)-1; |
|
776 |
result.best_path_dist = (uint)-1; |
|
777 |
result.best_trackdir = 0xff; |
|
778 |
||
779 |
/* Initialize target */ |
|
780 |
target.dest_coords = current->xy; |
|
781 |
||
782 |
/* GO! */ |
|
783 |
r = AyStarMain_Main(&_npf_aystar); |
|
784 |
assert(r != AYSTAR_STILL_BUSY); |
|
785 |
||
786 |
/* This depot is closer */ |
|
787 |
if (result.best_path_dist < best_result.best_path_dist) |
|
788 |
best_result = result; |
|
789 |
} |
|
790 |
if (result.best_bird_dist != 0) {
|
|
791 |
DEBUG(misc, 1) ("NPF: Could not find route to any depot from 0x%x.", tile);
|
|
792 |
} |
|
793 |
return best_result; |
|
794 |
} |
|
795 |
||
796 |
void InitializeNPF(void) |
|
797 |
{
|
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
798 |
init_AyStar(&_npf_aystar, NTPHash, 1024); |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
799 |
_npf_aystar.loops_per_tick = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
800 |
_npf_aystar.max_path_cost = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
801 |
_npf_aystar.max_search_nodes = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
802 |
#if 0 |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
803 |
init_AyStar(&_train_find_station, NTPHash, 1024); |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
804 |
init_AyStar(&_train_find_depot, NTPHash, 1024); |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
805 |
init_AyStar(&_road_find_station, NTPHash, 1024); |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
806 |
init_AyStar(&_road_find_depot, NTPHash, 1024); |
| 1247 | 807 |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
808 |
_train_find_station.loops_per_tick = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
809 |
_train_find_depot.loops_per_tick = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
810 |
_road_find_station.loops_per_tick = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
811 |
_road_find_depot.loops_per_tick = 0; |
| 1247 | 812 |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
813 |
_train_find_station.max_path_cost = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
814 |
_train_find_depot.max_path_cost = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
815 |
_road_find_station.max_path_cost = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
816 |
_road_find_depot.max_path_cost = 0; |
| 1247 | 817 |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
818 |
_train_find_station.max_search_nodes = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
819 |
_train_find_depot.max_search_nodes = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
820 |
_road_find_station.max_search_nodes = 0; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
821 |
_road_find_depot.max_search_nodes = 0; |
| 1247 | 822 |
|
|
1463
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
823 |
_train_find_station.CalculateG = NPFRailPathCost; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
824 |
_train_find_depot.CalculateG = NPFRailPathCost; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
825 |
_road_find_station.CalculateG = NPFRoadPathCost; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
826 |
_road_find_depot.CalculateG = NPFRoadPathCost; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
827 |
|
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
828 |
_train_find_station.CalculateH = NPFCalcStationHeuristic; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
829 |
_train_find_depot.CalculateH = NPFCalcStationHeuristic; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
830 |
_road_find_station.CalculateH = NPFCalcStationHeuristic; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
831 |
_road_find_depot.CalculateH = NPFCalcStationHeuristic; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
832 |
|
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
833 |
_train_find_station.EndNodeCheck = NPFFindStationOrTile; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
834 |
_train_find_depot.EndNodeCheck = NPFFindStationOrTile; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
835 |
_road_find_station.EndNodeCheck = NPFFindStationOrTile; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
836 |
_road_find_depot.EndNodeCheck = NPFFindStationOrTile; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
837 |
|
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
838 |
_train_find_station.FoundEndNode = NPFSaveTargetData; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
839 |
_train_find_depot.FoundEndNode = NPFSaveTargetData; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
840 |
_road_find_station.FoundEndNode = NPFSaveTargetData; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
841 |
_road_find_depot.FoundEndNode = NPFSaveTargetData; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
842 |
|
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
843 |
_train_find_station.GetNeighbours = NPFFollowTrack; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
844 |
_train_find_depot.GetNeighbours = NPFFollowTrack; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
845 |
_road_find_station.GetNeighbours = NPFFollowTrack; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
846 |
_road_find_depot.GetNeighbours = NPFFollowTrack; |
|
a9b4664cef34
(svn r1967) Codechange: A mix of mostly indentation-related tidyups.
pasky
parents:
1460
diff
changeset
|
847 |
#endif |
| 1247 | 848 |
} |
849 |
||
850 |
void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v) {
|
|
851 |
/* Ships don't really reach their stations, but the tile in front. So don't |
|
852 |
* save the station id for ships. For roadvehs we don't store it either, |
|
853 |
* because multistop depends on vehicles actually reaching the exact |
|
854 |
* dest_tile, not just any stop of that station. |
|
855 |
* So only for train orders to stations we fill fstd->station_index, for all |
|
856 |
* others only dest_coords */ |
|
857 |
if ((v->current_order.type) == OT_GOTO_STATION && v->type == VEH_Train) {
|
|
858 |
fstd->station_index = v->current_order.station; |
|
|
1452
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
859 |
/* Let's take the closest tile of the station as our target for trains */ |
|
9285e482f984
(svn r1956) -Fix: [NPF] New target tile for heuristic should perform better with larger stations (HackyKid)
matthijs
parents:
1339
diff
changeset
|
860 |
fstd->dest_coords = CalcClosestStationTile(v->current_order.station, v->tile); |
| 1247 | 861 |
} else {
|
862 |
fstd->dest_coords = v->dest_tile; |
|
863 |
fstd->station_index = -1; |
|
864 |
} |
|
865 |
} |