town_cmd.c
changeset 3636 a36cc46e754d
parent 3585 43461f26b729
child 3639 c27c9e4fddbd
equal deleted inserted replaced
3635:26da0c860a64 3636:a36cc46e754d
   101 	}
   101 	}
   102 
   102 
   103 	z = ti->z;
   103 	z = ti->z;
   104 
   104 
   105 	/* Add bricks below the house? */
   105 	/* Add bricks below the house? */
   106 	if (ti->tileh) {
   106 	if (ti->tileh != SLOPE_FLAT) {
   107 		AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z);
   107 		AddSortableSpriteToDraw(SPR_FOUNDATION_BASE + ti->tileh, ti->x, ti->y, 16, 16, 7, z);
   108 		AddChildSpriteScreen(dcts->sprite_1, 31, 1);
   108 		AddChildSpriteScreen(dcts->sprite_1, 31, 1);
   109 		z += 8;
   109 		z += 8;
   110 	} else {
   110 	} else {
   111 		/* Else draw regular ground */
   111 		/* Else draw regular ground */
   135 	}
   135 	}
   136 }
   136 }
   137 
   137 
   138 static uint GetSlopeZ_Town(const TileInfo* ti)
   138 static uint GetSlopeZ_Town(const TileInfo* ti)
   139 {
   139 {
   140 	return ti->z + (ti->tileh == 0 ? 0 : 8);
   140 	return ti->z + (ti->tileh == SLOPE_FLAT ? 0 : 8);
   141 }
   141 }
   142 
   142 
   143 static uint GetSlopeTileh_Town(TileIndex tile, uint tileh)
   143 static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
   144 {
   144 {
   145 	return 0;
   145 	return SLOPE_FLAT;
   146 }
   146 }
   147 
   147 
   148 static void AnimateTile_Town(TileIndex tile)
   148 static void AnimateTile_Town(TileIndex tile)
   149 {
   149 {
   150 	int pos, dest;
   150 	int pos, dest;
   456 	return r;
   456 	return r;
   457 }
   457 }
   458 
   458 
   459 static bool IsRoadAllowedHere(TileIndex tile, int dir)
   459 static bool IsRoadAllowedHere(TileIndex tile, int dir)
   460 {
   460 {
   461 	uint k;
   461 	Slope k;
   462 	uint slope;
   462 	Slope slope;
   463 
   463 
   464 	// If this assertion fails, it might be because the world contains
   464 	// If this assertion fails, it might be because the world contains
   465 	//  land at the edges. This is not ok.
   465 	//  land at the edges. This is not ok.
   466 	TILE_ASSERT(tile);
   466 	TILE_ASSERT(tile);
   467 
   467 
   475 					CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR)))
   475 					CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR)))
   476 				return false;
   476 				return false;
   477 		}
   477 		}
   478 
   478 
   479 		slope = GetTileSlope(tile, NULL);
   479 		slope = GetTileSlope(tile, NULL);
   480 		if (slope == 0) {
   480 		if (slope == SLOPE_FLAT) {
   481 no_slope:
   481 no_slope:
   482 			// Tile has no slope
   482 			// Tile has no slope
   483 			// Disallow the road if any neighboring tile has a road.
   483 			// Disallow the road if any neighboring tile has a road.
   484 			if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]))), dir^2) ||
   484 			if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+1]))), dir^2) ||
   485 					HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]))), dir^2) ||
   485 					HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir+3]))), dir^2) ||
   491 			return true;
   491 			return true;
   492 		}
   492 		}
   493 
   493 
   494 		// If the tile is not a slope in the right direction, then
   494 		// If the tile is not a slope in the right direction, then
   495 		// maybe terraform some.
   495 		// maybe terraform some.
   496 		if ((k = (dir&1)?0xC:0x9) != slope && (k^0xF) != slope) {
   496 		k = (dir & 1) ? SLOPE_NE : SLOPE_NW;
       
   497 		if (k != slope && ComplementSlope(k) != slope) {
   497 			uint32 r = Random();
   498 			uint32 r = Random();
   498 
   499 
   499 			if (CHANCE16I(1, 8, r) && !_generating_world) {
   500 			if (CHANCE16I(1, 8, r) && !_generating_world) {
   500 				int32 res;
   501 				int32 res;
   501 
   502 
   502 				if (CHANCE16I(1, 16, r)) {
   503 				if (CHANCE16I(1, 16, r)) {
   503 					res = DoCommand(tile, slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER,
   504 					res = DoCommand(tile, slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER,
   504 					                      CMD_TERRAFORM_LAND);
   505 					                      CMD_TERRAFORM_LAND);
   505 				} else {
   506 				} else {
   506 					res = DoCommand(tile, slope ^ 0xF, 1, DC_EXEC | DC_AUTO | DC_NO_WATER,
   507 					res = DoCommand(tile, ComplementSlope(slope), 1, DC_EXEC | DC_AUTO | DC_NO_WATER,
   507 					                      CMD_TERRAFORM_LAND);
   508 					                      CMD_TERRAFORM_LAND);
   508 				}
   509 				}
   509 				if (CmdFailed(res) && CHANCE16I(1, 3, r)) {
   510 				if (CmdFailed(res) && CHANCE16I(1, 3, r)) {
   510 					// We can consider building on the slope, though.
   511 					// We can consider building on the slope, though.
   511 					goto no_slope;
   512 					goto no_slope;
   529 	return true;
   530 	return true;
   530 }
   531 }
   531 
   532 
   532 static void LevelTownLand(TileIndex tile)
   533 static void LevelTownLand(TileIndex tile)
   533 {
   534 {
   534 	uint tileh;
   535 	Slope tileh;
   535 
   536 
   536 	TILE_ASSERT(tile);
   537 	TILE_ASSERT(tile);
   537 
   538 
   538 	// Don't terraform if land is plain or if there's a house there.
   539 	// Don't terraform if land is plain or if there's a house there.
   539 	if (IsTileType(tile, MP_HOUSE)) return;
   540 	if (IsTileType(tile, MP_HOUSE)) return;
   540 	tileh = GetTileSlope(tile, NULL);
   541 	tileh = GetTileSlope(tile, NULL);
   541 	if (tileh == 0) return;
   542 	if (tileh == SLOPE_FLAT) return;
   542 
   543 
   543 	// First try up, then down
   544 	// First try up, then down
   544 	if (!TerraformTownTile(tile, ~tileh & 0xF, 1)) {
   545 	if (!TerraformTownTile(tile, ~tileh & 0xF, 1)) {
   545 		TerraformTownTile(tile, tileh & 0xF, 0);
   546 		TerraformTownTile(tile, tileh & 0xF, 0);
   546 	}
   547 	}
   645 	if (IsClearWaterTile(tile)) return;
   646 	if (IsClearWaterTile(tile)) return;
   646 
   647 
   647 	// Determine direction of slope,
   648 	// Determine direction of slope,
   648 	//  and build a road if not a special slope.
   649 	//  and build a road if not a special slope.
   649 	switch (GetTileSlope(tile, NULL)) {
   650 	switch (GetTileSlope(tile, NULL)) {
   650 		case  3: i = DIAGDIR_NE; break;
   651 		case SLOPE_SW: i = DIAGDIR_NE; break;
   651 		case  6: i = DIAGDIR_NW; break;
   652 		case SLOPE_SE: i = DIAGDIR_NW; break;
   652 		case  9: i = DIAGDIR_SE; break;
   653 		case SLOPE_NW: i = DIAGDIR_SE; break;
   653 		case 12: i = DIAGDIR_SW; break;
   654 		case SLOPE_NE: i = DIAGDIR_SW; break;
   654 
   655 
   655 		default:
   656 		default:
   656 build_road_and_exit:
   657 build_road_and_exit:
   657 			if (!CmdFailed(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
   658 			if (!CmdFailed(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
   658 				_grow_town_result = -1;
   659 				_grow_town_result = -1;
   792 	// clearing some land and then building a road there.
   793 	// clearing some land and then building a road there.
   793 	tile = t->xy;
   794 	tile = t->xy;
   794 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
   795 	for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
   795 		// Only work with plain land that not already has a house with GetHouseConstructionTick=0
   796 		// Only work with plain land that not already has a house with GetHouseConstructionTick=0
   796 		if ((!IsTileType(tile, MP_HOUSE) || GetHouseConstructionTick(tile) != 0) &&
   797 		if ((!IsTileType(tile, MP_HOUSE) || GetHouseConstructionTick(tile) != 0) &&
   797 				GetTileSlope(tile, NULL) == 0) {
   798 				GetTileSlope(tile, NULL) == SLOPE_FLAT) {
   798 			if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) {
   799 			if (!CmdFailed(DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR))) {
   799 				DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
   800 				DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
   800 				_current_player = old_player;
   801 				_current_player = old_player;
   801 				return true;
   802 				return true;
   802 			}
   803 			}
  1011 	// Check if too close to the edge of map
  1012 	// Check if too close to the edge of map
  1012 	if (DistanceFromEdge(tile) < 12)
  1013 	if (DistanceFromEdge(tile) < 12)
  1013 		return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
  1014 		return_cmd_error(STR_0237_TOO_CLOSE_TO_EDGE_OF_MAP);
  1014 
  1015 
  1015 	// Can only build on clear flat areas.
  1016 	// Can only build on clear flat areas.
  1016 	if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != 0) {
  1017 	if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) {
  1017 		return_cmd_error(STR_0239_SITE_UNSUITABLE);
  1018 		return_cmd_error(STR_0239_SITE_UNSUITABLE);
  1018 	}
  1019 	}
  1019 
  1020 
  1020 	// Check distance to all other towns.
  1021 	// Check distance to all other towns.
  1021 	if (IsCloseToTown(tile, 20))
  1022 	if (IsCloseToTown(tile, 20))
  1048 		// Generate a tile index not too close from the edge
  1049 		// Generate a tile index not too close from the edge
  1049 		tile = RandomTile();
  1050 		tile = RandomTile();
  1050 		if (DistanceFromEdge(tile) < 20) continue;
  1051 		if (DistanceFromEdge(tile) < 20) continue;
  1051 
  1052 
  1052 		// Make sure the tile is plain
  1053 		// Make sure the tile is plain
  1053 		if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != 0) continue;
  1054 		if (!IsTileType(tile, MP_CLEAR) || GetTileSlope(tile, NULL) != SLOPE_FLAT) continue;
  1054 
  1055 
  1055 		// Check not too close to a town
  1056 		// Check not too close to a town
  1056 		if (IsCloseToTown(tile, 20)) continue;
  1057 		if (IsCloseToTown(tile, 20)) continue;
  1057 
  1058 
  1058 		// Get a unique name for the town.
  1059 		// Get a unique name for the town.
  1091 	}
  1092 	}
  1092 
  1093 
  1093 	return true;
  1094 	return true;
  1094 }
  1095 }
  1095 
  1096 
  1096 static bool CheckBuildHouseMode(TileIndex tile, uint tileh, int mode)
  1097 static bool CheckBuildHouseMode(TileIndex tile, Slope tileh, int mode)
  1097 {
  1098 {
  1098 	int b;
  1099 	int b;
  1099 	uint slope;
  1100 	Slope slope;
  1100 
  1101 
  1101 	static const byte _masks[8] = {
  1102 	static const byte _masks[8] = {
  1102 		0xC,0x3,0x9,0x6,
  1103 		0xC,0x3,0x9,0x6,
  1103 		0x3,0xC,0x6,0x9,
  1104 		0x3,0xC,0x6,0x9,
  1104 	};
  1105 	};
  1105 
  1106 
  1106 	slope = GetTileSlope(tile, NULL);
  1107 	slope = GetTileSlope(tile, NULL);
  1107 	if (slope & 0x10)
  1108 	if (IsSteepSlope(slope)) return false;
  1108 		return false;
       
  1109 
  1109 
  1110 	b = 0;
  1110 	b = 0;
  1111 	if ((slope & 0xF && ~slope & _masks[mode])) b = ~b;
  1111 	if ((slope != SLOPE_FLAT && ~slope & _masks[mode])) b = ~b;
  1112 	if ((tileh & 0xF && ~tileh & _masks[mode+4])) b = ~b;
  1112 	if ((tileh != SLOPE_FLAT && ~tileh & _masks[mode+4])) b = ~b;
  1113 	if (b)
  1113 	if (b)
  1114 		return false;
  1114 		return false;
  1115 
  1115 
  1116 	return !CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR));
  1116 	return !CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR));
  1117 }
  1117 }
  1146 	};
  1146 	};
  1147 
  1147 
  1148 	for (i = 0; i != 4; i++) {
  1148 	for (i = 0; i != 4; i++) {
  1149 		tile += ToTileIndexDiff(_tile_add[i]);
  1149 		tile += ToTileIndexDiff(_tile_add[i]);
  1150 
  1150 
  1151 		if (GetTileSlope(tile, NULL)) return false;
  1151 		if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
  1152 
  1152 
  1153 		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_FORCETEST, CMD_LANDSCAPE_CLEAR)))
  1153 		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_FORCETEST, CMD_LANDSCAPE_CLEAR)))
  1154 			return false;
  1154 			return false;
  1155 	}
  1155 	}
  1156 
  1156 
  1160 static void DoBuildTownHouse(Town *t, TileIndex tile)
  1160 static void DoBuildTownHouse(Town *t, TileIndex tile)
  1161 {
  1161 {
  1162 	int i;
  1162 	int i;
  1163 	uint bitmask;
  1163 	uint bitmask;
  1164 	int house;
  1164 	int house;
  1165 	uint slope;
  1165 	Slope slope;
  1166 	uint z;
  1166 	uint z;
  1167 	uint oneof = 0;
  1167 	uint oneof = 0;
  1168 
  1168 
  1169 	// Above snow?
  1169 	// Above snow?
  1170 	slope = GetTileSlope(tile, &z);
  1170 	slope = GetTileSlope(tile, &z);
  1218 			}
  1218 			}
  1219 
  1219 
  1220 			if (HASBITS(t->flags12 , oneof)) continue;
  1220 			if (HASBITS(t->flags12 , oneof)) continue;
  1221 
  1221 
  1222 			// Make sure there is no slope?
  1222 			// Make sure there is no slope?
  1223 			if (_housetype_extra_flags[house] & 0x12 && slope) continue;
  1223 			if (_housetype_extra_flags[house] & 0x12 && slope != SLOPE_FLAT) continue;
  1224 
  1224 
  1225 			if (_housetype_extra_flags[house] & 0x10) {
  1225 			if (_housetype_extra_flags[house] & 0x10) {
  1226 				if (CheckFree2x2Area(tile) ||
  1226 				if (CheckFree2x2Area(tile) ||
  1227 						CheckFree2x2Area(tile += TileDiffXY(-1,  0)) ||
  1227 						CheckFree2x2Area(tile += TileDiffXY(-1,  0)) ||
  1228 						CheckFree2x2Area(tile += TileDiffXY( 0, -1)) ||
  1228 						CheckFree2x2Area(tile += TileDiffXY( 0, -1)) ||
  1281 {
  1281 {
  1282 	int32 r;
  1282 	int32 r;
  1283 
  1283 
  1284 	// make sure it's possible
  1284 	// make sure it's possible
  1285 	if (!EnsureNoVehicle(tile)) return false;
  1285 	if (!EnsureNoVehicle(tile)) return false;
  1286 	if (GetTileSlope(tile, NULL) & 0x10) return false;
  1286 	if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
  1287 
  1287 
  1288 	r = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
  1288 	r = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
  1289 	if (CmdFailed(r)) return false;
  1289 	if (CmdFailed(r)) return false;
  1290 
  1290 
  1291 	DoBuildTownHouse(t, tile);
  1291 	DoBuildTownHouse(t, tile);
  1486 static bool DoBuildStatueOfCompany(TileIndex tile)
  1486 static bool DoBuildStatueOfCompany(TileIndex tile)
  1487 {
  1487 {
  1488 	PlayerID old;
  1488 	PlayerID old;
  1489 	int32 r;
  1489 	int32 r;
  1490 
  1490 
  1491 	if (GetTileSlope(tile, NULL) != 0) return false;
  1491 	if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
  1492 
  1492 
  1493 	if (!IsTileType(tile, MP_HOUSE) &&
  1493 	if (!IsTileType(tile, MP_HOUSE) &&
  1494 			!IsTileType(tile, MP_CLEAR) &&
  1494 			!IsTileType(tile, MP_CLEAR) &&
  1495 			!IsTileType(tile, MP_TREES)) {
  1495 			!IsTileType(tile, MP_TREES)) {
  1496 		return false;
  1496 		return false;