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