151 tile = TILE_MASK(tile + TileOffsByDiagDir(direction)); |
150 tile = TILE_MASK(tile + TileOffsByDiagDir(direction)); |
152 |
151 |
153 if (++tpf->rd.cur_length > 50) |
152 if (++tpf->rd.cur_length > 50) |
154 return; |
153 return; |
155 |
154 |
156 bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type); |
155 TrackStatus ts = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type); |
157 bits = (byte)((bits | (bits >> 8)) & _bits_mask[direction]); |
156 TrackBits bits = (TrackBits)(TrackStatusToTrackBits(ts) & _bits_mask[direction]); |
158 if (bits == 0) |
157 if (bits == TRACK_BIT_NONE) return; |
159 return; |
|
160 |
158 |
161 assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY()); |
159 assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY()); |
162 |
160 |
163 uint i = 0; |
161 bool only_one_track = true; |
164 /* only one direction */ |
162 do { |
165 if (KillFirstBit(bits) == 0) { |
163 Track track = RemoveFirstTrack(&bits); |
166 i = FindFirstBit(bits); |
164 if (bits != TRACK_BIT_NONE) only_one_track = false; |
167 rd = tpf->rd; |
165 rd = tpf->rd; |
168 goto continue_here; |
|
169 } |
|
170 /* several directions */ |
|
171 do { |
|
172 i = FindFirstBit(bits); |
|
173 rd = tpf->rd; |
|
174 |
166 |
175 /* Change direction 4 times only */ |
167 /* Change direction 4 times only */ |
176 if ((byte)i != tpf->rd.pft_var6) { |
168 if (!only_one_track && track != tpf->rd.last_choosen_track) { |
177 if (++tpf->rd.depth > 4) { |
169 if (++tpf->rd.depth > 4) { |
178 tpf->rd = rd; |
170 tpf->rd = rd; |
179 return; |
171 return; |
180 } |
172 } |
181 tpf->rd.pft_var6 = (byte)i; |
173 tpf->rd.last_choosen_track = track; |
182 } |
174 } |
183 |
175 |
184 continue_here: |
176 tpf->the_dir = (Trackdir)(track + (HasBit(_otherdir_mask[direction], track) ? 8 : 0)); |
185 tpf->the_dir = (Trackdir)(i + (HasBit(_otherdir_mask[direction], i) ? 8 : 0)); |
177 |
186 |
178 if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length)) { |
187 if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, NULL)) { |
|
188 TPFMode2(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
179 TPFMode2(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
189 } |
180 } |
190 |
181 |
191 tpf->rd = rd; |
182 tpf->rd = rd; |
192 } while (ClrBit(bits, i) != 0); |
183 } while (bits != TRACK_BIT_NONE); |
193 |
184 |
194 } |
185 } |
195 |
186 |
196 /** |
187 /** |
197 * Checks if any vehicle can enter/leave tile in given diagdir |
188 * Checks if any vehicle can enter/leave tile in given diagdir |
259 GetTunnelBridgeTransportType(tile) != tpf->tracktype) { |
250 GetTunnelBridgeTransportType(tile) != tpf->tracktype) { |
260 return; |
251 return; |
261 } |
252 } |
262 } |
253 } |
263 |
254 |
264 uint32 bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type); |
255 uint32 bits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type)); |
265 |
256 |
266 /* Check in case of rail if the owner is the same */ |
257 /* Check in case of rail if the owner is the same */ |
267 if (tpf->tracktype == TRANSPORT_RAIL) { |
258 if (tpf->tracktype == TRANSPORT_RAIL) { |
268 if (bits != 0 && GetTileTrackStatus(tile_org, TRANSPORT_RAIL, 0) != 0) { |
259 if (bits != 0 && TrackStatusToTrackdirBits(GetTileTrackStatus(tile_org, TRANSPORT_RAIL, 0)) != TRACKDIR_BIT_NONE) { |
269 if (GetTileOwner(tile_org) != GetTileOwner(tile)) return; |
260 if (GetTileOwner(tile_org) != GetTileOwner(tile)) return; |
270 } |
261 } |
271 } |
262 } |
272 |
263 |
273 tpf->rd.cur_length++; |
264 tpf->rd.cur_length++; |
285 bits = KillFirstBit(bits); |
276 bits = KillFirstBit(bits); |
286 |
277 |
287 tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i); |
278 tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i); |
288 RememberData rd = tpf->rd; |
279 RememberData rd = tpf->rd; |
289 |
280 |
290 if (TPFSetTileBit(tpf, tile, tpf->the_dir) && |
281 /* make sure we are not leaving from invalid side */ |
291 !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) { |
282 if (TPFSetTileBit(tpf, tile, tpf->the_dir) && CanAccessTileInDir(tile, TrackdirToExitdir(tpf->the_dir), tpf->tracktype) && |
|
283 !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length) ) { |
292 TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
284 TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
293 } |
285 } |
294 tpf->rd = rd; |
286 tpf->rd = rd; |
295 } while (bits != 0); |
287 } while (bits != 0); |
296 } |
288 } |
309 tpf.new_link = tpf.links; |
301 tpf.new_link = tpf.links; |
310 tpf.num_links_left = lengthof(tpf.links); |
302 tpf.num_links_left = lengthof(tpf.links); |
311 |
303 |
312 tpf.rd.cur_length = 0; |
304 tpf.rd.cur_length = 0; |
313 tpf.rd.depth = 0; |
305 tpf.rd.depth = 0; |
314 tpf.rd.pft_var6 = 0; |
306 tpf.rd.last_choosen_track = INVALID_TRACK; |
315 |
307 |
316 tpf.var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000 |
308 tpf.var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000 |
317 |
309 |
318 tpf.disable_tile_hash = HasBit(flags, 12); // 0x1000 |
310 tpf.disable_tile_hash = HasBit(flags, 12); // 0x1000 |
319 |
311 |
320 |
312 |
321 tpf.tracktype = (TransportType)(flags & 0xFF); |
313 tpf.tracktype = (TransportType)(flags & 0xFF); |
322 tpf.sub_type = sub_type; |
314 tpf.sub_type = sub_type; |
323 |
315 |
324 if (HasBit(flags, 11)) { |
316 if (HasBit(flags, 11)) { |
325 tpf.rd.pft_var6 = 0xFF; |
317 tpf.enum_proc(tile, data, INVALID_TRACKDIR, 0); |
326 tpf.enum_proc(tile, data, INVALID_TRACKDIR, 0, 0); |
|
327 TPFMode2(&tpf, tile, direction); |
318 TPFMode2(&tpf, tile, direction); |
328 } else { |
319 } else { |
329 /* clear the hash_heads */ |
320 /* clear the hash_heads */ |
330 memset(tpf.hash_head, 0, sizeof(tpf.hash_head)); |
321 memset(tpf.hash_head, 0, sizeof(tpf.hash_head)); |
331 TPFMode1(&tpf, tile, direction); |
322 TPFMode1(&tpf, tile, direction); |
689 /* Not a regular rail tile? |
680 /* Not a regular rail tile? |
690 * Then we can't use the code below, but revert to more general code. */ |
681 * Then we can't use the code below, but revert to more general code. */ |
691 if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) { |
682 if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) { |
692 /* We found a tile which is not a normal railway tile. |
683 /* We found a tile which is not a normal railway tile. |
693 * Determine which tracks that exist on this tile. */ |
684 * Determine which tracks that exist on this tile. */ |
694 uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _tpfmode1_and[direction]; |
685 TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _tpfmode1_and[direction]; |
695 bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK)); |
686 bits = TrackStatusToTrackBits(ts); |
696 |
687 |
697 /* Check that the tile contains exactly one track */ |
688 /* Check that the tile contains exactly one track */ |
698 if (bits == 0 || KillFirstBit(bits) != 0) break; |
689 if (bits == 0 || KillFirstBit(bits) != 0) break; |
699 |
690 |
700 if (!HasBit(tpf->railtypes, GetRailType(tile))) { |
691 if (!HasBit(tpf->railtypes, GetRailType(tile))) { |