road_cmd.c
changeset 3434 0ada2e311826
parent 3430 fcc344e41319
child 3435 dfba5b1c7c2d
equal deleted inserted replaced
3433:4e0d2ea104b3 3434:0ada2e311826
   275  * @param p1 road piece flags
   275  * @param p1 road piece flags
   276  * @param p2 the town that is building the road (0 if not applicable)
   276  * @param p2 the town that is building the road (0 if not applicable)
   277  */
   277  */
   278 int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   278 int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   279 {
   279 {
   280 	TileInfo ti;
       
   281 	int32 cost = 0;
   280 	int32 cost = 0;
   282 	int32 ret;
   281 	int32 ret;
   283 	RoadBits existing = 0;
   282 	RoadBits existing = 0;
   284 	RoadBits pieces;
   283 	RoadBits pieces;
   285 	TileIndex tile;
   284 	TileIndex tile;
       
   285 	byte tileh;
   286 
   286 
   287 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   287 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   288 
   288 
   289 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
   289 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
   290 	 * if a non-player is building the road */
   290 	 * if a non-player is building the road */
   291 	if ((p1 >> 4) || (_current_player < MAX_PLAYERS && p2 != 0) || !IsTownIndex(p2)) return CMD_ERROR;
   291 	if ((p1 >> 4) || (_current_player < MAX_PLAYERS && p2 != 0) || !IsTownIndex(p2)) return CMD_ERROR;
   292 	pieces = p1;
   292 	pieces = p1;
   293 
   293 
   294 	FindLandscapeHeight(&ti, x, y);
   294 	tile = TileVirtXY(x, y);
   295 	tile = ti.tile;
   295 	tileh = GetTileSlope(tile, NULL);
   296 
   296 
   297 	switch (ti.type) {
   297 	switch (GetTileType(tile)) {
   298 		case MP_STREET:
   298 		case MP_STREET:
   299 			switch (GetRoadType(tile)) {
   299 			switch (GetRoadType(tile)) {
   300 				case ROAD_NORMAL:
   300 				case ROAD_NORMAL:
   301 					existing = GetRoadBits(tile);
   301 					existing = GetRoadBits(tile);
   302 					if ((existing & pieces) == pieces) {
   302 					if ((existing & pieces) == pieces) {
   318 			break;
   318 			break;
   319 
   319 
   320 		case MP_RAILWAY: {
   320 		case MP_RAILWAY: {
   321 			Axis roaddir;
   321 			Axis roaddir;
   322 
   322 
   323 			if (IsSteepTileh(ti.tileh)) { // very steep tile
   323 			if (IsSteepTileh(tileh)) { // very steep tile
   324 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   324 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   325 			}
   325 			}
   326 
   326 
   327 #define M(x) (1 << (x))
   327 #define M(x) (1 << (x))
   328 			/* Level crossings may only be built on these slopes */
   328 			/* Level crossings may only be built on these slopes */
   329 			if (!HASBIT(M(14) | M(13) | M(11) | M(10) | M(7) | M(5) | M(0), ti.tileh)) {
   329 			if (!HASBIT(M(14) | M(13) | M(11) | M(10) | M(7) | M(5) | M(0), tileh)) {
   330 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   330 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   331 			}
   331 			}
   332 #undef M
   332 #undef M
   333 
   333 
   334 			if (GetRailTileType(tile) != RAIL_TYPE_NORMAL) goto do_clear;
   334 			if (GetRailTileType(tile) != RAIL_TYPE_NORMAL) goto do_clear;
   355 			return _price.build_road * 2;
   355 			return _price.build_road * 2;
   356 		}
   356 		}
   357 
   357 
   358 		case MP_TUNNELBRIDGE:
   358 		case MP_TUNNELBRIDGE:
   359 			/* check for flat land */
   359 			/* check for flat land */
   360 			if (IsSteepTileh(ti.tileh)) { // very steep tile
   360 			if (IsSteepTileh(tileh)) { // very steep tile
   361 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   361 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   362 			}
   362 			}
   363 
   363 
   364 			if (!IsBridge(tile) || !IsBridgeMiddle(tile)) goto do_clear;
   364 			if (!IsBridge(tile) || !IsBridgeMiddle(tile)) goto do_clear;
   365 
   365 
   391 			ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   391 			ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   392 			if (CmdFailed(ret)) return ret;
   392 			if (CmdFailed(ret)) return ret;
   393 			cost += ret;
   393 			cost += ret;
   394 	}
   394 	}
   395 
   395 
   396 	ret = CheckRoadSlope(ti.tileh, &pieces, existing);
   396 	ret = CheckRoadSlope(tileh, &pieces, existing);
   397 	if (CmdFailed(ret)) return_cmd_error(STR_1800_LAND_SLOPED_IN_WRONG_DIRECTION);
   397 	if (CmdFailed(ret)) return_cmd_error(STR_1800_LAND_SLOPED_IN_WRONG_DIRECTION);
   398 	if (ret != 0 && (!_patches.build_on_slopes || _is_old_ai_player)) {
   398 	if (ret != 0 && (!_patches.build_on_slopes || _is_old_ai_player)) {
   399 		return CMD_ERROR;
   399 		return CMD_ERROR;
   400 	}
   400 	}
   401 	cost += ret;
   401 	cost += ret;
   402 
   402 
   403 	if (ti.type == MP_STREET) {
   403 	if (IsTileType(tile, MP_STREET)) {
   404 		// Don't put the pieces that already exist
   404 		// Don't put the pieces that already exist
   405 		pieces &= ComplementRoadBits(existing);
   405 		pieces &= ComplementRoadBits(existing);
   406 	}
   406 	}
   407 
   407 
   408 	cost += CountRoadBits(pieces) * _price.build_road;
   408 	cost += CountRoadBits(pieces) * _price.build_road;
   409 
   409 
   410 	if (flags & DC_EXEC) {
   410 	if (flags & DC_EXEC) {
   411 		if (ti.type == MP_STREET) {
   411 		if (IsTileType(tile, MP_STREET)) {
   412 			SetRoadBits(tile, existing | pieces);
   412 			SetRoadBits(tile, existing | pieces);
   413 		} else {
   413 		} else {
   414 			MakeRoadNormal(tile, _current_player, pieces, p2);
   414 			MakeRoadNormal(tile, _current_player, pieces, p2);
   415 		}
   415 		}
   416 
   416