(svn r2657) -Codechange: The available railtypes per player are now a bitmask, so
authorcelestar
Wed, 20 Jul 2005 22:02:58 +0000
changeset 2147 eb6ba42fd216
parent 2146 336f4e117777
child 2148 542ea702738c
(svn r2657) -Codechange: The available railtypes per player are now a bitmask, so
that railtypes do not be in ascending order of appearance. Allows easier
implementation or more railtypes
ai_old.c
engine.c
main_gui.c
oldloader.c
openttd.c
player.h
players.c
table/engines.h
train_gui.c
vehicle.h
--- a/ai_old.c	Wed Jul 20 19:15:23 2005 +0000
+++ b/ai_old.c	Wed Jul 20 22:02:58 2005 +0000
@@ -1075,7 +1075,7 @@
 static void AiWantTrainRoute(Player *p)
 {
 	uint16 r;
-	p->ai.railtype_to_use = p->max_railtype - 1;
+	p->ai.railtype_to_use = GetBestRailtype(p);
 	r = (uint16)Random();
 
 	if (r > 0xD000) {
--- a/engine.c	Wed Jul 20 19:15:23 2005 +0000
+++ b/engine.c	Wed Jul 20 22:02:58 2005 +0000
@@ -12,8 +12,6 @@
 #include "saveload.h"
 #include "sprite.h"
 
-#define UPDATE_PLAYER_RAILTYPE(e,p) if ((byte)(e->railtype + 1) > p->max_railtype) p->max_railtype = e->railtype + 1;
-
 enum {
 	ENGINE_AVAILABLE = 1,
 	ENGINE_INTRODUCING = 2,
@@ -755,9 +753,9 @@
 {
 	Player *p = GetPlayer(player);
 
+	assert(e->railtype < RAILTYPE_END);
 	SETBIT(e->player_avail, player);
-
-	UPDATE_PLAYER_RAILTYPE(e, p);
+	SETBIT(p->avail_railtypes, e->railtype);
 
 	e->preview_player = 0xFF;
 	InvalidateWindowClasses(WC_BUILD_VEHICLE);
@@ -897,8 +895,10 @@
 
 	// make maglev / monorail available
 	FOR_ALL_PLAYERS(p) {
-		if (p->is_active)
-			UPDATE_PLAYER_RAILTYPE(e,p);
+		if (p->is_active) {
+			assert(e->railtype < RAILTYPE_END);
+			SETBIT(p->avail_railtypes, e->railtype);
+		}
 	}
 
 	if ((byte)index < NUM_TRAIN_ENGINES) {
@@ -967,26 +967,6 @@
 	return 0;
 }
 
-int GetPlayerMaxRailtype(int p)
-{
-	Engine *e;
-	int rt = 0;
-	int i;
-
-	for(e=_engines,i=0; i!=lengthof(_engines); e++,i++) {
-		if (!HASBIT(e->player_avail, p))
-			continue;
-
-		if ((i >= 27 && i < 54) || (i >= 57 && i < 84) || (i >= 89 && i < 116))
-			continue;
-
-		if (rt < e->railtype)
-			rt = e->railtype;
-	}
-
-	return rt + 1;
-}
-
 
 static const SaveLoad _engine_desc[] = {
 	SLE_VAR(Engine,intro_date,						SLE_UINT16),
--- a/main_gui.c	Wed Jul 20 19:15:23 2005 +0000
+++ b/main_gui.c	Wed Jul 20 22:02:58 2005 +0000
@@ -327,8 +327,7 @@
 
 static void MenuClickBuildRail(int index)
 {
-	Player *p = GetPlayer(_local_player);
-	_last_built_railtype = min(index, p->max_railtype-1);
+	_last_built_railtype = index;
 	ShowBuildRailToolbar(_last_built_railtype, -1);
 }
 
@@ -941,7 +940,7 @@
 {
 	Player *p = GetPlayer(_local_player);
 	Window *w2;
-	w2 = PopupMainToolbMenu(w, 457, 19, STR_1015_RAILROAD_CONSTRUCTION, p->max_railtype);
+	w2 = PopupMainToolbMenu(w, 457, 19, STR_1015_RAILROAD_CONSTRUCTION, GetNumRailtypes(p));
 	WP(w2,menu_d).sel_index = _last_built_railtype;
 }
 
--- a/oldloader.c	Wed Jul 20 19:15:23 2005 +0000
+++ b/oldloader.c	Wed Jul 20 22:02:58 2005 +0000
@@ -1020,7 +1020,7 @@
 
 	OCL_SVAR(  OC_UINT8, Player, block_preview ),
 	OCL_SVAR(  OC_UINT8, Player, ai.tick ),
-	OCL_SVAR(  OC_UINT8, Player, max_railtype ),
+	OCL_SVAR(  OC_UINT8, Player, avail_railtypes ),
 	OCL_SVAR(   OC_TILE, Player, location_of_house ),
 	OCL_SVAR(  OC_UINT8, Player, share_owners[0] ),
 	OCL_SVAR(  OC_UINT8, Player, share_owners[1] ),
--- a/openttd.c	Wed Jul 20 19:15:23 2005 +0000
+++ b/openttd.c	Wed Jul 20 22:02:58 2005 +0000
@@ -1279,6 +1279,7 @@
 {
 	Window *w;
 	ViewPort *vp;
+	Player *p;
 
 	// in version 2.1 of the savegame, town owner was unified.
 	if (version <= 0x200) {
@@ -1432,5 +1433,9 @@
 		} END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0);
 	}
 
+	FOR_ALL_PLAYERS(p) {
+		p->avail_railtypes = GetPlayerRailtypes(p->index);
+	}
+
 	return true;
 }
--- a/player.h	Wed Jul 20 19:15:23 2005 +0000
+++ b/player.h	Wed Jul 20 22:02:58 2005 +0000
@@ -2,6 +2,8 @@
 #define PLAYER_H
 
 #include "aystar.h"
+#include "engine.h"
+#include "rail.h"
 
 typedef struct PlayerEconomyEntry {
 	int32 income;
@@ -157,7 +159,7 @@
 
 	byte player_color;
 	byte player_money_fraction;
-	byte max_railtype;
+	byte avail_railtypes;
 	byte block_preview;
 	PlayerID index;
 
@@ -203,6 +205,44 @@
   return &_players[i];
 }
 
+/** Returns the number of rail types the player can build
+  * @param *p Player in question
+  */
+static inline int GetNumRailtypes(Player *p)
+{
+	int num = 0;
+	int i;
+
+	for (i = 0; i < (int)sizeof(p->avail_railtypes) * 8; i++)
+		if (HASBIT(p->avail_railtypes, i)) num++;
+
+	assert(num <= RAILTYPE_END);
+	return num;
+}
+
+byte GetPlayerRailtypes(int p);
+
+/** Finds out if a Player has a certain railtype available
+  */
+static inline bool HasRailtypeAvail(Player *p, RailType Railtype)
+{
+	return HASBIT(p->avail_railtypes, Railtype);
+}
+
+/** 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 here. When adding
+  * new railtypes, modify this function
+  * @param p the player "in action"
+  * @return The "best" railtype a player has available
+  */
+static inline byte GetBestRailtype(Player *p)
+{
+	if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV;
+	if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO;
+	return RAILTYPE_RAIL;
+}
+
 #define IS_HUMAN_PLAYER(p) (!GetPlayer((byte)(p))->is_ai)
 #define IS_INTERACTIVE_PLAYER(p) (((byte)p) == _local_player)
 
--- a/players.c	Wed Jul 20 19:15:23 2005 +0000
+++ b/players.c	Wed Jul 20 22:02:58 2005 +0000
@@ -487,7 +487,7 @@
 	p->ai.state = 5; /* AIS_WANT_NEW_ROUTE */
 	p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = 0xFF;
 
-	p->max_railtype = GetPlayerMaxRailtype(index);
+	p->avail_railtypes = GetPlayerRailtypes(index);
 	p->inaugurated_year = _cur_year;
 	p->face = Random();
 
@@ -622,6 +622,27 @@
 	DeleteWindowById(WC_BUY_COMPANY, pi);
 }
 
+byte GetPlayerRailtypes(int p)
+{
+	Engine *e;
+	int rt = 0;
+	int i;
+
+	for(e = _engines, i = 0; i != lengthof(_engines); e++, i++) {
+		if (!HASBIT(e->player_avail, p))
+			continue;
+
+		/* Skip all wagons */
+		if ((i >= 27 && i < 54) || (i >= 57 && i < 84) || (i >= 89 && i < 116))
+			continue;
+
+		assert(e->railtype < RAILTYPE_END);
+		SETBIT(rt, e->railtype);
+	}
+
+	return rt;
+}
+
 static void DeletePlayerStuff(int pi)
 {
 	Player *p;
@@ -969,7 +990,7 @@
 
 	SLE_VAR(Player,player_color,		SLE_UINT8),
 	SLE_VAR(Player,player_money_fraction,SLE_UINT8),
-	SLE_VAR(Player,max_railtype,		SLE_UINT8),
+	SLE_VAR(Player,avail_railtypes,		SLE_UINT8),
 	SLE_VAR(Player,block_preview,		SLE_UINT8),
 
 	SLE_VAR(Player,cargo_types,			SLE_UINT16),
--- a/table/engines.h	Wed Jul 20 19:15:23 2005 +0000
+++ b/table/engines.h	Wed Jul 20 22:02:58 2005 +0000
@@ -9,9 +9,18 @@
 
 /** Writes the properties of a vehicle into the EngineInfo struct.
   * @see EngineInfo
+  * @param a Introduction date
+  * @param e Rail Type of the vehicle
+  * @param f Bitmask of the climates
   */
-
 #define MK(a,b,c,d,e,f) {a,b,c,d,((e)<<4)|(f)}
+/** Writes the properties of a train carriage into the EngineInfo struct.
+  * @see EngineInfo
+  * @param a Introduction date
+  * @param e Rail Type of the vehicle
+  * @param f Bitmask of the climates
+  * @note the 0x80 in parameter b sets the "is carriage bit"
+  */
 #define MW(a,b,c,d,e,f) {a,b|0x80,c,d,((e)<<4)|(f)}
 
 EngineInfo _engine_info[TOTAL_NUM_ENGINES] = {
--- a/train_gui.c	Wed Jul 20 19:15:23 2005 +0000
+++ b/train_gui.c	Wed Jul 20 22:02:58 2005 +0000
@@ -323,7 +323,7 @@
 		WP(w,buildtrain_d).railtype = _m[tile].m3 & 0xF;
 	} else {
 		w->caption_color = _local_player;
-		WP(w,buildtrain_d).railtype = GetPlayer(_local_player)->max_railtype - 1;
+		WP(w,buildtrain_d).railtype = GetBestRailtype(GetPlayer(_local_player));
 	}
 }
 
--- a/vehicle.h	Wed Jul 20 19:15:23 2005 +0000
+++ b/vehicle.h	Wed Jul 20 22:02:58 2005 +0000
@@ -435,7 +435,7 @@
 }
 
 /* Validate functions for rail building */
-static inline bool ValParamRailtype(uint32 rail) { return rail <= GetPlayer(_current_player)->max_railtype;}
+static inline bool ValParamRailtype(uint32 rail) { return HASBIT(GetPlayer(_current_player)->avail_railtypes, rail);}
 
 // NOSAVE: Can be regenerated by inspecting the vehicles.
 VARDEF VehicleID _vehicle_position_hash[0x1000];