(svn r2279) - Fix: Check the parameters of the first 10 Commands. While there also add proper comments for the functions and fix up CmdFailed()

This commit is contained in:
Darkvater 2005-05-07 10:26:12 +00:00
parent b90e9d49ca
commit 3ad11e0ad4
6 changed files with 137 additions and 128 deletions

View File

@ -210,20 +210,23 @@ static bool TerraformTileHeight(TerraformerState *ts, uint tile, int height)
return true; return true;
} }
/* Terraform land /** Terraform land
* p1 - corners * @param x,y coordinates to terraform
* p2 - direction * @param p1 corners to terraform. Human user only north, towns more
* @param p2 direction; eg up or down
*/ */
int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
TerraformerState ts; TerraformerState ts;
uint tile; TileIndex tile;
int direction; int direction;
TerraformerHeightMod modheight_data[576]; TerraformerHeightMod modheight_data[576];
TileIndex tile_table_data[625]; TileIndex tile_table_data[625];
/* A normal user can only terraform one corner, the northern one; p1 & 8 */
if (_current_player < MAX_PLAYERS && p1 != 8) return CMD_ERROR;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
_error_message = INVALID_STRING_ID; _error_message = INVALID_STRING_ID;
@ -267,7 +270,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2)
int count; int count;
TileIndex *ti = ts.tile_table; TileIndex *ti = ts.tile_table;
for(count = ts.tile_table_count; count != 0; count--, ti++) { for (count = ts.tile_table_count; count != 0; count--, ti++) {
uint z, t; uint z, t;
uint tile = *ti; uint tile = *ti;
@ -289,7 +292,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
int count; int count;
TileIndex *ti = ts.tile_table; TileIndex *ti = ts.tile_table;
for(count = ts.tile_table_count; count != 0; count--, ti++) { for (count = ts.tile_table_count; count != 0; count--, ti++) {
DoCommandByTile(*ti, 0, 0, flags, CMD_LANDSCAPE_CLEAR); DoCommandByTile(*ti, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
} }
} }
@ -301,7 +304,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2)
uint til; uint til;
mod = ts.modheight; mod = ts.modheight;
for(count = ts.modheight_count; count != 0; count--, mod++) { for (count = ts.modheight_count; count != 0; count--, mod++) {
til = mod->tile; til = mod->tile;
SetTileHeight(til, mod->height); SetTileHeight(til, mod->height);
@ -313,7 +316,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
int count; int count;
TileIndex *ti = ts.tile_table; TileIndex *ti = ts.tile_table;
for(count = ts.tile_table_count; count != 0; count--, ti++) { for (count = ts.tile_table_count; count != 0; count--, ti++) {
MarkTileDirtyByTile(*ti); MarkTileDirtyByTile(*ti);
} }
} }

View File

@ -191,4 +191,6 @@ int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint p
bool IsValidCommand(uint cmd); bool IsValidCommand(uint cmd);
int32 GetAvailableMoneyForCommand(void); int32 GetAvailableMoneyForCommand(void);
/* Validate functions for rail building */
static inline bool ValParamRailtype(uint32 rail) { return (rail > GetPlayer(_current_player)->max_railtype) ? false : true;}
#endif /* COMMAND_H */ #endif /* COMMAND_H */

View File

@ -273,11 +273,11 @@ void GetTileDesc(TileIndex tile, TileDesc *td)
_tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td); _tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td);
} }
/* Clear a piece of landscape /** Clear a piece of landscape
* p1 = 0, * @param x,y coordinates of clearance
* p2 = 0 * @param p1 unused
* @param p2 unused
*/ */
int32 CmdLandscapeClear(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdLandscapeClear(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
TileIndex tile = TILE_FROM_XY(x, y); TileIndex tile = TILE_FROM_XY(x, y);

View File

@ -275,8 +275,15 @@ static uint32 CheckRailSlope(uint tileh, uint rail_bits, uint existing, TileInde
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
} }
int32 CmdBuildSingleRail(int x, int y, uint32 flags, /* Validate functions for rail building */
uint32 rail_type, uint32 rail) static inline bool ValParamTrackOrientation(uint32 rail) {return (rail > 5) ? false : true;}
/** Build a single piece of rail
* @param x,y coordinates on where to build
* @param p1 railtype of being built piece (normal, mono, maglev)
* @param p2 rail combination to build
*/
int32 CmdBuildSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
TileIndex tile; TileIndex tile;
uint tileh; uint tileh;
@ -285,14 +292,12 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags,
int32 cost = 0; int32 cost = 0;
int32 ret; int32 ret;
if (rail_type > _players[_current_player].max_railtype || if (!(ValParamRailtype(p1) && ValParamTrackOrientation(p2))) return CMD_ERROR;
rail > 5) // invalid track number?
return CMD_ERROR;
tile = TILE_FROM_XY(x, y); tile = TILE_FROM_XY(x, y);
tileh = GetTileSlope(tile, NULL); tileh = GetTileSlope(tile, NULL);
m5 = _map5[tile]; m5 = _map5[tile];
rail_bit = 1 << rail; rail_bit = 1 << p2;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@ -313,7 +318,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags,
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
_map_owner[tile] = _current_player; _map_owner[tile] = _current_player;
_map3_lo[tile] &= ~0x0F; _map3_lo[tile] &= ~0x0F;
_map3_lo[tile] |= rail_type; _map3_lo[tile] |= p1;
_map5[tile] = (m5 & 0xC7) | 0x20; // railroad under bridge _map5[tile] = (m5 & 0xC7) | 0x20; // railroad under bridge
} }
break; break;
@ -334,7 +339,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags,
} }
if (m5 & RAIL_TYPE_SPECIAL || if (m5 & RAIL_TYPE_SPECIAL ||
_map_owner[tile] != _current_player || _map_owner[tile] != _current_player ||
(_map3_lo[tile] & 0xFU) != rail_type) { (_map3_lo[tile] & 0xFU) != p1) {
// Get detailed error message // Get detailed error message
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
} }
@ -361,7 +366,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags,
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
_map3_lo[tile] = _map_owner[tile]; _map3_lo[tile] = _map_owner[tile];
_map_owner[tile] = _current_player; _map_owner[tile] = _current_player;
_map3_hi[tile] = rail_type; _map3_hi[tile] = p1;
_map5[tile] = 0x10 | (rail_bit == 1 ? 0x08 : 0x00); // level crossing _map5[tile] = 0x10 | (rail_bit == 1 ? 0x08 : 0x00); // level crossing
} }
break; break;
@ -384,7 +389,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags,
SetTileType(tile, MP_RAILWAY); SetTileType(tile, MP_RAILWAY);
_map_owner[tile] = _current_player; _map_owner[tile] = _current_player;
_map2[tile] = 0; // Bare land _map2[tile] = 0; // Bare land
_map3_lo[tile] = rail_type; // No signals, rail type _map3_lo[tile] = p1; // No signals, rail type
_map5[tile] = rail_bit; _map5[tile] = rail_bit;
} }
break; break;
@ -392,7 +397,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags,
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
SetSignalsOnBothDir(tile, rail); SetSignalsOnBothDir(tile, p2);
} }
return cost + _price.build_rail; return cost + _price.build_rail;
@ -414,17 +419,18 @@ static const byte _signals_table_both[] = {
}; };
/* Remove a single track. /** Remove a single piece of track
* p1 - unused * @param x,y coordinates for removal of track
* p2 - tile direction * @param p1 unused
* @param p2 rail orientation
*/ */
int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
TileInfo ti; TileInfo ti;
TileIndex tile;
byte rail_bit = 1 << p2; byte rail_bit = 1 << p2;
byte m5;
uint tile; if (!ValParamTrackOrientation(p2)) return CMD_ERROR;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@ -458,6 +464,7 @@ int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2)
_map_owner[tile] = OWNER_NONE; _map_owner[tile] = OWNER_NONE;
_map5[tile] = ti.map5 & 0xC7; _map5[tile] = ti.map5 & 0xC7;
} else if (ti.type == MP_STREET) { } else if (ti.type == MP_STREET) {
byte m5;
if (!(ti.map5 & 0xF0)) if (!(ti.map5 & 0xF0))
return CMD_ERROR; return CMD_ERROR;
@ -526,11 +533,11 @@ static const struct {
0,-16,-16, 0,-16, 0, 0, 0, 0,-16,-16, 0,-16, 0, 0, 0,
}}; }};
static int32 ValidateAutoDrag(int *railbit, int x, int y, int ex, int ey) static int32 ValidateAutoDrag(byte *railbit, int x, int y, int ex, int ey)
{ {
int dx, dy, trdx, trdy; int dx, dy, trdx, trdy;
if (*railbit > 5) return CMD_ERROR; // only 6 possible track-combinations if (!ValParamTrackOrientation(*railbit)) return CMD_ERROR;
// calculate delta x,y from start to end tile // calculate delta x,y from start to end tile
dx = ex - x; dx = ex - x;
@ -568,36 +575,37 @@ static int32 ValidateAutoDrag(int *railbit, int x, int y, int ex, int ey)
return 0; return 0;
} }
/* Build a stretch of railroad tracks. /** Build a stretch of railroad tracks.
* x,y= start tile * @param x,y start tile of drag
* p1 = end tile * @param p1 end tile of drag
* p2 = (bit 0-3) - railroad type normal/maglev * @param p2 various bitstuffed elements
* p2 = (bit 4-6) - track-orientation, valid values: 0-5 * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
* p2 = (bit 7) - 0 = build, 1 = remove tracks * - p2 = (bit 4-6) - track-orientation, valid values: 0-5
* - p2 = (bit 7) - 0 = build, 1 = remove tracks
*/ */
static int32 CmdRailTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2) static int32 CmdRailTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
int ex, ey; int ex, ey;
int32 ret, total_cost = 0; int32 ret, total_cost = 0;
int railbit = (p2 >> 4) & 7; byte railbit = (p2 >> 4) & 7;
byte mode = HASBIT(p2, 7); byte mode = HASBIT(p2, 7);
if (!(ValParamRailtype(p2 & 0x3) && ValParamTrackOrientation(railbit))) return CMD_ERROR;
/* unpack end point */ /* unpack end point */
ex = TileX(p1) * 16; ex = TileX(p1) * 16;
ey = TileY(p1) * 16; ey = TileY(p1) * 16;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
if (flags & DC_EXEC) if (CmdFailed(ValidateAutoDrag(&railbit, x, y, ex, ey))) return CMD_ERROR;
SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y));
if (ValidateAutoDrag(&railbit, x, y, ex, ey) == CMD_ERROR) if (flags & DC_EXEC) SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y));
return CMD_ERROR;
for(;;) { for(;;) {
ret = DoCommand(x, y, p2&0x3, railbit&7, flags, (mode == 0) ? CMD_BUILD_SINGLE_RAIL : CMD_REMOVE_SINGLE_RAIL); ret = DoCommand(x, y, p2 & 0x3, railbit & 7, flags, (mode == 0) ? CMD_BUILD_SINGLE_RAIL : CMD_REMOVE_SINGLE_RAIL);
if (ret == CMD_ERROR) { if (CmdFailed(ret)) {
if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0)) if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0))
break; break;
} else } else
@ -613,15 +621,12 @@ static int32 CmdRailTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2
if (railbit & 0x6) railbit ^= 1; if (railbit & 0x6) railbit ^= 1;
} }
if (total_cost == 0) return (total_cost == 0) ? CMD_ERROR : total_cost;
return CMD_ERROR;
return total_cost;
} }
int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
return CmdRailTrackHelper(x, y, flags, p1, p2); return CmdRailTrackHelper(x, y, flags, p1, CLRBIT(p2, 7));
} }
int32 CmdRemoveRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdRemoveRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
@ -629,20 +634,23 @@ int32 CmdRemoveRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return CmdRailTrackHelper(x, y, flags, p1, SETBIT(p2, 7)); return CmdRailTrackHelper(x, y, flags, p1, SETBIT(p2, 7));
} }
/* Build a train depot /** Build a train depot
* p1 = rail type * @param x,y position of the train depot
* p2 = depot direction * @param p1 rail type
* @param p2 depot direction (0 through 3), where 0 is NW, 1 is NE, etc.
*/ */
int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
uint tile = TILE_FROM_XY(x,y); Depot *d;
TileIndex tile = TILE_FROM_XY(x,y);
int32 cost, ret; int32 cost, ret;
Depot *depot;
uint tileh; uint tileh;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
if (!EnsureNoVehicle(tile)) return CMD_ERROR; if (!EnsureNoVehicle(tile)) return CMD_ERROR;
/* check railtype and valid direction for depot (0 through 3), 4 in total */
if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR;
tileh = GetTileSlope(tile, NULL); tileh = GetTileSlope(tile, NULL);
if (tileh != 0) { if (tileh != 0) {
@ -651,11 +659,11 @@ int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
} }
ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (ret == CMD_ERROR) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
cost = ret; cost = ret;
depot = AllocateDepot(); d = AllocateDepot();
if (depot == NULL) if (d == NULL)
return CMD_ERROR; return CMD_ERROR;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -669,8 +677,8 @@ int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
p2 | RAIL_TYPE_DEPOT /* map5 */ p2 | RAIL_TYPE_DEPOT /* map5 */
); );
depot->xy = tile; d->xy = tile;
depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index; d->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
SetSignalsOnBothDir(tile, (p2&1) ? 2 : 1); SetSignalsOnBothDir(tile, (p2&1) ? 2 : 1);
@ -679,12 +687,13 @@ int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return cost + _price.build_train_depot; return cost + _price.build_train_depot;
} }
/* build signals, alternate between double/single, signal/semaphore, /** Build signals, alternate between double/single, signal/semaphore,
* pre/exit/combo-signals * pre/exit/combo-signals, and what-else not
* p1 bits 0-2 - track-orientation, valid values: 0-5 * @param x,y coordinates where signals is being built
* p1 bit 3 - choose semaphores/signals or cycle normal/pre/exit/combo * @param p1 various bitstuffed elements
* depending on context * - p1 = (bit 0-2) - track-orientation, valid values: 0-5
* p2 = used for CmdBuildManySignals() to copy style of first signal * - p1 = (bit 3) - choose semaphores/signals or cycle normal/pre/exit/combo depending on context
* @param p2 used for CmdBuildManySignals() to copy style of first signal
*/ */
int32 CmdBuildSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdBuildSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
@ -695,20 +704,16 @@ int32 CmdBuildSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
byte m5; byte m5;
int32 cost; int32 cost;
if (!(track < 6) || // only 6 possible track-combinations if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile))
!IsTileType(tile, MP_RAILWAY) ||
!EnsureNoVehicle(tile))
return CMD_ERROR; return CMD_ERROR;
// Protect against invalid signal copying /* Protect against invalid signal copying */
if (p2 != 0 && (p2 & _signals_table_both[track]) == 0) if (p2 != 0 && (p2 & _signals_table_both[track]) == 0) return CMD_ERROR;
return CMD_ERROR;
m5 = _map5[tile]; m5 = _map5[tile];
if (m5 & 0x80 || // mustn't be a depot /* You can't build signals in a depot, and the selected track must exist */
!HASBIT(m5, track)) // track must exist if (m5 & 0x80 || !HASBIT(m5, track)) return CMD_ERROR;
return CMD_ERROR;
if (!CheckTileOwnership(tile)) return CMD_ERROR; if (!CheckTileOwnership(tile)) return CMD_ERROR;
@ -818,7 +823,7 @@ int32 CmdBuildSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
static int32 CmdSignalTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2) static int32 CmdSignalTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
int ex, ey; int ex, ey;
int railbit = (p2 >> 4) & 7; byte railbit = (p2 >> 4) & 7;
bool error = true; bool error = true;
TileIndex tile = TILE_FROM_XY(x, y); TileIndex tile = TILE_FROM_XY(x, y);
int32 ret, total_cost, signal_ctr; int32 ret, total_cost, signal_ctr;
@ -895,26 +900,24 @@ int32 CmdBuildSignalTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return CmdSignalTrackHelper(x, y, flags, p1, p2); return CmdSignalTrackHelper(x, y, flags, p1, p2);
} }
/* Remove signals /** Remove signals
* p1 bits 0-2 = track, valid values: 0-5 * @param x,y coordinates where signal is being deleted from
* p2 = unused * @param p1 track combination to remove signal from
*/ */
int32 CmdRemoveSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdRemoveSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
TileIndex tile = TILE_FROM_XY(x, y); TileIndex tile = TILE_FROM_XY(x, y);
uint track = p1 & 0x7; uint track = p1 & 0x7;
if (!(track < 6) || // only 6 possible track-combinations if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile))
!IsTileType(tile, MP_RAILWAY) ||
!EnsureNoVehicle(tile))
return CMD_ERROR; return CMD_ERROR;
if ((_map5[tile] & RAIL_TYPE_MASK) != RAIL_TYPE_SIGNALS || if ((_map5[tile] & RAIL_TYPE_MASK) != RAIL_TYPE_SIGNALS ||
(_map3_lo[tile] & _signals_table_both[track]) == 0) // signals on track? (_map3_lo[tile] & _signals_table_both[track]) == 0) // signals on track?
return CMD_ERROR; return CMD_ERROR;
if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) /* Only water can remove signals from anyone */
return CMD_ERROR; if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);

View File

@ -917,22 +917,23 @@ static void GetStationLayout(byte *layout, int numtracks, int plat_len, StationS
} }
} }
/* build railroad station /** Build railroad station
* p1 & 1 - orientation * @param x_org,y_org starting position of station dragging/placement
* (p1 >> 8) & 0xFF - numtracks * @param p1 various bitstuffed elements
* (p1 >> 16) & 0xFF - platform length * - p1 = (bit 0) - orientation (p1 & 1)
* p2 & 0xF - railtype * - p1 = (bit 8-15) - number of tracks (p1 >> 8) & 0xFF)
* p2 & 0x10 - set for custom station * - p1 = (bit 16-23) - platform length (p1 >> 16) & 0xFF)
* p2 >> 8 - custom station id * @param p2 various bitstuffed elements
* - p2 = (bit 0- 3) - railtype (p2 & 0xF)
* - p2 = (bit 4) - set for custom station (p2 & 0x10)
* - p2 = (bit 8-..) - custom station id (p2 >> 8)
*/ */
int32 CmdBuildRailroadStation(int x, int y, uint32 flags, uint32 p1, uint32 p2)
int32 CmdBuildRailroadStation(int x_org, int y_org, uint32 flags, uint32 p1, uint32 p2)
{ {
/* unpack params */
int w_org,h_org;
uint tile_org;
int32 cost, ret;
Station *st; Station *st;
TileIndex tile_org;
int w_org, h_org;
int32 cost, ret;
int est; int est;
int plat_len, numtracks; int plat_len, numtracks;
int direction; int direction;
@ -940,25 +941,23 @@ int32 CmdBuildRailroadStation(int x_org, int y_org, uint32 flags, uint32 p1, uin
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
tile_org = TILE_FROM_XY(x_org,y_org); tile_org = TILE_FROM_XY(x, y);
/* Does the authority allow this? */ /* Does the authority allow this? */
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
return CMD_ERROR; if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
{ /* unpack parameters */
/* unpack parameters */ direction = p1 & 1;
direction = p1 & 1; numtracks = (p1 >> 8) & 0xFF;
plat_len = (p1 >> 16) & 0xFF; plat_len = (p1 >> 16) & 0xFF;
numtracks = (p1 >> 8) & 0xFF; /* w = length, h = num_tracks */
/* w = length, h = num_tracks */ if (direction) {
if (direction) { h_org = plat_len;
h_org = plat_len; w_org = numtracks;
w_org = numtracks; } else {
} else { w_org = plat_len;
w_org = plat_len; h_org = numtracks;
h_org = numtracks;
}
} }
// these values are those that will be stored in train_tile and station_platforms // these values are those that will be stored in train_tile and station_platforms
@ -970,7 +969,7 @@ int32 CmdBuildRailroadStation(int x_org, int y_org, uint32 flags, uint32 p1, uin
est = -1; est = -1;
// If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug // If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
// for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365 // for detail info, see: https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365
if ((ret=CheckFlatLandBelow(tile_org, w_org, h_org, flags&~DC_EXEC, 5 << direction, _patches.nonuniform_stations ? &est : NULL)) == CMD_ERROR) return CMD_ERROR; if (CmdFailed(ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags&~DC_EXEC, 5 << direction, _patches.nonuniform_stations ? &est : NULL))) return CMD_ERROR;
cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len; cost = ret + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len;
// Make sure there are no similar stations around us. // Make sure there are no similar stations around us.
@ -1026,7 +1025,7 @@ int32 CmdBuildRailroadStation(int x_org, int y_org, uint32 flags, uint32 p1, uin
// Now really clear the land below the station // Now really clear the land below the station
// It should never return CMD_ERROR.. but you never know ;) // It should never return CMD_ERROR.. but you never know ;)
// (a bit strange function name for it, but it really does clear the land, when DC_EXEC is in flags) // (a bit strange function name for it, but it really does clear the land, when DC_EXEC is in flags)
if (CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << direction, _patches.nonuniform_stations ? &est : NULL) == CMD_ERROR) return CMD_ERROR; if (CmdFailed(CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << direction, _patches.nonuniform_stations ? &est : NULL))) return CMD_ERROR;
st->train_tile = finalvalues[0]; st->train_tile = finalvalues[0];
if (!st->facilities) st->xy = finalvalues[0]; if (!st->facilities) st->xy = finalvalues[0];
@ -1045,7 +1044,7 @@ int32 CmdBuildRailroadStation(int x_org, int y_org, uint32 flags, uint32 p1, uin
GetStationLayout(layout_ptr, numtracks, plat_len, statspec); GetStationLayout(layout_ptr, numtracks, plat_len, statspec);
do { do {
int tile = tile_org; TileIndex tile = tile_org;
int w = plat_len; int w = plat_len;
do { do {

View File

@ -161,11 +161,12 @@ bool CheckBridge_Stuff(byte bridge_type, int bridge_len)
return true; return true;
} }
/* Build a Bridge /** Build a Bridge
* x,y - end tile coord * @param x,y end tile coord
* p1 - packed start tile coords (~ dx) * @param p1 packed start tile coords (~ dx)
* p2&0xFF - bridge type (hi bh) * @param p2 various bitstuffed elements
* p2>>8 - rail type. &0x80 means road bridge. * - p2 = (bit 0- 7) - bridge type (hi bh)
* - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge.
*/ */
int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
@ -185,11 +186,15 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2)
bridge_type = p2 & 0xFF; bridge_type = p2 & 0xFF;
railtype = (byte)(p2 >> 8); railtype = (byte)(p2 >> 8);
/* Out of bounds bridge */
if (bridge_type >= MAX_BRIDGES) return_cmd_error(STR_5015_CAN_T_BUILD_BRIDGE_HERE);
// type of bridge // type of bridge
if (railtype & 0x80) { if (HASBIT(railtype, 7)) { // bit 15 of original p2 param
railtype = 0; railtype = 0;
rail_or_road = 2; rail_or_road = 2;
} else { } else {
if (!ValParamRailtype(railtype)) return CMD_ERROR;
rail_or_road = 0; rail_or_road = 0;
} }
@ -198,9 +203,6 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2)
direction = 0; direction = 0;
if (bridge_type >= MAX_BRIDGES) // out of bounds bridge
return_cmd_error(STR_5015_CAN_T_BUILD_BRIDGE_HERE);
/* check if valid, and make sure that (x,y) are smaller than (sx,sy) */ /* check if valid, and make sure that (x,y) are smaller than (sx,sy) */
if (x == sx) { if (x == sx) {
if (y == sy) if (y == sy)
@ -249,7 +251,7 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2)
/* Try and clear the start landscape */ /* Try and clear the start landscape */
if ((ret = DoCommandByTile(ti_start.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)) == CMD_ERROR) if (CmdFailed(ret = DoCommandByTile(ti_start.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)))
return CMD_ERROR; return CMD_ERROR;
cost = ret; cost = ret;
@ -261,7 +263,7 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2)
/* Try and clear the end landscape */ /* Try and clear the end landscape */
if ((ret=DoCommandByTile(ti_end.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)) == CMD_ERROR) if (CmdFailed(ret = DoCommandByTile(ti_end.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)))
return CMD_ERROR; return CMD_ERROR;
cost += ret; cost += ret;
@ -338,7 +340,7 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2)
} else { } else {
not_valid_below:; not_valid_below:;
/* try and clear the middle landscape */ /* try and clear the middle landscape */
if ((ret=DoCommandByTile(ti.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)) == CMD_ERROR) if (CmdFailed(ret = DoCommandByTile(ti.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)))
return CMD_ERROR; return CMD_ERROR;
cost += ret; cost += ret;
m5 = 0xC0; m5 = 0xC0;