mirror of https://github.com/OpenTTD/OpenTTD
(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 railtypesrelease/0.4.5
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)
|
static void AiWantTrainRoute(Player *p)
|
||||||
{
|
{
|
||||||
uint16 r;
|
uint16 r;
|
||||||
p->ai.railtype_to_use = p->max_railtype - 1;
|
p->ai.railtype_to_use = GetBestRailtype(p);
|
||||||
r = (uint16)Random();
|
r = (uint16)Random();
|
||||||
|
|
||||||
if (r > 0xD000) {
|
if (r > 0xD000) {
|
||||||
|
|
32
engine.c
32
engine.c
|
@ -12,8 +12,6 @@
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
#include "sprite.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 {
|
enum {
|
||||||
ENGINE_AVAILABLE = 1,
|
ENGINE_AVAILABLE = 1,
|
||||||
ENGINE_INTRODUCING = 2,
|
ENGINE_INTRODUCING = 2,
|
||||||
|
@ -755,9 +753,9 @@ void AcceptEnginePreview(Engine *e, PlayerID player)
|
||||||
{
|
{
|
||||||
Player *p = GetPlayer(player);
|
Player *p = GetPlayer(player);
|
||||||
|
|
||||||
|
assert(e->railtype < RAILTYPE_END);
|
||||||
SETBIT(e->player_avail, player);
|
SETBIT(e->player_avail, player);
|
||||||
|
SETBIT(p->avail_railtypes, e->railtype);
|
||||||
UPDATE_PLAYER_RAILTYPE(e, p);
|
|
||||||
|
|
||||||
e->preview_player = 0xFF;
|
e->preview_player = 0xFF;
|
||||||
InvalidateWindowClasses(WC_BUILD_VEHICLE);
|
InvalidateWindowClasses(WC_BUILD_VEHICLE);
|
||||||
|
@ -897,8 +895,10 @@ static void NewVehicleAvailable(Engine *e)
|
||||||
|
|
||||||
// make maglev / monorail available
|
// make maglev / monorail available
|
||||||
FOR_ALL_PLAYERS(p) {
|
FOR_ALL_PLAYERS(p) {
|
||||||
if (p->is_active)
|
if (p->is_active) {
|
||||||
UPDATE_PLAYER_RAILTYPE(e,p);
|
assert(e->railtype < RAILTYPE_END);
|
||||||
|
SETBIT(p->avail_railtypes, e->railtype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((byte)index < NUM_TRAIN_ENGINES) {
|
if ((byte)index < NUM_TRAIN_ENGINES) {
|
||||||
|
@ -967,26 +967,6 @@ int32 CmdRenameEngine(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return 0;
|
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[] = {
|
static const SaveLoad _engine_desc[] = {
|
||||||
SLE_VAR(Engine,intro_date, SLE_UINT16),
|
SLE_VAR(Engine,intro_date, SLE_UINT16),
|
||||||
|
|
|
@ -327,8 +327,7 @@ static void MenuClickShowAir(int index)
|
||||||
|
|
||||||
static void MenuClickBuildRail(int index)
|
static void MenuClickBuildRail(int index)
|
||||||
{
|
{
|
||||||
Player *p = GetPlayer(_local_player);
|
_last_built_railtype = index;
|
||||||
_last_built_railtype = min(index, p->max_railtype-1);
|
|
||||||
ShowBuildRailToolbar(_last_built_railtype, -1);
|
ShowBuildRailToolbar(_last_built_railtype, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,7 +940,7 @@ static void ToolbarBuildRailClick(Window *w)
|
||||||
{
|
{
|
||||||
Player *p = GetPlayer(_local_player);
|
Player *p = GetPlayer(_local_player);
|
||||||
Window *w2;
|
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;
|
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, block_preview ),
|
||||||
OCL_SVAR( OC_UINT8, Player, ai.tick ),
|
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_TILE, Player, location_of_house ),
|
||||||
OCL_SVAR( OC_UINT8, Player, share_owners[0] ),
|
OCL_SVAR( OC_UINT8, Player, share_owners[0] ),
|
||||||
OCL_SVAR( OC_UINT8, Player, share_owners[1] ),
|
OCL_SVAR( OC_UINT8, Player, share_owners[1] ),
|
||||||
|
|
|
@ -1279,6 +1279,7 @@ bool AfterLoadGame(uint version)
|
||||||
{
|
{
|
||||||
Window *w;
|
Window *w;
|
||||||
ViewPort *vp;
|
ViewPort *vp;
|
||||||
|
Player *p;
|
||||||
|
|
||||||
// in version 2.1 of the savegame, town owner was unified.
|
// in version 2.1 of the savegame, town owner was unified.
|
||||||
if (version <= 0x200) {
|
if (version <= 0x200) {
|
||||||
|
@ -1432,5 +1433,9 @@ bool AfterLoadGame(uint version)
|
||||||
} END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0);
|
} END_TILE_LOOP(tile, MapSizeX(), MapSizeY(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FOR_ALL_PLAYERS(p) {
|
||||||
|
p->avail_railtypes = GetPlayerRailtypes(p->index);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
42
player.h
42
player.h
|
@ -2,6 +2,8 @@
|
||||||
#define PLAYER_H
|
#define PLAYER_H
|
||||||
|
|
||||||
#include "aystar.h"
|
#include "aystar.h"
|
||||||
|
#include "engine.h"
|
||||||
|
#include "rail.h"
|
||||||
|
|
||||||
typedef struct PlayerEconomyEntry {
|
typedef struct PlayerEconomyEntry {
|
||||||
int32 income;
|
int32 income;
|
||||||
|
@ -157,7 +159,7 @@ typedef struct Player {
|
||||||
|
|
||||||
byte player_color;
|
byte player_color;
|
||||||
byte player_money_fraction;
|
byte player_money_fraction;
|
||||||
byte max_railtype;
|
byte avail_railtypes;
|
||||||
byte block_preview;
|
byte block_preview;
|
||||||
PlayerID index;
|
PlayerID index;
|
||||||
|
|
||||||
|
@ -203,6 +205,44 @@ static inline Player* GetPlayer(uint i)
|
||||||
return &_players[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_HUMAN_PLAYER(p) (!GetPlayer((byte)(p))->is_ai)
|
||||||
#define IS_INTERACTIVE_PLAYER(p) (((byte)p) == _local_player)
|
#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->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->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->inaugurated_year = _cur_year;
|
||||||
p->face = Random();
|
p->face = Random();
|
||||||
|
|
||||||
|
@ -622,6 +622,27 @@ void DeletePlayerWindows(int pi)
|
||||||
DeleteWindowById(WC_BUY_COMPANY, 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)
|
static void DeletePlayerStuff(int pi)
|
||||||
{
|
{
|
||||||
Player *p;
|
Player *p;
|
||||||
|
@ -969,7 +990,7 @@ static const SaveLoad _player_desc[] = {
|
||||||
|
|
||||||
SLE_VAR(Player,player_color, SLE_UINT8),
|
SLE_VAR(Player,player_color, SLE_UINT8),
|
||||||
SLE_VAR(Player,player_money_fraction,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,block_preview, SLE_UINT8),
|
||||||
|
|
||||||
SLE_VAR(Player,cargo_types, SLE_UINT16),
|
SLE_VAR(Player,cargo_types, SLE_UINT16),
|
||||||
|
|
|
@ -9,9 +9,18 @@
|
||||||
|
|
||||||
/** Writes the properties of a vehicle into the EngineInfo struct.
|
/** Writes the properties of a vehicle into the EngineInfo struct.
|
||||||
* @see EngineInfo
|
* @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)}
|
#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)}
|
#define MW(a,b,c,d,e,f) {a,b|0x80,c,d,((e)<<4)|(f)}
|
||||||
|
|
||||||
EngineInfo _engine_info[TOTAL_NUM_ENGINES] = {
|
EngineInfo _engine_info[TOTAL_NUM_ENGINES] = {
|
||||||
|
|
|
@ -323,7 +323,7 @@ static void ShowBuildTrainWindow(TileIndex tile)
|
||||||
WP(w,buildtrain_d).railtype = _m[tile].m3 & 0xF;
|
WP(w,buildtrain_d).railtype = _m[tile].m3 & 0xF;
|
||||||
} else {
|
} else {
|
||||||
w->caption_color = _local_player;
|
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 */
|
/* 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.
|
// NOSAVE: Can be regenerated by inspecting the vehicles.
|
||||||
VARDEF VehicleID _vehicle_position_hash[0x1000];
|
VARDEF VehicleID _vehicle_position_hash[0x1000];
|
||||||
|
|
Loading…
Reference in New Issue