@ -43,14 +43,79 @@ static void MarkStationDirty(Station *st)
}
}
}
}
static void InitializeRoadStop ( RoadStop * road_stop , RoadStop * previous , TileIndex tile , uint index )
{
road_stop - > xy = tile ;
road_stop - > used = true ;
road_stop - > status = 3 ; //stop is free
road_stop - > slot [ 0 ] = road_stop - > slot [ 1 ] = INVALID_SLOT ;
road_stop - > next = NULL ;
road_stop - > prev = previous ;
road_stop - > station = index ;
}
inline int GetRoadStopType ( TileIndex tile )
{
return ( _map5 [ tile ] < 0x47 ) ? RS_TRUCK : RS_BUS ;
}
RoadStop * GetPrimaryRoadStop ( const Station * st , RoadStopType type )
{
switch ( type ) {
case RS_BUS : return st - > bus_stops ;
case RS_TRUCK : return st - > truck_stops ;
default :
NOT_REACHED ( ) ;
}
return NULL ;
}
RoadStop * GetRoadStopByTile ( TileIndex tile , RoadStopType type )
{
const Station * st = GetStation ( _map2 [ tile ] ) ;
RoadStop * rs ;
for ( rs = GetPrimaryRoadStop ( st , type ) ; rs - > xy ! = tile ; rs = rs - > next )
assert ( rs - > next ! = NULL ) ;
return rs ;
}
uint GetNumRoadStops ( const Station * st , RoadStopType type )
{
int num = 0 ;
const RoadStop * rs ;
assert ( st ! = NULL ) ;
for ( rs = GetPrimaryRoadStop ( st , type ) ; rs ! = NULL ; num + + , rs = rs - > next ) ;
return num ;
}
RoadStop * GetFirstFreeRoadStop ( void )
{
RoadStop * rs = _roadstops ;
int i = 0 ;
for ( i = 0 ; i < NUM_ROAD_STOPS ; i + + , rs + + ) {
if ( ! rs - > used ) {
rs - > index = i ;
return rs ;
}
}
return NULL ;
}
/* Calculate the radius of the station. Basicly it is the biggest
/* Calculate the radius of the station. Basicly it is the biggest
radius that is available within the station */
radius that is available within the station */
static byte FindCatchmentRadius ( Station * st )
static byte FindCatchmentRadius ( Station * st )
{
{
byte ret = 0 ;
byte ret = 0 ;
if ( st - > bus_tile ) ret = max ( ret , CA_BUS ) ;
if ( st - > bus_ stops ! = NULL ) ret = max ( ret , CA_BUS ) ;
if ( st - > lorry_tile ) ret = max ( ret , CA_TRUCK ) ;
if ( st - > truck_stops ! = NULL ) ret = max ( ret , CA_TRUCK ) ;
if ( st - > train_tile ) ret = max ( ret , CA_TRAIN ) ;
if ( st - > train_tile ) ret = max ( ret , CA_TRAIN ) ;
if ( st - > dock_tile ) ret = max ( ret , CA_DOCK ) ;
if ( st - > dock_tile ) ret = max ( ret , CA_DOCK ) ;
@ -101,7 +166,7 @@ TileIndex GetStationTileForVehicle(const Vehicle *v, const Station *st)
case VEH_Train : return st - > train_tile ;
case VEH_Train : return st - > train_tile ;
case VEH_Aircraft : return st - > airport_tile ;
case VEH_Aircraft : return st - > airport_tile ;
case VEH_Ship : return st - > dock_tile ;
case VEH_Ship : return st - > dock_tile ;
case VEH_Road : return ( v - > cargo_type = = CT_PASSENGERS ) ? st - > bus_tile : st - > lorry_tile ;
case VEH_Road : return ( v - > cargo_type = = CT_PASSENGERS ) ? st - > bus_stops - > xy : st - > truck_stops - > xy ;
default :
default :
assert ( false ) ;
assert ( false ) ;
return 0 ;
return 0 ;
@ -326,7 +391,8 @@ static void StationInitialize(Station *st, TileIndex tile)
GoodsEntry * ge ;
GoodsEntry * ge ;
st - > xy = tile ;
st - > xy = tile ;
st - > bus_tile = st - > lorry_tile = st - > airport_tile = st - > dock_tile = st - > train_tile = 0 ;
st - > airport_tile = st - > dock_tile = st - > train_tile = 0 ;
st - > bus_stops = st - > truck_stops = NULL ;
st - > had_vehicle_of_type = 0 ;
st - > had_vehicle_of_type = 0 ;
st - > time_since_load = 255 ;
st - > time_since_load = 255 ;
st - > time_since_unload = 255 ;
st - > time_since_unload = 255 ;
@ -352,8 +418,9 @@ static void StationInitialize(Station *st, TileIndex tile)
static void UpdateStationVirtCoord ( Station * st )
static void UpdateStationVirtCoord ( Station * st )
{
{
Point pt = RemapCoords2 ( TileX ( st - > xy ) * 16 , TileY ( st - > xy ) * 16 ) ;
Point pt = RemapCoords2 ( TileX ( st - > xy ) * 16 , TileY ( st - > xy ) * 16 ) ;
pt . y - = 32 ;
pt . y - = 32 ;
if ( st - > facilities & FACIL_AIRPORT & & st - > airport_type = = AT_OILRIG ) pt . y - = 16 ;
if ( st - > facilities & FACIL_AIRPORT & & st - > airport_type = = AT_OILRIG ) pt . y - = 16 ;
SetDParam ( 0 , st - > index ) ;
SetDParam ( 0 , st - > index ) ;
SetDParam ( 1 , st - > facilities ) ;
SetDParam ( 1 , st - > facilities ) ;
@ -498,10 +565,13 @@ void GetAcceptanceAroundTiles(uint *accepts, uint tile, int w, int h, int rad)
static void UpdateStationAcceptance ( Station * st , bool show_msg )
static void UpdateStationAcceptance ( Station * st , bool show_msg )
{
{
uint old_acc , new_acc ;
uint old_acc , new_acc ;
TileIndex span [ 1 + 1 + 2 + 2 + 1 ] ;
TileIndex * span ;
RoadStop * cur_rs ;
int i ;
int i ;
int min_x , min_y , max_x , max_y ;
int min_x , min_y , max_x , max_y ;
int rad = 4 ; //Put this to surpress a compiler warning
int rad = 4 ; //Put this to surpress a compiler warning
int num = 0 ;
int num_bus , num_truck ;
uint accepts [ NUM_CARGO ] ;
uint accepts [ NUM_CARGO ] ;
// Don't update acceptance for a buoy
// Don't update acceptance for a buoy
@ -511,33 +581,62 @@ static void UpdateStationAcceptance(Station *st, bool show_msg)
/* old accepted goods types */
/* old accepted goods types */
old_acc = GetAcceptanceMask ( st ) ;
old_acc = GetAcceptanceMask ( st ) ;
if ( st - > train_tile ! = 0 ) num + = 2 ;
if ( st - > airport_tile ! = 0 ) num + = 2 ;
if ( st - > dock_tile ! = 0 ) num + + ;
num_bus = GetNumRoadStops ( st , RS_BUS ) ;
num_truck = GetNumRoadStops ( st , RS_TRUCK ) ;
num + = ( num_bus + num_truck ) ;
span = malloc ( num * sizeof ( * span ) ) ;
if ( span = = NULL )
error ( " UpdateStationAcceptance: Could not allocate memory " ) ;
// Put all the tiles that span an area in the table.
// Put all the tiles that span an area in the table.
span [ 3 ] = span [ 5 ] = 0 ;
span [ 0 ] = st - > bus_tile ;
span [ 1 ] = st - > lorry_tile ;
span [ 2 ] = st - > train_tile ;
if ( st - > train_tile ! = 0 ) {
if ( st - > train_tile ! = 0 ) {
span [ 3 ] = st - > train_tile + TILE_XY ( st - > trainst_w - 1 , st - > trainst_h - 1 ) ;
* span + + = st - > train_tile ;
* span + + = st - > train_tile + TILE_XY ( st - > trainst_w - 1 , st - > trainst_h - 1 ) ;
}
}
span [ 4 ] = st - > airport_tile ;
if ( st - > airport_tile ! = 0 ) {
if ( st - > airport_tile ! = 0 ) {
span [ 5 ] = st - > airport_tile + TILE_XY ( _airport_size_x [ st - > airport_type ] - 1 , _airport_size_y [ st - > airport_type ] - 1 ) ;
* span + + = st - > airport_tile ;
* span + + = st - > airport_tile + TILE_XY ( _airport_size_x [ st - > airport_type ] - 1 , _airport_size_y [ st - > airport_type ] - 1 ) ;
}
if ( st - > dock_tile ! = 0 )
* span + + = st - > dock_tile ;
cur_rs = st - > bus_stops ;
for ( i = 0 ; i < num_bus ; i + + ) {
* span + + = cur_rs - > xy ;
cur_rs = cur_rs - > next ;
}
cur_rs = st - > truck_stops ;
for ( i = 0 ; i < num_truck ; i + + ) {
* span + + = cur_rs - > xy ;
cur_rs = cur_rs - > next ;
}
}
span [ 6 ] = st - > dock_tile ;
// Construct a rectangle from those points
// Construct a rectangle from those points
min_x = min_y = 0x7FFFFFFF ;
min_x = min_y = 0x7FFFFFFF ;
max_x = max_y = 0 ;
max_x = max_y = 0 ;
for ( i = 0 ; i ! = 7 ; i + + ) {
for ( ; num ! = 0 ; num - - ) {
uint tile = span [ i ] ;
TileIndex tile = * ( - - span ) ;
if ( tile ) {
if ( tile ! = 0 ) { //assume there is no station at (0, 0)
min_x = min ( min_x , TileX ( tile ) ) ;
min_x = min ( min_x , TileX ( tile ) ) ;
max_x = max ( max_x , TileX ( tile ) ) ;
max_x = max ( max_x , TileX ( tile ) ) ;
min_y = min ( min_y , TileY ( tile ) ) ;
min_y = min ( min_y , TileY ( tile ) ) ;
max_y = max ( max_y , TileY ( tile ) ) ;
max_y = max ( max_y , TileY ( tile ) ) ;
}
}
}
}
free ( span ) ;
span = NULL ;
if ( _patches . modified_catchment ) {
if ( _patches . modified_catchment ) {
rad = FindCatchmentRadius ( st ) ;
rad = FindCatchmentRadius ( st ) ;
} else {
} else {
@ -546,7 +645,7 @@ static void UpdateStationAcceptance(Station *st, bool show_msg)
// And retrieve the acceptance.
// And retrieve the acceptance.
if ( max_x ! = 0 ) {
if ( max_x ! = 0 ) {
GetAcceptanceAroundTiles ( accepts , TILE_XY ( min_x , min_y ) , max_x - min_x + 1 , max_y - min_y + 1 , rad ) ;
GetAcceptanceAroundTiles ( accepts , TILE_XY ( min_x , min_y ) , max_x - min_x + 1 , max_y - min_y + 1 , rad ) ;
} else {
} else {
memset ( accepts , 0 , sizeof ( accepts ) ) ;
memset ( accepts , 0 , sizeof ( accepts ) ) ;
}
}
@ -1127,10 +1226,10 @@ ResolveStationSpriteGroup(struct SpriteGroup *spritegroup, struct Station *stat)
value = stat - > airport_type ;
value = stat - > airport_type ;
break ;
break ;
case 0x82 :
case 0x82 :
value = stat - > truck_stop _ status;
value = stat - > truck_stop s- > status;
break ;
break ;
case 0x83 :
case 0x83 :
value = stat - > bus_stop _ status;
value = stat - > bus_stop s- > status;
break ;
break ;
case 0x86 :
case 0x86 :
value = stat - > airport_flags & 0xFFFF ;
value = stat - > airport_flags & 0xFFFF ;
@ -1260,16 +1359,47 @@ int32 DoConvertStationRail(uint tile, uint totype, bool exec)
return _price . build_rail > > 1 ;
return _price . build_rail > > 1 ;
}
}
void FindRoadStationSpot ( bool truck_station , Station * st , RoadStop * * * currstop , RoadStop * * prev )
{
RoadStop * * primary_stop ;
primary_stop = ( truck_station ) ? & st - > truck_stops : & st - > bus_stops ;
if ( * primary_stop = = NULL ) {
//we have no station of the type yet, so write a "primary station"
//(the one at st->foo_stops)
* currstop = primary_stop ;
} else {
//there are stops already, so append to the end of the list
* prev = * primary_stop ;
* currstop = & ( * primary_stop ) - > next ;
while ( * * currstop ! = NULL ) {
* prev = ( * prev ) - > next ;
* currstop = & ( * * currstop ) - > next ;
}
}
}
/* Build a bus station
/* Build a bus station
* p1 - direction
* direction - direction of the stop exit
* p2 - unused
* type - 0 for Bus stops , 1 for truck stops
*/
*/
int32 CmdBuildBusStation ( int x , int y , uint32 flags , uint32 p1 , uint32 p2 )
int32 CmdBuild RoadStop ( int x , int y , uint32 flags , uint32 direction, uint32 type )
{
{
RoadStop * road_stop ;
RoadStop * * currstop ;
RoadStop * prev = NULL ;
uint tile ;
uint tile ;
int32 cost ;
int32 cost ;
Station * st ;
Station * st ;
//Bus stops have a _map5 value of 0x47 + direction
//Truck stops have 0x43 + direction
byte gfxbase = ( type ) ? 0x43 : 0x47 ;
//saveguard the parameters
if ( direction > 3 | | type > 1 )
return CMD_ERROR ;
SET_EXPENSES_TYPE ( EXPENSES_CONSTRUCTION ) ;
SET_EXPENSES_TYPE ( EXPENSES_CONSTRUCTION ) ;
@ -1278,7 +1408,8 @@ int32 CmdBuildBusStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if ( ! ( flags & DC_NO_TOWN_RATING ) & & ! CheckIfAuthorityAllows ( tile ) )
if ( ! ( flags & DC_NO_TOWN_RATING ) & & ! CheckIfAuthorityAllows ( tile ) )
return CMD_ERROR ;
return CMD_ERROR ;
if ( ( cost = CheckFlatLandBelow ( tile , 1 , 1 , flags , 1 < < p1 , NULL ) ) = = CMD_ERROR )
cost = CheckFlatLandBelow ( tile , 1 , 1 , flags , 1 < < direction , NULL ) ;
if ( cost = = CMD_ERROR )
return CMD_ERROR ;
return CMD_ERROR ;
st = GetStationAround ( tile , 1 , 1 , - 1 ) ;
st = GetStationAround ( tile , 1 , 1 , - 1 ) ;
@ -1291,6 +1422,14 @@ int32 CmdBuildBusStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if ( st ! = NULL & & st - > facilities ) st = NULL ;
if ( st ! = NULL & & st - > facilities ) st = NULL ;
}
}
//give us a road stop in the list, and check if something went wrong
road_stop = GetFirstFreeRoadStop ( ) ;
if ( road_stop = = NULL )
return_cmd_error ( ( type ) ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS ) ;
if ( st ! = NULL & & ( GetNumRoadStops ( st , RS_BUS ) + GetNumRoadStops ( st , RS_TRUCK ) > = ROAD_STOP_LIMIT ) )
return_cmd_error ( ( type ) ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS ) ;
if ( st ! = NULL ) {
if ( st ! = NULL ) {
if ( st - > owner ! = OWNER_NONE & & st - > owner ! = _current_player )
if ( st - > owner ! = OWNER_NONE & & st - > owner ! = _current_player )
return_cmd_error ( STR_3009_TOO_CLOSE_TO_ANOTHER_STATION ) ;
return_cmd_error ( STR_3009_TOO_CLOSE_TO_ANOTHER_STATION ) ;
@ -1298,8 +1437,7 @@ int32 CmdBuildBusStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if ( ! CheckStationSpreadOut ( st , tile , 1 , 1 ) )
if ( ! CheckStationSpreadOut ( st , tile , 1 , 1 ) )
return CMD_ERROR ;
return CMD_ERROR ;
if ( st - > bus_tile ! = 0 )
FindRoadStationSpot ( type , st , & currstop , & prev ) ;
return_cmd_error ( STR_3044_TOO_CLOSE_TO_ANOTHER_BUS ) ;
} else {
} else {
Town * t ;
Town * t ;
@ -1309,6 +1447,8 @@ int32 CmdBuildBusStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
st - > town = t = ClosestTownFromTile ( tile , ( uint ) - 1 ) ;
st - > town = t = ClosestTownFromTile ( tile , ( uint ) - 1 ) ;
FindRoadStationSpot ( type , st , & currstop , & prev ) ;
if ( _current_player < MAX_PLAYERS & & flags & DC_EXEC )
if ( _current_player < MAX_PLAYERS & & flags & DC_EXEC )
SETBIT ( t - > have_ratings , _current_player ) ;
SETBIT ( t - > have_ratings , _current_player ) ;
@ -1321,13 +1461,17 @@ int32 CmdBuildBusStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
StationInitialize ( st , tile ) ;
StationInitialize ( st , tile ) ;
}
}
cost + = _price . build_bus_station ;
cost + = ( type ) ? _price . build_truck_station : _price . build_bus_station ;
if ( flags & DC_EXEC ) {
if ( flags & DC_EXEC ) {
st - > bus_tile = tile ;
//point to the correct item in the _busstops or _truckstops array
* currstop = road_stop ;
//initialize an empty station
InitializeRoadStop ( road_stop , prev , tile , st - > index ) ;
( * currstop ) - > type = type ;
if ( ! st - > facilities ) st - > xy = tile ;
if ( ! st - > facilities ) st - > xy = tile ;
st - > facilities | = FACIL_BUS_STOP ;
st - > facilities | = ( type ) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP ;
st - > bus_stop_status = 3 ;
st - > owner = _current_player ;
st - > owner = _current_player ;
st - > build_date = _date ;
st - > build_date = _date ;
@ -1336,7 +1480,7 @@ int32 CmdBuildBusStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
MP_SETTYPE ( MP_STATION ) | MP_MAPOWNER_CURRENT |
MP_SETTYPE ( MP_STATION ) | MP_MAPOWNER_CURRENT |
MP_MAP2 | MP_MAP5 | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR ,
MP_MAP2 | MP_MAP5 | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR ,
st - > index , /* map2 parameter */
st - > index , /* map2 parameter */
p1 + 0x47 /* map5 parameter */
gfxbase + direction /* map5 parameter */
) ;
) ;
UpdateStationVirtCoordDirty ( st ) ;
UpdateStationVirtCoordDirty ( st ) ;
@ -1347,143 +1491,60 @@ int32 CmdBuildBusStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
}
// Remove a bus station
// Remove a bus station
static int32 Remove BusStation ( Station * st , uint32 flags )
static int32 Remove RoadStop ( Station * st , uint32 flags , TileIndex tile )
{
{
uint tile ;
RoadStop * * primary_stop ;
RoadStop * cur_stop ;
bool is_truck = _map5 [ tile ] < 0x47 ;
if ( _current_player ! = OWNER_WATER & & ! CheckOwnership ( st - > owner ) )
if ( _current_player ! = OWNER_WATER & & ! CheckOwnership ( st - > owner ) )
return CMD_ERROR ;
return CMD_ERROR ;
tile = st - > bus_tile ;
if ( is_truck ) { //truck stop
primary_stop = & st - > truck_stops ;
if ( ! EnsureNoVehicle ( tile ) )
cur_stop = GetRoadStopByTile ( tile , RS_TRUCK ) ;
return CMD_ERROR ;
} else {
primary_stop = & st - > bus_stops ;
if ( flags & DC_EXEC ) {
cur_stop = GetRoadStopByTile ( tile , RS_BUS ) ;
DoClearSquare ( tile ) ;
st - > bus_tile = 0 ;
st - > facilities & = ~ FACIL_BUS_STOP ;
UpdateStationVirtCoordDirty ( st ) ;
DeleteStationIfEmpty ( st ) ;
}
}
return _price . remove_bus_station ;
assert ( cur_stop ! = NULL ) ;
}
/* Build a truck station
* p1 - direction
* p2 - unused
*/
int32 CmdBuildTruckStation ( int x , int y , uint32 flags , uint32 p1 , uint32 p2 )
{
uint tile ;
int32 cost = 0 ;
Station * st ;
SET_EXPENSES_TYPE ( EXPENSES_CONSTRUCTION ) ;
tile = TILE_FROM_XY ( x , y ) ;
if ( ! EnsureNoVehicle ( tile ) )
if ( ! ( flags & DC_NO_TOWN_RATING ) & & ! CheckIfAuthorityAllows ( tile ) )
return CMD_ERROR ;
if ( ( cost = CheckFlatLandBelow ( tile , 1 , 1 , flags , 1 < < p1 , NULL ) ) = = CMD_ERROR )
return CMD_ERROR ;
st = GetStationAround ( tile , 1 , 1 , - 1 ) ;
if ( st = = CHECK_STATIONS_ERR )
return CMD_ERROR ;
return CMD_ERROR ;
/* Find a station close to us */
if ( st = = NULL ) {
st = GetClosestStationFromTile ( tile , 8 , _current_player ) ;
if ( st ! = NULL & & st - > facilities ) st = NULL ;
}
if ( st ! = NULL ) {
if ( st - > owner ! = OWNER_NONE & & st - > owner ! = _current_player )
return_cmd_error ( STR_3009_TOO_CLOSE_TO_ANOTHER_STATION ) ;
if ( ! CheckStationSpreadOut ( st , tile , 1 , 1 ) )
return CMD_ERROR ;
if ( st - > lorry_tile ! = 0 )
return_cmd_error ( STR_3045_TOO_CLOSE_TO_ANOTHER_TRUCK ) ;
} else {
Town * t ;
st = AllocateStation ( ) ;
if ( st = = NULL )
return CMD_ERROR ;
st - > town = t = ClosestTownFromTile ( tile , ( uint ) - 1 ) ;
if ( _current_player < MAX_PLAYERS & & flags & DC_EXEC )
SETBIT ( t - > have_ratings , _current_player ) ;
st - > sign . width_1 = 0 ;
if ( ! GenerateStationName ( st , tile , 0 ) )
return CMD_ERROR ;
if ( flags & DC_EXEC )
StationInitialize ( st , tile ) ;
}
cost + = _price . build_truck_station ;
if ( flags & DC_EXEC ) {
if ( flags & DC_EXEC ) {
st - > lorry_tile = tile ;
DoClearSquare ( tile ) ;
if ( ! st - > facilities ) st - > xy = tile ;
st - > facilities | = FACIL_TRUCK_STOP ;
st - > truck_stop_status = 3 ;
st - > owner = _current_player ;
st - > build_date = _date ;
ModifyTile ( tile ,
MP_SETTYPE ( MP_STATION ) | MP_MAPOWNER_CURRENT |
MP_MAP2 | MP_MAP3LO_CLEAR | MP_MAP3HI_CLEAR | MP_MAP5 ,
st - > index , /* map2 parameter */
p1 + 0x43 /* map5 parameter */
) ;
UpdateStationVirtCoordDirty ( st ) ;
UpdateStationAcceptance ( st , false ) ;
InvalidateWindow ( WC_STATION_LIST , st - > owner ) ;
}
return cost ;
}
// Remove a truck station
cur_stop - > used = false ;
static int32 RemoveTruckStation ( Station * st , uint32 flags )
if ( cur_stop - > prev ! = NULL ) //alter previous stop
{
cur_stop - > prev - > next = cur_stop - > next ;
uint tile ;
if ( _current_player ! = OWNER_WATER & & ! CheckOwnership ( st - > owner ) )
if ( cur_stop - > next ! = NULL ) //alter next stop
return CMD_ERROR ;
cur_stop - > next - > prev = cur_stop - > prev ;
tile = st - > lorry_tile ;
//we only had one stop left
if ( cur_stop - > next = = NULL & & cur_stop - > prev = = NULL ) {
if ( ! EnsureNoVehicle ( tile ) )
//so we remove ALL stops
return CMD_ERROR ;
* primary_stop = NULL ;
st - > facilities & = ( is_truck ) ? ~ FACIL_TRUCK_STOP : ~ FACIL_BUS_STOP ;
if ( flags & DC_EXEC ) {
} else if ( cur_stop = = * primary_stop ) {
DoClearSquare ( tile ) ;
//removed the first stop in the list
//need to set the primary element to the next stop
st - > lorry_tile = 0 ;
* primary_stop = ( * primary_stop ) - > next ;
st - > facilities & = ~ FACIL_TRUCK_STOP ;
}
UpdateStationVirtCoordDirty ( st ) ;
UpdateStationVirtCoordDirty ( st ) ;
DeleteStationIfEmpty ( st ) ;
DeleteStationIfEmpty ( st ) ;
}
}
return _price . remove_truck _station;
return ( is_truck ) ? _price . remove_truck_station : _price . remove_bus_station ;
}
}
// FIXME -- need to move to its corresponding Airport variable
// FIXME -- need to move to its corresponding Airport variable
// Country Airfield (small)
// Country Airfield (small)
static const byte _airport_map5_tiles_country [ ] = {
static const byte _airport_map5_tiles_country [ ] = {
@ -2215,7 +2276,7 @@ static const byte _enter_station_speedtable[12] = {
static uint32 VehicleEnter_Station ( Vehicle * v , uint tile , int x , int y )
static uint32 VehicleEnter_Station ( Vehicle * v , uint tile , int x , int y )
{
{
uint16 station_id ;
uint16 station_id ; //XXX should be stationindex
byte dir ;
byte dir ;
uint16 spd ;
uint16 spd ;
@ -2252,12 +2313,12 @@ static uint32 VehicleEnter_Station(Vehicle *v, uint tile, int x, int y)
}
}
} else if ( v - > type = = VEH_Road ) {
} else if ( v - > type = = VEH_Road ) {
if ( v - > u . road . state < 16 & & ( v - > u . road . state & 4 ) = = 0 & & v - > u . road . frame = = 0 ) {
if ( v - > u . road . state < 16 & & ( v - > u . road . state & 4 ) = = 0 & & v - > u . road . frame = = 0 ) {
Station * st = GetStation ( _map2 [ tile ] ) ;
byte m5 = _map5 [ tile ] ;
byte m5 = _map5 [ tile ] ;
byte * b , bb , state ;
byte * b , bb , state ;
if ( IS_BYTE_INSIDE ( m5 , 0x43 , 0x4B ) ) {
if ( IS_BYTE_INSIDE ( m5 , 0x43 , 0x4B ) ) {
b = ( m5 > = 0x47 ) ? & st - > bus_stop_status : & st - > truck_stop_status ;
RoadStop * rs = GetRoadStopByTile ( tile , GetRoadStopType ( tile ) ) ;
b = & rs - > status ;
bb = * b ;
bb = * b ;
@ -2275,6 +2336,8 @@ static uint32 VehicleEnter_Station(Vehicle *v, uint tile, int x, int y)
bb & = ~ 2 ;
bb & = ~ 2 ;
state + = 2 ;
state + = 2 ;
}
}
bb | = 0x80 ;
* b = bb ;
* b = bb ;
v - > u . road . state = state ;
v - > u . road . state = state ;
}
}
@ -2625,7 +2688,8 @@ uint MoveGoodsToStation(uint tile, int w, int h, int type, uint amount)
/* several stations around, find the two with the highest rating */
/* several stations around, find the two with the highest rating */
st2 = st1 = NULL ;
st2 = st1 = NULL ;
best_rating = best_rating2 = 0 ;
best_rating = best_rating2 = 0 ;
for ( i = 0 ; i ! = 8 & & around [ i ] ! = 0xFF ; i + + ) {
for ( i = 0 ; i ! = 8 & & around [ i ] ! = 0xFF ; i + + ) {
if ( around_ptr [ i ] - > goods [ type ] . rating > = best_rating ) {
if ( around_ptr [ i ] - > goods [ type ] . rating > = best_rating ) {
best_rating2 = best_rating ;
best_rating2 = best_rating ;
st2 = st1 ;
st2 = st1 ;
@ -2686,8 +2750,8 @@ void BuildOilRig(uint tile)
st - > airport_flags = 0 ;
st - > airport_flags = 0 ;
st - > airport_type = AT_OILRIG ;
st - > airport_type = AT_OILRIG ;
st - > xy = tile ;
st - > xy = tile ;
st - > bus_ tile = 0 ;
st - > bus_ stops = NULL ;
st - > lorry_tile = 0 ;
st - > truck_stops = NULL ;
st - > airport_tile = tile ;
st - > airport_tile = tile ;
st - > dock_tile = tile ;
st - > dock_tile = tile ;
st - > train_tile = 0 ;
st - > train_tile = 0 ;
@ -2768,11 +2832,8 @@ static int32 ClearTile_Station(uint tile, byte flags) {
if ( m5 < 0x43 | | ( m5 > = 83 & & m5 < = 114 ) )
if ( m5 < 0x43 | | ( m5 > = 83 & & m5 < = 114 ) )
return RemoveAirport ( st , flags ) ;
return RemoveAirport ( st , flags ) ;
if ( m5 < 0x47 )
return RemoveTruckStation ( st , flags ) ;
if ( m5 < 0x4B )
if ( m5 < 0x4B )
return Remove BusStation( st , flags ) ;
return RemoveRoadStop ( st , flags , tile ) ;
if ( m5 = = 0x52 )
if ( m5 = = 0x52 )
return RemoveBuoy ( st , flags ) ;
return RemoveBuoy ( st , flags ) ;
@ -2789,6 +2850,7 @@ void InitializeStations(void)
int i ;
int i ;
Station * s ;
Station * s ;
memset ( _roadstops , 0 , sizeof ( _roadstops ) ) ;
memset ( _stations , 0 , sizeof ( _stations [ 0 ] ) * _stations_size ) ;
memset ( _stations , 0 , sizeof ( _stations [ 0 ] ) * _stations_size ) ;
i = 0 ;
i = 0 ;
@ -2820,14 +2882,27 @@ const TileTypeProcs _tile_type_station_procs = {
GetSlopeTileh_Station , /* get_slope_tileh_proc */
GetSlopeTileh_Station , /* get_slope_tileh_proc */
} ;
} ;
static const byte _roadstop_desc [ ] = {
SLE_VAR ( RoadStop , xy , SLE_UINT32 ) ,
SLE_VAR ( RoadStop , used , SLE_UINT8 ) ,
SLE_VAR ( RoadStop , status , SLE_UINT8 ) ,
SLE_VAR ( RoadStop , index , SLE_UINT32 ) ,
SLE_VAR ( RoadStop , station , SLE_UINT16 ) ,
SLE_VAR ( RoadStop , type , SLE_UINT8 ) ,
SLE_REF ( RoadStop , next , REF_ROADSTOPS ) ,
SLE_REF ( RoadStop , prev , REF_ROADSTOPS ) ,
SLE_ARR ( RoadStop , slot , SLE_UINT16 , NUM_SLOTS ) ,
SLE_END ( )
} ;
static const byte _station_desc [ ] = {
static const byte _station_desc [ ] = {
SLE_CONDVAR ( Station , xy , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , xy , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , xy , SLE_UINT32 , 6 , 255 ) ,
SLE_CONDVAR ( Station , xy , SLE_UINT32 , 6 , 255 ) ,
SLE_CONDVAR ( Station , bus_tile , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , bus_tile_obsolete , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , bus_tile , SLE_UINT32 , 6 , 255 ) ,
SLE_CONDVAR ( Station , lorry_tile_obsolete , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , lorry_tile , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , lorry_tile , SLE_UINT32 , 6 , 255 ) ,
SLE_CONDVAR ( Station , train_tile , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , train_tile , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , train_tile , SLE_UINT32 , 6 , 255 ) ,
SLE_CONDVAR ( Station , train_tile , SLE_UINT32 , 6 , 255 ) ,
SLE_CONDVAR ( Station , airport_tile , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
SLE_CONDVAR ( Station , airport_tile , SLE_FILE_U16 | SLE_VAR_U32 , 0 , 5 ) ,
@ -2850,8 +2925,10 @@ static const byte _station_desc[] = {
SLE_VAR ( Station , owner , SLE_UINT8 ) ,
SLE_VAR ( Station , owner , SLE_UINT8 ) ,
SLE_VAR ( Station , facilities , SLE_UINT8 ) ,
SLE_VAR ( Station , facilities , SLE_UINT8 ) ,
SLE_VAR ( Station , airport_type , SLE_UINT8 ) ,
SLE_VAR ( Station , airport_type , SLE_UINT8 ) ,
SLE_VAR ( Station , truck_stop_status , SLE_UINT8 ) ,
SLE_VAR ( Station , bus_stop_status , SLE_UINT8 ) ,
// truck/bus_stop_status was stored here in savegame format 0 - 6
SLE_CONDVAR ( Station , truck_stop_status_obsolete , SLE_UINT8 , 0 , 5 ) ,
SLE_CONDVAR ( Station , bus_stop_status_obsolete , SLE_UINT8 , 0 , 5 ) ,
// blocked_months was stored here in savegame format 0 - 4.0
// blocked_months was stored here in savegame format 0 - 4.0
SLE_CONDVAR ( Station , blocked_months_obsolete , SLE_UINT8 , 0 , 4 ) ,
SLE_CONDVAR ( Station , blocked_months_obsolete , SLE_UINT8 , 0 , 4 ) ,
@ -2865,7 +2942,10 @@ static const byte _station_desc[] = {
SLE_CONDVAR ( Station , stat_id , SLE_UINT8 , 3 , 255 ) ,
SLE_CONDVAR ( Station , stat_id , SLE_UINT8 , 3 , 255 ) ,
SLE_CONDVAR ( Station , build_date , SLE_UINT16 , 3 , 255 ) ,
SLE_CONDVAR ( Station , build_date , SLE_UINT16 , 3 , 255 ) ,
// reserve extra space in savegame here. (currently 32 bytes)
SLE_CONDREF ( Station , bus_stops , REF_ROADSTOPS , 6 , 255 ) ,
SLE_CONDREF ( Station , truck_stops , REF_ROADSTOPS , 6 , 255 ) ,
// reserve extra space in savegame here. (currently 28 bytes)
SLE_CONDARR ( NullStruct , null , SLE_FILE_U8 | SLE_VAR_NULL , 32 , 2 , 255 ) ,
SLE_CONDARR ( NullStruct , null , SLE_FILE_U8 | SLE_VAR_NULL , 32 , 2 , 255 ) ,
SLE_END ( )
SLE_END ( )
@ -2887,8 +2967,9 @@ static const byte _goods_desc[] = {
static void SaveLoad_STNS ( Station * st )
static void SaveLoad_STNS ( Station * st )
{
{
int i ;
int i ;
SlObject ( st , _station_desc ) ;
SlObject ( st , _station_desc ) ;
for ( i = 0 ; i ! = NUM_CARGO ; i + + )
for ( i = 0 ; i ! = NUM_CARGO ; i + + )
SlObject ( & st - > goods [ i ] , _goods_desc ) ;
SlObject ( & st - > goods [ i ] , _goods_desc ) ;
}
}
@ -2920,6 +3001,32 @@ static void Load_STNS(void)
st - > trainst_w = w ;
st - > trainst_w = w ;
st - > trainst_h = h ;
st - > trainst_h = h ;
}
}
if ( _sl . full_version < 0x600 ) {
/* Convert old bus and truck tile to new-ones */
RoadStop * * currstop ;
RoadStop * prev = NULL ;
RoadStop * road_stop ;
if ( st - > bus_tile_obsolete ! = 0 ) {
road_stop = GetFirstFreeRoadStop ( ) ;
if ( road_stop = = NULL )
error ( " Station: too many busstations in savegame " ) ;
FindRoadStationSpot ( RS_BUS , st , & currstop , & prev ) ;
* currstop = road_stop ;
InitializeRoadStop ( road_stop , prev , st - > bus_tile_obsolete , st - > index ) ;
}
if ( st - > lorry_tile_obsolete ! = 0 ) {
road_stop = GetFirstFreeRoadStop ( ) ;
if ( road_stop = = NULL )
error ( " Station: too many truckstations in savegame " ) ;
FindRoadStationSpot ( RS_TRUCK , st , & currstop , & prev ) ;
* currstop = road_stop ;
InitializeRoadStop ( road_stop , prev , st - > lorry_tile_obsolete , st - > index ) ;
}
}
}
}
/* This is to ensure all pointers are within the limits of
/* This is to ensure all pointers are within the limits of
@ -2928,7 +3035,28 @@ static void Load_STNS(void)
_station_tick_ctr = 0 ;
_station_tick_ctr = 0 ;
}
}
static void Save_ROADSTOP ( void )
{
uint i ;
for ( i = 0 ; i < lengthof ( _roadstops ) ; i + + ) {
if ( _roadstops [ i ] . used ) {
SlSetArrayIndex ( i ) ;
SlObject ( & _roadstops [ i ] , _roadstop_desc ) ;
}
}
}
static void Load_ROADSTOP ( void )
{
int index ;
while ( ( index = SlIterateArray ( ) ) ! = - 1 )
SlObject ( & _roadstops [ index ] , _roadstop_desc ) ;
}
const ChunkHandler _station_chunk_handlers [ ] = {
const ChunkHandler _station_chunk_handlers [ ] = {
{ ' STNS ' , Save_STNS , Load_STNS , CH_ARRAY | CH_LAST } ,
{ ' STNS ' , Save_STNS , Load_STNS , CH_ARRAY } ,
{ ' ROAD ' , Save_ROADSTOP , Load_ROADSTOP , CH_ARRAY | CH_LAST } ,
} ;
} ;