(svn r2288) - CodeChange: protected the next batch of commands (41 so far, out of 115).

- CodeChange: changed the airport gui airport-type checking. Added function GetValidAirports() that returns bitmasked availibility, is also used for checking.
- CodeChange: to check tree-planting, 2 const arrays have been moved to table/tree_land.h (type and count)
- CodeChange: added IsTownIndex() in following of IsStationIndex(), etc.
- Fix (regression): road tunnels did not work anymore, forgot that their type was 0x200 (documented now)
This commit is contained in:
Darkvater
2005-05-09 22:33:00 +00:00
parent 4ad80ae872
commit ab954a934a
12 changed files with 260 additions and 215 deletions

View File

@@ -124,8 +124,10 @@ uint GetRoadBitsByTile(TileIndex tile)
return (byte)(r | (r >> 8));
}
/* Delete a piece of road
* p1 = piece type
/** Delete a piece of road.
* @param x,y tile coordinates for road construction
* @param p1 road piece flags
* @param p2 unused
*/
int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
@@ -137,13 +139,16 @@ int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
TileIndex tile;
byte owner;
Town *t;
/* true if the roadpiece was always removeable,
false if it was a center piece. Affects town ratings drop
*/
/* true if the roadpiece was always removeable,
* false if it was a center piece. Affects town ratings drop */
bool edge_road;
byte pieces = (byte)p1;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
if (pieces >> 4) return CMD_ERROR;
FindLandscapeHeight(&ti, x, y);
tile = ti.tile;
@@ -169,10 +174,9 @@ int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
bool b;
_road_special_gettrackstatus = true;
b = CheckAllowRemoveRoad(tile, p1, &edge_road);
b = CheckAllowRemoveRoad(tile, pieces, &edge_road);
_road_special_gettrackstatus = false;
if (!b)
return CMD_ERROR;
if (!b) return CMD_ERROR;
}
if (ti.type == MP_TUNNELBRIDGE) {
@@ -180,9 +184,9 @@ int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return CMD_ERROR;
if ((ti.map5 & 0xE9) == 0xE8) {
if (p1 & 10) goto return_error;
if (pieces & 10) goto return_error;
} else if ((ti.map5 & 0xE9) == 0xE9) {
if (p1 & 5) goto return_error;
if (pieces & 5) goto return_error;
} else
goto return_error;
@@ -202,7 +206,7 @@ int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
// XXX - change cascading ifs to switch when doing rewrite
if ((ti.map5 & 0xF0) == 0) { // normal road
uint c = p1, t2;
byte c = pieces, t2;
if (ti.tileh != 0 && (ti.map5 == 5 || ti.map5 == 10)) {
c |= (c & 0xC) >> 2;
@@ -235,10 +239,10 @@ int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (!(ti.map5 & 8)) {
c = 2;
if (p1 & 5) goto return_error;
if (pieces & 5) goto return_error;
} else {
c = 1;
if (p1 & 10) goto return_error;
if (pieces & 10) goto return_error;
}
cost = _price.remove_road * 2;
@@ -340,30 +344,33 @@ static uint32 CheckRoadSlope(int tileh, byte *pieces, byte existing)
return CMD_ERROR;
}
/* Build a piece of road
* p1 = piece flags
* p2 = town which is building the road
/** Build a piece of road.
* @param x,y tile coordinates for road construction
* @param p1 road piece flags
* @param p2 the town that is building the road (0 if not applicable)
*/
int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
TileInfo ti;
int32 cost;
byte pieces = (byte)p1, existing = 0;
uint tile;
TileIndex tile;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
* if a non-player is building the road */
if ((pieces >> 4) || (_current_player < MAX_PLAYERS && p2 != 0) || !IsTownIndex(p2)) return CMD_ERROR;
FindLandscapeHeight(&ti, x, y);
tile = ti.tile;
// allow building road under bridge
if (ti.type != MP_TUNNELBRIDGE && !EnsureNoVehicle(tile))
return CMD_ERROR;
if (ti.type != MP_TUNNELBRIDGE && !EnsureNoVehicle(tile)) return CMD_ERROR;
if (ti.type == MP_STREET) {
if (!(ti.map5 & 0xF0)) {
if ( ((pieces) & (byte)(ti.map5)) == (pieces))
if ( (pieces & (byte)(ti.map5)) == (pieces))
return_cmd_error(STR_1007_ALREADY_BUILT);
existing = ti.map5;
} else {
@@ -433,12 +440,12 @@ int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
return cost;
} else {
do_clear:;
if (DoCommandByTile(tile, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR) == CMD_ERROR)
if (CmdFailed(DoCommandByTile(tile, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR)))
return CMD_ERROR;
}
cost = CheckRoadSlope(ti.tileh, &pieces, existing);
if (cost == CMD_ERROR) return_cmd_error(STR_1800_LAND_SLOPED_IN_WRONG_DIRECTION);
if (CmdFailed(cost)) return_cmd_error(STR_1800_LAND_SLOPED_IN_WRONG_DIRECTION);
if (cost && (!_patches.build_on_slopes || (!_patches.ainew_active && _is_ai_player)))
return CMD_ERROR;
@@ -494,123 +501,130 @@ int32 DoConvertStreetRail(uint tile, uint totype, bool exec)
}
// Build a long piece of road.
// x,y = end tile
// p1 = start tile
// p2&1 = start tile starts in the 2nd half
// p2&2 = end tile starts in the 2nd half
// p2&4 = direction (0 = along x, 1=along y)
/** Build a long piece of road.
* @param x,y end tile of drag
* @param p1 start tile of drag
* @param p2 various bitstuffed elements
* - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
* - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
* - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
*/
int32 CmdBuildLongRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
uint start_tile, end_tile, tile;
int mode;
int32 cost,ret;
TileIndex start_tile, end_tile, tile;
int32 cost, ret;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
if (p1 > MapSize()) return CMD_ERROR;
start_tile = p1;
end_tile = TILE_FROM_XY(x, y);
if (start_tile > end_tile || (start_tile == end_tile && (p2&1))) {
uint t = start_tile; start_tile = end_tile; end_tile = t;
/* Only drag in X or Y direction dictated by the direction variable */
if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
if (HASBIT(p2, 2) && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
/* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
TileIndex t = start_tile;
start_tile = end_tile;
end_tile = t;
p2 ^= IS_INT_INSIDE(p2&3, 1, 3) ? 3 : 0;
}
cost = 0;
tile = start_tile;
// Start tile is the small number.
for(;;) {
mode = (p2&4) ? 5 : 10;
for (;;) {
uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
if (tile == start_tile && (p2&1))
mode &= (4+2);
else if (tile == end_tile && !(p2&2))
mode &= (1+8);
ret = DoCommandByTile(tile, mode, 0, flags, CMD_BUILD_ROAD);
if (ret == CMD_ERROR) {
if (_error_message != STR_1007_ALREADY_BUILT)
return CMD_ERROR;
} else {
ret = DoCommandByTile(tile, bits, 0, flags, CMD_BUILD_ROAD);
if (CmdFailed(ret)) {
if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
} else
cost += ret;
}
if (tile == end_tile)
break;
if (tile == end_tile) break;
tile += (p2&4)?TILE_XY(0,1):TILE_XY(1,0);
tile += HASBIT(p2, 2) ? TILE_XY(0, 1) : TILE_XY(1, 0);
}
// already built?
if (cost == 0)
return CMD_ERROR;
return cost;
return (cost == 0) ? CMD_ERROR : cost;
}
// Remove a long piece of road.
// x,y = end tile
// p1 = start tile
// p2&1 = start tile starts in the 2nd half
// p2&2 = end tile starts in the 2nd half
// p2&4 = direction (0 = along x, 1=along y)
/** Remove a long piece of road.
* @param x,y end tile of drag
* @param p1 start tile of drag
* @param p2 various bitstuffed elements
* - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
* - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
* - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
*/
int32 CmdRemoveLongRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
uint start_tile, end_tile, tile;
int32 cost,ret;
TileIndex start_tile, end_tile, tile;
int32 cost, ret;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
if (p1 > MapSize()) return CMD_ERROR;
start_tile = p1;
end_tile = TILE_FROM_XY(x, y);
if (start_tile > end_tile || (start_tile == end_tile && (p2&1))) {
uint t = start_tile; start_tile = end_tile; end_tile = t;
/* Only drag in X or Y direction dictated by the direction variable */
if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
if (HASBIT(p2, 2) && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
/* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
if (start_tile > end_tile || (start_tile == end_tile && HASBIT(p2, 0))) {
TileIndex t = start_tile;
start_tile = end_tile;
end_tile = t;
p2 ^= IS_INT_INSIDE(p2&3, 1, 3) ? 3 : 0;
}
cost = 0;
tile = start_tile;
// Start tile is the small number.
for(;;) {
uint bits = (p2 & 4) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
if (tile == end_tile && !(p2&2)) bits &= ROAD_NW | ROAD_NE;
if (tile == start_tile && (p2&1)) bits &= ROAD_SE | ROAD_SW;
for (;;) {
uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
// try to remove the halves.
if (bits) {
ret = DoCommandByTile(tile, bits, 0, flags, CMD_REMOVE_ROAD);
if (ret != CMD_ERROR)
cost += ret;
if (!CmdFailed(ret)) cost += ret;
}
if (tile == end_tile)
break;
if (tile == end_tile) break;
tile += (p2&4)?TILE_XY(0,1):TILE_XY(1,0);
tile += HASBIT(p2, 2) ? TILE_XY(0, 1) : TILE_XY(1, 0);
}
// already built?
if (cost == 0)
return CMD_ERROR;
return cost;
return (cost == 0) ? CMD_ERROR : cost;
}
/* Build a road depot
* p1 - direction (0-3)
* p2 - unused
/** Build a road depot.
* @param x,y tile coordinates where the depot will be built
* @param p1 depot direction (0 through 3), where 0 is NW, 1 is NE, etc.
* @param p2 unused
*/
int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
TileInfo ti;
int32 cost;
Depot *dep;
uint tile;
TileIndex tile;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
if (p2 > 3) return CMD_ERROR; // check direction
FindLandscapeHeight(&ti, x, y);
tile = ti.tile;
@@ -624,8 +638,7 @@ int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
cost = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (cost == CMD_ERROR)
return CMD_ERROR;
if (CmdFailed(cost)) return CMD_ERROR;
dep = AllocateDepot();
if (dep == NULL)