(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
This commit is contained in:
celestar 2005-07-20 22:02:58 +00:00
parent 030c37160d
commit 18a93cca3d
10 changed files with 91 additions and 37 deletions

View File

@ -1075,7 +1075,7 @@ static void AiWantPassengerRoute(Player *p)
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) {

View File

@ -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 @@ void AcceptEnginePreview(Engine *e, PlayerID player)
{
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 @@ static void NewVehicleAvailable(Engine *e)
// 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 @@ int32 CmdRenameEngine(int x, int y, uint32 flags, uint32 p1, uint32 p2)
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),

View File

@ -327,8 +327,7 @@ static void MenuClickShowAir(int index)
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 @@ static void ToolbarBuildRailClick(Window *w)
{
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;
}

View File

@ -1020,7 +1020,7 @@ static const OldChunks player_chunk[] = {
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] ),

View File

@ -1279,6 +1279,7 @@ bool AfterLoadGame(uint version)
{
Window *w;
ViewPort *vp;
Player *p;
// in version 2.1 of the savegame, town owner was unified.
if (version <= 0x200) {
@ -1432,5 +1433,9 @@ bool AfterLoadGame(uint version)
} END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0);
}
FOR_ALL_PLAYERS(p) {
p->avail_railtypes = GetPlayerRailtypes(p->index);
}
return true;
}

View File

@ -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 @@ typedef struct Player {
byte player_color;
byte player_money_fraction;
byte max_railtype;
byte avail_railtypes;
byte block_preview;
PlayerID index;
@ -203,6 +205,44 @@ static inline Player* GetPlayer(uint i)
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)

View File

@ -487,7 +487,7 @@ Player *DoStartupNewPlayer(bool is_ai)
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 @@ void DeletePlayerWindows(int pi)
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 @@ static const SaveLoad _player_desc[] = {
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),

View File

@ -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] = {

View File

@ -323,7 +323,7 @@ static void ShowBuildTrainWindow(TileIndex tile)
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));
}
}

View File

@ -435,7 +435,7 @@ static inline Vehicle *GetFirstVehicleFromSharedList(Vehicle *v)
}
/* 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];