|
@@ -24,49 +24,49 @@
|
|
|
|
|
|
|
|
|
static uint CountRoadBits(RoadBits r)
|
|
|
{
|
|
|
uint count = 0;
|
|
|
|
|
|
if (r & ROAD_NW) ++count;
|
|
|
if (r & ROAD_SW) ++count;
|
|
|
if (r & ROAD_SE) ++count;
|
|
|
if (r & ROAD_NE) ++count;
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
|
|
|
static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool* edge_road)
|
|
|
{
|
|
|
RoadBits present;
|
|
|
RoadBits n;
|
|
|
Owner owner;
|
|
|
*edge_road = true;
|
|
|
|
|
|
if (_game_mode == GM_EDITOR) return true;
|
|
|
|
|
|
// Only do the special processing for actual players.
|
|
|
if (_current_player >= MAX_PLAYERS) return true;
|
|
|
if (!IsValidPlayer(_current_player)) return true;
|
|
|
|
|
|
owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
|
|
|
|
|
|
// Only do the special processing if the road is owned
|
|
|
// by a town
|
|
|
if (owner != OWNER_TOWN) return (owner == OWNER_NONE) || CheckOwnership(owner);
|
|
|
|
|
|
if (_cheats.magic_bulldozer.value) return true;
|
|
|
|
|
|
// Get a bitmask of which neighbouring roads has a tile
|
|
|
n = 0;
|
|
|
present = GetAnyRoadBits(tile);
|
|
|
if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile,-1, 0)) & ROAD_SW) n |= ROAD_NE;
|
|
|
if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1)) & ROAD_NW) n |= ROAD_SE;
|
|
|
if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0)) & ROAD_NE) n |= ROAD_SW;
|
|
|
if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0,-1)) & ROAD_SE) n |= ROAD_NW;
|
|
|
|
|
|
// If 0 or 1 bits are set in n, or if no bits that match the bits to remove,
|
|
|
// then allow it
|
|
|
if ((n & (n - 1)) != 0 && (n & remove) != 0) {
|
|
|
Town *t;
|
|
|
*edge_road = false;
|
|
|
// you can remove all kind of roads with extra dynamite
|
|
|
if (_patches.extra_dynamite) return true;
|
|
@@ -268,49 +268,49 @@ static uint32 CheckRoadSlope(Slope tileh
|
|
|
*pieces |= (*pieces & 0xC) >> 2;
|
|
|
*pieces |= (*pieces & 0x3) << 2;
|
|
|
if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
|
|
|
}
|
|
|
return CMD_ERROR;
|
|
|
}
|
|
|
|
|
|
/** Build a piece of road.
|
|
|
* @param tile tile where to build road
|
|
|
* @param p1 road piece flags
|
|
|
* @param p2 the town that is building the road (0 if not applicable)
|
|
|
*/
|
|
|
int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
int32 cost = 0;
|
|
|
int32 ret;
|
|
|
RoadBits existing = 0;
|
|
|
RoadBits pieces;
|
|
|
Slope tileh;
|
|
|
|
|
|
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 ((p1 >> 4) || (_current_player < MAX_PLAYERS && p2 != 0) || !IsValidTownID(p2)) return CMD_ERROR;
|
|
|
if ((p1 >> 4) || (IsValidPlayer(_current_player) && p2 != 0) || !IsValidTownID(p2)) return CMD_ERROR;
|
|
|
pieces = p1;
|
|
|
|
|
|
tileh = GetTileSlope(tile, NULL);
|
|
|
|
|
|
switch (GetTileType(tile)) {
|
|
|
case MP_STREET:
|
|
|
switch (GetRoadTileType(tile)) {
|
|
|
case ROAD_TILE_NORMAL:
|
|
|
if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
|
|
|
|
|
|
existing = GetRoadBits(tile);
|
|
|
if ((existing & pieces) == pieces) {
|
|
|
return_cmd_error(STR_1007_ALREADY_BUILT);
|
|
|
}
|
|
|
if (!EnsureNoVehicle(tile)) return CMD_ERROR;
|
|
|
break;
|
|
|
|
|
|
case ROAD_TILE_CROSSING:
|
|
|
if (pieces != GetCrossingRoadBits(tile)) { // XXX is this correct?
|
|
|
return_cmd_error(STR_1007_ALREADY_BUILT);
|
|
|
}
|
|
|
goto do_clear;
|
|
|
|
|
|
default:
|