changeset 7857:707c26c48f4e draft

(svn r11407) -Fix: do not allow building of tram-tracks when they are not available (SmatZ)
author truelight <truelight@openttd.org>
date Sun, 11 Nov 2007 12:34:44 +0000
parents cdcab4e1c890
children 89dfb98b8baa
files src/main_gui.cpp src/player.h src/road_cmd.cpp src/station_cmd.cpp src/tunnelbridge_cmd.cpp
diffstat 5 files changed, 41 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -19,6 +19,7 @@
 #include "viewport.h"
 #include "gfx.h"
 #include "player.h"
+#include "road.h"
 #include "command.h"
 #include "news.h"
 #include "town.h"
@@ -930,7 +931,7 @@
 {
 	const Player *p = GetPlayer(_local_player);
 	/* The standard road button is *always* available */
-	Window *w2 = PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 2, ~(p->avail_roadtypes | 1));
+	Window *w2 = PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 2, ~(p->avail_roadtypes | ROADTYPES_ROAD));
 	WP(w2, menu_d).sel_index = _last_built_roadtype;
 }
 
--- a/src/player.h
+++ b/src/player.h
@@ -8,8 +8,11 @@
 #include "oldpool.h"
 #include "aystar.h"
 #include "rail.h"
+#include "road.h"
 #include "engine.h"
 #include "livery.h"
+#include "genworld.h"
+#include "gfx.h"
 
 struct PlayerEconomyEntry {
 	Money income;
@@ -253,12 +256,34 @@
 byte GetPlayerRailtypes(PlayerID p);
 byte GetPlayerRoadtypes(PlayerID p);
 
-/** Finds out if a Player has a certain railtype available */
-static inline bool HasRailtypeAvail(const Player *p, RailType Railtype)
+/** Finds out if a Player has a certain railtype available
+ * @param p Player in question
+ * @param Railtype requested RailType
+ * @return true if player has requested RailType available
+ */
+static inline bool HasRailtypeAvail(const Player *p, const RailType Railtype)
 {
 	return HASBIT(p->avail_railtypes, Railtype);
 }
 
+/** Finds out, whether given player has all given RoadTypes available
+ * @param PlayerID ID of player
+ * @param rts RoadTypes to test
+ * @return true if player has all requested RoadTypes available
+ */
+static inline bool HasRoadTypesAvail(const PlayerID p, const RoadTypes rts)
+{
+	RoadTypes avail_roadtypes;
+
+	if (p == OWNER_TOWN || _game_mode == GM_EDITOR || IsGeneratingWorld()) {
+		avail_roadtypes = ROADTYPES_ROAD;
+	} else {
+		if (!IsValidPlayer(p)) return false;
+		avail_roadtypes = (RoadTypes)GetPlayer(p)->avail_roadtypes | ROADTYPES_ROAD; // road is available for always for everybody
+	}
+	return (rts & ~avail_roadtypes) == 0;
+}
+
 static inline bool IsHumanPlayer(PlayerID pi)
 {
 	return !GetPlayer(pi)->is_ai;
@@ -272,7 +297,10 @@
 void DrawPlayerIcon(PlayerID p, int x, int y);
 
 /* Validate functions for rail building */
-static inline bool ValParamRailtype(uint32 rail) { return HASBIT(GetPlayer(_current_player)->avail_railtypes, rail);}
+static inline bool ValParamRailtype(const uint32 rail) { return HASBIT(GetPlayer(_current_player)->avail_railtypes, rail);}
+
+/* Validate functions for road building */
+static inline bool ValParamRoadType(const RoadType rt) { return HasRoadTypesAvail(_current_player, RoadTypeToRoadTypes(rt));}
 
 /** Returns the "best" railtype a player can build.
  * As the AI doesn't know what the BEST one is, we have our own priority list
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -405,7 +405,7 @@
 	RoadBits pieces = Extract<RoadBits, 0>(p1);
 
 	RoadType rt = (RoadType)GB(p1, 4, 2);
-	if (!IsValidRoadType(rt)) return CMD_ERROR;
+	if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
 
 	DisallowedRoadDirections toggle_drd = (DisallowedRoadDirections)GB(p1, 6, 2);
 
@@ -636,7 +636,7 @@
 
 	start_tile = p1;
 	RoadType rt = (RoadType)GB(p2, 3, 2);
-	if (!IsValidRoadType(rt)) return CMD_ERROR;
+	if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
 
 	/* Only drag in X or Y direction dictated by the direction variable */
 	if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
@@ -786,7 +786,7 @@
 	DiagDirection dir = Extract<DiagDirection, 0>(p1);
 	RoadType rt = (RoadType)GB(p1, 2, 2);
 
-	if (!IsValidRoadType(rt)) return CMD_ERROR;
+	if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
 
 	tileh = GetTileSlope(tile, NULL);
 	if (tileh != SLOPE_FLAT && (
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -1318,7 +1318,7 @@
 	bool town_owned_road  = build_over_road && IsTileOwner(tile, OWNER_TOWN);
 	RoadTypes rts = (RoadTypes)GB(p2, 2, 3);
 
-	if (rts == ROADTYPES_NONE || HASBIT(rts, ROADTYPE_HWAY)) return CMD_ERROR;
+	if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_player, rts)) return CMD_ERROR;
 
 	/* Trams only have drive through stops */
 	if (!is_drive_through && HASBIT(rts, ROADTYPE_TRAM)) return CMD_ERROR;
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -213,7 +213,7 @@
 	if (HASBIT(p2, 15)) {
 		railtype = INVALID_RAILTYPE; // road bridge
 		roadtypes = (RoadTypes)GB(p2, 8, 3);
-		if (!AreValidRoadTypes(roadtypes)) return CMD_ERROR;
+		if (!AreValidRoadTypes(roadtypes) || !HasRoadTypesAvail(_current_player, roadtypes)) return CMD_ERROR;
 	} else {
 		if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR;
 		railtype = (RailType)GB(p2, 8, 8);
@@ -464,8 +464,9 @@
 	_build_tunnel_endtile = 0;
 	if (!HASBIT(p1, 9)) {
 		if (!ValParamRailtype(p1)) return CMD_ERROR;
-	} else if (!AreValidRoadTypes((RoadTypes)GB(p1, 0, 3))) {
-		return CMD_ERROR;
+	} else {
+		const RoadTypes rts = (RoadTypes)GB(p1, 0, 3);
+		if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_player, rts)) return CMD_ERROR;
 	}
 
 	start_tileh = GetTileSlope(start_tile, &start_z);