/** * Are the tiles of the industry free? * @param tile Position to check. * @param it Industry tiles table. * @param itspec_index The index of the itsepc to build/fund * @param type Type of the industry. * @param initial_random_bits The random bits the industry is going to have after construction. * @param founder Industry founder * @param creation_type The circumstances the industry is created under. * @param [out] custom_shape_check Perform custom check for the site. * @return Failed or succeeded command. */ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = NULL) { bool refused_slope = false; bool custom_shape = false; do { IndustryGfx gfx = GetTranslatedIndustryTileID(it->gfx); TileIndex cur_tile = TileAddWrap(tile, it->ti.x, it->ti.y); if (!IsValidTile(cur_tile)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } if (gfx == GFX_WATERTILE_SPECIALCHECK) { if (!IsTileType(cur_tile, MP_WATER) || !IsTileFlat(cur_tile)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } } else { CommandCost ret = EnsureNoVehicleOnGround(cur_tile); if (ret.Failed()) return ret; if (IsBridgeAbove(cur_tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); const IndustryTileSpec *its = GetIndustryTileSpec(gfx); IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour; /* Perform land/water check if not disabled */ if (!HasBit(its->slopes_refused, 5) && ((HasTileWaterClass(cur_tile) && IsTileOnWater(cur_tile)) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); if (HasBit(its->callback_mask, CBM_INDT_SHAPE_CHECK)) { custom_shape = true; CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index, initial_random_bits, founder, creation_type); if (ret.Failed()) return ret; } else { Slope tileh = GetTileSlope(cur_tile); refused_slope |= IsSlopeRefused(tileh, its->slopes_refused); } if ((ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) || // Tile must be a house ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) && IsTileType(cur_tile, MP_HOUSE))) { // Tile is allowed to be a house (and it is a house) if (!IsTileType(cur_tile, MP_HOUSE)) { return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS); } /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */ Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); if (ret.Failed()) return ret; } else { /* Clear the tiles, but do not affect town ratings */ CommandCost ret = DoCommand(cur_tile, 0, 0, DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) { if (!(ind_behav & INDUSTRYBEH_BUILT_ONWATER)) return ret; if (!_settings_game.construction.build_on_competitor_canal) return ret; if (_settings_game.construction.build_on_competitor_canal && (ind_behav & INDUSTRYBEH_BUILT_ONWATER) && (IsTileType(cur_tile, MP_INDUSTRY) || _current_company >= MAX_COMPANIES)) return ret; } } } } while ((++it)->ti.x != -0x80); if (custom_shape_check != NULL) *custom_shape_check = custom_shape; /* It is almost impossible to have a fully flat land in TG, so what we * do is that we check if we can make the land flat later on. See * CheckIfCanLevelIndustryPlatform(). */ if (!refused_slope || (_settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions)) { return CommandCost(); } return_cmd_error(STR_ERROR_SITE_UNSUITABLE); }