diff options
author | rubidium <rubidium@openttd.org> | 2009-12-01 22:45:39 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2009-12-01 22:45:39 +0000 |
commit | f52e27c688b00fd2b44887f0694717cd8449d31d (patch) | |
tree | 1268b38bfce0d85fd3868c19fb1454460ef135e7 /src/pathfinder/opf | |
parent | a7beae873310c67c8761994269627ebeabf08996 (diff) | |
download | openttd-f52e27c688b00fd2b44887f0694717cd8449d31d.tar.xz |
(svn r18364) -Codechange: move the pathfinders and their related files into a separate directory
Diffstat (limited to 'src/pathfinder/opf')
-rw-r--r-- | src/pathfinder/opf/opf_ship.cpp | 107 | ||||
-rw-r--r-- | src/pathfinder/opf/opf_ship.h | 21 |
2 files changed, 128 insertions, 0 deletions
diff --git a/src/pathfinder/opf/opf_ship.cpp b/src/pathfinder/opf/opf_ship.cpp new file mode 100644 index 000000000..7ee5ec9c3 --- /dev/null +++ b/src/pathfinder/opf/opf_ship.cpp @@ -0,0 +1,107 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file pathfind.cpp Implementation of the oldest supported pathfinder. */ + +#include "../../stdafx.h" +#include "../../debug.h" +#include "../../tunnelbridge_map.h" +#include "../../core/alloc_type.hpp" +#include "../../tunnelbridge.h" +#include "opf_ship.h" + +struct RememberData { + uint16 cur_length; + byte depth; + Track last_choosen_track; +}; + +struct TrackPathFinder { + TPFEnumProc *enum_proc; + void *userdata; + RememberData rd; + TrackdirByte the_dir; +}; + +static void TPFModeShip(TrackPathFinder *tpf, TileIndex tile, DiagDirection direction) +{ + if (IsTileType(tile, MP_TUNNELBRIDGE)) { + /* wrong track type */ + if (GetTunnelBridgeTransportType(tile) != TRANSPORT_WATER) return; + + DiagDirection dir = GetTunnelBridgeDirection(tile); + /* entering tunnel / bridge? */ + if (dir == direction) { + TileIndex endtile = GetOtherTunnelBridgeEnd(tile); + + tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1; + + tile = endtile; + } else { + /* leaving tunnel / bridge? */ + if (ReverseDiagDir(dir) != direction) return; + } + } + + /* This addition will sometimes overflow by a single tile. + * The use of TILE_MASK here makes sure that we still point at a valid + * tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail. */ + tile = TILE_MASK(tile + TileOffsByDiagDir(direction)); + + if (++tpf->rd.cur_length > 50) + return; + + TrackBits bits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & DiagdirReachesTracks(direction); + if (bits == TRACK_BIT_NONE) return; + + assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY()); + + bool only_one_track = true; + do { + Track track = RemoveFirstTrack(&bits); + if (bits != TRACK_BIT_NONE) only_one_track = false; + RememberData rd = tpf->rd; + + /* Change direction 4 times only */ + if (!only_one_track && track != tpf->rd.last_choosen_track) { + if (++tpf->rd.depth > 4) { + tpf->rd = rd; + return; + } + tpf->rd.last_choosen_track = track; + } + + tpf->the_dir = TrackEnterdirToTrackdir(track, direction); + + if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length)) { + TPFModeShip(tpf, tile, TrackdirToExitdir(tpf->the_dir)); + } + + tpf->rd = rd; + } while (bits != TRACK_BIT_NONE); + +} + +void OPFShipFollowTrack(TileIndex tile, DiagDirection direction, TPFEnumProc *enum_proc, void *data) +{ + assert(IsValidDiagDirection(direction)); + + SmallStackSafeStackAlloc<TrackPathFinder, 1> tpf; + + /* initialize path finder variables */ + tpf->userdata = data; + tpf->enum_proc = enum_proc; + + tpf->rd.cur_length = 0; + tpf->rd.depth = 0; + tpf->rd.last_choosen_track = INVALID_TRACK; + + tpf->enum_proc(tile, data, INVALID_TRACKDIR, 0); + TPFModeShip(tpf, tile, direction); +} diff --git a/src/pathfinder/opf/opf_ship.h b/src/pathfinder/opf/opf_ship.h new file mode 100644 index 000000000..6afff227b --- /dev/null +++ b/src/pathfinder/opf/opf_ship.h @@ -0,0 +1,21 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file opf_ship.h Original pathfinder for ships; very simple. */ + +#ifndef OPF_SHIP_H +#define OPF_SHIP_H + +#include "../../direction_type.h" + +typedef bool TPFEnumProc(TileIndex tile, void *data, Trackdir trackdir, uint length); + +void OPFShipFollowTrack(TileIndex tile, DiagDirection direction, TPFEnumProc *enum_proc, void *data); + +#endif /* OPF_SHIP_H */ |