|
@@ -619,97 +619,97 @@ void UpdateStationAcceptance(Station *st
|
|
|
|
|
|
static void UpdateStationSignCoord(BaseStation *st)
|
|
|
{
|
|
|
const StationRect *r = &st->rect;
|
|
|
|
|
|
if (r->IsEmpty()) return; // no tiles belong to this station
|
|
|
|
|
|
/* clamp sign coord to be inside the station rect */
|
|
|
st->xy = TileXY(ClampU(TileX(st->xy), r->left, r->right), ClampU(TileY(st->xy), r->top, r->bottom));
|
|
|
st->UpdateVirtCoord();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* This is called right after a station was deleted.
|
|
|
* It checks if the whole station is free of substations, and if so, the station will be
|
|
|
* deleted after a little while.
|
|
|
* @param st Station
|
|
|
*/
|
|
|
static void DeleteStationIfEmpty(BaseStation *st)
|
|
|
{
|
|
|
if (!st->IsInUse()) {
|
|
|
st->delete_ctr = 0;
|
|
|
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
|
|
}
|
|
|
/* station remains but it probably lost some parts - station sign should stay in the station boundaries */
|
|
|
UpdateStationSignCoord(st);
|
|
|
}
|
|
|
|
|
|
CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags);
|
|
|
|
|
|
/**
|
|
|
* Checks if the given tile is buildable, flat and has a certain height.
|
|
|
* @param tile TileIndex to check.
|
|
|
* @param invalid_dirs Prohibited directions for slopes (set of #DiagDirection).
|
|
|
* @param allowed_z Height allowed for the tile. If allowed_z is negative, it will be set to the height of this tile.
|
|
|
* @param allow_steep Whether steep slopes are allowed.
|
|
|
* @param check_bridge Check for the existance of a bridge.
|
|
|
* @return The cost in case of success, or an error code if it failed.
|
|
|
*/
|
|
|
CommandCost CheckBuildableTile(TileIndex tile, uint invalid_dirs, int &allowed_z, bool allow_steep, bool check_bridge = true)
|
|
|
{
|
|
|
if (check_bridge && MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) {
|
|
|
return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
|
|
|
}
|
|
|
|
|
|
CommandCost ret = EnsureNoVehicleOnGround(tile);
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
|
|
uint z;
|
|
|
int z;
|
|
|
Slope tileh = GetTileSlope(tile, &z);
|
|
|
|
|
|
/* Prohibit building if
|
|
|
* 1) The tile is "steep" (i.e. stretches two height levels).
|
|
|
* 2) The tile is non-flat and the build_on_slopes switch is disabled.
|
|
|
*/
|
|
|
if ((!allow_steep && IsSteepSlope(tileh)) ||
|
|
|
((!_settings_game.construction.build_on_slopes) && tileh != SLOPE_FLAT)) {
|
|
|
return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
|
|
|
}
|
|
|
|
|
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
|
|
int flat_z = z + GetSlopeMaxZ(tileh);
|
|
|
if (tileh != SLOPE_FLAT) {
|
|
|
/* Forbid building if the tile faces a slope in a invalid direction. */
|
|
|
for (DiagDirection dir = DIAGDIR_BEGIN; dir != DIAGDIR_END; dir++) {
|
|
|
if (HasBit(invalid_dirs, dir) && !CanBuildDepotByTileh(dir, tileh)) {
|
|
|
return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
|
|
|
}
|
|
|
}
|
|
|
cost.AddCost(_price[PR_BUILD_FOUNDATION]);
|
|
|
}
|
|
|
|
|
|
/* The level of this tile must be equal to allowed_z. */
|
|
|
if (allowed_z < 0) {
|
|
|
/* First tile. */
|
|
|
allowed_z = flat_z;
|
|
|
} else if (allowed_z != flat_z) {
|
|
|
return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
|
|
|
}
|
|
|
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Tries to clear the given area.
|
|
|
* @param tile_area Area to check.
|
|
|
* @param flags Operation to perform.
|
|
|
* @return The cost in case of success, or an error code if it failed.
|
|
|
*/
|
|
|
CommandCost CheckFlatLand(TileArea tile_area, DoCommandFlag flags)
|
|
|
{
|
|
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
|
|
int allowed_z = -1;
|
|
|
|
|
|
TILE_AREA_LOOP(tile_cur, tile_area) {
|
|
|
CommandCost ret = CheckBuildableTile(tile_cur, 0, allowed_z, true);
|
|
|
if (ret.Failed()) return ret;
|
|
@@ -2539,97 +2539,97 @@ static void DrawTile_Station(TileInfo *t
|
|
|
StationGfx gfx = GetAirportGfx(ti->tile);
|
|
|
if (gfx >= NEW_AIRPORTTILE_OFFSET) {
|
|
|
const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
|
|
|
if (ats->grf_prop.spritegroup[0] != NULL && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats)) {
|
|
|
return;
|
|
|
}
|
|
|
/* No sprite group (or no valid one) found, meaning no graphics associated.
|
|
|
* Use the substitute one instead */
|
|
|
assert(ats->grf_prop.subst_id != INVALID_AIRPORTTILE);
|
|
|
gfx = ats->grf_prop.subst_id;
|
|
|
}
|
|
|
switch (gfx) {
|
|
|
case APT_RADAR_GRASS_FENCE_SW:
|
|
|
t = &_station_display_datas_airport_radar_grass_fence_sw[GetAnimationFrame(ti->tile)];
|
|
|
break;
|
|
|
case APT_GRASS_FENCE_NE_FLAG:
|
|
|
t = &_station_display_datas_airport_flag_grass_fence_ne[GetAnimationFrame(ti->tile)];
|
|
|
break;
|
|
|
case APT_RADAR_FENCE_SW:
|
|
|
t = &_station_display_datas_airport_radar_fence_sw[GetAnimationFrame(ti->tile)];
|
|
|
break;
|
|
|
case APT_RADAR_FENCE_NE:
|
|
|
t = &_station_display_datas_airport_radar_fence_ne[GetAnimationFrame(ti->tile)];
|
|
|
break;
|
|
|
case APT_GRASS_FENCE_NE_FLAG_2:
|
|
|
t = &_station_display_datas_airport_flag_grass_fence_ne_2[GetAnimationFrame(ti->tile)];
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Owner owner = GetTileOwner(ti->tile);
|
|
|
|
|
|
PaletteID palette;
|
|
|
if (Company::IsValidID(owner)) {
|
|
|
palette = COMPANY_SPRITE_COLOUR(owner);
|
|
|
} else {
|
|
|
/* Some stations are not owner by a company, namely oil rigs */
|
|
|
palette = PALETTE_TO_GREY;
|
|
|
}
|
|
|
|
|
|
if (layout == NULL && (t == NULL || t->seq == NULL)) t = GetStationTileLayout(GetStationType(ti->tile), GetStationGfx(ti->tile));
|
|
|
|
|
|
/* don't show foundation for docks */
|
|
|
if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile)) {
|
|
|
if (statspec != NULL && HasBit(statspec->flags, SSF_CUSTOM_FOUNDATIONS)) {
|
|
|
/* Station has custom foundations.
|
|
|
* Check whether the foundation continues beyond the tile's upper sides. */
|
|
|
uint edge_info = 0;
|
|
|
uint z;
|
|
|
int z;
|
|
|
Slope slope = GetFoundationPixelSlope(ti->tile, &z);
|
|
|
if (!HasFoundationNW(ti->tile, slope, z)) SetBit(edge_info, 0);
|
|
|
if (!HasFoundationNE(ti->tile, slope, z)) SetBit(edge_info, 1);
|
|
|
SpriteID image = GetCustomStationFoundationRelocation(statspec, st, ti->tile, tile_layout, edge_info);
|
|
|
|
|
|
if (HasBit(statspec->flags, SSF_EXTENDED_FOUNDATIONS)) {
|
|
|
/* Station provides extended foundations. */
|
|
|
|
|
|
static const uint8 foundation_parts[] = {
|
|
|
0, 0, 0, 0, // Invalid, Invalid, Invalid, SLOPE_SW
|
|
|
0, 1, 2, 3, // Invalid, SLOPE_EW, SLOPE_SE, SLOPE_WSE
|
|
|
0, 4, 5, 6, // Invalid, SLOPE_NW, SLOPE_NS, SLOPE_NWS
|
|
|
7, 8, 9 // SLOPE_NE, SLOPE_ENW, SLOPE_SEN
|
|
|
};
|
|
|
|
|
|
AddSortableSpriteToDraw(image + foundation_parts[ti->tileh], PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
|
|
|
} else {
|
|
|
/* Draw simple foundations, built up from 8 possible foundation sprites. */
|
|
|
|
|
|
/* Each set bit represents one of the eight composite sprites to be drawn.
|
|
|
* 'Invalid' entries will not drawn but are included for completeness. */
|
|
|
static const uint8 composite_foundation_parts[] = {
|
|
|
/* Invalid (00000000), Invalid (11010001), Invalid (11100100), SLOPE_SW (11100000) */
|
|
|
0x00, 0xD1, 0xE4, 0xE0,
|
|
|
/* Invalid (11001010), SLOPE_EW (11001001), SLOPE_SE (11000100), SLOPE_WSE (11000000) */
|
|
|
0xCA, 0xC9, 0xC4, 0xC0,
|
|
|
/* Invalid (11010010), SLOPE_NW (10010001), SLOPE_NS (11100100), SLOPE_NWS (10100000) */
|
|
|
0xD2, 0x91, 0xE4, 0xA0,
|
|
|
/* SLOPE_NE (01001010), SLOPE_ENW (00001001), SLOPE_SEN (01000100) */
|
|
|
0x4A, 0x09, 0x44
|
|
|
};
|
|
|
|
|
|
uint8 parts = composite_foundation_parts[ti->tileh];
|
|
|
|
|
|
/* If foundations continue beyond the tile's upper sides then
|
|
|
* mask out the last two pieces. */
|
|
|
if (HasBit(edge_info, 0)) ClrBit(parts, 6);
|
|
|
if (HasBit(edge_info, 1)) ClrBit(parts, 7);
|
|
|
|
|
|
if (parts == 0) {
|
|
|
/* We always have to draw at least one sprite to make sure there is a boundingbox and a sprite with the
|
|
|
* correct offset for the childsprites.
|
|
|
* So, draw the (completely empty) sprite of the default foundations. */
|
|
|
goto draw_default_foundation;
|
|
|
}
|
|
|
|
|
|
StartSpriteCombine();
|
|
|
for (int i = 0; i < 8; i++) {
|