mirror of https://github.com/OpenTTD/OpenTTD.git
(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:
parent
030c37160d
commit
18a93cca3d
2
ai_old.c
2
ai_old.c
|
@ -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) {
|
||||
|
|
32
engine.c
32
engine.c
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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] ),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
42
player.h
42
player.h
|
@ -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)
|
||||
|
||||
|
|
25
players.c
25
players.c
|
@ -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),
|
||||
|
|
|
@ -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] = {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue