summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatthijs <matthijs@openttd.org>2005-02-06 22:36:08 +0000
committermatthijs <matthijs@openttd.org>2005-02-06 22:36:08 +0000
commitc5c5c9b17c1c4fd543873f866534d3fa06f9f1cb (patch)
treeb4e6f6fce72b1b3fcb2b25b635ad70c6bd5b6741
parenteed181245dffbc04a2e527e8e7cccf44ce4fda86 (diff)
downloadopenttd-c5c5c9b17c1c4fd543873f866534d3fa06f9f1cb.tar.xz
(svn r1834) - Fix: NPF does not check the owner of its target, busses try to enter other players' depots. TODO
- Add: asserts to find the v->u.rail.track == 0 problem. - Add: IsValidDepot(), IsValidTown(), IsValidSign(), IsValidVehicle(), IsValidStation() - Add: GetTileOwner(), IsTileOwner() - Codechange: Replaced IsShipDepotTile(), IsTrainDepotTile(), IsRoadDepotTile() by IsTileDepotType(). - Codechange: typedeffed the MAP_OWNERS as Owner. Should be used as variable type. - Codechange: Replaced a few uint by TileIndex.
-rw-r--r--ai.c8
-rw-r--r--ai_new.c2
-rw-r--r--ai_pathfinder.c3
-rw-r--r--depot.c31
-rw-r--r--depot.h34
-rw-r--r--industry.h8
-rw-r--r--map.h8
-rw-r--r--npf.c81
-rw-r--r--npf.h15
-rw-r--r--order_gui.c2
-rw-r--r--rail_cmd.c1
-rw-r--r--roadveh_cmd.c10
-rw-r--r--roadveh_gui.c4
-rw-r--r--ship_cmd.c16
-rw-r--r--ship_gui.c6
-rw-r--r--signs.h8
-rw-r--r--station.h8
-rw-r--r--tile.h10
-rw-r--r--town.h8
-rw-r--r--train_cmd.c27
-rw-r--r--train_gui.c4
-rw-r--r--ttd.h7
-rw-r--r--tunnelbridge_cmd.c1
-rw-r--r--vehicle.h8
24 files changed, 180 insertions, 130 deletions
diff --git a/ai.c b/ai.c
index 5e3d9e2bd..2a1132993 100644
--- a/ai.c
+++ b/ai.c
@@ -284,7 +284,7 @@ static void AiHandleReplaceTrain(Player *p)
uint tile;
// wait until the vehicle reaches the depot.
- if (!IsTrainDepotTile(v->tile) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
+ if (!IsTileDepotType(v->tile, TRANSPORT_RAIL) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
AiHandleGotoDepot(p, CMD_TRAIN_GOTO_DEPOT);
return;
}
@@ -312,7 +312,7 @@ static void AiHandleReplaceRoadVeh(Player *p)
int veh;
uint tile;
- if (!IsRoadDepotTile(v->tile) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED)) {
+ if (!IsTileDepotType(v->tile, TRANSPORT_ROAD) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED)) {
AiHandleGotoDepot(p, CMD_SEND_ROADVEH_TO_DEPOT);
return;
}
@@ -3561,7 +3561,7 @@ static void AiStateSellVeh(Player *p)
if (v->owner == _current_player) {
if (v->type == VEH_Train) {
- if (!IsTrainDepotTile(v->tile) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
+ if (!IsTileDepotType(v->tile, TRANSPORT_RAIL) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
if (v->current_order.type != OT_GOTO_DEPOT)
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_TRAIN_GOTO_DEPOT);
goto going_to_depot;
@@ -3571,7 +3571,7 @@ static void AiStateSellVeh(Player *p)
DoCommandByTile(v->tile, v->index, 1, DC_EXEC, CMD_SELL_RAIL_WAGON);
} else if (v->type == VEH_Road) {
- if (!IsRoadDepotTile(v->tile) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED)) {
+ if (!IsTileDepotType(v->tile, TRANSPORT_ROAD) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED)) {
if (v->current_order.type != OT_GOTO_DEPOT)
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
goto going_to_depot;
diff --git a/ai_new.c b/ai_new.c
index c3de5fedb..3d28f7f9b 100644
--- a/ai_new.c
+++ b/ai_new.c
@@ -1213,7 +1213,7 @@ static void AiNew_CheckVehicle(Player *p, Vehicle *v) {
// We are already sending him back
if (AiNew_GetSpecialVehicleFlag(p, v) & AI_VEHICLEFLAG_SELL) {
- if (v->type == VEH_Road && IsRoadDepotTile(v->tile) &&
+ if (v->type == VEH_Road && IsTileDepotType(v->tile, TRANSPORT_ROAD) &&
(v->vehstatus&VS_STOPPED)) {
// We are at the depot, sell the vehicle
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
diff --git a/ai_pathfinder.c b/ai_pathfinder.c
index 1a4dcd684..14d648786 100644
--- a/ai_pathfinder.c
+++ b/ai_pathfinder.c
@@ -5,6 +5,7 @@
#include "tile.h"
#include "command.h"
#include "ai.h"
+#include "depot.h"
#define TEST_STATION_NO_DIR 0xFF
@@ -35,7 +36,7 @@ static bool IsRoad(TileIndex tile)
{
return
// MP_STREET, but not a road depot?
- (IsTileType(tile, MP_STREET) && !(_map5[tile] & 0x20)) ||
+ (IsTileType(tile, MP_STREET) && !(IsTileDepotType(tile, TRANSPORT_ROAD))) ||
(IsTileType(tile, MP_TUNNELBRIDGE) && (
// road tunnel?
((_map5[tile] & 0x80) == 0 && (_map5[tile] & 0x4) == 0x4) ||
diff --git a/depot.c b/depot.c
index 0430162d2..f52bd2573 100644
--- a/depot.c
+++ b/depot.c
@@ -46,33 +46,6 @@ Depot *GetDepotByTile(uint tile)
}
/**
- * Check if a tile is a road-depot
- */
-bool IsRoadDepotTile(TileIndex tile)
-{
- return IsTileType(tile, MP_STREET) &&
- (_map5[tile] & 0xF0) == 0x20;
-}
-
-/**
- * Check if a tile is a train-depot
- */
-bool IsTrainDepotTile(TileIndex tile)
-{
- return IsTileType(tile, MP_RAILWAY) &&
- (_map5[tile] & 0xFC) == 0xC0;
-}
-
-/**
- * Check if a tile is a ship-depot
- */
-bool IsShipDepotTile(TileIndex tile)
-{
- return IsTileType(tile, MP_WATER) &&
- (_map5[tile] & ~3) == 0x80;
-}
-
-/**
* Allocate a new depot
*/
Depot *AllocateDepot(void)
@@ -80,7 +53,7 @@ Depot *AllocateDepot(void)
Depot *depot;
FOR_ALL_DEPOTS(depot) {
- if (depot->xy == 0) {
+ if (!IsValidDepot(depot)) {
uint index = depot->index;
memset(depot, 0, sizeof(Depot));
@@ -142,7 +115,7 @@ static void Save_DEPT(void)
Depot *depot;
FOR_ALL_DEPOTS(depot) {
- if (depot->xy != 0) {
+ if (IsValidDepot(depot)) {
SlSetArrayIndex(depot->index);
SlObject(depot, _depot_desc);
}
diff --git a/depot.h b/depot.h
index b2ae02068..11f47401a 100644
--- a/depot.h
+++ b/depot.h
@@ -2,6 +2,7 @@
#define DEPOT_H
#include "pool.h"
+#include "tile.h"
struct Depot {
TileIndex xy;
@@ -40,12 +41,39 @@ VARDEF TileIndex _last_built_road_depot_tile;
VARDEF TileIndex _last_built_aircraft_depot_tile;
VARDEF TileIndex _last_built_ship_depot_tile;
-bool IsTrainDepotTile(TileIndex tile);
-bool IsRoadDepotTile(TileIndex tile);
+/**
+ * Check if a depot really exists.
+ */
+static inline bool IsValidDepot(Depot* depot)
+{
+ return depot->xy != 0; /* XXX: Replace by INVALID_TILE someday */
+}
+
+/**
+ * Check if a tile is a depot of the given type.
+ */
+static inline bool IsTileDepotType(TileIndex tile, TransportType type)
+{
+ switch(type)
+ {
+ case TRANSPORT_RAIL:
+ return IsTileType(tile, MP_RAILWAY) && (_map5[tile] & 0xFC) == 0xC0;
+ break;
+ case TRANSPORT_ROAD:
+ return IsTileType(tile, MP_STREET) && (_map5[tile] & 0xF0) == 0x20;
+ break;
+ case TRANSPORT_WATER:
+ return IsTileType(tile, MP_WATER) && (_map5[tile] & ~3) == 0x80;
+ break;
+ default:
+ assert(0);
+ return false;
+ }
+}
+
Depot *GetDepotByTile(uint tile);
void InitializeDepot(void);
Depot *AllocateDepot(void);
-bool IsShipDepotTile(TileIndex tile);
void DoDeleteDepot(uint tile);
#endif /* DEPOT_H */
diff --git a/industry.h b/industry.h
index 7fac15f28..c7a2dd063 100644
--- a/industry.h
+++ b/industry.h
@@ -32,6 +32,14 @@ struct Industry {
extern MemoryPool _industry_pool;
/**
+ * Check if an Industry really exists.
+ */
+static inline bool IsValidIndustry(Industry* industry)
+{
+ return industry->xy != 0; /* XXX: Replace by INVALID_TILE someday */
+}
+
+/**
* Get the pointer to the industry with index 'index'
*/
static inline Industry *GetIndustry(uint index)
diff --git a/map.h b/map.h
index 55704a555..f9cff89e2 100644
--- a/map.h
+++ b/map.h
@@ -35,6 +35,14 @@ uint ScaleByMapSize(uint); // Scale relative to the number of tiles
uint ScaleByMapSize1D(uint); // Scale relative to the circumference of the map
typedef uint32 TileIndex;
+
+typedef enum {
+ OWNER_TOWN = 0xf, // a town owns the tile
+ OWNER_NONE = 0x10, // nobody owns the tile
+ OWNER_WATER = 0x11, // "water" owns the tile
+ OWNER_SPECTATOR = 0xff, // spectator in MP or in scenario editor
+} Owner;
+
enum {
INVALID_TILE = (uint32) -1
};
diff --git a/npf.c b/npf.c
index 5a1696436..965a0a919 100644
--- a/npf.c
+++ b/npf.c
@@ -319,24 +319,7 @@ int32 NPFRailPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent) {
/* Will find any depot */
int32 NPFFindDepot(AyStar* as, OpenListNode *current) {
TileIndex tile = current->path.node.tile;
- bool isDepot;
- switch(GetTileType(tile)) {
- case MP_RAILWAY:
- /* Check if this is a rail depot */
- isDepot = IsTrainDepotTile(tile);
- break;
- case MP_STREET:
- /* Check if this is a road depot */
- isDepot = IsRoadDepotTile(tile);
- break;
- case MP_WATER:
- isDepot = IsShipDepotTile(tile);
- break;
- default:
- isDepot = false;
- break;
- }
- if (isDepot)
+ if (IsTileDepotType(tile, as->user_data[NPF_TYPE]))
return AYSTAR_FOUND_END_NODE;
else
return AYSTAR_DONE;
@@ -397,11 +380,7 @@ void NPFFollowTrack(AyStar* aystar, OpenListNode* current) {
flotr = FindLengthOfTunnel(src_tile, src_exitdir);
dst_tile = flotr.tile;
} else {
- if (
- (type == TRANSPORT_ROAD && IsRoadStationTile(src_tile))
- || (type == TRANSPORT_ROAD && IsRoadDepotTile(src_tile))
- || (type == TRANSPORT_RAIL && IsTrainDepotTile(src_tile))
- ){
+ if (IsTileDepotType(src_tile, type)){
/* This is a road station or a train or road depot. We can enter and exit
* those from one side only. Trackdirs don't support that (yet), so we'll
* do this here. */
@@ -429,19 +408,29 @@ void NPFFollowTrack(AyStar* aystar, OpenListNode* current) {
}
// TODO: check correct rail type (mono, maglev, etc)
- // TODO: check tile owner
+
+ /* Check the owner of the tile */
+ if (
+ IsTileType(dst_tile, MP_RAILWAY) /* Rail tile */
+ || IsTileDepotType(dst_tile, TRANSPORT_ROAD) /* Road depot tile */
+ || IsTileType(dst_tile, MP_STATION) /* Station tile */
+ || IsTileDepotType(dst_tile, TRANSPORT_WATER) /* Water depot tile */
+ ) /* TODO: Crossings, tunnels and bridges are "public" now */
+ /* The above cases are "private" tiles, we need to check the owner */
+ if (!IsTileOwner(dst_tile, aystar->user_data[NPF_OWNER]))
+ return;
/* Determine available tracks */
- if (type == TRANSPORT_ROAD && (IsRoadStationTile(dst_tile) || IsRoadDepotTile(dst_tile))){
- byte exitdir;
+ if (type == TRANSPORT_ROAD && (IsRoadStationTile(dst_tile) || IsTileDepotType(dst_tile, TRANSPORT_ROAD))){
/* Road stations and depots return 0 on GTTS, so we have to do this by hand... */
- if (IsRoadStationTile(dst_tile))
- exitdir = GetRoadStationDir(dst_tile);
- else /* Road depot */
- exitdir = _map5[dst_tile] & 3; /* Extract the direction from the map */
- ts = (1 << _dir_to_diag_trackdir[exitdir]) |
- (1 << _dir_to_diag_trackdir[_reverse_dir[exitdir]]);
- /* Find the trackdirs that are available for a station with this orientation. They are in both directions */
+ byte exitdir;
+ if (IsRoadStationTile(dst_tile))
+ exitdir = GetRoadStationDir(dst_tile);
+ else /* Road depot */
+ /* Find the trackdirs that are available for a depot with this orientation. They are in both directions */
+ exitdir = _map5[dst_tile] & 3; /* Extract the direction from the map */
+ ts = (1 << _dir_to_diag_trackdir[exitdir])
+ | (1 << _dir_to_diag_trackdir[_reverse_dir[exitdir]]);
} else {
ts = GetTileTrackStatus(dst_tile, type);
}
@@ -500,7 +489,7 @@ void NPFFollowTrack(AyStar* aystar, OpenListNode* current) {
* multiple targets that are spread around, we should perform a breadth first
* search by specifiying CalcZero as our heuristic.
*/
-NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type) {
+NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner) {
int r;
NPFFoundTargetData result;
@@ -539,6 +528,7 @@ NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFF
/* Initialize user_data */
_npf_aystar.user_data[NPF_TYPE] = type;
+ _npf_aystar.user_data[NPF_OWNER] = owner;
/* GO! */
r = AyStarMain_Main(&_npf_aystar);
@@ -556,7 +546,7 @@ NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFF
return result;
}
-NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, byte trackdir1, TileIndex tile2, byte trackdir2, NPFFindStationOrTileData* target, TransportType type) {
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, byte trackdir1, TileIndex tile2, byte trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner) {
AyStarNode start1;
AyStarNode start2;
@@ -565,10 +555,10 @@ NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, byte trackdir1
start1.direction = trackdir1;
start2.direction = trackdir2;
- return NPFRouteInternal(&start1, &start2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type);
+ return NPFRouteInternal(&start1, &start2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner);
}
-NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, byte trackdir, NPFFindStationOrTileData* target, TransportType type) {
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, byte trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner) {
AyStarNode start;
assert(tile != 0);
@@ -579,10 +569,10 @@ NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, byte trackdir, NPFFin
* return a not found then */
start.user_data[NPF_TRACKDIR_CHOICE] = 0xff;
- return NPFRouteInternal(&start, NULL, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type);
+ return NPFRouteInternal(&start, NULL, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner);
}
-NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, byte trackdir, TransportType type) {
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, byte trackdir, TransportType type, Owner owner) {
AyStarNode start;
start.tile = tile;
@@ -593,10 +583,10 @@ NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, byte trackdir, Tr
/* perform a breadth first search. Target is NULL,
* since we are just looking for any depot...*/
- return NPFRouteInternal(&start, NULL, NULL, NPFFindDepot, NPFCalcZero, type);
+ return NPFRouteInternal(&start, NULL, NULL, NPFFindDepot, NPFCalcZero, type, owner);
}
-NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, TransportType type) {
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, TransportType type, Owner owner) {
/* Okay, what we're gonna do. First, we look at all depots, calculate
* the manhatten distance to get to each depot. We then sort them by
* distance. We start by trying to plan a route to the closest, then
@@ -629,7 +619,10 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, Tran
init_InsSort(&depots);
/* Okay, let's find all depots that we can use first */
FOR_ALL_DEPOTS(depot) {
- if (IsTileType(depot->xy, tiletype))
+ /* Check if this is really a valid depot, it is of the needed type and
+ * owner */
+ if (IsValidDepot(depot) && IsTileDepotType(depot->xy, tiletype) && IsTileOwner(depot->xy, owner))
+ /* If so, let's add it to the queue, sorted by distance */
depots.push(&depots, depot, DistanceManhattan(tile, depot->xy));
}
@@ -655,6 +648,7 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, Tran
/* Initialize user_data */
_npf_aystar.user_data[NPF_TYPE] = type;
+ _npf_aystar.user_data[NPF_OWNER] = owner;
/* Initialize Start Node */
start.tile = tile;
@@ -663,11 +657,12 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, Tran
/* Initialize Result */
_npf_aystar.user_path = &result;
best_result.best_path_dist = (uint)-1;
+ best_result.best_bird_dist = (uint)-1;
/* Just iterate the depots in order of increasing distance */
while ((current = depots.pop(&depots))) {
/* Check to see if we already have a path shorter than this
- * depot's manhattan distance. Hack: We call DistanceManhattan
+ * depot's manhattan distance. HACK: We call DistanceManhattan
* again, we should probably modify the queue to give us that
* value... */
if ( DistanceManhattan(tile, current->xy * NPF_TILE_LENGTH) > best_result.best_path_dist)
diff --git a/npf.h b/npf.h
index 0b3e17a0e..1444cbe73 100644
--- a/npf.h
+++ b/npf.h
@@ -15,7 +15,8 @@ typedef struct NPFFindStationOrTileData { /* Meant to be stored in AyStar.target
} NPFFindStationOrTileData;
enum { /* Indices into AyStar.userdata[] */
- NPF_TYPE = 0, /* Contains an TransportTypes value */
+ NPF_TYPE = 0, /* Contains a TransportTypes value */
+ NPF_OWNER, /* Contains an Owner value */
};
enum { /* Indices into AyStarNode.userdata[] */
@@ -30,7 +31,7 @@ enum { /* Flags for AyStarNode.userdata[NPF_NODE_FLAGS]*/
typedef struct NPFFoundTargetData { /* Meant to be stored in AyStar.userpath */
uint best_bird_dist; /* The best heuristic found. Is 0 if the target was found */
uint best_path_dist; /* The shortest path. Is (uint)-1 if no path is found */
- byte best_trackdir; /* The trackdir that leads to the shortes path/closest birds dist */
+ byte best_trackdir; /* The trackdir that leads to the shortest path/closest birds dist */
AyStarNode node; /* The node within the target the search led us to */
} NPFFoundTargetData;
@@ -39,20 +40,20 @@ typedef struct NPFFoundTargetData { /* Meant to be stored in AyStar.userpath */
/* Will search from the given tile and direction, for a route to the given
* station for the given transport type. See the declaration of
* NPFFoundTargetData above for the meaning of the result. */
-NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, byte trackdir, NPFFindStationOrTileData* target, TransportType type);
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, byte trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner);
/* Will search as above, but with two start nodes, the second being the
* reverse. Look at the NPF_NODE_REVERSE flag in the result node to see which
* direction was taken */
-NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, byte trackdir1, TileIndex tile2, byte trackdir2, NPFFindStationOrTileData* target, TransportType type);
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, byte trackdir1, TileIndex tile2, byte trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner);
/* Will search a route to the closest depot. */
/* Search using breadth first. Good for little track choice and inaccurate
* heuristic, such as railway/road */
-NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, byte trackdir, TransportType type);
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, byte trackdir, TransportType type, Owner owner);
/* Search by trying each depot in order of Manhattan Distance. Good for lots
- * of choices and accurate heuristics, such as water */
-NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, TransportType type);
+ * of choices and accurate heuristics, such as water. */
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, byte trackdir, TransportType type, Owner owner);
void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v);
diff --git a/order_gui.c b/order_gui.c
index a7dce599d..46be40278 100644
--- a/order_gui.c
+++ b/order_gui.c
@@ -194,7 +194,7 @@ static Order GetOrderCmdFromTile(Vehicle *v, uint tile)
case MP_WATER:
if (v->type != VEH_Ship) break;
- if ( IsShipDepotTile(tile) && _map_owner[tile] == _local_player) {
+ if ( IsTileDepotType(tile, TRANSPORT_ROAD) && IsTileOwner(tile, _local_player)) {
switch (_map5[tile]) {
case 0x81: tile--; break;
case 0x83: tile-= TILE_XY(0,1); break;
diff --git a/rail_cmd.c b/rail_cmd.c
index c4d8a2e37..845d6d8d0 100644
--- a/rail_cmd.c
+++ b/rail_cmd.c
@@ -2260,6 +2260,7 @@ static uint32 VehicleEnter_Track(Vehicle *v, uint tile, int x, int y)
if ((v=v->next) != NULL) {
v->vehstatus &= ~VS_HIDDEN;
v->u.rail.track = _depot_track_mask[dir];
+ assert(v->u.rail.track);
}
}
}
diff --git a/roadveh_cmd.c b/roadveh_cmd.c
index 872d91a9a..6dd84da5a 100644
--- a/roadveh_cmd.c
+++ b/roadveh_cmd.c
@@ -116,12 +116,12 @@ int32 CmdBuildRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
int32 cost;
Vehicle *v;
UnitID unit_num;
- uint tile = TILE_FROM_XY(x,y);
+ TileIndex tile = TILE_FROM_XY(x,y);
Engine *e;
if (!IsEngineBuildable(p1, VEH_Road)) return CMD_ERROR;
- if (!IsRoadDepotTile((TileIndex)tile)) return CMD_ERROR;
+ if (!IsTileDepotType(tile, TRANSPORT_ROAD)) return CMD_ERROR;
if (_map_owner[tile] != _current_player) return CMD_ERROR;
@@ -243,7 +243,7 @@ int32 CmdSellRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
- if (!IsRoadDepotTile(v->tile) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED))
+ if (!IsTileDepotType(v->tile, TRANSPORT_ROAD) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED))
return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
if (flags & DC_EXEC) {
@@ -297,7 +297,7 @@ static Depot *FindClosestRoadDepot(Vehicle *v)
NPFFoundTargetData ftd;
/* See where we are now */
byte trackdir = _dir_to_diag_trackdir[(v->direction>>1)&3];
- ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD);
+ ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->owner);
if (ftd.best_bird_dist == 0)
return GetDepotByTile(ftd.node.tile); /* Target found */
else
@@ -1104,7 +1104,7 @@ static int RoadFindPathToDest(Vehicle *v, uint tile, int enterdir)
trackdir = _dir_to_diag_trackdir[enterdir];
//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
- ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD);
+ ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->owner);
if (ftd.best_bird_dist != 0 || ftd.best_trackdir == 0xff) {
/* Not found, just do something, or we are already there */
//TODO: maybe display error?
diff --git a/roadveh_gui.c b/roadveh_gui.c
index d5b5d28da..f67365cf0 100644
--- a/roadveh_gui.c
+++ b/roadveh_gui.c
@@ -822,7 +822,7 @@ static void PlayerRoadVehWndProc(Window *w, WindowEvent *e)
DrawVehicleProfitButton(v, x, y + 13);
SetDParam(0, v->unitnumber);
- if (IsRoadDepotTile(v->tile) && (v->vehstatus & VS_HIDDEN))
+ if (IsTileDepotType(v->tile, TRANSPORT_ROAD) && (v->vehstatus & VS_HIDDEN))
str = STR_021F;
else
str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
@@ -881,7 +881,7 @@ static void PlayerRoadVehWndProc(Window *w, WindowEvent *e)
tile = _last_built_road_depot_tile;
do {
- if (_map_owner[tile] == _local_player && IsRoadDepotTile(tile)) {
+ if (IsTileOwner(tile, _local_player) && IsTileDepotType(tile, TRANSPORT_ROAD)) {
ShowRoadDepotWindow(tile);
ShowBuildRoadVehWindow(tile);
return;
diff --git a/ship_cmd.c b/ship_cmd.c
index 684d30471..537059ffd 100644
--- a/ship_cmd.c
+++ b/ship_cmd.c
@@ -69,14 +69,12 @@ static Depot *FindClosestShipDepot(Vehicle *v)
Depot *depot;
Depot *best_depot = NULL;
uint tile, dist, best_dist = (uint)-1;
- byte owner = v->owner;
uint tile2 = v->tile;
if (_patches.new_pathfinding_all) {
NPFFoundTargetData ftd;
byte trackdir = _track_direction_to_trackdir[FIND_FIRST_BIT(v->u.ship.state)][v->direction];
- /* XXX --- SLOW!!!! */
- ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER);
+ ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, v->owner);
if (ftd.best_bird_dist == 0)
best_depot = GetDepotByTile(ftd.node.tile); /* Found target */
else
@@ -84,7 +82,7 @@ static Depot *FindClosestShipDepot(Vehicle *v)
} else {
FOR_ALL_DEPOTS(depot) {
tile = depot->xy;
- if (IsTileType(tile, MP_WATER) && _map_owner[tile] == owner) {
+ if (IsValidDepot(depot) && IsTileDepotType(tile, TRANSPORT_WATER) && IsTileOwner(tile, v->owner)) {
dist = DistanceManhattan(tile, tile2);
if (dist < best_dist) {
best_dist = dist;
@@ -598,7 +596,7 @@ static int ChooseShipTrack(Vehicle *v, uint tile, int enterdir, uint tracks)
NPFFillWithOrderData(&fstd, v);
- ftd = NPFRouteToStationOrTile(src_tile, _track_direction_to_trackdir[track][v->direction], &fstd, TRANSPORT_WATER);
+ ftd = NPFRouteToStationOrTile(src_tile, _track_direction_to_trackdir[track][v->direction], &fstd, TRANSPORT_WATER, v->owner);
if (ftd.best_bird_dist == 0 && ftd.best_trackdir != 0xff)
/* Found the target, and it is not our current tile */
@@ -876,12 +874,12 @@ int32 CmdBuildShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
int32 value;
Vehicle *v;
UnitID unit_num;
- uint tile = TILE_FROM_XY(x,y);
+ TileIndex tile = TILE_FROM_XY(x,y);
Engine *e;
if (!IsEngineBuildable(p1, VEH_Ship)) return CMD_ERROR;
- if (!IsShipDepotTile((TileIndex)tile)) return CMD_ERROR;
+ if (!IsTileDepotType(tile, TRANSPORT_WATER)) return CMD_ERROR;
if (_map_owner[tile] != _current_player) return CMD_ERROR;
@@ -964,7 +962,7 @@ int32 CmdSellShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
- if (!IsShipDepotTile(v->tile) || v->u.road.state != 0x80 || !(v->vehstatus&VS_STOPPED))
+ if (!IsTileDepotType(v->tile, TRANSPORT_WATER) || v->u.road.state != 0x80 || !(v->vehstatus&VS_STOPPED))
return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
if (flags & DC_EXEC) {
@@ -1088,7 +1086,7 @@ int32 CmdRefitShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return CMD_ERROR;
if (!( SkipStoppedInDepotCheck )) {
- if (!IsShipDepotTile(v->tile) ||
+ if (!IsTileDepotType(v->tile, TRANSPORT_WATER) ||
!(v->vehstatus&VS_STOPPED) ||
v->u.ship.state != 0x80)
return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
diff --git a/ship_gui.c b/ship_gui.c
index 2da8378f5..31d7081d9 100644
--- a/ship_gui.c
+++ b/ship_gui.c
@@ -491,7 +491,7 @@ static void ShipViewWndProc(Window *w, WindowEvent *e) {
if (ShipVehInfo(v->engine_type)->refittable &&
v->vehstatus&VS_STOPPED &&
v->u.ship.state == 0x80 &&
- IsShipDepotTile(v->tile))
+ IsTileDepotType(v->tile, TRANSPORT_WATER))
disabled = 0;
if (v->owner != _local_player)
@@ -979,7 +979,7 @@ static void PlayerShipsWndProc(Window *w, WindowEvent *e)
DrawVehicleProfitButton(v, x, y + 13);
SetDParam(0, v->unitnumber);
- if (IsShipDepotTile(v->tile) && (v->vehstatus & VS_HIDDEN))
+ if (IsTileDepotType(v->tile, TRANSPORT_WATER) && (v->vehstatus & VS_HIDDEN))
str = STR_021F;
else
str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
@@ -1040,7 +1040,7 @@ static void PlayerShipsWndProc(Window *w, WindowEvent *e)
tile = _last_built_ship_depot_tile;
do {
- if (_map_owner[tile] == _local_player && IsShipDepotTile(tile)) {
+ if (_map_owner[tile] == _local_player && IsTileDepotType(tile, TRANSPORT_WATER)) {
ShowShipDepotWindow(tile);
ShowBuildShipWindow(tile);
return;
diff --git a/signs.h b/signs.h
index 1d19206c5..dc8c65785 100644
--- a/signs.h
+++ b/signs.h
@@ -18,6 +18,14 @@ typedef struct SignStruct {
extern MemoryPool _sign_pool;
/**
+ * Check if a Sign really exists.
+ */
+static inline bool IsValidSign(SignStruct* ss)
+{
+ return ss->str != 0;
+}
+
+/**
* Get the pointer to the sign with index 'index'
*/
static inline SignStruct *GetSign(uint index)
diff --git a/station.h b/station.h
index 26d22b827..4a4d721b1 100644
--- a/station.h
+++ b/station.h
@@ -272,6 +272,14 @@ static inline bool IsRoadStationTile(uint tile) {
return IsTileType(tile, MP_STATION) && IS_BYTE_INSIDE(_map5[tile], 0x43, 0x4B);
}
+/**
+ * Check if a station really exists.
+ */
+static inline bool IsValidStation(Station* station)
+{
+ return station->xy != 0; /* XXX: Replace by INVALID_TILE someday */
+}
+
/* Get's the direction the station exit points towards. Ie, returns 0 for a
* station with the exit NE. */
static inline byte GetRoadStationDir(uint tile) {
diff --git a/tile.h b/tile.h
index bd2917223..bcb06d29d 100644
--- a/tile.h
+++ b/tile.h
@@ -57,4 +57,14 @@ static inline bool IsTileType(TileIndex tile, TileType type)
return GetTileType(tile) == type;
}
+static inline bool GetTileOwner(TileIndex tile)
+{
+ return _map_owner[tile];
+}
+
+static inline bool IsTileOwner(TileIndex tile, Owner owner)
+{
+ return GetTileOwner(tile) == owner;
+}
+
#endif
diff --git a/town.h b/town.h
index c5c3b574f..cf7eee16e 100644
--- a/town.h
+++ b/town.h
@@ -134,6 +134,14 @@ VARDEF uint16 *_town_sort;
extern MemoryPool _town_pool;
/**
+ * Check if a Town really exists.
+ */
+static inline bool IsValidTown(Town* town)
+{
+ return town->xy != 0; /* XXX: Replace by INVALID_TILE someday */
+}
+
+/**
* Get the pointer to the town with index 'index'
*/
static inline Town *GetTown(uint index)
diff --git a/train_cmd.c b/train_cmd.c
index a26d37786..3ab59828b 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -538,11 +538,11 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
Vehicle *v, *u;
UnitID unit_num;
Engine *e;
- uint tile = TILE_FROM_XY(x,y);
+ TileIndex tile = TILE_FROM_XY(x,y);
if (!IsEngineBuildable(p1, VEH_Train)) return CMD_ERROR;
- if (!IsTrainDepotTile((TileIndex)tile)) return CMD_ERROR;
+ if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR;
if (_map_owner[tile] != _current_player) return CMD_ERROR;
@@ -641,7 +641,7 @@ int CheckTrainStoppedInDepot(Vehicle *v)
TileIndex tile = v->tile;
/* check if stopped in a depot */
- if (!IsTrainDepotTile(tile) || v->cur_speed != 0) {
+ if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) {
errmsg:
_error_message = STR_881A_TRAINS_CAN_ONLY_BE_ALTERED;
return -1;
@@ -1128,7 +1128,7 @@ static void ReverseTrainDirection(Vehicle *v)
int l = 0, r = -1;
Vehicle *u;
- if (IsTrainDepotTile(v->tile))
+ if (IsTileDepotType(v->tile, TRANSPORT_RAIL))
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
/* Check if we were approaching a rail/road-crossing */
@@ -1156,7 +1156,7 @@ static void ReverseTrainDirection(Vehicle *v)
ReverseTrainSwapVeh(v, l++, r--);
} while (l <= r);
- if (IsTrainDepotTile(v->tile))
+ if (IsTileDepotType(v->tile, TRANSPORT_RAIL))
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
CLRBIT(v->u.rail.flags, VRF_REVERSING);
@@ -1176,7 +1176,7 @@ int32 CmdReverseTrainDirection(int x, int y, uint32 flags, uint32 p1, uint32 p2)
_error_message = STR_EMPTY;
-// if (v->u.rail.track & 0x80 || IsTrainDepotTile(v->tile))
+// if (v->u.rail.track & 0x80 || IsTileDepotType(v->tile, TRANSPORT_RAIL))
// return CMD_ERROR;
if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0)
@@ -1300,7 +1300,7 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v)
tfdd.owner = v->owner;
tfdd.best_length = (uint)-1;
- if (IsTrainDepotTile(tile)){
+ if (IsTileDepotType(tile, TRANSPORT_RAIL)){
tfdd.tile = tile;
tfdd.best_length = 0;
return tfdd;
@@ -1311,7 +1311,7 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v)
if (_patches.new_pathfinding_all) {
NPFFoundTargetData ftd;
byte trackdir = _track_direction_to_trackdir[FIND_FIRST_BIT(v->u.rail.track)][v->direction];
- ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_RAIL);
+ ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_RAIL, v->owner);
if (ftd.best_bird_dist == 0) {
/* Found target */
tfdd.tile = ftd.node.tile;
@@ -1442,7 +1442,7 @@ static void HandleLocomotiveSmokeCloud(Vehicle *v)
switch (RailVehInfo(engtype)->engclass) {
case 0:
// steam smoke.
- if ( (v->tick_counter&0xF) == 0 && !IsTrainDepotTile(v->tile) && !IsTunnelTile(v->tile)) {
+ if ( (v->tick_counter&0xF) == 0 && !IsTileDepotType(v->tile, TRANSPORT_RAIL) && !IsTunnelTile(v->tile)) {
CreateEffectVehicleRel(v,
(_vehicle_smoke_pos[v->direction]),
(_vehicle_smoke_pos[v->direction+8]),
@@ -1453,14 +1453,14 @@ static void HandleLocomotiveSmokeCloud(Vehicle *v)
case 1:
// diesel smoke
- if (u->cur_speed <= 40 && !IsTrainDepotTile(v->tile) && !IsTunnelTile(v->tile) && (uint16)Random() <= 0x1E00) {
+ if (u->cur_speed <= 40 && !IsTileDepotType(v->tile, TRANSPORT_RAIL) && !IsTunnelTile(v->tile) && (uint16)Random() <= 0x1E00) {
CreateEffectVehicleRel(v, 0,0,10, EV_SMOKE_3);
}
break;
case 2:
// blue spark
- if ( (v->tick_counter&0x3) == 0 && !IsTrainDepotTile(v->tile) && !IsTunnelTile(v->tile) && (uint16)Random() <= 0x5B0) {
+ if ( (v->tick_counter&0x3) == 0 && !IsTileDepotType(v->tile, TRANSPORT_RAIL) && !IsTunnelTile(v->tile) && (uint16)Random() <= 0x5B0) {
CreateEffectVehicleRel(v, 0,0,10, EV_SMOKE_2);
}
break;
@@ -1671,7 +1671,7 @@ static byte ChooseTrainTrack(Vehicle *v, uint tile, int enterdir, byte trackbits
trackdir = _track_exitdir_to_trackdir[FIND_FIRST_BIT(v->u.rail.track)][enterdir];
assert(trackdir != 0xff);
- ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL);
+ ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner);
if (ftd.best_bird_dist != 0 || ftd.best_trackdir == 0xff) {
/* Not found, or we are already there. Just do something */
//TODO: maybe display error?
@@ -1804,7 +1804,7 @@ static bool CheckReverseTrain(Vehicle *v)
assert(trackdir != 0xff);
assert(trackdir_rev != 0xff);
- ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL);
+ ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner);
if (ftd.best_bird_dist != 0) {
/* We didn't find anything, just keep on going straight ahead */
reverse_best = false;
@@ -2493,6 +2493,7 @@ static void TrainController(Vehicle *v)
if (!(r&0x4)) {
v->tile = gp.new_tile;
v->u.rail.track = chosen_track;
+ assert(v->u.rail.track);
}
if (v->subtype == TS_Front_Engine)
diff --git a/train_gui.c b/train_gui.c
index 91db42a52..f3809421a 100644
--- a/train_gui.c
+++ b/train_gui.c
@@ -1321,7 +1321,7 @@ static void PlayerTrainsWndProc(Window *w, WindowEvent *e)
DrawVehicleProfitButton(v, x, y + 13);
SetDParam(0, v->unitnumber);
- if (IsTrainDepotTile(v->tile) && (v->vehstatus & VS_HIDDEN))
+ if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && (v->vehstatus & VS_HIDDEN))
str = STR_021F;
else
str = v->age > v->max_age - 366 ? STR_00E3 : STR_00E2;
@@ -1382,7 +1382,7 @@ static void PlayerTrainsWndProc(Window *w, WindowEvent *e)
tile = _last_built_train_depot_tile;
do {
- if (_map_owner[tile] == _local_player && IsTrainDepotTile(tile)) {
+ if (_map_owner[tile] == _local_player && IsTileDepotType(tile, TRANSPORT_RAIL)) {
ShowTrainDepotWindow(tile);
ShowBuildTrainWindow(tile);
return;
diff --git a/ttd.h b/ttd.h
index 9e9127156..1928e5099 100644
--- a/ttd.h
+++ b/ttd.h
@@ -510,13 +510,6 @@ enum SpecialStrings {
typedef void PlaceProc(uint tile);
-enum MAP_OWNERS {
- OWNER_TOWN = 0xf, // a town owns the tile
- OWNER_NONE = 0x10, // nobody owns the tile
- OWNER_WATER = 0x11, // "water" owns the tile
- OWNER_SPECTATOR = 0xff, // spectator in MP or in scenario editor
-};
-
VARDEF bool _savegame_sort_dirty;
VARDEF byte _savegame_sort_order;
diff --git a/tunnelbridge_cmd.c b/tunnelbridge_cmd.c
index 04903d375..a42640deb 100644
--- a/tunnelbridge_cmd.c
+++ b/tunnelbridge_cmd.c
@@ -1435,6 +1435,7 @@ static uint32 VehicleEnter_TunnelBridge(Vehicle *v, uint tile, int x, int y)
/* We're at the tunnel exit ?? */
v->tile = tile;
v->u.rail.track = _exit_tunnel_track[dir];
+ assert(v->u.rail.track);
v->vehstatus &= ~VS_HIDDEN;
return 4;
}
diff --git a/vehicle.h b/vehicle.h
index 689118bca..15e985889 100644
--- a/vehicle.h
+++ b/vehicle.h
@@ -372,6 +372,14 @@ static inline uint16 GetVehiclePoolSize(void)
#define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
/**
+ * Check if a Vehicle really exists.
+ */
+static inline bool IsValidVehicle(Vehicle* v)
+{
+ return v->type != 0;
+}
+
+/**
* Check if an index is a vehicle-index (so between 0 and max-vehicles)
*
* @return Returns true if the vehicle-id is in range