diff options
author | Darkvater <darkvater@openttd.org> | 2005-05-07 10:26:12 +0000 |
---|---|---|
committer | Darkvater <darkvater@openttd.org> | 2005-05-07 10:26:12 +0000 |
commit | 3ad11e0ad45af46ffbc3cbe16156794d76f1cf4f (patch) | |
tree | 41092e6384d7ca2d43fd19eb44c85504508903a0 | |
parent | b90e9d49caf46acc51975fdf995858b20d13055f (diff) | |
download | openttd-3ad11e0ad45af46ffbc3cbe16156794d76f1cf4f.tar.xz |
(svn r2279) - Fix: Check the parameters of the first 10 Commands. While there also add proper comments for the functions and fix up CmdFailed()
-rw-r--r-- | clear_cmd.c | 21 | ||||
-rw-r--r-- | command.h | 2 | ||||
-rw-r--r-- | landscape.c | 8 | ||||
-rw-r--r-- | rail_cmd.c | 145 | ||||
-rw-r--r-- | station_cmd.c | 65 | ||||
-rw-r--r-- | tunnelbridge_cmd.c | 26 |
6 files changed, 138 insertions, 129 deletions
diff --git a/clear_cmd.c b/clear_cmd.c index fa3c4772d..f12f37ff1 100644 --- a/clear_cmd.c +++ b/clear_cmd.c @@ -210,20 +210,23 @@ static bool TerraformTileHeight(TerraformerState *ts, uint tile, int height) return true; } -/* Terraform land - * p1 - corners - * p2 - direction +/** Terraform land + * @param x,y coordinates to terraform + * @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) { TerraformerState ts; - uint tile; + TileIndex tile; int direction; TerraformerHeightMod modheight_data[576]; 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); _error_message = INVALID_STRING_ID; @@ -267,7 +270,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2) int count; 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 tile = *ti; @@ -289,7 +292,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2) { int count; 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); } } @@ -301,7 +304,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2) uint til; mod = ts.modheight; - for(count = ts.modheight_count; count != 0; count--, mod++) { + for (count = ts.modheight_count; count != 0; count--, mod++) { til = mod->tile; SetTileHeight(til, mod->height); @@ -313,7 +316,7 @@ int32 CmdTerraformLand(int x, int y, uint32 flags, uint32 p1, uint32 p2) { int count; 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); } } @@ -191,4 +191,6 @@ int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint p bool IsValidCommand(uint cmd); 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 */ diff --git a/landscape.c b/landscape.c index aca702b7a..46c1e13c1 100644 --- a/landscape.c +++ b/landscape.c @@ -273,11 +273,11 @@ void GetTileDesc(TileIndex tile, TileDesc *td) _tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td); } -/* Clear a piece of landscape - * p1 = 0, - * p2 = 0 +/** Clear a piece of landscape + * @param x,y coordinates of clearance + * @param p1 unused + * @param p2 unused */ - int32 CmdLandscapeClear(int x, int y, uint32 flags, uint32 p1, uint32 p2) { TileIndex tile = TILE_FROM_XY(x, y); diff --git a/rail_cmd.c b/rail_cmd.c index 40498cb68..7bb367c57 100644 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -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); } -int32 CmdBuildSingleRail(int x, int y, uint32 flags, - uint32 rail_type, uint32 rail) +/* Validate functions for rail building */ +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; uint tileh; @@ -285,14 +292,12 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags, int32 cost = 0; int32 ret; - if (rail_type > _players[_current_player].max_railtype || - rail > 5) // invalid track number? - return CMD_ERROR; + if (!(ValParamRailtype(p1) && ValParamTrackOrientation(p2))) return CMD_ERROR; tile = TILE_FROM_XY(x, y); tileh = GetTileSlope(tile, NULL); m5 = _map5[tile]; - rail_bit = 1 << rail; + rail_bit = 1 << p2; SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); @@ -313,7 +318,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags, if (flags & DC_EXEC) { _map_owner[tile] = _current_player; _map3_lo[tile] &= ~0x0F; - _map3_lo[tile] |= rail_type; + _map3_lo[tile] |= p1; _map5[tile] = (m5 & 0xC7) | 0x20; // railroad under bridge } break; @@ -334,7 +339,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags, } if (m5 & RAIL_TYPE_SPECIAL || _map_owner[tile] != _current_player || - (_map3_lo[tile] & 0xFU) != rail_type) { + (_map3_lo[tile] & 0xFU) != p1) { // Get detailed error message 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) { _map3_lo[tile] = _map_owner[tile]; _map_owner[tile] = _current_player; - _map3_hi[tile] = rail_type; + _map3_hi[tile] = p1; _map5[tile] = 0x10 | (rail_bit == 1 ? 0x08 : 0x00); // level crossing } break; @@ -384,7 +389,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags, SetTileType(tile, MP_RAILWAY); _map_owner[tile] = _current_player; _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; } break; @@ -392,7 +397,7 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags, if (flags & DC_EXEC) { MarkTileDirtyByTile(tile); - SetSignalsOnBothDir(tile, rail); + SetSignalsOnBothDir(tile, p2); } return cost + _price.build_rail; @@ -414,17 +419,18 @@ static const byte _signals_table_both[] = { }; -/* Remove a single track. - * p1 - unused - * p2 - tile direction +/** Remove a single piece of track + * @param x,y coordinates for removal of track + * @param p1 unused + * @param p2 rail orientation */ - int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2) { TileInfo ti; + TileIndex tile; byte rail_bit = 1 << p2; - byte m5; - uint tile; + + if (!ValParamTrackOrientation(p2)) return CMD_ERROR; 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; _map5[tile] = ti.map5 & 0xC7; } else if (ti.type == MP_STREET) { + byte m5; if (!(ti.map5 & 0xF0)) return CMD_ERROR; @@ -526,11 +533,11 @@ static const struct { 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; - 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 dx = ex - x; @@ -568,36 +575,37 @@ static int32 ValidateAutoDrag(int *railbit, int x, int y, int ex, int ey) return 0; } -/* Build a stretch of railroad tracks. - * x,y= start tile - * p1 = end tile - * p2 = (bit 0-3) - railroad type normal/maglev - * p2 = (bit 4-6) - track-orientation, valid values: 0-5 - * p2 = (bit 7) - 0 = build, 1 = remove tracks +/** Build a stretch of railroad tracks. + * @param x,y start tile of drag + * @param p1 end tile of drag + * @param p2 various bitstuffed elements + * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) + * - 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) { int ex, ey; int32 ret, total_cost = 0; - int railbit = (p2 >> 4) & 7; + byte railbit = (p2 >> 4) & 7; byte mode = HASBIT(p2, 7); + if (!(ValParamRailtype(p2 & 0x3) && ValParamTrackOrientation(railbit))) return CMD_ERROR; + /* unpack end point */ ex = TileX(p1) * 16; ey = TileY(p1) * 16; SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); - if (flags & DC_EXEC) - SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y)); + if (CmdFailed(ValidateAutoDrag(&railbit, x, y, ex, ey))) return CMD_ERROR; - if (ValidateAutoDrag(&railbit, x, y, ex, ey) == CMD_ERROR) - return CMD_ERROR; + if (flags & DC_EXEC) SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y)); 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)) break; } else @@ -613,15 +621,12 @@ static int32 CmdRailTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2 if (railbit & 0x6) railbit ^= 1; } - if (total_cost == 0) - return CMD_ERROR; - - return total_cost; + return (total_cost == 0) ? CMD_ERROR : total_cost; } 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) @@ -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)); } -/* Build a train depot - * p1 = rail type - * p2 = depot direction +/** Build a train depot + * @param x,y position of the train depot + * @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) { - uint tile = TILE_FROM_XY(x,y); + Depot *d; + TileIndex tile = TILE_FROM_XY(x,y); int32 cost, ret; - Depot *depot; uint tileh; SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); 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); 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); - if (ret == CMD_ERROR) return CMD_ERROR; + if (CmdFailed(ret)) return CMD_ERROR; cost = ret; - depot = AllocateDepot(); - if (depot == NULL) + d = AllocateDepot(); + if (d == NULL) return CMD_ERROR; 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 */ ); - depot->xy = tile; - depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index; + d->xy = tile; + d->town_index = ClosestTownFromTile(tile, (uint)-1)->index; 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; } -/* build signals, alternate between double/single, signal/semaphore, - * pre/exit/combo-signals - * p1 bits 0-2 - track-orientation, valid values: 0-5 - * p1 bit 3 - choose semaphores/signals or cycle normal/pre/exit/combo - * depending on context - * p2 = used for CmdBuildManySignals() to copy style of first signal +/** Build signals, alternate between double/single, signal/semaphore, + * pre/exit/combo-signals, and what-else not + * @param x,y coordinates where signals is being built + * @param p1 various bitstuffed elements + * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 + * - 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) { @@ -695,20 +704,16 @@ int32 CmdBuildSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2) byte m5; int32 cost; - if (!(track < 6) || // only 6 possible track-combinations - !IsTileType(tile, MP_RAILWAY) || - !EnsureNoVehicle(tile)) + if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile)) return CMD_ERROR; - // Protect against invalid signal copying - if (p2 != 0 && (p2 & _signals_table_both[track]) == 0) - return CMD_ERROR; + /* Protect against invalid signal copying */ + if (p2 != 0 && (p2 & _signals_table_both[track]) == 0) return CMD_ERROR; m5 = _map5[tile]; - if (m5 & 0x80 || // mustn't be a depot - !HASBIT(m5, track)) // track must exist - return CMD_ERROR; + /* You can't build signals in a depot, and the selected track must exist */ + if (m5 & 0x80 || !HASBIT(m5, track)) 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) { int ex, ey; - int railbit = (p2 >> 4) & 7; + byte railbit = (p2 >> 4) & 7; bool error = true; TileIndex tile = TILE_FROM_XY(x, y); 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); } -/* Remove signals - * p1 bits 0-2 = track, valid values: 0-5 - * p2 = unused +/** Remove signals + * @param x,y coordinates where signal is being deleted from + * @param p1 track combination to remove signal from */ int32 CmdRemoveSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2) { TileIndex tile = TILE_FROM_XY(x, y); uint track = p1 & 0x7; - if (!(track < 6) || // only 6 possible track-combinations - !IsTileType(tile, MP_RAILWAY) || - !EnsureNoVehicle(tile)) + if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile)) return CMD_ERROR; if ((_map5[tile] & RAIL_TYPE_MASK) != RAIL_TYPE_SIGNALS || (_map3_lo[tile] & _signals_table_both[track]) == 0) // signals on track? return CMD_ERROR; - if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) - return CMD_ERROR; + /* Only water can remove signals from anyone */ + if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR; SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); diff --git a/station_cmd.c b/station_cmd.c index c4269b9e4..d7cc53116 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -917,22 +917,23 @@ static void GetStationLayout(byte *layout, int numtracks, int plat_len, StationS } } -/* build railroad station - * p1 & 1 - orientation - * (p1 >> 8) & 0xFF - numtracks - * (p1 >> 16) & 0xFF - platform length - * p2 & 0xF - railtype - * p2 & 0x10 - set for custom station - * p2 >> 8 - custom station id +/** Build railroad station + * @param x_org,y_org starting position of station dragging/placement + * @param p1 various bitstuffed elements + * - p1 = (bit 0) - orientation (p1 & 1) + * - p1 = (bit 8-15) - number of tracks (p1 >> 8) & 0xFF) + * - p1 = (bit 16-23) - platform length (p1 >> 16) & 0xFF) + * @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_org, int y_org, uint32 flags, uint32 p1, uint32 p2) +int32 CmdBuildRailroadStation(int x, int y, uint32 flags, uint32 p1, uint32 p2) { - /* unpack params */ - int w_org,h_org; - uint tile_org; - int32 cost, ret; Station *st; + TileIndex tile_org; + int w_org, h_org; + int32 cost, ret; int est; int plat_len, numtracks; int direction; @@ -940,25 +941,23 @@ int32 CmdBuildRailroadStation(int x_org, int y_org, uint32 flags, uint32 p1, uin 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? */ - if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) - return CMD_ERROR; - - { - /* unpack parameters */ - direction = p1 & 1; - plat_len = (p1 >> 16) & 0xFF; - numtracks = (p1 >> 8) & 0xFF; - /* w = length, h = num_tracks */ - if (direction) { - h_org = plat_len; - w_org = numtracks; - } else { - w_org = plat_len; - h_org = numtracks; - } + if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR; + if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR; + + /* unpack parameters */ + direction = p1 & 1; + numtracks = (p1 >> 8) & 0xFF; + plat_len = (p1 >> 16) & 0xFF; + /* w = length, h = num_tracks */ + if (direction) { + h_org = plat_len; + w_org = numtracks; + } else { + w_org = plat_len; + h_org = numtracks; } // 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; // 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 - 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; // 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 // 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) - 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]; 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); do { - int tile = tile_org; + TileIndex tile = tile_org; int w = plat_len; do { diff --git a/tunnelbridge_cmd.c b/tunnelbridge_cmd.c index 402d25f76..592fe3a0c 100644 --- a/tunnelbridge_cmd.c +++ b/tunnelbridge_cmd.c @@ -161,11 +161,12 @@ bool CheckBridge_Stuff(byte bridge_type, int bridge_len) return true; } -/* Build a Bridge - * x,y - end tile coord - * p1 - packed start tile coords (~ dx) - * p2&0xFF - bridge type (hi bh) - * p2>>8 - rail type. &0x80 means road bridge. +/** Build a Bridge + * @param x,y end tile coord + * @param p1 packed start tile coords (~ dx) + * @param p2 various bitstuffed elements + * - 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) { @@ -185,11 +186,15 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2) bridge_type = p2 & 0xFF; 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 - if (railtype & 0x80) { + if (HASBIT(railtype, 7)) { // bit 15 of original p2 param railtype = 0; rail_or_road = 2; } else { + if (!ValParamRailtype(railtype)) return CMD_ERROR; rail_or_road = 0; } @@ -198,9 +203,6 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2) 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) */ if (x == sx) { 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 */ - 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; cost = ret; @@ -261,7 +263,7 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2) /* 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; cost += ret; @@ -338,7 +340,7 @@ int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2) } else { not_valid_below:; /* 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; cost += ret; m5 = 0xC0; |